diff options
| author | Oz Linden <oz@lindenlab.com> | 2018-01-17 12:43:28 -0500 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2018-01-17 12:43:28 -0500 | 
| commit | d7c8678c3aa46aed09dce6c1edfc196e72d4b428 (patch) | |
| tree | 538a1ef15c2e28676f6a7618bc1e0b5749e2bcea /indra/llcorehttp | |
| parent | 9e4b977b2fbb565cef88f3d72e07dbdf8cb2cd69 (diff) | |
| parent | 7acbd8ed8d73c507675d45360df07d232c431a8b (diff) | |
merge 5.1.0-release
Diffstat (limited to 'indra/llcorehttp')
| -rw-r--r-- | indra/llcorehttp/CMakeLists.txt | 46 | ||||
| -rw-r--r-- | indra/llcorehttp/_httplibcurl.cpp | 33 | ||||
| -rw-r--r-- | indra/llcorehttp/_httpoprequest.cpp | 184 | ||||
| -rw-r--r-- | indra/llcorehttp/_httpoprequest.h | 4 | ||||
| -rw-r--r-- | indra/llcorehttp/_httppolicy.cpp | 3 | ||||
| -rw-r--r-- | indra/llcorehttp/_httpservice.cpp | 49 | ||||
| -rw-r--r-- | indra/llcorehttp/bufferarray.cpp | 22 | ||||
| -rw-r--r-- | indra/llcorehttp/httpcommon.cpp | 9 | ||||
| -rw-r--r-- | indra/llcorehttp/httpcommon.h | 6 | ||||
| -rw-r--r-- | indra/llcorehttp/httprequest.cpp | 4 | ||||
| -rw-r--r-- | indra/llcorehttp/httprequest.h | 2 | ||||
| -rw-r--r-- | indra/llcorehttp/httpresponse.h | 10 | ||||
| -rw-r--r-- | indra/llcorehttp/httpstats.cpp | 108 | ||||
| -rw-r--r-- | indra/llcorehttp/httpstats.h | 74 | ||||
| -rw-r--r-- | indra/llcorehttp/tests/test_httprequest.hpp | 17 | ||||
| -rw-r--r-- | indra/llcorehttp/tests/test_httpstatus.hpp | 2 | 
16 files changed, 409 insertions, 164 deletions
| diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 831a2813ee..40ec836f12 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -6,6 +6,7 @@ include(00-Common)  include(GoogleMock)  include(CURL)  include(OpenSSL) +include(NGHTTP2)  include(ZLIB)  include(LLCoreHttp)  include(LLAddBuildTest) @@ -30,6 +31,7 @@ set(llcorehttp_SOURCE_FILES      httpoptions.cpp      httprequest.cpp      httpresponse.cpp +    httpstats.cpp      _httplibcurl.cpp      _httpopcancel.cpp      _httpoperation.cpp @@ -57,6 +59,7 @@ set(llcorehttp_HEADER_FILES      httpoptions.h      httprequest.h      httpresponse.h +    httpstats.h      _httpinternal.h      _httplibcurl.h      _httpopcancel.h @@ -92,6 +95,7 @@ target_link_libraries(    ${CURL_LIBRARIES}    ${OPENSSL_LIBRARIES}    ${CRYPTO_LIBRARIES} +  ${NGHTTP2_LIBRARIES}    ${BOOST_THREAD_LIBRARY}    ${BOOST_SYSTEM_LIBRARY}    ) @@ -130,6 +134,7 @@ if (LL_TESTS)        ${CURL_LIBRARIES}        ${OPENSSL_LIBRARIES}        ${CRYPTO_LIBRARIES} +      ${NGHTTP2_LIBRARIES}        ${BOOST_THREAD_LIBRARY}        ${BOOST_SYSTEM_LIBRARY}        ) @@ -137,18 +142,18 @@ if (LL_TESTS)    # If http_proxy is in the current environment (e.g. to fetch s3-proxy    # autobuild packages), suppress it for this integration test: it screws up    # the tests. -  #LL_ADD_INTEGRATION_TEST(llcorehttp -  #                        "${llcorehttp_TEST_SOURCE_FILES}" -  #                        "${test_libs}" -  #                        "-Dhttp_proxy" -  #                        ${PYTHON_EXECUTABLE} -  #                        "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py" -  #                        ) +  LL_ADD_INTEGRATION_TEST(llcorehttp +                          "${llcorehttp_TEST_SOURCE_FILES}" +                          "${test_libs}" +                          "-Dhttp_proxy" +                          ${PYTHON_EXECUTABLE} +                          "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py" +                          )  if (DARWIN)    # Path inside the app bundle where we'll need to copy libraries    set(LL_TEST_DESTINATION_DIR -    ${CMAKE_SOURCE_DIR}/../build-darwin-i386/sharedlibs/Resources +    ${CMAKE_BINARY_DIR}/sharedlibs/Resources    )    # Create the Contents/Resources directory @@ -164,21 +169,23 @@ if (DARWIN)    # Copy the required libraries to the package app    add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR} -    DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib -  ) -  add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR} -    DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib +    COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR} +    DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib    )    add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR} -    DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib +    COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR} +    DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib    )    add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib ${LL_TEST_DESTINATION_DIR} -    DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib +    COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR} +    DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib    ) +  foreach(expat ${EXPAT_COPY}) +    add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD +      COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LL_TEST_DESTINATION_DIR} +      DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} +    ) +  endforeach(expat)  endif (DARWIN) @@ -198,6 +205,7 @@ endif (DARWIN)        ${CURL_LIBRARIES}        ${OPENSSL_LIBRARIES}        ${CRYPTO_LIBRARIES} +      ${NGHTTP2_LIBRARIES}        ${BOOST_THREAD_LIBRARY}        ${BOOST_SYSTEM_LIBRARY}        ) @@ -214,7 +222,7 @@ endif (DARWIN)      # The following come from LLAddBuildTest.cmake's INTEGRATION_TEST_xxxx target.      set_target_properties(http_texture_load                            PROPERTIES -                          LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE ${TCMALLOC_LINK_FLAGS}" +                          LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE"                            LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"                            LINK_FLAGS_RELEASE ""                            ) diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index c25e01a318..abd304f6a5 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -40,6 +40,15 @@ namespace  void check_curl_multi_code(CURLMcode code);  void check_curl_multi_code(CURLMcode code, int curl_setopt_option); +// This is a template because different 'option' values require different +// types for 'ARG'. Just pass them through unchanged (by value). +template <typename ARG> +void check_curl_multi_setopt(CURLM* handle, CURLMoption option, ARG argument) +{ +    CURLMcode code = curl_multi_setopt(handle, option, argument); +    check_curl_multi_code(code, option); +} +  static const char * const LOG_CORE("CoreHttp");  } // end anonymous namespace @@ -461,46 +470,38 @@ void HttpLibcurl::policyUpdated(int policy_class)  		HttpPolicyClass & options(policy.getClassOptions(policy_class));  		CURLM * multi_handle(mMultiHandles[policy_class]); -		CURLMcode code;  		// Enable policy if stalled  		policy.stallPolicy(policy_class, false);  		mDirtyPolicy[policy_class] = false; -		 +  		if (options.mPipelining > 1)  		{  			// We'll try to do pipelining on this multihandle -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_PIPELINING,  									 1L); -			check_curl_multi_code(code, CURLMOPT_PIPELINING); -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_MAX_PIPELINE_LENGTH,  									 long(options.mPipelining)); -			check_curl_multi_code(code, CURLMOPT_MAX_PIPELINE_LENGTH); -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_MAX_HOST_CONNECTIONS,  									 long(options.mPerHostConnectionLimit)); -			check_curl_multi_code(code, CURLMOPT_MAX_HOST_CONNECTIONS); -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_MAX_TOTAL_CONNECTIONS,  									 long(options.mConnectionLimit)); -			check_curl_multi_code(code, CURLMOPT_MAX_TOTAL_CONNECTIONS);  		}  		else  		{ -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_PIPELINING,  									 0L); -			check_curl_multi_code(code, CURLMOPT_PIPELINING); -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_MAX_HOST_CONNECTIONS,  									 0L); -			check_curl_multi_code(code, CURLMOPT_MAX_HOST_CONNECTIONS); -			code = curl_multi_setopt(multi_handle, +			check_curl_multi_setopt(multi_handle,  									 CURLMOPT_MAX_TOTAL_CONNECTIONS,  									 long(options.mConnectionLimit)); -			check_curl_multi_code(code, CURLMOPT_MAX_TOTAL_CONNECTIONS);  		}  	}  	else if (! mDirtyPolicy[policy_class]) diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index fceed8524b..cc49a2af80 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -47,6 +47,8 @@  #include "llhttpconstants.h"  #include "llproxy.h" +#include "httpstats.h" +  // *DEBUG:  "[curl:bugs] #1420" problem and testing.  //  // A pipelining problem, https://sourceforge.net/p/curl/bugs/1420/, @@ -106,6 +108,15 @@ void os_strlower(char * str);  // Error testing and reporting for libcurl status codes  void check_curl_easy_code(CURLcode code, int curl_setopt_option); +// This is a template because different 'option' values require different +// types for 'ARG'. Just pass them through unchanged (by value). +template <typename ARG> +void check_curl_easy_setopt(CURL* handle, CURLoption option, ARG argument) +{ +    CURLcode code = curl_easy_setopt(handle, option, argument); +    check_curl_easy_code(code, option); +} +  static const char * const LOG_CORE("CoreHttp");  } // end anonymous namespace @@ -247,6 +258,8 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)  		response->setHeaders(mReplyHeaders);          response->setRequestURL(mReqURL); +        response->setRequestMethod(methodToString(mReqMethod)); +          if (mReplyOffset || mReplyLength)  		{  			// Got an explicit offset/length in response @@ -452,8 +465,6 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,  // *TODO:  Move this to _httplibcurl where it belongs.  HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  { -	CURLcode code; -	  	// Scrub transport and result data for retried op case  	mCurlActive = false;  	mCurlHandle = NULL; @@ -492,45 +503,28 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  		return HttpStatus(HttpStatus::LLCORE, HE_BAD_ALLOC);  	} -	code = curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); -	check_curl_easy_code(code, CURLOPT_IPRESOLVE); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1); -	check_curl_easy_code(code, CURLOPT_NOSIGNAL); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1); -	check_curl_easy_code(code, CURLOPT_NOPROGRESS); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str()); -	check_curl_easy_code(code, CURLOPT_URL); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle()); -	check_curl_easy_code(code, CURLOPT_PRIVATE); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); -	check_curl_easy_code(code, CURLOPT_ENCODING); - -	code = curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1); -	check_curl_easy_code(code, CURLOPT_AUTOREFERER); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT); -	check_curl_easy_code(code, CURLOPT_MAXREDIRS); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback); -	check_curl_easy_code(code, CURLOPT_WRITEFUNCTION); -    code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, getHandle()); -	check_curl_easy_code(code, CURLOPT_WRITEDATA); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback); -	check_curl_easy_code(code, CURLOPT_READFUNCTION); -    code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, getHandle()); -	check_curl_easy_code(code, CURLOPT_READDATA); -    code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback); -    check_curl_easy_code(code, CURLOPT_SEEKFUNCTION); -    code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, getHandle()); -    check_curl_easy_code(code, CURLOPT_SEEKDATA); - -	code = curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, ""); -	check_curl_easy_code(code, CURLOPT_COOKIEFILE); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str()); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle()); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); + +	check_curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback); +    check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, getHandle()); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback); +    check_curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, getHandle()); +    check_curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback); +    check_curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, getHandle()); + +	check_curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");  	if (gpolicy.mSslCtxCallback)  	{ -		code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback); -		check_curl_easy_code(code, CURLOPT_SSL_CTX_FUNCTION); -        code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, getHandle()); -		check_curl_easy_code(code, CURLOPT_SSL_CTX_DATA); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback); +        check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, getHandle());  		mCallbackSSLVerify = gpolicy.mSslCtxCallback;  	} @@ -548,16 +542,12 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  		dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();          nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;  	} -	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect); -	check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV); -	check_curl_easy_code(code, CURLOPT_SSL_VERIFYPEER); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV); -	check_curl_easy_code(code, CURLOPT_SSL_VERIFYHOST); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV); -    code = curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody); -    check_curl_easy_code(code, CURLOPT_NOBODY); +    check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);  	// The Linksys WRT54G V5 router has an issue with frequent  	// DNS lookups from LAN machines.  If they happen too often, @@ -565,8 +555,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  	// about 700 or so requests and starts issuing TCP RSTs to  	// new connections.  Reuse the DNS lookups for even a few  	// seconds and no RSTs. -	code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout); -	check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);  	if (gpolicy.mUseLLProxy)  	{ @@ -589,81 +578,66 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  	{  		// *TODO:  This is fine for now but get fuller socks5/  		// authentication thing going later.... -		code = curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, gpolicy.mHttpProxy.c_str()); -		check_curl_easy_code(code, CURLOPT_PROXY); -		code = curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); -		check_curl_easy_code(code, CURLOPT_PROXYTYPE); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, gpolicy.mHttpProxy.c_str()); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);  	}  	if (gpolicy.mCAPath.size())  	{ -		code = curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, gpolicy.mCAPath.c_str()); -		check_curl_easy_code(code, CURLOPT_CAPATH); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, gpolicy.mCAPath.c_str());  	}  	if (gpolicy.mCAFile.size())  	{ -		code = curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, gpolicy.mCAFile.c_str()); -		check_curl_easy_code(code, CURLOPT_CAINFO); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, gpolicy.mCAFile.c_str());  	}  	switch (mReqMethod)  	{  	case HOR_GET:          if (nobody == 0) -            code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1); -		check_curl_easy_code(code, CURLOPT_HTTPGET); +            check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);  		break;  	case HOR_POST:  		{ -			code = curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1); -			check_curl_easy_code(code, CURLOPT_POST); -			code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); -			check_curl_easy_code(code, CURLOPT_ENCODING); +			check_curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1); +			check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");  			long data_size(0);  			if (mReqBody)  			{  				data_size = mReqBody->size();  			} -			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL)); -			check_curl_easy_code(code, CURLOPT_POSTFIELDS); -			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size); -			check_curl_easy_code(code, CURLOPT_POSTFIELDSIZE); +			check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL)); +			check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);  			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");  		}  		break;      case HOR_PATCH: -        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH"); -        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST); +        check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");          // fall through.  The rest is the same as PUT      case HOR_PUT:  		{ -			code = curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1); -			check_curl_easy_code(code, CURLOPT_UPLOAD); +			check_curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);  			long data_size(0);  			if (mReqBody)  			{  				data_size = mReqBody->size();  			} -			code = curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size); -			check_curl_easy_code(code, CURLOPT_INFILESIZE); +			check_curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);  			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");  		}  		break;      case HOR_DELETE: -        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE"); -        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST); +        check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");          break;      case HOR_COPY: -        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY"); -        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST); +        check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY");          break;      case HOR_MOVE: -        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "MOVE"); -        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST); +        check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "MOVE");          break;  	default: @@ -681,12 +655,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  	// Tracing  	if (mTracing >= HTTP_TRACE_CURL_HEADERS)  	{ -		code = curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1); -		check_curl_easy_code(code, CURLOPT_VERBOSE); -		code = curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this); -		check_curl_easy_code(code, CURLOPT_DEBUGDATA); -		code = curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback); -		check_curl_easy_code(code, CURLOPT_DEBUGFUNCTION); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback);  	}  	// There's a CURLOPT for this now... @@ -763,6 +734,13 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  		//  		// xfer_timeout *= cpolicy.mPipelining;  		xfer_timeout *= 2L; + +		// Also try requesting HTTP/2. +/******************************/ +		// but for test purposes, only if overriding VIEWERASSET +		if (getenv("VIEWERASSET")) +/******************************/ +		check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);  	}  	// *DEBUG:  Enable following override for timeout handling and "[curl:bugs] #1420" tests      //if (cpolicy.mPipelining) @@ -770,10 +748,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)      //    xfer_timeout = 1L;      //    timeout = 1L;      //} -	code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout); -	check_curl_easy_code(code, CURLOPT_TIMEOUT); -	code = curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout); -	check_curl_easy_code(code, CURLOPT_CONNECTTIMEOUT); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);  	// Request headers  	if (mReqHeaders) @@ -781,15 +757,12 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  		// Caller's headers last to override  		mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders);  	} -	code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders); -	check_curl_easy_code(code, CURLOPT_HTTPHEADER); +	check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);  	if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_USE_RETRY_AFTER))  	{ -		code = curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback); -		check_curl_easy_code(code, CURLOPT_HEADERFUNCTION); -		code = curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this); -		check_curl_easy_code(code, CURLOPT_HEADERDATA); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback); +		check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);  	}  	if (status) @@ -810,6 +783,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void  	}  	const size_t req_size(size * nmemb);  	const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size)); +    HTTPStats::instance().recordDataDown(write_size);  	return write_size;  } @@ -838,7 +812,8 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void  	const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));  	const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size)); -	op->mCurlBodyPos += read_size; +    HTTPStats::instance().recordDataUp(read_size); +    op->mCurlBodyPos += read_size;  	return read_size;  } @@ -1143,6 +1118,25 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe  	return 0;  } +std::string HttpOpRequest::methodToString(const HttpOpRequest::EMethod &e) +{ +    if (e == HOR_COPY) +        return "COPY"; +    else if (e == HOR_DELETE) +        return  "DELETE"; +    else if (e == HOR_GET) +        return "GET"; +    else if (e == HOR_MOVE) +        return "MOVE"; +    else if (e == HOR_PATCH) +        return "PATCH"; +    else if (e == HOR_POST) +        return "POST"; +    else if (e == HOR_PUT) +        return "PUT"; + +    return "UNKNOWN"; +}  }   // end namespace LLCore diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h index 43d49324af..cdbe350785 100644 --- a/indra/llcorehttp/_httpoprequest.h +++ b/indra/llcorehttp/_httpoprequest.h @@ -87,7 +87,8 @@ public:          HOR_COPY,          HOR_MOVE  	}; -	 +    static std::string methodToString(const EMethod &); +  	virtual void stageFromRequest(HttpService *);  	virtual void stageFromReady(HttpService *);  	virtual void stageFromActive(HttpService *); @@ -237,6 +238,7 @@ public:  };  // end class HttpOpRequest +  /// HttpOpRequestCompare isn't an operation but a uniform comparison  /// functor for STL containers that order by priority.  Mainly  /// used for the ready queue container but defined here. diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp index 4889cac9bf..885f0ed61d 100644 --- a/indra/llcorehttp/_httppolicy.cpp +++ b/indra/llcorehttp/_httppolicy.cpp @@ -34,6 +34,7 @@  #include "_httppolicyclass.h"  #include "lltimer.h" +#include "httpstats.h"  namespace  { @@ -444,6 +445,8 @@ bool HttpPolicy::stageAfterCompletion(const HttpOpRequest::ptr_t &op)  	}  	op->stageFromActive(mService); + +    HTTPStats::instance().recordResultCode(op->mStatus.getType());  	return false;						// not active  } diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 6c39fdc61b..49d865cbfa 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -38,7 +38,8 @@  #include "lltimer.h"  #include "llthread.h" - +#include "llexception.h" +#include "llmemory.h"  namespace  { @@ -293,22 +294,42 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)  	ELoopSpeed loop(REQUEST_SLEEP);  	while (! mExitRequested)  	{ -		loop = processRequestQueue(loop); +        try +        { +		    loop = processRequestQueue(loop); -		// Process ready queue issuing new requests as needed -		ELoopSpeed new_loop = mPolicy->processReadyQueue(); -		loop = (std::min)(loop, new_loop); +		    // Process ready queue issuing new requests as needed +		    ELoopSpeed new_loop = mPolicy->processReadyQueue(); +		    loop = (std::min)(loop, new_loop); -		// Give libcurl some cycles -		new_loop = mTransport->processTransport(); -		loop = (std::min)(loop, new_loop); +		    // Give libcurl some cycles +		    new_loop = mTransport->processTransport(); +		    loop = (std::min)(loop, new_loop); -		// Determine whether to spin, sleep briefly or sleep for next request -		if (REQUEST_SLEEP != loop) -		{ -			ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS); -		} -	} +		    // Determine whether to spin, sleep briefly or sleep for next request +		    if (REQUEST_SLEEP != loop) +		    { +			    ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS); +		    } +        } +        catch (const LLContinueError&) +        { +            LOG_UNHANDLED_EXCEPTION(""); +        } +        catch (std::bad_alloc) +        { +            LLMemory::logMemoryInfo(TRUE); + +            //output possible call stacks to log file. +            LLError::LLCallStacks::print(); + +            LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL; +        } +        catch (...) +        { +            CRASH_ON_UNHANDLED_EXCEPTION(""); +        } +    }  	shutdown();  	sState = STOPPED; diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp index 8eaaeed710..be534b3ce4 100644 --- a/indra/llcorehttp/bufferarray.cpp +++ b/indra/llcorehttp/bufferarray.cpp @@ -25,6 +25,8 @@   */  #include "bufferarray.h" +#include "llexception.h" +#include "llmemory.h"  // BufferArray is a list of chunks, each a BufferArray::Block, of contiguous @@ -140,8 +142,22 @@ size_t BufferArray::append(const void * src, size_t len)  		{  			mBlocks.reserve(mBlocks.size() + 5);  		} -		Block * block = Block::alloc(BLOCK_ALLOC_SIZE); -		memcpy(block->mData, c_src, copy_len); +        Block * block; +        try +        { +            block = Block::alloc(BLOCK_ALLOC_SIZE); +        } +        catch (std::bad_alloc) +        { +            LLMemory::logMemoryInfo(TRUE); + +            //output possible call stacks to log file. +            LLError::LLCallStacks::print(); + +            LL_WARNS() << "Bad memory allocation in thrown by Block::alloc in read!" << LL_ENDL; +            break; +        } +        memcpy(block->mData, c_src, copy_len);  		block->mUsed = copy_len;  		llassert_always(block->mUsed <= block->mAlloced);  		mBlocks.push_back(block); @@ -149,7 +165,7 @@ size_t BufferArray::append(const void * src, size_t len)  		c_src += copy_len;  		len -= copy_len;  	} -	return ret; +	return ret - len;  } diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index c423047bb0..1829062af6 100644 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -50,11 +50,12 @@ HttpStatus::type_enum_t EXT_CURL_EASY;  HttpStatus::type_enum_t EXT_CURL_MULTI;  HttpStatus::type_enum_t LLCORE; -HttpStatus::operator unsigned long() const +HttpStatus::operator U32() const  { -	static const int shift(sizeof(unsigned long) * 4); +	// Effectively, concatenate mType (high) with mStatus (low). +	static const int shift(sizeof(mDetails->mStatus) * 8); -	unsigned long result(((unsigned long)mDetails->mType) << shift | (unsigned long)(int)mDetails->mStatus); +	U32 result(U32(mDetails->mType) << shift | U32((int)mDetails->mStatus));  	return result;  } @@ -64,7 +65,7 @@ std::string HttpStatus::toHex() const  	std::ostringstream result;  	result.width(8);  	result.fill('0'); -	result << std::hex << operator unsigned long(); +	result << std::hex << operator U32();  	return result.str();  } diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h index d715fea78f..e4bd4957f8 100644 --- a/indra/llcorehttp/httpcommon.h +++ b/indra/llcorehttp/httpcommon.h @@ -383,10 +383,10 @@ struct HttpStatus  	/// creates an ambiguous second path to integer conversion  	/// which tends to find programming errors such as formatting  	/// the status to a stream (operator<<). -	operator unsigned long() const; -	unsigned long toULong() const +	operator U32() const; +	U32 toULong() const  	{ -		return operator unsigned long(); +		return operator U32();  	}  	/// And to convert to a hex string. diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp index e09f0c3b18..2687f77217 100644 --- a/indra/llcorehttp/httprequest.cpp +++ b/indra/llcorehttp/httprequest.cpp @@ -37,7 +37,7 @@  #include "_httpopsetget.h"  #include "lltimer.h" - +#include "httpstats.h"  namespace  { @@ -62,6 +62,8 @@ HttpRequest::HttpRequest()  	mRequestQueue->addRef();  	mReplyQueue.reset( new HttpReplyQueue() ); + +    HTTPStats::instance().recordHTTPRequest();  } diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h index 17cfdcd7b6..a418eb6a7a 100644 --- a/indra/llcorehttp/httprequest.h +++ b/indra/llcorehttp/httprequest.h @@ -680,7 +680,7 @@ private:  	/// @}  	// End Global State  	// ==================================== -	 +  };  // end class HttpRequest diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h index 0bfa4585c7..b834085e5c 100644 --- a/indra/llcorehttp/httpresponse.h +++ b/indra/llcorehttp/httpresponse.h @@ -204,6 +204,15 @@ public:              return mRequestUrl;          } +    void setRequestMethod(const std::string &method) +        { +            mRequestMethod = method; +        } + +    const std::string &getRequestMethod() const +        { +            return mRequestMethod; +        }  protected:  	// Response data here @@ -217,6 +226,7 @@ protected:  	unsigned int		mRetries;  	unsigned int		m503Retries;      std::string         mRequestUrl; +    std::string         mRequestMethod;  	TransferStats::ptr_t	mStats;  }; diff --git a/indra/llcorehttp/httpstats.cpp b/indra/llcorehttp/httpstats.cpp new file mode 100644 index 0000000000..b2de7f51ff --- /dev/null +++ b/indra/llcorehttp/httpstats.cpp @@ -0,0 +1,108 @@ +/**  + * @file llviewerstats.cpp + * @brief LLViewerStats class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "httpstats.h" +#include "llerror.h" + +namespace LLCore +{ +HTTPStats::HTTPStats() +{ +    resetStats(); +} + + +HTTPStats::~HTTPStats() +{ +} + +void HTTPStats::resetStats() +{ +    mResutCodes.clear(); +    mDataDown.reset(); +    mDataUp.reset(); +    mRequests = 0; +} + + +void HTTPStats::recordResultCode(S32 code) +{ +    std::map<S32, S32>::iterator it; + +    it = mResutCodes.find(code); + +    if (it == mResutCodes.end()) +        mResutCodes[code] = 1; +    else +        (*it).second = (*it).second + 1; + +} + +namespace +{ +    std::string byte_count_converter(F32 bytes) +    { +        static const char unit_suffix[] = { 'B', 'K', 'M', 'G' }; + +        F32 value = bytes; +        int suffix = 0; + +        while ((value > 1024.0) && (suffix < 3)) +        { +            value /= 1024.0; +            ++suffix; +        } + +        std::stringstream out; + +        out << std::setprecision(4) << value << unit_suffix[suffix]; + +        return out.str(); +    } +} + +void HTTPStats::dumpStats() +{ +    std::stringstream out; + +    out << "HTTP DATA SUMMARY" << std::endl; +    out << "HTTP Transfer counts:" << std::endl; +    out << "Data Sent: " << byte_count_converter(mDataUp.getSum()) << "   (" << mDataUp.getSum() << ")" << std::endl; +    out << "Data Recv: " << byte_count_converter(mDataDown.getSum()) << "   (" << mDataDown.getSum() << ")" << std::endl; +    out << "Total requests: " << mRequests << "(request objects created)" << std::endl; +    out << std::endl; +    out << "Result Codes:" << std::endl << "--- -----" << std::endl; + +    for (std::map<S32, S32>::iterator it = mResutCodes.begin(); it != mResutCodes.end(); ++it) +    {  +        out << (*it).first << " " << (*it).second << std::endl; +    } + +    LL_WARNS("HTTP Core") << out.str() << LL_ENDL; +} + + +} diff --git a/indra/llcorehttp/httpstats.h b/indra/llcorehttp/httpstats.h new file mode 100644 index 0000000000..2c713cb548 --- /dev/null +++ b/indra/llcorehttp/httpstats.h @@ -0,0 +1,74 @@ +/**  + * @file llviewerim_peningtats.h + * @brief LLViewerStats class header file + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLVIEWERSTATS_H +#define LL_LLVIEWERSTATS_H + +#include "lltracerecording.h" +#include "lltrace.h" +#include "llstatsaccumulator.h" +#include "llsingleton.h" +#include "llsd.h" + +namespace LLCore +{ +    class HTTPStats : public LLSingleton<HTTPStats> +    { +        LLSINGLETON(HTTPStats); +        virtual ~HTTPStats(); + +    public: +        void resetStats(); + +        typedef LLStatsAccumulator StatsAccumulator; + +        void    recordDataDown(size_t bytes) +        { +            mDataDown.push(bytes); +        } + +        void    recordDataUp(size_t bytes) +        { +            mDataUp.push(bytes); +        } + +        void    recordHTTPRequest() { ++mRequests; } + +        void    recordResultCode(S32 code); + +        void    dumpStats(); +    private: +        StatsAccumulator mDataDown; +        StatsAccumulator mDataUp; + +        S32              mRequests; + +        std::map<S32, S32> mResutCodes; +    }; + + +} +#endif // LL_LLVIEWERSTATS_H diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 6cd7960ecd..b450f3502e 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -215,7 +215,8 @@ void HttpRequestTestObjectType::test<1>()  		HttpRequest::destroyService();  		// make sure we didn't leak any memory -		ensure("Memory returned", mMemTotal == GetMemTotal()); +		// nat 2017-08-15 don't: requires total stasis in every other subsystem +//		ensure("Memory returned", mMemTotal == GetMemTotal());  	}  	catch (...)  	{ @@ -835,7 +836,7 @@ void HttpRequestTestObjectType::test<8>()  		ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) +#if 0 // defined(WIN32)  		// Can only do this memory test on Windows.  On other platforms,  		// the LL logging system holds on to memory and produces what looks  		// like memory leaks... @@ -946,7 +947,7 @@ void HttpRequestTestObjectType::test<9>()  		ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) +#if 0 // defined(WIN32)  		// Can only do this memory test on Windows.  On other platforms,  		// the LL logging system holds on to memory and produces what looks  		// like memory leaks... @@ -1182,7 +1183,7 @@ void HttpRequestTestObjectType::test<11>()  		ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) +#if 0 // defined(WIN32)  		// Can only do this memory test on Windows.  On other platforms,  		// the LL logging system holds on to memory and produces what looks  		// like memory leaks... @@ -1428,7 +1429,7 @@ void HttpRequestTestObjectType::test<13>()  		ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) +#if 0 // defined(WIN32)  		// Can only do this memory test on Windows.  On other platforms,  		// the LL logging system holds on to memory and produces what looks  		// like memory leaks... @@ -1662,7 +1663,7 @@ void HttpRequestTestObjectType::test<15>()  		ensure("Two handler calls on the way out", 2 == mHandlerCalls); -#if defined(WIN32) +#if 0 // defined(WIN32)  		// Can only do this memory test on Windows.  On other platforms,  		// the LL logging system holds on to memory and produces what looks  		// like memory leaks... @@ -3089,6 +3090,10 @@ void HttpRequestTestObjectType::test<23>()  	set_test_name("HttpRequest GET 503s with 'Retry-After'"); +#if LL_WINDOWS && ADDRESS_SIZE == 64 +	skip("llcorehttp 503-with-retry test hangs on Windows 64"); +#endif +  	// This tests mainly that the code doesn't fall over if  	// various well- and mis-formed Retry-After headers are  	// sent along with the response.  Direct inspection of diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp index 4502d32fe1..cbe3f574d4 100644 --- a/indra/llcorehttp/tests/test_httpstatus.hpp +++ b/indra/llcorehttp/tests/test_httpstatus.hpp @@ -244,7 +244,7 @@ void HttpStatusTestObjectType::test<7>()  	HttpStatus status(404);  	std::string msg = status.toHex();  	// std::cout << "Result:  " << msg << std::endl; -	ensure(msg == "01940001"); +	ensure_equals(msg, "01940001");  } | 
