toolkit/components/url-classifier/content/request-backoff.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 // This implements logic for stopping requests if the server starts to return
     6 // too many errors.  If we get MAX_ERRORS errors in ERROR_PERIOD minutes, we
     7 // back off for TIMEOUT_INCREMENT minutes.  If we get another error
     8 // immediately after we restart, we double the timeout and add
     9 // TIMEOUT_INCREMENT minutes, etc.
    10 // 
    11 // This is similar to the logic used by the search suggestion service.
    13 // HTTP responses that count as an error.  We also include any 5xx response
    14 // as an error.
    15 const HTTP_FOUND                 = 302;
    16 const HTTP_SEE_OTHER             = 303;
    17 const HTTP_TEMPORARY_REDIRECT    = 307;
    19 /**
    20  * @param maxErrors Number of times to request before backing off.
    21  * @param retryIncrement Time (ms) for each retry before backing off.
    22  * @param maxRequests Number the number of requests needed to trigger backoff
    23  * @param requestPeriod Number time (ms) in which maxRequests have to occur to
    24  *     trigger the backoff behavior
    25  * @param timeoutIncrement Number time (ms) the starting timeout period
    26  *     we double this time for consecutive errors
    27  * @param maxTimeout Number time (ms) maximum timeout period
    28  */
    29 function RequestBackoff(maxErrors, retryIncrement,
    30                         maxRequests, requestPeriod,
    31                         timeoutIncrement, maxTimeout) {
    32   this.MAX_ERRORS_ = maxErrors;
    33   this.RETRY_INCREMENT_ = retryIncrement;
    34   this.MAX_REQUESTS_ = maxRequests;
    35   this.REQUEST_PERIOD_ = requestPeriod;
    36   this.TIMEOUT_INCREMENT_ = timeoutIncrement;
    37   this.MAX_TIMEOUT_ = maxTimeout;
    39   // Queue of ints keeping the time of all requests
    40   this.requestTimes_ = [];
    42   this.numErrors_ = 0;
    43   this.errorTimeout_ = 0;
    44   this.nextRequestTime_ = 0;
    45 }
    47 /**
    48  * Reset the object for reuse.
    49  */
    50 RequestBackoff.prototype.reset = function() {
    51   this.numErrors_ = 0;
    52   this.errorTimeout_ = 0;
    53   this.nextRequestTime_ = 0;
    54 }
    56 /**
    57  * Check to see if we can make a request.
    58  */
    59 RequestBackoff.prototype.canMakeRequest = function() {
    60   var now = Date.now();
    61   if (now < this.nextRequestTime_) {
    62     return false;
    63   }
    65   return (this.requestTimes_.length < this.MAX_REQUESTS_ ||
    66           (now - this.requestTimes_[0]) > this.REQUEST_PERIOD_);
    67 }
    69 RequestBackoff.prototype.noteRequest = function() {
    70   var now = Date.now();
    71   this.requestTimes_.push(now);
    73   // We only care about keeping track of MAX_REQUESTS
    74   if (this.requestTimes_.length > this.MAX_REQUESTS_)
    75     this.requestTimes_.shift();
    76 }
    78 RequestBackoff.prototype.nextRequestDelay = function() {
    79   return Math.max(0, this.nextRequestTime_ - Date.now());
    80 }
    82 /**
    83  * Notify this object of the last server response.  If it's an error,
    84  */
    85 RequestBackoff.prototype.noteServerResponse = function(status) {
    86   if (this.isErrorStatus(status)) {
    87     this.numErrors_++;
    89     if (this.numErrors_ < this.MAX_ERRORS_)
    90       this.errorTimeout_ = this.RETRY_INCREMENT_;
    91     else if (this.numErrors_ == this.MAX_ERRORS_)
    92       this.errorTimeout_ = this.TIMEOUT_INCREMENT_;
    93     else
    94       this.errorTimeout_ *= 2;
    96     this.errorTimeout_ = Math.min(this.errorTimeout_, this.MAX_TIMEOUT_);
    97     this.nextRequestTime_ = Date.now() + this.errorTimeout_;
    98   } else {
    99     // Reset error timeout, allow requests to go through.
   100     this.reset();
   101   }
   102 }
   104 /**
   105  * We consider 302, 303, 307, 4xx, and 5xx http responses to be errors.
   106  * @param status Number http status
   107  * @return Boolean true if we consider this http status an error
   108  */
   109 RequestBackoff.prototype.isErrorStatus = function(status) {
   110   return ((400 <= status && status <= 599) ||
   111           HTTP_FOUND == status ||
   112           HTTP_SEE_OTHER == status ||
   113           HTTP_TEMPORARY_REDIRECT == status);
   114 }

mercurial