2011-03-25 22 views
9

Estoy buscando ayudar a un proyecto de código abierto con Python. Por lo que pude ver, Twisted no permite enviar y recibir información con gzip http: http://twistedmatrix.com/trac/ticket/104Twisted http gzip support

Google parece confirmarlo, ya que no pude encontrar ninguna mención de que la documentación. Mi pregunta es si estoy en lo cierto al respecto o si esto ha cambiado. Alternativamente, ¿es realmente útil para alguien? Supongo que hay una razón por la que aún no se ha implementado.

Lo siento si este no es el lugar adecuado para preguntar ...

+0

Sospecho que muchas personas que se preocupan por la compresión HTTP gzip están ejecutando sus aplicaciones twisted.web detrás de otro servidor HTTP como Apache o nginx. Por lo tanto, tener soporte para ello en retorcido.la web no es particularmente interesante o importante. Dicho esto, no hay ninguna razón por la que todos deberían * tener * para ejecutar su aplicación en una configuración como esa. Como de costumbre, la respuesta a "¿por qué no está implementado esto todavía?" es simplemente "nadie ha hecho el trabajo todavía" ... – mithrandi

Respuesta

3

El billete está todavía abierta, por lo que es correcto que esta función todavía no está disponible en Twisted. Sin embargo, Nevow incluye soporte para enviar respuestas gzip: http://bazaar.launchpad.net/~divmod-dev/divmod.org/trunk/view/head:/Nevow/nevow/compression.py. Como Nevow puede Twisted Web se puede utilizar fácilmente en conjunto, esta podría ser una forma de obtener lo que desea.

Afortunadamente, la característica también será portada desde Nevow a Twisted Web algún día también.

+0

Si su objetivo es ayudar a un proyecto de código abierto con Python, ¡entonces portar esta característica de Nevow a Twisted sería una excelente manera de hacerlo! – Glyph

+0

La migración de nevow.compression a twisted.web debería ser relativamente fácil; Creo que los únicos cambios importantes necesarios serían eliminar la locura de finishRequest que requiere la API de solicitud de Nevow y, en su lugar, anular IRequest.finish en su lugar. – mithrandi

6

Esto ahora es posible usando Resource Encoders. Citando desde ese enlace:

from twisted.web.server import Site, GzipEncoderFactory 
from twisted.web.resource import Resource, EncodingResourceWrapper 
from twisted.internet import reactor 

class Simple(Resource): 
    isLeaf = True 
    def render_GET(self, request): 
     return "<html>Hello, world!</html>" 

resource = Simple() 
wrapped = EncodingResourceWrapper(resource, [GzipEncoderFactory()]) 
site = Site(wrapped) 
reactor.listenTCP(8080, site) 
reactor.run() 

Consulte el enlace para obtener más información. El ticket en la pregunta ahora también está cerrado.

+2

Es importante tener en cuenta que en este ejemplo, isLeaf se establece en true, por lo que se reconocerá que el recurso envuelto tiene el codificador. Si isLeaf no es verdadero, se llamará a getChild y es posible que no esté empaquetado por EncodingResourceWrapper. – Chris

6

De la documentación para EncodingResourceWrapper:

Tenga en cuenta que no serán envueltos los recursos niños devueltos, por lo que tiene para envolver de forma explícita si desea que la codificación que se aplicará.

Así que si un Resource implementa getChild, entonces también necesita envolver ese recurso.
Por ejemplo:

from twisted.web.server import Site, GzipEncoderFactory 
from twisted.web.resource import EncodingResourceWrapper 
from twisted.web import static 
from twisted.internet import reactor 
from twisted.python import log 
import sys 
log.startLogging(sys.stdout) 

class WebServer(static.File):   
    def getChild(self, path, request): 
     child = static.File.getChild(self, path, request)    
     return EncodingResourceWrapper(child, [GzipEncoderFactory()]) 

resource = WebServer('/tmp') 

site = Site(resource) 
reactor.listenTCP(8080, site) 
reactor.run() 

puede probarlo con netcat:

printf 'GET/HTTP/1.1\r\nHost: localhost\r\nAccept-Encoding: gzip,deflate\r\nConnection: close\r\n\r\n' | nc localhost 8080 
1

me gustaría ampliar un poco @ danbrough es gran respuesta en el caso de las tierras de alguien más aquí: Puño de todo, si le pone niños con IResource.putChild, su solución no funcionará directamente, deberá sobrescribir IResource.getChildWithDefault en lugar de solo IResource.getChild.

También sucede, que el tener algunos recursos protegidos con HTTP BasicAuthenticationy servirlos comprimido con Gzip es un poco más complicado, ya que el anterior no funcionará. En este caso se le tenga que jugar con el HTTPAuthSessionWrapper así:

class GzipAuthSessionWrapper(HTTPAuthSessionWrapper): 
    def getChildWithDefault(self, path, request): 
    child = HTTPAuthSessionWrapper.getChildWithDefault(self, path, request) 
    gzipChild = EncodingResourceWrapper(child, [GzipEncoderFactory()]) 
    return gzipChild 

También tendrá que configurar el Realm, Checkers y Portal como de costumbre (documentation).