preface
I recently read How Tomcat Works in Depth and found it easy to read, and every single one
Chapter 1 explains the principle of Tomcat step by step. In the following chapters, Tomcat is improved based on the new functions in chapter 1.
The result is a simplified version of Tomcat. So if you are interested, please read it in order. This article is to record the knowledge points of chapter 1
And source code implementation (make wheels).
Copy the code
How to implement
HTTP protocol is our Web server and browser interaction protocol, the specific knowledge and background of this article will not be too tired to describe. A simple example would be:
- Enter http://www.baidu.com in your browser and press Enter.
- The browser probably sent the following HTTP request to Baidu’s server:
GET/index. HTTP / 1.1 HTML
Host: www.baidu.com
.
Copy the code
- When baidu Web server receives our request, it finds the corresponding server resources and accordingly:
HTTP / 1.1 200 OK
.
<html>
<head>
<title>Google it and you'll see</title>
</head>
<body>
.
</body>
</html>
Copy the code
The static (HTML/images/CSS, etc.)web server implementation is also relatively simple:
Code implementation
Use Java heresocketThe API implements a simple static Web server.
Copy the code
- Create a new main method with the following core pseudocode:
// Enable socket Server 8080 port listening.
ServerSocket server = new ServerSocket(8080.1, InetAddress.getByName("127.0.0.1"));
try (Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
OutputStream outputStream = accept.getOutputStream()) {
// Parse the user's request
Request request = new Request();
request.setRequestStream(inputStream);
request.parseRequest();
// Generate a response object and respond to a static resource
Response resp = new Response(outputStream, request);
resp.accessStaticResources();
} catch (IOException e) {
LOGGER.warn("catch from user request.",e);
}
// Shut down the server
serverSocket.close();
Copy the code
-
The Request object
Main function: the user request (socketInputStream) parses to a string, extracting the URI in the request
Copy the code
Parse the string as follows:
StringBuilder requestStr = new StringBuilder();
int i;
// New a byte buffer array
byte[] buffer = ArrayUtil.generatorCache();
try {
i = inputStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
i = -1;
}
// Convert read byte to String
for (int j = 0; j < i; j++) {
requestStr.append((char) buffer[j]);
}
// Parse the request string to extract the request URI
this.parseURI(requestStr.toString());
Copy the code
Now that the requested information is parsed into a string, how do we know what static resource it wants to request?
Let’s print the parse string:
System.out.println(requestStr.toString());
Copy the code
GET /index.html HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive cache-control: max-age=0 user-agent: Mozilla / 5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36 upgrade-insecure -Requests: 1 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh; Q = 0.9
You can obviously see that the area in bold is the URI we want to extract, so how do we extract it? /index. HTML has a space before and after the string. IndexOf (String indexOf);
// Get the space index before /index.html
int oneSpace = requestStr.indexOf("");
// Get the space index after /index.html
int twoSpace = requestStr.indexOf("", oneSpace + 1);
// Intercepts the user request URI
uri = requestStr.substring(oneSpace + 1, twoSpace);
Copy the code
-
The Response object
The above Request object has resolved the resource that the user wants to Request, so the function of Response is to find the file,
Using Socket outputStream to output the file as a byte stream to the browser, we can display our HTML to the user
Copy the codeSo where do we put our static files for this project? Take a look at our project structure:
-main
- Java Java code
-resources
-webroot the folder where our static resources are stored
Copy the code
Since we only use MAVEN to build the project and we do not use Spring or other frameworks, how do we locate the webroot folder? Refer to the code on the Internet:
String WEB_PROJECT_ROOT = HttpServer.class.getClassLoader().getResource("webroot").getFile().substring(1);
Copy the code
The previous doubts are solved, next we will directly find the corresponding file to write back to the end of the ~ pseudo-code is as follows:
// Find the requested resource file according to the request URI
File staticResource = new File(HttpServer.WEB_PROJECT_ROOT + request.getUri());
// The resource exists
if (staticResource.exists() && staticResource.isFile()) {
outputStream.write(this.responseToByte(200."OK"));
write(staticResource);
// The resource does not exist. Use the default 404
} else {
staticResource = new File(HttpServer.WEB_PROJECT_ROOT + "/404.html");
outputStream.write(this.responseToByte(404."file not found"));
write(staticResource);
}
Copy the code
The responseToByte() method is only responsible for printing the response line:
HTTP / 1.1 200 OK
Copy the code
If the resource does not exist, we print:
HTTP/1.1 404 file not found
Copy the code
The write() method is also simple, turning an incoming file object into a stream and using the socket’s outputStream output
try (FileInputStream fis = new FileInputStream(file)) {
byte[] cache = new byte[1024];
int read;
while ((read = fis.read(cache, 0.1024)) != -1) {
outputStream.write(cache, 0, read);
}
}
Copy the code
See the effect
Run the main method, open our browser and output 127.0.0.1/index.html, press Enter, you can see the result as shown:
Try entering a resource that does not exist:
Press F12 to see what the Http request and response look like:
Request:
GET/ABC. HTTP / 1.1 HTML
Host: 127.0.0.1:8080
Other headers ignore...
Response:
HTTP/1.1 404 file not found
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 not found! </title>
</head>
<body>
<h1> Request page does not exist! </h1>
</body>
</html>
Copy the code
By now, Tomcat 1.0 web server has been developed. It can implement simple HTML, CSS, images and other resources access functions. In the next chapter, we will implement the following simple Servlet container function development:
Implement Tomcat part 2 with me: Implement a simple Servlet container
PS: The source of this chapter has been uploaded to Github SimpleTomcat