DIY-Tomcat项目 part 1 实现和测试Request以及Response

发布于:2024-11-29 ⋅ 阅读:(31) ⋅ 点赞:(0)

实现Request

package Webserver.src.connector;

import java.io.IOException;
import java.io.InputStream;

/*
GET /index.html HTTP/1.1
        Host: localhost:8888
        Connection: keep-alive
        Cache-Control: max-age=0
        Upgrade-Insecure-Requests: 1
        User-Agent: Mozilla/5.0
*/

public class Request {
    private static final int BUFFER_SIZE = 1024;

    private InputStream input;
    private String uri;

    public Request(InputStream input) {
        this.input = input;
    }

    public String getRequestURI() {
        return uri;
    }

    public void parse() {
        int length = 0;
        byte[] buffer = new byte[BUFFER_SIZE];
        try {
            length = input.read(buffer);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        StringBuilder request = new StringBuilder();
        for (int i = 0; i < length; i ++) {
            request.append((char)buffer[i]);
        }
        uri = parseUri(request.toString());
    }

    private String parseUri(String s) {
        int index1, index2;
        index1 = s.indexOf(' ');
        if (index1 != -1) {
            index2 = s.indexOf(' ', index1 + 1);
            if (index2 > index1) {
                return s.substring(index1 + 1, index2);
            }
        }
        return "";
    }
}

代码解释

  • parseUri是找出传入的HTTP请求头中的请求的文件地址uri
  • parse是将输入流中的HTTP请求复制到buffer中,再将buffer中的请求分段读入到StringBuilder request中,再通过 parseUri获得请求头中的uri

测试Request

文件一:D:\Java\Webserver\src\test\util\TestUtils.java

package Webserver.src.test.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

import Webserver.src.connector.Request;

public class TestUtils {
    
    public static Request crreatRequest(String requestStr) {
        InputStream input = new ByteArrayInputStream(requestStr.getBytes());
        Request request = new Request(input);
        request.parse();
        return request;
    }

    public static String readFileTOString(String filename) throws IOException {
        return new String(Files.readAllBytes(Paths.get(filename)));
    }
}

文件二:

package Webserver.src.test.connector;

import Webserver.src.connector.Request;
import Webserver.src.test.util.TestUtils;

public class RequestTest {
    
    private static final String validRequest = "GET /index.html HTTP/1.1";

    public void givenValidRequest_thenExtrackUri() {
        Request request = TestUtils.crreatRequest(validRequest);
        System.out.println(request.getRequestURI());
    }

    public static void main(String[] args) {
        RequestTest test = new RequestTest();
        test.givenValidRequest_thenExtrackUri();
    }
}

测试结果

在这里插入图片描述
成功打印请求中的uri

实现Response

代码实现

文件一:D:\Java\Webserver\src\connector\HttpStatus.java

package Webserver.src.connector;

public enum HttpStatus {
    SC_OK(200, "OK"),
    SC_NOT_FOUND(404, "File Not Found");

    private int statusCode;
    private String reason;

    HttpStatus(int code, String reason) {
        this.statusCode = code;
        this.reason = reason;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public String getReason() {
        return reason;
    }
}

  • 枚举了两种HTTP状态码及其错误原因 - 200和404便于其他文件引用

文件二:D:\Java\Webserver\src\connector\Request.java

package Webserver.src.connector;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

/*
HTTP/1.1 200 OK
 */

public class Response {
    
    private static final int BUFFER_SIZE = 1024;

    Request request;
    OutputStream output;

    public Response(OutputStream output) {
        this.output = output;
    }

    public void setRequest(Request request) {
        this.request = request;
    }

    public void sendStaticResource() throws IOException {
        File file = new File(ConnectorUtils.WEB_ROOT, request.getRequestURI());
        try {
            write(file, HttpStatus.SC_OK);
        } catch (IOException e) {
            write(new File(ConnectorUtils.WEB_ROOT, "/404.html"), HttpStatus.SC_NOT_FOUND);
        }
    }

    private void write(File resource, HttpStatus status) throws IOException {
        try (FileInputStream fis = new FileInputStream(resource)) {
            output.write(ConnectorUtils.renderStatus(status).getBytes());
            byte[] buffer = new byte[BUFFER_SIZE];
            int length = 0;
            while ((length = fis.read(buffer, 0, BUFFER_SIZE)) != -1) {
                output.write(buffer, 0, length);
            }
        }
    }
}
  • 将Response与相应的Request绑定,以获得请求头中的请求
  • 创建File文件,并指向对应路径下的静态文件
  • 通过write函数将对应静态文件中的内容和相应的HTTP状态码输出到输出流中

测试Response

文件一:
D:\Java\Webserver\webroot\404.html

<!DOCTYPE html>
<html lang="en">
<h1>File not found</h1>
</html>

D:\Java\Webserver\webroot\index.html

<!DOCTYPE html>
<html lang="en">
<h1>Good Good Study</h1>
<body>
<img src="images/imooc.jpg"/>
</body>
</html>

文件二:D:\Java\Webserver\src\test\connector\ResponseTest.java

package Webserver.src.test.connector;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import Webserver.src.connector.ConnectorUtils;
import Webserver.src.connector.Request;
import Webserver.src.connector.Response;
import Webserver.src.test.util.TestUtils;

public class ResponseTest {
    private static final String validRequest = "GET /index.html HTTP/1.1";
    private static final String InvalidRequest = "GET /noexist.html HTTP/1.1";

    public void givenValidRequest_thenReturnStaticResource() throws IOException {
        Request request = TestUtils.crreatRequest(validRequest);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        Response response = new Response(output);
        response.setRequest(request);
        response.sendStaticResource();

        String resource = TestUtils.readFileTOString(ConnectorUtils.WEB_ROOT + request.getRequestURI());
        System.out.println(resource);
        System.out.println(output.toString());
    }

    public void givenInvalidRequest_thenReturnError() throws IOException {
        Request request = TestUtils.crreatRequest(InvalidRequest);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        Response response = new Response(output);
        response.setRequest(request);
        response.sendStaticResource();

        String resource = TestUtils.readFileTOString(ConnectorUtils.WEB_ROOT + "/404.html");
        System.out.println(resource);
        System.out.println(output.toString());
    }
}
  • 分别对两个HTTP请求做测试,一个是有效的请求,一个是无效的请求
  • 通过输出resource和输出流中的内容判断测试是否成功

validRequest 测试

    public static void main(String[] args) {
        ResponseTest responseTest = new ResponseTest();
        try {
            responseTest.givenValidRequest_thenReturnStaticResource();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

测试结果

在这里插入图片描述

  • resource和输出流output成果打印出相应的内容

InvalidRequest 测试

    public static void main(String[] args) {
        ResponseTest responseTest = new ResponseTest();
        try {
            responseTest.givenInvalidRequest_thenReturnError();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

测试结果

在这里插入图片描述

  • resource成功打印出了404.html中的内容
  • 输出流output也成功返回了相应的响应头以及404.html中的内容

网站公告

今日签到

点亮在社区的每一天
去签到