web-dev-qa-db-fra.com

Analyser http GET et POST de BaseHTTPHandler?

BaseHTTPHandler du module BaseHTTPServer ne semble pas fournir un moyen pratique d'accéder aux paramètres de requête http. Quelle est la meilleure façon d'analyser les paramètres GET du chemin d'accès et les paramètres POST du corps de la demande?

En ce moment, j'utilise ceci pour GET:

def do_GET(self):
    parsed_path = urlparse.urlparse(self.path)
    try:
        params = dict([p.split('=') for p in parsed_path[4].split('&')])
    except:
        params = {}

Cela fonctionne pour la plupart des cas, mais j'aimerais quelque chose de plus robuste qui gère correctement les encodages et les cas comme les paramètres vides. Idéalement, j'aimerais quelque chose de petit et autonome, plutôt qu'un framework web complet.

34
ataylor

Vous pouvez essayer les modules Werkzeug , la bibliothèque de base Werkzeug n'est pas trop grande et si nécessaire, vous pouvez simplement extraire ce morceau de code et vous avez terminé.

Le url_decode la méthode renvoie un MultiDict et prend en charge l'encodage :)

Contrairement au urlparse.parse_qs méthode dont la version Werkzeug s'occupe:

  • codage
  • plusieurs valeurs
  • ordre de tri

Si vous n'en avez pas besoin (ou dans le cas de l'encodage, utilisez Python 3) alors n'hésitez pas à utiliser les solutions intégrées.

6
Wolph

Vous pouvez utiliser urllib.parse :

>>> from urllib.parse import urlparse, parse_qs
>>> url = 'http://example.com/?foo=bar&one=1'
>>> parse_qs(urlparse(url).query)
{'foo': ['bar'], 'one': ['1']}

Pour Python 2 , le module est nommé urlparse au lieu de url.parse.

85
zag

Meilleure solution à une vieille question:

def do_POST(self):
    length = int(self.headers.getheader('content-length'))
    field_data = self.rfile.read(length)
    fields = urlparse.parse_qs(field_data)

Cela va extraire les données encodées en url POST du contenu du document et les analyser en dict avec un codage urld approprié.

12
Mike

Avez-vous étudié l'utilisation de bibliothèques comme CherryPy ? Ils fournissent un chemin beaucoup plus rapide pour gérer ces choses que BaseHTTPServer.

2
Benno

La prise en charge des paramètres de requête HTTP de base est fournie dans le module CGI . Le mécanisme recommandé pour gérer les données du formulaire est la classe cgi.FieldStorage.

Pour obtenir les données de formulaire soumises, il est préférable d'utiliser la classe FieldStorage. Les autres classes définies dans ce module sont fournies principalement pour une compatibilité descendante. Instanciez-le exactement une fois, sans arguments. Cela lit le contenu du formulaire à partir de l'entrée standard ou de l'environnement (en fonction de la valeur des différentes variables d'environnement définies selon la norme CGI). Puisqu'il peut consommer une entrée standard, il ne doit être instancié qu'une seule fois.

L'instance FieldStorage peut être indexée comme un dictionnaire Python. Elle permet de tester l'appartenance avec l'opérateur in, et prend également en charge la méthode de dictionnaire standard keys() et le fonction intégrée len(). Les champs de formulaire contenant des chaînes vides sont ignorés et n'apparaissent pas dans le dictionnaire. Pour conserver ces valeurs, fournissez une valeur vraie pour le paramètre facultatif du mot clé keep_blank_values ​​lors de la création du FieldStorage exemple.

Par exemple, le code suivant (qui suppose que l'en-tête Content-Type et la ligne vierge ont déjà été imprimés) vérifie que le nom des champs et addr sont tous deux définis sur une chaîne non vide:

form = cgi.FieldStorage()
if "name" not in form or "addr" not in form:
    print "<H1>Error</H1>"
    print "Please fill in the name and addr fields."
    return
print "<p>name:", form["name"].value
print "<p>addr:", form["addr"].value
#...further form processing here...
2
gimel