SH-3241 Validate header correctness, SH-3243 more unit tests
Define expectations for headers for GET, POST, PUT requests. Document those in the interface, test those with integration tests. Verify that header overrides work as expected.meow-7.2.2
parent
d238341afa
commit
8d3e5f3959
|
|
@ -468,6 +468,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -482,6 +484,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -214,14 +214,46 @@ public:
|
|||
/// request in other requests (like cancellation) and will be an
|
||||
/// argument when any HttpHandler object is invoked.
|
||||
///
|
||||
/// Headers supplied by default:
|
||||
/// - Connection: keep-alive
|
||||
/// - Accept: */*
|
||||
/// - Accept-Encoding: deflate, gzip
|
||||
/// - Keep-alive: 300
|
||||
/// - Host: <stuff>
|
||||
///
|
||||
/// Some headers excluded by default:
|
||||
/// - Pragma:
|
||||
/// - Cache-control:
|
||||
/// - Range:
|
||||
/// - Transfer-Encoding:
|
||||
/// - Referer:
|
||||
///
|
||||
/// @param policy_id Default or user-defined policy class under
|
||||
/// which this request is to be serviced.
|
||||
/// @param priority Standard priority scheme inherited from
|
||||
/// Indra code base (U32-type scheme).
|
||||
/// @param url
|
||||
/// @param options (optional)
|
||||
/// @param headers (optional)
|
||||
/// @param handler (optional)
|
||||
/// @param url URL with any encoded query parameters to
|
||||
/// be accessed.
|
||||
/// @param options Optional instance of an HttpOptions object
|
||||
/// to provide additional controls over the request
|
||||
/// function for this request only. Any such
|
||||
/// object then becomes shared-read across threads
|
||||
/// and no code should modify the HttpOptions
|
||||
/// instance.
|
||||
/// @param headers Optional instance of an HttpHeaders object
|
||||
/// to provide additional and/or overridden
|
||||
/// headers for the request. As with options,
|
||||
/// the instance becomes shared-read across threads
|
||||
/// and no code should modify the HttpHeaders
|
||||
/// instance.
|
||||
/// @param handler Optional pointer to an HttpHandler instance
|
||||
/// whose onCompleted() method will be invoked
|
||||
/// during calls to update(). This is a non-
|
||||
/// reference-counted object which would be a
|
||||
/// problem for shutdown and other edge cases but
|
||||
/// the pointer is only dereferenced during
|
||||
/// calls to update().
|
||||
///
|
||||
/// @return The handle of the request if successfully
|
||||
/// queued or LLCORE_HTTP_HANDLE_INVALID if the
|
||||
/// request could not be queued. In the latter
|
||||
|
|
@ -244,20 +276,29 @@ public:
|
|||
/// request in other requests (like cancellation) and will be an
|
||||
/// argument when any HttpHandler object is invoked.
|
||||
///
|
||||
/// @param policy_id Default or user-defined policy class under
|
||||
/// which this request is to be serviced.
|
||||
/// @param priority Standard priority scheme inherited from
|
||||
/// Indra code base (U32-type scheme).
|
||||
/// @param url
|
||||
/// @param offset
|
||||
/// @param len
|
||||
/// @param options (optional)
|
||||
/// @param headers (optional)
|
||||
/// @param handler (optional)
|
||||
/// @return The handle of the request if successfully
|
||||
/// queued or LLCORE_HTTP_HANDLE_INVALID if the
|
||||
/// request could not be queued. In the latter
|
||||
/// case, @see getStatus() will return more info.
|
||||
/// Headers supplied by default:
|
||||
/// - Connection: keep-alive
|
||||
/// - Accept: */*
|
||||
/// - Accept-Encoding: deflate, gzip
|
||||
/// - Keep-alive: 300
|
||||
/// - Host: <stuff>
|
||||
/// - Range: <stuff> (will be omitted if offset == 0 and len == 0)
|
||||
///
|
||||
/// Some headers excluded by default:
|
||||
/// - Pragma:
|
||||
/// - Cache-control:
|
||||
/// - Transfer-Encoding:
|
||||
/// - Referer:
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param offset Offset of first byte into resource to be returned.
|
||||
/// @param len Count of bytes to be returned
|
||||
/// @param options @see requestGet()
|
||||
/// @param headers "
|
||||
/// @param handler "
|
||||
/// @return "
|
||||
///
|
||||
HttpHandle requestGetByteRange(policy_t policy_id,
|
||||
priority_t priority,
|
||||
|
|
@ -269,22 +310,37 @@ public:
|
|||
HttpHandler * handler);
|
||||
|
||||
|
||||
/// Queue a full HTTP POST. Query arguments and body may
|
||||
/// be provided. Caller is responsible for escaping and
|
||||
/// encoding and communicating the content types.
|
||||
///
|
||||
/// @param policy_id Default or user-defined policy class under
|
||||
/// which this request is to be serviced.
|
||||
/// @param priority Standard priority scheme inherited from
|
||||
/// Indra code base.
|
||||
/// @param url
|
||||
/// Headers supplied by default:
|
||||
/// - Connection: keep-alive
|
||||
/// - Accept: */*
|
||||
/// - Accept-Encoding: deflate, gzip
|
||||
/// - Keep-Alive: 300
|
||||
/// - Host: <stuff>
|
||||
/// - Content-Length: <digits>
|
||||
/// - Content-Type: application/x-www-form-urlencoded
|
||||
///
|
||||
/// Some headers excluded by default:
|
||||
/// - Pragma:
|
||||
/// - Cache-Control:
|
||||
/// - Transfer-Encoding: ... chunked ...
|
||||
/// - Referer:
|
||||
/// - Content-Encoding:
|
||||
/// - Expect:
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param body Byte stream to be sent as the body. No
|
||||
/// further encoding or escaping will be done
|
||||
/// to the content.
|
||||
/// @param options (optional)
|
||||
/// @param headers (optional)
|
||||
/// @param handler (optional)
|
||||
/// @return The handle of the request if successfully
|
||||
/// queued or LLCORE_HTTP_HANDLE_INVALID if the
|
||||
/// request could not be queued. In the latter
|
||||
/// case, @see getStatus() will return more info.
|
||||
/// @param options @see requestGet()K(optional)
|
||||
/// @param headers "
|
||||
/// @param handler "
|
||||
/// @return "
|
||||
///
|
||||
HttpHandle requestPost(policy_t policy_id,
|
||||
priority_t priority,
|
||||
|
|
@ -295,22 +351,37 @@ public:
|
|||
HttpHandler * handler);
|
||||
|
||||
|
||||
/// Queue a full HTTP PUT. Query arguments and body may
|
||||
/// be provided. Caller is responsible for escaping and
|
||||
/// encoding and communicating the content types.
|
||||
///
|
||||
/// @param policy_id Default or user-defined policy class under
|
||||
/// which this request is to be serviced.
|
||||
/// @param priority Standard priority scheme inherited from
|
||||
/// Indra code base.
|
||||
/// @param url
|
||||
/// Headers supplied by default:
|
||||
/// - Connection: keep-alive
|
||||
/// - Accept: */*
|
||||
/// - Accept-Encoding: deflate, gzip
|
||||
/// - Keep-Alive: 300
|
||||
/// - Host: <stuff>
|
||||
/// - Content-Length: <digits>
|
||||
///
|
||||
/// Some headers excluded by default:
|
||||
/// - Pragma:
|
||||
/// - Cache-Control:
|
||||
/// - Transfer-Encoding: ... chunked ...
|
||||
/// - Referer:
|
||||
/// - Content-Encoding:
|
||||
/// - Expect:
|
||||
/// - Content-Type:
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param body Byte stream to be sent as the body. No
|
||||
/// further encoding or escaping will be done
|
||||
/// to the content.
|
||||
/// @param options (optional)
|
||||
/// @param headers (optional)
|
||||
/// @param handler (optional)
|
||||
/// @return The handle of the request if successfully
|
||||
/// queued or LLCORE_HTTP_HANDLE_INVALID if the
|
||||
/// request could not be queued. In the latter
|
||||
/// case, @see getStatus() will return more info.
|
||||
/// @param options @see requestGet()K(optional)
|
||||
/// @param headers "
|
||||
/// @param handler "
|
||||
/// @return "
|
||||
///
|
||||
HttpHandle requestPut(policy_t policy_id,
|
||||
priority_t priority,
|
||||
|
|
@ -326,11 +397,8 @@ public:
|
|||
/// immediately processes it and returns the request to the reply
|
||||
/// queue.
|
||||
///
|
||||
/// @param handler (optional)
|
||||
/// @return The handle of the request if successfully
|
||||
/// queued or LLCORE_HTTP_HANDLE_INVALID if the
|
||||
/// request could not be queued. In the latter
|
||||
/// case, @see getStatus() will return more info.
|
||||
/// @param handler @see requestGet()
|
||||
/// @return "
|
||||
///
|
||||
HttpHandle requestNoOp(HttpHandler * handler);
|
||||
|
||||
|
|
@ -345,7 +413,8 @@ public:
|
|||
/// spend in the call. As hinted at above, this
|
||||
/// is partly a function of application code so it's
|
||||
/// a soft limit. A '0' value will run without
|
||||
/// time limit.
|
||||
/// time limit until everything queued has been
|
||||
/// delivered.
|
||||
///
|
||||
/// @return Standard status code.
|
||||
HttpStatus update(long usecs);
|
||||
|
|
@ -365,10 +434,8 @@ public:
|
|||
/// @param request Handle of previously-issued request to
|
||||
/// be changed.
|
||||
/// @param priority New priority value.
|
||||
/// @param handler (optional)
|
||||
/// @return The handle of the request if successfully
|
||||
/// queued or LLCORE_HTTP_HANDLE_INVALID if the
|
||||
/// request could not be queued.
|
||||
/// @param handler @see requestGet()
|
||||
/// @return "
|
||||
///
|
||||
HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler * handler);
|
||||
|
||||
|
|
|
|||
|
|
@ -1705,11 +1705,18 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
// Issue a GET that *can* connect
|
||||
mStatus = HttpStatus(200);
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\W*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\W*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\W*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\W*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\W*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -1735,12 +1742,19 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
mStatus = HttpStatus(200);
|
||||
handler.mHeadersRequired.clear();
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\W*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\W*\\image/x-j2c", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\W*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.clear();
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\W*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\W*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*image/x-j2c", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("\\W*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -1830,6 +1844,816 @@ void HttpRequestTestObjectType::test<16>()
|
|||
}
|
||||
|
||||
|
||||
// Test header generation on POST requests
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<17>()
|
||||
{
|
||||
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");
|
||||
|
||||
// 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");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
mHandlerCalls = 0;
|
||||
|
||||
HttpRequest * req = NULL;
|
||||
HttpOptions * options = NULL;
|
||||
HttpHeaders * headers = NULL;
|
||||
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 = 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(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/x-www-form-urlencoded", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
|
||||
HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
NULL,
|
||||
&handler);
|
||||
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(10);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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(&handler);
|
||||
ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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 = 10;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
// release options & headers
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
}
|
||||
options = NULL;
|
||||
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
}
|
||||
headers = NULL;
|
||||
|
||||
// release the request object
|
||||
delete req;
|
||||
req = NULL;
|
||||
|
||||
// Shut down service
|
||||
HttpRequest::destroyService();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
stop_thread(req);
|
||||
if (ba)
|
||||
{
|
||||
ba->release();
|
||||
ba = NULL;
|
||||
}
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
options = NULL;
|
||||
}
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
headers = NULL;
|
||||
}
|
||||
delete req;
|
||||
HttpRequest::destroyService();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test header generation on PUT requests
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<18>()
|
||||
{
|
||||
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");
|
||||
|
||||
// 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");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
mHandlerCalls = 0;
|
||||
|
||||
HttpRequest * req = NULL;
|
||||
HttpOptions * options = NULL;
|
||||
HttpHeaders * headers = NULL;
|
||||
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 = 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(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:.*", boost::regex::icase));
|
||||
HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
NULL,
|
||||
&handler);
|
||||
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(10);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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(&handler);
|
||||
ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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 = 10;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
// release options & headers
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
}
|
||||
options = NULL;
|
||||
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
}
|
||||
headers = NULL;
|
||||
|
||||
// release the request object
|
||||
delete req;
|
||||
req = NULL;
|
||||
|
||||
// Shut down service
|
||||
HttpRequest::destroyService();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
stop_thread(req);
|
||||
if (ba)
|
||||
{
|
||||
ba->release();
|
||||
ba = NULL;
|
||||
}
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
options = NULL;
|
||||
}
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
headers = NULL;
|
||||
}
|
||||
delete req;
|
||||
HttpRequest::destroyService();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test header generation on GET requests with overrides
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<19>()
|
||||
{
|
||||
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");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
mHandlerCalls = 0;
|
||||
|
||||
HttpRequest * req = NULL;
|
||||
HttpOptions * options = NULL;
|
||||
HttpHeaders * headers = 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 = new HttpOptions();
|
||||
options->setWantHeaders(true);
|
||||
|
||||
// headers
|
||||
headers = new HttpHeaders;
|
||||
headers->mHeaders.push_back("Keep-Alive: 120");
|
||||
headers->mHeaders.push_back("Accept-encoding: deflate");
|
||||
headers->mHeaders.push_back("Accept: text/plain");
|
||||
|
||||
// Issue a GET with modified headers
|
||||
mStatus = HttpStatus(200);
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*text/plain", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*deflate", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*120", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-keep-alive:\\s*300", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
options,
|
||||
headers,
|
||||
&handler);
|
||||
ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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(&handler);
|
||||
ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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 = 10;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
// release options & headers
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
}
|
||||
options = NULL;
|
||||
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
}
|
||||
headers = NULL;
|
||||
|
||||
// release the request object
|
||||
delete req;
|
||||
req = NULL;
|
||||
|
||||
// Shut down service
|
||||
HttpRequest::destroyService();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
stop_thread(req);
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
options = NULL;
|
||||
}
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
headers = NULL;
|
||||
}
|
||||
delete req;
|
||||
HttpRequest::destroyService();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test header generation on POST requests with overrides
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<20>()
|
||||
{
|
||||
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");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
mHandlerCalls = 0;
|
||||
|
||||
HttpRequest * req = NULL;
|
||||
HttpOptions * options = NULL;
|
||||
HttpHeaders * headers = NULL;
|
||||
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 = new HttpOptions();
|
||||
options->setWantHeaders(true);
|
||||
|
||||
// headers
|
||||
headers = new HttpHeaders();
|
||||
headers->mHeaders.push_back("keep-Alive: 120");
|
||||
headers->mHeaders.push_back("Accept: text/html");
|
||||
headers->mHeaders.push_back("content-type: application/llsd+xml");
|
||||
headers->mHeaders.push_back("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(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*text/html", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*120", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/llsd\\+xml", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("\\s*X-Reflect-cache-control:\\s*no-store", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*application/x-www-form-urlencoded", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-keep-alive:\\s*300", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
|
||||
HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
headers,
|
||||
&handler);
|
||||
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(10);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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(&handler);
|
||||
ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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 = 10;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
// release options & headers
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
}
|
||||
options = NULL;
|
||||
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
}
|
||||
headers = NULL;
|
||||
|
||||
// release the request object
|
||||
delete req;
|
||||
req = NULL;
|
||||
|
||||
// Shut down service
|
||||
HttpRequest::destroyService();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
stop_thread(req);
|
||||
if (ba)
|
||||
{
|
||||
ba->release();
|
||||
ba = NULL;
|
||||
}
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
options = NULL;
|
||||
}
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
headers = NULL;
|
||||
}
|
||||
delete req;
|
||||
HttpRequest::destroyService();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test header generation on PUT requests with overrides
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<21>()
|
||||
{
|
||||
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");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
mHandlerCalls = 0;
|
||||
|
||||
HttpRequest * req = NULL;
|
||||
HttpOptions * options = NULL;
|
||||
HttpHeaders * headers = NULL;
|
||||
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 = new HttpOptions();
|
||||
options->setWantHeaders(true);
|
||||
|
||||
// headers
|
||||
headers = new HttpHeaders;
|
||||
headers->mHeaders.push_back("content-type: text/plain");
|
||||
headers->mHeaders.push_back("content-type: text/html");
|
||||
headers->mHeaders.push_back("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(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
|
||||
handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/llsd\\+xml", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*text/plain", boost::regex::icase));
|
||||
handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*text/html", boost::regex::icase));
|
||||
HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
headers,
|
||||
&handler);
|
||||
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(10);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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(&handler);
|
||||
ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
}
|
||||
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 = 10;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
// release options & headers
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
}
|
||||
options = NULL;
|
||||
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
}
|
||||
headers = NULL;
|
||||
|
||||
// release the request object
|
||||
delete req;
|
||||
req = NULL;
|
||||
|
||||
// Shut down service
|
||||
HttpRequest::destroyService();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
stop_thread(req);
|
||||
if (ba)
|
||||
{
|
||||
ba->release();
|
||||
ba = NULL;
|
||||
}
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
options = NULL;
|
||||
}
|
||||
if (headers)
|
||||
{
|
||||
headers->release();
|
||||
headers = NULL;
|
||||
}
|
||||
delete req;
|
||||
HttpRequest::destroyService();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace tut
|
||||
|
||||
namespace
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||
|
||||
def reflect_headers(self):
|
||||
for name in self.headers.keys():
|
||||
# print "Header: %s: %s" % (name, self.headers[name])
|
||||
self.send_header("X-Reflect-" + name, self.headers[name])
|
||||
|
||||
if not VERBOSE:
|
||||
|
|
|
|||
Loading…
Reference in New Issue