Exemplo n.º 1
0
def respond_with_json_bytes(
    request: Request, code: int, json_bytes: bytes, send_cors: bool = False,
):
    """Sends encoded JSON in response to the given request.

    Args:
        request: The http request to respond to.
        code: The HTTP response code.
        json_bytes: The json bytes to use as the response body.
        send_cors: Whether to send Cross-Origin Resource Sharing headers
            https://fetch.spec.whatwg.org/#http-cors-protocol

    Returns:
        twisted.web.server.NOT_DONE_YET if the request is still active.
    """

    request.setResponseCode(code)
    request.setHeader(b"Content-Type", b"application/json")
    request.setHeader(b"Content-Length", b"%d" % (len(json_bytes),))
    request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")

    if send_cors:
        set_cors_headers(request)

    # note that this is zero-copy (the bytesio shares a copy-on-write buffer with
    # the original `bytes`).
    bytes_io = BytesIO(json_bytes)

    producer = NoRangeStaticProducer(request, bytes_io)
    producer.start()
    return NOT_DONE_YET
Exemplo n.º 2
0
 def render_POST(self, request):
     
     context = self._context(request)
     
     form, status, appstruct = self._validate_form(request)
     
     if status == 'ok':
         filename = context['renderer'](appstruct)
         
         fileobj = FilePath(filename)
         
         request.setHeader('content-disposition', 'attachment; filename="output.pdf"')
         request.setHeader('content-length', str(fileobj.getsize()))
         request.setHeader('content-type', 'application/pdf')
         
         producer = NoRangeStaticProducer(request, fileobj.open('r'))
         
         producer.start()
         
         return NOT_DONE_YET
     
     data['renderer_form'] = form.render(appstruct)
     
     self.render_template(data, request)
     
     return NOT_DONE_YET
Exemplo n.º 3
0
def respond_with_json_bytes(request, code, json_bytes, send_cors=False,
                            response_code_message=None):
    """Sends encoded JSON in response to the given request.

    Args:
        request (twisted.web.http.Request): The http request to respond to.
        code (int): The HTTP response code.
        json_bytes (bytes): The json bytes to use as the response body.
        send_cors (bool): Whether to send Cross-Origin Resource Sharing headers
            http://www.w3.org/TR/cors/
    Returns:
        twisted.web.server.NOT_DONE_YET"""

    request.setResponseCode(code, message=response_code_message)
    request.setHeader(b"Content-Type", b"application/json")
    request.setHeader(b"Content-Length", b"%d" % (len(json_bytes),))
    request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")

    if send_cors:
        set_cors_headers(request)

    # todo: we can almost certainly avoid this copy and encode the json straight into
    # the bytesIO, but it would involve faffing around with string->bytes wrappers.
    bytes_io = BytesIO(json_bytes)

    producer = NoRangeStaticProducer(request, bytes_io)
    producer.start()
    return NOT_DONE_YET
Exemplo n.º 4
0
def respond_with_json_bytes(
    request, code, json_bytes, send_cors=False, response_code_message=None
):
    """Sends encoded JSON in response to the given request.

    Args:
        request (twisted.web.http.Request): The http request to respond to.
        code (int): The HTTP response code.
        json_bytes (bytes): The json bytes to use as the response body.
        send_cors (bool): Whether to send Cross-Origin Resource Sharing headers
            http://www.w3.org/TR/cors/
    Returns:
        twisted.web.server.NOT_DONE_YET"""

    request.setResponseCode(code, message=response_code_message)
    request.setHeader(b"Content-Type", b"application/json")
    request.setHeader(b"Content-Length", b"%d" % (len(json_bytes),))
    request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")

    if send_cors:
        set_cors_headers(request)

    # todo: we can almost certainly avoid this copy and encode the json straight into
    # the bytesIO, but it would involve faffing around with string->bytes wrappers.
    bytes_io = BytesIO(json_bytes)

    producer = NoRangeStaticProducer(request, bytes_io)
    producer.start()
    return NOT_DONE_YET
Exemplo n.º 5
0
        def writeResponse(reader):
            # Some readers from `tftp` do not provide a way to get the size
            # of the generated content. Only set `Content-Length` when size
            # can be determined for the response.
            if hasattr(reader, "size"):
                request.setHeader(b"Content-Length", reader.size)

            # The readers from `tftp` use `finish` instead of `close`, but
            # `NoRangeStaticProducer` expects `close` instead of `finish`. Map
            # `finish` to `close` so the file handlers are cleaned up.
            reader.close = reader.finish

            # Produce the result without allowing range. This producer will
            # call `close` on the reader and `finish` on the request when done.
            producer = NoRangeStaticProducer(request, reader)
            producer.start()
