diff --git a/Makefile b/Makefile index 8cef3ebe..79121996 100644 --- a/Makefile +++ b/Makefile @@ -415,6 +415,9 @@ OBJLIST = \ ${OBJDIR}httplib_pthread_setspecific${OBJEXT} \ ${OBJDIR}httplib_gmtime_r${OBJEXT} \ ${OBJDIR}httplib_localtime_r${OBJEXT} \ + ${OBJDIR}lh_ipt_to_ip${OBJEXT} \ + ${OBJDIR}lh_ipt_to_ip4${OBJEXT} \ + ${OBJDIR}lh_ipt_to_ip6${OBJEXT} \ ${OBJDIR}wince_rename${OBJEXT} \ ${OBJDIR}wince_stat${OBJEXT} \ ${OBJDIR}wince_strftime${OBJEXT} \ @@ -463,7 +466,6 @@ ${OBJDIR}httplib_accept_new_connection${OBJEXT} : ${SRCDIR}httplib_accept_new ${INCDIR}libhttp.h ${OBJDIR}httplib_addenv${OBJEXT} : ${SRCDIR}httplib_addenv.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -492,7 +494,6 @@ ${OBJDIR}httplib_check_acl${OBJEXT} : ${SRCDIR}httplib_check_acl.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_check_authorization${OBJEXT} : ${SRCDIR}httplib_check_authorization.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -529,24 +530,20 @@ ${OBJDIR}httplib_compare_dir_entries${OBJEXT} : ${SRCDIR}httplib_compare_dir_ ${OBJDIR}httplib_connect_client${OBJEXT} : ${SRCDIR}httplib_connect_client.c \ ${SRCDIR}httplib_pthread.h \ ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_connect_socket${OBJEXT} : ${SRCDIR}httplib_connect_socket.c \ ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_connect_websocket_client${OBJEXT} : ${SRCDIR}httplib_connect_websocket_client.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_construct_etag${OBJEXT} : ${SRCDIR}httplib_construct_etag.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -578,7 +575,6 @@ ${OBJDIR}httplib_difftimespec${OBJEXT} : ${SRCDIR}httplib_difftimespec.c ${INCDIR}libhttp.h ${OBJDIR}httplib_dir_scan_callback${OBJEXT} : ${SRCDIR}httplib_dir_scan_callback.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -587,7 +583,6 @@ ${OBJDIR}httplib_discard_unread_request_data${OBJEXT} : ${SRCDIR}httplib_disca ${INCDIR}libhttp.h ${OBJDIR}httplib_download${OBJEXT} : ${SRCDIR}httplib_download.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -635,7 +630,6 @@ ${OBJDIR}httplib_get_builtin_mime_type${OBJEXT} : ${SRCDIR}httplib_get_builti ${INCDIR}libhttp.h ${OBJDIR}httplib_get_cookie${OBJEXT} : ${SRCDIR}httplib_get_cookie.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -686,7 +680,6 @@ ${OBJDIR}httplib_get_request_len${OBJEXT} : ${SRCDIR}httplib_get_request_len. ${INCDIR}libhttp.h ${OBJDIR}httplib_get_response${OBJEXT} : ${SRCDIR}httplib_get_response.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -699,7 +692,6 @@ ${OBJDIR}httplib_get_server_ports${OBJEXT} : ${SRCDIR}httplib_get_server_port ${INCDIR}libhttp.h ${OBJDIR}httplib_get_system_name${OBJEXT} : ${SRCDIR}httplib_get_system_name.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -720,7 +712,6 @@ ${OBJDIR}httplib_get_var${OBJEXT} : ${SRCDIR}httplib_get_var.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_getreq${OBJEXT} : ${SRCDIR}httplib_getreq.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -730,13 +721,11 @@ ${OBJDIR}httplib_global_data${OBJEXT} : ${SRCDIR}httplib_global_data.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_gmt_time_string${OBJEXT} : ${SRCDIR}httplib_gmt_time_string.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_handle_cgi_request${OBJEXT} : ${SRCDIR}httplib_handle_cgi_request.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -759,7 +748,6 @@ ${OBJDIR}httplib_handle_not_modified_static_file_request${OBJEXT} : ${SRCDIR}htt ${INCDIR}libhttp.h ${OBJDIR}httplib_handle_propfind${OBJEXT} : ${SRCDIR}httplib_handle_propfind.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -771,7 +759,6 @@ ${OBJDIR}httplib_handle_request${OBJEXT} : ${SRCDIR}httplib_handle_request.c ${INCDIR}libhttp.h ${OBJDIR}httplib_handle_static_file_request${OBJEXT} : ${SRCDIR}httplib_handle_static_file_request.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -801,7 +788,6 @@ ${OBJDIR}httplib_initialize_ssl${OBJEXT} : ${SRCDIR}httplib_initialize_ssl.c ${INCDIR}libhttp.h ${OBJDIR}httplib_interpret_uri${OBJEXT} : ${SRCDIR}httplib_interpret_uri.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -834,7 +820,6 @@ ${OBJDIR}httplib_is_valid_port${OBJEXT} : ${SRCDIR}httplib_is_valid_port.c ${INCDIR}libhttp.h ${OBJDIR}httplib_is_websocket_protocol${OBJEXT} : ${SRCDIR}httplib_is_websocket_protocol.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -867,7 +852,6 @@ ${OBJDIR}httplib_lock_unlock_context${OBJEXT} : ${SRCDIR}httplib_lock_unlock_ ${OBJDIR}httplib_log_access${OBJEXT} : ${SRCDIR}httplib_log_access.c \ ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -917,7 +901,6 @@ ${OBJDIR}httplib_next_option${OBJEXT} : ${SRCDIR}httplib_next_option.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_open_auth_file${OBJEXT} : ${SRCDIR}httplib_open_auth_file.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -934,7 +917,6 @@ ${OBJDIR}httplib_option_value_to_int${OBJEXT} : ${SRCDIR}httplib_option_value ${INCDIR}libhttp.h ${OBJDIR}httplib_parse_auth_header${OBJEXT} : ${SRCDIR}httplib_parse_auth_header.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -959,7 +941,6 @@ ${OBJDIR}httplib_parse_range_header${OBJEXT} : ${SRCDIR}httplib_parse_range_h ${INCDIR}libhttp.h ${OBJDIR}httplib_path_to_unicode${OBJEXT} : ${SRCDIR}httplib_path_to_unicode.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -969,23 +950,19 @@ ${OBJDIR}httplib_poll${OBJEXT} : ${SRCDIR}httplib_poll.c \ ${OBJDIR}httplib_prepare_cgi_environment${OBJEXT} : ${SRCDIR}httplib_prepare_cgi_environment.c \ ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_print_dir_entry${OBJEXT} : ${SRCDIR}httplib_print_dir_entry.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_printf${OBJEXT} : ${SRCDIR}httplib_printf.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_process_new_connection${OBJEXT} : ${SRCDIR}httplib_process_new_connection.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1041,7 +1018,6 @@ ${OBJDIR}httplib_readdir${OBJEXT} : ${SRCDIR}httplib_readdir.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_redirect_to_https_port${OBJEXT} : ${SRCDIR}httplib_redirect_to_https_port.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1060,7 +1036,6 @@ ${OBJDIR}httplib_remove_bad_file${OBJEXT} : ${SRCDIR}httplib_remove_bad_file. ${INCDIR}libhttp.h ${OBJDIR}httplib_remove_directory${OBJEXT} : ${SRCDIR}httplib_remove_directory.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1073,7 +1048,6 @@ ${OBJDIR}httplib_reset_per_request_attributes${OBJEXT} : ${SRCDIR}httplib_rese ${INCDIR}libhttp.h ${OBJDIR}httplib_scan_directory${OBJEXT} : ${SRCDIR}httplib_scan_directory.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1092,7 +1066,6 @@ ${OBJDIR}httplib_send_file_data${OBJEXT} : ${SRCDIR}httplib_send_file_data.c ${INCDIR}libhttp.h ${OBJDIR}httplib_send_http_error${OBJEXT} : ${SRCDIR}httplib_send_http_error.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1111,7 +1084,6 @@ ${OBJDIR}httplib_send_static_cache_header${OBJEXT} : ${SRCDIR}httplib_send_sta ${INCDIR}libhttp.h ${OBJDIR}httplib_send_websocket_handshake${OBJEXT} : ${SRCDIR}httplib_send_websocket_handshake.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1137,7 +1109,6 @@ ${OBJDIR}httplib_set_gpass_option${OBJEXT} : ${SRCDIR}httplib_set_gpass_optio ${INCDIR}libhttp.h ${OBJDIR}httplib_set_handler_type${OBJEXT} : ${SRCDIR}httplib_set_handler_type.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1168,7 +1139,6 @@ ${OBJDIR}httplib_set_tcp_nodelay${OBJEXT} : ${SRCDIR}httplib_set_tcp_nodelay. ${INCDIR}libhttp.h ${OBJDIR}httplib_set_thread_name${OBJEXT} : ${SRCDIR}httplib_set_thread_name.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1206,7 +1176,6 @@ ${OBJDIR}httplib_skip_quoted${OBJEXT} : ${SRCDIR}httplib_skip_quoted.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_snprintf${OBJEXT} : ${SRCDIR}httplib_snprintf.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1215,12 +1184,10 @@ ${OBJDIR}httplib_sockaddr_to_string${OBJEXT} : ${SRCDIR}httplib_sockaddr_to_s ${INCDIR}libhttp.h ${OBJDIR}httplib_spawn_process${OBJEXT} : ${SRCDIR}httplib_spawn_process.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_ssi${OBJEXT} : ${SRCDIR}httplib_ssi.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1232,7 +1199,6 @@ ${OBJDIR}httplib_ssl_error${OBJEXT} : ${SRCDIR}httplib_ssl_error.c \ ${OBJDIR}httplib_ssl_get_client_cert_info${OBJEXT} : ${SRCDIR}httplib_ssl_get_client_cert_info.c \ ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1267,7 +1233,6 @@ ${OBJDIR}httplib_sslize${OBJEXT} : ${SRCDIR}httplib_sslize.c \ ${OBJDIR}httplib_start${OBJEXT} : ${SRCDIR}httplib_start.c \ ${SRCDIR}httplib_pthread.h \ ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1293,7 +1258,6 @@ ${OBJDIR}httplib_store_body${OBJEXT} : ${SRCDIR}httplib_store_body.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_strcasecmp${OBJEXT} : ${SRCDIR}httplib_strcasecmp.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_utils.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1320,7 +1284,6 @@ ${OBJDIR}httplib_strndup${OBJEXT} : ${SRCDIR}httplib_strndup.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_substitute_index_file${OBJEXT} : ${SRCDIR}httplib_substitute_index_file.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1366,12 +1329,10 @@ ${OBJDIR}httplib_version${OBJEXT} : ${SRCDIR}httplib_version.c \ ${INCDIR}libhttp.h ${OBJDIR}httplib_vprintf${OBJEXT} : ${SRCDIR}httplib_vprintf.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h ${OBJDIR}httplib_vsnprintf${OBJEXT} : ${SRCDIR}httplib_vsnprintf.c \ - ${SRCDIR}httplib_string.h \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h @@ -1486,6 +1447,18 @@ ${OBJDIR}httplib_localtime_r${OBJEXT} : ${SRCDIR}httplib_localtime_r.c \ ${SRCDIR}httplib_utils.h \ ${INCDIR}libhttp.h +${OBJDIR}lh_ipt_to_ip${OBJEXT} : ${SRCDIR}lh_ipt_to_ip.c \ + ${SRCDIR}httplib_main.h \ + ${INCDIR}libhttp.h + +${OBJDIR}lh_ipt_to_ip4${OBJEXT} : ${SRCDIR}lh_ipt_to_ip4.c \ + ${SRCDIR}httplib_main.h \ + ${INCDIR}libhttp.h + +${OBJDIR}lh_ipt_to_ip6${OBJEXT} : ${SRCDIR}lh_ipt_to_ip6.c \ + ${SRCDIR}httplib_main.h \ + ${INCDIR}libhttp.h + ${OBJDIR}wince_rename${OBJEXT} : ${SRCDIR}wince_rename.c \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h diff --git a/include/libhttp.h b/include/libhttp.h index b26710cd..5c1655f8 100644 --- a/include/libhttp.h +++ b/include/libhttp.h @@ -226,11 +226,13 @@ enum { /* */ /* */ /* struct lh_ctx_t; */ /* struct lh_con_t; */ + /* struct lh_ip_t; */ /* */ /* Hidden structures used by the library to store context and connection information */ /* */ struct lh_ctx_t; /* Handle for an HTTP context */ struct lh_con_t; /* Handle for an individual connection */ +struct lh_ip_t; /* Handle for an IPv4/IPv6 ip address */ /* */ /************************************************************************************************/ @@ -322,10 +324,11 @@ struct lh_slp_t { /* */ }; /* */ /************************************************************************************************/ +/* + * This structure contains callback functions for handling form fields. + * It is used as an argument to httplib_handle_form_request. + */ - -/* This structure contains callback functions for handling form fields. - It is used as an argument to httplib_handle_form_request. */ struct httplib_form_data_handler { int (*field_found)( const char *key, const char *filename, char *path, size_t pathlen, void *user_data ); int (*field_get)( const char *key, const char *value, size_t valuelen, void *user_data ); @@ -453,6 +456,10 @@ LIBHTTP_API int httplib_websocket_client_write( struct lh_ctx_t *ctx, struct LIBHTTP_API int httplib_websocket_write( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int opcode, const char *data, size_t data_len ); LIBHTTP_API int httplib_write( const struct lh_ctx_t *ctx, struct lh_con_t * conn, const void *buf, size_t len ); +LIBHTTP_API char * lh_ipt_to_up( const struct lh_ip_t *in, char *buffwe, size_t buflen, bool compress, bool hybrid ); +LIBHTTP_API char * lh_ipt_to_ip4( const struct lh_ip_t *in, char *buffer, size_t buflen, bool hybrid ); +LIBHTTP_API char * lh_ipt_to_ip6( const struct lh_ip_t *in, char *buffer, size_t buflen, bool compress ); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/httplib_addenv.c b/src/httplib_addenv.c index 6f34f06e..427e3437 100644 --- a/src/httplib_addenv.c +++ b/src/httplib_addenv.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" /* diff --git a/src/httplib_check_authorization.c b/src/httplib_check_authorization.c index 870088b6..c3a72a8d 100644 --- a/src/httplib_check_authorization.c +++ b/src/httplib_check_authorization.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* Return 1 if request is authorised, 0 otherwise. */ bool XX_httplib_check_authorization( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *path ) { diff --git a/src/httplib_connect_client.c b/src/httplib_connect_client.c index 4c602d02..1464ae9e 100644 --- a/src/httplib_connect_client.c +++ b/src/httplib_connect_client.c @@ -28,7 +28,6 @@ #include "httplib_main.h" #include "httplib_pthread.h" #include "httplib_ssl.h" -#include "httplib_string.h" static struct lh_con_t * httplib_connect_client_impl( struct lh_ctx_t *ctx, const struct httplib_client_options *client_options, int use_ssl ); diff --git a/src/httplib_connect_socket.c b/src/httplib_connect_socket.c index 78397974..d8fae36e 100644 --- a/src/httplib_connect_socket.c +++ b/src/httplib_connect_socket.c @@ -27,7 +27,6 @@ #include "httplib_main.h" #include "httplib_ssl.h" -#include "httplib_string.h" #include "httplib_utils.h" /* diff --git a/src/httplib_connect_websocket_client.c b/src/httplib_connect_websocket_client.c index 16d4ab11..f0e13bdf 100644 --- a/src/httplib_connect_websocket_client.c +++ b/src/httplib_connect_websocket_client.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * struct lh_con_t *httplib_connect_websocket_client(); diff --git a/src/httplib_construct_etag.c b/src/httplib_construct_etag.c index e560e37e..be6a9e73 100644 --- a/src/httplib_construct_etag.c +++ b/src/httplib_construct_etag.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_construct_etag( struct lh_ctx_t *ctx, char *buf, size_t buf_len, const struct file *filep ); diff --git a/src/httplib_dir_scan_callback.c b/src/httplib_dir_scan_callback.c index 5ac19f2a..b1a0b98f 100644 --- a/src/httplib_dir_scan_callback.c +++ b/src/httplib_dir_scan_callback.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" void XX_httplib_dir_scan_callback( struct lh_ctx_t *ctx, struct de *de, void *data ) { diff --git a/src/httplib_download.c b/src/httplib_download.c index b45a7a47..fcb0738d 100644 --- a/src/httplib_download.c +++ b/src/httplib_download.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * struct lh_con_t *httplib_download(); diff --git a/src/httplib_get_cookie.c b/src/httplib_get_cookie.c index 58e9172d..4c7774a9 100644 --- a/src/httplib_get_cookie.c +++ b/src/httplib_get_cookie.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * HCP24: some changes to compare hole var_name diff --git a/src/httplib_get_response.c b/src/httplib_get_response.c index f1f98a1e..11a38d00 100644 --- a/src/httplib_get_response.c +++ b/src/httplib_get_response.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * int httplib_get_response( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int timeout ); diff --git a/src/httplib_get_system_name.c b/src/httplib_get_system_name.c index 94586d51..9891837f 100644 --- a/src/httplib_get_system_name.c +++ b/src/httplib_get_system_name.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_get_system_name( char **sysName ); diff --git a/src/httplib_getreq.c b/src/httplib_getreq.c index 5b5eca03..6bec8381 100644 --- a/src/httplib_getreq.c +++ b/src/httplib_getreq.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * bool XX_httplib_getreq( struct lh_ctx_t *ctx, struct lh_con_t *conn, int *err ); diff --git a/src/httplib_gmt_time_string.c b/src/httplib_gmt_time_string.c index c9093077..acc63bd1 100644 --- a/src/httplib_gmt_time_string.c +++ b/src/httplib_gmt_time_string.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" /* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be diff --git a/src/httplib_handle_cgi_request.c b/src/httplib_handle_cgi_request.c index e4038740..aeb7af54 100644 --- a/src/httplib_handle_cgi_request.c +++ b/src/httplib_handle_cgi_request.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_handle_cgi_request( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *prog ); diff --git a/src/httplib_handle_propfind.c b/src/httplib_handle_propfind.c index ce1cf03d..bc4706a3 100644 --- a/src/httplib_handle_propfind.c +++ b/src/httplib_handle_propfind.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" /* diff --git a/src/httplib_handle_static_file_request.c b/src/httplib_handle_static_file_request.c index 22562bd1..ced15e5e 100644 --- a/src/httplib_handle_static_file_request.c +++ b/src/httplib_handle_static_file_request.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" /* diff --git a/src/httplib_interpret_uri.c b/src/httplib_interpret_uri.c index 460e0f5f..79833601 100644 --- a/src/httplib_interpret_uri.c +++ b/src/httplib_interpret_uri.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_interpret_uri(); diff --git a/src/httplib_is_websocket_protocol.c b/src/httplib_is_websocket_protocol.c index 9a38a753..3c7ad861 100644 --- a/src/httplib_is_websocket_protocol.c +++ b/src/httplib_is_websocket_protocol.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * int XX_httplib_is_websocket_protocol( const struct lh_con_t *conn ); diff --git a/src/httplib_log_access.c b/src/httplib_log_access.c index 46cc4df7..23f9bf32 100644 --- a/src/httplib_log_access.c +++ b/src/httplib_log_access.c @@ -27,7 +27,6 @@ #include "httplib_main.h" #include "httplib_ssl.h" -#include "httplib_string.h" static const char *header_val( const struct lh_con_t *conn, const char *header ); diff --git a/src/httplib_main.h b/src/httplib_main.h index 4ec64bda..4c4cb819 100644 --- a/src/httplib_main.h +++ b/src/httplib_main.h @@ -614,34 +614,49 @@ struct lh_ctx_t { * struct lh_con_t; */ - /****************************************************************************************/ -struct lh_con_t { /* */ - struct lh_rqi_t request_info; /* The request info of the connection */ - SSL * ssl; /* SSL descriptor */ - SSL_CTX * client_ssl_ctx; /* SSL context for client connections */ - struct socket client; /* Connected client */ - time_t conn_birth_time; /* Time (wall clock) when connection was established */ - struct timespec req_time; /* Time (since system start) when the request was received */ - int64_t num_bytes_sent; /* Total bytes sent to client */ - int64_t content_len; /* Content-Length header value */ - int64_t consumed_content; /* How many bytes of content have been read */ - int is_chunked; /* Transfer-Encoding is chunked: 0=no, 1=yes: data available, 2: all data read */ - size_t chunk_remainder; /* Unread data from the last chunk */ - char * buf; /* Buffer for received data */ - char * path_info; /* PATH_INFO part of the URL */ - bool must_close; /* true, if connection must be closed */ - bool in_error_handler; /* true, if in handler for user defined error pages */ - int buf_size; /* Buffer size */ - int request_len; /* Size of the request + headers in a buffer */ - int data_len; /* Total size of data in a buffer */ - int status_code; /* HTTP reply status code, e.g. 200 */ - time_t last_throttle_time; /* Last time throttled data was sent */ - int64_t throttle; /* Throttling, bytes/sec. <= 0 means no throttle */ - int64_t last_throttle_bytes; /* Bytes sent this second */ - pthread_mutex_t mutex; /* Used by httplib_(un)lock_connection to ensure atomic transmissions for websockets */ - int thread_index; /* Thread index within ctx */ -}; /* */ - /****************************************************************************************/ + /************************************************************************************************/ +struct lh_con_t { /* */ + struct lh_rqi_t request_info; /* The request info of the connection */ + SSL * ssl; /* SSL descriptor */ + SSL_CTX * client_ssl_ctx; /* SSL context for client connections */ + struct socket client; /* Connected client */ + time_t conn_birth_time; /* Time (wall clock) when connection was established */ + struct timespec req_time; /* Time (since system start) when the request was received */ + int64_t num_bytes_sent; /* Total bytes sent to client */ + int64_t content_len; /* Content-Length header value */ + int64_t consumed_content; /* How many bytes of content have been read */ + int is_chunked; /* Transfer-Encoding is chunked: 0=no, 1=yes: data available, 2: all data read */ + size_t chunk_remainder; /* Unread data from the last chunk */ + char * buf; /* Buffer for received data */ + char * path_info; /* PATH_INFO part of the URL */ + bool must_close; /* true, if connection must be closed */ + bool in_error_handler; /* true, if in handler for user defined error pages */ + int buf_size; /* Buffer size */ + int request_len; /* Size of the request + headers in a buffer */ + int data_len; /* Total size of data in a buffer */ + int status_code; /* HTTP reply status code, e.g. 200 */ + time_t last_throttle_time; /* Last time throttled data was sent */ + int64_t throttle; /* Throttling, bytes/sec. <= 0 means no throttle */ + int64_t last_throttle_bytes; /* Bytes sent this second */ + pthread_mutex_t mutex; /* Used by httplib_(un)lock_connection to ensure atomic transmissions for websockets */ + int thread_index; /* Thread index within ctx */ +}; /* */ + /************************************************************************************************/ + + /************************************************************************************************/ + /* */ + /* struct lh_ip_t; */ + /* */ + /* LibHTTP allows both IPv4 and IPv6 communication. The code base doesn't make any difference */ + /* between the two by encoding internally both address variations as a structure with two */ + /* 64 bit values. IPv6 values will fit in this structure perfectly as they need 128 bits, while */ + /* IPv4 addresses are stored as ::FFFF:0:0/96 addresses which is the official dual stack way */ + /* of representing IPv4 addresses in IPv6 address space. */ +struct lh_ip_t { /* */ + uint64_t high_quad; /* The high order 64 bits of an IP address */ + uint64_t low_quad; /* The low order 64 bits of an IP address */ +}; /* */ + /************************************************************************************************/ struct worker_thread_args { struct lh_ctx_t * ctx; @@ -902,12 +917,15 @@ bool XX_httplib_should_decode_url( const struct lh_ctx_t *ctx ); bool XX_httplib_should_keep_alive( const struct lh_ctx_t *ctx, const struct lh_con_t *conn ); char * XX_httplib_skip( char **buf, const char *delimiters ); char * XX_httplib_skip_quoted( char **buf, const char *delimiters, const char *whitespace, char quotechar ); +void XX_httplib_snprintf( struct lh_ctx_t *ctx, const struct lh_con_t *conn, bool *truncated, char *buf, size_t buflen, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(6, 7); void XX_httplib_sockaddr_to_string(char *buf, size_t len, const union usa *usa ); pid_t XX_httplib_spawn_process( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir ); int XX_httplib_start_thread_with_id( httplib_thread_func_t func, void *param, pthread_t *threadidptr ); int XX_httplib_stat( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *path, struct file *filep ); int XX_httplib_substitute_index_file( struct lh_ctx_t *ctx, struct lh_con_t *conn, char *path, size_t path_len, struct file *filep ); const char * XX_httplib_suggest_connection_header( const struct lh_ctx_t *ctx, const struct lh_con_t *conn ); +int XX_httplib_vprintf( const struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *fmt, va_list ap ); +void XX_httplib_vsnprintf( struct lh_ctx_t *ctx, const struct lh_con_t *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, va_list ap ); LIBHTTP_THREAD XX_httplib_websocket_client_thread( void *data ); int XX_httplib_websocket_write_exec( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int opcode, const char *data, size_t dataLen, uint32_t masking_key ); LIBHTTP_THREAD XX_httplib_worker_thread( void *thread_func_param ); diff --git a/src/httplib_open_auth_file.c b/src/httplib_open_auth_file.c index 07035eaf..6dfc2b41 100644 --- a/src/httplib_open_auth_file.c +++ b/src/httplib_open_auth_file.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * Use the global passwords file, if specified by auth_gpass option, diff --git a/src/httplib_parse_auth_header.c b/src/httplib_parse_auth_header.c index 979a8300..517aa4d4 100644 --- a/src/httplib_parse_auth_header.c +++ b/src/httplib_parse_auth_header.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * Return 1 on success. Always initializes the ah structure. diff --git a/src/httplib_path_to_unicode.c b/src/httplib_path_to_unicode.c index f77c61e3..cc5c88bf 100644 --- a/src/httplib_path_to_unicode.c +++ b/src/httplib_path_to_unicode.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #if defined(_WIN32) diff --git a/src/httplib_prepare_cgi_environment.c b/src/httplib_prepare_cgi_environment.c index f1db4f69..f2d9d296 100644 --- a/src/httplib_prepare_cgi_environment.c +++ b/src/httplib_prepare_cgi_environment.c @@ -27,7 +27,6 @@ #include "httplib_main.h" #include "httplib_ssl.h" -#include "httplib_string.h" #include "httplib_utils.h" /* diff --git a/src/httplib_print_dir_entry.c b/src/httplib_print_dir_entry.c index 1f64885b..4492c59a 100644 --- a/src/httplib_print_dir_entry.c +++ b/src/httplib_print_dir_entry.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" void XX_httplib_print_dir_entry( struct lh_ctx_t *ctx, struct de *de ) { diff --git a/src/httplib_printf.c b/src/httplib_printf.c index 086920eb..34feeaf5 100644 --- a/src/httplib_printf.c +++ b/src/httplib_printf.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" int httplib_printf( const struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *fmt, ... ) { diff --git a/src/httplib_process_new_connection.c b/src/httplib_process_new_connection.c index 1716fdc9..ce9ff2a3 100644 --- a/src/httplib_process_new_connection.c +++ b/src/httplib_process_new_connection.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_process_new_connection( struct lh_ctx_t *ctx, struct lh_con_t *conn ); diff --git a/src/httplib_redirect_to_https_port.c b/src/httplib_redirect_to_https_port.c index a5d9e65b..68e2862c 100644 --- a/src/httplib_redirect_to_https_port.c +++ b/src/httplib_redirect_to_https_port.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_redirect_to_https_port( const struct lh_ctx_t *ctx, struct lh_con_t *conn, int ssl_index ); diff --git a/src/httplib_remove_directory.c b/src/httplib_remove_directory.c index 75dd325b..37fda3da 100644 --- a/src/httplib_remove_directory.c +++ b/src/httplib_remove_directory.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * int XX_httplib_remove_directory( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *dir ); diff --git a/src/httplib_scan_directory.c b/src/httplib_scan_directory.c index 8a41a40d..322b2f1d 100644 --- a/src/httplib_scan_directory.c +++ b/src/httplib_scan_directory.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" int XX_httplib_scan_directory( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *dir, void *data, void (*cb)(struct lh_ctx_t *ctx, struct de *, void *) ) { diff --git a/src/httplib_send_http_error.c b/src/httplib_send_http_error.c index 1e41e5a3..16a3a4eb 100644 --- a/src/httplib_send_http_error.c +++ b/src/httplib_send_http_error.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" void XX_httplib_send_http_error( struct lh_ctx_t *ctx, struct lh_con_t *conn, int status, const char *fmt, ... ) { diff --git a/src/httplib_send_websocket_handshake.c b/src/httplib_send_websocket_handshake.c index 3cd78d98..a47a3ebf 100644 --- a/src/httplib_send_websocket_handshake.c +++ b/src/httplib_send_websocket_handshake.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" #define B64_SHA_LEN (sizeof(sha)*2) diff --git a/src/httplib_set_handler_type.c b/src/httplib_set_handler_type.c index 82fcde1c..eebc1edf 100644 --- a/src/httplib_set_handler_type.c +++ b/src/httplib_set_handler_type.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_set_handler_type(); diff --git a/src/httplib_set_thread_name.c b/src/httplib_set_thread_name.c index b520d2ab..d286dc7e 100644 --- a/src/httplib_set_thread_name.c +++ b/src/httplib_set_thread_name.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #if !defined(NO_THREAD_NAME) diff --git a/src/httplib_snprintf.c b/src/httplib_snprintf.c index f1ff5afc..7f54a825 100644 --- a/src/httplib_snprintf.c +++ b/src/httplib_snprintf.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * void XX_httplib_snprintf( struct lh_ctx_t *ctx, const struct lh_con_t *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, ... ); diff --git a/src/httplib_spawn_process.c b/src/httplib_spawn_process.c index 995e7660..453c8438 100644 --- a/src/httplib_spawn_process.c +++ b/src/httplib_spawn_process.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #if defined(_WIN32) diff --git a/src/httplib_ssi.c b/src/httplib_ssi.c index ce03b031..6a3483af 100644 --- a/src/httplib_ssi.c +++ b/src/httplib_ssi.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" #include "httplib_utils.h" static void send_ssi_file( struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *, struct file *, int ); diff --git a/src/httplib_ssl_get_client_cert_info.c b/src/httplib_ssl_get_client_cert_info.c index aa5ca151..ea5f7cbd 100644 --- a/src/httplib_ssl_get_client_cert_info.c +++ b/src/httplib_ssl_get_client_cert_info.c @@ -27,7 +27,6 @@ #include "httplib_main.h" #include "httplib_ssl.h" -#include "httplib_string.h" #if !defined(NO_SSL) diff --git a/src/httplib_start.c b/src/httplib_start.c index 2f33b6fb..9d4c0484 100644 --- a/src/httplib_start.c +++ b/src/httplib_start.c @@ -28,7 +28,6 @@ #include "httplib_main.h" #include "httplib_pthread.h" #include "httplib_ssl.h" -#include "httplib_string.h" #include "httplib_utils.h" /* diff --git a/src/httplib_strcasestr.c b/src/httplib_strcasestr.c index 4bcc2a72..ded4e9c6 100644 --- a/src/httplib_strcasestr.c +++ b/src/httplib_strcasestr.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * const char *httplib_strcasestr( const char *big_str, const char *small_str ); diff --git a/src/httplib_string.h b/src/httplib_string.h deleted file mode 100644 index 4d5abf1d..00000000 --- a/src/httplib_string.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2016 Lammert Bies - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - -void XX_httplib_snprintf( struct lh_ctx_t *ctx, const struct lh_con_t *conn, bool *truncated, char *buf, size_t buflen, PRINTF_FORMAT_STRING(const char *fmt), ... ) PRINTF_ARGS(6, 7); -int XX_httplib_vprintf( const struct lh_ctx_t *ctx, struct lh_con_t *conn, const char *fmt, va_list ap ); -void XX_httplib_vsnprintf( struct lh_ctx_t *ctx, const struct lh_con_t *conn, bool *truncated, char *buf, size_t buflen, const char *fmt, va_list ap ); diff --git a/src/httplib_substitute_index_file.c b/src/httplib_substitute_index_file.c index ceed4e34..59fa4151 100644 --- a/src/httplib_substitute_index_file.c +++ b/src/httplib_substitute_index_file.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * bool XX_httplib_substitute_index_file( struct lh_ctx_t *ctx, struct lh_con_t *conn, char *path, size_t path_len, struct file *filep ); diff --git a/src/httplib_vprintf.c b/src/httplib_vprintf.c index 721c7750..18b2b6f6 100644 --- a/src/httplib_vprintf.c +++ b/src/httplib_vprintf.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * Alternative alloc_vprintf() for non-compliant C runtimes diff --git a/src/httplib_vsnprintf.c b/src/httplib_vsnprintf.c index a2be9a47..0afdca8e 100644 --- a/src/httplib_vsnprintf.c +++ b/src/httplib_vsnprintf.c @@ -26,7 +26,6 @@ */ #include "httplib_main.h" -#include "httplib_string.h" /* * Return null terminated string of given maximum length. @@ -60,7 +59,7 @@ void XX_httplib_vsnprintf( struct lh_ctx_t *ctx, const struct lh_con_t *conn, bo else { if ( truncated != NULL ) *truncated = true; - if ( ctx != NULL && conn != NULL) httplib_cry( LH_DEBUG_WARNING, ctx, conn, "%s: truncating vsnprintf buffer: [%.*s]", __func__, (int)((buflen > 200) ? 200 : (buflen - 1)), buf ); + if ( ctx != NULL && conn != NULL ) httplib_cry( LH_DEBUG_WARNING, ctx, conn, "%s: truncating vsnprintf buffer: [%.*s]", __func__, (int)((buflen > 200) ? 200 : (buflen - 1)), buf ); n = (int)buflen - 1; } buf[n] = '\0'; diff --git a/src/lh_ip_to_ipt.c b/src/lh_ip_to_ipt.c new file mode 100644 index 00000000..d3f9a369 --- /dev/null +++ b/src/lh_ip_to_ipt.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2016 Lammert Bies + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "httplib_main.h" + +/* + * struct lh_ip_t *lh_ip_to_ipt( const char *in, struct lh_ip_t *out ); + * + * The function lh_ip_to_ipt() converts a character representation of an IP + * address to an lh_ip_t structure. If the conversion succeeds, the function + * returns a pointer to the storage location of the IP address. Otherwise NULL + * is returned. The calling routine should provide the storage location for the + * IP address. + * + * The function is capable of converting both IPv4 and IPv6 addresses in + * in compressed and hybrid notation. + */ + +LIBHTTP_API char *lh_ip_to_ipt( const char *in, struct lh_ip_t *out ) { + + int block; + int num_colon; + bool bracket; + bool has_dots; + bool has_colons; + bool is_ipv4; + bool dig[4]; + unsigned int val[8]; + const char *p_src; + + if ( in == NULL || out == NULL ) return NULL; + + p_src = in; + while ( *p_src != '\0' ) { + + if ( ! isdigit( *p_src ) && *p_src != '.' ) break; + p_src++; + } + + is_ipv4 = (*p_src == '\0'); + + /* + * We found characters which do not belong in a pure IPv4 address. This + * could be a hybrid address. Let's check if that is the case. In a + * hybrid address both dots and colons are present. We do not check for + * full validity yet. + */ + + if ( ! is_ipv4 ) { + + has_dots = false; + has_colons = false; + + p_src = in; + while ( *p_src != '\0' ) { + + if ( *p_src == ':' ) has_colons = true; + if ( *p_src == '.' ) has_dots = true; + + p_src++; + } + +##### + } + + + + /* + * It is a valid IPv4 address. Let's convert it! + */ + + if ( is_ipv4 ) { + + p_src = in; + block = 0; + val[0] = 0; + val[1] = 0; + val[2] = 0; + val[3] = 0; + dig[0] = false; + dig[1] = false; + dig[2] = false; + dig[3] = false; + + while ( *p_src != '\0' && block < 4 ) { + + if ( *p_src == '.' ) block++; + else { dig[block] = true; val[block] *= 10; val[block] += *p_scr - '0'; } + + p_src++; + } + + if ( block == 3 && val[0] <= 255 && val[1] <= 255 && val[2] <= 255 && val[3] < 255 && + dig[0] && dig[1] && dig[2] && dig[3] ) { + + out->high_quad = 0x0000000000000000ull; + out->low_quad = ((uint64_t)val[0] << 24) | ((uint64_t)val[1] << 16) | ((uint64_t)val[2] << 8) | ((uint64_t)val[3]) | + 0x0000FFFF00000000ull; + + return out; + } + + return NULL; + } + + /* + * The string is neither hybrid, nor pure IPv6. The only option left is + * a pure IPv6 address. Let's start the conversion! + */ + + val[0] = 0; + val[1] = 0; + val[2] = 0; + val[3] = 0; + val[4] = 0; + val[5] = 0; + val[6] = 0; + val[7] = 0; + num_colon = 0; + p_src = in; + + /* + * Bracketed IP addresses are used in cases where a port may be + * specified. We skip the first bracket, and must check that an end + * bracket exists. + */ + + if ( *p_src = '[' ) { bracket = true; p_src++; } + else bracket = false; + + /* + * Loop through all the characters of the IPv6 address. + */ + + while ( *p_src != '\0' && num_colon < 8 ) { + + /* + * Check each recognized character and perform an action on it. + * Then continue the loop with the next character, or end the + * loop if a closing bracket has been found. + */ + + if ( *p_src == ']' ) { if ( bracket ) { bracket = false; p_src++; } break; } + if ( *p_src == ':' ) { num_colon++; p_src++; continue; } + if ( isdigit( *p_src ) ) { val[num_colon] *= 16; val[num_colon] += *p_src-'0'; p_src++; continue; } + if ( *p_src >= 'A' && *p_src <= 'F' ) { val[num_colon] *= 16; val[num_colon] += *p_src-'A'+10; p_src++; continue; } + if ( *p_src >= 'a' && *p_src <= 'f' ) { val[num_colon] *= 16; val[num_colon] += *p_src-'a'+10; p_src++; continue; } + + /* + * We found a character which cannot be part of an IPv6 + * address. No need to search further. Just tell the calling + * application that the conversion could not take place. + */ + + return NULL; + } + + /* + * The IP address is invalid. Let's tell it the application. + */ + + if ( *p_src != '\0' || num_colon >= 8 || bracket ) return NULL; + + /* + * We counted less than 7 colons. Somewhere should be a double colon + * which must be expanded. Let's search for it. If we find more than + * one double colon, the address is invalid and we return NULL to the + * application to tell them. + */ + + if ( num_colon < 7 ) { + + num_colon = 0; + double_loc = -1; + p_src = in; + + while ( *p_src ) { + + if ( *p_src == ':' ) { + + if ( *(p_src+1) == ':' ) { + + if ( double_loc >= 0 ) return NULL; + double_loc = num_colon; + } + + num_colon++; + } + + p_src++; + } + + if ( double_loc < 0 ) return NULL; + + stap = 7-num_colon; + + for (a=7; a>8-num_colon+double_loc; a--) val[a] = val[a-step]; + for (a=0; a<8-num_colon; a++) val[a+double_loc+1] = 0; + + if ( val[0] <= 0xFFFFu && val[1] <= 0xFFFFu && val[2] <= 0xFFFFu && val[3] <= 0xFFFFu && + val[4] <= 0xFFFFu && val[5] <= 0xFFFFu && val[6] <= 0xFFFFu && val[7] <= 0xFFFFu ) { + + out->high_quad = ((uint64_t)val[0] << 48) | ((uint64_t)val[1] << 32) | ((uint64_t)val[2] << 16) | ((uint64_t)val[3]); + out->low_quad = ((uint64_t)val[4] << 48) | ((uint64_t)val[5] << 32) | ((uint64_t)val[6] << 16) | ((uint64_t)val[7]); + + return out; + } + + return NULL; + } + + return NULL; + +} /* lh_ipt_to_ip4 */ diff --git a/src/lh_ipt_to_ip.c b/src/lh_ipt_to_ip.c new file mode 100644 index 00000000..f9647e27 --- /dev/null +++ b/src/lh_ipt_to_ip.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016 Lammert Bies + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "httplib_main.h" + +/* + * char *lh_ipt_to_ip( const struct lh_ip_t *in, char *buffer, size_t buflen ) + * + * The function lh_ipt_to_ip() converts an IP address encoded in a lh_ip_t + * structure to a string representation. This can either be an IPv4 or IPv6 + * address, depending on the value of the IP address. Compression of IPv6 + * addresses is controlled with a parameter and another parameter selects if + * plain IPv4 or hybrid IPv4 notation must be returned if the address is an + * IPv4 address. + * + * If an error occurs, NULL is returned, otherwise a string containing + * the IP address. The caller must supply a buffer which is large enough to + * hold the resulting string and the NUL terminator character. + * + * In hybrid notation, the IP address is returned as ::ffff:aaa.bbb.ccc.ddd + */ + +LIBHTTP_API char *lh_ipt_to_ip( const struct lh_ip_t *in, char *buffer, size_t buflen, bool compress, bool hybrid ) { + + bool ipv4; + + if ( in == NULL || buffer == NULL || buflen < 1 ) return NULL; + + ipv4 = ( ( in->high_quad == 0x0000000000000000ull ) && + ( (in->low_quad & 0xFFFFFFFF00000000ull) == 0x0000FFFF00000000ull ) ); + + if ( ipv4 ) return lh_ipt_to_ip4( in, buffer, buflen, hybrid ); + else return lh_ipt_to_ip6( in, buffer, buflen, compress ); + +} /* lh_ipt_to_ip */ diff --git a/src/lh_ipt_to_ip4.c b/src/lh_ipt_to_ip4.c new file mode 100644 index 00000000..87ff7696 --- /dev/null +++ b/src/lh_ipt_to_ip4.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Lammert Bies + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "httplib_main.h" + +/* + * char *lh_ipt_to_ip4( const struct lh_ip_t *in, char *buffer, size_t buflen, bool hybrid ); + * + * The function lh_ipt_to_ip4() converts an IP address encoded in a lh_ip_t + * structure to an IPv4 address. The address must be encoded in ::FFFF:0:0/96 + * format. If an error occurs, NULL is returned, otherwise a string containing + * the IP address. The caller must supply a buffer which is large enough to + * hold the resulting string and the NUL terminator character. + * + * In hybrid notation, the IP address is returned as ::ffff:aaa.bbb.ccc.ddd + */ + +LIBHTTP_API char *lh_ipt_to_ip4( const struct lh_ip_t *in, char *buffer, size_t buflen, bool hybrid ) { + + bool truncated; + + if ( in == NULL || buffer == NULL || buflen < 1 ) return NULL; + if ( in->high_quad != 0x0000000000000000ull ) return NULL; + if ( (in->low_quad & 0xFFFFFFFF00000000ull) != 0x0000FFFF00000000ull ) return NULL; + + + if ( hybrid ) XX_httplib_snprintf( NULL, NULL, &truncated, buffer, buflen, "::ffff:%u.%u.%u.%u" + , (unsigned int) ((in->low_quad >> 24) & 0xFFu) + , (unsigned int) ((in->low_quad >> 16) & 0xFFu) + , (unsigned int) ((in->low_quad >> 8) & 0xFFu) + , (unsigned int) ((in->low_quad ) & 0xFFu) ); + + else XX_httplib_snprintf( NULL, NULL, &truncated, buffer, buflen, "%u.%u.%u.%u" + , (unsigned int) ((in->low_quad >> 24) & 0xFFu) + , (unsigned int) ((in->low_quad >> 16) & 0xFFu) + , (unsigned int) ((in->low_quad >> 8) & 0xFFu) + , (unsigned int) ((in->low_quad ) & 0xFFu) ); + + if ( truncated ) return NULL; + + return buffer; + +} /* lh_ipt_to_ip4 */ diff --git a/src/lh_ipt_to_ip6.c b/src/lh_ipt_to_ip6.c new file mode 100644 index 00000000..a849599d --- /dev/null +++ b/src/lh_ipt_to_ip6.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 Lammert Bies + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "httplib_main.h" + +#define BUFLEN 64 + +/* + * char *lh_ipt_to_ip6( const struct lh_ip_t *in, char *buffer, size_t buflen, bool compress ); + * + * The function lh_ipt_to_ip6() converts an IP address encoded in a lh_ip_t + * structure to an IPv6 address. The function can generate both a version with + * all zeros, and a compressed version where the maximum possible amount of + * zero values has been eliminated. If an error occurs, NULL is returned, + * otherwise a pointer to the string representation of the address. The caller + * must provide a buffer large enough to store the resulting string and the + * NUL terminator. + */ + +LIBHTTP_API char *lh_ipt_to_ip6( const struct lh_ip_t *in, char *buffer, size_t buflen, bool compress ) { + + int a; + int cur_loc; + int max_loc; + int max_val; + int count; + int num_zeroblock; + int zero_block[8]; + bool truncated; + char temp[BUFLEN]; + char *p_src; + char *p_dst; + + if ( in == NULL || buffer == NULL || buflen < 1 ) return NULL; + + if ( ! compress ) { + + if ( buflen < 40 ) return NULL; + + XX_httplib_snprintf( NULL, NULL, &truncated, buffer, buflen, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" + , (unsigned int) ((in->high_quad >> 48) & 0xFFFFu) + , (unsigned int) ((in->high_quad >> 32) & 0xFFFFu) + , (unsigned int) ((in->high_quad >> 16) & 0xFFFFu) + , (unsigned int) ((in->high_quad ) & 0xFFFFu) + , (unsigned int) ((in->low_quad >> 48) & 0xFFFFu) + , (unsigned int) ((in->low_quad >> 32) & 0xFFFFu) + , (unsigned int) ((in->low_quad >> 16) & 0xFFFFu) + , (unsigned int) ((in->low_quad ) & 0xFFFFu) ); + + if ( truncated ) return NULL; + + return buffer; + } + + /* + * First fill the string with an uncompressed version of the IP + * address. We already skip leading zeros by using %x instead of %04x. + */ + + XX_httplib_snprintf( NULL, NULL, NULL, buffer, buflen, "%x:%x:%x:%x:%x:%x:%x:%x" + , (unsigned int) ((in->high_quad >> 48) & 0xFFFFu) + , (unsigned int) ((in->high_quad >> 32) & 0xFFFFu) + , (unsigned int) ((in->high_quad >> 16) & 0xFFFFu) + , (unsigned int) ((in->high_quad ) & 0xFFFFu) + , (unsigned int) ((in->low_quad >> 48) & 0xFFFFu) + , (unsigned int) ((in->low_quad >> 32) & 0xFFFFu) + , (unsigned int) ((in->low_quad >> 16) & 0xFFFFu) + , (unsigned int) ((in->low_quad ) & 0xFFFFu) ); + + for (a=0; a<8; a++) zero_block[a] = 1; + + p_src = temp; + count = 0; + num_zeroblock = 8; + + while ( *p_src != '\0' && count < 8 ) { + + /* + * Search within the eight blocks and mark those blocks which + * contain a nonzero digit. We are not able to reduce those + * further and we therefore mark them as non-zero. + */ + + if ( *p_src == ':' ) { count++; p_src++; continue; } + if ( *p_src != '0' && zero_block[count] ) { zero_block[count] = 0; num_zeroblock--; p_src++; continue; } + + p_src++; + } + + /* + * None of the blocks contains the value zero. Further compression is + * not possible and we can jump to the end of the function to provide + * the caller the string representation of the IP address. + */ + + if ( num_zeroblock == 0 ) goto end; + + /* + * The elements of zero_block[] initially contain the value 1 if the + * block contains value 0, and 0 otherwise. We now combine the counters + * where the zero_block element of a first zero element contains the + * count of sequential blocks which are zero. The counters of other + * elements in the same sequence are set to zero. + */ + + for (a=6; a>=0; a--) { if ( zero_block[a] > 0 && zero_block[a+1] > 0 ) { zero_block[a] += zero_block[a+1]; zero_block[a+1] = 0; } } + + /* + * Now search the largest sequence of zero blocks. There may be more + * than one sequence of zero blocks in an IPv6 address but we can only + * convert one to '::'. We want to convert the largest sequence to '..' + * because in that way we can compress the most characters. + */ + + max_loc = 0; + max_val = 0; + + for (a=0; a<8; a++) { if ( zero_block[a] > max_val ) { max_val = zero_block[a]; max_loc = a; } } + + if ( max_val > 0 ) { + + /* + * We have found a location which can be reduced. Let's remove + * all zero's from those blocks. + */ + + cur_loc = 0; + p_src = temp; + p_dst = temp; + count = 0; + + while ( *p_src ) { + + if ( cur_loc >= max_loc && max_val > 0 ) { + + if ( *p_src == '0' ) { p_src++; count++; continue; } + } + + if ( *p_src == ':' ) { + + if ( cur_loc >= max_loc ) max_val--; + cur_loc++; + } + + if ( count > 0 ) *p_dst = *p_src; + + p_src++; + p_dst++; + } + + *p_dst = '\0'; + p_src = temp; + p_dst = temp; + count = 0; + + /* + * Now reduce a possible sequence of more than two colons to ::. + */ + + while ( *p_src ) { + + if ( *p_src == ':' && *(p_src+1) == ':' && *(p_src+2) == ':' ) { p_src++; count++; continue; } + + if ( count > 0 ) *p_dst = *p_src; + + p_src++; + p_dst++; + } + + *p_dst = '\0'; + } + +end: + XX_httplib_snprintf( NULL, NULL, &truncated, buffer, buflen, "%s", temp ); + + if ( truncated ) return NULL; + + return buffer; + +} /* lh_ipt_to_ip6 */