예제 #1
0
def send_entity(environ, start_response, entity):
    """
    Send a :py:class:`bag <tiddlyweb.model.bag.Bag>` or :py:class:`recipe
    <tiddlyweb.model.recipe.Recipe>` out over HTTP, first
    :py:class:`serializing <tiddlyweb.serializer.Serializer>` to
    the correct type. If an incoming ``Etag`` validates, raise a
    ``304`` response.
    """
    etag_string = entity_etag(environ, entity)
    check_incoming_etag(environ, etag_string)

    try:
        serialize_type, mime_type = get_serialize_type(environ)
        serializer = Serializer(serialize_type, environ)
        serializer.object = entity
        content = serializer.to_string()
    except NoSerializationError:
        raise HTTP415('Content type %s not supported' % mime_type)

    start_response("200 OK",
            [('Content-Type', mime_type),
                ('Cache-Control', 'no-cache'),
                ('ETag', etag_string),
                ('Vary', 'Accept')])

    if isinstance(content, basestring):
        return [content]
    else:
        return content
예제 #2
0
파일: sendentity.py 프로젝트: FND/tiddlyweb
def send_entity(environ, start_response, entity):
    """
    Send a bag or recipe out HTTP, first serializing to
    the correct type. If the incoming etag matches, raise
    304.
    """
    etag_string = entity_etag(environ, entity)
    check_incoming_etag(environ, etag_string)

    try:
        serialize_type, mime_type = get_serialize_type(environ)
        serializer = Serializer(serialize_type, environ)
        serializer.object = entity
        content = serializer.to_string()
    except NoSerializationError:
        raise HTTP415('Content type %s not supported' % mime_type)

    start_response("200 OK",
            [('Content-Type', mime_type),
                ('Cache-Control', 'no-cache'),
                ('ETag', etag_string),
                ('Vary', 'Accept')])

    if isinstance(content, basestring):
        return [content]
    else:
        return content
예제 #3
0
파일: tiddler.py 프로젝트: tup/tiddlyweb
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']
    tiddlers_etag = tiddler_etag(environ, tiddler)

    LOGGER.debug('attempting to validate %s with revision %s',
            tiddler.title.encode('utf-8'), tiddler.revision)

    etag = None
    last_modified = None
    if request_method == 'GET':
        incoming_etag = check_incoming_etag(environ, tiddlers_etag)
        if not incoming_etag:  # only check last-modified if no etag
            last_modified_string = http_date_from_timestamp(
                    tiddler.modified)
            last_modified = ('Last-Modified', last_modified_string)
            check_last_modified(environ, last_modified_string)

    else:
        incoming_etag = environ.get('HTTP_IF_MATCH', None)
        LOGGER.debug('attempting to validate incoming etag(PUT):'
            '%s against %s', incoming_etag, tiddlers_etag)
        if incoming_etag and not _etag_write_match(incoming_etag,
                tiddlers_etag):
            raise HTTP412('Provided ETag does not match. '
                'Server content probably newer.')
    etag = ('Etag', '%s' % tiddlers_etag)
    return last_modified, etag
예제 #4
0
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_string = http_date_from_timestamp(tiddlers.modified)
    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"' % (tiddlers.hexdigest(),
                               sha('%s:%s' %
                                   (username, mime_type)).hexdigest())
    etag = ('Etag', etag_string)

    incoming_etag = check_incoming_etag(environ,
                                        etag_string,
                                        last_modified=last_modified_string)
    if not incoming_etag:  # only check last modified when no etag
        check_last_modified(environ, last_modified_string, etag=etag_string)

    return last_modified, etag
예제 #5
0
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_string = http_date_from_timestamp(tiddlers.modified)
    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"' % (tiddlers.hexdigest(),
            sha('%s:%s' % (username.encode('utf-8'), mime_type)).hexdigest())
    etag = ('Etag', etag_string)

    incoming_etag = check_incoming_etag(environ, etag_string)
    if not incoming_etag:  # only check last modified when no etag
        check_last_modified(environ, last_modified_string)

    return last_modified, etag
