Поддержка скрученного http gzip

Я хочу помочь проекту с открытым исходным кодом на Python.
Насколько я могу судить, Twisted не не поддерживал отправку и получение информации gzip с помощью HTTP (по состоянию на 2011 год). http://twistedmatrix.com/trac/ticket/104

Google, кажется, подтверждает это, так как я не смог найти упоминания об этом в документации. Мой вопрос в том, прав ли я в этом, или это изменилось? С другой стороны, это действительно полезно для кого-либо? Я думаю, есть причина, по которой он еще не реализован.

Извините, если это не то место, где можно спросить...


person Tiersen    schedule 25.03.2011    source источник
comment
Я подозреваю, что многие люди, которые заботятся о сжатии HTTP gzip, запускают свои приложения twisted.web за другим HTTP-сервером, таким как Apache или nginx. Таким образом, наличие его поддержки в twisted.web не представляет особого интереса или важности. Тем не менее, нет причин, по которым каждый должен должен запускать свое приложение с такой настройкой. Как обычно, ответ на вопрос, почему это еще не реализовано? просто еще никто не работал...   -  person mithrandi    schedule 26.03.2011


Ответы (4)


Из документации для EncodingResourceWrapper:

Обратите внимание, что возвращенные дочерние ресурсы не будут упакованы, поэтому вам необходимо явно обернуть их, если вы хотите применить кодировку.

Поэтому, если Resource реализует getChild, вам также необходимо обернуть этот ресурс.
Например:

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()

вы можете проверить это с помощью netcat:

printf 'GET /  HTTP/1.1\r\nHost: localhost\r\nAccept-Encoding: gzip,deflate\r\nConnection: close\r\n\r\n' | nc localhost 8080
person Dan Brough    schedule 09.07.2013

Теперь это возможно с помощью кодировщиков ресурсов. Цитата из той ссылки:

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()

См. ссылку для получения дополнительной информации. Билет в вопросе теперь также закрыт.

person Daniel C. Sobral    schedule 04.03.2013
comment
Важно отметить, что в этом примере isLeaf имеет значение true, поэтому обернутый ресурс будет распознан как содержащий кодировщик. Если isLeaf не равно true, то будет вызываться getChild, и это может не быть обернуто EncodingResourceWrapper. - person Chris; 07.02.2016

Билет все еще открыт, поэтому правильно, что эта функция все еще недоступна в Twisted. Тем не менее, Nevow поддерживает отправку ответов в формате gzip: http://bazaar.launchpad.net/~divmod-dev/divmod.org/trunk/view/head:/Nevow/nevow/compression.py. Поскольку Nevow может легко использоваться вместе с Twisted Web, это может быть способом получить то, что вы хотите.

Надеюсь, когда-нибудь эта функция также будет перенесена из Nevow в Twisted Web.

person Jean-Paul Calderone    schedule 25.03.2011
comment
Если его цель — помочь проекту с открытым исходным кодом на Python, то перенос этой функции из Nevow в Twisted будет отличным способом сделать это! - person Glyph; 25.03.2011
comment
Портирование newow.compression на Twisted.web должно быть относительно простым; Я полагаю, что единственными серьезными изменениями, которые требуются, было бы удаление безумия finishRequest, которое требует API запроса Nevow, и вместо этого переопределение IRequest.finish. - person mithrandi; 26.03.2011
comment
Этот ответ устарел - person Franklin Piat; 22.07.2021

Я хотел бы немного расширить отличный ответ @danbrough на случай, если кто-то еще приземлится здесь: Прежде всего, если вы поместите детей с IResource.putChild, его решение не будет работать напрямую, вам придется перезаписать IResource.getChildWithDefault вместо просто IResource.getChild.

Бывает и так, что защитить некоторые ресурсы с помощью HTTP BasicAuthentication и обслуживать их, сжатые с помощью Gzip, немного сложнее, так как описанное выше не сработает. В этом случае вам нужно будет возиться с HTTPAuthSessionWrapper следующим образом:

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

Вам также потребуется настроить Realm, Checkers и Portal как обычно (документация).

person evilham    schedule 09.04.2015