Exemple #1
0
 def prepare_stream(self):
     if self.request.method in self.STREAM_METHODS:
         self.stream = RequestStreamReader(self.request)
         self.uploader = asyncio.async(
             self.provider.upload(self.stream, **self.arguments)
         )
     else:
         self.stream = None
Exemple #2
0
 def prepare_stream(self):
     if self.request.method in self.STREAM_METHODS:
         self.stream = RequestStreamReader(self.request)
         self.uploader = asyncio.async(
             self.provider.upload(self.stream, **self.arguments)
         )
     else:
         self.stream = None
Exemple #3
0
    async def prepare_stream(self):
        """Sets up an asyncio pipe from client to server
        Only called on PUT when path is to a file
        """
        self.rsock, self.wsock = socket.socketpair()

        self.reader, _ = await asyncio.open_unix_connection(sock=self.rsock)
        _, self.writer = await asyncio.open_unix_connection(sock=self.wsock)

        self.stream = RequestStreamReader(self.request, self.reader)
        self.uploader = asyncio.ensure_future(self.provider.upload(self.stream, self.target_path))
Exemple #4
0
    async def prepare_stream(self):
        if self.request.method in self.STREAM_METHODS:
            self.rsock, self.wsock = socket.socketpair()

            self.reader, _ = await asyncio.open_unix_connection(sock=self.rsock)
            _, self.writer = await asyncio.open_unix_connection(sock=self.wsock)

            self.stream = RequestStreamReader(self.request, self.reader)

            self.uploader = asyncio.ensure_future(self.provider.upload(self.stream,
                                                 **self.arguments))
        else:
            self.stream = None
Exemple #5
0
class CRUDHandler(core.BaseHandler):

    ACTION_MAP = {
        'GET': 'download',
        'PUT': 'upload',
        'DELETE': 'delete',
    }
    STREAM_METHODS = ('PUT', )

    @utils.coroutine
    def prepare(self):
        yield from super().prepare()
        self.prepare_stream()

    def prepare_stream(self):
        if self.request.method in self.STREAM_METHODS:
            self.stream = RequestStreamReader(self.request)
            self.uploader = asyncio.async(
                self.provider.upload(self.stream, **self.arguments)
            )
        else:
            self.stream = None

    @utils.coroutine
    def data_received(self, chunk):
        """Note: Only called during uploads."""
        if self.stream:
            self.stream.feed_data(chunk)

    @utils.coroutine
    def get(self):
        """Download a file."""
        try:
            self.arguments['accept_url'] = TRUTH_MAP[self.arguments.get('accept_url', 'true').lower()]
        except KeyError:
            raise web.HTTPError(status_code=400)

        result = yield from self.provider.download(**self.arguments)

        if isinstance(result, str):
            return self.redirect(result)

        try:
            headers = result.response.headers
        except AttributeError:
            headers = {}

        self.set_header('Content-Type', result.content_type)
        if result.size:
            self.set_header('Content-Length', str(result.size))

        # Build `Content-Disposition` header from `displayName` override,
        # headers of provider response, or file path, whichever is truthy first
        if self.arguments.get('displayName'):
            disposition = utils.make_disposition(self.arguments['displayName'])
        elif headers.get('content-disposition'):
            disposition = headers['content-disposition']
        else:
            disposition = utils.make_disposition(os.path.split(self.arguments['path'])[-1])

        self.set_header('Content-Disposition', disposition)

        while True:
            chunk = yield from result.read(settings.CHUNK_SIZE)
            if not chunk:
                break
            self.write(chunk)
            yield from utils.future_wrapper(self.flush())

    @utils.coroutine
    def put(self):
        """Upload a file."""
        self.stream.feed_eof()
        metadata, created = yield from self.uploader
        if created:
            self.set_status(201)
        self.write(metadata)

        self._send_hook(
            'create' if created else 'update',
            metadata,
        )

    @utils.coroutine
    def delete(self):
        """Delete a file."""
        # TODO: Current release does not allow deletion of directories (needs authorization code)
        if self.arguments.get('path', '').endswith('/'):
            raise web.HTTPError('Deletion of directories is currently not supported', status_code=400)

        yield from self.provider.delete(**self.arguments)
        self.set_status(http.client.NO_CONTENT)

        self._send_hook(
            'delete',
            {'path': self.arguments['path']}
        )
Exemple #6
0
class CRUDHandler(core.BaseProviderHandler):

    ACTION_MAP = {
        'GET': 'download',
        'PUT': 'upload',
        'DELETE': 'delete',
        'POST': 'create_folder',
    }
    STREAM_METHODS = ('PUT', )

    @utils.coroutine
    def prepare(self):
        yield from super().prepare()
        self.prepare_stream()

    def prepare_stream(self):
        if self.request.method in self.STREAM_METHODS:
            self.stream = RequestStreamReader(self.request)
            self.uploader = asyncio.async(
                self.provider.upload(self.stream, **self.arguments)
            )
        else:
            self.stream = None

    @utils.coroutine
    def data_received(self, chunk):
        """Note: Only called during uploads."""
        if self.stream:
            self.stream.feed_data(chunk)

    @utils.coroutine
    def get(self):
        """Download a file."""
        try:
            self.arguments['accept_url'] = TRUTH_MAP[self.arguments.get('accept_url', 'true').lower()]
        except KeyError:
            raise web.HTTPError(status_code=400)

        result = yield from self.provider.download(**self.arguments)

        if isinstance(result, str):
            return self.redirect(result)

        if hasattr(result, 'content_type'):
            self.set_header('Content-Type', result.content_type)

        if hasattr(result, 'size') and result.size is not None:
            self.set_header('Content-Length', str(result.size))

        # Build `Content-Disposition` header from `displayName` override,
        # headers of provider response, or file path, whichever is truthy first
        if self.arguments.get('displayName'):
            disposition = utils.make_disposition(self.arguments['displayName'])
        else:
            # If the file extention is in mime_types
            # override the content type to fix issues with safari shoving in new file extensions
            if self.arguments['path'].ext in mime_types:
                self.set_header('Content-Type', mime_types[self.arguments['path'].ext])

            disposition = utils.make_disposition(self.arguments['path'].name)

        self.set_header('Content-Disposition', disposition)

        while True:
            chunk = yield from result.read(settings.CHUNK_SIZE)
            if not chunk:
                break
            self.write(chunk)
            yield from utils.future_wrapper(self.flush())

    @utils.coroutine
    def post(self):
        """Create a folder"""
        metadata = yield from self.provider.create_folder(**self.arguments)

        self.set_status(201)
        self.write(metadata)

        self._send_hook('create_folder', metadata)

    @utils.coroutine
    def put(self):
        """Upload a file."""
        self.stream.feed_eof()
        metadata, created = yield from self.uploader
        if created:
            self.set_status(201)
        self.write(metadata)

        self._send_hook(
            'create' if created else 'update',
            metadata,
        )

    @utils.coroutine
    def delete(self):
        """Delete a file."""
        # TODO: Current release does not allow deletion of directories (needs authorization code)
        # if self.arguments.get('path', '').endswith('/'):
        #     raise web.HTTPError('Deletion of directories is currently not supported', status_code=400)

        yield from self.provider.delete(**self.arguments)
        self.set_status(http.client.NO_CONTENT)

        self._send_hook(
            'delete',
            {
                'path': str(self.arguments['path']),
                'materialized': str(self.arguments['path'])
            }
        )