SH-4061 - integrated LLHttpRetryPolicy with new corehttp header parsing
commit
8d3afb35d8
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -359,12 +359,17 @@ int HttpLibcurl::getActiveCountInClass(int policy_class) const
|
|||
|
||||
struct curl_slist * append_headers_to_slist(const HttpHeaders * headers, struct curl_slist * slist)
|
||||
{
|
||||
for (HttpHeaders::container_t::const_iterator it(headers->mHeaders.begin());
|
||||
|
||||
headers->mHeaders.end() != it;
|
||||
++it)
|
||||
const HttpHeaders::const_iterator end(headers->end());
|
||||
for (HttpHeaders::const_iterator it(headers->begin()); end != it; ++it)
|
||||
{
|
||||
slist = curl_slist_append(slist, (*it).c_str());
|
||||
static const char sep[] = ": ";
|
||||
std::string header;
|
||||
header.reserve((*it).first.size() + (*it).second.size() + sizeof(sep));
|
||||
header.append((*it).first);
|
||||
header.append(sep);
|
||||
header.append((*it).second);
|
||||
|
||||
slist = curl_slist_append(slist, header.c_str());
|
||||
}
|
||||
return slist;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -610,7 +610,8 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
|
|||
|
||||
const size_t hdr_size(size * nmemb);
|
||||
const char * hdr_data(static_cast<const char *>(data)); // Not null terminated
|
||||
|
||||
bool is_header(true);
|
||||
|
||||
if (hdr_size >= status_line_len && ! strncmp(status_line, hdr_data, status_line_len))
|
||||
{
|
||||
// One of possibly several status lines. Reset what we know and start over
|
||||
|
|
@ -621,8 +622,9 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
|
|||
op->mStatus = HttpStatus();
|
||||
if (op->mReplyHeaders)
|
||||
{
|
||||
op->mReplyHeaders->mHeaders.clear();
|
||||
op->mReplyHeaders->clear();
|
||||
}
|
||||
is_header = false;
|
||||
}
|
||||
|
||||
// Nothing in here wants a final CR/LF combination. Remove
|
||||
|
|
@ -637,18 +639,18 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
|
|||
}
|
||||
|
||||
// Save header if caller wants them in the response
|
||||
if (op->mProcFlags & PF_SAVE_HEADERS)
|
||||
if (is_header && op->mProcFlags & PF_SAVE_HEADERS)
|
||||
{
|
||||
// Save headers in response
|
||||
if (! op->mReplyHeaders)
|
||||
{
|
||||
op->mReplyHeaders = new HttpHeaders;
|
||||
}
|
||||
op->mReplyHeaders->mHeaders.push_back(std::string(hdr_data, wanted_hdr_size));
|
||||
op->mReplyHeaders->appendNormal(hdr_data, wanted_hdr_size);
|
||||
}
|
||||
|
||||
// Detect and parse 'Content-Range' headers
|
||||
if (op->mProcFlags & PF_SCAN_RANGE_HEADER)
|
||||
if (is_header && op->mProcFlags & PF_SCAN_RANGE_HEADER)
|
||||
{
|
||||
char hdr_buffer[128]; // Enough for a reasonable header
|
||||
size_t frag_size((std::min)(wanted_hdr_size, sizeof(hdr_buffer) - 1));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -328,7 +328,7 @@ WorkingSet::WorkingSet()
|
|||
mTextures.reserve(30000);
|
||||
|
||||
mHeaders = new LLCore::HttpHeaders;
|
||||
mHeaders->mHeaders.push_back("Accept: image/x-j2c");
|
||||
mHeaders->append("Accept", "image/x-j2c");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "httpheaders.h"
|
||||
|
||||
#include "llstring.h"
|
||||
|
||||
|
||||
namespace LLCore
|
||||
{
|
||||
|
|
@ -40,5 +42,142 @@ HttpHeaders::~HttpHeaders()
|
|||
{}
|
||||
|
||||
|
||||
void
|
||||
HttpHeaders::clear()
|
||||
{
|
||||
mHeaders.clear();
|
||||
}
|
||||
|
||||
|
||||
void HttpHeaders::append(const std::string & name, const std::string & value)
|
||||
{
|
||||
mHeaders.push_back(value_type(name, value));
|
||||
}
|
||||
|
||||
|
||||
void HttpHeaders::append(const char * name, const char * value)
|
||||
{
|
||||
mHeaders.push_back(value_type(name, value));
|
||||
}
|
||||
|
||||
|
||||
void HttpHeaders::appendNormal(const char * header, size_t size)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
||||
int col_pos(0);
|
||||
for (; col_pos < size; ++col_pos)
|
||||
{
|
||||
if (':' == header[col_pos])
|
||||
break;
|
||||
}
|
||||
|
||||
if (col_pos < size)
|
||||
{
|
||||
// Looks like a header, split it and normalize.
|
||||
// Name is everything before the colon, may be zero-length.
|
||||
name.assign(header, col_pos);
|
||||
|
||||
// Value is everything after the colon, may also be zero-length.
|
||||
const size_t val_len(size - col_pos - 1);
|
||||
if (val_len)
|
||||
{
|
||||
value.assign(header + col_pos + 1, val_len);
|
||||
}
|
||||
|
||||
// Clean the strings
|
||||
LLStringUtil::toLower(name);
|
||||
LLStringUtil::trim(name);
|
||||
LLStringUtil::trimHead(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uncertain what this is, we'll pack it as
|
||||
// a name without a value. Won't clean as we don't
|
||||
// know what it is...
|
||||
name.assign(header, size);
|
||||
}
|
||||
|
||||
mHeaders.push_back(value_type(name, value));
|
||||
}
|
||||
|
||||
|
||||
// Find from end to simulate a tradition of using single-valued
|
||||
// std::map for this in the past.
|
||||
const std::string * HttpHeaders::find(const char * name) const
|
||||
{
|
||||
const_reverse_iterator iend(rend());
|
||||
for (const_reverse_iterator iter(rbegin()); iend != iter; ++iter)
|
||||
{
|
||||
if ((*iter).first == name)
|
||||
{
|
||||
return &(*iter).second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Standard Iterators
|
||||
HttpHeaders::iterator HttpHeaders::begin()
|
||||
{
|
||||
return mHeaders.begin();
|
||||
}
|
||||
|
||||
|
||||
HttpHeaders::const_iterator HttpHeaders::begin() const
|
||||
{
|
||||
return mHeaders.begin();
|
||||
}
|
||||
|
||||
|
||||
HttpHeaders::iterator HttpHeaders::end()
|
||||
{
|
||||
return mHeaders.end();
|
||||
}
|
||||
|
||||
|
||||
HttpHeaders::const_iterator HttpHeaders::end() const
|
||||
{
|
||||
return mHeaders.end();
|
||||
}
|
||||
|
||||
|
||||
// Standard Reverse Iterators
|
||||
HttpHeaders::reverse_iterator HttpHeaders::rbegin()
|
||||
{
|
||||
return mHeaders.rbegin();
|
||||
}
|
||||
|
||||
|
||||
HttpHeaders::const_reverse_iterator HttpHeaders::rbegin() const
|
||||
{
|
||||
return mHeaders.rbegin();
|
||||
}
|
||||
|
||||
|
||||
HttpHeaders::reverse_iterator HttpHeaders::rend()
|
||||
{
|
||||
return mHeaders.rend();
|
||||
}
|
||||
|
||||
|
||||
HttpHeaders::const_reverse_iterator HttpHeaders::rend() const
|
||||
{
|
||||
return mHeaders.rend();
|
||||
}
|
||||
|
||||
|
||||
// Return the raw container to the caller.
|
||||
//
|
||||
// To be used FOR UNIT TESTS ONLY.
|
||||
//
|
||||
HttpHeaders::container_t & HttpHeaders::getContainerTESTONLY()
|
||||
{
|
||||
return mHeaders;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace LLCore
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -43,13 +43,26 @@ namespace LLCore
|
|||
/// caller has asked that headers be returned (not the default
|
||||
/// option).
|
||||
///
|
||||
/// @note
|
||||
/// This is a minimally-functional placeholder at the moment
|
||||
/// to fill out the class hierarchy. The final class will be
|
||||
/// something else, probably more pair-oriented. It's also
|
||||
/// an area where shared values are desirable so refcounting is
|
||||
/// already specced and a copy-on-write scheme imagined.
|
||||
/// Expect changes here.
|
||||
/// Class is mostly a thin wrapper around a vector of pairs
|
||||
/// of strings. Methods provided are few and intended to
|
||||
/// reflect actual use patterns. These include:
|
||||
/// - Clearing the list
|
||||
/// - Appending a name/value pair to the vector
|
||||
/// - Processing a raw byte string into a normalized name/value
|
||||
/// pair and appending the result.
|
||||
/// - Simple case-sensitive find-last-by-name search
|
||||
/// - Forward and reverse iterators over all pairs
|
||||
///
|
||||
/// Container is ordered and multi-valued. Headers are
|
||||
/// written in the order in which they are appended and
|
||||
/// are stored in the order in which they're received from
|
||||
/// the wire. The same header may appear two or more times
|
||||
/// in any container. Searches using the simple find()
|
||||
/// interface will find only the last occurrence (somewhat
|
||||
/// simulates the use of std::map). Fuller searches require
|
||||
/// the use of an iterator. Headers received from the wire
|
||||
/// are only returned from the last request when redirections
|
||||
/// are involved.
|
||||
///
|
||||
/// Threading: Not intrinsically thread-safe. It *is* expected
|
||||
/// that callers will build these objects and then share them
|
||||
|
|
@ -63,6 +76,16 @@ namespace LLCore
|
|||
|
||||
class HttpHeaders : public LLCoreInt::RefCounted
|
||||
{
|
||||
public:
|
||||
typedef std::pair<std::string, std::string> header_t;
|
||||
typedef std::vector<header_t> container_t;
|
||||
typedef container_t::iterator iterator;
|
||||
typedef container_t::const_iterator const_iterator;
|
||||
typedef container_t::reverse_iterator reverse_iterator;
|
||||
typedef container_t::const_reverse_iterator const_reverse_iterator;
|
||||
typedef container_t::value_type value_type;
|
||||
typedef container_t::size_type size_type;
|
||||
|
||||
public:
|
||||
/// @post In addition to the instance, caller has a refcount
|
||||
/// to the instance. A call to @see release() will destroy
|
||||
|
|
@ -76,7 +99,78 @@ protected:
|
|||
void operator=(const HttpHeaders &); // Not defined
|
||||
|
||||
public:
|
||||
typedef std::vector<std::string> container_t;
|
||||
// Empty the list of headers.
|
||||
void clear();
|
||||
|
||||
// Append a name/value pair supplied as either std::strings
|
||||
// or NUL-terminated char * to the header list. No normalization
|
||||
// is performed on the strings. No conformance test is
|
||||
// performed (names may contain spaces, colons, etc.).
|
||||
//
|
||||
void append(const std::string & name, const std::string & value);
|
||||
void append(const char * name, const char * value);
|
||||
|
||||
// Extract a name/value pair from a raw byte array using
|
||||
// the first colon character as a separator. Input string
|
||||
// does not need to be NUL-terminated. Resulting name/value
|
||||
// pair is appended to the header list.
|
||||
//
|
||||
// Normalization is performed on the name/value pair as
|
||||
// follows:
|
||||
// - name is lower-cased according to mostly ASCII rules
|
||||
// - name is left- and right-trimmed of spaces and tabs
|
||||
// - value is left-trimmed of spaces and tabs
|
||||
// - either or both of name and value may be zero-length
|
||||
//
|
||||
// By convention, headers read from the wire will be normalized
|
||||
// in this fashion prior to delivery to any HttpHandler code.
|
||||
// Headers to be written to the wire are left as appended to
|
||||
// the list.
|
||||
void appendNormal(const char * header, size_t size);
|
||||
|
||||
// Perform a simple, case-sensitive search of the header list
|
||||
// returning a pointer to the value of the last matching header
|
||||
// in the header list. If none is found, a NULL pointer is returned.
|
||||
//
|
||||
// Any pointer returned references objects in the container itself
|
||||
// and will have the same lifetime as this class. If you want
|
||||
// the value beyond the lifetime of this instance, make a copy.
|
||||
//
|
||||
// @arg name C-style string giving the name of a header
|
||||
// to search. The comparison is case-sensitive
|
||||
// though list entries may have been normalized
|
||||
// to lower-case.
|
||||
//
|
||||
// @return NULL if the header wasn't found otherwise
|
||||
// a pointer to a std::string in the container.
|
||||
// Pointer is valid only for the lifetime of
|
||||
// the container or until container is modifed.
|
||||
//
|
||||
const std::string * find(const char * name) const;
|
||||
|
||||
// Count of headers currently in the list.
|
||||
size_type size() const
|
||||
{
|
||||
return mHeaders.size();
|
||||
}
|
||||
|
||||
// Standard std::vector-based forward iterators.
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
|
||||
// Standard std::vector-based reverse iterators.
|
||||
reverse_iterator rbegin();
|
||||
const_reverse_iterator rbegin() const;
|
||||
reverse_iterator rend();
|
||||
const_reverse_iterator rend() const;
|
||||
|
||||
public:
|
||||
// For unit tests only - not a public API
|
||||
container_t & getContainerTESTONLY();
|
||||
|
||||
protected:
|
||||
container_t mHeaders;
|
||||
|
||||
}; // end class HttpHeaders
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -36,7 +36,6 @@
|
|||
using namespace LLCoreInt;
|
||||
|
||||
|
||||
|
||||
namespace tut
|
||||
{
|
||||
|
||||
|
|
@ -63,7 +62,7 @@ void HttpHeadersTestObjectType::test<1>()
|
|||
HttpHeaders * headers = new HttpHeaders();
|
||||
ensure("One ref on construction of HttpHeaders", headers->getRefCount() == 1);
|
||||
ensure("Memory being used", mMemTotal < GetMemTotal());
|
||||
ensure("Nothing in headers", 0 == headers->mHeaders.size());
|
||||
ensure("Nothing in headers", 0 == headers->size());
|
||||
|
||||
// release the implicit reference, causing the object to be released
|
||||
headers->release();
|
||||
|
|
@ -85,14 +84,340 @@ void HttpHeadersTestObjectType::test<2>()
|
|||
|
||||
{
|
||||
// Append a few strings
|
||||
std::string str1("Pragma:");
|
||||
headers->mHeaders.push_back(str1);
|
||||
std::string str2("Accept: application/json");
|
||||
headers->mHeaders.push_back(str2);
|
||||
std::string str1n("Pragma");
|
||||
std::string str1v("");
|
||||
headers->append(str1n, str1v);
|
||||
std::string str2n("Accept");
|
||||
std::string str2v("application/json");
|
||||
headers->append(str2n, str2v);
|
||||
|
||||
ensure("Headers retained", 2 == headers->mHeaders.size());
|
||||
ensure("First is first", headers->mHeaders[0] == str1);
|
||||
ensure("Second is second", headers->mHeaders[1] == str2);
|
||||
ensure("Headers retained", 2 == headers->size());
|
||||
HttpHeaders::container_t & c(headers->getContainerTESTONLY());
|
||||
|
||||
ensure("First name is first name", c[0].first == str1n);
|
||||
ensure("First value is first value", c[0].second == str1v);
|
||||
ensure("Second name is second name", c[1].first == str2n);
|
||||
ensure("Second value is second value", c[1].second == str2v);
|
||||
}
|
||||
|
||||
// release the implicit reference, causing the object to be released
|
||||
headers->release();
|
||||
|
||||
// make sure we didn't leak any memory
|
||||
ensure(mMemTotal == GetMemTotal());
|
||||
}
|
||||
|
||||
template <> template <>
|
||||
void HttpHeadersTestObjectType::test<3>()
|
||||
{
|
||||
set_test_name("HttpHeaders basic find");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
|
||||
// create a new ref counted object with an implicit reference
|
||||
HttpHeaders * headers = new HttpHeaders();
|
||||
|
||||
{
|
||||
// Append a few strings
|
||||
std::string str1n("Uno");
|
||||
std::string str1v("1");
|
||||
headers->append(str1n, str1v);
|
||||
std::string str2n("doS");
|
||||
std::string str2v("2-2-2-2");
|
||||
headers->append(str2n, str2v);
|
||||
std::string str3n("TRES");
|
||||
std::string str3v("trois gymnopedie");
|
||||
headers->append(str3n, str3v);
|
||||
|
||||
ensure("Headers retained", 3 == headers->size());
|
||||
|
||||
const std::string * result(NULL);
|
||||
|
||||
// Find a header
|
||||
result = headers->find("TRES");
|
||||
ensure("Found the last item", result != NULL);
|
||||
ensure("Last item is a nice", result != NULL && str3v == *result);
|
||||
|
||||
// appends above are raw and find is case sensitive
|
||||
result = headers->find("TReS");
|
||||
ensure("Last item not found due to case", result == NULL);
|
||||
|
||||
result = headers->find("TRE");
|
||||
ensure("Last item not found due to prefixing (1)", result == NULL);
|
||||
|
||||
result = headers->find("TRESS");
|
||||
ensure("Last item not found due to prefixing (2)", result == NULL);
|
||||
}
|
||||
|
||||
// release the implicit reference, causing the object to be released
|
||||
headers->release();
|
||||
|
||||
// make sure we didn't leak any memory
|
||||
ensure(mMemTotal == GetMemTotal());
|
||||
}
|
||||
|
||||
template <> template <>
|
||||
void HttpHeadersTestObjectType::test<4>()
|
||||
{
|
||||
set_test_name("HttpHeaders normalized header entry");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
|
||||
// create a new ref counted object with an implicit reference
|
||||
HttpHeaders * headers = new HttpHeaders();
|
||||
|
||||
{
|
||||
static char line1[] = " AcCePT : image/yourfacehere";
|
||||
static char line1v[] = "image/yourfacehere";
|
||||
headers->appendNormal(line1, sizeof(line1) - 1);
|
||||
|
||||
ensure("First append worked in some fashion", 1 == headers->size());
|
||||
|
||||
const std::string * result(NULL);
|
||||
|
||||
// Find a header
|
||||
result = headers->find("accept");
|
||||
ensure("Found 'accept'", result != NULL);
|
||||
ensure("accept value has face", result != NULL && *result == line1v);
|
||||
|
||||
// Left-clean on value
|
||||
static char line2[] = " next : \t\tlinejunk \t";
|
||||
headers->appendNormal(line2, sizeof(line2) - 1);
|
||||
ensure("Second append worked", 2 == headers->size());
|
||||
result = headers->find("next");
|
||||
ensure("Found 'next'", result != NULL);
|
||||
ensure("next value is left-clean", result != NULL &&
|
||||
*result == "linejunk \t");
|
||||
|
||||
// First value unmolested
|
||||
result = headers->find("accept");
|
||||
ensure("Found 'accept' again", result != NULL);
|
||||
ensure("accept value has face", result != NULL && *result == line1v);
|
||||
|
||||
// Colons in value are okay
|
||||
static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
|
||||
static char line3v[] = ":plop:-neuf-=vleem=";
|
||||
headers->appendNormal(line3, sizeof(line3) - 1);
|
||||
ensure("Third append worked", 3 == headers->size());
|
||||
result = headers->find("fancy-pants");
|
||||
ensure("Found 'fancy-pants'", result != NULL);
|
||||
ensure("fancy-pants value has colons", result != NULL && *result == line3v);
|
||||
|
||||
// Zero-length value
|
||||
static char line4[] = "all-talk-no-walk:";
|
||||
headers->appendNormal(line4, sizeof(line4) - 1);
|
||||
ensure("Fourth append worked", 4 == headers->size());
|
||||
result = headers->find("all-talk-no-walk");
|
||||
ensure("Found 'all-talk'", result != NULL);
|
||||
ensure("al-talk value is zero-length", result != NULL && result->size() == 0);
|
||||
|
||||
// Zero-length name
|
||||
static char line5[] = ":all-talk-no-walk";
|
||||
static char line5v[] = "all-talk-no-walk";
|
||||
headers->appendNormal(line5, sizeof(line5) - 1);
|
||||
ensure("Fifth append worked", 5 == headers->size());
|
||||
result = headers->find("");
|
||||
ensure("Found no-name", result != NULL);
|
||||
ensure("no-name value is something", result != NULL && *result == line5v);
|
||||
|
||||
// Lone colon is still something
|
||||
headers->clear();
|
||||
static char line6[] = " :";
|
||||
headers->appendNormal(line6, sizeof(line6) - 1);
|
||||
ensure("Sixth append worked", 1 == headers->size());
|
||||
result = headers->find("");
|
||||
ensure("Found 2nd no-name", result != NULL);
|
||||
ensure("2nd no-name value is nothing", result != NULL && result->size() == 0);
|
||||
|
||||
// Line without colons is taken as-is and unstripped in name
|
||||
static char line7[] = " \toskdgioasdghaosdghoowg28342908tg8902hg0hwedfhqew890v7qh0wdebv78q0wdevbhq>?M>BNM<ZV>?NZ? \t";
|
||||
headers->appendNormal(line7, sizeof(line7) - 1);
|
||||
ensure("Seventh append worked", 2 == headers->size());
|
||||
result = headers->find(line7);
|
||||
ensure("Found whatsit line", result != NULL);
|
||||
ensure("Whatsit line has no value", result != NULL && result->size() == 0);
|
||||
|
||||
// Normaling interface heeds the byte count, doesn't look for NUL-terminator
|
||||
static char line8[] = "binary:ignorestuffontheendofthis";
|
||||
headers->appendNormal(line8, 13);
|
||||
ensure("Eighth append worked", 3 == headers->size());
|
||||
result = headers->find("binary");
|
||||
ensure("Found 'binary'", result != NULL);
|
||||
ensure("binary value was limited to 'ignore'", result != NULL &&
|
||||
*result == "ignore");
|
||||
|
||||
}
|
||||
|
||||
// release the implicit reference, causing the object to be released
|
||||
headers->release();
|
||||
|
||||
// make sure we didn't leak any memory
|
||||
ensure(mMemTotal == GetMemTotal());
|
||||
}
|
||||
|
||||
// Verify forward iterator finds everything as expected
|
||||
template <> template <>
|
||||
void HttpHeadersTestObjectType::test<5>()
|
||||
{
|
||||
set_test_name("HttpHeaders iterator tests");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
|
||||
// create a new ref counted object with an implicit reference
|
||||
HttpHeaders * headers = new HttpHeaders();
|
||||
|
||||
HttpHeaders::iterator end(headers->end()), begin(headers->begin());
|
||||
ensure("Empty container has equal begin/end const iterators", end == begin);
|
||||
HttpHeaders::const_iterator cend(headers->end()), cbegin(headers->begin());
|
||||
ensure("Empty container has equal rbegin/rend const iterators", cend == cbegin);
|
||||
|
||||
ensure("Empty container has equal begin/end iterators", headers->end() == headers->begin());
|
||||
|
||||
{
|
||||
static char line1[] = " AcCePT : image/yourfacehere";
|
||||
static char line1v[] = "image/yourfacehere";
|
||||
headers->appendNormal(line1, sizeof(line1) - 1);
|
||||
|
||||
static char line2[] = " next : \t\tlinejunk \t";
|
||||
static char line2v[] = "linejunk \t";
|
||||
headers->appendNormal(line2, sizeof(line2) - 1);
|
||||
|
||||
static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
|
||||
static char line3v[] = ":plop:-neuf-=vleem=";
|
||||
headers->appendNormal(line3, sizeof(line3) - 1);
|
||||
|
||||
static char line4[] = "all-talk-no-walk:";
|
||||
static char line4v[] = "";
|
||||
headers->appendNormal(line4, sizeof(line4) - 1);
|
||||
|
||||
static char line5[] = ":all-talk-no-walk";
|
||||
static char line5v[] = "all-talk-no-walk";
|
||||
headers->appendNormal(line5, sizeof(line5) - 1);
|
||||
|
||||
static char line6[] = " :";
|
||||
static char line6v[] = "";
|
||||
headers->appendNormal(line6, sizeof(line6) - 1);
|
||||
|
||||
ensure("All entries accounted for", 6 == headers->size());
|
||||
|
||||
static char * values[] = {
|
||||
line1v,
|
||||
line2v,
|
||||
line3v,
|
||||
line4v,
|
||||
line5v,
|
||||
line6v
|
||||
};
|
||||
|
||||
int i(0);
|
||||
HttpHeaders::const_iterator cend(headers->end());
|
||||
for (HttpHeaders::const_iterator it(headers->begin());
|
||||
cend != it;
|
||||
++it, ++i)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Const Iterator value # " << i << " was " << values[i];
|
||||
ensure(str.str(), (*it).second == values[i]);
|
||||
}
|
||||
|
||||
// Rewind, do non-consts
|
||||
i = 0;
|
||||
HttpHeaders::iterator end(headers->end());
|
||||
for (HttpHeaders::iterator it(headers->begin());
|
||||
end != it;
|
||||
++it, ++i)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Const Iterator value # " << i << " was " << values[i];
|
||||
ensure(str.str(), (*it).second == values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// release the implicit reference, causing the object to be released
|
||||
headers->release();
|
||||
|
||||
// make sure we didn't leak any memory
|
||||
ensure(mMemTotal == GetMemTotal());
|
||||
}
|
||||
|
||||
// Reverse iterators find everything as expected
|
||||
template <> template <>
|
||||
void HttpHeadersTestObjectType::test<6>()
|
||||
{
|
||||
set_test_name("HttpHeaders reverse iterator tests");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
|
||||
// create a new ref counted object with an implicit reference
|
||||
HttpHeaders * headers = new HttpHeaders();
|
||||
|
||||
HttpHeaders::reverse_iterator rend(headers->rend()), rbegin(headers->rbegin());
|
||||
ensure("Empty container has equal rbegin/rend const iterators", rend == rbegin);
|
||||
HttpHeaders::const_reverse_iterator crend(headers->rend()), crbegin(headers->rbegin());
|
||||
ensure("Empty container has equal rbegin/rend const iterators", crend == crbegin);
|
||||
|
||||
{
|
||||
static char line1[] = " AcCePT : image/yourfacehere";
|
||||
static char line1v[] = "image/yourfacehere";
|
||||
headers->appendNormal(line1, sizeof(line1) - 1);
|
||||
|
||||
static char line2[] = " next : \t\tlinejunk \t";
|
||||
static char line2v[] = "linejunk \t";
|
||||
headers->appendNormal(line2, sizeof(line2) - 1);
|
||||
|
||||
static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
|
||||
static char line3v[] = ":plop:-neuf-=vleem=";
|
||||
headers->appendNormal(line3, sizeof(line3) - 1);
|
||||
|
||||
static char line4[] = "all-talk-no-walk:";
|
||||
static char line4v[] = "";
|
||||
headers->appendNormal(line4, sizeof(line4) - 1);
|
||||
|
||||
static char line5[] = ":all-talk-no-walk";
|
||||
static char line5v[] = "all-talk-no-walk";
|
||||
headers->appendNormal(line5, sizeof(line5) - 1);
|
||||
|
||||
static char line6[] = " :";
|
||||
static char line6v[] = "";
|
||||
headers->appendNormal(line6, sizeof(line6) - 1);
|
||||
|
||||
ensure("All entries accounted for", 6 == headers->size());
|
||||
|
||||
static char * values[] = {
|
||||
line6v,
|
||||
line5v,
|
||||
line4v,
|
||||
line3v,
|
||||
line2v,
|
||||
line1v
|
||||
};
|
||||
|
||||
int i(0);
|
||||
HttpHeaders::const_reverse_iterator cend(headers->rend());
|
||||
for (HttpHeaders::const_reverse_iterator it(headers->rbegin());
|
||||
cend != it;
|
||||
++it, ++i)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Const Iterator value # " << i << " was " << values[i];
|
||||
ensure(str.str(), (*it).second == values[i]);
|
||||
}
|
||||
|
||||
// Rewind, do non-consts
|
||||
i = 0;
|
||||
HttpHeaders::reverse_iterator end(headers->rend());
|
||||
for (HttpHeaders::reverse_iterator it(headers->rbegin());
|
||||
end != it;
|
||||
++it, ++i)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Iterator value # " << i << " was " << values[i];
|
||||
ensure(str.str(), (*it).second == values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// release the implicit reference, causing the object to be released
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -60,6 +60,8 @@ void usleep(unsigned long usec);
|
|||
namespace tut
|
||||
{
|
||||
|
||||
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
|
||||
|
|
@ -109,11 +111,17 @@ public:
|
|||
for (int i(0); i < mHeadersRequired.size(); ++i)
|
||||
{
|
||||
bool found = false;
|
||||
for (HttpHeaders::container_t::const_iterator iter(header->mHeaders.begin());
|
||||
header->mHeaders.end() != iter;
|
||||
for (HttpHeaders::const_iterator iter(header->begin());
|
||||
header->end() != iter;
|
||||
++iter)
|
||||
{
|
||||
if (boost::regex_match(*iter, mHeadersRequired[i]))
|
||||
// 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;
|
||||
|
|
@ -129,11 +137,14 @@ public:
|
|||
{
|
||||
for (int i(0); i < mHeadersDisallowed.size(); ++i)
|
||||
{
|
||||
for (HttpHeaders::container_t::const_iterator iter(header->mHeaders.begin());
|
||||
header->mHeaders.end() != iter;
|
||||
for (HttpHeaders::const_iterator iter(header->begin());
|
||||
header->end() != iter;
|
||||
++iter)
|
||||
{
|
||||
if (boost::regex_match(*iter, mHeadersDisallowed[i]))
|
||||
if (boost::regex_match((*iter).first,
|
||||
mHeadersDisallowed[i].first) &&
|
||||
boost::regex_match((*iter).second,
|
||||
mHeadersDisallowed[i].second))
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "Disallowed header # " << i << " not found in response";
|
||||
|
|
@ -159,8 +170,8 @@ public:
|
|||
std::string mName;
|
||||
HttpHandle mExpectHandle;
|
||||
std::string mCheckContentType;
|
||||
std::vector<boost::regex> mHeadersRequired;
|
||||
std::vector<boost::regex> mHeadersDisallowed;
|
||||
regex_container_t mHeadersRequired;
|
||||
regex_container_t mHeadersDisallowed;
|
||||
};
|
||||
|
||||
typedef test_group<HttpRequestTestData> HttpRequestTestGroupType;
|
||||
|
|
@ -1335,7 +1346,9 @@ void HttpRequestTestObjectType::test<13>()
|
|||
|
||||
// Issue a GET that succeeds
|
||||
mStatus = HttpStatus(200);
|
||||
handler.mHeadersRequired.push_back(boost::regex("\\W*X-LL-Special:.*", boost::regex::icase));
|
||||
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,
|
||||
0U,
|
||||
url_base,
|
||||
|
|
@ -1702,18 +1715,54 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
// Issue a GET that *can* connect
|
||||
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.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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -1735,23 +1784,60 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
// Do a texture-style fetch
|
||||
headers = new HttpHeaders;
|
||||
headers->mHeaders.push_back("Accept: image/x-j2c");
|
||||
headers->append("Accept", "image/x-j2c");
|
||||
|
||||
mStatus = HttpStatus(200);
|
||||
handler.mHeadersRequired.clear();
|
||||
handler.mHeadersDisallowed.clear();
|
||||
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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -1892,20 +1978,63 @@ void HttpRequestTestObjectType::test<17>()
|
|||
|
||||
// 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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -2052,20 +2181,64 @@ void HttpRequestTestObjectType::test<18>()
|
|||
|
||||
// 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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -2206,27 +2379,73 @@ void HttpRequestTestObjectType::test<19>()
|
|||
|
||||
// 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");
|
||||
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(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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -2359,10 +2578,10 @@ void HttpRequestTestObjectType::test<20>()
|
|||
|
||||
// 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");
|
||||
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>");
|
||||
|
|
@ -2371,23 +2590,76 @@ void HttpRequestTestObjectType::test<20>()
|
|||
|
||||
// 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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
@ -2529,9 +2801,9 @@ void HttpRequestTestObjectType::test<21>()
|
|||
|
||||
// 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");
|
||||
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>");
|
||||
|
|
@ -2540,22 +2812,71 @@ void HttpRequestTestObjectType::test<21>()
|
|||
|
||||
// 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));
|
||||
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,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
|
|
|
|||
|
|
@ -47,24 +47,13 @@ bool LLAdaptiveRetryPolicy::getRetryAfter(const LLSD& headers, F32& retry_header
|
|||
|
||||
bool LLAdaptiveRetryPolicy::getRetryAfter(const LLCore::HttpHeaders *headers, F32& retry_header_time)
|
||||
{
|
||||
// Look for matching header. Hopefully it's correct enough to let
|
||||
// us extract the field we are looking for. Does not purport to be
|
||||
// in any way a viable general HTTP header parser.
|
||||
if (headers)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator it = headers->mHeaders.begin();
|
||||
it != headers->mHeaders.end();
|
||||
++it)
|
||||
const std::string *retry_value = headers->find(HTTP_IN_HEADER_RETRY_AFTER.c_str());
|
||||
if (retry_value &&
|
||||
getSecondsUntilRetryAfter(*retry_value, retry_header_time))
|
||||
{
|
||||
const std::string& str = *it;
|
||||
const std::string match = HTTP_IN_HEADER_RETRY_AFTER + ":";
|
||||
size_t pos = str.find(match);
|
||||
if ((pos != std::string::npos) &&
|
||||
(pos+match.length() <= str.length()))
|
||||
{
|
||||
retry_header_time = strtod(str.substr(pos+match.length()).c_str(), NULL);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -77,7 +66,6 @@ void LLAdaptiveRetryPolicy::onFailure(S32 status, const LLSD& headers)
|
|||
onFailureCommon(status, has_retry_header_time, retry_header_time);
|
||||
}
|
||||
|
||||
// TODO: replace this parsing junk once CoreHttp has its own header parsing capabilities.
|
||||
void LLAdaptiveRetryPolicy::onFailure(const LLCore::HttpResponse *response)
|
||||
{
|
||||
F32 retry_header_time;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -2480,6 +2480,7 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mQAMode(qa_mode),
|
||||
mHttpRequest(NULL),
|
||||
mHttpOptions(NULL),
|
||||
mHttpOptionsWithHeaders(NULL),
|
||||
mHttpHeaders(NULL),
|
||||
mHttpMetricsHeaders(NULL),
|
||||
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
|
|
@ -2510,11 +2511,13 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
|
||||
mHttpRequest = new LLCore::HttpRequest;
|
||||
mHttpOptions = new LLCore::HttpOptions;
|
||||
mHttpOptionsWithHeaders = new LLCore::HttpOptions;
|
||||
mHttpOptionsWithHeaders->setWantHeaders(true);
|
||||
mHttpHeaders = new LLCore::HttpHeaders;
|
||||
// *TODO: Should this be 'image/j2c' instead of 'image/x-j2c' ?
|
||||
mHttpHeaders->mHeaders.push_back(HTTP_OUT_HEADER_ACCEPT + ": " + HTTP_CONTENT_IMAGE_X_J2C);
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
|
||||
mHttpMetricsHeaders = new LLCore::HttpHeaders;
|
||||
mHttpMetricsHeaders->mHeaders.push_back(HTTP_OUT_HEADER_CONTENT_TYPE + ": " + HTTP_CONTENT_LLSD_XML);
|
||||
mHttpMetricsHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
|
||||
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault();
|
||||
}
|
||||
|
||||
|
|
@ -2535,6 +2538,12 @@ LLTextureFetch::~LLTextureFetch()
|
|||
mHttpOptions = NULL;
|
||||
}
|
||||
|
||||
if (mHttpOptionsWithHeaders)
|
||||
{
|
||||
mHttpOptionsWithHeaders->release();
|
||||
mHttpOptionsWithHeaders = NULL;
|
||||
}
|
||||
|
||||
if (mHttpHeaders)
|
||||
{
|
||||
mHttpHeaders->release();
|
||||
|
|
@ -4143,7 +4152,7 @@ void LLTextureFetchDebugger::init()
|
|||
{
|
||||
mHttpHeaders = new LLCore::HttpHeaders;
|
||||
// *TODO: Should this be 'image/j2c' instead of 'image/x-j2c' ?
|
||||
mHttpHeaders->mHeaders.push_back(HTTP_OUT_HEADER_ACCEPT + ": " + HTTP_CONTENT_IMAGE_X_J2C);
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
* Copyright (C) 2012-2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -352,6 +352,7 @@ private:
|
|||
// LLCurl interfaces used in the past.
|
||||
LLCore::HttpRequest * mHttpRequest; // Ttf
|
||||
LLCore::HttpOptions * mHttpOptions; // Ttf
|
||||
LLCore::HttpOptions * mHttpOptionsWithHeaders; // Ttf
|
||||
LLCore::HttpHeaders * mHttpHeaders; // Ttf
|
||||
LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
|
||||
LLCore::HttpRequest::policy_t mHttpPolicyClass; // T*
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ void RetryPolicyTestObject::test<7>()
|
|||
LLCore::HttpHeaders *headers = new LLCore::HttpHeaders();
|
||||
response->setStatus(503);
|
||||
response->setHeaders(headers);
|
||||
headers->mHeaders.push_back(HTTP_IN_HEADER_RETRY_AFTER + ": 600");
|
||||
headers->append(HTTP_IN_HEADER_RETRY_AFTER, std::string("600"));
|
||||
policy.onFailure(response);
|
||||
should_retry = policy.shouldRetry(seconds_to_wait);
|
||||
ensure("header 3",should_retry);
|
||||
|
|
@ -272,7 +272,7 @@ void RetryPolicyTestObject::test<7>()
|
|||
response->setHeaders(headers);
|
||||
LLSD sd_headers;
|
||||
time(&nowseconds);
|
||||
headers->mHeaders.push_back(HTTP_IN_HEADER_RETRY_AFTER + ": " + LLDate((F64)nowseconds).asRFC1123());
|
||||
headers->append(HTTP_IN_HEADER_RETRY_AFTER,LLDate((F64)nowseconds).asRFC1123());
|
||||
policy.onFailure(response);
|
||||
should_retry = policy.shouldRetry(seconds_to_wait);
|
||||
ensure("header 4",should_retry);
|
||||
|
|
|
|||
Loading…
Reference in New Issue