Exemplo n.º 1
0
class MediaMixin:
    cache_control = CacheControl(maxage=86400)

    def serve_file(self, request, fullpath, status_code=None):
        return file_response(request, fullpath, status_code=status_code,
                             cache_control=self.cache_control)

    def directory_index(self, request, fullpath):
        names = [Html('a', '../', href='../', cn='folder')]
        files = []
        for f in sorted(os.listdir(fullpath)):
            if not f.startswith('.'):
                if os.path.isdir(os.path.join(fullpath, f)):
                    names.append(Html('a', f, href=f+'/', cn='folder'))
                else:
                    files.append(Html('a', f, href=f))
        names.extend(files)
        return self.static_index(request, names)

    def static_index(self, request, links):
        doc = request.html_document
        doc.title = 'Index of %s' % request.path
        title = Html('h2', doc.title)
        list = Html('ul', *[Html('li', a) for a in links])
        doc.body.append(Html('div', title, list))
        return doc.http_response(request)
Exemplo n.º 2
0
class FileRouter(Router, MediaMixin):
    '''A Router for a single file
    '''
    response_content_types = RouterParam(
        ('application/octet-stream', 'text/css', 'application/javascript',
         'text/html'))
    cache_control = CacheControl(maxage=86400)

    def __init__(self, route, file_path, status_code=None, raise_404=True):
        super().__init__(route)
        self._status_code = status_code
        self._file_path = file_path
        self._raise_404 = raise_404

    def filesystem_path(self, request):
        return self._file_path

    def get(self, request):
        fullpath = self.filesystem_path(request)
        if os.path.isfile(fullpath):
            return self.serve_file(request,
                                   fullpath,
                                   status_code=self._status_code)
        elif self._raise_404:
            raise Http404
Exemplo n.º 3
0
 def test_CacheControl(self):
     headers = CIMultiDict()
     c = CacheControl()
     self.assertFalse(c.private)
     self.assertFalse(c.maxage)
     c(headers)
     self.assertEqual(', '.join(headers.getall('cache-control')),
                      'no-cache')
     c = CacheControl(maxage=3600)
     c(headers)
     self.assertEqual(', '.join(headers.getall('cache-control')),
                      'max-age=3600, public')
     c = CacheControl(maxage=3600, private=True)
     c(headers)
     self.assertEqual(', '.join(headers.getall('cache-control')),
                      'max-age=3600, private')
     c = CacheControl(maxage=3600, must_revalidate=True)
     c(headers)
     self.assertEqual(', '.join(headers.getall('cache-control')),
                      'max-age=3600, public, must-revalidate')
     c = CacheControl(maxage=3600, proxy_revalidate=True)
     c(headers)
     self.assertEqual(', '.join(headers.getall('cache-control')),
                      'max-age=3600, public, proxy-revalidate')
     c = CacheControl(maxage=3600, proxy_revalidate=True, nostore=True)
     c(headers)
     self.assertEqual(', '.join(headers.getall('cache-control')),
                      'no-store, no-cache, must-revalidate, max-age=0')
Exemplo n.º 4
0
 def test_CacheControl(self):
     headers = Headers()
     c = CacheControl()
     self.assertFalse(c.private)
     self.assertFalse(c.maxage)
     c(headers)
     self.assertEqual(headers['cache-control'], 'no-cache')
     c = CacheControl(maxage=3600)
     c(headers)
     self.assertEqual(headers['cache-control'], 'max-age=3600, public')
     c = CacheControl(maxage=3600, private=True)
     c(headers)
     self.assertEqual(headers['cache-control'], 'max-age=3600, private')
     c = CacheControl(maxage=3600, must_revalidate=True)
     c(headers)
     self.assertEqual(headers['cache-control'],
                      'max-age=3600, public, must-revalidate')
     c = CacheControl(maxage=3600, proxy_revalidate=True)
     c(headers)
     self.assertEqual(headers['cache-control'],
                      'max-age=3600, public, proxy-revalidate')
     c = CacheControl(maxage=3600, proxy_revalidate=True,
                      nostore=True)
     c(headers)
     self.assertEqual(headers['cache-control'],
                      'no-store, no-cache, must-revalidate, max-age=0')
