web-dev-qa-db-fra.com

Puis-je définir un en-tête avec SimpleHTTPServer de python?

J'utilise SimpleHTTPServer pour tester certaines pages Web sur lesquelles je travaille. Cela fonctionne très bien, mais je dois faire des requêtes interdomaines. Cela nécessite de définir un en-tête Access-Control-Allow-Origin avec les domaines auxquels la page est autorisée à accéder.

Existe-t-il un moyen simple de définir un en-tête avec SimpleHTTPServer et de servir le contenu d'origine? L'en-tête serait le même pour chaque demande.

47
nynexman4464

C'est un peu un bidouillage parce que cela change le comportement de end_headers(), mais je pense que c'est légèrement mieux que de copier et coller le fichier SimpleHTTPServer.py entier.

Mon approche remplace end_headers() dans une sous-classe dans laquelle elle appelle send_my_headers(), suivie de l'appel de end_headers() de la superclasse.

Ce n'est pas 1 - 2 lignes non plus, moins de 20 cependant; principalement chaud.

#!/usr/bin/env python
import SimpleHTTPServer

class MyHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_my_headers()

        SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)

    def send_my_headers(self):
        self.send_header("Access-Control-Allow-Origin", "*")


if __== '__main__':
    SimpleHTTPServer.test(HandlerClass=MyHTTPRequestHandler)
47
berto

Je dirais qu'il n'y a pas de moyen simple de le faire, où simple signifie "ajoute simplement 1 ou 2 lignes qui vont écrire l'en-tête supplémentaire et conserver les fonctionnalités existantes". La meilleure solution serait donc de sous-classer la classe SimpleHTTPRequestHandler et de réimplémenter la fonctionnalité, en ajoutant le nouvel en-tête.

Le problème qui explique pourquoi il n’existe pas de moyen simple de le faire peut être observé en regardant l’implémentation de la classe SimpleHTTPRequestHandler dans la bibliothèque Python: http://hg.python.org/cpython/file/19c74cadea95/Lib/http /server.py#l654

Notez la méthode send_head(), en particulier les lignes à la fin de la méthode qui envoient les en-têtes de réponse. Notez l'invocation de la méthode end_headers(). Cette méthode écrit les en-têtes dans la sortie, avec une ligne vide signalant la fin de tous les en-têtes et le début du corps de la réponse: http://docs.python.org/py3k/library/http.server.html # http.server.BaseHTTPRequestHandler.end_headers

Par conséquent, il ne serait pas possible de sous-classer le gestionnaire SimpleHTTPRequestHandler, d'appeler la méthode do_GET() de super-classe, puis d'ajouter simplement un autre en-tête, car l'envoi des en-têtes est déjà terminé lorsque l'appel de la méthode do_GET() de super-classe est renvoyé. Et cela doit fonctionner comme ceci parce que la méthode do_GET() doit envoyer le corps (le fichier demandé), et envoyer le corps - elle doit finaliser l'envoi des en-têtes.

Donc, encore une fois, je pense que vous êtes coincé avec la sous-classification de la classe SimpleHTTPRequestHandler, l'implémentant exactement comme le code dans la bibliothèque (copiez-le simplement?), Et ajoutez un autre en-tête avant l'appel de la méthode end_headers() dans send_head():

...
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
# this below is the new header
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
return f
...
9
Ivan Zuzak
# coding: utf-8
import SimpleHTTPServer
import SocketServer
PORT = 9999

def do_GET(self):
    self.send_response(200)
    self.send_header('Access-Control-Allow-Origin', 'http://example.com')           
    self.end_headers()

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
Handler.do_GET = do_GET
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()
4
iMom0

Bien qu’il s’agisse d’une réponse ancienne, c’est le premier résultat obtenu dans Google ...

Fondamentalement ce que @ iMon0 a suggéré..Semble correct? .. Exemple de doPOST

def do_POST(self):
    self.send_response()
    self.send_header('Content-type','application/json')
    self.send_header('Access-Control-Allow-Origin','*')
    self.end_headers()
    sTest = {}
    sTest['dummyitem'] = "Just an example of JSON"
    self.wfile.write(json.dumps(sTest))

En faisant cela, le flux semble correct.

1: Vous recevez une demande

2: vous appliquez les en-têtes et le type de réponse souhaités

3: Vous publiez les données que vous voulez, que ce soit ce que vous voulez ou ce que vous voulez.,

L'exemple ci-dessus fonctionne bien pour moi et peut être étendu davantage, il s'agit simplement d'un serveur de postes JSON simple. Donc, je vais laisser ça ici sur les SOF si quelqu'un en a besoin ou si je reviens moi-même dans quelques mois.

Ceci produit un fichier JSON valide avec uniquement l'objet sTest, comme une page/fichier généré par PHP.

0
Mayhem