MagicStack / MagicStack/httptools

with curl and https

Ouverte
#89 1 commentaire 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
Python
Étoiles
1.3k
Forks
107
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

I try to combine pycurl and httptools, but I found it can't deal with https, here is my code:

success with http:

import pycurl
import httptools

class HttpResponse:
    def on_message_begin(self):
        print('on_message_begin')
    def on_url(self, url: bytes):
        print(f'on_url: url={url}')
    def on_header(self, name: bytes, value: bytes):
        print(f'on_header: name={name}, value={value.decode("ISO-8859-1")}')
    def on_headers_complete(self):
        print(f'on_header_complete')
    def on_body(self, body: bytes):
        print(f'on_body: {len(body)}')
    def on_message_complete(self):
        print(f'on_message_complete')
    def on_chunk_header(self):
        print(f'on_chunk_header')
    def on_chunk_complete(self):
        print(f'on_chunk_complete')
    def on_status(self, status: bytes):
        print(f'on_status: status={status}')

print(pycurl.version)
print(httptools.__version__)
m = HttpResponse()
p = httptools.HttpResponseParser(m)

c = pycurl.Curl()
c.setopt(pycurl.URL, "http://uvloop.readthedocs.io/")
c.setopt(pycurl.HTTP_TRANSFER_DECODING, 0)
c.setopt(pycurl.WRITEFUNCTION, p.feed_data)
c.setopt(pycurl.HEADERFUNCTION, p.feed_data)
c.perform()

and output:

PycURL/7.45.2 libcurl/7.76.1 OpenSSL/1.1.1u zlib/1.2.11 libssh2/1.9.0 nghttp2/1.43.0
0.5.0
on_message_begin
on_status: status=b'Found'
on_header: name=b'Date', value=Thu, 08 Jun 2023 09:50:21 GMT
on_header: name=b'Content-Type', value=text/html; charset=utf-8
on_header: name=b'Transfer-Encoding', value=chunked
on_header: name=b'Connection', value=keep-alive
on_header: name=b'Location', value=https://uvloop.readthedocs.io/
on_header: name=b'CF-Ray', value=7d403ae94955cec5-SJC
on_header: name=b'CF-Cache-Status', value=EXPIRED
on_header: name=b'Cache-Control', value=max-age=1200
on_header: name=b'Content-Language', value=en
on_header: name=b'Vary', value=Accept-Language, Cookie, Accept-Encoding
on_header: name=b'CDN-Cache-Control', value=public
on_header: name=b'Referrer-Policy', value=no-referrer-when-downgrade
on_header: name=b'X-Backend', value=web-i-0854c4793bcd745a7
on_header: name=b'X-Content-Type-Options', value=nosniff
on_header: name=b'X-RTD-Domain', value=uvloop.readthedocs.io
on_header: name=b'X-RTD-Project', value=
on_header: name=b'X-RTD-Project-Method', value=public_domain
on_header: name=b'X-RTD-Redirect', value=http_to_https
on_header: name=b'X-RTD-Version-Method', value=path
on_header: name=b'X-Served', value=Django-Proxito
on_header: name=b'X-XSS-Protection', value=1; mode=block
on_header: name=b'Server', value=cloudflare
on_header: name=b'alt-svc', value=h3=":443"; ma=86400
on_header_complete
on_chunk_header
on_chunk_complete
on_message_complete

fail with https:

import certifi
import pycurl
import httptools


class HttpResponse:
    def on_message_begin(self):
        print('on_message_begin')
    def on_url(self, url: bytes):
        print(f'on_url: url={url}')
    def on_header(self, name: bytes, value: bytes):
        print(f'on_header: name={name}, value={value.decode("ISO-8859-1")}')
    def on_headers_complete(self):
        print(f'on_header_complete')
    def on_body(self, body: bytes):
        print(f'on_body: {len(body)}')
    def on_message_complete(self):
        print(f'on_message_complete')
    def on_chunk_header(self):
        print(f'on_chunk_header')
    def on_chunk_complete(self):
        print(f'on_chunk_complete')
    def on_status(self, status: bytes):
        print(f'on_status: status={status}')

print(pycurl.version)
print(httptools.__version__)
m = HttpResponse()
p = httptools.HttpResponseParser(m)

c = pycurl.Curl()
c.setopt(pycurl.URL, "https://uvloop.readthedocs.io/")
c.setopt(c.CAINFO, certifi.where())
c.setopt(pycurl.HTTP_TRANSFER_DECODING, 0)
c.setopt(pycurl.WRITEFUNCTION, p.feed_data)
c.setopt(pycurl.HEADERFUNCTION, p.feed_data)
c.perform()

output:

PycURL/7.45.2 libcurl/7.76.1 OpenSSL/1.1.1u zlib/1.2.11 libssh2/1.9.0 nghttp2/1.43.0
0.5.0
on_message_begin

---------------------------------------------------------------------------
HttpParserError                           Traceback (most recent call last)
httptools/parser/parser.pyx in httptools.parser.parser.HttpParser.feed_data()

HttpParserError: Expected dot

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
/tmp/ipykernel_16171/3019824725.py in <module>
     37 c.setopt(pycurl.WRITEFUNCTION, p.feed_data)
     38 c.setopt(pycurl.HEADERFUNCTION, p.feed_data)
---> 39 c.perform()

error: (23, 'Failed writing header')

by the way, how can i let httptools auto decode with Accept-Encoding: gzip,deflate

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Reproduisez les deux exemples pycurl fournis et commencez par le traceback HttpParserError dans httptools/parser/parser.pyx. Comparez les données envoyées à p.feed_data via WRITEFUNCTION et HEADERFUNCTION pour HTTP et HTTPS, puis documentez ou testez le comportement attendu de HTTPS et du décodage gzip.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
backend, networking
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.