Exemplo n.º 5
0
class JsonRouter(Router):
    model = RouterParam()
    cache_control = CacheControl()
    response_content_types = ['application/json']

    def head(self, request):
        if hasattr(self, 'get'):
            return self.get(request)

    def json_response(self, request, data):
        """Return a response as application/json
        """
        response = Json(data).http_response(request)
        self.cache_control(response)
        return response

    def get_model(self, request, model=None):
        model = request.app.models.get(model or self.model)
        if not model:
            raise Http404
        return model
Exemplo n.º 6
0
class SocketIO(Router):
    info_cache = CacheControl(nostore=True)
    home_cache = CacheControl(maxage=60*60*24*30)

    def __init__(self, route, **kwargs):
        super().__init__(route, **kwargs)
        self.handle = LuxWs()
        self.add_child(WebSocket('/websocket', self.handle, **kwargs))
        self.add_child(WebSocket('<server_id>/<session_id>/websocket',
                                 self.handle, **kwargs))

    def get(self, request):
        response = request.response
        self.home_cache(response.headers)
        response.content_type = 'text/plain'
        response.content = 'Welcome to SockJS!\n'
        return response

    @route(method=('OPTIONS', 'GET'),
           response_content_types=('application/json',))
    def info(self, request):
        response = request.response
        self.info_cache(response.headers)
        self.origin(request)
        return Json({'websocket': request.config['WEBSOCKET_AVAILABLE'],
                     'origins': ['*:*'],
                     'entropy': randint(0, sys.maxsize)}
                    ).http_response(request)

    @route('iframe[0-9-.a-z_]*.html', re=True,
           response_content_types=('text/html',))
    def iframe(self, request):
        response = request.response
        url = request.absolute_uri(self.full_route.path)
        response.content = IFRAME_TEXT % url
        hsh = hashlib.md5(response.content[0]).hexdigest()
        value = request.get('HTTP_IF_NONE_MATCH')

        if value and value.find(hsh) != -1:
            raise HttpException(status=304)

        self.home_cache(response.headers)
        response['Etag'] = hsh
        return response

    def origin(self, request):
        """Handles request authentication"""
        response = request.response
        origin = request.get('HTTP_ORIGIN', '*')

        # Respond with '*' to 'null' origin
        if origin == 'null':
            origin = '*'

        response['Access-Control-Allow-Origin'] = origin

        headers = request.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS')
        if headers:
            response['Access-Control-Allow-Headers'] = headers

        response['Access-Control-Allow-Credentials'] = 'true'
Exemplo n.º 7
0
class MediaRouter(Router, MediaMixin):
    '''A :class:`Router` for serving static media files from a given
    directory.

    :param rute: The top-level url for this router. For example ``/media``
        will serve the ``/media/<path:path>`` :class:`Route`.
    :param path: Check the :attr:`path` attribute.
    :param show_indexes: Check the :attr:`show_indexes` attribute.

    .. attribute::    path

        The file-system path of the media files to serve.

    .. attribute::    show_indexes

        If ``True``, the router will serve media file directories as
        well as media files.

    .. attribute:: default_file

        The default file to serve when a directory is requested.
    '''
    cache_control = CacheControl(maxage=86400)

    def __init__(self,
                 rule,
                 path,
                 show_indexes=False,
                 default_suffix=None,
                 default_file='index.html',
                 raise_404=True,
                 **params):
        super().__init__('%s/<path:path>' % rule, **params)
        self._default_suffix = default_suffix
        self._default_file = default_file
        self._show_indexes = show_indexes
        self._file_path = path
        self._raise_404 = raise_404

    def filesystem_path(self, request):
        path = request.urlargs['path']
        bits = [bit for bit in path.split('/') if bit]
        return os.path.join(self._file_path, *bits)

    def get(self, request):
        fullpath = self.filesystem_path(request)
        if os.path.isdir(fullpath) and self._default_file:
            file = os.path.join(fullpath, self._default_file)
            if os.path.isfile(file):
                if not request.path.endswith('/'):
                    return request.redirect('%s/' % request.path)
                fullpath = file
        #
        if os.path.isdir(fullpath):
            if self._show_indexes:
                return self.directory_index(request, fullpath)
            else:
                raise Http404
        #
        filename = os.path.basename(fullpath)
        if '.' not in filename and self._default_suffix:
            fullpath = '%s.%s' % (fullpath, self._default_suffix)
        #
        if os.path.isfile(fullpath):
            return self.serve_file(request, fullpath)
        elif self._raise_404:
            raise Http404
