2012-10-30 20 views
12

Próbuję utworzyć prosty serwer sieciowy Python, aby zapisać tekst o nazwie Post ed do pliku o nazwie store.json, który znajduje się w tym samym folderze, co skrypt Pythona. Oto połowa mojego kodu, czy ktoś może mi powiedzieć, czym powinna być reszta?Prosty serwer WWW w języku Python do zapisywania pliku

import string,cgi,time 
from os import curdir, sep 
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
#import pri 

class StoreHandler(BaseHTTPRequestHandler): 
def do_GET(self): 
    try: 
     if self.path == "/store.json": 
      f = open(curdir + sep + "store.json") #self.path has /test.html 
      self.send_response(200) 
      self.send_header('Content-type','text/json') 
      self.end_headers() 
      self.wfile.write(f.read()) 
      f.close() 
      return 
     return 
    except IOError: 
     self.send_error(404,'File Not Found: %s' % self.path) 
def do_POST(self): 
    //if the url is 'store.json' then 
    //what do I do here? 

def main(): 
    try: 
     server = HTTPServer(('', 80), StoreHandler) 
     print 'started...' 
     server.serve_forever() 
    except KeyboardInterrupt: 
     print '^C received, shutting down server' 
     server.socket.close() 
if __name__ == '__main__': 
    main() 

Odpowiedz

26

Oto ogólna idea:

from os import curdir 
from os.path import join as pjoin 

from http.server import BaseHTTPRequestHandler, HTTPServer 

class StoreHandler(BaseHTTPRequestHandler): 
    store_path = pjoin(curdir, 'store.json') 

    def do_GET(self): 
     if self.path == '/store.json': 
      with open(self.store_path) as fh: 
       self.send_response(200) 
       self.send_header('Content-type', 'text/json') 
       self.end_headers() 
       self.wfile.write(fh.read().encode()) 

    def do_POST(self): 
     if self.path == '/store.json': 
      length = self.headers['content-length'] 
      data = self.rfile.read(int(length)) 

      with open(self.store_path, 'w') as fh: 
       fh.write(data.decode()) 

      self.send_response(200) 


server = HTTPServer(('', 8080), StoreHandler) 
server.serve_forever() 
$ curl -X POST --data "one two three four" localhost:8080/store.json 
$ curl -X GET localhost:8080/store.json  
one two three four% 
+0

'ImportError: Brak modułu o nazwie 'BaseHTTPServer'' –

+2

Ok, musisz zmienić' from BaseHTTPServer' na 'from http.server' –

+1

Niestety, nie zauważyliśmy części tagu" -3.x ". – gvalkov

7

Ważne jest, abyś musiał poprawnie zbudować cgi.FieldStorage z surowych opublikowanych danych, np.

form = cgi.FieldStorage(
      fp=self.rfile, 
      headers=self.headers, 
      environ={'REQUEST_METHOD':'POST', 
        'CONTENT_TYPE':self.headers['Content-Type'], 
        }) 

potem łatwo jest zrzucić plik, tutaj jest prosta procedura obsługi, która pokazuje formularz na do_GET przesłać każdy użytkownik plik wybiera i zapisuje ten plik do/tmp w do_POST gdy forma jest zamieszczona

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler 

import cgi 

class StoreHandler(BaseHTTPRequestHandler): 
    def do_POST(self): 

     form = cgi.FieldStorage(
      fp=self.rfile, 
      headers=self.headers, 
      environ={'REQUEST_METHOD':'POST', 
        'CONTENT_TYPE':self.headers['Content-Type'], 
        }) 
     filename = form['file'].filename 
     data = form['file'].file.read() 
     open("/tmp/%s"%filename, "wb").write(data) 

     self.respond("uploaded %s, thanks"%filename) 

    def do_GET(self): 
     response = """ 
     <html><body> 
     <form enctype="multipart/form-data" method="post"> 
     <p>File: <input type="file" name="file"></p> 
     <p><input type="submit" value="Upload"></p> 
     </form> 
     </body></html> 
     """   

     self.respond(response) 

    def respond(self, response, status=200): 
     self.send_response(status) 
     self.send_header("Content-type", "text/html") 
     self.send_header("Content-length", len(response)) 
     self.end_headers() 
     self.wfile.write(response) 

Należy również pamiętać, że self.respond nie jest standardową metodą, którą właśnie dodałem, aby szybko zwrócić jakąś odpowiedź.

+0

to Python 3, nie SimpleHTTP nadal działa? Przepraszam, nie wspomniałem o tym. –

+0

@ArlenBeiler Zmieniono na BaseHTTPRequestHandler, jeśli działa na python3, również wydaje się, że jest to SimplreREquestHandler w python3 http://docs.python.org/3.3/library/http.server.html#http.server.SimpleHTTPRequestHandler –