Image won't load on python-based webserver
Question: 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.


Answer: Don't use relative paths for image like `../images/img.gif`. Rather use full
url or url relative to the root.

  * <http://localhost/images/img.gif> \- full url
  * /images/img.gif - path relative to root url 

