예제 #1
0
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
예제 #2
0
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
예제 #3
0
 def validateDateString(dateString):
     try:
         _ = stringToDatetime(dateString)
     except ValueError:
         raise ValueError(
             'Invalid date string: {!r}'.format(dateString))
     return True
예제 #4
0
 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")
예제 #5
0
 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
예제 #7
0
 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)
예제 #8
0
파일: authhmac.py 프로젝트: wgnet/twoost
 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 _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
예제 #10
0
    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
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
 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()
예제 #14
0
파일: client.py 프로젝트: habnabit/txacme
 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()
예제 #15
0
 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
예제 #16
0
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
예제 #17
0
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
예제 #18
0
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
예제 #19
0
    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
예제 #20
0
    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
예제 #21
0
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
예제 #22
0
 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)
예제 #23
0
 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)
예제 #24
0
 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)
예제 #25
0
파일: authhmac.py 프로젝트: wgnet/twoost
 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()
예제 #26
0
 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)
예제 #27
0
 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()