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
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))
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
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']} )
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']) } )