Exemplo n.º 8
0
from datetime import datetime

from pulsar import Http404
from pulsar.utils.httpurl import CacheControl

CACHE_TIME = 31536000
nocache = CacheControl(nostore=True)
cache = CacheControl(maxage=CACHE_TIME)
APPJSON = 'application/json'
PRELUDE = 'h' * 2048 + '\n'


class Transport(object):
    access_methods = 'OPTIONS, POST'

    __slots__ = ['handshake', 'handle']

    def __init__(self, request, handle=None):
        self.handshake = request
        self.handle = handle

    @property
    def response(self):
        return self.request.response

    @property
    def protocol(self):
        return self.request.connection._current_consumer

    def write(self, msg):
        raise NotImplementedError
Exemplo n.º 9
0
class MediaMixin(Router):
    response_content_types = RouterParam(
        ('application/octet-stream', 'text/css'))
    cache_control = CacheControl(maxage=86400)
    _file_path = ''

    def serve_file(self, request, fullpath):
        # Respect the If-Modified-Since header.
        statobj = os.stat(fullpath)
        content_type, encoding = mimetypes.guess_type(fullpath)
        response = request.response
        if content_type:
            response.content_type = content_type
        response.encoding = encoding
        if not self.was_modified_since(
                request.environ.get('HTTP_IF_MODIFIED_SINCE'),
                statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]):
            response.status_code = 304
        else:
            response.content = open(fullpath, 'rb').read()
            response.headers["Last-Modified"] = http_date(
                statobj[stat.ST_MTIME])
        return response

    def was_modified_since(self, header=None, mtime=0, size=0):
        '''Check if an item was modified since the user last downloaded it

:param header: the value of the ``If-Modified-Since`` header. If this is None,
    simply return ``True``.
:param mtime: the modification time of the item in question.
:param size: the size of the item.
'''
        try:
            if header is None:
                raise ValueError
            matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
                               re.IGNORECASE)
            header_mtime = mktime_tz(parsedate_tz(matches.group(1)))
            header_len = matches.group(3)
            if header_len and int(header_len) != size:
                raise ValueError()
            if mtime > header_mtime:
                raise ValueError()
        except (AttributeError, ValueError, OverflowError):
            return True
        return False

    def directory_index(self, request, fullpath):
        names = [Html('a', '../', href='../', cn='folder')]
        files = []
        for f in sorted(os.listdir(fullpath)):
            if not f.startswith('.'):
                if os.path.isdir(os.path.join(fullpath, f)):
                    names.append(Html('a', f, href=f + '/', cn='folder'))
                else:
                    files.append(Html('a', f, href=f))
        names.extend(files)
        return self.static_index(request, names)

    def html_title(self, request):
        return 'Index of %s' % request.path

    def static_index(self, request, links):
        title = Html('h2', self.html_title(request))
        list = Html('ul', *[Html('li', a) for a in links])
        body = Html('div', title, list)
        doc = request.html_document(title=title, body=body)
        return doc.http_response(request)