extras-buildsys/common HTTPServer.py,1.9,1.10

Daniel Williams (dcbw) fedora-extras-commits at redhat.com
Sun Mar 26 18:53:04 UTC 2006


Author: dcbw

Update of /cvs/fedora/extras-buildsys/common
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv10743/common

Modified Files:
	HTTPServer.py 
Log Message:
2006-03-26  Dan Williams  <dcbw at redhat.com>

    * common/HTTPServer.py
        - Add ability to process HTTP POST requests, mostly for
            file uploads




Index: HTTPServer.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/HTTPServer.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- HTTPServer.py	12 Mar 2006 05:44:24 -0000	1.9
+++ HTTPServer.py	26 Mar 2006 18:52:56 -0000	1.10
@@ -27,6 +27,7 @@
 import socket
 from OpenSSL import SSL
 import DebugUtils
+import cgi
 
 
 class PlgHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
@@ -43,6 +44,21 @@
         except socket.timeout:
             pass
 
+    def do_POST(self):
+        handler = self._server.get_POST_handler(self.path)
+        if not handler:
+            self.send_error(404)
+            return
+
+        environ = {}
+        environ['REQUEST_METHOD'] = "POST"
+        fs = cgi.FieldStorage(fp=self.rfile, headers=self.headers, environ=environ)
+        try:
+            handler(self, fs)
+        except Exception, e:
+            self.send_error(500, "Error processing POST request: %s" % e)
+        del fs, environ
+            
     def list_directory(self, path):
         self.send_error(404, "No permission to list directory")
 
@@ -85,19 +101,36 @@
                 pass
 
 
-class PlgHTTPSServer(SSLCommon.PlgBaseSSLServer):
+class PlgHTTPPOSTHandler(object):
+    def __init__(self):
+        self._POST_handlers = {}
+
+    def set_POST_handler(self, location, handler):
+        if handler:
+            self._POST_handlers[location] = handler
+        else:
+            del self._POST_handlers[location]
+
+    def get_POST_handler(self, location):
+        if self._POST_handlers.has_key(location):
+            return self._POST_handlers[location]
+        return None
+
+class PlgHTTPSServer(SSLCommon.PlgBaseSSLServer, PlgHTTPPOSTHandler):
     def __init__(self, server_address, http_dir, certs):
         self.http_dir = http_dir
+        PlgHTTPPOSTHandler.__init__(self)
         SSLCommon.PlgBaseSSLServer.__init__(self, server_address, PlgHTTPRequestHandler, certs)
 
-class PlgHTTPServer(SSLCommon.PlgBaseServer):
+class PlgHTTPServer(SSLCommon.PlgBaseServer, PlgHTTPPOSTHandler):
     def __init__(self, server_address, http_dir):
         self.http_dir = http_dir
+        PlgHTTPPOSTHandler.__init__(self)
         SSLCommon.PlgBaseServer.__init__(self, server_address, PlgHTTPRequestHandler)
 
 
 class PlgHTTPServerManager(threading.Thread):
-    def __init__(self, addr, http_dir, certs):
+    def __init__(self, addr, http_dir, certs=None):
         if certs and len(certs) > 0:
             self._server = PlgHTTPSServer(addr, http_dir, certs)
         else:
@@ -106,6 +139,12 @@
         threading.Thread.__init__(self)
         self.setName("PlgHTTPServerManager: %s/%s" % (addr, http_dir))
 
+    def set_POST_handler(self, location, handler):
+        self._server.set_POST_handler(location, handler)
+
+    def get_POST_handler(self, location):
+        return self._server.get_POST_handler(location)
+
     def run(self):
         DebugUtils.registerThreadName(self)
         self._server.serve_forever()
@@ -123,6 +162,48 @@
 # Testing stuff
 ###########################################################
 
+""" Use this HTML:
+<html><body>
+<FORM ENCTYPE="multipart/form-data" ACTION="http://localhost:8886/upload" METHOD="POST">
+File to process: <INPUT NAME="filedata" TYPE="file">
+<INPUT TYPE="text" NAME="jobid">
+<input type="text" NAME="arch">
+<INPUT TYPE="submit" VALUE="Send File">
+</FORM>
+</body></html>
+"""
+
+def upload_callback(request_handler, fs):
+    # Search for filename
+    fslist = [fs]
+    if not fs.name and not fs.filename and fs.value:
+        fslist = fs.value
+    jobid = arch = filename = tmpfile = None
+    for item in fslist:
+        if item.name == 'jobid':
+            try:
+                jobid = int(item.value)
+            except ValueError:
+                pass
+        elif item.name == 'arch':
+            arch = item.value
+        elif item.name == 'filedata':
+            filename = item.filename
+            tmpfile = item.file
+
+    if jobid and arch and filename and tmpfile:
+        import shutil
+        dest = file("/tmp/%s" % filename, "w+b")
+        print dest, tmpfile
+        shutil.copyfileobj(tmpfile, dest)
+        dest.close()
+        request_handler.send_response(200, "Success")
+        request_handler.send_header("Content-type", "text/html")
+        request_handler.end_headers()
+        request_handler.wfile.write("<html><body>Success!</body></html>")
+    else:
+        request_handler.send_error(400, "Invalid request for %s" % request_handler.path)
+
 if __name__ == '__main__':
     if len(sys.argv) < 4:
         print "Usage: python HTTPServer.py key_and_cert ca_cert peer_ca_cert"
@@ -154,6 +235,7 @@
 
     print "Starting the server."
     server = PlgHTTPServerManager(('localhost', 8886), srcdir, certs)
+    server.set_POST_handler('/upload', upload_callback)
     server.start()
 
     while True:




More information about the fedora-extras-commits mailing list