2012-10-18 12 views
13

Mi piace usare SimpleHTTPServer di Python per lo sviluppo locale di tutti i tipi di applicazioni web che richiedono risorse di carico tramite Ajax chiama eccPerché SimpleHTTerver reindirizza a? Querystring/quando richiedo? Querystring?

Quando uso stringhe di query nei miei URL, il server reindirizza sempre allo stesso URL con una barra allegata.

Ad esempio /folder/?id=1 reindirizza a /folder/?id=1/ utilizzando una risposta HTTP 301.

Avvio semplicemente il server utilizzando python -m SimpleHTTPServer.

Qualche idea su come potermi liberare del comportamento di reindirizzamento? Questo è Python 2.7.2.

+0

SimpleHTTPServer serve solo file. Usa qualcos'altro per gestire i parametri nelle richieste. –

risposta

3

Ok. Con l'aiuto di Morten ho trovato questo, che sembra essere tutto ciò di cui ho bisogno: semplicemente ignorando le stringhe di query se sono lì e servono i file statici.

import SimpleHTTPServer 
import SocketServer 

PORT = 8000 


class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): 

    def __init__(self, req, client_addr, server): 
     SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, req, client_addr, server) 

    def do_GET(self): 
     # cut off a query string 
     if '?' in self.path: 
      self.path = self.path.split('?')[0] 
     SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) 


class MyTCPServer(SocketServer.ThreadingTCPServer): 
    allow_reuse_address = True 

if __name__ == '__main__': 
    httpd = MyTCPServer(('localhost', PORT), CustomHandler) 
    httpd.allow_reuse_address = True 
    print "Serving at port", PORT 
    httpd.serve_forever() 
+0

Questo non sembra rispettare i parametri url. Aggiunge ancora '/' dopo i parametri della query. –

2

Non sono sicuro di come viene generato il reindirizzamento ... Ho provato a implementare un SimpleHTTPServer di base e non ho alcun reindirizzamento quando utilizzo parametri di stringa di query.

Basta fare qualcosa come self.path.split("/") ed elaborare il percorso prima di gestire la richiesta? Questo codice fa quello che vuoi penso:

import SocketServer 
import SimpleHTTPServer 
import os 


class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): 
    def folder(self): 
     fid = self.uri[-1].split("?id=")[-1].rstrip() 
     return "FOLDER ID: %s" % fid 

    def get_static_content(self): 
     # set default root to cwd 
     root = os.getcwd() 
     # look up routes and set root directory accordingly 
     for pattern, rootdir in ROUTES: 
      if path.startswith(pattern): 
       # found match! 
       path = path[len(pattern):] # consume path up to pattern len 
       root = rootdir 
       break 
     # normalize path and prepend root directory 
     path = path.split('?',1)[0] 
     path = path.split('#',1)[0] 
     path = posixpath.normpath(urllib.unquote(path)) 
     words = path.split('/') 
     words = filter(None, words) 
     path = root 
     for word in words: 
      drive, word = os.path.splitdrive(word) 
      head, word = os.path.split(word) 
      if word in (os.curdir, os.pardir): 
       continue 
      path = os.path.join(path, word) 
      return path 

    def do_GET(self): 
     path = self.path 
     self.uri = path.split("/")[1:] 

     actions = { 
      "folder": self.folder, 
     } 
     resource = self.uri[0] 
     if not resource: 
      return self.get_static_content() 
     action = actions.get(resource) 
     if action: 
      print "action from looking up '%s' is:" % resource, action 
      return self.wfile.write(action()) 
     SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) 


class MyTCPServer(SocketServer.ThreadingTCPServer): 
    allow_reuse_address = True 

httpd = MyTCPServer(('localhost', 8080), CustomHandler) 
httpd.allow_reuse_address = True 
print "serving at port", 8080 
httpd.serve_forever() 

Provalo:

HTTP GET /folder/?id=500x ->"FOLDER ID: 500x"

EDIT:

Va bene così se non avete usato la SimpleHTTserver-roba prima, in pratica implementate il gestore di richieste di base, implementate do_GET(), do_PUT(), do_POST() ecc.

Quello che faccio di solito è analizzare la stringa di richiesta (usando re), la corrispondenza di modello e vedere se riesco a trovare un gestore di richieste e, in caso contrario, gestire la richiesta come richiesta di contenuto statico se possibile.

Tu dici che vuoi per servire contenuti statici, se possibile, allora si dovrebbe capovolgere questo pattern matching in giro, e vedere prima se la richiesta corrisponde al file-store e se non, quindi partita contro i gestori :)

+0

Innanzitutto, grazie! Mostra che è possibile prevenire il reindirizzamento.Tuttavia sembra che questo gestore non serva i file statici come sono abituato. Quello che voglio sostanzialmente è essere in grado di servire qualsiasi percorso disponibile come file statico, ignorando completamente la parte della stringa di query. – Marian

+0

Basta aggiungere la logica nel metodo do_GET(), ho fatto un aggiornamento che fa proprio quello –

+0

hai preso in considerazione l'utilizzo di web.py? è davvero leggero e sarebbe una frazione del codice sopra. –

3

Il modo giusto per fare questo, per garantire che i parametri di query rimangono come dovrebbero, è quello di assicurarsi di fare una richiesta per il nome del file direttamente invece di lasciare SimpleHTTPServer reindirizzare al tuo index.html

Per esempio http://localhost:8000/?param1=1 esegue un reindirizzamento (301) e modifica l'URL in http://localhost:8000/?param=1/ che causa problemi con il parametro di query.

Tuttavia http://localhost:8000/index.html?param1=1 (rendendo esplicito il file di indice) viene caricato correttamente.

Quindi non lasciare che SimpleHTTPServer esegua un reindirizzamento dell'URL per risolvere il problema.