예제 #6
0
def list_entities(environ,
                  start_response,
                  method_name,
                  store_list=None,
                  serializer_list=None):
    """
    Get an optionally :py:mod:`filtered <tiddlyweb.filters>` list
    of all the :py:class:`bags <tiddlyweb.model.bag.Bag>` or
    :py:class:`recipes <tiddlyweb.model.recipe.Recipe>`
    the current ``tiddlyweb.usersign`` can read.
    """
    store = environ['tiddlyweb.store']
    serialize_type, mime_type = get_serialize_type(environ, collection=True)
    serializer = Serializer(serialize_type, environ)
    filters = environ['tiddlyweb.filters']
    if method_name:
        if not store_list:
            store_list = getattr(store, method_name)
        if not serializer_list:
            serializer_list = getattr(serializer, method_name)

    try:
        kept_entities = _filter_readable(environ, store_list(), filters)
    except FilterError as exc:
        raise HTTP400(exc)

    etag_string = '"%s:%s"' % (kept_entities.hexdigest(),
                               sha(mime_type).hexdigest())
    check_incoming_etag(environ, etag_string)

    try:
        output = serializer_list(kept_entities)
    except NoSerializationError:
        raise HTTP415('Content type not supported: %s' % mime_type)

    start_response("200 OK", [('Content-Type', mime_type), ('Vary', 'Accept'),
                              ('Cache-Control', 'no-cache'),
                              ('Etag', etag_string)])

    if isinstance(output, basestring):
        return [output]
    else:
        return output
예제 #7
0
def list_entities(environ, start_response, method_name,
        store_list=None, serializer_list=None):
    """
    Get an optionally :py:mod:`filtered <tiddlyweb.filters>` list
    of all the :py:class:`bags <tiddlyweb.model.bag.Bag>` or
    :py:class:`recipes <tiddlyweb.model.recipe.Recipe>`
    the current ``tiddlyweb.usersign`` can read.
    """
    store = environ['tiddlyweb.store']
    serialize_type, mime_type = get_serialize_type(environ, collection=True)
    serializer = Serializer(serialize_type, environ)
    filters = environ['tiddlyweb.filters']
    if method_name:
        if not store_list:
            store_list = getattr(store, method_name)
        if not serializer_list:
            serializer_list = getattr(serializer, method_name)

    try:
        kept_entities = _filter_readable(environ, store_list(), filters)
    except FilterError as exc:
        raise HTTP400(exc)

    etag_string = '"%s:%s"' % (kept_entities.hexdigest(),
            sha(mime_type).hexdigest())
    check_incoming_etag(environ, etag_string)

    try:
        output = serializer_list(kept_entities)
    except NoSerializationError:
        raise HTTP415('Content type not supported: %s' % mime_type)

    start_response("200 OK", [('Content-Type', mime_type),
                ('Vary', 'Accept'),
                ('Cache-Control', 'no-cache'),
                ('Etag', etag_string)])

    if isinstance(output, basestring):
        return [output]
    else:
        return output