Exemplo n.º 6
0
    def render_GET(self, request):
        if self.size:
            request.setHeader(b'content-length', intToBytes(self.size))
        if self.type:
            request.setHeader(b'content-type', networkString(self.type))
        if self.encoding:
            request.setHeader(b'content-encoding', networkString(self.encoding))

        request.setResponseCode(http.OK)

        # FIXME: depending on self.size, eg when 128kB, we might want to directly return bytes
        # instead of the overhead setting up a producer etc ..

        # if we want to serve directly out of ZIP files, we cannot support HTTP
        # range requests, as the file-like object returned for a file within an archive
        # does not support seek() (it will raise "not implemented" - 2018/06 with Python 3.6.5)
        producer = NoRangeStaticProducer(request, self.file)
        producer.start()

        # and make sure the connection doesn't get closed
        return server.NOT_DONE_YET
Exemplo n.º 7
0
 def _callbackRenderResponseContext( self, request ):
     
     self._CleanUpTempFile( request )
     
     response_context = request.hydrus_response_context
     
     status_code = response_context.GetStatusCode()
     
     request.setResponseCode( status_code )
     
     for ( k, v, kwargs ) in response_context.GetCookies(): request.addCookie( k, v, **kwargs )
     
     do_finish = True
     
     if response_context.HasBody():
         
         ( mime, body ) = response_context.GetMimeBody()
         
         content_type = HC.mime_string_lookup[ mime ]
         
         content_length = len( body )
         
         request.setHeader( 'Content-Type', content_type )
         request.setHeader( 'Content-Length', str( content_length ) )
         
         request.write( HydrusData.ToByteString( body ) )
         
     elif response_context.HasPath():
         
         path = response_context.GetPath()
         
         size = os.path.getsize( path )
         
         if response_context.IsJSON():
             
             mime = HC.APPLICATION_JSON
             
             content_type = HC.mime_string_lookup[ mime ]
             
         else:
             
             mime = HydrusFileHandling.GetMime( path )
             
             ( base, filename ) = os.path.split( path )
             
             content_type = HC.mime_string_lookup[ mime ] + '; ' + filename
             
         
         content_length = size
         
         # can't be unicode!
         request.setHeader( 'Content-Type', str( content_type ) )
         request.setHeader( 'Content-Length', str( content_length ) )
         
         request.setHeader( 'Expires', time.strftime( '%a, %d %b %Y %H:%M:%S GMT', time.gmtime( time.time() + 86400 * 365 ) ) )
         request.setHeader( 'Cache-Control', str( 86400 * 365  ) )
         
         fileObject = open( path, 'rb' )
         
         producer = NoRangeStaticProducer( request, fileObject )
         
         producer.start()
         
         do_finish = False
         
     else:
         
         content_length = 0
         
         request.setHeader( 'Content-Length', str( content_length ) )
         
     
     request.hydrus_request_data_usage += content_length
     
     self._recordDataUsage( request )
     
     if do_finish:
         
         request.finish()
Exemplo n.º 8
0
    def _callbackRenderResponseContext(self, request):

        self._CleanUpTempFile(request)

        if request.channel is None:

            # Connection was lost, it seems.
            # no need for request.finish

            return

        if request.requestHeaders.hasHeader('Origin'):

            if self._service.SupportsCORS():

                request.setHeader('Access-Control-Allow-Origin', '*')

        response_context = request.hydrus_response_context

        status_code = response_context.GetStatusCode()

        request.setResponseCode(status_code)

        for (k, v, kwargs) in response_context.GetCookies():

            request.addCookie(k, v, **kwargs)

        do_finish = True

        if response_context.HasPath():

            path = response_context.GetPath()

            size = os.path.getsize(path)

            mime = response_context.GetMime()

            content_type = HC.mime_mimetype_string_lookup[mime]

            content_length = size

            (base, filename) = os.path.split(path)

            content_disposition = 'inline; filename="' + filename + '"'

            request.setHeader('Content-Type', str(content_type))
            request.setHeader('Content-Length', str(content_length))
            request.setHeader('Content-Disposition', str(content_disposition))

            request.setHeader(
                'Expires',
                time.strftime('%a, %d %b %Y %H:%M:%S GMT',
                              time.gmtime(time.time() + 86400 * 365)))
            request.setHeader('Cache-Control',
                              'max-age={}'.format(86400 * 365))

            fileObject = open(path, 'rb')

            producer = NoRangeStaticProducer(request, fileObject)

            producer.start()

            do_finish = False

        elif response_context.HasBody():

            mime = response_context.GetMime()

            body_bytes = response_context.GetBodyBytes()

            content_type = HC.mime_mimetype_string_lookup[mime]

            content_length = len(body_bytes)

            content_disposition = 'inline'

            request.setHeader('Content-Type', content_type)
            request.setHeader('Content-Length', str(content_length))
            request.setHeader('Content-Disposition', content_disposition)

            request.write(body_bytes)

        else:

            content_length = 0

            if status_code != 204:  # 204 is No Content

                request.setHeader('Content-Length', str(content_length))

        self._reportDataUsed(request, content_length)
        self._reportRequestUsed(request)

        if do_finish:

            request.finish()
