1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-06 05:02:40 +03:00

IPv6 is always enabled

This commit is contained in:
Lammert Bies
2016-12-26 01:15:22 +01:00
parent 3b5e4e5a75
commit 074e9a9a8c
20 changed files with 27 additions and 114 deletions

View File

@@ -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/

View File

@@ -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

View File

@@ -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. |

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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 ) ) {

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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 );

View File

@@ -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);

View File

@@ -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 ) {

View File

@@ -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 */

View File

@@ -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);
}
if ( conn->client.rsa.sa.sa_family == AF_INET6 ) conn->request_info.remote_port = ntohs( conn->client.rsa.sin6.sin6_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 );