def _cache_period_from_headers(headers, time_now=time.time): cache_controls = _parse_cache_control(headers) if b'no-store' in cache_controls: return 0 if b'max-age' in cache_controls: try: max_age = int(cache_controls[b'max-age']) return max_age except ValueError: pass expires = headers.getRawHeaders(b'expires') if expires is not None: try: expires_date = stringToDatetime(expires[-1]) return expires_date - time_now() except ValueError: # RFC7234 says 'A cache recipient MUST interpret invalid date formats, # especially the value "0", as representing a time in the past (i.e., # "already expired"). return 0 return None
def _cache_period_from_headers( headers: Headers, time_now: Callable[[], float] = time.time) -> Optional[float]: cache_controls = _parse_cache_control(headers) if b"no-store" in cache_controls: return 0 if b"max-age" in cache_controls: max_age = cache_controls[b"max-age"] if max_age: try: return int(max_age) except ValueError: pass expires = headers.getRawHeaders(b"expires") if expires is not None: try: expires_date = stringToDatetime(expires[-1]) return expires_date - time_now() except ValueError: # RFC7234 says 'A cache recipient MUST interpret invalid date formats, # especially the value "0", as representing a time in the past (i.e., # "already expired"). return 0 return None
def validateDateString(dateString): try: _ = stringToDatetime(dateString) except ValueError: raise ValueError( 'Invalid date string: {!r}'.format(dateString)) return True
def checkDate(self, date): if not date and self.max_request_time_delta is not None: raise error.LoginFailed("Missing mandatory 'date' header") t2 = stringToDatetime(date) t1 = time.time() if self.max_request_time_delta is not None and abs(t1 - t2) > self.max_request_time_delta: raise error.LoginFailed("Request 'date' too old")
def get_server_time(self): """Get the time at the server.""" date_string = yield self.get_server_date_header(self.SERVER_IRI) # delay import, otherwise a default reactor gets installed from twisted.web import http timestamp = http.stringToDatetime(date_string) defer.returnValue(timestamp)
def setLastModified(self, when): """Set the X{Last-Modified} time for the response to this request. If I am called more than once, I ignore attempts to set Last-Modified earlier, only replacing the Last-Modified time if it is to a later value. If I am a conditional request, I may modify my response code to L{NOT_MODIFIED} if appropriate for the time given. @param when: The last time the resource being returned was modified, in seconds since the epoch. @type when: number @return: If I am a X{If-Modified-Since} conditional request and the time given is not newer than the condition, I return L{http.CACHED<CACHED>} to indicate that you should write no body. Otherwise, I return a false value. """ # time.time() may be a float, but the HTTP-date strings are # only good for whole seconds. when = long(math.ceil(when)) if (not self.lastModified) or (self.lastModified < when): self.lastModified = when modified_since = self.getHeader('if-modified-since') if modified_since: modified_since = stringToDatetime(modified_since) if modified_since >= when: self.setResponseCode(NOT_MODIFIED) return '' # TODO: return http.CACHED (requires Twisted) return None
def __init__(self, headers): self.expires = None self.mtime = None self.length = 0 self.start = 0 self.size = 0 self.mimeType = None headers = InsensitiveDict(headers) encoding = headers.get("Transfer-Encoding", None) if encoding == 'chunked': raise errors.FlumotionError("Chunked transfer not supported") expires = headers.get("Expires", None) if expires is not None: try: self.expires = http.stringToDatetime(expires) except: self.expires = 0 lastmod = headers.get("Last-Modified", None) if lastmod is not None: self.mtime = http.stringToDatetime(lastmod) range = headers.get("Content-Range", None) length = headers.get("Content-Length", None) if range is not None: start, end, total = http.parseContentRange(range) self.start = start self.length = total if length is not None: self.size = int(length) else: self.size = end - start elif length is not None: self.length = int(length) self.size = int(length) else: raise errors.FlumotionError("Can't get length/size from headers", headers) ctype = headers.get("Content-Type", None) if ctype is not None: self.mimeType, _pdict = cgi.parse_header(ctype)
def retry_after(cls, response, default=5, _now=time.time): """ Parse the Retry-After value from a response. """ val = response.headers.getRawHeaders(b'retry-after', [default])[0] try: return int(val) except ValueError: return http.stringToDatetime(val) - _now()
def get_server_time(self): """Get the time at the server.""" headers = {"Cache-Control": "no-cache"} request = RequestHead(self.SERVER_URL, headers=headers) response = urllib2.urlopen(request) date_string = response.info()["Date"] # delay import, otherwise a default reactor gets installed from twisted.web import http timestamp = http.stringToDatetime(date_string) return timestamp
def get_http_date(url): try: rep = requests.get(url) except: pass else: # get server date server_date = rep.headers.get('date') if server_date: # 1477189234 = time.mktime((2016,10,23,10,20,34,0,0,0)) t = stringToDatetime(server_date) return t
def authenticate_request(request, authorizations=()): """ Called for a request that requires authentication via API key signature. Calls will result in request having additional attributes: - authenticated: bool - apikey: None or Player :param request: The request to authenticate. :type request: Request :return: Whether or not the request has passed authentication. :rtype: bool """ request.authenticated = False request.apikey = None signature = request.getHeader('Signature') if signature is not None: (key_id, nonce, signed) = signature.split(':') try: #: :type: restserver.APIKey apikey = get_api_key(key_id) except InvalidAPIKey: pass # Fall through to Access Denied else: authorized = True for authorization in authorizations: if not apikey.is_authorized(authorization): authorized = False break if authorized: request.apikey = apikey date_header = request.getHeader('Date') if apikey.valid and date_header: timestamp = stringToDatetime(date_header) offset = abs(unixtime() - timestamp) if offset <= 600: tosign = '\n'.join(( request.method, request.uri, date_header, nonce )) hashed = hmac.new(apikey.secret, tosign, sha1) verify = hashed.digest().encode('base64').rstrip('\n') if verify == signed: request.authenticated = True return True return False
def _isConditionalRequest(self, req): # support for time based conditional requests if not self._conditionalRequestsEnabled: return False if req.method not in (b'GET', b'HEAD'): return False if req.getHeader("If-None-Match") is not None: return False modifiedSince = req.getHeader("If-Modified-Since") if not modifiedSince: return False modifiedSince = http.stringToDatetime(modifiedSince) return modifiedSince and self._timeInventoryLoaded <= modifiedSince
def _check_media_fresh(self, response): if response.status == 304: return True elif response.status == 200: # The media stores don't set the mtime of the stored files to the # value of the Last-Modified headers, and some web servers (e.g # nginx) only return 304s if the time matches exactly. Check the # time manually when we see a 200 to work around that. try: request_time = response.meta['media_last_modified'] response_time = http.stringToDatetime( response.headers['Last-Modified']) except KeyError: return False return request_time >= response_time
def authenticate_request(request, authorizations=()): """ Called for a request that requires authentication via API key signature. Calls will result in request having additional attributes: - authenticated: bool - apikey: None or Player :param request: The request to authenticate. :type request: Request :return: Whether or not the request has passed authentication. :rtype: bool """ request.authenticated = False request.apikey = None signature = request.getHeader('Signature') if signature is not None: (key_id, nonce, signed) = signature.split(':') try: #: :type: restserver.APIKey apikey = get_api_key(key_id) except InvalidAPIKey: pass # Fall through to Access Denied else: authorized = True for authorization in authorizations: if not apikey.is_authorized(authorization): authorized = False break if authorized: request.apikey = apikey date_header = request.getHeader('Date') if apikey.valid and date_header: timestamp = stringToDatetime(date_header) offset = abs(unixtime() - timestamp) if offset <= 600: tosign = '\n'.join( (request.method, request.uri, date_header, nonce)) hashed = hmac.new(apikey.secret, tosign, sha1) verify = hashed.digest().encode('base64').rstrip('\n') if verify == signed: request.authenticated = True return True return False
def _translate_response(self, django_response, response): for header_name, header_value in django_response.items(): response.set_header(header_name, header_value) for cookie_name, cookie in django_response.cookies.iteritems(): # convert an http formated datetime to a datetime.datetime object expires = None if cookie['expires']: expires = datetime.datetime(*time.localtime( stringToDatetime(cookie['expires']))[:6]) max_age = cookie['max-age'] and int(cookie['max-age']) response.add_cookie(cookie_name, cookie.value, expires=expires, max_age=max_age, domain=cookie['domain'], path=cookie['path'], secure=cookie['secure']) response.set_mime_type(django_response['Content-Type']) response.set_status(http.Status[django_response.status_code]) response.write(django_response.content)
def _translate_response(self, django_response, response): for header_name, header_value in django_response.items(): response.set_header(header_name, header_value) for cookie_name, cookie in django_response.cookies.iteritems(): # convert an http formated datetime to a datetime.datetime object expires = None if cookie['expires']: expires = datetime.datetime( *time.localtime(stringToDatetime(cookie['expires']))[:6]) max_age = cookie['max-age'] and int(cookie['max-age']) response.add_cookie(cookie_name, cookie.value, expires=expires, max_age=max_age, domain=cookie['domain'], path=cookie['path'], secure=cookie['secure']) response.set_mime_type(django_response['Content-Type']) response.set_status(http.Status[django_response.status_code]) response.write(django_response.content)
def get_server_time(self): """Get the time at the server.""" date_string = yield self.get_server_date_header(self.SERVER_URL) timestamp = http.stringToDatetime(date_string) defer.returnValue(timestamp)
def _handleResponseDate(self, uri, r): d = r.headers.getRawHeaders('date', [None])[0] if d: server = urlparse.urlparse(uri).netloc self._client_server_time_diffs[server] = stringToDatetime(d) - time.time()
def testRoundtrip(self): for i in range(10000): time = random.randint(0, 2000000000) timestr = http.datetimeToString(time) time2 = http.stringToDatetime(timestr) self.assertEquals(time, time2)
def _handleResponseDate(self, uri, r): d = r.headers.getRawHeaders('date', [None])[0] if d: server = urlparse.urlparse(uri).netloc self._client_server_time_diffs[server] = stringToDatetime( d) - time.time()