diff --git a/Makefile b/Makefile index 3a38e416..7056c514 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ ifneq ($(OS),Windows_NT) OS:=$(shell uname -s) endif -DFLAGS = -DUSE_STACK_SIZE=102400 -DUSE_WEBSOCKET -DUSE_IPV6 +DFLAGS = -DUSE_STACK_SIZE=102400 -DUSE_WEBSOCKET INCDIR = include/ LIBDIR = lib/ diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4fef2415..7f00c378 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,7 @@ Release Notes v2.0 (work in progress) Changes ------- +- IPv6 support is now always available - Combined three send file functions into `httplib_send_file()`. - Memory allocation debugging can be switched on and off dynamically - Memory allocation functions are available for the main application diff --git a/doc/api/httplib_check_feature.md b/doc/api/httplib_check_feature.md index 60136ae6..7fbc5e22 100644 --- a/doc/api/httplib_check_feature.md +++ b/doc/api/httplib_check_feature.md @@ -25,7 +25,6 @@ The following parameter values can be used: | **1** | NO_FILES | *Able to serve files*. If this feature is available, the webserver is able to serve files directly from a directory tree. | | **2** | NO_SSL | *Support for HTTPS*. If this feature is available, the webserver van use encryption in the client-server connection. SSLv2, SSLv3, TLSv1.0, TLSv1.1 and TLSv1.2 are supported depending on the SSL library LibHTTP has been compiled with, but which protocols are used effectively when the server is running is dependent on the options used when the server is started. | | **4** | NO_CGI | *Support for CGI*. If this feature is available, external CGI scripts can be called by the webserver. | -| **8** | USE_IPV6 | *Support IPv6*. The LibHTTP library is capable of communicating over both IPv4 and IPv6, but IPv6 support is only available if it has been enabled at compile time. | | **16** | USE_WEBSOCKET | Support for web sockets. WebSockets support is available in the LibHTTP library if the proper options has been used during cimpile time. | | **128** | NO_CACHING | *Support for caching*. The webserver will support caching, if it has not been disabled while compiling the library. | diff --git a/doc/api/httplib_client_options.md b/doc/api/httplib_client_options.md index da6162c3..2c27c501 100644 --- a/doc/api/httplib_client_options.md +++ b/doc/api/httplib_client_options.md @@ -13,9 +13,8 @@ ### Description -The the `mgclient_options` structure contains host and security information to connect as a client to another host. A parameter of this type is used in the call to the function [`httplib_connect_client_secure()`](httplib_connect_client_secure.md). Please note that IPv6 addresses are only permitted if IPv6 support was enabled during compilation. You can use the function [`httplib_check_feature()`](httplib_check_feature.md) with the parameter `USE_IPV6` while running your application to check if IPv6 is supported. +The the `mgclient_options` structure contains host and security information to connect as a client to another host. A parameter of this type is used in the call to the function [`httplib_connect_client_secure()`](httplib_connect_client_secure.md). ### See Also -* [`httplib_check_feature();`](httplib_check_feature.md) * [`httplib_connect_client_secure();`](httplib_connect_client_secure.md) diff --git a/doc/api/httplib_connect_client.md b/doc/api/httplib_connect_client.md index 12e478b1..ba8db92b 100644 --- a/doc/api/httplib_connect_client.md +++ b/doc/api/httplib_connect_client.md @@ -20,10 +20,9 @@ ### Description -The function `httplib_connect_client()` connects to a TCP server as a client. This server can be a HTTP server but this is not necessary. The function returns a pointer to a connection structure when the connection is established and NULL otherwise. The host may be on IPv4 or IPv6, but IPv6 is not enabled in every LibHTTP installation. Specifically the use of IPv6 communications has to be enabled when the library is compiled. At runtime you can use the [`httplib_check_feature()`](httplib_check_feature.md) function with the parameter `USE_IPV6` to check if IPv6 communication is supported. +The function `httplib_connect_client()` connects to a TCP server as a client. This server can be a HTTP server but this is not necessary. The function returns a pointer to a connection structure when the connection is established and NULL otherwise. ### See Also -* [`httplib_check_feature();`](httplib_check_feature.md) * [`httplib_connect_client_secure();`](httplib_connect_client_secure.md) * [`httplib_connect_websocket_client();`](httplib_connect_websocket_client.md) diff --git a/doc/api/httplib_connect_client_secure.md b/doc/api/httplib_connect_client_secure.md index 48888056..66fd3c24 100644 --- a/doc/api/httplib_connect_client_secure.md +++ b/doc/api/httplib_connect_client_secure.md @@ -20,11 +20,8 @@ The function `httplib_connect_client_secure()` creates a secure connection with a server. The information about the connection and server is passed in a structure and an error message may be returned in a local buffer. The function returns a pointer to a `struct httplib_connection` structure when successful and NULL otherwise. -Please note that IPv6 communication is supported by LibHTTP, but only if the use of IPv6 was enabled at compile time. The check while running a program if IPv6 communication is possible you can call [`httplib_check_feature()`](httplib_check_feature.md) with the `USE_IPV6` parameter to check if IPv6 communications can be used. - ### See Also * [`struct httplib_client_options;`](httplib_client_options.md) -* [`httplib_check_feature();`](httplib_check_feature.md) * [`httplib_connect_client();`](httplib_connect_client.md) * [`httplib_connect_websocket_client();`](httplib_connect_websocket_client.md) diff --git a/doc/api/httplib_connect_websocket_client.md b/doc/api/httplib_connect_websocket_client.md index 63d3b7b1..bb506339 100644 --- a/doc/api/httplib_connect_websocket_client.md +++ b/doc/api/httplib_connect_websocket_client.md @@ -27,10 +27,7 @@ The function `httplib_connect_websocket_client()` connects to a websocket on a server as a client. Data and close events are processed with callback functions which must be provided in the call. -LibHTTP supports both IPv4 and IPv6 communication, but only if the use if IPv6 has been enabled at compile time. When running an application it is possible to check if IPv6 addressing is available by calling the [`httplib_check_feature()`](httplib_check_feature.md) function with the `USE_IPV6` parameter. - ### See Also -* [`httplib_check_feature();`](httplib_check_feature.md) * [`httplib_connect_client();`](httplib_connect_client.md) * [`httplib_connect_client_secure();`](httplib_connect_client_secure.md) diff --git a/doc/api/httplib_download.md b/doc/api/httplib_download.md index 8a901302..37583f48 100644 --- a/doc/api/httplib_download.md +++ b/doc/api/httplib_download.md @@ -29,9 +29,6 @@ The format string is a format string from the `printf()` series of functions to `conn = httplib_download( "google.com", 80, 0, ebuf, sizeof(ebuf), "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n" );` -Please note that although LibHTTP supports both IPv4 and IPv6 communication that IPv6 addressing is only available if it was enabled at compile time. When running an application it is possible to check if IPv6 support has been compiled in by using the [`httplib_check_feature()`](httplib_check_feature.md) function with the parameter `USE_IPV6`. - ### See Also -* [`httplib_check_feature();`](httplib_check_feature.md) * [`httplib_close_connection();`](httplib_close_connection.md) diff --git a/include/libhttp.h b/include/libhttp.h index dbfab093..ba685992 100644 --- a/include/libhttp.h +++ b/include/libhttp.h @@ -961,7 +961,6 @@ LIBHTTP_API int httplib_get_response(struct httplib_connection *conn, char *ebuf 1 serve files (NO_FILES not set) 2 support HTTPS (NO_SSL not set) 4 support CGI (NO_CGI not set) - 8 support IPv6 (USE_IPV6 set) 16 support WebSocket (USE_WEBSOCKET set) 128 support caching (NO_CACHING not set) The result is undefined for all other feature values. diff --git a/src/httplib_check_feature.c b/src/httplib_check_feature.c index 64f6eaed..5c4538e9 100644 --- a/src/httplib_check_feature.c +++ b/src/httplib_check_feature.c @@ -47,9 +47,6 @@ unsigned httplib_check_feature( unsigned feature ) { #if !defined(NO_CGI) | 0x0004u #endif -#if defined(USE_IPV6) - | 0x0008u -#endif #if defined(USE_WEBSOCKET) | 0x0010u #endif diff --git a/src/httplib_connect_client.c b/src/httplib_connect_client.c index f420e975..7587edd3 100644 --- a/src/httplib_connect_client.c +++ b/src/httplib_connect_client.c @@ -104,13 +104,8 @@ static struct httplib_connection *httplib_connect_client_impl( const struct http else { -#ifdef USE_IPV6 len = (sa.sa.sa_family == AF_INET) ? sizeof(conn->client.rsa.sin) : sizeof(conn->client.rsa.sin6); psa = (sa.sa.sa_family == AF_INET) ? (struct sockaddr *)&(conn->client.rsa.sin) : (struct sockaddr *)&(conn->client.rsa.sin6); -#else - len = sizeof(conn->client.rsa.sin); - psa = (struct sockaddr *)&(conn->client.rsa.sin); -#endif conn->buf_size = MAX_REQUEST_SIZE; conn->buf = (char *)(conn + 1); diff --git a/src/httplib_connect_socket.c b/src/httplib_connect_socket.c index d20c3c49..d4be44cc 100644 --- a/src/httplib_connect_socket.c +++ b/src/httplib_connect_socket.c @@ -68,16 +68,15 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "%s", "SSL is not initialized" ); return 0; } -#else +#else /* NO_SSL */ UNUSED_PARAMETER(use_ssl); -#endif +#endif /*NO_SSL */ if (XX_httplib_inet_pton(AF_INET, host, &sa->sin, sizeof(sa->sin))) { sa->sin.sin_port = htons((uint16_t)port); ip_ver = 4; } -#ifdef USE_IPV6 else if ( XX_httplib_inet_pton( AF_INET6, host, &sa->sin6, sizeof(sa->sin6) ) ) { @@ -107,7 +106,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in httplib_free( h ); } } -#endif + if ( ip_ver == 0 ) { XX_httplib_snprintf( NULL, NULL, ebuf, ebuf_len, "%s", "host not found" ); @@ -115,9 +114,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in } if ( ip_ver == 4 ) *sock = socket( PF_INET, SOCK_STREAM, 0 ); -#ifdef USE_IPV6 else if ( ip_ver == 6 ) *sock = socket( PF_INET6, SOCK_STREAM, 0 ); -#endif if ( *sock == INVALID_SOCKET ) { @@ -128,10 +125,7 @@ int XX_httplib_connect_socket( struct httplib_context *ctx, const char *host, in XX_httplib_set_close_on_exec( *sock, XX_httplib_fc(ctx) ); if ( ip_ver == 4 && connect( *sock, (struct sockaddr *)&sa->sin, sizeof(sa->sin) ) == 0 ) return 1; - -#ifdef USE_IPV6 if ( ip_ver == 6 && connect( *sock, (struct sockaddr *)&sa->sin6, sizeof(sa->sin6) ) == 0 ) return 1; -#endif /* * Not connected diff --git a/src/httplib_get_rel_url_at_current_server.c b/src/httplib_get_rel_url_at_current_server.c index 7e6b9e48..c74b829f 100644 --- a/src/httplib_get_rel_url_at_current_server.c +++ b/src/httplib_get_rel_url_at_current_server.c @@ -100,17 +100,8 @@ const char * XX_httplib_get_rel_url_at_current_server( const char *uri, const st return 0; } -#if defined(USE_IPV6) - if ( conn->client.lsa.sa.sa_family == AF_INET6 ) { - - if ( ntohs( conn->client.lsa.sin6.sin6_port ) != port ) return 0; - } - - else -#endif - { - if ( ntohs( conn->client.lsa.sin.sin_port ) != port ) return 0; - } + if ( conn->client.lsa.sa.sa_family == AF_INET6 ) { if ( ntohs( conn->client.lsa.sin6.sin6_port ) != port ) return 0; } + else { if ( ntohs( conn->client.lsa.sin.sin_port ) != port ) return 0; } if ( request_domain_len != server_domain_len || ( memcmp( server_domain, hostbegin, server_domain_len ) != 0 ) ) { diff --git a/src/httplib_get_server_ports.c b/src/httplib_get_server_ports.c index 14a2c9f8..8c93f353 100644 --- a/src/httplib_get_server_ports.c +++ b/src/httplib_get_server_ports.c @@ -42,13 +42,9 @@ int httplib_get_server_ports( const struct httplib_context *ctx, int size, struc for (i = 0; (i < size) && (i < (int)ctx->num_listening_sockets); i++) { - ports[cnt].port = -#if defined(USE_IPV6) - (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6) - ? ntohs(ctx->listening_sockets[i].lsa.sin6.sin6_port) - : -#endif - ntohs(ctx->listening_sockets[i].lsa.sin.sin_port); + ports[cnt].port = (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6) + ? ntohs( ctx->listening_sockets[i].lsa.sin6.sin6_port ) + : ntohs( ctx->listening_sockets[i].lsa.sin.sin_port ); ports[cnt].is_ssl = ctx->listening_sockets[i].is_ssl; ports[cnt].is_redirect = ctx->listening_sockets[i].ssl_redir; diff --git a/src/httplib_main.h b/src/httplib_main.h index 2db4c60d..eca413ed 100644 --- a/src/httplib_main.h +++ b/src/httplib_main.h @@ -394,9 +394,7 @@ typedef int SOCKET; union usa { struct sockaddr sa; struct sockaddr_in sin; -#if defined(USE_IPV6) struct sockaddr_in6 sin6; -#endif }; /* NOTE(lsm): this enum shoulds be in sync with the config_options below. */ diff --git a/src/httplib_prepare_cgi_environment.c b/src/httplib_prepare_cgi_environment.c index 55c06773..35a61be4 100644 --- a/src/httplib_prepare_cgi_environment.c +++ b/src/httplib_prepare_cgi_environment.c @@ -73,13 +73,8 @@ void XX_httplib_prepare_cgi_environment( struct httplib_connection *conn, const XX_httplib_addenv( env, "%s", "SERVER_PROTOCOL=HTTP/1.1" ); XX_httplib_addenv( env, "%s", "REDIRECT_STATUS=200" ); /* For PHP */ -#if defined(USE_IPV6) - if ( conn->client.lsa.sa.sa_family == AF_INET6 ) XX_httplib_addenv( env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin6.sin6_port) ); - else -#endif - { - XX_httplib_addenv( env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin.sin_port ) ); - } + if ( conn->client.lsa.sa.sa_family == AF_INET6 ) XX_httplib_addenv( env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin6.sin6_port ) ); + else XX_httplib_addenv( env, "SERVER_PORT=%d", ntohs( conn->client.lsa.sin.sin_port ) ); XX_httplib_sockaddr_to_string( src_addr, sizeof(src_addr), &conn->client.rsa ); diff --git a/src/httplib_redirect_to_https_port.c b/src/httplib_redirect_to_https_port.c index 0cb45d50..0b4c72d9 100644 --- a/src/httplib_redirect_to_https_port.c +++ b/src/httplib_redirect_to_https_port.c @@ -70,13 +70,9 @@ void XX_httplib_redirect_to_https_port( struct httplib_connection *conn, int ssl httplib_printf( conn, "HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s%s%s\r\n\r\n", host, -#if defined(USE_IPV6) - (conn->ctx->listening_sockets[ssl_index].lsa.sa.sa_family - == AF_INET6) - ? (int)ntohs(conn->ctx->listening_sockets[ssl_index].lsa.sin6.sin6_port) - : -#endif - (int)ntohs(conn->ctx->listening_sockets[ssl_index].lsa.sin.sin_port), + (conn->ctx->listening_sockets[ssl_index].lsa.sa.sa_family == AF_INET6) + ? (int)ntohs( conn->ctx->listening_sockets[ssl_index].lsa.sin6.sin6_port ) + : (int)ntohs( conn->ctx->listening_sockets[ssl_index].lsa.sin.sin_port ), conn->request_info.local_uri, (conn->request_info.query_string == NULL) ? "" : "?", (conn->request_info.query_string == NULL) ? "" : conn->request_info.query_string); diff --git a/src/httplib_set_ports_option.c b/src/httplib_set_ports_option.c index a7242245..5e254dfb 100644 --- a/src/httplib_set_ports_option.c +++ b/src/httplib_set_ports_option.c @@ -42,10 +42,8 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip int XX_httplib_set_ports_option( struct httplib_context *ctx ) { const char *list; - int on = 1; -#if defined(USE_IPV6) - int off = 0; -#endif /* USE_IPV6 */ + int on; + int off; struct vec vec; struct socket so; struct socket *ptr; @@ -58,6 +56,8 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { if ( ctx == NULL ) return 0; + on = 1; + off = 0; ports_total = 0; ports_ok = 0; @@ -130,7 +130,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { #endif /* _WIN32 */ if ( ip_version > 4 ) { -#if defined(USE_IPV6) + if ( ip_version == 6 ) { if ( so.lsa.sa.sa_family == AF_INET6 && setsockopt( so.sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&off, sizeof(off) ) != 0 ) { @@ -142,12 +142,6 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { httplib_cry( XX_httplib_fc(ctx), "cannot set socket option IPV6_V6ONLY (entry %i)", ports_total ); } } -#else /* USE_IPV6 */ - httplib_cry( XX_httplib_fc(ctx), "IPv6 not available" ); - closesocket( so.sock ); - so.sock = INVALID_SOCKET; - continue; -#endif /* USE_IPV6 */ } if ( so.lsa.sa.sa_family == AF_INET ) { @@ -162,7 +156,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { continue; } } -#if defined(USE_IPV6) + else if ( so.lsa.sa.sa_family == AF_INET6 ) { len = sizeof(so.lsa.sin6); @@ -175,7 +169,7 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { continue; } } -#endif /* USE_IPV6 */ + else { httplib_cry( XX_httplib_fc(ctx), "cannot bind: address family not supported (entry %i)", ports_total ); continue; @@ -202,14 +196,8 @@ int XX_httplib_set_ports_option( struct httplib_context *ctx ) { * Update lsa port in case of random free ports */ -#if defined(USE_IPV6) if ( so.lsa.sa.sa_family == AF_INET6 ) so.lsa.sin6.sin6_port = usa.sin6.sin6_port; - - else -#endif /* USE_IPV6 */ - { - so.lsa.sin.sin_port = usa.sin.sin_port; - } + else so.lsa.sin.sin_port = usa.sin.sin_port; ptr = httplib_realloc( ctx->listening_sockets, (ctx->num_listening_sockets+1) * sizeof(ctx->listening_sockets[0]) ); @@ -282,9 +270,7 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip unsigned int port; int ch; int len; -#if defined(USE_IPV6) char buf[100] = {0}; -#endif /* USE_IPV6 */ /* * MacOS needs that. If we do not zero it, subsequent bind() will fail. @@ -309,7 +295,6 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip *ip_version = 4; } -#if defined(USE_IPV6) else if ( sscanf( vec->ptr, "[%49[^]]]:%u%n", buf, &port, &len ) == 2 && XX_httplib_inet_pton( AF_INET6, buf, &so->lsa.sin6, sizeof(so->lsa.sin6) ) ) { /* @@ -320,7 +305,6 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip so->lsa.sin6.sin6_port = htons( (uint16_t)port ); *ip_version = 6; } -#endif /* USE_IPV6 */ else if ( vec->ptr[0] == '+' && sscanf( vec->ptr + 1, "%u%n", &port, &len ) == 1 ) { @@ -331,8 +315,6 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip len++; -#if defined(USE_IPV6) - /* * Set socket family to IPv6, do not use IPV6_V6ONLY */ @@ -341,18 +323,6 @@ static bool parse_port_string( const struct vec *vec, struct socket *so, int *ip so->lsa.sin6.sin6_port = htons(( uint16_t)port ); *ip_version = 4 + 6; - -#else /* USE_IPV6 */ - - /* - * Bind to IPv4 only, since IPv6 is not built in. - */ - - so->lsa.sin.sin_port = htons( (uint16_t)port ); - *ip_version = 4; - -#endif /* USE_IPV6 */ - } else if ( sscanf( vec->ptr, "%u%n", &port, &len ) == 1 ) { diff --git a/src/httplib_sockaddr_to_string.c b/src/httplib_sockaddr_to_string.c index 2a762b3b..67422d75 100644 --- a/src/httplib_sockaddr_to_string.c +++ b/src/httplib_sockaddr_to_string.c @@ -34,8 +34,6 @@ void XX_httplib_sockaddr_to_string( char *buf, size_t len, const union usa *usa buf[0] = '\0'; if ( usa->sa.sa_family == AF_INET ) getnameinfo(&usa->sa, sizeof(usa->sin), buf, (unsigned)len, NULL, 0, NI_NUMERICHOST ); -#if defined(USE_IPV6) else if ( usa->sa.sa_family == AF_INET6 ) getnameinfo(&usa->sa, sizeof(usa->sin6), buf, (unsigned)len, NULL, 0, NI_NUMERICHOST ); -#endif } /* XX_httplib_sockaddr_to_string */ diff --git a/src/httplib_worker_thread.c b/src/httplib_worker_thread.c index 19f58e87..a51589bf 100644 --- a/src/httplib_worker_thread.c +++ b/src/httplib_worker_thread.c @@ -124,14 +124,9 @@ static void *worker_thread_run( struct worker_thread_args *thread_args ) { * error handler would have the corresponding info. * Thanks to Johannes Winkelmann for the patch. */ -#if defined(USE_IPV6) + if ( conn->client.rsa.sa.sa_family == AF_INET6 ) conn->request_info.remote_port = ntohs( conn->client.rsa.sin6.sin6_port ); - - else -#endif - { - conn->request_info.remote_port = ntohs(conn->client.rsa.sin.sin_port); - } + else conn->request_info.remote_port = ntohs( conn->client.rsa.sin.sin_port ); XX_httplib_sockaddr_to_string( conn->request_info.remote_addr, sizeof(conn->request_info.remote_addr), &conn->client.rsa );