SH-4257 Preparation for a new cap grant: GetMesh2

Thu, 20 Jun 2013 19:18:39 -0400

author
Monty Brandenberg <monty@lindenlab.com>
date
Thu, 20 Jun 2013 19:18:39 -0400
changeset 40685
6335fca454a8
parent 40684
f110aa675d5e
child 40686
08c1824b4ac3

SH-4257 Preparation for a new cap grant: GetMesh2
Mesh repo is using three policy classes now: one for
large objects, one for GetMesh2 regions, one for
GetMesh regions. It's also detecting the presence
of the cap and using the correct class. Class
initialization cleaned up significantly in llappcorehttp
using data-directed code. Pulled in the changes to
HttpHeader done for sunshine-internal then did a
refactoring pass on the header callback which now
uses a unified approach to clean up and deliver
header information to all interested parties. Added
support for using Retry-After header information on
503 retries.

indra/llcorehttp/_httpinternal.h file | annotate | diff | revisions
indra/llcorehttp/_httpoperation.cpp file | annotate | diff | revisions
indra/llcorehttp/_httpoprequest.cpp file | annotate | diff | revisions
indra/llcorehttp/_httpoprequest.h file | annotate | diff | revisions
indra/llcorehttp/_httppolicy.cpp file | annotate | diff | revisions
indra/llcorehttp/_httppolicyclass.cpp file | annotate | diff | revisions
indra/llcorehttp/_httpservice.cpp file | annotate | diff | revisions
indra/llcorehttp/httpoptions.cpp file | annotate | diff | revisions
indra/llcorehttp/httpoptions.h file | annotate | diff | revisions
indra/newview/llappcorehttp.cpp file | annotate | diff | revisions
indra/newview/llappcorehttp.h file | annotate | diff | revisions
indra/newview/llmeshrepository.cpp file | annotate | diff | revisions
indra/newview/llmeshrepository.h file | annotate | diff | revisions
     1.1 --- a/indra/llcorehttp/_httpinternal.h	Wed Jun 19 19:58:09 2013 +0000
     1.2 +++ b/indra/llcorehttp/_httpinternal.h	Thu Jun 20 19:18:39 2013 -0400
     1.3 @@ -98,7 +98,7 @@
     1.4  
     1.5  // Maxium number of policy classes that can be defined.
     1.6  // *TODO:  Currently limited to the default class + 1, extend.
     1.7 -const int HTTP_POLICY_CLASS_LIMIT = 4;
     1.8 +const int HTTP_POLICY_CLASS_LIMIT = 8;
     1.9  
    1.10  // Debug/informational tracing.  Used both
    1.11  // as a global option and in per-request traces.
    1.12 @@ -138,6 +138,10 @@
    1.13  const int HTTP_CONNECTION_LIMIT_MIN = 1;
    1.14  const int HTTP_CONNECTION_LIMIT_MAX = 256;
    1.15  
    1.16 +// Miscellaneous defaults
    1.17 +const long HTTP_PIPELINING_DEFAULT = 0L;
    1.18 +const bool HTTP_USE_RETRY_AFTER_DEFAULT = true;
    1.19 +
    1.20  // Tuning parameters
    1.21  
    1.22  // Time worker thread sleeps after a pass through the
     2.1 --- a/indra/llcorehttp/_httpoperation.cpp	Wed Jun 19 19:58:09 2013 +0000
     2.2 +++ b/indra/llcorehttp/_httpoperation.cpp	Thu Jun 20 19:18:39 2013 -0400
     2.3 @@ -4,7 +4,7 @@
     2.4   *
     2.5   * $LicenseInfo:firstyear=2012&license=viewerlgpl$
     2.6   * Second Life Viewer Source Code
     2.7 - * Copyright (C) 2012, Linden Research, Inc.
     2.8 + * Copyright (C) 2012-2013, Linden Research, Inc.
     2.9   *
    2.10   * This library is free software; you can redistribute it and/or
    2.11   * modify it under the terms of the GNU Lesser General Public
    2.12 @@ -53,7 +53,7 @@
    2.13  	  mUserHandler(NULL),
    2.14  	  mReqPolicy(HttpRequest::DEFAULT_POLICY_ID),
    2.15  	  mReqPriority(0U),
    2.16 -	  mTracing(0)
    2.17 +	  mTracing(HTTP_TRACE_OFF)
    2.18  {
    2.19  	mMetricCreated = totalTime();
    2.20  }
     3.1 --- a/indra/llcorehttp/_httpoprequest.cpp	Wed Jun 19 19:58:09 2013 +0000
     3.2 +++ b/indra/llcorehttp/_httpoprequest.cpp	Thu Jun 20 19:18:39 2013 -0400
     3.3 @@ -64,6 +64,15 @@
     3.4  							   unsigned int * last,
     3.5  							   unsigned int * length);
     3.6  
     3.7 +// Similar for Retry-After headers.  Only parses the delta form
     3.8 +// of the header, HTTP time formats aren't interesting for client
     3.9 +// purposes.
    3.10 +//
    3.11 +// @return		0 if successfully parsed and seconds time delta
    3.12 +//				returned in time argument.
    3.13 +//
    3.14 +int parse_retry_after_header(char * buffer, int * time);
    3.15 +
    3.16  
    3.17  // Take data from libcurl's CURLOPT_DEBUGFUNCTION callback and
    3.18  // escape and format it for a tracing line in logging.  Absolutely
    3.19 @@ -74,14 +83,12 @@
    3.20  							   std::string & safe_line);
    3.21  
    3.22  
    3.23 -// OS-neutral string comparisons of various types
    3.24 -int os_strncasecmp(const char *s1, const char *s2, size_t n);
    3.25 -int os_strcasecmp(const char *s1, const char *s2);
    3.26 -char * os_strtok_r(char *str, const char *delim, char **saveptr);
    3.27 -
    3.28 -
    3.29 -static const char * const hdr_whitespace(" \t");
    3.30 -static const char * const hdr_separator(": \t");
    3.31 +// OS-neutral string comparisons of various types.
    3.32 +int os_strcasecmp(const char * s1, const char * s2);
    3.33 +char * os_strtok_r(char * str, const char * delim, char ** saveptr);
    3.34 +char * os_strtrim(char * str);
    3.35 +char * os_strltrim(char * str);
    3.36 +void os_strlower(char * str);
    3.37  
    3.38  } // end anonymous namespace
    3.39  
    3.40 @@ -104,6 +111,8 @@
    3.41  	  mCurlService(NULL),
    3.42  	  mCurlHeaders(NULL),
    3.43  	  mCurlBodyPos(0),
    3.44 +	  mCurlTemp(NULL),
    3.45 +	  mCurlTempLen(0),
    3.46  	  mReplyBody(NULL),
    3.47  	  mReplyOffset(0),
    3.48  	  mReplyLength(0),
    3.49 @@ -154,6 +163,10 @@
    3.50  		mCurlHeaders = NULL;
    3.51  	}
    3.52  
    3.53 +	delete [] mCurlTemp;
    3.54 +	mCurlTemp = NULL;
    3.55 +	mCurlTempLen = 0;
    3.56 +	
    3.57  	if (mReplyBody)
    3.58  	{
    3.59  		mReplyBody->release();
    3.60 @@ -207,6 +220,11 @@
    3.61  		mCurlHeaders = NULL;
    3.62  	}
    3.63  
    3.64 +	// Also not needed on the other side
    3.65 +	delete [] mCurlTemp;
    3.66 +	mCurlTemp = NULL;
    3.67 +	mCurlTempLen = 0;
    3.68 +	
    3.69  	addAsReply();
    3.70  }
    3.71  
    3.72 @@ -335,6 +353,10 @@
    3.73  		{
    3.74  			mProcFlags |= PF_SAVE_HEADERS;
    3.75  		}
    3.76 +		if (options->getUseRetryAfter())
    3.77 +		{
    3.78 +			mProcFlags |= PF_USE_RETRY_AFTER;
    3.79 +		}
    3.80  		mPolicyRetryLimit = options->getRetries();
    3.81  		mPolicyRetryLimit = llclamp(mPolicyRetryLimit, HTTP_RETRY_COUNT_MIN, HTTP_RETRY_COUNT_MAX);
    3.82  		mTracing = (std::max)(mTracing, llclamp(options->getTrace(), HTTP_TRACE_MIN, HTTP_TRACE_MAX));
    3.83 @@ -549,7 +571,7 @@
    3.84  	}
    3.85  	curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
    3.86  
    3.87 -	if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS))
    3.88 +	if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_USE_RETRY_AFTER))
    3.89  	{
    3.90  		curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
    3.91  		curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
    3.92 @@ -610,10 +632,9 @@
    3.93  {
    3.94  	static const char status_line[] = "HTTP/";
    3.95  	static const size_t status_line_len = sizeof(status_line) - 1;
    3.96 -
    3.97 -	static const char con_ran_line[] = "content-range:";
    3.98 -	static const size_t con_ran_line_len = sizeof(con_ran_line) - 1;
    3.99 -
   3.100 +	static const char con_ran_line[] = "content-range";
   3.101 +	static const char con_retry_line[] = "retry-after";
   3.102 +	
   3.103  	HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
   3.104  
   3.105  	const size_t hdr_size(size * nmemb);
   3.106 @@ -627,6 +648,7 @@
   3.107  		op->mReplyOffset = 0;
   3.108  		op->mReplyLength = 0;
   3.109  		op->mReplyFullLength = 0;
   3.110 +		op->mReplyRetryAfter = 0;
   3.111  		op->mStatus = HttpStatus();
   3.112  		if (op->mReplyHeaders)
   3.113  		{
   3.114 @@ -645,6 +667,53 @@
   3.115  			--wanted_hdr_size;
   3.116  		}
   3.117  	}
   3.118 +
   3.119 +	// Copy and normalize header fragments for the following
   3.120 +	// stages.  Would like to modify the data in-place but that
   3.121 +	// may not be allowed and we need one byte extra for NUL.
   3.122 +	// At the end of this we will have:
   3.123 +	//
   3.124 +	// If ':' present in header:
   3.125 +	//   1.  name points to text to left of colon which
   3.126 +	//       will be ascii lower-cased and left and right
   3.127 +	//       trimmed of whitespace.
   3.128 +	//   2.  value points to text to right of colon which
   3.129 +	//       will be left trimmed of whitespace.
   3.130 +	// Otherwise:
   3.131 +	//   1.  name points to header which will be left
   3.132 +	//       trimmed of whitespace.
   3.133 +	//   2.  value is NULL
   3.134 +	// Any non-NULL pointer may point to a zero-length string.
   3.135 +	//
   3.136 +	if (wanted_hdr_size >= op->mCurlTempLen)
   3.137 +	{
   3.138 +		delete [] op->mCurlTemp;
   3.139 +		op->mCurlTempLen = 2 * wanted_hdr_size + 1;
   3.140 +		op->mCurlTemp = new char [op->mCurlTempLen];
   3.141 +	}
   3.142 +	memcpy(op->mCurlTemp, hdr_data, wanted_hdr_size);
   3.143 +	op->mCurlTemp[wanted_hdr_size] = '\0';
   3.144 +	char * name(op->mCurlTemp);
   3.145 +	char * value(strchr(name, ':'));
   3.146 +	if (value)
   3.147 +	{
   3.148 +		*value++ = '\0';
   3.149 +		os_strlower(name);
   3.150 +		name = os_strtrim(name);
   3.151 +		value = os_strltrim(value);
   3.152 +	}
   3.153 +	else
   3.154 +	{
   3.155 +		// Doesn't look well-formed, do minimal normalization on it
   3.156 +		name = os_strltrim(name);
   3.157 +	}
   3.158 +
   3.159 +	// Normalized, now reject headers with empty names.
   3.160 +	if (! *name)
   3.161 +	{
   3.162 +		// No use continuing
   3.163 +		return hdr_size;
   3.164 +	}
   3.165  	
   3.166  	// Save header if caller wants them in the response
   3.167  	if (is_header && op->mProcFlags & PF_SAVE_HEADERS)
   3.168 @@ -654,43 +723,53 @@
   3.169  		{
   3.170  			op->mReplyHeaders = new HttpHeaders;
   3.171  		}
   3.172 -		op->mReplyHeaders->appendNormal(hdr_data, wanted_hdr_size);
   3.173 +		op->mReplyHeaders->append(name, value ? value : "");
   3.174  	}
   3.175  
   3.176 +	// From this point, header-specific processors are free to
   3.177 +	// modify the header value.
   3.178 +	
   3.179  	// Detect and parse 'Content-Range' headers
   3.180 -	if (is_header && op->mProcFlags & PF_SCAN_RANGE_HEADER)
   3.181 +	if (is_header
   3.182 +		&& op->mProcFlags & PF_SCAN_RANGE_HEADER
   3.183 +		&& value && *value
   3.184 +		&& ! strcmp(name, con_ran_line))
   3.185  	{
   3.186 -		char hdr_buffer[128];			// Enough for a reasonable header
   3.187 -		size_t frag_size((std::min)(wanted_hdr_size, sizeof(hdr_buffer) - 1));
   3.188 -		
   3.189 -		memcpy(hdr_buffer, hdr_data, frag_size);
   3.190 -		hdr_buffer[frag_size] = '\0';
   3.191 -		if (frag_size > con_ran_line_len &&
   3.192 -			! os_strncasecmp(hdr_buffer, con_ran_line, con_ran_line_len))
   3.193 +		unsigned int first(0), last(0), length(0);
   3.194 +		int status;
   3.195 +
   3.196 +		if (! (status = parse_content_range_header(value, &first, &last, &length)))
   3.197  		{
   3.198 -			unsigned int first(0), last(0), length(0);
   3.199 -			int status;
   3.200 +			// Success, record the fragment position
   3.201 +			op->mReplyOffset = first;
   3.202 +			op->mReplyLength = last - first + 1;
   3.203 +			op->mReplyFullLength = length;
   3.204 +		}
   3.205 +		else if (-1 == status)
   3.206 +		{
   3.207 +			// Response is badly formed and shouldn't be accepted
   3.208 +			op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
   3.209 +		}
   3.210 +		else
   3.211 +		{
   3.212 +			// Ignore the unparsable.
   3.213 +			LL_INFOS_ONCE("CoreHttp") << "Problem parsing odd Content-Range header:  '"
   3.214 +									  << std::string(hdr_data, wanted_hdr_size)
   3.215 +									  << "'.  Ignoring."
   3.216 +									  << LL_ENDL;
   3.217 +		}
   3.218 +	}
   3.219  
   3.220 -			if (! (status = parse_content_range_header(hdr_buffer, &first, &last, &length)))
   3.221 -			{
   3.222 -				// Success, record the fragment position
   3.223 -				op->mReplyOffset = first;
   3.224 -				op->mReplyLength = last - first + 1;
   3.225 -				op->mReplyFullLength = length;
   3.226 -			}
   3.227 -			else if (-1 == status)
   3.228 -			{
   3.229 -				// Response is badly formed and shouldn't be accepted
   3.230 -				op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
   3.231 -			}
   3.232 -			else
   3.233 -			{
   3.234 -				// Ignore the unparsable.
   3.235 -				LL_INFOS_ONCE("CoreHttp") << "Problem parsing odd Content-Range header:  '"
   3.236 -										  << std::string(hdr_data, frag_size)
   3.237 -										  << "'.  Ignoring."
   3.238 -										  << LL_ENDL;
   3.239 -			}
   3.240 +	// Detect and parse 'Retry-After' headers
   3.241 +	if (is_header
   3.242 +		&& op->mProcFlags & PF_USE_RETRY_AFTER
   3.243 +		&& value && *value
   3.244 +		&& ! strcmp(name, con_retry_line))
   3.245 +	{
   3.246 +		int time(0);
   3.247 +		if (! parse_retry_after_header(value, &time))
   3.248 +		{
   3.249 +			op->mReplyRetryAfter = time;
   3.250  		}
   3.251  	}
   3.252  
   3.253 @@ -805,14 +884,16 @@
   3.254  							   unsigned int * last,
   3.255  							   unsigned int * length)
   3.256  {
   3.257 +	static const char * const hdr_whitespace(" \t");
   3.258 +
   3.259  	char * tok_state(NULL), * tok(NULL);
   3.260  	bool match(true);
   3.261  			
   3.262 -	if (! os_strtok_r(buffer, hdr_separator, &tok_state))
   3.263 +	if (! (tok = os_strtok_r(buffer, hdr_whitespace, &tok_state)))
   3.264  		match = false;
   3.265 -	if (match && (tok = os_strtok_r(NULL, hdr_whitespace, &tok_state)))
   3.266 -		match = 0 == os_strcasecmp("bytes", tok);
   3.267 -	if (match && ! (tok = os_strtok_r(NULL, " \t", &tok_state)))
   3.268 +	else
   3.269 +		match = (0 == os_strcasecmp("bytes", tok));
   3.270 +	if (match && ! (tok = os_strtok_r(NULL, hdr_whitespace, &tok_state)))
   3.271  		match = false;
   3.272  	if (match)
   3.273  	{
   3.274 @@ -851,6 +932,25 @@
   3.275  }
   3.276  
   3.277  
   3.278 +int parse_retry_after_header(char * buffer, int * time)
   3.279 +{
   3.280 +	char * endptr(buffer);
   3.281 +	long lcl_time(strtol(buffer, &endptr, 10));
   3.282 +	if (*endptr == '\0' && endptr != buffer && lcl_time > 0)
   3.283 +	{
   3.284 +		*time = lcl_time;
   3.285 +		return 0;
   3.286 +	}
   3.287 +
   3.288 +	// Could attempt to parse HTTP time here but we're not really
   3.289 +	// interested in it.  Scheduling based on wallclock time on
   3.290 +	// user hardware will lead to tears.
   3.291 +	
   3.292 +	// Header is there but badly/unexpectedly formed, try to ignore it.
   3.293 +	return 1;
   3.294 +}
   3.295 +
   3.296 +
   3.297  void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub, std::string & safe_line)
   3.298  {
   3.299  	std::string out;
   3.300 @@ -887,15 +987,6 @@
   3.301  }
   3.302  
   3.303  
   3.304 -int os_strncasecmp(const char *s1, const char *s2, size_t n)
   3.305 -{
   3.306 -#if LL_WINDOWS
   3.307 -	return _strnicmp(s1, s2, n);
   3.308 -#else
   3.309 -	return strncasecmp(s1, s2, n);
   3.310 -#endif	// LL_WINDOWS
   3.311 -}
   3.312 -
   3.313  
   3.314  int os_strcasecmp(const char *s1, const char *s2)
   3.315  {
   3.316 @@ -917,6 +1008,45 @@
   3.317  }
   3.318  
   3.319  
   3.320 +void os_strlower(char * str)
   3.321 +{
   3.322 +	for (char c(0); (c = *str); ++str)
   3.323 +	{
   3.324 +		*str = tolower(c);
   3.325 +	}
   3.326 +}
   3.327 +
   3.328 +
   3.329 +char * os_strtrim(char * lstr)
   3.330 +{
   3.331 +	while (' ' == *lstr || '\t' == *lstr)
   3.332 +	{
   3.333 +		++lstr;
   3.334 +	}
   3.335 +	if (*lstr)
   3.336 +	{
   3.337 +		for (char * rstr(lstr + strlen(lstr)); *--rstr;)
   3.338 +		{
   3.339 +			if (' ' == *rstr || '\t' == *rstr)
   3.340 +			{
   3.341 +				*rstr = '\0';
   3.342 +			}
   3.343 +		}
   3.344 +	}
   3.345 +	return lstr;
   3.346 +}
   3.347 +
   3.348 +
   3.349 +char * os_strltrim(char * lstr)
   3.350 +{
   3.351 +	while (' ' == *lstr || '\t' == *lstr)
   3.352 +	{
   3.353 +		++lstr;
   3.354 +	}
   3.355 +	return lstr;
   3.356 +}
   3.357 +
   3.358 +
   3.359  }  // end anonymous namespace
   3.360  
   3.361  		
     4.1 --- a/indra/llcorehttp/_httpoprequest.h	Wed Jun 19 19:58:09 2013 +0000
     4.2 +++ b/indra/llcorehttp/_httpoprequest.h	Thu Jun 20 19:18:39 2013 -0400
     4.3 @@ -158,6 +158,7 @@
     4.4  	unsigned int		mProcFlags;
     4.5  	static const unsigned int	PF_SCAN_RANGE_HEADER = 0x00000001U;
     4.6  	static const unsigned int	PF_SAVE_HEADERS = 0x00000002U;
     4.7 +	static const unsigned int	PF_USE_RETRY_AFTER = 0x00000004U;
     4.8  
     4.9  public:
    4.10  	// Request data
    4.11 @@ -175,6 +176,8 @@
    4.12  	HttpService *		mCurlService;
    4.13  	curl_slist *		mCurlHeaders;
    4.14  	size_t				mCurlBodyPos;
    4.15 +	char *				mCurlTemp;				// Scratch buffer for header processing
    4.16 +	size_t				mCurlTempLen;
    4.17  	
    4.18  	// Result data
    4.19  	HttpStatus			mStatus;
    4.20 @@ -184,6 +187,7 @@
    4.21  	size_t				mReplyFullLength;
    4.22  	HttpHeaders *		mReplyHeaders;
    4.23  	std::string			mReplyConType;
    4.24 +	int					mReplyRetryAfter;
    4.25  
    4.26  	// Policy data
    4.27  	int					mPolicyRetries;
     5.1 --- a/indra/llcorehttp/_httppolicy.cpp	Wed Jun 19 19:58:09 2013 +0000
     5.2 +++ b/indra/llcorehttp/_httppolicy.cpp	Thu Jun 20 19:18:39 2013 -0400
     5.3 @@ -160,8 +160,12 @@
     5.4  	
     5.5  	const HttpTime now(totalTime());
     5.6  	const int policy_class(op->mReqPolicy);
     5.7 -	
     5.8 -	const HttpTime delta(retry_deltas[llclamp(op->mPolicyRetries, 0, delta_max)]);
     5.9 +	HttpTime delta(retry_deltas[llclamp(op->mPolicyRetries, 0, delta_max)]);
    5.10 +
    5.11 +	if (op->mReplyRetryAfter > 0 && op->mReplyRetryAfter < 30)
    5.12 +	{
    5.13 +		delta = op->mReplyRetryAfter * U64L(1000000);
    5.14 +	}
    5.15  	op->mPolicyRetryAt = now + delta;
    5.16  	++op->mPolicyRetries;
    5.17  	if (error_503 == op->mStatus)
    5.18 @@ -170,10 +174,10 @@
    5.19  	}
    5.20  	LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op)
    5.21  						 << " retry " << op->mPolicyRetries
    5.22 -						 << " scheduled for +" << (delta / HttpTime(1000))
    5.23 +						 << " scheduled in " << (delta / HttpTime(1000))
    5.24  						 << " mS.  Status:  " << op->mStatus.toHex()
    5.25  						 << LL_ENDL;
    5.26 -	if (op->mTracing > 0)
    5.27 +	if (op->mTracing > HTTP_TRACE_OFF)
    5.28  	{
    5.29  		LL_INFOS("CoreHttp") << "TRACE, ToRetryQueue, Handle:  "
    5.30  							 << static_cast<HttpHandle>(op)
     6.1 --- a/indra/llcorehttp/_httppolicyclass.cpp	Wed Jun 19 19:58:09 2013 +0000
     6.2 +++ b/indra/llcorehttp/_httppolicyclass.cpp	Thu Jun 20 19:18:39 2013 -0400
     6.3 @@ -4,7 +4,7 @@
     6.4   *
     6.5   * $LicenseInfo:firstyear=2012&license=viewerlgpl$
     6.6   * Second Life Viewer Source Code
     6.7 - * Copyright (C) 2012, Linden Research, Inc.
     6.8 + * Copyright (C) 2012-2013, Linden Research, Inc.
     6.9   *
    6.10   * This library is free software; you can redistribute it and/or
    6.11   * modify it under the terms of the GNU Lesser General Public
    6.12 @@ -37,7 +37,7 @@
    6.13  	: mSetMask(0UL),
    6.14  	  mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
    6.15  	  mPerHostConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
    6.16 -	  mPipelining(0)
    6.17 +	  mPipelining(HTTP_PIPELINING_DEFAULT)
    6.18  {}
    6.19  
    6.20  
     7.1 --- a/indra/llcorehttp/_httpservice.cpp	Wed Jun 19 19:58:09 2013 +0000
     7.2 +++ b/indra/llcorehttp/_httpservice.cpp	Thu Jun 20 19:18:39 2013 -0400
     7.3 @@ -55,9 +55,6 @@
     7.4  {
     7.5  	// Create the default policy class
     7.6  	HttpPolicyClass pol_class;
     7.7 -	pol_class.set(HttpRequest::CP_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT);
     7.8 -	pol_class.set(HttpRequest::CP_PER_HOST_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT);
     7.9 -	pol_class.set(HttpRequest::CP_ENABLE_PIPELINING, 0L);
    7.10  	mPolicyClasses.push_back(pol_class);
    7.11  }
    7.12  
     8.1 --- a/indra/llcorehttp/httpoptions.cpp	Wed Jun 19 19:58:09 2013 +0000
     8.2 +++ b/indra/llcorehttp/httpoptions.cpp	Thu Jun 20 19:18:39 2013 -0400
     8.3 @@ -39,7 +39,8 @@
     8.4  	  mTracing(HTTP_TRACE_OFF),
     8.5  	  mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
     8.6  	  mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
     8.7 -	  mRetries(HTTP_RETRY_COUNT_DEFAULT)
     8.8 +	  mRetries(HTTP_RETRY_COUNT_DEFAULT),
     8.9 +	  mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT)
    8.10  {}
    8.11  
    8.12  
    8.13 @@ -76,5 +77,10 @@
    8.14  	mRetries = retries;
    8.15  }
    8.16  
    8.17 +void HttpOptions::setUseRetryAfter(bool use_retry)
    8.18 +{
    8.19 +	mUseRetryAfter = use_retry;
    8.20 +}
    8.21 +
    8.22  
    8.23  }   // end namespace LLCore
     9.1 --- a/indra/llcorehttp/httpoptions.h	Wed Jun 19 19:58:09 2013 +0000
     9.2 +++ b/indra/llcorehttp/httpoptions.h	Thu Jun 20 19:18:39 2013 -0400
     9.3 @@ -98,13 +98,19 @@
     9.4  			return mRetries;
     9.5  		}
     9.6  	
     9.7 +	void				setUseRetryAfter(bool use_retry);
     9.8 +	bool				getUseRetryAfter() const
     9.9 +		{
    9.10 +			return mUseRetryAfter;
    9.11 +		}
    9.12 +	
    9.13  protected:
    9.14  	bool				mWantHeaders;
    9.15  	int					mTracing;
    9.16  	unsigned int		mTimeout;
    9.17  	unsigned int		mTransferTimeout;
    9.18  	unsigned int		mRetries;
    9.19 -	
    9.20 +	bool				mUseRetryAfter;
    9.21  }; // end class HttpOptions
    9.22  
    9.23  
    10.1 --- a/indra/newview/llappcorehttp.cpp	Wed Jun 19 19:58:09 2013 +0000
    10.2 +++ b/indra/newview/llappcorehttp.cpp	Thu Jun 20 19:18:39 2013 -0400
    10.3 @@ -72,11 +72,17 @@
    10.4  				  "texture fetch"
    10.5  			  },
    10.6  			  {
    10.7 -				  AP_MESH,				8,		1,		32,		4,
    10.8 +				  // *FIXME:  Should become 32, 1, 32, 1 before release
    10.9 +				  AP_MESH1,				8,		1,		32,		4,
   10.10  				  "MeshMaxConcurrentRequests",
   10.11  				  "mesh fetch"
   10.12  			  },
   10.13  			  {
   10.14 +				  AP_MESH2,				8,		1,		32,		4,
   10.15 +				  "MeshMaxConcurrentRequests",
   10.16 +				  "mesh2 fetch"
   10.17 +			  },
   10.18 +			  {
   10.19  				  AP_LARGE_MESH,		2,		1,		8,		1,
   10.20  				  "",
   10.21  				  "large mesh fetch"
   10.22 @@ -171,6 +177,8 @@
   10.23  		}
   10.24  
   10.25  		// Set it and report
   10.26 +		// *TODO:  These are intended to be per-host limits when we can
   10.27 +		// support that in llcorehttp/libcurl.
   10.28  		LLCore::HttpStatus status;
   10.29  		status = LLCore::HttpRequest::setPolicyClassOption(mPolicies[policy],
   10.30  														   LLCore::HttpRequest::CP_CONNECTION_LIMIT,
    11.1 --- a/indra/newview/llappcorehttp.h	Wed Jun 19 19:58:09 2013 +0000
    11.2 +++ b/indra/newview/llappcorehttp.h	Thu Jun 20 19:18:39 2013 -0400
    11.3 @@ -47,7 +47,8 @@
    11.4  	{
    11.5  		AP_DEFAULT,
    11.6  		AP_TEXTURE,
    11.7 -		AP_MESH,
    11.8 +		AP_MESH1,
    11.9 +		AP_MESH2,
   11.10  		AP_LARGE_MESH,
   11.11  		AP_UPLOADS,
   11.12  		AP_COUNT						// Must be last
    12.1 --- a/indra/newview/llmeshrepository.cpp	Wed Jun 19 19:58:09 2013 +0000
    12.2 +++ b/indra/newview/llmeshrepository.cpp	Thu Jun 20 19:18:39 2013 -0400
    12.3 @@ -560,6 +560,7 @@
    12.4    mHttpLargeOptions(NULL),
    12.5    mHttpHeaders(NULL),
    12.6    mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
    12.7 +  mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
    12.8    mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
    12.9    mHttpPriority(0),
   12.10    mHttpGetCount(0U),
   12.11 @@ -574,8 +575,9 @@
   12.12  	mHttpLargeOptions->setTransferTimeout(LARGE_MESH_XFER_TIMEOUT);
   12.13  	mHttpHeaders = new LLCore::HttpHeaders;
   12.14  	mHttpHeaders->append("Accept", "application/vnd.ll.mesh");
   12.15 -	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_MESH);
   12.16 -	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
   12.17 +	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_MESH2);
   12.18 +	mHttpLegacyPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_MESH1);
   12.19 +	mHttpLargePolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
   12.20  }
   12.21  
   12.22  
   12.23 @@ -795,13 +797,22 @@
   12.24  }
   12.25  
   12.26  //static 
   12.27 -std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id)
   12.28 +std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id, int * cap_version)
   12.29  {
   12.30 +	int version(1);
   12.31  	std::string http_url;
   12.32  	
   12.33  	if (gAgent.getRegion())
   12.34  	{
   12.35 -		http_url = gMeshRepo.mGetMeshCapability; 
   12.36 +		if (! gMeshRepo.mGetMesh2Capability.empty())
   12.37 +		{
   12.38 +			version = 2;
   12.39 +			http_url = gMeshRepo.mGetMesh2Capability;
   12.40 +		}
   12.41 +		else
   12.42 +		{
   12.43 +			http_url = gMeshRepo.mGetMeshCapability;
   12.44 +		}
   12.45  	}
   12.46  
   12.47  	if (!http_url.empty())
   12.48 @@ -814,20 +825,22 @@
   12.49  		llwarns << "Current region does not have GetMesh capability!  Cannot load " << mesh_id << ".mesh" << llendl;
   12.50  	}
   12.51  
   12.52 +	*cap_version = version;
   12.53  	return http_url;
   12.54  }
   12.55  
   12.56  // May only be called by repo thread
   12.57 -LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
   12.58 -												  size_t offset,
   12.59 -												  size_t len,
   12.60 +LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int cap_version,
   12.61 +												  size_t offset, size_t len,
   12.62  												  LLCore::HttpHandler * handler)
   12.63  {
   12.64  	LLCore::HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
   12.65  	
   12.66  	if (len < LARGE_MESH_FETCH_THRESHOLD)
   12.67  	{
   12.68 -		handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
   12.69 +		handle = mHttpRequest->requestGetByteRange((2 == cap_version
   12.70 +													? mHttpPolicyClass
   12.71 +													: mHttpLegacyPolicyClass),
   12.72  												   mHttpPriority,
   12.73  												   url,
   12.74  												   offset,
   12.75 @@ -911,12 +924,13 @@
   12.76  			}
   12.77  
   12.78  			//reading from VFS failed for whatever reason, fetch from sim
   12.79 -			std::string http_url = constructUrl(mesh_id);
   12.80 +			int cap_version(1);
   12.81 +			std::string http_url = constructUrl(mesh_id, &cap_version);
   12.82  			if (!http_url.empty())
   12.83  			{
   12.84  				LLMeshSkinInfoHandler * handler = new LLMeshSkinInfoHandler(mesh_id, offset, size);
   12.85  				// LL_WARNS("Mesh") << "MESH:  Issuing Skin Info Request" << LL_ENDL;
   12.86 -				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
   12.87 +				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
   12.88  				if (LLCORE_HTTP_HANDLE_INVALID == handle)
   12.89  				{
   12.90  					// *TODO:  Better error message
   12.91 @@ -1000,12 +1014,13 @@
   12.92  			}
   12.93  
   12.94  			//reading from VFS failed for whatever reason, fetch from sim
   12.95 -			std::string http_url = constructUrl(mesh_id);
   12.96 +			int cap_version(1);
   12.97 +			std::string http_url = constructUrl(mesh_id, &cap_version);
   12.98  			if (!http_url.empty())
   12.99  			{
  12.100  				LLMeshDecompositionHandler * handler = new LLMeshDecompositionHandler(mesh_id, offset, size);
  12.101  				// LL_WARNS("Mesh") << "MESH:  Issuing Decomp Request" << LL_ENDL;
  12.102 -				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
  12.103 +				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
  12.104  				if (LLCORE_HTTP_HANDLE_INVALID == handle)
  12.105  				{
  12.106  					// *TODO:  Better error message
  12.107 @@ -1088,12 +1103,13 @@
  12.108  			}
  12.109  
  12.110  			//reading from VFS failed for whatever reason, fetch from sim
  12.111 -			std::string http_url = constructUrl(mesh_id);
  12.112 +			int cap_version(1);
  12.113 +			std::string http_url = constructUrl(mesh_id, &cap_version);
  12.114  			if (!http_url.empty())
  12.115  			{
  12.116  				LLMeshPhysicsShapeHandler * handler = new LLMeshPhysicsShapeHandler(mesh_id, offset, size);
  12.117  				// LL_WARNS("Mesh") << "MESH:  Issuing Physics Shape Request" << LL_ENDL;
  12.118 -				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
  12.119 +				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
  12.120  				if (LLCORE_HTTP_HANDLE_INVALID == handle)
  12.121  				{
  12.122  					// *TODO:  Better error message
  12.123 @@ -1177,7 +1193,8 @@
  12.124  
  12.125  	//either cache entry doesn't exist or is corrupt, request header from simulator	
  12.126  	bool retval = true ;
  12.127 -	std::string http_url = constructUrl(mesh_params.getSculptID());
  12.128 +	int cap_version(1);
  12.129 +	std::string http_url = constructUrl(mesh_params.getSculptID(), &cap_version);
  12.130  	if (!http_url.empty())
  12.131  	{
  12.132  		//grab first 4KB if we're going to bother with a fetch.  Cache will prevent future fetches if a full mesh fits
  12.133 @@ -1186,7 +1203,7 @@
  12.134  
  12.135  		LLMeshHeaderHandler * handler = new LLMeshHeaderHandler(mesh_params);
  12.136  		// LL_WARNS("Mesh") << "MESH:  Issuing Request" << LL_ENDL;
  12.137 -		LLCore::HttpHandle handle = getByteRange(http_url, 0, MESH_HEADER_SIZE, handler);
  12.138 +		LLCore::HttpHandle handle = getByteRange(http_url, cap_version, 0, MESH_HEADER_SIZE, handler);
  12.139  		if (LLCORE_HTTP_HANDLE_INVALID == handle)
  12.140  		{
  12.141  			// *TODO:  Better error message
  12.142 @@ -1261,12 +1278,13 @@
  12.143  			}
  12.144  
  12.145  			//reading from VFS failed for whatever reason, fetch from sim
  12.146 -			std::string http_url = constructUrl(mesh_id);
  12.147 +			int cap_version(1);
  12.148 +			std::string http_url = constructUrl(mesh_id, &cap_version);
  12.149  			if (!http_url.empty())
  12.150  			{
  12.151  				LLMeshLODHandler * handler = new LLMeshLODHandler(mesh_params, lod, offset, size);
  12.152  				// LL_WARNS("Mesh") << "MESH:  Issuing LOD Request" << LL_ENDL;
  12.153 -				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
  12.154 +				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
  12.155  				if (LLCORE_HTTP_HANDLE_INVALID == handle)
  12.156  				{
  12.157  					// *TODO:  Better error message
  12.158 @@ -2653,6 +2671,7 @@
  12.159  		{
  12.160  			region_name = gAgent.getRegion()->getName();
  12.161  			mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh");
  12.162 +			mGetMesh2Capability = gAgent.getRegion()->getCapability("GetMesh2");
  12.163  		}
  12.164  	}
  12.165  
    13.1 --- a/indra/newview/llmeshrepository.h	Wed Jun 19 19:58:09 2013 +0000
    13.2 +++ b/indra/newview/llmeshrepository.h	Thu Jun 20 19:18:39 2013 -0400
    13.3 @@ -328,13 +328,14 @@
    13.4  	LLCore::HttpOptions *				mHttpLargeOptions;
    13.5  	LLCore::HttpHeaders *				mHttpHeaders;
    13.6  	LLCore::HttpRequest::policy_t		mHttpPolicyClass;
    13.7 +	LLCore::HttpRequest::policy_t		mHttpLegacyPolicyClass;
    13.8  	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass;
    13.9  	LLCore::HttpRequest::priority_t		mHttpPriority;
   13.10  
   13.11  	typedef std::set<LLCore::HttpHandler *> http_request_set;
   13.12  	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests
   13.13  
   13.14 -	static std::string constructUrl(LLUUID mesh_id);
   13.15 +	static std::string constructUrl(LLUUID mesh_id, int * cap_version);
   13.16  
   13.17  	LLMeshRepoThread();
   13.18  	~LLMeshRepoThread();
   13.19 @@ -384,7 +385,8 @@
   13.20  	// or dispose of handler.
   13.21  	//
   13.22  	// Threads:  Repo thread only
   13.23 -	LLCore::HttpHandle getByteRange(const std::string & url, size_t offset, size_t len, 
   13.24 +	LLCore::HttpHandle getByteRange(const std::string & url, int cap_version,
   13.25 +									size_t offset, size_t len, 
   13.26  									LLCore::HttpHandler * handler);
   13.27  
   13.28  private:
   13.29 @@ -595,7 +597,7 @@
   13.30  	void updateInventory(inventory_data data);
   13.31  
   13.32  	std::string mGetMeshCapability;
   13.33 -
   13.34 +	std::string mGetMesh2Capability;
   13.35  };
   13.36  
   13.37  extern LLMeshRepository gMeshRepo;

mercurial