patternpythonMinor
Python HTTP Server
Viewed 0 times
serverhttppython
Problem
This is one of my first times writing Python. I'm most curious about style and whether
```
#!/usr/bin/pythonw
import socket
import os
class Server:
def __init__(self, directory, host="", port=8123):
print("Server running on port ", port)
self.directory = directory
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind((host, port))
serversocket.listen(5)
while 1:
connection, address = serversocket.accept()
print("Connection received")
socketfile = connection.makefile("rw")
request = socketfile.readline()
print(request)
url = self.getURL(request)
print("Serving ", url)
responseBody = None
responseCode = 200
try:
with open(url, "rb") as requestedFile:
responseBody = requestedFile.read()
except FileNotFoundError:
print("Error 404: File not found")
responseBody = b"404 Error Not Found"
responseCode = 404
connection.sendall(self.writeResponse(url, responseCode, responseBody))
socketfile.close()
connection.close()
print("Connection closed\n")
def writeResponse(self, url, code, body):
response = "HTTP/1.1 " + ("200\n" if code is 200 else "404\n")
response = response + "Cache-Control: no-cache, no-store, must-revalidate\n"
response = response + "Pragma: no-cache\n"
response = response + "Expires: 0\n"
response = response + "Connection: close\n"
if code is 200:
response = response + "Content-Length: " + str(os.path.getsize(url)) + "\n"
if ".css" in url:
response = response + "Content-Type: text/css; charset=UTF-8\n"
elif ".js" in url:
response = response + "Content-Type: application/javascript charset=UTF-8\n"
response = response + "\n"
return str.encode(response) +
while 1: x,y = socket.accept() is an acceptable way to wait for new connections.```
#!/usr/bin/pythonw
import socket
import os
class Server:
def __init__(self, directory, host="", port=8123):
print("Server running on port ", port)
self.directory = directory
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind((host, port))
serversocket.listen(5)
while 1:
connection, address = serversocket.accept()
print("Connection received")
socketfile = connection.makefile("rw")
request = socketfile.readline()
print(request)
url = self.getURL(request)
print("Serving ", url)
responseBody = None
responseCode = 200
try:
with open(url, "rb") as requestedFile:
responseBody = requestedFile.read()
except FileNotFoundError:
print("Error 404: File not found")
responseBody = b"404 Error Not Found"
responseCode = 404
connection.sendall(self.writeResponse(url, responseCode, responseBody))
socketfile.close()
connection.close()
print("Connection closed\n")
def writeResponse(self, url, code, body):
response = "HTTP/1.1 " + ("200\n" if code is 200 else "404\n")
response = response + "Cache-Control: no-cache, no-store, must-revalidate\n"
response = response + "Pragma: no-cache\n"
response = response + "Expires: 0\n"
response = response + "Connection: close\n"
if code is 200:
response = response + "Content-Length: " + str(os.path.getsize(url)) + "\n"
if ".css" in url:
response = response + "Content-Type: text/css; charset=UTF-8\n"
elif ".js" in url:
response = response + "Content-Type: application/javascript charset=UTF-8\n"
response = response + "\n"
return str.encode(response) +
Solution
Instead of
Python has an official style guide called PEP8. I suggest to give that a good read and follow the recommendations, especially in terms of indentation and naming rules.
Inside the
This variable is reassigned later, no need to initialize it.
It's never a good idea to do much in a constructor.
Instead of starting a server to accept connections in the constructor,
I suggest to move that logic to a method.
Everywhere you write
These conditions seem a bit weak:
Are you sure that
while 1:, it would be more natural to write while True:Python has an official style guide called PEP8. I suggest to give that a good read and follow the recommendations, especially in terms of indentation and naming rules.
Inside the
Server constructor you have a pointless assignment:responseBody = NoneThis variable is reassigned later, no need to initialize it.
It's never a good idea to do much in a constructor.
Instead of starting a server to accept connections in the constructor,
I suggest to move that logic to a method.
Everywhere you write
x = x + something, a shorter (and recommended) way is to write x += something.These conditions seem a bit weak:
if ".css" in url:
# ...
elif ".js" in url:
# ...Are you sure that
.css or .js won't appear at unexpected places inside the url? If you expect these to be at the end, it would be better to use the more strict conditions:if url.endswith(".css"):
# ...
elif url.endswith(".js"):
# ...Code Snippets
responseBody = Noneif ".css" in url:
# ...
elif ".js" in url:
# ...if url.endswith(".css"):
# ...
elif url.endswith(".js"):
# ...Context
StackExchange Code Review Q#120744, answer score: 4
Revisions (0)
No revisions yet.