diff options
Diffstat (limited to 'indra/llcorehttp/tests/test_httprequest.hpp')
-rw-r--r-- | indra/llcorehttp/tests/test_httprequest.hpp | 5248 |
1 files changed, 2624 insertions, 2624 deletions
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 3eaac10aeb..aed906bb8f 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_httprequest.hpp * @brief unit tests for the LLCore::HttpRequest class * @@ -51,8 +51,8 @@ using namespace LLCoreInt; // loaded system where the unit test is in competition with // other programs. static const int LOOP_SLEEP_INTERVAL(10000); -static const int LOOP_COUNT_SHORT(500); // 5-second dwell time -static const int LOOP_COUNT_LONG(3000); // 30-second dwell time +static const int LOOP_COUNT_SHORT(500); // 5-second dwell time +static const int LOOP_COUNT_LONG(3000); // 30-second dwell time namespace { @@ -72,117 +72,117 @@ typedef std::vector<std::pair<boost::regex, boost::regex> > regex_container_t; struct HttpRequestTestData { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. - int mHandlerCalls; - HttpStatus mStatus; + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + int mHandlerCalls; + HttpStatus mStatus; }; class TestHandler2 : public LLCore::HttpHandler { public: - TestHandler2(HttpRequestTestData * state, - const std::string & name) - : mState(state), - mName(name), - mExpectHandle(LLCORE_HTTP_HANDLE_INVALID) - {} - - virtual void onCompleted(HttpHandle handle, HttpResponse * response) - { - if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle) - { - ensure("Expected handle received in handler", mExpectHandle == handle); - } - ensure("Handler got a response", NULL != response); - if (response && mState) - { - const HttpStatus actual_status(response->getStatus()); - std::ostringstream test; - test << "Expected HttpStatus received in response. Wanted: " - << mState->mStatus.toHex() << " Received: " << actual_status.toHex(); - ensure(test.str().c_str(), actual_status == mState->mStatus); - } - if (mState) - { - mState->mHandlerCalls++; - } - if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty()) - { - ensure("Response required with header check", response != NULL); - HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this - ensure("Some quantity of headers returned", header != NULL); - - if (! mHeadersRequired.empty()) - { - for (int i(0); i < mHeadersRequired.size(); ++i) - { - bool found = false; - for (HttpHeaders::const_iterator iter(header->begin()); - header->end() != iter; - ++iter) - { - // std::cerr << "Header: " << (*iter).first - // << ": " << (*iter).second << std::endl; - - if (boost::regex_match((*iter).first, - mHeadersRequired[i].first) && - boost::regex_match((*iter).second, - mHeadersRequired[i].second)) - { - found = true; - break; - } - } - std::ostringstream str; - str << "Required header #" << i << " " - << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second - << " not found in response"; - ensure(str.str(), found); - } - } - - if (! mHeadersDisallowed.empty()) - { - for (int i(0); i < mHeadersDisallowed.size(); ++i) - { - for (HttpHeaders::const_iterator iter(header->begin()); - header->end() != iter; - ++iter) - { - if (boost::regex_match((*iter).first, - mHeadersDisallowed[i].first) && - boost::regex_match((*iter).second, - mHeadersDisallowed[i].second)) - { - std::ostringstream str; - str << "Disallowed header #" << i << " " - << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second - << " found in response"; - ensure(str.str(), false); - } - } - } - } - } - - if (! mCheckContentType.empty()) - { - ensure("Response required with content type check", response != NULL); - std::string con_type(response->getContentType()); - ensure("Content-Type as expected (" + mCheckContentType + ")", - mCheckContentType == con_type); - } - - // std::cout << "TestHandler2::onCompleted() invoked" << std::endl; - } - - HttpRequestTestData * mState; - std::string mName; - HttpHandle mExpectHandle; - std::string mCheckContentType; - regex_container_t mHeadersRequired; - regex_container_t mHeadersDisallowed; + TestHandler2(HttpRequestTestData * state, + const std::string & name) + : mState(state), + mName(name), + mExpectHandle(LLCORE_HTTP_HANDLE_INVALID) + {} + + virtual void onCompleted(HttpHandle handle, HttpResponse * response) + { + if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle) + { + ensure("Expected handle received in handler", mExpectHandle == handle); + } + ensure("Handler got a response", NULL != response); + if (response && mState) + { + const HttpStatus actual_status(response->getStatus()); + std::ostringstream test; + test << "Expected HttpStatus received in response. Wanted: " + << mState->mStatus.toHex() << " Received: " << actual_status.toHex(); + ensure(test.str().c_str(), actual_status == mState->mStatus); + } + if (mState) + { + mState->mHandlerCalls++; + } + if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty()) + { + ensure("Response required with header check", response != NULL); + HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this + ensure("Some quantity of headers returned", header != NULL); + + if (! mHeadersRequired.empty()) + { + for (int i(0); i < mHeadersRequired.size(); ++i) + { + bool found = false; + for (HttpHeaders::const_iterator iter(header->begin()); + header->end() != iter; + ++iter) + { + // std::cerr << "Header: " << (*iter).first + // << ": " << (*iter).second << std::endl; + + if (boost::regex_match((*iter).first, + mHeadersRequired[i].first) && + boost::regex_match((*iter).second, + mHeadersRequired[i].second)) + { + found = true; + break; + } + } + std::ostringstream str; + str << "Required header #" << i << " " + << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second + << " not found in response"; + ensure(str.str(), found); + } + } + + if (! mHeadersDisallowed.empty()) + { + for (int i(0); i < mHeadersDisallowed.size(); ++i) + { + for (HttpHeaders::const_iterator iter(header->begin()); + header->end() != iter; + ++iter) + { + if (boost::regex_match((*iter).first, + mHeadersDisallowed[i].first) && + boost::regex_match((*iter).second, + mHeadersDisallowed[i].second)) + { + std::ostringstream str; + str << "Disallowed header #" << i << " " + << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second + << " found in response"; + ensure(str.str(), false); + } + } + } + } + } + + if (! mCheckContentType.empty()) + { + ensure("Response required with content type check", response != NULL); + std::string con_type(response->getContentType()); + ensure("Content-Type as expected (" + mCheckContentType + ")", + mCheckContentType == con_type); + } + + // std::cout << "TestHandler2::onCompleted() invoked" << std::endl; + } + + HttpRequestTestData * mState; + std::string mName; + HttpHandle mExpectHandle; + std::string mCheckContentType; + regex_container_t mHeadersRequired; + regex_container_t mHeadersDisallowed; }; typedef test_group<HttpRequestTestData> HttpRequestTestGroupType; @@ -192,72 +192,72 @@ HttpRequestTestGroupType HttpRequestTestGroup("HttpRequest Tests"); template <> template <> void HttpRequestTestObjectType::test<1>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest construction"); - - HttpRequest * req = NULL; - - try - { - // Get singletons created - HttpRequest::createService(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // release the request object - delete req; - req = NULL; - - HttpRequest::destroyService(); - } - catch (...) - { - delete req; - HttpRequest::destroyService(); - throw; - } + ScopedCurlInit ready; + + set_test_name("HttpRequest construction"); + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // release the request object + delete req; + req = NULL; + + HttpRequest::destroyService(); + } + catch (...) + { + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<2>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest and Null Op queued"); - - HttpRequest * req = NULL; - - try - { - // Get singletons created - HttpRequest::createService(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a NoOp - HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t()); - ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID); - - // release the request object - delete req; - req = NULL; - - // Request queue should have two references: global singleton & service object - ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount()); - - // Okay, tear it down - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ScopedCurlInit ready; + + set_test_name("HttpRequest and Null Op queued"); + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a NoOp + HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t()); + ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID); + + // release the request object + delete req; + req = NULL; + + // Request queue should have two references: global singleton & service object + ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount()); + + // Okay, tear it down + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } namespace @@ -268,1243 +268,1243 @@ namespace template <> template <> void HttpRequestTestObjectType::test<3>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest NoOp + Stop execution"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + ScopedCurlInit ready; + + set_test_name("HttpRequest NoOp + Stop execution"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - - try - { - // Get singletons created + HttpRequest * req = NULL; + + try + { + // Get singletons created HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a NoOp - HttpHandle handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_SHORT); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a NoOp + HttpHandle handle = req->requestNoOp(handlerp); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_SHORT); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<4>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - set_test_name("2 HttpRequest instances, one thread"); + set_test_name("2 HttpRequest instances, one thread"); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - TestHandler2 handler1(this, "handler1"); - TestHandler2 handler2(this, "handler2"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + TestHandler2 handler1(this, "handler1"); + TestHandler2 handler2(this, "handler2"); LLCore::HttpHandler::ptr_t handler1p(&handler1, NoOpDeletor); LLCore::HttpHandler::ptr_t handler2p(&handler2, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req1 = NULL; - HttpRequest * req2 = NULL; - - try - { - - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req1 = new HttpRequest(); - req2 = new HttpRequest(); - - // Issue some NoOps - HttpHandle handle = req1->requestNoOp(handler1p); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); - handler1.mExpectHandle = handle; - - handle = req2->requestNoOp(handler2p); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); - handler2.mExpectHandle = handle; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 2) - { - req1->update(1000000); - req2->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 2); - - // Okay, request a shutdown of the servicing thread - handle = req2->requestStopThread(handler2p); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - handler2.mExpectHandle = handle; - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 3) - { - req1->update(1000000); - req2->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 3); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req1; - req1 = NULL; - delete req2; - req2 = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 3 == mHandlerCalls); - } - catch (...) - { - stop_thread(req1); - delete req1; - delete req2; - HttpRequest::destroyService(); - throw; - } + mHandlerCalls = 0; + + HttpRequest * req1 = NULL; + HttpRequest * req2 = NULL; + + try + { + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req1 = new HttpRequest(); + req2 = new HttpRequest(); + + // Issue some NoOps + HttpHandle handle = req1->requestNoOp(handler1p); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler1.mExpectHandle = handle; + + handle = req2->requestNoOp(handler2p); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler2.mExpectHandle = handle; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 2) + { + req1->update(1000000); + req2->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 2); + + // Okay, request a shutdown of the servicing thread + handle = req2->requestStopThread(handler2p); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler2.mExpectHandle = handle; + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 3) + { + req1->update(1000000); + req2->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 3); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req1; + req1 = NULL; + delete req2; + req2 = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 3 == mHandlerCalls); + } + catch (...) + { + stop_thread(req1); + delete req1; + delete req2; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<5>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest Spin (soft) + NoOp + hard termination"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + ScopedCurlInit ready; + + set_test_name("HttpRequest Spin (soft) + NoOp + hard termination"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - - try - { - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a Spin - HttpHandle handle = req->requestSpin(1); - ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Issue a NoOp - handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_SHORT); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("NoOp notification received", mHandlerCalls == 1); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a Spin + HttpHandle handle = req->requestSpin(1); + ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Issue a NoOp + handle = req->requestNoOp(handlerp); + ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_SHORT); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("NoOp notification received", mHandlerCalls == 1); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<6>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest Spin + NoOp + hard termination"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - - try - { + ScopedCurlInit ready; + + set_test_name("HttpRequest Spin + NoOp + hard termination"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a Spin - HttpHandle handle = req->requestSpin(0); // Hard spin - ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Issue a NoOp - handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_SHORT); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("No notifications received", mHandlerCalls == 0); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a Spin + HttpHandle handle = req->requestSpin(0); // Hard spin + ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Issue a NoOp + handle = req->requestNoOp(handlerp); + ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_SHORT); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("No notifications received", mHandlerCalls == 0); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<7>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - set_test_name("HttpRequest GET to dead port + Stop execution"); + set_test_name("HttpRequest GET to dead port + Stop execution"); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; - - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); opts = HttpOptions::ptr_t(new HttpOptions()); - opts->setRetries(1); // Don't try for too long - default retries take about 18S - - // Issue a GET that can't connect - mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - "http://127.0.0.1:2/nothing/here", - 0, - 0, - opts, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options + opts->setRetries(1); // Don't try for too long - default retries take about 18S + + // Issue a GET that can't connect + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + "http://127.0.0.1:2/nothing/here", + 0, + 0, + opts, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options opts.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<8>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET to real service"); + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + set_test_name("HttpRequest GET to real service"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base, - HttpOptions::ptr_t(), + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base, + HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<9>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET with Range: header to real service"); + set_test_name("HttpRequest GET with Range: header to real service"); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, - HttpOptions::ptr_t(), + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, + HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<10>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest PUT to real service"); + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + set_test_name("HttpRequest PUT to real service"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; + + HttpRequest * req = NULL; + BufferArray * body = new BufferArray; - HttpRequest * req = NULL; - BufferArray * body = new BufferArray; - - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - static const char * body_text("Now is the time for all good men..."); - body->append(body_text, strlen(body_text)); - mStatus = HttpStatus(200); - HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - url_base, - body, + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + static const char * body_text("Now is the time for all good men..."); + body->append(body_text, strlen(body_text)); + mStatus = HttpStatus(200); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + url_base, + body, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // Lose the request body - body->release(); - body = NULL; - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - if (body) - { - body->release(); - } - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // Lose the request body + body->release(); + body = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + if (body) + { + body->release(); + } + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<11>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest POST to real service"); + set_test_name("HttpRequest POST to real service"); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - BufferArray * body = new BufferArray; - - try - { + HttpRequest * req = NULL; + BufferArray * body = new BufferArray; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - static const char * body_text("Now is the time for all good men..."); - body->append(body_text, strlen(body_text)); - mStatus = HttpStatus(200); - HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - url_base, - body, + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + static const char * body_text("Now is the time for all good men..."); + body->append(body_text, strlen(body_text)); + mStatus = HttpStatus(200); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + url_base, + body, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // Lose the request body - body->release(); - body = NULL; - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - if (body) - { - body->release(); - } - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // Lose the request body + body->release(); + body = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + if (body) + { + body->release(); + } + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<12>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET with some tracing"); + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + set_test_name("HttpRequest GET with some tracing"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); + HttpRequest::createService(); - // Enable tracing - HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); + // Enable tracing + HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<13>() { - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET with returned headers"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); - handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest GET with returned headers"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; - try - { + try + { // Get singletons created - HttpRequest::createService(); + HttpRequest::createService(); - // Enable tracing - HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); + // Enable tracing + HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); opts = HttpOptions::ptr_t(new HttpOptions()); - opts->setWantHeaders(true); - - // Issue a GET that succeeds - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, - opts, + opts->setWantHeaders(true); + + // Issue a GET that succeeds + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, + opts, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - // release options + // release options opts.reset(); - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<14>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest GET timeout"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); - LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; - - try - { - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - opts = HttpOptions::ptr_t(new HttpOptions); - opts->setRetries(0); // Don't retry - opts->setTimeout(2); - - // Issue a GET that sleeps - mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, - opts, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options - opts.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + ScopedCurlInit ready; + + set_test_name("HttpRequest GET timeout"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + opts = HttpOptions::ptr_t(new HttpOptions); + opts->setRetries(0); // Don't retry + opts->setTimeout(2); + + // Issue a GET that sleeps + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, + opts, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options + opts.reset(); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + opts.reset(); + delete req; + HttpRequest::destroyService(); + throw; + } } // Test retrieval of Content-Type/Content-Encoding headers template <> template <> void HttpRequestTestObjectType::test<15>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET with Content-Type"); + set_test_name("HttpRequest GET with Content-Type"); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - // Load and clear the string setting to preload std::string object - // for memory return tests. - handler.mCheckContentType = "application/llsd+xml"; - handler.mCheckContentType.clear(); - mHandlerCalls = 0; + // Load and clear the string setting to preload std::string object + // for memory return tests. + handler.mCheckContentType = "application/llsd+xml"; + handler.mCheckContentType.clear(); + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - handler.mCheckContentType = "application/llsd+xml"; - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base, + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + handler.mCheckContentType = "application/llsd+xml"; + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mCheckContentType.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mCheckContentType.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -1512,236 +1512,236 @@ void HttpRequestTestObjectType::test<15>() template <> template <> void HttpRequestTestObjectType::test<16>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest GET"); + std::string url_base(get_base_url()); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + set_test_name("Header generation for HttpRequest GET"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Do a texture-style fetch - headers = HttpHeaders::ptr_t(new HttpHeaders); - headers->append("Accept", "image/x-j2c"); - - mStatus = HttpStatus(200); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("image/x-j2c", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("\\W*X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - 0, - 47, - options, - headers, - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 2); - - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 3) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 3); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Do a texture-style fetch + headers = HttpHeaders::ptr_t(new HttpHeaders); + headers->append("Accept", "image/x-j2c"); + + mStatus = HttpStatus(200); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("image/x-j2c", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("\\W*X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + 0, + 47, + options, + headers, + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 2); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 3) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 3); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -1749,183 +1749,183 @@ void HttpRequestTestObjectType::test<16>() template <> template <> void HttpRequestTestObjectType::test<17>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); + std::string url_base(get_base_url()); - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest POST"); + set_test_name("Header generation for HttpRequest POST"); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // And a buffer array - const char * msg("It was the best of times, it was the worst of times."); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default POST - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer_encoding", boost::regex::icase), - boost::regex(".*chunked.*", boost::regex::icase))); - HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // And a buffer array + const char * msg("It was the best of times, it was the worst of times."); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default POST + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer_encoding", boost::regex::icase), + boost::regex(".*chunked.*", boost::regex::icase))); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); delete req; - HttpRequest::destroyService(); - throw; - } + HttpRequest::destroyService(); + throw; + } } @@ -1933,184 +1933,184 @@ void HttpRequestTestObjectType::test<17>() template <> template <> void HttpRequestTestObjectType::test<18>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest PUT"); + std::string url_base(get_base_url()); - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + set_test_name("Header generation for HttpRequest PUT"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // options set - options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // And a buffer array - const char * msg("It was the best of times, it was the worst of times."); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default PUT - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*chunked.*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = HttpOptions::ptr_t(new HttpOptions()); + options->setWantHeaders(true); + + // And a buffer array + const char * msg("It was the best of times, it was the worst of times."); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default PUT + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*chunked.*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); delete req; - HttpRequest::destroyService(); - throw; - } + HttpRequest::destroyService(); + throw; + } } @@ -2118,189 +2118,189 @@ void HttpRequestTestObjectType::test<18>() template <> template <> void HttpRequestTestObjectType::test<19>() { - // It appears that HttpRequest is fully capable of sending duplicate header values in violation of - // this test's expectations. Something needs to budge: is sending duplicate header values desired? - // - // Test server /reflect/ response headers (mirrored from request) - // - // X-Reflect-content-type: text/plain - // X-Reflect-content-type: text/html - // X-Reflect-content-type: application/llsd+xml - // - skip("FIXME: Bad assertions or broken functionality."); - - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest GET with header overrides"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // It appears that HttpRequest is fully capable of sending duplicate header values in violation of + // this test's expectations. Something needs to budge: is sending duplicate header values desired? + // + // Test server /reflect/ response headers (mirrored from request) + // + // X-Reflect-content-type: text/plain + // X-Reflect-content-type: text/html + // X-Reflect-content-type: application/llsd+xml + // + skip("FIXME: Bad assertions or broken functionality."); + + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest GET with header overrides"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // headers - headers = HttpHeaders::ptr_t(new HttpHeaders); - headers->append("Keep-Alive", "120"); - headers->append("Accept-encoding", "deflate"); - headers->append("Accept", "text/plain"); - - // Issue a GET with modified headers - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("text/plain", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("deflate", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("120", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("300", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - options, - headers, - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // headers + headers = HttpHeaders::ptr_t(new HttpHeaders); + headers->append("Keep-Alive", "120"); + headers->append("Accept-encoding", "deflate"); + headers->append("Accept", "text/plain"); + + // Issue a GET with modified headers + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("text/plain", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("deflate", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("120", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("300", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + options, + headers, + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -2308,214 +2308,214 @@ void HttpRequestTestObjectType::test<19>() template <> template <> void HttpRequestTestObjectType::test<20>() { - // It appears that HttpRequest is fully capable of sending duplicate header values in violation of - // this test's expectations. Something needs to budge: is sending duplicate header values desired? - // - // Test server /reflect/ response headers (mirrored from request) - // - // X-Reflect-content-type: text/plain - // X-Reflect-content-type: text/html - // X-Reflect-content-type: application/llsd+xml - // - skip("FIXME: Bad assertions or broken functionality."); - - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest POST with header overrides"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // It appears that HttpRequest is fully capable of sending duplicate header values in violation of + // this test's expectations. Something needs to budge: is sending duplicate header values desired? + // + // Test server /reflect/ response headers (mirrored from request) + // + // X-Reflect-content-type: text/plain + // X-Reflect-content-type: text/html + // X-Reflect-content-type: application/llsd+xml + // + skip("FIXME: Bad assertions or broken functionality."); + + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest POST with header overrides"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // options set + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // headers - headers = HttpHeaders::ptr_t(new HttpHeaders()); - headers->append("keep-Alive", "120"); - headers->append("Accept", "text/html"); - headers->append("content-type", "application/llsd+xml"); - headers->append("cache-control", "no-store"); - - // And a buffer array - const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default POST - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("text/html", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("120", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/llsd\\+xml", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex("no-store", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("300", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - headers, - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // headers + headers = HttpHeaders::ptr_t(new HttpHeaders()); + headers->append("keep-Alive", "120"); + headers->append("Accept", "text/html"); + headers->append("content-type", "application/llsd+xml"); + headers->append("cache-control", "no-store"); + + // And a buffer array + const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default POST + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("text/html", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("120", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/llsd\\+xml", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex("no-store", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("300", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + headers, + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -2523,516 +2523,516 @@ void HttpRequestTestObjectType::test<20>() template <> template <> void HttpRequestTestObjectType::test<21>() { - // It appears that HttpRequest is fully capable of sending duplicate header values in violation of - // this test's expectations. Something needs to budge: is sending duplicate header values desired? - // - // Test server /reflect/ response headers (mirrored from request) - // - // X-Reflect-content-type: text/plain - // X-Reflect-content-type: text/html - // X-Reflect-content-type: application/llsd+xml - // - skip("FIXME: Bad assertions or broken functionality."); - - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest PUT with header overrides"); - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // It appears that HttpRequest is fully capable of sending duplicate header values in violation of + // this test's expectations. Something needs to budge: is sending duplicate header values desired? + // + // Test server /reflect/ response headers (mirrored from request) + // + // X-Reflect-content-type: text/plain + // X-Reflect-content-type: text/html + // X-Reflect-content-type: application/llsd+xml + // + skip("FIXME: Bad assertions or broken functionality."); + + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest PUT with header overrides"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // options set + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // headers - headers = HttpHeaders::ptr_t(new HttpHeaders); - headers->append("content-type", "text/plain"); - headers->append("content-type", "text/html"); - headers->append("content-type", "application/llsd+xml"); - - // And a buffer array - const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default PUT - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/llsd\\+xml", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("text/plain", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("text/html", boost::regex::icase))); - HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - headers, - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // headers + headers = HttpHeaders::ptr_t(new HttpHeaders); + headers->append("content-type", "text/plain"); + headers->append("content-type", "text/html"); + headers->append("content-type", "application/llsd+xml"); + + // And a buffer array + const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default PUT + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/llsd\\+xml", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("text/plain", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("text/html", boost::regex::icase))); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + headers, + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } // BUG-2295 Tests - Content-Range header received but no body template <> template <> void HttpRequestTestObjectType::test<22>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("BUG-2295"); + set_test_name("BUG-2295"); #if LL_WINDOWS && ADDRESS_SIZE == 64 - // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it - if (getenv("TEAMCITY_PROJECT_NAME")) - { - skip("BUG-2295 - partial load on W64 causes freeze"); - } + // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it + if (getenv("TEAMCITY_PROJECT_NAME")) + { + skip("BUG-2295 - partial load on W64 causes freeze"); + } #endif - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpOptions::ptr_t options; - HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpRequest * req = NULL; - try - { + try + { // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setRetries(1); // Partial_File is retryable and can timeout in here - options->setDNSCacheTimeout(30); - - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // ====================================== - // Issue bug2295 GETs that will get a 206 - // ====================================== - mStatus = HttpStatus(206); - static const int test_count(3); - for (int i(0); i < test_count; ++i) - { - char buffer[128]; - sprintf(buffer, "/bug2295/%d/", i); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + buffer, - 0, - 25, - options, + options->setRetries(1); // Partial_File is retryable and can timeout in here + options->setDNSCacheTimeout(30); + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // ====================================== + // Issue bug2295 GETs that will get a 206 + // ====================================== + mStatus = HttpStatus(206); + static const int test_count(3); + for (int i(0); i < test_count; ++i) + { + char buffer[128]; + sprintf(buffer, "/bug2295/%d/", i); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + buffer, + 0, + 25, + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + } + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < test_count) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time - ms1", count < limit); + ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count); + + // ====================================== + // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE) + // ====================================== + mHandlerCalls = 0; + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE); + static const int test2_count(1); + for (int i(0); i < test2_count; ++i) + { + char buffer[128]; + sprintf(buffer, "/bug2295/00000012/%d/", i); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + buffer, + 0, + 25, + options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - } - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < test_count) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time - ms1", count < limit); - ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count); - - // ====================================== - // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE) - // ====================================== - mHandlerCalls = 0; - mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE); - static const int test2_count(1); - for (int i(0); i < test2_count; ++i) - { - char buffer[128]; - sprintf(buffer, "/bug2295/00000012/%d/", i); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + buffer, - 0, - 25, - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - } - - // Run the notification pump. - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < test2_count) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time - ms2", count < limit); - ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count); - - // ====================================== - // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status - // ====================================== - mHandlerCalls = 0; - mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR); - static const int test3_count(1); - for (int i(0); i < test3_count; ++i) - { - char buffer[128]; - sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + buffer, - 0, - 25, - options, + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + } + + // Run the notification pump. + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < test2_count) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time - ms2", count < limit); + ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count); + + // ====================================== + // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status + // ====================================== + mHandlerCalls = 0; + mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR); + static const int test3_count(1); + for (int i(0); i < test3_count; ++i) + { + char buffer[128]; + sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + buffer, + 0, + 25, + options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - } - - // Run the notification pump. - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < test3_count) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time - ms3", count < limit); - ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count); - - // ====================================== - // Okay, request a shutdown of the servicing thread - // ====================================== - mStatus = HttpStatus(); - mHandlerCalls = 0; - HttpHandle handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Shutdown request executed in reasonable time", count < limit); - ensure("Shutdown handler invocation", mHandlerCalls == 1); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + } + + // Run the notification pump. + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < test3_count) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time - ms3", count < limit); + ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count); + + // ====================================== + // Okay, request a shutdown of the servicing thread + // ====================================== + mStatus = HttpStatus(); + mHandlerCalls = 0; + HttpHandle handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Shutdown request executed in reasonable time", count < limit); + ensure("Shutdown handler invocation", mHandlerCalls == 1); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options options.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<23>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - set_test_name("HttpRequest GET 503s with 'Retry-After'"); + set_test_name("HttpRequest GET 503s with 'Retry-After'"); #if LL_WINDOWS && ADDRESS_SIZE == 64 - // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it - if (getenv("TEAMCITY_PROJECT_NAME")) - { - skip("llcorehttp 503-with-retry test hangs on Windows 64"); - } + // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it + if (getenv("TEAMCITY_PROJECT_NAME")) + { + 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 - // the parsing result isn't supported. - - // Handler can be stack-allocated *if* there are no dangling - // references to it after completion of this method. - // Create before memory record as the string copy will bump numbers. - TestHandler2 handler(this, "handler"); + // 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 + // the parsing result isn't supported. + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - std::string url_base(get_base_url() + "/503/"); // path to 503 generators - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; - - try - { + std::string url_base(get_base_url() + "/503/"); // path to 503 generators + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); opts = HttpOptions::ptr_t(new HttpOptions()); - opts->setRetries(1); // Retry once only - opts->setUseRetryAfter(true); // Try to parse the retry-after header - - // Issue a GET that 503s with valid retry-after - mStatus = HttpStatus(503); - int url_limit(6); - for (int i(0); i < url_limit; ++i) - { - std::ostringstream url; - url << url_base << i << "/"; - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url.str(), - 0, - 0, - opts, + opts->setRetries(1); // Retry once only + opts->setUseRetryAfter(true); // Try to parse the retry-after header + + // Issue a GET that 503s with valid retry-after + mStatus = HttpStatus(503); + int url_limit(6); + for (int i(0); i < url_limit; ++i) + { + std::ostringstream url; + url << url_base << i << "/"; + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url.str(), + 0, + 0, + opts, HttpHeaders::ptr_t(), handlerp); - std::ostringstream testtag; - testtag << "Valid handle returned for 503 request #" << i; - ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID); - } - - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < url_limit) - { - req->update(0); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == url_limit); - - // Okay, request a shutdown of the servicing thread - mStatus = HttpStatus(); - mHandlerCalls = 0; - HttpHandle handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 1); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options + std::ostringstream testtag; + testtag << "Valid handle returned for 503 request #" << i; + ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID); + } + + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < url_limit) + { + req->update(0); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == url_limit); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + mHandlerCalls = 0; + HttpHandle handle = req->requestStopThread(handlerp); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 1); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options opts.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -3045,7 +3045,7 @@ namespace void usleep(unsigned long usec) { - Sleep((DWORD) (usec / 1000UL)); + Sleep((DWORD) (usec / 1000UL)); } #endif |