O status code 103 de webservers

Categoria: Python Publicado: Sábado, 06 Novembro 2021 Escrito por Helio Loureiro Imprimir

E foi assim que tudo começou.  Com um singelo e modesto "deu merda".  Primeiramente uma rápida introdução pra explicar o que isso significa:  temos um bot pra adicionar assuntos nas pautas do canal Unix Load On.  O bot roda em Python no raspberrypi3 que tenho aqui em casa.  O mesmo que fica tirando fotos pela janela e mostra no twitter no perfil @helio_weather.

Então temos essa função "/addpauta" com um estilo de inglês a la Raimundos pra adicionar novos links.  O programa no bot rodava um código com módulo requests pra pegar a página e buscar o título do artigo.   Só isso.  Então não era algo esperado pra ter o resultado "deu merda".  Mas deu.

Olhando a mesma URL usando o ipython:

> ipython3
Python 3.9.7 (default, Sep 10 2021, 14:59:43) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.20.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import requests

In [2]: url = "https://www.theregister.com/2021/11/02/fedora_35/"

In [3]: r = requests.get(url)

In [4]: r.status_code
Out[4]: 103

In [5]: r.text
Out[5]: ''

então é isso.  O webserver retorna 103, que é uma nova RFC, e espera que você continue pegando o conteúdo.  Só que o módulo requests não faz isso.

Existe um bug aberto no github sobre esse problema onde eles relatam que o comportamento não é bem do requests, mas da urllib3, que é parte do core do Python.  Traduzindo em miúdos: não tem solução e talvez façam uma correção no Python 3.10.

Atualizar todo o Python só pra corrigir um erro besta desses?  Entra em cena o curl, que já comentei em usando curl pra monitorar um site.  Não o curl propriamente dito, mas a pycurl.  Tanto curl quanto pycurl passam dando tchauzinho por esse problema de manipular a resposta 103.  E mandam aquele abraço pra urllib3.

Olhando via script:

> curl -s https://www.theregister.com/2021/11/02/fedora_35/ | head -10
<!doctype html>
<html lang="en">
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>Fedora 35 released with GNOME 41 desktop • The Register</title>
    <meta name="robots" content="max-snippet:-1, max-image-preview:standard, max-video-preview:0">
    <meta name="viewport" content="initial-scale=1.0, width=device-width"/>
    <meta property="og:image" content="https://regmedia.co.uk/2021/11/02/fedora35.jpg"/>
    <meta property="og:type" content="article" />
    <meta property="og:url" content="https://www.theregister.com/2021/11/02/fedora_35/" />

fazendo o mesmo em Python:

import pycurl
from io import BytesIO

def curl(url):
   crl = pycurl.Curl()
   crl.setopt(crl.URL, url)
   b_obj = BytesIO()
   crl.setopt(crl.WRITEDATA, b_obj)
   crl.setopt(crl.FOLLOWLOCATION, True)
   crl.setopt(pycurl.USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0')
   crl.perform()
   crl.close()
   return b_obj.getvalue().decode('utf-8')

print(curl("https://www.theregister.com/2021/11/02/fedora_35/"))

então fica aqui a lição: onde a requests falhar, pycurl estará lá pra te salvar.

Acessos: 682
Mastodon Mastodon
We use cookies

We use cookies on our website. Some of them are essential for the operation of the site, while others help us to improve this site and the user experience (tracking cookies). You can decide for yourself whether you want to allow cookies or not. Please note that if you reject them, you may not be able to use all the functionalities of the site.