From ab5044b6044d49387a93683111cc97f1c2ea097a Mon Sep 17 00:00:00 2001 From: stefanocasazza Date: Tue, 7 Mar 2017 15:39:12 +0100 Subject: [PATCH] fix --- configure | 48 ++--- include/ulib/base/base.h | 36 +++- include/ulib/internal/csp_interface.h | 1 + include/ulib/internal/memory_pool.h | 2 +- include/ulib/net/client/client.h | 31 +--- include/ulib/net/server/client_image.h | 10 +- include/ulib/net/server/server.h | 4 +- include/ulib/utility/http2.h | 81 +++----- include/ulib/utility/uhttp.h | 46 ++++- m4/ac_compilation_options.m4 | 30 +-- src/ulib/base/utility.c | 173 ++++++++--------- src/ulib/log.cpp | 5 +- src/ulib/net/client/client.cpp | 69 ++++++- src/ulib/net/client/http.cpp | 20 +- src/ulib/net/server/client_image.cpp | 44 ++--- src/ulib/net/server/plugin/mod_http.cpp | 8 +- src/ulib/net/server/plugin/mod_nocat.cpp | 8 +- src/ulib/net/server/server.cpp | 32 ++-- src/ulib/net/socket.cpp | 2 +- src/ulib/utility/http2.cpp | 195 +++++++++++++------ src/ulib/utility/semaphore.cpp | 2 +- src/ulib/utility/uhttp.cpp | 226 ++++++++++++----------- tests/examples/businesses.test | 19 +- tests/examples/ok/businesses.ok | 11 +- tests/examples/web_server.sh | 26 +-- 25 files changed, 640 insertions(+), 489 deletions(-) diff --git a/configure b/configure index d31f4e0d..0dc29c82 100755 --- a/configure +++ b/configure @@ -1037,7 +1037,6 @@ enable_gcc_optimized enable_final enable_new_ldflags enable_CRPWS -enable_check_time enable_captive_portal enable_thread_approach enable_HIS @@ -1046,6 +1045,7 @@ enable_GSDS enable_HCRS enable_HPRS enable_http2 +enable_check_time enable_classic enable_throttling enable_alias @@ -1780,7 +1780,6 @@ Optional Features: --enable-final build size optimized apps (needs more amounts of memory) [default=yes] --enable-new-ldflags enable the new linker flags (enable-new-dtags,as-needed,...) [default=yes] --enable-CRPWS enable Client Response Partial Write Support [default=no] - --enable-check-time enable server check time between request for parallelization [default=no] --enable-captive-portal enable server captive portal mode [default=no] --enable-thread-approach enable server thread approach support [default=no] --enable-HIS enable HTTP Inotify Support [default=no] @@ -1789,6 +1788,7 @@ Optional Features: --enable-HCRS enable Cache Request Support [default=no] --enable-HPRS enable Homogeneous Pipeline Request Support [default=no] --enable-http2 enable HTTP/2 support [default=no] + --enable-check-time enable server check time between request for parallelization [default=no] --enable-classic enable server classic model support [default=no] --enable-throttling enable server bandwidth throttling support [default=no] --enable-alias enable alias URI support [default=yes] @@ -26257,28 +26257,6 @@ $as_echo "#define U_CLIENT_RESPONSE_PARTIAL_WRITE_SUPPORT 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_CRPWS" >&5 $as_echo "$enable_CRPWS" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if you want to enable server check time between request for parallelization" >&5 -$as_echo_n "checking if you want to enable server check time between request for parallelization... " >&6; } - # Check whether --enable-check-time was given. -if test "${enable_check_time+set}" = set; then : - enableval=$enable_check_time; -fi - - if test -z "$enable_check_time"; then - if test "$enable_debug" = "yes"; then - enable_check_time="yes" - else - enable_check_time="no" - fi - fi - if test "$enable_check_time" = "yes"; then - -$as_echo "#define U_SERVER_CHECK_TIME_BETWEEN_REQUEST 1" >>confdefs.h - - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_check_time" >&5 -$as_echo "$enable_check_time" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if you want to enable server captive portal mode" >&5 $as_echo_n "checking if you want to enable server captive portal mode... " >&6; } # Check whether --enable-captive-portal was given. @@ -26443,6 +26421,28 @@ $as_echo "#define U_HTTP2_DISABLE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_http2" >&5 $as_echo "$enable_http2" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if you want to enable server check time between request for parallelization" >&5 +$as_echo_n "checking if you want to enable server check time between request for parallelization... " >&6; } + # Check whether --enable-check-time was given. +if test "${enable_check_time+set}" = set; then : + enableval=$enable_check_time; +fi + + if test -z "$enable_check_time"; then + if test "$enable_debug" = "yes" -a "$enable_http2" != "yes"; then + enable_check_time="yes" + else + enable_check_time="no" + fi + fi + if test "$enable_check_time" = "yes"; then + +$as_echo "#define U_SERVER_CHECK_TIME_BETWEEN_REQUEST 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_check_time" >&5 +$as_echo "$enable_check_time" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if you want to enable server classic model support" >&5 $as_echo_n "checking if you want to enable server classic model support... " >&6; } # Check whether --enable-classic was given. diff --git a/include/ulib/base/base.h b/include/ulib/base/base.h index c0cec3fc..7379fa49 100644 --- a/include/ulib/base/base.h +++ b/include/ulib/base/base.h @@ -67,6 +67,36 @@ /*typedef pthread_cond_t __gthread_cond_t;*/ /*typedef struct timespec __gthread_time_t;*/ # endif +# define U_DO_PRAGMA(x) +# define U_DUMP_KERNEL_VERSION(x) +#elif defined(U_CSP_INTERFACE) +# define U_DO_PRAGMA(x) +# define U_DUMP_KERNEL_VERSION(x) +#else +# define U_DO_PRAGMA(x) _Pragma (#x) +# define U_DUMP_KERNEL_VERSION(x) U_DO_PRAGMA(message (#x " = " U_STRINGIFY(x))) +#endif + +/* Checks define */ +#if defined(USE_LOAD_BALANCE) && defined(_MSWINDOWS_) +# undef USE_LOAD_BALANCE +U_DO_PRAGMA(message (Sorry_I_was_compiled_on_Windows_so_I_cannot_use_load_balance)) +#endif +#if defined(U_THROTTLING_SUPPORT) && !defined(U_HTTP2_DISABLE) +# undef U_THROTTLING_SUPPORT +U_DO_PRAGMA(message (Sorry_I_was_compiled_with_http2_enabled_so_I_cannot_support_bandwidth_throttling)) +#endif +#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && !defined(U_HTTP2_DISABLE) +# undef U_SERVER_CHECK_TIME_BETWEEN_REQUEST +U_DO_PRAGMA(message (Sorry_I_was_compiled_with_http2_enabled_so_I_cannot_support_check_time_between_request)) +#endif +#if !defined(U_CACHE_REQUEST_DISABLE) && !defined(U_HTTP2_DISABLE) +# define U_CACHE_REQUEST_DISABLE +U_DO_PRAGMA(message (Sorry_I_was_compiled_with_http2_enabled_so_I_cannot_support_cache_request)) +#endif +#if defined(U_HTTP_INOTIFY_SUPPORT) && defined(U_SERVER_CAPTIVE_PORTAL) +# undef U_HTTP_INOTIFY_SUPPORT +U_DO_PRAGMA(message (Sorry_I_was_compiled_with_server_captive_portal_mode_enabled_so_I_cannot_support_http_inotify)) #endif #include @@ -87,12 +117,6 @@ #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #endif -#ifdef __clang__ -# define U_DUMP_KERNEL_VERSION(x) -#else -# define U_DO_PRAGMA(x) _Pragma (#x) -# define U_DUMP_KERNEL_VERSION(x) U_DO_PRAGMA(message (#x " = " U_STRINGIFY(x))) -#endif #ifdef USE_LIBZ /* check for crc32 */ # include diff --git a/include/ulib/internal/csp_interface.h b/include/ulib/internal/csp_interface.h index c4b21c4f..dab5a711 100644 --- a/include/ulib/internal/csp_interface.h +++ b/include/ulib/internal/csp_interface.h @@ -6,6 +6,7 @@ typedef _Bool bool; #endif +#define U_CSP_INTERFACE #include #include diff --git a/include/ulib/internal/memory_pool.h b/include/ulib/internal/memory_pool.h index b15f4b83..ff1adebc 100644 --- a/include/ulib/internal/memory_pool.h +++ b/include/ulib/internal/memory_pool.h @@ -521,7 +521,7 @@ public: #endif private: -#if defined(ENABLE_MEMPOOL) && !defined(U_SERVER_CAPTIVE_PORTAL) +#ifdef ENABLE_MEMPOOL static void deallocate(void* ptr, uint32_t length); #else static void deallocate(void* ptr, uint32_t length) diff --git a/include/ulib/net/client/client.h b/include/ulib/net/client/client.h index d90519da..90d24e80 100644 --- a/include/ulib/net/client/client.h +++ b/include/ulib/net/client/client.h @@ -154,31 +154,6 @@ public: void prepareRequest(const UString& req) { request = req; prepareRequest(U_STRING_TO_PARAM(req)); } - void prepareRequest(const UString& header, const UString& body) - { - U_TRACE(0, "UClient_Base::prepareRequest(%V,%V)", header.rep, body.rep) - - if (body.empty()) prepareRequest(header); - else - { - request = header; - - iovcnt = 2; - - iov[0].iov_base = (caddr_t)header.data(); - iov[0].iov_len = header.size(); - iov[1].iov_base = (caddr_t) body.data(); - iov[1].iov_len = body.size(); - - (void) U_SYSCALL(memset, "%p,%d,%u", iov+2, 0, sizeof(struct iovec) * 4); - - U_INTERNAL_ASSERT_EQUALS(iov[2].iov_len, 0) - U_INTERNAL_ASSERT_EQUALS(iov[3].iov_len, 0) - U_INTERNAL_ASSERT_EQUALS(iov[4].iov_len, 0) - U_INTERNAL_ASSERT_EQUALS(iov[5].iov_len, 0) - } - } - // LOG static void closeLog(); @@ -272,9 +247,11 @@ protected: static UFileConfig* cfg; static bool log_shared_with_server, bIPv6; + void loadConfigParam(); bool readHTTPResponse(); - bool sendRequest(bool bread_response); + bool sendRequestAndReadResponse(const UString& header, const UString& body); + bool sendRequestAndReadResponse() { return sendRequest(true); } #ifdef USE_LIBSSL @@ -288,8 +265,6 @@ protected: } #endif - void loadConfigParam(); - UClient_Base(UFileConfig* pcfg = 0); ~UClient_Base(); diff --git a/include/ulib/net/server/client_image.h b/include/ulib/net/server/client_image.h index a84e4622..efcb2ec5 100644 --- a/include/ulib/net/server/client_image.h +++ b/include/ulib/net/server/client_image.h @@ -287,7 +287,7 @@ public: { U_TRACE_NO_PARAM(0, "UClientImage_Base::setRequestNoCache()") -# if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE U_ClientImage_request |= NO_CACHE; U_INTERNAL_DUMP("U_ClientImage_request = %d %B", U_ClientImage_request, U_ClientImage_request) @@ -300,7 +300,7 @@ public: U_INTERNAL_DUMP("U_ClientImage_pipeline = %b size_request = %u U_http_uri_offset = %u", U_ClientImage_pipeline, size_request, U_http_uri_offset) -# if !defined(U_CACHE_REQUEST_DISABLE) || (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) +# if !defined(U_CACHE_REQUEST_DISABLE) || defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) U_INTERNAL_ASSERT_MAJOR(size_request, 0) U_INTERNAL_ASSERT_RANGE(1,U_http_uri_offset,254) U_INTERNAL_ASSERT_MAJOR(U_http_info.startHeader, 2) @@ -322,7 +322,7 @@ public: U_INTERNAL_DUMP("U_ClientImage_request_is_cached = %b", U_ClientImage_request_is_cached) -# if !defined(U_CACHE_REQUEST_DISABLE) || (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) +# if !defined(U_CACHE_REQUEST_DISABLE) || defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) U_INTERNAL_ASSERT(U_ClientImage_request_is_cached) uint32_t sz = request->size(); @@ -392,7 +392,7 @@ public: protected: USocket* socket; -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT UString uri; uint64_t bytes_sent; uint32_t min_limit, max_limit, started_at; @@ -496,7 +496,7 @@ protected: static bool isValidRequest( const char* ptr, uint32_t sz) { return true; } static bool isValidRequestExt(const char* ptr, uint32_t sz) { return true; } -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +#ifndef U_CACHE_REQUEST_DISABLE static bool isRequestCacheable() __pure; #endif diff --git a/include/ulib/net/server/server.h b/include/ulib/net/server/server.h index 9e073f3d..695646e3 100644 --- a/include/ulib/net/server/server.h +++ b/include/ulib/net/server/server.h @@ -366,7 +366,7 @@ public: static uint32_t shared_data_add, map_size; static bool update_date, update_date1, update_date2, update_date3; -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +#ifdef USE_LOAD_BALANCE static uint8_t loadavg_threshold; #endif @@ -611,7 +611,7 @@ protected: static UString getStats(); #endif -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT static bool throttling_chk; static UString* throttling_mask; static UThrottling* throttling_rec; diff --git a/include/ulib/utility/http2.h b/include/ulib/utility/http2.h index 5cb2b82f..0de189e7 100644 --- a/include/ulib/utility/http2.h +++ b/include/ulib/utility/http2.h @@ -18,7 +18,7 @@ #include #include -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +#ifdef USE_LOAD_BALANCE # include #endif @@ -279,7 +279,6 @@ protected: static void readFrame(); static void setStream(); static void manageData(); - static void sendGoAway(); static bool initRequest(); static void writeResponse(); static void decodeHeaders(); @@ -288,6 +287,7 @@ protected: static void handlerResponse(); static void sendResetStream(); static void sendWindowUpdate(); + static void sendGoAway(USocket* psocket); static void updateSetting(unsigned char* ptr, uint32_t len); static void writeData(struct iovec* iov, bool bdata, bool flag); @@ -315,7 +315,7 @@ protected: static void clear() { - U_TRACE_NO_PARAM(0, "UHTTP2::clear()") + U_TRACE_NO_PARAM(0+256, "UHTTP2::clear()") for (pStream = pConnection->streams; pStream <= pStreamEnd; ++pStream) { @@ -510,39 +510,12 @@ protected: U_RETURN(true); } - // HTTP/1.1 conversion + static void downgradeRequest(); // HTTP2 => HTTP1 + +#ifdef USE_LOAD_BALANCE + static bool bproxy; -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) static void wrapRequest(); - - static void wrapResponse() - { - U_TRACE_NO_PARAM(0, "UHTTP2::wrapResponse()") - - U_INTERNAL_DUMP("U_http_info.nResponseCode = %u U_http_info.clength = %u U_http_version = %C", U_http_info.nResponseCode, U_http_info.clength, U_http_version) - - U_http_version = '2'; - - UHTTP::ext->setBuffer(U_CAPACITY); - - UHTTP::client_http->getResponseHeader()->table.callForAllEntry(wrapHeaders); - - handlerResponse(); - } - - static bool wrapHeaders(UStringRep* key, void* elem) - { - U_TRACE(0, "UHTTP2::wrapHeaders(%V,%p)", key, elem) - - if (key->equal(U_CONSTANT_TO_PARAM("Date")) == false && - key->equal(U_CONSTANT_TO_PARAM("Server")) == false) - { - if (key->equal(U_CONSTANT_TO_PARAM("Set-Cookie"))) UHTTP::set_cookie->_assign(key); - else UHTTP::ext->snprintf_add(U_CONSTANT_TO_PARAM("%v: %v\r\n"), key, (const UStringRep*)elem); - } - - U_RETURN(true); - } #endif static bool setIndexStaticTable(UHashMap* table, const char* key, uint32_t length) @@ -578,6 +551,27 @@ protected: U_RETURN(false); } + static bool isHpackError(int32_t index) + { + U_TRACE(0, "UHTTP2::isHpackError(%d)", index) + + U_INTERNAL_DUMP("index = %d hpack_errno = %d", index, hpack_errno) + + if (index == -1 || + hpack_errno) + { +# ifdef DEBUG + if (hpack_errno == 0) hpack_errno = -2; // The decoding buffer ends before the decoded HPACK block +# endif + + nerror = COMPRESSION_ERROR; + + U_RETURN(true); + } + + U_RETURN(false); + } + static void setHpackDynTblCapacity(HpackDynamicTable* dyntbl, uint32_t value) { U_TRACE(0, "UHTTP2::setHpackDynTblCapacity(%p,%u)", dyntbl, value) @@ -776,25 +770,6 @@ protected: return hpack_error[-hpack_errno-2].desc; } - static bool isHpackError(int32_t index) - { - U_TRACE(0, "UHTTP2::isHpackError(%d)", index) - - U_INTERNAL_DUMP("index = %d hpack_errno = %d", index, hpack_errno) - - if (index == -1 || - hpack_errno) - { - if (hpack_errno == 0) hpack_errno = -2; // The decoding buffer ends before the decoded HPACK block - - nerror = COMPRESSION_ERROR; - - U_RETURN(true); - } - - U_RETURN(false); - } - static bool findHeader(uint32_t index) { U_TRACE(0, "UHTTP2::findHeader(%u)", index) diff --git a/include/ulib/utility/uhttp.h b/include/ulib/utility/uhttp.h index 812cfcfa..53c02813 100644 --- a/include/ulib/utility/uhttp.h +++ b/include/ulib/utility/uhttp.h @@ -47,7 +47,7 @@ class USSLSession; class UMimeMultipart; class UModProxyService; -template class UHttpClient; +template class UClient; template class URDBObjectHandler; class U_EXPORT UHTTP { @@ -209,11 +209,39 @@ public: static bool readBodyResponse(USocket* socket, UString* buffer, UString& body); #ifndef U_HTTP2_DISABLE - static bool copyHeaders(UStringRep* key, void* elem); + static bool copyHeaders(UStringRep* key, void* elem); + static bool upgradeHeaders(UStringRep* key, void* elem) + { + U_TRACE(0, "UHTTP::upgradeHeaders(%V,%p)", key, elem) + + if (key->equal(U_CONSTANT_TO_PARAM("Date")) == false && + key->equal(U_CONSTANT_TO_PARAM("Server")) == false) + { + if (key->equal(U_CONSTANT_TO_PARAM("Set-Cookie"))) set_cookie->_assign(key); + else ext->snprintf_add(U_CONSTANT_TO_PARAM("%v: %v\r\n"), key, (const UStringRep*)elem); + } + + U_RETURN(true); + } + + static void upgradeResponse(UHashMap* ptable) + { + U_TRACE(0, "UHTTP::upgradeResponse(%p)", ptable) + + U_INTERNAL_DUMP("U_http_info.nResponseCode = %u U_http_info.clength = %u U_http_version = %C", U_http_info.nResponseCode, U_http_info.clength, U_http_version) + + ext->setBuffer(U_CAPACITY); + + ptable->callForAllEntry(upgradeHeaders); + + U_http_version = '2'; + + handlerResponse(); + } #endif -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) - static UHttpClient* client_http; +#ifdef USE_LOAD_BALANCE + static UClient* client_http; static bool manageRequestOnRemoteServer(); #endif @@ -299,7 +327,7 @@ public: { U_TRACE_NO_PARAM(0, "UHTTP::startRequest()") -# if (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) || (defined(DEBUG) && !defined(U_LOG_DISABLE)) +# if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) || (defined(DEBUG) && !defined(U_LOG_DISABLE)) UClientImage_Base::startRequest(); # endif @@ -449,6 +477,10 @@ public: static bool isUriRequestProtected() __pure; #endif +#if defined(U_HTTP_STRICT_TRANSPORT_SECURITY) || defined(USE_LIBSSL) + static bool isValidation(); +#endif + #ifdef U_ALIAS static UString* alias; static bool virtual_host; @@ -685,7 +717,7 @@ public: #ifndef U_LOG_DISABLE static char iov_buffer[20]; static struct iovec iov_vec[10]; -# if !defined(U_CACHE_REQUEST_DISABLE) || (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) +# if !defined(U_CACHE_REQUEST_DISABLE) || defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) static uint32_t request_offset, referer_offset, agent_offset; # endif @@ -1137,7 +1169,7 @@ private: static void processRewriteRule() U_NO_EXPORT; #endif -#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) static int inotify_wd; static char* inotify_name; static uint32_t inotify_len; diff --git a/m4/ac_compilation_options.m4 b/m4/ac_compilation_options.m4 index 7f45a292..eb46648b 100644 --- a/m4/ac_compilation_options.m4 +++ b/m4/ac_compilation_options.m4 @@ -102,21 +102,6 @@ AC_DEFUN([AC_COMPILATION_OPTIONS],[ fi AC_MSG_RESULT([$enable_CRPWS]) - AC_MSG_CHECKING(if you want to enable server check time between request for parallelization) - AC_ARG_ENABLE(check-time, - [ --enable-check-time enable server check time between request for parallelization [[default=no]]]) - if test -z "$enable_check_time"; then - if test "$enable_debug" = "yes"; then - enable_check_time="yes" - else - enable_check_time="no" - fi - fi - if test "$enable_check_time" = "yes"; then - AC_DEFINE(U_SERVER_CHECK_TIME_BETWEEN_REQUEST, 1, [enable server check time between request for parallelization]) - fi - AC_MSG_RESULT([$enable_check_time]) - AC_MSG_CHECKING(if you want to enable server captive portal mode) AC_ARG_ENABLE(captive-portal, [ --enable-captive-portal enable server captive portal mode [[default=no]]]) @@ -225,6 +210,21 @@ AC_DEFUN([AC_COMPILATION_OPTIONS],[ fi AC_MSG_RESULT([$enable_http2]) + AC_MSG_CHECKING(if you want to enable server check time between request for parallelization) + AC_ARG_ENABLE(check-time, + [ --enable-check-time enable server check time between request for parallelization [[default=no]]]) + if test -z "$enable_check_time"; then + if test "$enable_debug" = "yes" -a "$enable_http2" != "yes"; then + enable_check_time="yes" + else + enable_check_time="no" + fi + fi + if test "$enable_check_time" = "yes"; then + AC_DEFINE(U_SERVER_CHECK_TIME_BETWEEN_REQUEST, 1, [enable server check time between request for parallelization]) + fi + AC_MSG_RESULT([$enable_check_time]) + AC_MSG_CHECKING(if you want to enable server classic model support) AC_ARG_ENABLE(classic, [ --enable-classic enable server classic model support [[default=no]]]) diff --git a/src/ulib/base/utility.c b/src/ulib/base/utility.c index 2403855c..e8c8e7bf 100644 --- a/src/ulib/base/utility.c +++ b/src/ulib/base/utility.c @@ -453,15 +453,15 @@ cap_list[] = { }; */ -# ifdef DEBUG - cap_value_t minimal_cap_values[] = { CAP_SETUID, CAP_SETGID, CAP_SETPCAP, CAP_SYS_PTRACE }; -# else +# ifndef DEBUG cap_value_t minimal_cap_values[] = { CAP_SETUID, CAP_SETGID, CAP_SETPCAP }; +# else + cap_value_t minimal_cap_values[] = { CAP_SETUID, CAP_SETGID, CAP_SETPCAP, CAP_SYS_PTRACE }; # endif cap_t caps = cap_init(); - if (caps == 0) U_ERROR("cap_init() failed"); + if (caps == 0) U_ERROR_SYSCALL("cap_init() failed"); (void) cap_clear(caps); @@ -469,16 +469,16 @@ cap_list[] = { (void) cap_set_flag(caps, CAP_PERMITTED, 3, minimal_cap_values, CAP_SET); (void) cap_set_flag(caps, CAP_INHERITABLE, 3, minimal_cap_values, CAP_SET); - if (cap_set_proc(caps) < 0) U_ERROR("cap_set_proc() failed"); + if (cap_set_proc(caps) < 0) U_ERROR_SYSCALL("cap_set_proc() failed"); (void) cap_free(caps); - if (prctl(U_PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) U_ERROR("prctl() failed"); + if (prctl(U_PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) U_ERROR_SYSCALL("prctl() failed"); # endif U_INTERNAL_TRACE("u_never_need_root()") - U_INTERNAL_PRINT("(_euid_=%d, uid=%d)", effective_uid, real_uid) + U_INTERNAL_PRINT("_euid_ = %d, uid = %d", effective_uid, real_uid) if (real_uid == (uid_t)(-1)) U_ERROR("u_init_security() not called"); @@ -487,7 +487,7 @@ cap_list[] = { if (geteuid() != real_uid || getuid() != real_uid) { - U_ERROR("Did not drop root privilege"); + U_ERROR_SYSCALL("Did not drop root privilege"); } effective_uid = real_uid; @@ -523,7 +523,7 @@ void u_dont_need_group(void) U_INTERNAL_TRACE("u_dont_need_group()") #ifndef _MSWINDOWS_ - U_INTERNAL_PRINT("(egid_=%d, gid=%d)", effective_gid, real_gid) + U_INTERNAL_PRINT("egid_ = %d, gid = %d", effective_gid, real_gid) if (real_gid == (gid_t)(-1)) U_ERROR("u_init_security() not called"); @@ -532,7 +532,7 @@ void u_dont_need_group(void) if (setegid(real_gid) == -1 || getegid() != real_gid) { - U_ERROR("Did not drop group privilege"); + U_ERROR_SYSCALL("Did not drop group privilege"); } #endif } @@ -544,7 +544,7 @@ void u_never_need_group(void) U_INTERNAL_TRACE("u_never_need_group()") #ifndef _MSWINDOWS_ - U_INTERNAL_PRINT("(egid_=%d, gid=%d)", effective_gid, real_gid) + U_INTERNAL_PRINT("egid_ = %d, gid = %d", effective_gid, real_gid) if (real_gid == (gid_t)(-1)) U_ERROR("u_init_security() not called"); @@ -553,7 +553,7 @@ void u_never_need_group(void) if (getegid() != real_gid || getgid() != real_gid) { - U_ERROR("Did not drop group privilege"); + U_ERROR_SYSCALL("Did not drop group privilege"); } effective_gid = real_gid; @@ -743,8 +743,8 @@ __pure int u_getScreenWidth(void) /** * Calculate the download rate and trim it as appropriate for the speed. Appropriate means that - * if rate is greater than 1K/s, kilobytes are used, and if rate is greater than 1MB/s, megabytes are used. - * UNITS is zero for B/s, one for KB/s, two for MB/s, and three for GB/s + * if rate is greater than 1K/s, kilobytes are used, and if rate is greater than 1MB/s, megabytes + * are used. UNITS is zero for B/s, one for KB/s, two for MB/s, and three for GB/s */ double u_calcRate(uint64_t bytes, uint32_t msecs, int* restrict units) @@ -970,7 +970,7 @@ int u_get_num_cpu(void) /** * Parses a comma-separated list of numbers and ranges - * of numbers,with optional ':%u' strides modifying ranges. + * of numbers, with optional ':%u' strides modifying ranges. * * Some examples of input lists and their equivalent simple list: * @@ -1023,7 +1023,7 @@ int u_get_num_cpu(void) (void) fclose(fp); } -#endif +# endif } return u_num_cpu; @@ -1089,7 +1089,7 @@ void u_switch_to_realtime_priority(void) void u_get_memusage(unsigned long* vsz, unsigned long* rss) { -#ifdef U_LINUX +#if defined(U_LINUX) && !defined(U_COVERITY_FALSE_POSITIVE) static int fd_stat; char* p; @@ -1157,6 +1157,43 @@ void u_get_memusage(unsigned long* vsz, unsigned long* rss) #endif } +uint8_t u_get_loadavg(void) +{ + /** + * /proc/loadavg (ex: 0.19 1.37 0.97 1/263 26041) + * + * The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or waiting for disk I/O (state D) + * averaged over 1, 5, and 15 minutes. They are the same as the load average numbers given by uptime(1) and other programs. The fourth field consists + * of two numbers separated by a slash (/). The first of these is the number of currently runnable kernel scheduling entities (processes, threads). + * The value after the slash is the number of kernel scheduling entities that currently exist on the system. The fifth field is the PID of the process + * that was most recently created on the system + */ + +#if defined(U_LINUX) && !defined(U_COVERITY_FALSE_POSITIVE) + static int fd_loadavg; + + char buffer[8]; + ssize_t bytes_read; + + U_INTERNAL_TRACE("u_get_loadavg()") + + if (fd_loadavg == 0) fd_loadavg = open("/proc/loadavg", O_RDONLY); + + U_INTERNAL_ASSERT_DIFFERS(fd_loadavg, -1) + + bytes_read = pread(fd_loadavg, buffer, sizeof(buffer), 0); + + if (bytes_read > 0) + { + U_INTERNAL_ASSERT_RANGE(1,bytes_read,(int)sizeof(buffer)) + + if (buffer[1] == '.') return (((buffer[0]-'0') * 10) + (buffer[2]-'0') + (buffer[3] > '5')); // 0.19 => 2, 4.56 => 46, ... + } +#endif + + return 255; +} + uint32_t u_get_uptime(void) { #ifdef U_LINUX @@ -1179,45 +1216,6 @@ uint32_t u_get_uptime(void) return 0; } -uint8_t u_get_loadavg(void) -{ - /** - * /proc/loadavg (ex: 0.19 1.37 0.97 1/263 26041) - * - * The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or waiting for disk I/O (state D) - * averaged over 1, 5, and 15 minutes. They are the same as the load average numbers given by uptime(1) and other programs. The fourth field consists - * of two numbers separated by a slash (/). The first of these is the number of currently runnable kernel scheduling entities (processes, threads). - * The value after the slash is the number of kernel scheduling entities that currently exist on the system. The fifth field is the PID of the process - * that was most recently created on the system - */ - -#ifdef U_LINUX - static int fd_loadavg; - - char buffer[8]; - ssize_t bytes_read; - - U_INTERNAL_TRACE("u_get_loadavg()") - - if (fd_loadavg == 0) fd_loadavg = open("/proc/loadavg", O_RDONLY); - - U_INTERNAL_ASSERT_DIFFERS(fd_loadavg, -1) - - bytes_read = pread(fd_loadavg, buffer, sizeof(buffer), 0); - - if (bytes_read > 0) - { - U_INTERNAL_ASSERT_RANGE(1,bytes_read,(int)sizeof(buffer)) - -# ifndef U_COVERITY_FALSE_POSITIVE - if (buffer[1] == '.') return (((buffer[0]-'0') * 10) + (buffer[2]-'0') + (buffer[3] > '5')); // 0.19 => 2, 4.56 => 46, ... -# endif - } -#endif - - return 255; -} - __pure bool u_rmatch(const char* restrict haystack, uint32_t haystack_len, const char* restrict needle, uint32_t needle_len) { U_INTERNAL_TRACE("u_rmatch(%.*s,%u,%.*s,%u)", U_min(haystack_len,128), haystack, haystack_len, @@ -1276,8 +1274,7 @@ __pure const char* u__strpbrk(const char* restrict s, uint32_t slen, const char* /* Search a string for a terminator of a group of delimitator {} [] () <%%>...*/ -__pure const char* u_strpend(const char* restrict s, uint32_t slen, - const char* restrict group_delimitor, uint32_t group_delimitor_len, char skip_line_comment) +__pure const char* u_strpend(const char* restrict s, uint32_t slen, const char* restrict group_delimitor, uint32_t group_delimitor_len, char skip_line_comment) { char c; int level = 1; @@ -1341,7 +1338,7 @@ loop: c = *++s; return 0; } -/* check if string a start with string b */ +/* check if string 'a' start with string 'b' */ __pure bool u_startsWith(const char* restrict a, uint32_t n1, const char* restrict b, uint32_t n2) { @@ -1403,7 +1400,7 @@ __pure bool u_isNumber(const char* restrict s, uint32_t n) return (s == end); } -/* find first char not quoted */ +/* find the first char not quoted */ __pure const char* u_find_char(const char* restrict s, const char* restrict end, char c) { @@ -1620,7 +1617,7 @@ __pure bool u_dosmatch(const char* restrict s, uint32_t n1, const char* restrict U_INTERNAL_ASSERT_MAJOR(n2, 0) U_INTERNAL_ASSERT_POINTER(mask) - if (flags & FNM_IGNORECASE) + if ((flags & FNM_IGNORECASE) != 0) { while (s < end_s) { @@ -1847,7 +1844,7 @@ __pure bool u_dosmatch_ext(const char* restrict s, uint32_t n1, const char* rest end = t; } - if (flags & FNM_IGNORECASE) + if ((flags & FNM_IGNORECASE) != 0) { start = u__tolower((unsigned char)start); end = u__tolower((unsigned char)end); @@ -1998,7 +1995,7 @@ __pure bool u_validate_email_address(const char* restrict address, uint32_t addr U_INTERNAL_PRINT("c = %c", *c) if (*c == '\"' && - (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) + (c == address || *(c-1) == '.' || *(c-1) == '\"')) { while (++c < end) { @@ -2025,12 +2022,15 @@ __pure bool u_validate_email_address(const char* restrict address, uint32_t addr if (*c == '@') break; if (*c <= ' ' || - *c >= 127) return false; + *c >= 127) + { + return false; + } if (strchr(RFC822_SPECIALS, *c)) return false; } - if (c == address || *(c - 1) == '.') return false; + if (c == address || *(c-1) == '.') return false; /* next we validate the domain portion (name@domain) */ @@ -2043,13 +2043,16 @@ __pure bool u_validate_email_address(const char* restrict address, uint32_t addr if (*c == '.') { - if (c == domain || *(c - 1) == '.') return false; + if (c == domain || *(c-1) == '.') return false; ++count; } if (*c <= ' ' || - *c >= 127) return false; + *c >= 127) + { + return false; + } if (strchr(RFC822_SPECIALS, *c)) return false; } @@ -2696,13 +2699,13 @@ static inline int rangematch(const char* restrict pattern, char test, int flags, do { char c2; - if (c == '\\' && !(flags & FNM_NOESCAPE)) c = *pattern++; + if (c == '\\' && (flags & FNM_NOESCAPE) == 0) c = *pattern++; U_INTERNAL_PRINT("c = %c test = %c", c, test) if (pattern > end_p) return -1; /* if (c == EOS) return (RANGE_ERROR); */ - if (c == '/' && (flags & FNM_PATHNAME)) return 0; + if (c == '/' && (flags & FNM_PATHNAME) != 0) return 0; if (flags & FNM_CASEFOLD) c = u__tolower((unsigned char)c); @@ -2712,11 +2715,11 @@ static inline int rangematch(const char* restrict pattern, char test, int flags, { pattern += 2; - if (c2 == '\\' && !(flags & FNM_NOESCAPE)) c2 = *pattern++; + if (c2 == '\\' && (flags & FNM_NOESCAPE) == 0) c2 = *pattern++; if (pattern > end_p) return -1; /* if (c2 == EOS) return (RANGE_ERROR); */ - if (flags & FNM_CASEFOLD) c2 = u__tolower((unsigned char)c2); + if ((flags & FNM_CASEFOLD) != 0) c2 = u__tolower((unsigned char)c2); if (c <= test && test <= c2) @@ -2752,7 +2755,7 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st if (pattern > end_p) { - if ((flags & FNM_LEADING_DIR) && *string == '/') return 0; + if ((flags & FNM_LEADING_DIR) != 0 && *string == '/') return 0; return (string != end_s); } @@ -2763,10 +2766,10 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st { if (string == end_s) return 1; - if (*string == '/' && (flags & FNM_PATHNAME)) return 1; + if (*string == '/' && (flags & FNM_PATHNAME) != 0) return 1; - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + if (*string == '.' && (flags & FNM_PERIOD) != 0 && + (string == stringstart || ((flags & FNM_PATHNAME) != 0 && *(string - 1) == '/'))) { return 1; } @@ -2783,8 +2786,8 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st while (c == '*') c = *++pattern; - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + if (*string == '.' && (flags & FNM_PERIOD) != 0 && + (string == stringstart || ((flags & FNM_PATHNAME) != 0 && *(string - 1) == '/'))) { return 1; } @@ -2793,12 +2796,12 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st if (pattern == end_p) /* if (c == EOS) */ { - if (flags & FNM_PATHNAME) return ((flags & FNM_LEADING_DIR) || memchr(string, '/', end_s - string) == 0 ? 0 : 1); + if ((flags & FNM_PATHNAME) != 0) return ((flags & FNM_LEADING_DIR) != 0 || memchr(string, '/', end_s - string) == 0 ? 0 : 1); return 0; } - if (c == '/' && flags & FNM_PATHNAME) + if (c == '/' && (flags & FNM_PATHNAME) != 0) { if ((string = (const char* restrict)memchr(string, '/', end_s - string)) == 0) return 1; @@ -2813,7 +2816,7 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st if (!kfnmatch(pattern, string, flags & ~FNM_PERIOD, nesting + 1)) return 0; - if (test == '/' && flags & FNM_PATHNAME) break; + if (test == '/' && (flags & FNM_PATHNAME) != 0) break; ++string; } @@ -2825,10 +2828,10 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st { if (string == end_s) return 1; - if (*string == '/' && (flags & FNM_PATHNAME)) return 1; + if (*string == '/' && (flags & FNM_PATHNAME) != 0) return 1; - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + if (*string == '.' && (flags & FNM_PERIOD) != 0 && + (string == stringstart || ((flags & FNM_PATHNAME) != 0 && *(string - 1) == '/'))) { return 1; } @@ -2846,7 +2849,7 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st case '\\': { - if (!(flags & FNM_NOESCAPE)) + if ((flags & FNM_NOESCAPE) == 0) { c = *pattern++; @@ -2866,7 +2869,7 @@ __pure static int kfnmatch(const char* restrict pattern, const char* restrict st norm: if (c == *string) { } - else if ((flags & FNM_CASEFOLD) && (u__tolower((unsigned char)c) == u__tolower((unsigned char)*string))) + else if ((flags & FNM_CASEFOLD) != 0 && (u__tolower((unsigned char)c) == u__tolower((unsigned char)*string))) { } else diff --git a/src/ulib/log.cpp b/src/ulib/log.cpp index edabef56..4b5d2520 100644 --- a/src/ulib/log.cpp +++ b/src/ulib/log.cpp @@ -762,7 +762,6 @@ void ULog::log(const struct iovec* iov, const char* name, const char* type, int U_TRACE(0, "ULog::log(%p,%S,%S,%d,%.*S,%u,%.*S,%u)", iov, name, type, ncount, msg_len, msg, msg_len, fmt_size, format, fmt_size) U_INTERNAL_ASSERT_MAJOR(ncount, 0) - U_INTERNAL_ASSERT_DIFFERS(U_http_version, '2') char buffer1[2000], buffer2[8192]; const char* ptr = (const char*)iov[2].iov_base; @@ -837,7 +836,7 @@ void ULog::log(const struct iovec* iov, const char* name, const char* type, int ptr = buffer1; } - len = u__snprintf(buffer2, sizeof(buffer2), U_CONSTANT_TO_PARAM("%ssend %s (%u bytes) %.*s%.*S"), name, type, ncount, msg_len, msg, sz, ptr); + len = u__snprintf(buffer2, sizeof(buffer2), U_CONSTANT_TO_PARAM("%ssend %s (%u bytes) %.*s%#.*S"), name, type, ncount, msg_len, msg, sz, ptr); va_list argp; va_start(argp, fmt_size); @@ -874,7 +873,7 @@ void ULog::logResponse(const UString& data, const char* name, const char* format U_INTERNAL_DUMP("u_printf_string_max_length = %d", u_printf_string_max_length) - len = u__snprintf(buffer, sizeof(buffer), U_CONSTANT_TO_PARAM("%sreceived response (%u bytes) %.*S"), name, sz, sz, ptr); + len = u__snprintf(buffer, sizeof(buffer), U_CONSTANT_TO_PARAM("%sreceived response (%u bytes) %#.*S"), name, sz, sz, ptr); va_list argp; va_start(argp, fmt_size); diff --git a/src/ulib/net/client/client.cpp b/src/ulib/net/client/client.cpp index c9471992..e55a5549 100644 --- a/src/ulib/net/client/client.cpp +++ b/src/ulib/net/client/client.cpp @@ -55,6 +55,7 @@ void UClient_Base::closeLog() { U_TRACE_NO_PARAM(0, "UClient_Base::closeLog()") +#ifndef U_LOG_DISABLE if (log && log_shared_with_server == false) { @@ -63,6 +64,7 @@ void UClient_Base::closeLog() log = 0; } +#endif } UClient_Base::~UClient_Base() @@ -71,6 +73,7 @@ UClient_Base::~UClient_Base() U_INTERNAL_ASSERT_POINTER(socket) +#ifndef U_LOG_DISABLE if (log && log_shared_with_server == false) { @@ -78,6 +81,7 @@ UClient_Base::~UClient_Base() delete log; } +#endif delete socket; @@ -185,8 +189,10 @@ void UClient_Base::setLogShared() U_INTERNAL_ASSERT_POINTER(UServer_Base::log) +#ifndef U_LOG_DISABLE log = UServer_Base::log; log_shared_with_server = true; +#endif } void UClient_Base::loadConfigParam() @@ -301,7 +307,9 @@ bool UClient_Base::connect() response.snprintf(U_CONSTANT_TO_PARAM("Sorry, couldn't connect to server %v%R"), host_port.rep, 0); // NB: the last argument (0) is necessary... +#ifndef U_LOG_DISABLE if (log) ULog::log(U_CONSTANT_TO_PARAM("%s%v"), log_shared_with_server ? UServer_Base::mod_name[0] : "", response.rep); +#endif U_RETURN(false); } @@ -449,6 +457,10 @@ bool UClient_Base::sendRequest(bool bread_response) resend: if (connect()) { +# ifndef U_LOG_DISABLE + if (log) ULog::log(iov, name, "request", ncount, "", 0, U_CONSTANT_TO_PARAM(" to %v"), host_port.rep); +# endif + ok = (USocketExt::writev(socket, iov, iovcnt, ncount, timeoutMS, 1) == ncount); if (ok == false) @@ -457,7 +469,9 @@ resend: if (++counter <= 2) goto resend; +# ifndef U_LOG_DISABLE if (log) ULog::log(U_CONSTANT_TO_PARAM("%serror on sending data to %V%R"), name, host_port.rep, 0); // NB: the last argument (0) is necessary... +# endif goto end; } @@ -470,25 +484,27 @@ resend: (log_shared_with_server == false || // check for SIGTERM event... UServer_Base::flag_loop)) { +# ifndef U_LOG_DISABLE if (log) errno = 0; +# endif goto resend; } - if (log) - { - ULog::log(iov, name, "request", ncount, "", 0, U_CONSTANT_TO_PARAM(" to %v"), host_port.rep); - ULog::log(U_CONSTANT_TO_PARAM("%serror on reading data from %V%R"), name, host_port.rep, 0); // 0 is necessary - } +# ifndef U_LOG_DISABLE + if (log) ULog::log(U_CONSTANT_TO_PARAM("%serror on reading data from %V%R"), name, host_port.rep, 0); // NB: the last argument (0) is necessary... +# endif goto end; } - if (log) +# ifndef U_LOG_DISABLE + if (log && + response) { - ULog::log(iov, name, "request", ncount, "", 0, U_CONSTANT_TO_PARAM(" to %v"), host_port.rep); - if (response) ULog::logResponse(response, name, U_CONSTANT_TO_PARAM(" from %v"), host_port.rep); + ULog::logResponse(response, name, U_CONSTANT_TO_PARAM(" from %v"), host_port.rep); } +# endif reset(); } @@ -505,6 +521,39 @@ end: U_RETURN(false); } +bool UClient_Base::sendRequestAndReadResponse(const UString& header, const UString& body) +{ + U_TRACE(0, "UClient_Base::sendRequestAndReadResponse(%V,%V)", header.rep, body.rep) + + if (body.empty() || + body.isSubStringOf(header)) + { + UClient_Base::prepareRequest(header); + } + else + { + UClient_Base::request = header; + + UClient_Base::iovcnt = 2; + + UClient_Base::iov[0].iov_base = (caddr_t)header.data(); + UClient_Base::iov[0].iov_len = header.size(); + UClient_Base::iov[1].iov_base = (caddr_t) body.data(); + UClient_Base::iov[1].iov_len = body.size(); + + (void) U_SYSCALL(memset, "%p,%d,%u", UClient_Base::iov+2, 0, sizeof(struct iovec) * 4); + + U_INTERNAL_ASSERT_EQUALS(UClient_Base::iov[2].iov_len, 0) + U_INTERNAL_ASSERT_EQUALS(UClient_Base::iov[3].iov_len, 0) + U_INTERNAL_ASSERT_EQUALS(UClient_Base::iov[4].iov_len, 0) + U_INTERNAL_ASSERT_EQUALS(UClient_Base::iov[5].iov_len, 0) + } + + if (UClient_Base::sendRequest(true)) U_RETURN(true); + + U_RETURN(false); +} + // read data response bool UClient_Base::readResponse(uint32_t count) @@ -515,11 +564,13 @@ bool UClient_Base::readResponse(uint32_t count) if (USocketExt::read(socket, response, count, timeoutMS)) { +# ifndef U_LOG_DISABLE if (log && response) { ULog::logResponse(response, (log_shared_with_server ? UServer_Base::mod_name[0] : ""), U_CONSTANT_TO_PARAM(" from %V"), host_port.rep); } +# endif U_RETURN(true); } @@ -554,11 +605,13 @@ bool UClient_Base::readHTTPResponse() if (UHTTP::readBodyResponse(socket, &buffer, response)) { +# ifndef U_LOG_DISABLE if (log && response) { ULog::logResponse(response, (log_shared_with_server ? UServer_Base::mod_name[0] : ""), U_CONSTANT_TO_PARAM(" from %V"), host_port.rep); } +# endif U_RETURN(true); } diff --git a/src/ulib/net/client/http.cpp b/src/ulib/net/client/http.cpp index 4d3a5250..8d4aa41a 100644 --- a/src/ulib/net/client/http.cpp +++ b/src/ulib/net/client/http.cpp @@ -653,24 +653,20 @@ int UHttpClient_Base::sendRequestAsync(const UString& _url, bool bqueue, const c UClient_Base::adjustTimeOut(); UTimeVal to_sleep(10); -loop: - if (UClient_Base::isOpen() == false) UClient_Base::socket->_socket(); - if ((UClient_Base::isConnected() || - UClient_Base::connect()) && - sendRequestEngine()) - { - goto next; - } +loop: if (UClient_Base::isOpen() == false) UClient_Base::socket->_socket(); - if (++num_attempts < U_MAX_ATTEMPTS) + if (((UClient_Base::isConnected() == false && + UClient_Base::connect() == false) || + sendRequestEngine() == false) && + ++num_attempts < U_MAX_ATTEMPTS) { to_sleep.nanosleep(); goto loop; } -next: +# ifndef U_LOG_DISABLE if (log_msg) { uint32_t sz = strlen(log_msg); @@ -679,6 +675,7 @@ next: if (log_fd == -1) ULog::log( log_msg, sz, str, num_attempts); else ULog::log(log_fd, log_msg, sz, str, num_attempts); } +# endif } // QUEUE MODE @@ -841,6 +838,7 @@ bool UHttpClient_Base::sendRequestEngine() { U_TRACE_NO_PARAM(0, "UHttpClient_Base::sendRequestEngine()") + U_INTERNAL_ASSERT_DIFFERS(U_http_version, '2') U_INTERNAL_ASSERT_RANGE(1,UClient_Base::iovcnt,6) UString headers; @@ -867,8 +865,6 @@ bool UHttpClient_Base::sendRequestEngine() body.clear(); responseHeader->clear(); - UClient_Base::response.setEmpty(); - result = (UClient_Base::sendRequestAndReadResponse() && responseHeader->readHeader(UClient_Base::socket, UClient_Base::response) // read the HTTP response header ? checkResponse(redirectCount) diff --git a/src/ulib/net/server/client_image.cpp b/src/ulib/net/server/client_image.cpp index c471719b..ea4f3f10 100644 --- a/src/ulib/net/server/client_image.cpp +++ b/src/ulib/net/server/client_image.cpp @@ -22,7 +22,7 @@ # include #endif -#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE) +#ifdef U_SERVER_CHECK_TIME_BETWEEN_REQUEST # define U_NUM_CLIENT_THRESHOLD 128 #endif @@ -326,7 +326,7 @@ __pure bool UClientImage_Base::isAllowed(UVector& vallow_IP) U_RETURN(false); } -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +#ifndef U_CACHE_REQUEST_DISABLE __pure bool UClientImage_Base::isRequestCacheable() { U_TRACE_NO_PARAM(0, "UClientImage_Base::isRequestCacheable()") @@ -589,7 +589,7 @@ const char* UClientImage_Base::getRequestUri(uint32_t& sz) #ifdef U_ALIAS if (*request_uri) { -# if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE U_INTERNAL_ASSERT_EQUALS(U_ClientImage_request_is_cached, false) # endif @@ -610,7 +610,7 @@ const char* UClientImage_Base::getRequestUri(uint32_t& sz) return ptr; } -#if defined(U_CACHE_REQUEST_DISABLE) && !defined(U_HTTP2_DISABLE) +#ifdef U_CACHE_REQUEST_DISABLE # define U_IOV_TO_SAVE sizeof(struct iovec) #else # define U_IOV_TO_SAVE (sizeof(struct iovec) * 4) @@ -620,7 +620,7 @@ void UClientImage_Base::startRequest() { U_TRACE_NO_PARAM(0, "UClientImage_Base::startRequest()") -#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE) +#ifdef U_SERVER_CHECK_TIME_BETWEEN_REQUEST long time_elapsed = chronometer->restart(); U_INTERNAL_DUMP("U_ClientImage_pipeline = %b time_elapsed = %ld time_run = %ld U_ClientImage_request_is_cached = %b csfd = %d", @@ -634,7 +634,7 @@ void UClientImage_Base::startRequest() # ifdef USE_LIBSSL if (UServer_Base::bssl) return; # endif -# if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE if (U_ClientImage_request_is_cached) return; # endif @@ -666,7 +666,7 @@ void UClientImage_Base::startRequest() #if defined(DEBUG) && !defined(U_LOG_DISABLE) if (UServer_Base::isLog()) { -#if !defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) || !defined(U_HTTP2_DISABLE) +# ifndef U_SERVER_CHECK_TIME_BETWEEN_REQUEST (void) chronometer->restart(); # endif } @@ -683,7 +683,7 @@ void UClientImage_Base::endRequest() if (UServer_Base::isParallelizationParent() == false) { -# if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE) +# ifdef U_SERVER_CHECK_TIME_BETWEEN_REQUEST time_run = chronometer->stop(); # ifdef DEBUG @@ -711,7 +711,7 @@ void UClientImage_Base::endRequest() uint32_t sz = 0; const char* ptr; -# if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE if (U_ClientImage_request_is_cached) { U_INTERNAL_DUMP("U_http_uri_offset = %u", U_http_uri_offset) @@ -753,7 +753,7 @@ void UClientImage_Base::endRequest() U_MEMCPY(ptr1, "\" run in ", U_CONSTANT_SIZE("\" run in ")); ptr1 += U_CONSTANT_SIZE("\" run in "); -# if !defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) || !defined(U_HTTP2_DISABLE) +# ifndef U_SERVER_CHECK_TIME_BETWEEN_REQUEST time_run = chronometer->stop(); # endif @@ -950,7 +950,7 @@ void UClientImage_Base::prepareForRead() UEventFd::fd = socket->iSockDesc; } -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT UServer_Base::initThrottlingClient(); #endif } @@ -977,7 +977,7 @@ bool UClientImage_Base::genericRead() U_INTERNAL_ASSERT_EQUALS(socket->iSockDesc, UEventFd::fd) -#if (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) || (defined(DEBUG) && !defined(U_LOG_DISABLE)) +#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) || (defined(DEBUG) && !defined(U_LOG_DISABLE)) startRequest(); #endif @@ -1026,7 +1026,7 @@ bool UClientImage_Base::genericRead() data_pending = 0; } -#if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE) +#ifdef U_SERVER_CHECK_TIME_BETWEEN_REQUEST if (U_ClientImage_advise_for_parallelization) { if (checkRequestToCache() == 2 && @@ -1158,7 +1158,7 @@ data_missing: U_RETURN(U_NOTIFIER_OK); } -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +#ifndef U_CACHE_REQUEST_DISABLE if (U_ClientImage_request_is_cached) { sz = checkRequestToCache(); @@ -1227,7 +1227,7 @@ data_missing: if (log_request_partial == UEventFd::fd) logRequest(); # endif -# if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE next: # endif sz = rbuffer->size(); @@ -1409,7 +1409,7 @@ write: if (U_ClientImage_pipeline) { endRequest(); -# if (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) || (defined(DEBUG) && !defined(U_LOG_DISABLE)) +# if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) || (defined(DEBUG) && !defined(U_LOG_DISABLE)) startRequest(); # endif @@ -1427,7 +1427,7 @@ error: endRequest(); -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (uri) UServer_Base::clearThrottling(); #endif @@ -1543,7 +1543,7 @@ bool UClientImage_Base::writeResponse() #endif } -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (iBytesWrite > 0) bytes_sent += iBytesWrite; #endif #ifdef DEBUG @@ -1636,7 +1636,7 @@ loop: iBytesWrite = USocketExt::_writev(socket, piov, iovcnt, ncount, U_TIMEOUT_MS); #endif -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (iBytesWrite > 0) bytes_sent += iBytesWrite; #endif #ifdef DEBUG @@ -1725,7 +1725,7 @@ void UClientImage_Base::resetPipeline() U_ClientImage_pipeline = false; -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +#ifndef U_CACHE_REQUEST_DISABLE if (U_ClientImage_request_is_cached == false) #endif size_request = 0; // NB: we don't want to process further the read buffer... @@ -1837,7 +1837,7 @@ int UClientImage_Base::handlerWrite() U_INTERNAL_DUMP("bwrite = %b", bwrite) -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (UServer_Base::checkThrottlingBeforeSend(bwrite) == false) U_RETURN(U_NOTIFIER_OK); #endif @@ -1848,7 +1848,7 @@ write: offset = start; iBytesWrite = USocketExt::sendfile(socket, sfd, &offset, count, 0); -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (iBytesWrite > 0) bytes_sent += iBytesWrite; #endif #ifdef DEBUG diff --git a/src/ulib/net/server/plugin/mod_http.cpp b/src/ulib/net/server/plugin/mod_http.cpp index d9c2a600..5a92f490 100644 --- a/src/ulib/net/server/plugin/mod_http.cpp +++ b/src/ulib/net/server/plugin/mod_http.cpp @@ -38,7 +38,7 @@ int UHttpPlugIn::handlerRead() { U_TRACE_NO_PARAM(0, "UHttpPlugIn::handlerRead()") -#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) U_INTERNAL_ASSERT_POINTER(UHTTP::cache_file) UHTTP::in_READ(); @@ -279,7 +279,7 @@ int UHttpPlugIn::handlerConfig(UFileConfig& cfg) // INOTIFY -# if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +# if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) if (cfg.readBoolean(U_CONSTANT_TO_PARAM("ENABLE_INOTIFY"))) { UServer_Base::handler_inotify = this; @@ -389,7 +389,7 @@ int UHttpPlugIn::handlerConfig(UFileConfig& cfg) } # endif -# if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +# ifdef U_THROTTLING_SUPPORT x = cfg.at(U_CONSTANT_TO_PARAM("BANDWIDTH_THROTTLING_MASK")); if (x) @@ -595,7 +595,7 @@ int UHttpPlugIn::handlerFork() { U_TRACE_NO_PARAM(0, "UHttpPlugIn::handlerFork()") -#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) UHTTP::initInotify(); #endif diff --git a/src/ulib/net/server/plugin/mod_nocat.cpp b/src/ulib/net/server/plugin/mod_nocat.cpp index 35ea679b..fc61c8c2 100644 --- a/src/ulib/net/server/plugin/mod_nocat.cpp +++ b/src/ulib/net/server/plugin/mod_nocat.cpp @@ -885,7 +885,9 @@ result: if (nfds < FD_SETSIZE) U_ASSERT_EQUALS(pmask->count(), 0) else { - U_DEBUG("pmask->count() = %u nfds = %u", pmask->count(), nfds); + U_DEBUG("pmask->count() = %u nfds = %u FD_SETSIZE = %u", pmask->count(), nfds, FD_SETSIZE); + + U_ASSERT_EQUALS(nfds-FD_SETSIZE, pmask->count()) } # endif @@ -893,8 +895,8 @@ result: { if (getPeer(i)) { - bset = (nfds < FD_SETSIZE ? FD_ISSET(i, paddrmask) - : pmask->isSet(i-FD_SETSIZE)); + bset = (i < FD_SETSIZE ? FD_ISSET(i, paddrmask) + : pmask->isSet(i-FD_SETSIZE)); if (bset) addPeerInfo(0); else diff --git a/src/ulib/net/server/server.cpp b/src/ulib/net/server/server.cpp index 1156e392..9a9d46e2 100644 --- a/src/ulib/net/server/server.cpp +++ b/src/ulib/net/server/server.cpp @@ -152,7 +152,7 @@ UVector* UServer_Base::vlog; #ifdef U_WELCOME_SUPPORT UString* UServer_Base::msg_welcome; #endif -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +#ifdef USE_LOAD_BALANCE unsigned char UServer_Base::loadavg_threshold = 45; // => 4.5 #endif #ifdef U_ACL_SUPPORT @@ -166,9 +166,6 @@ UVector* UServer_Base::vallow_IP_prv; #endif #ifdef DEBUG -# ifndef U_LOG_DISABLE -long UServer_Base::last_event; -# endif # ifdef USE_LIBEVENT # define U_WHICH "libevent" # elif defined(HAVE_EPOLL_WAIT) @@ -176,7 +173,9 @@ long UServer_Base::last_event; # else # define U_WHICH "select" # endif - +# ifndef U_LOG_DISABLE +long UServer_Base::last_event; +# endif uint32_t UServer_Base::nread; uint32_t UServer_Base::max_depth; uint32_t UServer_Base::nread_again; @@ -357,7 +356,7 @@ private: * the server returns a special code */ -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT # define U_THROTTLE_TIME 2 // Time between updates of the throttle table's rolling averages class U_NO_EXPORT UThrottling : public UDataStorage { @@ -895,7 +894,7 @@ public: { U_TRACE_NO_PARAM(0, "UTimeThread::run()") -# if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +# ifdef USE_LOAD_BALANCE uusockaddr addr; int fd_sock = -1; uint32_t laddr = 0; @@ -980,7 +979,7 @@ public: # endif } -# if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +# ifdef USE_LOAD_BALANCE if (fd_sock > 0) { uint8_t my_loadavg = u_get_loadavg(); @@ -1242,7 +1241,7 @@ UServer_Base::~UServer_Base() if (host) delete host; -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (throttling_rec) delete throttling_rec; if (throttling_mask) delete throttling_mask; #endif @@ -1474,6 +1473,7 @@ void UServer_Base::loadConfigParam() U_INTERNAL_ASSERT_POINTER(cfg) + // -------------------------------------------------------------------------------------------------------------------------------------- // userver - configuration parameters // -------------------------------------------------------------------------------------------------------------------------------------- // ENABLE_IPV6 flag indicating the use of ipv6 @@ -2445,12 +2445,10 @@ void UServer_Base::init() U_INTERNAL_ASSERT_POINTER(ptr_shared_data) U_INTERNAL_ASSERT_DIFFERS(ptr_shared_data, MAP_FAILED) -#if defined(U_LINUX) && defined(ENABLE_THREAD) -# if (defined(U_LOG_DISABLE) && !defined(USE_LIBZ)) || (defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_)) - bool bpthread_time = true; -# else - bool bpthread_time = (preforked_num_kids >= 4); // intuitive heuristic... -# endif +#if defined(USE_LOAD_BALANCE) || (defined(U_LOG_DISABLE) && !defined(USE_LIBZ)) + bool bpthread_time = true; +#elif defined(U_LINUX) && defined(ENABLE_THREAD) + bool bpthread_time = (preforked_num_kids >= 4); // intuitive heuristic... #else bool bpthread_time = false; #endif @@ -2535,7 +2533,7 @@ void UServer_Base::init() UTimer::insert(pstat); #endif -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (db_throttling) { // set up the throttles timer @@ -2632,7 +2630,7 @@ void UServer_Base::init() U_ERROR("System date not updated"); } -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (throttling_mask) initThrottlingServer(); #endif diff --git a/src/ulib/net/socket.cpp b/src/ulib/net/socket.cpp index c1b63146..697284ed 100644 --- a/src/ulib/net/socket.cpp +++ b/src/ulib/net/socket.cpp @@ -23,7 +23,7 @@ # include #else # include -# ifndef __clang__ +# ifdef U_LINUX U_DUMP_KERNEL_VERSION(LINUX_VERSION_CODE) # endif #endif diff --git a/src/ulib/utility/http2.cpp b/src/ulib/utility/http2.cpp index b40c7c07..2fdc053a 100644 --- a/src/ulib/utility/http2.cpp +++ b/src/ulib/utility/http2.cpp @@ -74,6 +74,12 @@ UHTTP2::HpackError UHTTP2::hpack_error[8]; "\x00\x03" "\x00\x00\x00\x80" // "\x00\x05" "\x00\xff\xff\xff" (h2spec(4.2) fail with this..????) +#define HTTP2_SETTINGS_DEFAULT \ + "\x00\x00\x00" \ + "\x04" \ + "\x00" \ + "\x00\x00\x00\x00" + // ================================ // SETTINGS ACK FRAME // ================================ @@ -896,9 +902,9 @@ void UHTTP2::decodeHeaders(UHashMap* table, HpackDynamicTable* dyntbl, # ifdef DEBUG if (index == 0) hpack_errno = -4; // The decoded or specified index is out of range +# endif if (isHpackError(index)) return; -# endif goto check2; } @@ -911,9 +917,7 @@ void UHTTP2::decodeHeaders(UHashMap* table, HpackDynamicTable* dyntbl, ptr = hpackDecodeInt(ptr, endptr, index, (1<<6)-1); // (63: 00111111) -# ifdef DEBUG if (isHpackError(index)) return; -# endif goto check1; } @@ -932,9 +936,9 @@ void UHTTP2::decodeHeaders(UHashMap* table, HpackDynamicTable* dyntbl, ptr = hpackDecodeInt(ptr, endptr, index, (1<<5)-1); // (31: 00011111) -# ifdef DEBUG if (isHpackError(index)) return; +# ifdef DEBUG if (upd == 1 && (uint32_t)index == dyntbl->hpack_max_capacity) // Omit the minimum of multiple resizes { @@ -1005,9 +1009,7 @@ upd_err: ptr = hpackDecodeInt(ptr, endptr, index, (1<<4)-1); // (15: 00001111) -# ifdef DEBUG if (isHpackError(index)) return; -# endif check1: U_INTERNAL_DUMP("index = %u", index) @@ -1018,17 +1020,15 @@ check1: ptr = hpackDecodeString(ptr, endptr, name); -# ifdef DEBUG if (isHpackError()) return; -# endif if (isHeaderName(name) == false) { hpack_errno = -7; // A invalid header name or value character was coded -# ifdef DEBUG +# ifdef DEBUG if (btest) return; -# endif +# endif nerror = PROTOCOL_ERROR; @@ -1044,9 +1044,7 @@ check1: ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif if (name.first_char() != ':') { @@ -1096,9 +1094,7 @@ check2: { ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif /** * A new entry can reference the name of an entry in the dynamic table that will be evicted when adding this new entry into the dynamic table. @@ -1155,9 +1151,7 @@ cdefault: { ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif } name._assign(entry->name); @@ -1193,9 +1187,7 @@ host: U_INTERNAL_ASSERT_EQUALS(bdecodeHeadersDebug, false) ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif UHTTP::setHostname(value); @@ -1239,9 +1231,7 @@ case_2_3: // GET - POST { ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif switch (u_get_unalignedp32(value.data())) { @@ -1344,9 +1334,7 @@ case_4_5: // :path => / /index.html { ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif setURI(value); } @@ -1457,9 +1445,7 @@ case_16: // accept-encoding: gzip, deflate { ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif } setEncoding(value); @@ -1483,9 +1469,7 @@ case_17: // accept-language ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_http_accept_language_len = value.size(); U_http_info.accept_language = value.data(); @@ -1511,9 +1495,7 @@ case_19: // accept ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_http_accept_len = value.size(); U_http_info.accept = value.data(); @@ -1537,9 +1519,9 @@ case_28: // content_length ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; +# ifdef DEBUG if (bdecodeHeadersDebug == false) # endif { @@ -1565,9 +1547,9 @@ case_31: // content_type ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; +# ifdef DEBUG if (bdecodeHeadersDebug == false) # endif { @@ -1596,9 +1578,7 @@ case_32: // cookie ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif if (U_http_info.cookie_len) value = UString(U_http_info.cookie_len+U_CONSTANT_SIZE("; ")+value.size(), U_CONSTANT_TO_PARAM("%.*s; %v"), U_HTTP_COOKIE_TO_TRACE, value.rep); @@ -1624,9 +1604,7 @@ case_35: // expect ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_INTERNAL_DUMP("name = %V value = %V", hpack_static_table[35-1].name, value.rep) @@ -1660,9 +1638,7 @@ case_40: // if-modified-since ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_http_info.if_modified_since = UTimeDate::getSecondFromTime(value.data(), true); @@ -1687,9 +1663,7 @@ case_50: // range ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_http_range_len = value.size() - U_CONSTANT_SIZE("bytes="); U_http_info.range = value.data() + U_CONSTANT_SIZE("bytes="); @@ -1715,9 +1689,7 @@ case_51: // referer ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_http_info.referer = value.data(); U_http_info.referer_len = value.size(); @@ -1751,9 +1723,7 @@ case_58: // user-agent ptr = hpackDecodeString(ptr, endptr, value); -# ifdef DEBUG if (isHpackError()) return; -# endif U_http_info.user_agent = value.data(); U_http_info.user_agent_len = value.size(); @@ -2325,6 +2295,8 @@ window_update: U_INTERNAL_DUMP("GOAWAY: Last-Stream-ID = %u", u_http2_parse_sid(frame.payload)) + UClientImage_Base::setCloseConnection(); + goto ret; } @@ -2597,8 +2569,6 @@ void UHTTP2::handlerResponse() { U_TRACE_NO_PARAM(0, "UHTTP2::handlerResponse()") - U_INTERNAL_ASSERT(bsetting_ack) - U_INTERNAL_ASSERT(bsetting_send) U_INTERNAL_ASSERT_MAJOR(pStream->state, STREAM_STATE_OPEN) uint32_t sz1 = UHTTP::set_cookie->size(), @@ -2943,7 +2913,8 @@ void UHTTP2::writeResponse() u_write_unalignedp32(ptr1+5,pStream->id); - U_SRV_LOG_WITH_ADDR("send response (%s,id:%u,bytes:%u) %#.*S to", pConnection->bnghttp2 ? "nghttp2" : "HTTP2", pStream->id, sz0+body_sz, sz0, ptr0); + U_SRV_LOG_WITH_ADDR("send response (%s,id:%u,bytes:%u) %#.*S to", pConnection->bnghttp2 ? "nghttp2" : "HTTP2", + pStream->id, sz0+HTTP2_FRAME_HEADER_SIZE+(body_sz ? body_sz+HTTP2_FRAME_HEADER_SIZE : 0), sz0, ptr0); if (body_sz == 0) { @@ -3034,10 +3005,11 @@ loop: } } -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) -void UHTTP2::wrapRequest() +// HTTP2 => HTTP1 + +void UHTTP2::downgradeRequest() { - U_TRACE_NO_PARAM(0, "UHTTP2::wrapRequest()") + U_TRACE_NO_PARAM(0, "UHTTP2::downgradeRequest()") UClientImage_Base::request->setBuffer(U_http_info.uri_len + U_http_info.query_len + @@ -3081,11 +3053,81 @@ void UHTTP2::wrapRequest() (void) UClientImage_Base::request->append(U_CONSTANT_TO_PARAM(U_CRLF)); } + +#ifdef USE_LOAD_BALANCE +bool UHTTP2::bproxy; + +void UHTTP2::wrapRequest() +{ + U_TRACE_NO_PARAM(0, "UHTTP2::wrapRequest()") + + U_INTERNAL_ASSERT_EQUALS(pStream, pStreamEnd) + + bproxy = true; + + uint32_t sz0 = pStream->headers.size(), + body_sz = UClientImage_Base::body->size(); + + U_DUMP("pStream->id = %d pStream->state = (%u, %s) pStream->headers(%u) = %V pStream->clength = %u pStream->body(%u) = %V", + pStream->id, pStream->state, getStreamStatusDescription(), sz0, pStream->headers.rep, pStream->clength, body_sz, pStream->body.rep) + + U_INTERNAL_ASSERT_MAJOR(sz0, 0) + + UClientImage_Base::request->setBuffer(sz0 + body_sz + 100); + + char* p0 = UClientImage_Base::request->data(); + + /** + * to avoid the response by userver: (24 bytes) + * + * SETTINGS Frame + * | Parameters: + * | MAX_CONCURRENT_STREAMS (0x3): 128 + * + * SETTINGS Frame + * | Flags: + * | - ACK (0x1) + * + * we don't write: + * + * U_MEMCPY(p0, HTTP2_CONNECTION_PREFACE HTTP2_SETTINGS_DEFAULT HTTP2_SETTINGS_ACK, U_CONSTANT_SIZE(HTTP2_CONNECTION_PREFACE HTTP2_SETTINGS_DEFAULT HTTP2_SETTINGS_ACK)); + * p0 += U_CONSTANT_SIZE(HTTP2_CONNECTION_PREFACE HTTP2_SETTINGS_DEFAULT HTTP2_SETTINGS_ACK); + */ + + u_http2_write_len_and_type(p0,sz0,HEADERS); + + p0[4] = FLAG_END_HEADERS | (body_sz == 0); // FLAG_END_STREAM (1) + + u_write_unalignedp32(p0+5,pStream->id); + + p0 += HTTP2_FRAME_HEADER_SIZE; + + U_MEMCPY(p0, pStream->headers.data(), sz0); + p0 += sz0; + + if (body_sz) + { + u_http2_write_len_and_type(p0,body_sz,DATA); + + p0[4] = FLAG_END_STREAM; + + u_write_unalignedp32(p0+5,pStream->id); + + p0 += HTTP2_FRAME_HEADER_SIZE; + + U_MEMCPY(p0, UClientImage_Base::body->data(), body_sz); + p0 += body_sz; + + UClientImage_Base::body->clear(); + } + + UClientImage_Base::request->size_adjust(p0); +} #endif void UHTTP2::handlerDelete(UClientImage_Base* pclient, bool& bsocket_open) { - U_TRACE(0, "UHTTP2::handlerDelete(%p,%b)", pclient, bsocket_open) + U_TRACE(0+256, "UHTTP2::handlerDelete(%p,%b)", pclient, bsocket_open) uint32_t idx = (pclient - UServer_Base::vClientImage); @@ -3119,7 +3161,7 @@ void UHTTP2::handlerDelete(UClientImage_Base* pclient, bool& bsocket_open) { nerror = NO_ERROR; - sendGoAway(); + sendGoAway(pclient->socket); bsocket_open = false; } @@ -3192,6 +3234,8 @@ void UHTTP2::handlerRequest() { U_ClientImage_http(UServer_Base::pClientImage) = '2'; + U_INTERNAL_DUMP("U_http2_settings_len = %u", U_http2_settings_len) + if (U_http2_settings_len) { bsetting_send = true; @@ -3234,7 +3278,7 @@ void UHTTP2::handlerRequest() U_http_version = '2'; U_http_info.endHeader = endHeader; - goto next; + goto next1; } /** @@ -3263,10 +3307,12 @@ void UHTTP2::handlerRequest() U_MEMCPY(UClientImage_Base::cbuffer, UClientImage_Base::request->c_pointer(U_http_uri_offset), sz); } -next: // maybe we have read more data than necessary... +next1: // maybe we have read more data than necessary... sz = UClientImage_Base::rbuffer->size(); + U_INTERNAL_DUMP("sz = %u U_http_info.endHeader = %u", sz, U_http_info.endHeader) + U_INTERNAL_ASSERT_MAJOR(sz, 0) if (sz > U_http_info.endHeader) UClientImage_Base::rstart = U_http_info.endHeader; @@ -3289,12 +3335,19 @@ next: // maybe we have read more data than necessary... u_get_unalignedp64(ptr+8) != U_MULTICHAR_CONSTANT64( 'T', 'P','/','2', '.', '0','\r','\n') || u_get_unalignedp64(ptr+16) != U_MULTICHAR_CONSTANT64('\r','\n','S','M','\r','\n','\r','\n')) { +# ifndef USE_LOAD_BALANCE goto err; +# else + goto next2; +# endif } UClientImage_Base::rstart += U_CONSTANT_SIZE(HTTP2_CONNECTION_PREFACE); } +#ifdef USE_LOAD_BALANCE +next2: +#endif UClientImage_Base::request->clear(); read_request: @@ -3341,10 +3394,12 @@ read_request: return; } +# ifndef USE_LOAD_BALANCE if (bsetting_ack == false) goto read_request; // we must wait for SETTINGS ack... U_INTERNAL_ASSERT(bsetting_ack) U_INTERNAL_ASSERT(bsetting_send) +# endif if (U_http_info.uri_len) { @@ -3436,6 +3491,28 @@ process_request: if (U_ClientImage_parallelization == U_PARALLELIZATION_PARENT) goto end; } +# ifdef USE_LOAD_BALANCE + U_INTERNAL_DUMP("bproxy = %b", bproxy) + + if (bproxy) + { + bproxy = false; + + uint32_t sz0 = UClientImage_Base::wbuffer->size(); + const char* ptr0 = UClientImage_Base::wbuffer->data(); + + U_INTERNAL_ASSERT_MAJOR(sz0, 0) + + U_SRV_LOG_WITH_ADDR("send response (HTTP2,id:%u,bytes:%u) %#.*S to", pStream->id, sz0, sz0, ptr0); + + if (USocketExt::write(UServer_Base::csocket, ptr0, sz0, 0) != (int)sz0) nerror = CONNECT_ERROR; + +# ifdef DEBUG + // (void) UFile::writeToTmp(ptr0, sz0, O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("load_balance_response.%P"), 0); +# endif + } + else +# endif writeResponse(); U_INTERNAL_DUMP("nerror = %u", nerror) @@ -3472,11 +3549,13 @@ process_request: } # endif - return; + U_INTERNAL_DUMP("U_ClientImage_close = %b", U_ClientImage_close) + + if (U_ClientImage_close == false) return; } err: - if (UServer_Base::csocket->isOpen()) sendGoAway(); + if (UServer_Base::csocket->isOpen()) sendGoAway(UServer_Base::csocket); U_ClientImage_state = U_PLUGIN_HANDLER_ERROR; @@ -3625,12 +3704,12 @@ void UHTTP2::sendPing() if (USocketExt::write(UServer_Base::csocket, buffer, sizeof(buffer), 0) != sizeof(buffer)) nerror = CONNECT_ERROR; } -void UHTTP2::sendGoAway() +void UHTTP2::sendGoAway(USocket* psocket) { - U_TRACE_NO_PARAM(0, "UHTTP2::sendGoAway()") + U_TRACE(0, "UHTTP2::sendGoAway(%p)", psocket) + U_INTERNAL_ASSERT(psocket->isOpen()) U_INTERNAL_ASSERT_POINTER(pConnection) - U_INTERNAL_ASSERT(UServer_Base::csocket->isOpen()) char buffer[HTTP2_FRAME_HEADER_SIZE+8] = { 0, 0, 8, // frame size GOAWAY, // header frame @@ -3650,7 +3729,7 @@ void UHTTP2::sendGoAway() pConnection->state = CONN_STATE_IS_CLOSING; - if (USocketExt::write(UServer_Base::csocket, buffer, sizeof(buffer), 0) == sizeof(buffer)) UClientImage_Base::close(); + if (USocketExt::write(psocket, buffer, sizeof(buffer), 0) == sizeof(buffer)) UClientImage_Base::close(); } void UHTTP2::sendResetStream() diff --git a/src/ulib/utility/semaphore.cpp b/src/ulib/utility/semaphore.cpp index ab1b3cbe..666e1d4b 100644 --- a/src/ulib/utility/semaphore.cpp +++ b/src/ulib/utility/semaphore.cpp @@ -16,7 +16,7 @@ #include #include -#if defined(U_LINUX) && !defined(__clang__) +#ifdef U_LINUX U_DUMP_KERNEL_VERSION(LINUX_VERSION_CODE) #endif diff --git a/src/ulib/utility/uhttp.cpp b/src/ulib/utility/uhttp.cpp index 2404ce4e..af1213e6 100644 --- a/src/ulib/utility/uhttp.cpp +++ b/src/ulib/utility/uhttp.cpp @@ -23,8 +23,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -47,11 +47,11 @@ #ifdef HAVE_LIBTCC # include #endif +#ifdef USE_LOAD_BALANCE +# include +#endif #ifndef _MSWINDOWS_ # include -# ifdef USE_LOAD_BALANCE -# include -# endif #endif #ifdef U_HTTP_INOTIFY_SUPPORT @@ -164,8 +164,8 @@ USSLSession* UHTTP::data_session_ssl; UVector* UHTTP::vallow_IP; URDBObjectHandler* UHTTP::db_session_ssl; #endif -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) -UHttpClient* UHTTP::client_http; +#ifdef USE_LOAD_BALANCE +UClient* UHTTP::client_http; #endif #ifdef U_HTTP_STRICT_TRANSPORT_SECURITY UString* UHTTP::uri_strict_transport_security_mask; @@ -173,7 +173,7 @@ UString* UHTTP::uri_strict_transport_security_mask; #ifndef U_LOG_DISABLE char UHTTP::iov_buffer[20]; struct iovec UHTTP::iov_vec[10]; -# if !defined(U_CACHE_REQUEST_DISABLE) || (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) +# if !defined(U_CACHE_REQUEST_DISABLE) || defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) uint32_t UHTTP::agent_offset; uint32_t UHTTP::request_offset; uint32_t UHTTP::referer_offset; @@ -350,7 +350,7 @@ UHTTP::UFileCacheData::~UFileCacheData() if (array) delete array; -#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) if (wd != -1 && UServer_Base::handler_inotify && UServer_Base::isChild() == false) @@ -365,7 +365,7 @@ UHTTP::UFileCacheData::~UFileCacheData() // INOTIFY FOR CACHE FILE SYSTEM -#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) int UHTTP::inotify_wd; char* UHTTP::inotify_name; uint32_t UHTTP::inotify_len; @@ -1034,11 +1034,16 @@ void UHTTP::init() if (msg) { U_SRV_LOG("%s", msg); } #endif -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) - U_NEW(UHttpClient, client_http, UHttpClient((UFileConfig*)0)); +#ifdef USE_LOAD_BALANCE + U_NEW(UClient, client_http, UClient((UFileConfig*)0)); - client_http->getResponseHeader()->setIgnoreCase(false); - client_http->UClient_Base::setActive(UServer_Base::bssl); +# ifndef U_LOG_DISABLE + if (UServer_Base::isLog()) client_http->setLogShared(); +# endif + + // TODO: we can check if there is a userver_tcp for response (HTTP Strict Transport Security management)... + + client_http->setActive(UServer_Base::bssl); #endif /** @@ -1383,7 +1388,7 @@ void UHTTP::dtor() { U_TRACE_NO_PARAM(0, "UHTTP::dtor()") -#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +#if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) if (UServer_Base::handler_inotify && // inotify: Inode based directory notification... UServer_Base::handler_inotify->fd != -1) { @@ -1458,7 +1463,7 @@ void UHTTP::dtor() # ifdef USE_LIBV8 if (v8_javascript) delete v8_javascript; # endif -# if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +# ifdef USE_LOAD_BALANCE if (client_http) delete client_http; # endif @@ -3618,7 +3623,7 @@ bool UHTTP::handlerCache() U_INTERNAL_ASSERT(U_ClientImage_request_is_cached) -#if !defined(U_CACHE_REQUEST_DISABLE) || (defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE)) +#if !defined(U_CACHE_REQUEST_DISABLE) || defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) const char* ptr = UClientImage_Base::request->data(); switch (u_get_unalignedp32(ptr)) @@ -3730,7 +3735,7 @@ next2: } # endif -# if defined(U_SERVER_CHECK_TIME_BETWEEN_REQUEST) && defined(U_HTTP2_DISABLE) +# ifdef U_SERVER_CHECK_TIME_BETWEEN_REQUEST if (U_ClientImage_advise_for_parallelization == 2) U_RETURN(true); # endif @@ -3771,6 +3776,62 @@ next2: U_RETURN(false); } +#if defined(U_HTTP_STRICT_TRANSPORT_SECURITY) || defined(USE_LIBSSL) +bool UHTTP::isValidation() +{ + U_TRACE_NO_PARAM(0, "UHTTP::isValidation()") + +#ifdef U_HTTP_STRICT_TRANSPORT_SECURITY + if (isUriRequestStrictTransportSecurity()) // check if the uri requested use HTTP Strict Transport Security to force client to use secure connections only + { + UString redirect_url(U_CAPACITY); + + // NB: we are in cleartext at the moment, prevent further execution and output + + redirect_url.snprintf(U_CONSTANT_TO_PARAM("%s:/%v"), U_http_websocket_len ? "wss" : "https", UServer_Base::getIPAddress().rep); + + if (global_alias) (void) redirect_url.append(*global_alias); + else (void) redirect_url.append(U_HTTP_URI_QUERY_TO_PARAM); + + // The Strict-Transport-Security header is ignored by the browser when your site is accessed using HTTP; + // this is because an attacker may intercept HTTP connections and inject the header or remove it. + // When your site is accessed over HTTPS with no certificate errors, the browser knows your site is HTTPS + // capable and will honor the Strict-Transport-Security header + + U_INTERNAL_DUMP("ext = %V", ext->rep) + + ext->clear(); + + setRedirectResponse(NO_BODY, U_STRING_TO_PARAM(redirect_url)); + + U_SRV_LOG("URI_STRICT_TRANSPORT_SECURITY: request redirected to %V", redirect_url.rep); + + U_RETURN(false); + } +#endif + +#ifdef USE_LIBSSL + if (isUriRequestNeedCertificate() && // check if the uri requested need a certificate + UServer_Base::pClientImage->askForClientCertificate() == false) + { + U_SRV_LOG("URI_REQUEST_CERT: request denied by mandatory certificate from client"); + + setForbidden(); + + U_RETURN(false); + } + + if (isUriRequestProtected() && // check if the uri requested is protected + checkUriProtected() == false) + { + U_RETURN(false); + } +#endif + + U_RETURN(true); +} +#endif + int UHTTP::handlerREAD() { U_TRACE_NO_PARAM(0, "UHTTP::handlerREAD()") @@ -3912,7 +3973,17 @@ int UHTTP::handlerREAD() UClientImage_Base::size_request = (U_http_info.endHeader ? U_http_info.endHeader : U_http_info.startHeader + U_CONSTANT_SIZE(U_CRLF2)); - U_INTERNAL_DUMP("U_http_info.clength = %u", U_http_info.clength) + U_INTERNAL_DUMP("UClientImage_Base::size_request = %u U_http_info.clength = %u", UClientImage_Base::size_request, U_http_info.clength) + + /* NB: readBodyRequest() depend on UClientImage_Base::request + * + * if (UClientImage_Base::size_request < UClientImage_Base::request->size()) + * { + * *UClientImage_Base::request = UClientImage_Base::rbuffer->substr(UClientImage_Base::rstart, UClientImage_Base::size_request); + * + * U_INTERNAL_DUMP("UClientImage_Base::request(%u) = %V", UClientImage_Base::request->size(), UClientImage_Base::request->rep) + * } + */ if (isGETorHEAD() == false) { @@ -3944,6 +4015,8 @@ int UHTTP::handlerREAD() # endif } + U_INTERNAL_DUMP("UClientImage_Base::size_request = %u", UClientImage_Base::size_request) + U_ClientImage_state = manageRequest(); U_RETURN(U_ClientImage_state); @@ -4077,7 +4150,7 @@ set_uri: U_http_info.uri = alias->data(); // process the HTTP message -#if defined(U_THROTTLING_SUPPORT) && defined(U_HTTP2_DISABLE) +#ifdef U_THROTTLING_SUPPORT if (isGETorHEAD() && UServer_Base::checkThrottling() == false) { @@ -4230,6 +4303,10 @@ manage: UClientImage_Base::isRequestInFileCache()) // => 3) { file_in_cache: +# if defined(U_HTTP_STRICT_TRANSPORT_SECURITY) || defined(USE_LIBSSL) + if (isValidation() == false) U_RETURN(U_PLUGIN_HANDLER_FINISHED); +# endif + mime_index = file_data->mime_index; U_INTERNAL_DUMP("mime_index(%d) = %C u_is_ssi() = %b", mime_index, mime_index, u_is_ssi(mime_index)) @@ -4272,7 +4349,7 @@ file_in_cache: { U_INTERNAL_ASSERT_DIFFERS(U_ClientImage_parallelization, U_PARALLELIZATION_PARENT) -# if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +# ifdef USE_LOAD_BALANCE if (UClientImage_Base::isNoHeaderForResponse() == false) # endif setDynamicResponse(); @@ -4348,68 +4425,18 @@ file_exist_and_need_to_be_processed: // NB: if we can't service the content of f } # if defined(U_HTTP_STRICT_TRANSPORT_SECURITY) || defined(USE_LIBSSL) - goto need_to_be_processed; -# else - goto end; + if (isValidation() == false) U_RETURN(U_PLUGIN_HANDLER_FINISHED); # endif + + goto end; } #if defined(U_HTTP_STRICT_TRANSPORT_SECURITY) || defined(USE_LIBSSL) - if (UClientImage_Base::isRequestNotFound() == false) // => 4) + if ( UClientImage_Base::isRequestNotFound() == false && // => 4) + (UClientImage_Base::isRequestAlreadyProcessed() || // => 5) + isValidation() == false)) { - if (UClientImage_Base::isRequestAlreadyProcessed()) U_RETURN(U_PLUGIN_HANDLER_FINISHED); // => 5) - -need_to_be_processed: - U_INTERNAL_DUMP("ext = %V", ext->rep) - - // check if the uri requested use HTTP Strict Transport Security to force client to use secure connections only - -# ifdef U_HTTP_STRICT_TRANSPORT_SECURITY - if (isUriRequestStrictTransportSecurity()) - { - ext->clear(); - - // NB: we are in cleartext at the moment, prevent further execution and output - - UString redirect_url(U_CAPACITY); - - redirect_url.snprintf(U_CONSTANT_TO_PARAM("%s:/%v"), U_http_websocket_len ? "wss" : "https", UServer_Base::getIPAddress().rep); - - if (global_alias) (void) redirect_url.append(*global_alias); - else (void) redirect_url.append(U_HTTP_URI_QUERY_TO_PARAM); - - // The Strict-Transport-Security header is ignored by the browser when your site is accessed using HTTP; - // this is because an attacker may intercept HTTP connections and inject the header or remove it. - // When your site is accessed over HTTPS with no certificate errors, the browser knows your site is HTTPS - // capable and will honor the Strict-Transport-Security header - - setRedirectResponse(NO_BODY, U_STRING_TO_PARAM(redirect_url)); - - U_SRV_LOG("URI_STRICT_TRANSPORT_SECURITY: request redirected to %V", redirect_url.rep); - - U_RETURN(U_PLUGIN_HANDLER_FINISHED); - } -# endif - -# ifdef USE_LIBSSL - if (isUriRequestNeedCertificate() && // check if the uri requested need a certificate - UServer_Base::pClientImage->askForClientCertificate() == false) - { - U_SRV_LOG("URI_REQUEST_CERT: request denied by mandatory certificate from client"); - - setForbidden(); - - U_RETURN(U_PLUGIN_HANDLER_FINISHED); - } - - if (isUriRequestProtected() && // check if the uri requested is protected - checkUriProtected() == false) - { - U_RETURN(U_PLUGIN_HANDLER_FINISHED); - } -# else - ; -# endif + U_RETURN(U_PLUGIN_HANDLER_FINISHED); } #endif @@ -4425,9 +4452,7 @@ need_to_be_processed: } #endif -#if !defined(U_HTTP_STRICT_TRANSPORT_SECURITY) && !defined(USE_LIBSSL) end: -#endif #ifdef DEBUG if (file_data && UClientImage_Base::isRequestInFileCache() && @@ -4444,12 +4469,8 @@ end: if (UClientImage_Base::isRequestFileCacheProcessed()) handlerResponse(); #ifndef U_HTTP2_DISABLE - U_INTERNAL_DUMP("UClientImage_Base::size_request = %u", UClientImage_Base::size_request) - if (UClientImage_Base::size_request == 0) { - U_INTERNAL_DUMP("U_ClientImage_state = %u %B", U_ClientImage_state, U_ClientImage_state) - U_INTERNAL_ASSERT_EQUALS(U_http_version, '2') U_INTERNAL_ASSERT(UServer_Base::csocket->isOpen()) U_INTERNAL_ASSERT_EQUALS(U_ClientImage_data_missing, false) @@ -4470,9 +4491,9 @@ end: U_RETURN(U_PLUGIN_HANDLER_FINISHED); } -//#define TEST_ON_LOCALHOST +//#define TEST_LOAD_BALANCE_ON_LOCALHOST -#if defined(USE_LOAD_BALANCE) && !defined(_MSWINDOWS_) +#ifdef USE_LOAD_BALANCE bool UHTTP::manageRequestOnRemoteServer() { U_TRACE_NO_PARAM(0, "UHTTP::manageRequestOnRemoteServer()") @@ -4482,7 +4503,7 @@ bool UHTTP::manageRequestOnRemoteServer() U_INTERNAL_ASSERT_POINTER(client_http) -#ifdef TEST_ON_LOCALHOST +#ifdef TEST_LOAD_BALANCE_ON_LOCALHOST if (u_get_unalignedp32(&U_SRV_MIN_LOAD_REMOTE_IP) == U_MULTICHAR_CONSTANT32(127,0,0,1)) U_RETURN(false); u_put_unalignedp32(&U_SRV_MIN_LOAD_REMOTE_IP, U_MULTICHAR_CONSTANT32(127,0,0,1)); #else @@ -4493,34 +4514,23 @@ bool UHTTP::manageRequestOnRemoteServer() // before connect to remote server check if it has changed... if (client_http->setHostPort(UIPAddress::toString(U_SRV_MIN_LOAD_REMOTE_IP), UServer_Base::port) && - client_http->UClient_Base::isConnected()) + client_http->isConnected()) { - client_http->UClient_Base::close(); + client_http->close(); } - U_INTERNAL_DUMP("U_http_version = %C", U_http_version) - # ifndef U_HTTP2_DISABLE - bool bhttp2; - if ((bhttp2 = (U_http_version == '2'))) UHTTP2::wrapRequest(); + if (U_http_version == '2') UHTTP2::wrapRequest(); # endif - client_http->prepareRequest(*UClientImage_Base::request, *UClientImage_Base::body); - // connect to remote server, send request and get response - if (client_http->sendRequestEngine()) + if (client_http->sendRequestAndReadResponse(*UClientImage_Base::request, *UClientImage_Base::body)) { UClientImage_Base::setNoHeaderForResponse(); *UClientImage_Base::wbuffer = client_http->getResponse(); -# ifndef U_HTTP2_DISABLE - if (bhttp2) UHTTP2::wrapResponse(); -# endif - - client_http->reset(); // reset reference to request... - U_RETURN(true); } } @@ -5020,7 +5030,7 @@ void UHTTP::setEndRequestProcessing() : u__snprintf(iov_buffer, sizeof(iov_buffer), U_CONSTANT_TO_PARAM("\" %u %u \""), U_http_info.nResponseCode, body_len)); } -# if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE if (iov_vec[4].iov_len != 1 && U_ClientImage_request_is_cached == false) { @@ -5057,7 +5067,7 @@ void UHTTP::setEndRequestProcessing() U_INTERNAL_DUMP("U_ClientImage_request = %b U_http_info.nResponseCode = %d U_ClientImage_request_is_cached = %b U_http_info.startHeader = %u", U_ClientImage_request, U_http_info.nResponseCode, U_ClientImage_request_is_cached, U_http_info.startHeader) -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +#ifndef U_CACHE_REQUEST_DISABLE if (isGETorHEAD() && UClientImage_Base::isRequestCacheable() && U_IS_HTTP_SUCCESS(U_http_info.nResponseCode)) @@ -8798,7 +8808,7 @@ nocontent: } # endif -# if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) && !defined(U_SERVER_CAPTIVE_PORTAL) +# if defined(HAVE_SYS_INOTIFY_H) && defined(U_HTTP_INOTIFY_SUPPORT) bool bstat = false; if (db_not_found) @@ -10767,7 +10777,7 @@ void UHTTP::prepareApacheLikeLog() const char* request; uint32_t request_len; -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +#ifndef U_CACHE_REQUEST_DISABLE agent_offset = request_offset = referer_offset = 0; @@ -10842,7 +10852,7 @@ void UHTTP::prepareApacheLikeLog() iov_vec[4].iov_base = (caddr_t) request; iov_vec[4].iov_len = U_min(1000, request_len); -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE request_offset = request - prequest; U_INTERNAL_DUMP("request_offset = %u", request_offset) @@ -10856,7 +10866,7 @@ next: iov_vec[6].iov_base = (caddr_t) U_http_info.referer; iov_vec[6].iov_len = U_min(1000, U_http_info.referer_len); -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE if (U_http_info.referer > prequest) { referer_offset = U_http_info.referer - prequest; @@ -10872,7 +10882,7 @@ next: iov_vec[8].iov_base = (caddr_t) U_http_info.user_agent; iov_vec[8].iov_len = U_min(1000, U_http_info.user_agent_len); -#if !defined(U_CACHE_REQUEST_DISABLE) && defined(U_HTTP2_DISABLE) +# ifndef U_CACHE_REQUEST_DISABLE if (U_http_info.user_agent > prequest) { agent_offset = U_http_info.user_agent - prequest; diff --git a/tests/examples/businesses.test b/tests/examples/businesses.test index 96d9c089..46c6eea5 100755 --- a/tests/examples/businesses.test +++ b/tests/examples/businesses.test @@ -29,8 +29,6 @@ rm -rf $DOC_ROOT/*log /tmp/request.* /tmp/response.* \ trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \ $DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]* -check_for_netcat - cat <inp/webserver.cfg userver { PORT 8080 @@ -44,21 +42,28 @@ http { } EOF +check_for_netcat + export MONGODB_HOST=localhost DIR_CMD="../../examples/userver" start_prg_background userver_tcp -c inp/webserver.cfg - send_req $NCAT localhost 8080 inp/http/businesses1.req businesses 2 - send_req $NCAT localhost 8080 inp/http/businesses2.req businesses 2 - send_req $NCAT localhost 8080 inp/http/businesses3.req businesses 2 - send_req $NCAT localhost 8080 inp/http/businesses4.req businesses 2 +wait_server_ready localhost 8080 + + send_req $NCAT localhost 8080 inp/http/businesses1.req businesses 2 kill + send_req $NCAT localhost 8080 inp/http/businesses2.req businesses 2 kill + send_req $NCAT localhost 8080 inp/http/businesses3.req businesses 2 kill + send_req $NCAT localhost 8080 inp/http/businesses4.req businesses 2 kill #JSON_REQ=`tail -1 inp/http/businesses1.req` +#/opt/go/bin/h2a -p 80 -H localhost -P 8080 -d -D +#ncat -4 localhost 80 < load_balance_response.31878 +#curl -v --http2-prior-knowledge http://localhost/servlet/businesses -d "$JSON_REQ" http://localhost/businesses >out/businesses.out #curl -v --http2-prior-knowledge http://localhost:8080/servlet/businesses -d "$JSON_REQ" http://localhost/businesses >out/businesses.out -kill_prg userver_tcp TERM +kill_server userver_tcp mv err/userver_tcp.err err/businesses.err diff --git a/tests/examples/ok/businesses.ok b/tests/examples/ok/businesses.ok index d7d38eef..8d8a83b5 100644 --- a/tests/examples/ok/businesses.ok +++ b/tests/examples/ok/businesses.ok @@ -1,25 +1,22 @@ HTTP/1.1 200 OK -Date: Sun, 19 Feb 2017 16:40:41 GMT +Date: Sun, 05 Mar 2017 16:39:37 GMT Server: ULib -Connection: close Content-Length: 56 Content-Type: application/json {"name":"","rating":"","address":"","phone":"","url":""}HTTP/1.1 200 OK -Date: Sun, 19 Feb 2017 16:40:41 GMT +Date: Sun, 05 Mar 2017 16:40:08 GMT Server: ULib -Connection: close Content-Length: 0 HTTP/1.1 200 OK -Date: Sun, 19 Feb 2017 16:40:41 GMT +Date: Sun, 05 Mar 2017 16:40:39 GMT Server: ULib -Connection: close Content-Length: 87 Content-Type: application/json {"type":"startup","token":"","fbPermissions":["public_profile","user_friends","email"]}HTTP/1.1 400 Bad Request -Date: Sun, 19 Feb 2017 16:40:41 GMT +Date: Sun, 05 Mar 2017 16:41:09 GMT Server: ULib Connection: close Content-Type: text/html; charset=UTF-8 diff --git a/tests/examples/web_server.sh b/tests/examples/web_server.sh index 5a4d5f85..c38bfcc8 100755 --- a/tests/examples/web_server.sh +++ b/tests/examples/web_server.sh @@ -36,7 +36,7 @@ start_test() { #/usr/bin/spawn-fcgi -p 8080 -f /usr/bin/php-cgi -C 5 -P /var/run/spawn-fcgi.pid # ================================================================= -# HTTP/2 +# HTTP2 # ================================================================= # ./h2a -c server.crt -k server.key -p 8000 -H 127.0.0.1 -P 443 # @@ -86,6 +86,7 @@ ALIAS "[ / /100.html ]" #DIGEST_AUTHENTICATION yes #CACHE_FILE_STORE nocat/webif.gz #CACHE_FILE_MASK inp/http/data/file1|*.flv|*.svgz +#URI_REQUEST_STRICT_TRANSPORT_SECURITY_MASK * } EOF @@ -100,24 +101,25 @@ compile_usp #STRACE=$TRUSS start_prg_background userver_tcp -c inp/webserver.cfg - # RA/RA.cfg - # deployment.properties + # RA/RA.cfg + # deployment.properties + +wait_server_ready localhost 8080 # HTTP pseudo-streaming for FLV video -#curl -I -s -D - 'http://10.30.1.131/test.flv' -o /dev/null -#curl -I -s -D - 'http://10.30.1.131/test.flv' -o /tmp/test.flv -#curl -s -v -r0-499 'http://10.30.1.131/test.flv' -o /tmp/test.flv -#curl -s -D 'http://10.30.1.131/test.flv?start=669000' -o /tmp/test.flv +#curl -I -s -D - 'http://localhost:8080/test.flv' -o /dev/null +#curl -I -s -D - 'http://localhost:8080/test.flv' -o /tmp/test.flv +#curl -s -v -r0-499 'http://localhost:8080/test.flv' -o /tmp/test.flv +#curl -s -D 'http://localhost:8080/test.flv?start=669000' -o /tmp/test.flv #sleep 6 -#kill_prg userver_tcp TERM +#kill_server userver_tcp mv err/userver_tcp.err err/web_server.err echo "PID = `cat /var/run/userver_tcp.pid`" -# check_for_netcat -# $NCAT 10.30.1.131 80 >out/web_server.out - -#openssl s_client -debug -cert ../ulib/CA/username.crt -key ../ulib/CA/username.key -pass pass:caciucco -CApath ../ulib/CA/CApath -verify 0 -connect 10.30.1.131:80 +#check_for_netcat +#send_req localhost 8080 inp/http/get_geoip.req web_server 3 +#openssl s_client -debug -cert ../ulib/CA/username.crt -key ../ulib/CA/username.key -pass pass:caciucco -CApath ../ulib/CA/CApath -verify 0 -connect localhost:8080