I've built a simple web server that gets a request and send a response. So when the server gets an invalid request, like "localhost/not-a-page", the server will send a response with the content of the HTML file "404.html" the webpage should display an image. So far, so good.
But when the 404 page loads up, the page can't find the image. The HTML part is correct and works offline. I've tried to move the image to serval locations, relative to the Python script, relative to the HTML. But it just can't find it. Hi I'm trying to make the server as low-level as I can, I want to learn how servers work. So I'm not using any server-related libraries. I'm using only the socket library of Python.
I'll appreciate any help to resolve this problem without using other libraries,
EDIT Here is the relevant Python part :
import socket
import threading
import os
default_error_page = """\
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Error response</title>
</head>
<body>
<center>
<h1>Response</h1>
<p>Error code: %(code)d</p>
<p>Message: %(status)s.</p>
</center>
</body>
</html>
"""
default_header_status = "HTTP/1.1 %(code)d %(status)s\r\n"
default_header_content_type = "Content-Type: text/html; charset=utf-8\r\n\r\n"
buffer_size = 1024
def get_page(code):
page = default_error_page
if code == 200:
pass
else:
file = open(os.path.dirname(__file__) + "/www/not-found.html", 'r')
page = file.read()
return page
class BaseServer:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_name = ""
host_name = ""
host_port = 8000 # default port
is_shutdown = False
def __init__(self, name):
self.server_name = name
def start_server(self):
thread = threading.Thread(target=self.run_server(), name=self.server_name)
thread.start()
def run_server(self):
self.server_socket.bind((self.host_name, self.host_port)) # bind to host
self.server_socket.listen()
while not self.is_shutdown:
conn, addr = self.server_socket.accept()
self.handle_request(conn, addr)
def handle_request(self, connection, address):
print(str(address[0]) + " Connected! (port " + str(address[1]) + ")")
result = self.parse_request(connection.recv(buffer_size))
if result == 0:
page = self.parse_response(200)
else:
page = self.parse_response(404)
connection.sendall(bytes(page))
def parse_request(self, data):
if len(data) == 0:
return
strings = str(bytes(data).decode('utf-8')).split('\r\n')
command, path, version = strings[0].split()
print("command - " + command)
print("path - " + path)
print("version - " + version)
status = 1
if path == "/":
status = 0
return status
def parse_response(self, code):
status = "ERROR"
if code == 200:
status = "OK"
elif code == 404:
status = "NOT FOUND"
base_header = (default_header_status % {'code': code, 'status': status})
base_content_type = default_header_content_type
# page = (default_error_page % {'code': code, 'status': status})
page = str(get_page(code))
return_string = str(base_header + base_content_type + page).encode('utf-8')
print(return_string)
return return_string
def main():
server = BaseServer("Home Server")
server.start_server()
if __name__ == "__main__":
main()
And this is the HTML:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/style/main.css"/>
<style>
*{
padding:0;
margin:0;
}
body{
background-color:#ffe6b3;
}
h1{
margin-top:30px;
background-color:#ffcc66;
font-size:3em;
display:inline-block;
color:#3a0000;
}
p{
margin-top:80px;
font-size:2em;
color:#3a0000;
}
#img404{
background-image:url(../images/404.gif);
width:100%;
height:50%;
background-repeat:no-repeat;
background-position:center 20%;
}
</style>
</head>
<body>
<center>
<div class=top>
<h1>ERROR 404</h1>
</div>
<p>
Sorry, we could not find the page :(
</p>
<div id="img404">
</div>
</center>
</body>
</html>
Sorry if it's not very readable, but I'm on the phone.
Dima.
Figured out my problem. After I saw the logs, I realized that the browser sends another request, for the image. And silly me, my code is:
if path ="/":
status = 0
else:
status = 1
So for every request which is not root("/") the server will return 404.
Oops