예제 #8
0
파일: tiddler.py 프로젝트: sgml/tiddlyweb
def validate_tiddler_headers(environ, tiddler):
    """
    Check ETag and last modified header information to
    see if a) on ``GET`` the user agent can use its cached tiddler
    b) on ``PUT`` we have edit contention.
    """
    request_method = environ['REQUEST_METHOD']
    this_tiddlers_etag = tiddler_etag(environ, tiddler)

    LOGGER.debug('attempting to validate %s with revision %s', tiddler.title,
                 tiddler.revision)

    etag = None
    last_modified = None
    if request_method == 'GET':
        last_modified_string = http_date_from_timestamp(tiddler.modified)
        last_modified = ('Last-Modified', last_modified_string)
        cache_header = 'no-cache'
        if CACHE_CONTROL_FIELD in tiddler.fields:
            try:
                cache_header = 'max-age=%s' % int(
                    tiddler.fields[CACHE_CONTROL_FIELD])
            except ValueError:
                pass  # if the value is not an int use default header
        incoming_etag = check_incoming_etag(environ,
                                            this_tiddlers_etag,
                                            last_modified=last_modified_string,
                                            cache_control=cache_header)
        if not incoming_etag:  # only check last-modified if no etag
            check_last_modified(environ,
                                last_modified_string,
                                etag=this_tiddlers_etag,
                                cache_control=cache_header)

    else:
        incoming_etag = environ.get('HTTP_IF_MATCH', None)
        LOGGER.debug(
            'attempting to validate incoming etag(PUT):'
            '%s against %s', incoming_etag, this_tiddlers_etag)
        if incoming_etag and not _etag_write_match(incoming_etag,
                                                   this_tiddlers_etag):
            raise HTTP412('Provided ETag does not match. '
                          'Server content probably newer.')
    etag = ('ETag', '%s' % this_tiddlers_etag)
    return last_modified, etag
예제 #9
0
파일: tiddler.py 프로젝트: 24king/tiddlyweb
def validate_tiddler_headers(environ, tiddler):
    """
    Check ETag and last modified header information to
    see if a) on ``GET`` the user agent can use its cached tiddler
    b) on ``PUT`` we have edit contention.
    """
    request_method = environ['REQUEST_METHOD']
    this_tiddlers_etag = tiddler_etag(environ, tiddler)

    LOGGER.debug('attempting to validate %s with revision %s',
            tiddler.title, tiddler.revision)

    etag = None
    last_modified = None
    if request_method == 'GET':
        last_modified_string = http_date_from_timestamp(tiddler.modified)
        last_modified = ('Last-Modified', last_modified_string)
        cache_header = 'no-cache'
        if CACHE_CONTROL_FIELD in tiddler.fields:
            try:
                cache_header = 'max-age=%s' % int(
                        tiddler.fields[CACHE_CONTROL_FIELD])
            except ValueError:
                pass  # if the value is not an int use default header
        incoming_etag = check_incoming_etag(environ, this_tiddlers_etag,
                last_modified=last_modified_string,
                cache_control=cache_header)
        if not incoming_etag:  # only check last-modified if no etag
            check_last_modified(environ, last_modified_string,
                    etag=this_tiddlers_etag,
                    cache_control=cache_header)

    else:
        incoming_etag = environ.get('HTTP_IF_MATCH', None)
        LOGGER.debug('attempting to validate incoming etag(PUT):'
            '%s against %s', incoming_etag, this_tiddlers_etag)
        if incoming_etag and not _etag_write_match(incoming_etag,
                this_tiddlers_etag):
            raise HTTP412('Provided ETag does not match. '
                'Server content probably newer.')
    etag = ('ETag', '%s' % this_tiddlers_etag)
    return last_modified, etag
예제 #10
0
    serializer = Serializer(serialize_type, environ)
    filters = environ['tiddlyweb.filters']
    if method_name:
        if not store_list:
            store_list = getattr(store, method_name)
        if not serializer_list:
            serializer_list = getattr(serializer, method_name)

    try:
        kept_entities = _filter_readable(environ, store_list(), filters)
    except FilterError, exc:
        raise HTTP400(exc)

    etag_string = '"%s:%s"' % (kept_entities.hexdigest(),
            sha(mime_type).hexdigest())
    check_incoming_etag(environ, etag_string)

    try:
        output = serializer_list(kept_entities)
    except NoSerializationError:
        raise HTTP415('Content type not supported: %s' % mime_type)

    start_response("200 OK", [('Content-Type', mime_type),
                ('Vary', 'Accept'),
                ('Cache-Control', 'no-cache'),
                ('Etag', etag_string)])

    if isinstance(output, basestring):
        return [output]
    else:
        return output