-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathS.py
More file actions
135 lines (110 loc) · 4.77 KB
/
Copy pathS.py
File metadata and controls
135 lines (110 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import socket
import signal # Allow socket destruction on Ctrl+C
import sys
import time
import threading
class WebServer(object):
"""
Class for describing simple HTTP server objects
"""
def __init__(self, port=8080):
self.host = socket.gethostname().split('.')[0] # Default to any avialable network interface
self.port = port
self.content_dir = 'web' # Directory where webpage files are stored
def start(self):
"""
Attempts to create and bind a socket to launch the server
"""
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("Starting server on {host}:{port}".format(host=self.host, port=self.port))
self.socket.bind((self.host, self.port))
print("Server started on port {port}.".format(port=self.port))
except Exception as e:
print("Error: Could not bind to port {port}".format(port=self.port))
self.shutdown()
sys.exit(1)
self._listen() # Start listening for connections
def shutdown(self):
"""
Shuts down the server
"""
try:
print("Shutting down server")
s.socket.shutdown(socket.SHUT_RDWR)
except Exception as e:
pass # Pass if socket is already closed
def _generate_headers(self, response_code):
"""
Generate HTTP response headers.
Parameters:
- response_code: HTTP response code to add to the header. 200 and 404 supported
Returns:
A formatted HTTP header for the given response_code
"""
header = ''
if response_code == 200:
header += 'HTTP/1.1 200 OK\n'
elif response_code == 404:
header += 'HTTP/1.1 404 Not Found\n'
time_now = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
header += 'Date: {now}\n'.format(now=time_now)
header += 'Server: Simple-Python-Server\n'
header += 'Connection: close\n\n' # Signal that connection will be closed after completing the request
return header
def _listen(self):
"""
Listens on self.port for any incoming connections
"""
self.socket.listen(5)
while True:
(client, address) = self.socket.accept()
client.settimeout(60)
print("Recieved connection from {addr}".format(addr=address))
threading.Thread(target=self._handle_client, args=(client, address)).start()
def _handle_client(self, client, address):
"""
Main loop for handling connecting clients and serving files from content_dir
Parameters:
- client: socket client from accept()
- address: socket address from accept()
"""
PACKET_SIZE = 1024
while True:
print("CLIENT",client)
data = client.recv(PACKET_SIZE).decode() # Recieve data packet from client and decode
if not data: break
request_method = data.split(' ')[0]
print("Method: {m}".format(m=request_method))
print("Request Body: {b}".format(b=data))
if request_method == "GET" or request_method == "HEAD":
# Ex) "GET /index.html" split on space
file_requested = data.split(' ')[1]
# If get has parameters ('?'), ignore them
file_requested = file_requested.split('?')[0]
if file_requested == "/":
file_requested = "/index.html"
filepath_to_serve = self.content_dir + file_requested
print("Serving web page [{fp}]".format(fp=filepath_to_serve))
# Load and Serve files content
try:
f = open(filepath_to_serve, 'rb')
if request_method == "GET": # Read only for GET
response_data = f.read()
f.close()
response_header = self._generate_headers(200)
except Exception as e:
print("File not found. Serving 404 page.")
response_header = self._generate_headers(404)
if request_method == "GET": # Temporary 404 Response Page
response_data = b"<html><body><center><h1>Error 404: File not found</h1></center><p>Head back to <a href="/">dry land</a>.</p></body></html>"
response = response_header.encode()
if request_method == "GET":
response += response_data
client.send(response)
client.close()
break
else:
print("Unknown HTTP request method {method}".format(method=request_method))
server = WebServer(8080)
server.start()