Created
July 11, 2017 06:25
-
-
Save lofaldli/8901cd2a247f5ad91ef0865db2aeb5e1 to your computer and use it in GitHub Desktop.
r/dailyprogrammer challenge 7/7/17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import socket | |
| STATUS_CODES = { | |
| 200: 'ok', | |
| 400: 'bad request', | |
| 404: 'file not found', | |
| 500: 'internal server error' | |
| } | |
| MIME_TYPES = { | |
| 'html': 'text/html', | |
| 'css': 'text/css', | |
| 'js': 'text/javascript', | |
| 'txt': 'text/plain', | |
| 'gif': 'image/gif', | |
| 'jpg': 'image/jpeg', | |
| 'jpeg': 'image/jpeg', | |
| 'png': 'image/png', | |
| 'svg': 'image/svg+xml', | |
| } | |
| def read_file(path): | |
| # watch out hackers | |
| path = '.' + path | |
| path = path.replace('../', '') | |
| with open(path, 'r') as f: | |
| return f.read() | |
| def response(status_code, body=''): | |
| return str.encode('\r\n'.join([ | |
| 'HTTP/1.0 %d %s' % (status_code, STATUS_CODES[status_code]), | |
| '', | |
| body, | |
| ])) | |
| def parse_request(req): | |
| lines = req.decode().split('\r\n') | |
| method, uri, http_version = lines.pop(0).split(' ') | |
| params = {} | |
| while len(lines) > 0: | |
| line = lines.pop(0) | |
| if not line: | |
| break | |
| key, val = line.split(': ') | |
| params[key] = val | |
| body = '\n'.join(lines) | |
| print(method, uri, http_version) | |
| for k, v in params.items(): | |
| print('%s: %s' % (k, v)) | |
| print() | |
| if body: | |
| print(body) | |
| # load index.html as default | |
| if uri[-1] == '/': | |
| uri += '/index.html' | |
| if method == 'GET': | |
| try: | |
| body = read_file(uri) | |
| return response(200, body) | |
| except Exception as e: | |
| print(e) | |
| return response(404) | |
| else: | |
| return response(400) | |
| class Server: | |
| def __init__(self, addr='127.0.0.1', port=8080): | |
| self.addr = addr | |
| self.port = port | |
| self.sock = None | |
| def open(self): | |
| self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
| self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| self.sock.bind((self.addr, self.port)) | |
| def close(self): | |
| self.sock.close() | |
| self.sock = None | |
| def listen(self): | |
| self.sock.listen() | |
| conn, addr = self.sock.accept() | |
| req = conn.recv(1024) | |
| return req, conn | |
| def reply(self, conn, response): | |
| conn.send(bytes(response)) | |
| conn.close() | |
| def serve(self): | |
| if self.sock is None: | |
| self.open() | |
| while True: | |
| req, conn = self.listen() | |
| self.reply(conn, parse_request(req)) | |
| self.close() | |
| def main(): | |
| try: | |
| s = Server() | |
| s.serve() | |
| except KeyboardInterrupt: | |
| s.close() | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment