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,
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 ,
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 ….
This is the data send through header when it request image file.
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()
Great work Rasad Keep it up mchn
LikeLiked by 1 person
Thank you very much brother…
LikeLike
Really helpful.keep it up bro!!
LikeLiked by 1 person
Thank you…
LikeLike
Really helpful!!keep it up bro!!
LikeLiked by 1 person
Thank you
LikeLike
really helpful!! Keep it up bro !!
LikeLiked by 1 person
Thank you
LikeLike
well done machan.superb !!!
LikeLike
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!
LikeLike
Really helpful for my assignment of creating a python server. Thank you.
LikeLike
tysm helped a lot
LikeLike
Helpful, thank you
LikeLike