Exemplo n.º 9
0
 def stopProducing(self):
     NoRangeStaticProducer.stopProducing(self)
     if hasattr(self, 'deferred'):
         self.deferred.callback(None)
Exemplo n.º 10
0
 def start(self):
     NoRangeStaticProducer.start(self)
     if self.request is None:
         return defer.succeed(None)
     self.deferred = defer.Deferred()
     return self.deferred
Exemplo n.º 11
0
 def start(self):
     NoRangeStaticProducer.start(self)
     if self.request is None:
         return defer.succeed(None)
     self.deferred = defer.Deferred()
     return self.deferred
Exemplo n.º 12
0
 def stream_opened(fd):
   producer = NoRangeStaticProducer(request, fd)
   producer.start()
Exemplo n.º 13
0
 def makeProducer(self, request, content_object):
     request.setResponseCode(OK)
     # TODO: add full support for multi-part download and upload
     # TODO: twisted.web.static.File is a nice example for streaming
     # TODO: For non-local backends twisted.web.Proxy approach should be reused.
     return NoRangeStaticProducer(request, content_object)
Exemplo n.º 14
0
 def __init__(self, request, fileObject):
     NoRangeStaticProducer.__init__(self, request, fileObject)
     # Add bytesWritten for simplicity
     self.bytesWritten = 0
     self.size = fileObject.length
Exemplo n.º 15
0
 def makeProducer(self, request, fileForReading):
     self._setContentHeaders(request)
     request.setResponseCode(http.OK)
     return NoRangeStaticProducer(request, fileForReading)
Exemplo n.º 16
0
 def stopProducing(self):
     NoRangeStaticProducer.stopProducing(self)
     if hasattr(self, 'deferred'):
         self.deferred.callback(None)
Exemplo n.º 17
0
 def _callbackRenderResponseContext( self, request ):
     
     self._CleanUpTempFile( request )
     
     if request.channel is None:
         
         raise HydrusExceptions.ServerException( 'Channel was closed! Probably a connectionLost that was not caught!' )
         
     
     response_context = request.hydrus_response_context
     
     status_code = response_context.GetStatusCode()
     
     request.setResponseCode( status_code )
     
     for ( k, v, kwargs ) in response_context.GetCookies():
         
         request.addCookie( k, v, **kwargs )
         
     
     do_finish = True
     
     if response_context.HasPath():
         
         path = response_context.GetPath()
         
         size = os.path.getsize( path )
         
         mime = response_context.GetMime()
         
         content_type = HC.mime_string_lookup[ mime ]
         
         content_length = size
         
         ( base, filename ) = os.path.split( path )
         
         content_disposition = 'inline; filename="' + filename + '"'
         
         # can't be unicode!
         request.setHeader( 'Content-Type', str( content_type ) )
         request.setHeader( 'Content-Length', str( content_length ) )
         request.setHeader( 'Content-Disposition', str( content_disposition ) )
         
         request.setHeader( 'Expires', time.strftime( '%a, %d %b %Y %H:%M:%S GMT', time.gmtime( time.time() + 86400 * 365 ) ) )
         request.setHeader( 'Cache-Control', str( 86400 * 365 ) )
         
         fileObject = open( path, 'rb' )
         
         producer = NoRangeStaticProducer( request, fileObject )
         
         producer.start()
         
         do_finish = False
         
     elif response_context.HasBody():
         
         mime = response_context.GetMime()
         
         body = response_context.GetBody()
         
         content_type = HC.mime_string_lookup[ mime ]
         
         content_length = len( body )
         
         content_disposition = 'inline'
         
         request.setHeader( 'Content-Type', content_type )
         request.setHeader( 'Content-Length', str( content_length ) )
         request.setHeader( 'Content-Disposition', content_disposition )
         
         request.write( HydrusData.ToByteString( body ) )
         
     else:
         
         content_length = 0
         
         request.setHeader( 'Content-Length', str( content_length ) )
         
     
     self._reportDataUsed( request, content_length )
     self._reportRequestUsed( request )
     
     if do_finish:
         
         request.finish()
Exemplo n.º 18
0
 def stream_opened(fd):
   producer = NoRangeStaticProducer(request, fd)
   producer.start()