def _validate_tiddler(environ, tiddler): """ Check ETAG and last modified information to see if a) the client can use its cached tiddler b) we have edit contention when trying to write. """ request_method = environ['REQUEST_METHOD'] tiddler_etag = _tiddler_etag(tiddler) logging.debug('attempting to validate %s with revision %s' % (tiddler.title, tiddler.revision)) etag = None last_modified = None if request_method == 'GET': incoming_etag = environ.get('HTTP_IF_NONE_MATCH', None) if incoming_etag == tiddler_etag: raise HTTP304(incoming_etag) last_modified_string = web.http_date_from_timestamp(tiddler.modified) last_modified = ('Last-Modified', last_modified_string) incoming_modified = environ.get('HTTP_IF_MODIFIED_SINCE', None) if incoming_modified and \ (web.datetime_from_http_date(incoming_modified) >= web.datetime_from_http_date(last_modified_string)): raise HTTP304('') else: incoming_etag = environ.get('HTTP_IF_MATCH', None) logging.debug('attempting to validate incoming etag: %s against %s' % (incoming_etag, tiddler_etag)) if incoming_etag and incoming_etag != tiddler_etag: raise HTTP412('Provided ETag does not match. Server content probably newer.') etag = ('Etag', tiddler_etag) return last_modified, etag
def _validate_tiddler_list(environ, bag): """ Calculate the Last modified and ETag for the tiddlers in bag. If the ETag matches an incoming If-None-Match, then raise a 304 and don't send the tiddler content. If the modified string in an If-Modified-Since is newer than the last-modified on the tiddlers, raise 304. If ETag testing is done, no last modified handling is done, even if the ETag testing fails. If no 304 is raised, then just return last-modified and ETag for the caller to use in constructing its HTTP response. """ last_modified_number = _last_modified_tiddler(bag) last_modified = None if last_modified_number: last_modified_string = http_date_from_timestamp(last_modified_number) last_modified = ("Last-Modified", last_modified_string) username = environ.get("tiddlyweb.usersign", {}).get("name", "") try: serialize_type, mime_type = get_serialize_type(environ) mime_type = mime_type.split(";", 1)[0].strip() except TypeError: mime_type = "" etag_string = '"%s:%s;%s"' % ( _sha_tiddler_titles(bag), last_modified_number, sha("%s:%s" % (username, mime_type)).hexdigest(), ) etag = ("Etag", etag_string) incoming_etag = environ.get("HTTP_IF_NONE_MATCH", None) if incoming_etag: if incoming_etag == etag_string: raise HTTP304(incoming_etag) else: incoming_modified = environ.get("HTTP_IF_MODIFIED_SINCE", None) if incoming_modified and ( datetime_from_http_date(incoming_modified) >= datetime_from_http_date(last_modified_string) ): raise HTTP304("") return last_modified, etag
def code_expired(registration): """ Return true if this registration is out of date. """ timestamp = registration.created created_time = datetime_from_http_date(http_date_from_timestamp(timestamp)) return created_time < (datetime.utcnow() - timedelta(minutes=1))
def _validate_tiddler_headers(environ, tiddler): """ Check ETAG and last modified information to see if a) the client can use its cached tiddler b) we have edit contention when trying to write. """ request_method = environ['REQUEST_METHOD'] tiddler_etag = web.tiddler_etag(environ, tiddler) logging.debug('attempting to validate %s with revision %s', tiddler.title, tiddler.revision) etag = None last_modified = None if request_method == 'GET': incoming_etag = environ.get('HTTP_IF_NONE_MATCH', None) if incoming_etag: logging.debug( 'attempting to validate incoming etag(GET):' '%s against %s', incoming_etag, tiddler_etag) if incoming_etag == tiddler_etag: raise HTTP304(incoming_etag) else: last_modified_string = web.http_date_from_timestamp( tiddler.modified) last_modified = ('Last-Modified', last_modified_string) incoming_modified = environ.get('HTTP_IF_MODIFIED_SINCE', None) if incoming_modified and \ (web.datetime_from_http_date(incoming_modified) >= web.datetime_from_http_date(last_modified_string)): raise HTTP304('') else: incoming_etag = environ.get('HTTP_IF_MATCH', None) logging.debug( 'attempting to validate incoming etag(PUT):' '%s against %s', incoming_etag, tiddler_etag) if incoming_etag and not _etag_write_match(incoming_etag, tiddler_etag): raise HTTP412('Provided ETag does not match. ' 'Server content probably newer.') etag = ('Etag', '%s' % tiddler_etag) return last_modified, etag
def _validate_tiddler_list(environ, tiddlers): last_modified_number = _last_modified_tiddler(tiddlers) last_modified_string = http_date_from_timestamp(last_modified_number) last_modified = ('Last-Modified', last_modified_string) etag_string = '%s:%s' % (_sha_tiddler_titles(tiddlers), last_modified_number) etag = ('Etag', etag_string) incoming_etag = environ.get('HTTP_IF_NONE_MATCH', None) if incoming_etag: if incoming_etag == etag_string: raise HTTP304(incoming_etag) else: incoming_modified = environ.get('HTTP_IF_MODIFIED_SINCE', None) if incoming_modified and \ (datetime_from_http_date(incoming_modified) >= \ datetime_from_http_date(last_modified_string)): raise HTTP304('') return last_modified, etag
def _validate_tiddler_list(environ, tiddlers): """ Do Etag and Last modified checks on the collection of tiddlers. If ETag testing is done, no last modified handling is done, even if the ETag testing fails. If no 304 is raised, then just return last-modified and ETag for the caller to use in constructing its HTTP response. """ last_modified_number = tiddlers.modified last_modified_string = http_date_from_timestamp(last_modified_number) last_modified = ('Last-Modified', last_modified_string) username = environ.get('tiddlyweb.usersign', {}).get('name', '') try: _, mime_type = get_serialize_type(environ) mime_type = mime_type.split(';', 1)[0].strip() except TypeError: mime_type = '' etag_string = '"%s:%s;%s"' % (tiddlers.hexdigest(), str(last_modified_number), sha('%s:%s' % (username, mime_type)).hexdigest()) etag = ('Etag', etag_string) incoming_etag = environ.get('HTTP_IF_NONE_MATCH', None) if incoming_etag: if incoming_etag == etag_string: raise HTTP304(incoming_etag) else: incoming_modified = environ.get('HTTP_IF_MODIFIED_SINCE', None) if incoming_modified and \ (datetime_from_http_date(incoming_modified) >= \ datetime_from_http_date(last_modified_string)): raise HTTP304('') return last_modified, etag
def test_bad_http_timestamp(): assert datetime_from_http_date('0') is None
def test_bad_http_timestamp(): assert datetime_from_http_date('0') == None