How create HTTP-Server using python Socket – Part II

How create HTTP-Server using python Socket – Part II

Hi guys, today i am going to show you hove add some extra features to our simple HTTP-Sever created using python socket module. So if you have no idea what is it please refer my previous blog post.

Previous post I describe you how send string as response. Here i will explain how send file. Yeh ! .html , .css , .jpg , .png and .js files can send. Again i want to say if you have no idea about this please first read this post.

First we should identify which file is client request. Then we can check whether its available in our container or not. If file exist we can send it and if not we should send error message saying file not exist.

while True:
    connection,address = my_socket.accept()
    req = connection.recv(1024).decode('utf-8')
    print(req) # Get print in our python console.

Previous post i describe how view client request using this. It gives us,

blog2

According to this request, it request ‘ / ‘ or root file.It may be ‘/home.html’,’/my_image.png’ or something. First how get this requesting file as separate value. Can you see this request can divide from spaces(‘ ‘) and our requesting file should be the second value of given list.

#socket creation and other functions done here (see previous post)
while True:
   connection,address = my_socket.accept()
   request = connection.recv(1024).decode('utf-8')
   string_list = request.split(' ')     # Split request from spaces

   method = string_list[0] # First string is a method
   requesting_file = string_list[1] #Second string is request file

   print('Client request ',requesting_file)

   connection.close()

This code will give this ,

blog3

OK , now we can get what file we want as well as which method. If we want to give some conditions according to request method, you have to put if condition. But I don’t want this kind of condition in here.

You know sometimes request came like this,

http://www.sample.com/myfile?er=’234′

this get request comes with data, but we don’t want data in here. Then i split it from ‘ ? ‘.

    myfile = requesting_file.split('?')[0] # After the "?" symbol not relevent here       
    
    myfile = myfile.lstrip('/')
    if(myfile == '/'):
        myfile = 'index.html'    # Load index file as default

hey! , I used lstrip() to remove ‘ / ‘ from file name. And when i get a request calling ‘ / ‘, I want to serve index.html file. Therefore i assign index.html as myfile.

Now we have file name.We have to read file. To do that we use try-catch to handle exception.

        try:
            file = open(myfile,'rb') # open file , r => read , b => byte format
            response = file.read()
            file.close()

            header = 'HTTP/1.1 200 OK\n'

            if(myfile.endswith(".jpg")):
                mimetype = 'image/jpg'
            elif(myfile.endswith(".css")):
                mimetype = 'text/css'
            else:
                mimetype = 'text/html'

            header += 'Content-Type: '+str(mimetype)+'<strong>\n\n</strong>'

        except Exception as e:
            header = 'HTTP/1.1 404 Not Found\n\n'
            response = '<html>
                          <body>
                            <center>
                             <h3>Error 404: File not found</h3>
                             <p>Python HTTP Server</p>
                            </center>
                          </body>
                        </html>'.encode('utf-8')
 

In here within try ,  open wanted file using python file open(file_name,open_type) function. Here we open file as ‘rb‘ type. Because we send file data as bytes. After that we read file and get content as response. Then closed the opened file.

When we get request it comes with some data as header. Like that when we send data to client we should send some header data. First thing is we should send response status. There are different status codes. If you want to know more about them read my this post.

In header we said which protocol and response message

'HTTP/1.1 200 OK\n'

At the end add new line character(‘\n’) to separate from other data. At the end of header data there should be two new lines(‘\n\n’). And we can send several data within header. As example here i send file type. It helps to browser to identify which type file comes. And if we want we can send server name (header += ‘Server: My-HTTP-server\n’), file sending time , connection type like that.

If file exist within try condition it will give header and content of file.

If file not exist , which means python file open unable to open file , then we can send error 404 (File not exist error), and default html content.

Most important thing is we can’t send string. We must convert string to UTF-8 character encoding type. That’s why i used encode(‘utf-8’).

Now we have header and content for both situations( if files exist or not). As previously did now we have to send this response to our client.

    final_response = header.encode('utf-8')
        final_response += response
        connection.send(final_response)
        connection.close()

Here response already come as byte code, because we read as byte. We convert our header to UTF-8 format and join both header and response to get final response. Now as we send our ‘Hello world’ to client, send final response. Then close the connection.

Wow… now we get this ….

blog4

This is the data send through header when it request image file.

blog5

So now you know how to create web server using python socket module with basic functionalities. You can improve these features by adding more error handlers and services.

Hope you learn something from these post. So share this with your friends and try to find new additions to this and comment if you have any suggestions or errors found to help others.

Here i give sample code we build through out the post.

import socket

HOST,PORT = '127.0.0.1',8082

my_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
my_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
my_socket.bind((HOST,PORT))
my_socket.listen(1)

print('Serving on port ',PORT)

while True:
    connection,address = my_socket.accept()
    request = connection.recv(1024).decode('utf-8')
    string_list = request.split(' ')     # Split request from spaces

    method = string_list[0]
    requesting_file = string_list[1]

    print('Client request ',requesting_file)

    myfile = requesting_file.split('?')[0] # After the "?" symbol not relevent here
    myfile = myfile.lstrip('/')
    if(myfile == ''):
        myfile = 'index.html'    # Load index file as default

    try:
        file = open(myfile,'rb') # open file , r => read , b => byte format
        response = file.read()
        file.close()

        header = 'HTTP/1.1 200 OK\n'

        if(myfile.endswith(".jpg")):
            mimetype = 'image/jpg'
        elif(myfile.endswith(".css")):
            mimetype = 'text/css'
        else:
            mimetype = 'text/html'

        header += 'Content-Type: '+str(mimetype)+'\n\n'

    except Exception as e:
        header = 'HTTP/1.1 404 Not Found\n\n'
        response = '<html><body><center><h3>Error 404: File not found</h3><p>Python HTTP Server</p></center></body></html>'.encode('utf-8')

    final_response = header.encode('utf-8')
    final_response += response
    connection.send(final_response)
    connection.close()

 

 

 

13 thoughts on “How create HTTP-Server using python Socket – Part II

  1. I reffered your two posts related to creating a server using python and it was really helpfull for me building my own server. Thank you very much!

    Like

Leave a comment