Chapter "Allow HTML files to be delivered" has been updated. ..
If you want to read more, please like the book or follow the author ;-)
The following is an excerpt of the contents of the book.
Up to the previous chapter, we were able to create a server that can return a response in HTTP format.
However, it doesn't implement any processing to interpret the request sent from the browser, so the body always returns It works!
No matter what request comes in.
This is not enough, so prepare an HTML file separately from the program source code in advance so that the file specified in the request path can be returned as the response body.
This is a so-called * static file distribution * function.
Since it is not necessary to publish the source code of the server through the server, ** put the files you want to publish through the server in the directory study / static /
**.
Example) Request path is /index.html
=> The contents of study / static / index.html
are returned as a response body
And so on.
I won't explain anything else, so let's go straight to the source code.
Here is an improved version that can return the HTML file prepared in advance as a response body.
study/WebServer.py
import os
import socket
from datetime import datetime
class WebServer:
"""
A class that represents a web server
"""
#Directory with executable files
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#Directory to put files for static distribution
DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")
def serve(self):
"""
Start the server
"""
print("===Start the server===")
try:
#Generate socket
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#Assign socket to localhost port 8080
server_socket.bind(("localhost", 8080))
server_socket.listen(10)
#Wait for a connection from the outside and establish a connection if there is a connection
print("===Wait for a connection from the client===")
(client_socket, address) = server_socket.accept()
print(f"===The connection with the client is complete remote_address: {address} ===")
#Get the data sent from the client
request = client_socket.recv(4096)
#Write the data sent from the client to a file
with open("server_recv.txt", "wb") as f:
f.write(request)
#The entire request
# 1.Request line(The first line)
# 2.Request body(2nd line-blank line)
# 3.Request body(Blank line~)
#Perth to
request_line, remain = request.split(b"\r\n", maxsplit=1)
request_headers, request_body = remain.split(b"\r\n\r\n", maxsplit=1)
#Parse the request line
method, path, http_version = request_line.decode().split(" ")
#At the beginning of path/And keep it as a relative path
relative_path = path.lstrip("/")
#Get the path of the file
static_file_path = os.path.join(self.DOCUMENT_ROOT, relative_path)
#Generate a response body from a file
with open(static_file_path, "r") as f:
response_body = f.read()
#Generate response line
response_line = "HTTP/1.1 200 OK\r\n"
#Generate response header
response_header = ""
response_header += f"Date: {datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')}\r\n"
response_header += "Host: HenaServer/0.1\r\n"
response_header += f"Content-Length: {len(response_body.encode())}\r\n"
response_header += "Connection: Close\r\n"
response_header += "Content-Type: text/html\r\n"
#Generate the entire response
response = (response_line + response_header + "\r\n" + response_body).encode()
#Send a response to the client
client_socket.send(response)
#End communication
client_socket.close()
finally:
print("===Stop the server.===")
if __name__ == '__main__':
server = WebServer()
server.serve()
https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter11/WebServer.py
Also, to check if the program is working properly, you need to prepare an HTML file separately, so create that as well.
Create a new static
directory directly under the study
directory and create index.html
in it.
Since it's a big deal, I changed it to something that is not Apache's puck. You can use whatever you like.
However, if you change the file name, it will not work as described in this manual, so leave the file name as index.html
.
study/static/index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>HenaServer</title>
</head>
<body>
<h1>Welcome to HenaServer!</h1>
</body>
</html>
https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter11/static/index.html
Defines the directory where the HTML files will be placed (called DOCUMENT_ROOT
).
#Directory with executable files
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#Directory to put files for static distribution
DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")
It may be difficult to read if you are not familiar with file paths in python,
--BASE_DIR
: study
absolute path to the directory
--DOCUMENT_ROOT
: study / static
directory absolute path
Is stored.
This is the main.
The HTTP request is parsed (decomposed) and the path information is extracted.
After that, the file is read based on the path and the response body is generated.
#The entire request
# 1.Request line(The first line)
# 2.Request body(2nd line-blank line)
# 3.Request body(Blank line~)
#Perth to
request_line, remain = request.split(b"\r\n", maxsplit=1)
request_headers, request_body = remain.split(b"\r\n\r\n", maxsplit=1)
#Parse the request line
method, path, http_version = request_line.decode().split(" ")
#At the beginning of path/And keep it as a relative path
relative_path = path.lstrip("/")
#Get the path of the file
static_file_path = os.path.join(self.DOCUMENT_ROOT, relative_path)
#Generate a response body from a file
with open(static_file_path, "r") as f:
response_body = f.read()
After getting the path, I combine it with DOCUMENT_ROOT
to get the static_file_path
, but note that I've removed the leading /
before that.
This is because, as a specification of os.path.join (base, path)
of python, if the absolute path starting with /
is given to the second argument path
, the first argument base
will be ignored. is.
If you know what you want to do, the source code is not difficult, so let's move it immediately.
Chapter "Allow HTML files to be delivered"
Recommended Posts