''' Revised from the code segments: http://stackoverflow.com/questions/23264569/python-3-x-basehttpserver-or-http-server and https://wiki.python.org/moin/BaseHttpServer#Official_Documentation Xiannong Meng 2015-09-12 Revised 2018-03-29 for CSCI 305 ''' from http.server import BaseHTTPRequestHandler, HTTPServer import urllib import time import os HOST_NAME = "localhost" #HOST_NAME = "dana213-lnx-5" #HOST_NAME = "polaris" #HOST_NAME = "brki164-lnx-20" # any real host name where the server is running HOST_PORT = 9000 # 1024 < port < 65536 server_name = "Python Server" default_page = "Invalid file." + \ "

You requested an invalid file.

" + \ "" class MyServer(BaseHTTPRequestHandler): def do_HEAD(self): """ Return an HTML header if the client requests head only """ print("in do_HEAD"); okay = self.check_file(self.path) if okay == True: self.send_response(200) # good file else: self.send_response(404) # bad file, we lump all codes for now cont_type = self.check_type(self.path) self.send_header("Server", server_name) self.send_header("Content-Type", cont_type) self.end_headers() def do_GET(self): """ Return the page requested by the client. """ print("in do_GET"); if (self.path == "/search"): # send form, set up the search box length = self.find_file_length("/form.html") self.send_my_head(200, length, "text/html") self.send_file("/form.html") return okay = self.check_file(self.path) if okay == True: cont_type = self.check_type(self.path) length = self.find_file_length(self.path) self.send_my_head(200, length, cont_type) self.send_file(self.path) # actually sending the file else: self.send_my_head(404, len(default_page), "text/html") self.wfile.write(bytes(default_page, "utf-8")) def do_POST(self): """ Process the form posted by the client """ length = int(self.headers['Content-Length']) post_data = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8')) # You now have a dictionary of the post data print("post data: ", post_data) # now you have a dictionary of post data ret_data = self.build_data(post_data) # print the returning data print("returning data: ", ret_data) print("returning data length: ", len(ret_data)) self.send_my_head(200, len(ret_data), "text/html") self.wfile.write(bytes(ret_data,"utf-8")) self.wfile.write(bytes("Lorem Ipsum","utf-8")) def send_my_head(self, response_code, length, data_type): """ Send HTTP header """ self.send_response(response_code) self.send_header("Server", server_name) self.send_header("Content-Length", length) self.send_header("Content-Type", data_type) self.end_headers() def build_data(self, post_data): """ The post_data is in the form of {'key1': ['val1'], 'key2': ['val2'], 'key3': ['val3']} e.g., {'SecondInput': ['zx z'], 'FirstInput': ['124'], 'Submit': ['Submit']} """ ret_str = "" for k in post_data: ret_str = ret_str + "key : " + str(k) + \ "\ndata : " + str(post_data[k]) + "\n" ret_str = ret_str + "\n" return ret_str def find_file_length(self, path): """ Compute and return the length of the file. """ first = path.find("/") if first != 0: # invalid file name return 0 # now we know the '/' leads the path, remove it path = path[1:] length = os.path.getsize(path) return length def check_file(self, path): """ Check to see if file or path exists. (for now, we only deal with files, need to handle directories """ first = path.find("/") if first != 0: return False # when we handle directory, this needs change # now we know the '/' leads the path, remove it path = path[1:] okay = False try: okay = os.path.exists(path) except OSError: pass return okay def send_file(self, path): """ Read and send the file requested by the client. """ f = None data = None path = path[1:] try: f = open(path, "rb") data = f.read() f.close() self.wfile.write(bytes(data)) except OSError: pass def check_type(self, path): """ Return the type of the file using some ad-hoc approach. """ file_type = "text/html" # default if path.endswith(".jpg") or \ path.endswith(".jpeg"): file_type = "image/jpeg" # jpeg image elif path.endswith(".png"): file_type = "image/png" # png image elif path.endswith(".js"): file_type = "text/javascript" # javascript return file_type if __name__ == '__main__': httpd = HTTPServer((HOST_NAME, HOST_PORT), MyServer) print(time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, HOST_PORT)) try: httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close() print(time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, HOST_PORT))