Skip to content

NintenSAGA/HTTP-Client-Server-for-Java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTTP Client/Server for Java

JDK Platform

由 Java Socket API 实现的简单 HTTP Client 与 Http Server

Info

开发日志: DevLog.md

测试用数据集: Data.zip

1. 概览

1.1 环境

本项目基于 JDK 17.0 编写,由 Maven 构造。

1.2 依赖

Scope GroupId ArtifactId Version
Provided org.projectlombok lombok 1.18.22
Compile org.json json 20220320
Test org.junit.jupiter junit-jupiter-engine 5.8.2

1.3 构建与运行

1.3.1 构建

  • HttpClient: mvn package -Pclient
  • HttpServer: mvn package -Pserver

1.3.2 运行

最终产品为 jar 文件,通过 java -jar [NAME].jar 运行。

2. 使用

2.1 外部文件

Data 及其子目录会在 HttpClient 或 HttpServer 启动时被自动创建于 jar 文件所在目录,结构如下:

Data
├── Client
│   └── Cache   // Client的缓存目录
└── Server
    ├── Cache   // Server的缓存目录(未使用)
    └── Static  // Server的静态文件存放目录

2.2 HttpServer

2.2.1 执行指令

java -jar /path/to/HttpServer.jar [OPTIONS]...

2.2.2 具体语法

SYNOPSIS
    ~   [-a <ADDRESS>] [-p <PORT>] [--keep-alive]
        [-t <TIMEOUT>] [--help]
        
OPTIONS
    --help          Show this help information.

    -a <ADDRESS>    Bind the server to the specified IPv4 address.
                    The default value is 127.0.0.1
    
    -p <PORT>       Bind the server to the specified port number.
                    The default value is 8080
                    
    --keep-alive    Enable keep-alive.
    
    -t <TIMEOUT>    Socket timeout.
                    The default value is 10000

2.2.3 启动信息

若运行正常,则会显示启动信息,包含:

  • Server 运行日志
  • 预设 URL Mapping 信息
  • 静态文件读取目录

如下所示:

SERVER: Preset mappings:
/register, methods: [POST]
/status, methods: [GET]
/login, methods: [GET]
/logout, methods: [GET]
/test, methods: [GET]
/missing, methods: [GET,POST]
/moved, methods: [GET]
SERVER: Server bound to /127.0.0.1:8080
SERVER: Reading static files from: [file:///.../Data/Server/Static]
SERVER: The server is now running

2.3 HttpClient

2.3.1 执行指令

java -jar /path/to/HttpClient.jar <URL> [OPTIONS]...

2.3.2 具体语法

SYNOPSIS
    ~   <URL>
        [-m <METHOD>] [--keep-alive] [-b <text>]
        [-h <headers>...] [--help]
        
URL
    Using the generic URI syntax of:
    http://<HOSTNAME>[:PORT][/PATH][?QUERY]
    e.g.: http://jyywiki.cn/OS/2020/, http://127.0.0.1:8080/help/, http://www.google.com/search?q=uri
    The default value of the port number is 80.
    Only support HTTP protocol (not HTTPS).
    
OPTIONS
    --help          Show this help information.

    -m <METHOD>     Send with the specified web method.
                    Only supports GET and POST.
                    The default value is GET.
                    
    --keep-alive    Enable keep-alive.
    
    -b <text>       Plain text body.
    
    -h <header>...  Send with the specified headers.
                    Syntax: <key>:<value>
                    e.g.: User-Agent:AbaAba/0.1

2.3.3 执行信息

若执行正常,则会显示

  • Client 执行日志
  • HTTP Request Message 原信息
  • HTTP Response Message 原信息

其中原信息包含:

  • Startline
  • Headers
  • Body
    • 若为 text/plain 则直接显示
    • 否则存储在缓存目录中,显示文件路径

如下所示:

/* 直接显示 Body 内容 */

CLIENT: Client has connect to the host
SOCKET[localhost127.0.0.1:8080]: Message sent 0.097656 KB

>> ==================== HTTP Request Message ==================== <<
>> GET /test HTTP/1.1
>> Accept: */*
>> User-Agent: Wget/1.21.3
>> Host: localhost
>> Accept-Encoding: gzip
>>
CLIENT: Status code received: 200
CLIENT: Handle returned directly...
CLIENT: Request complete

<< ==================== HTTP Response Message ==================== >>
<< HTTP/1.1 200 OK
<< date: Tue, 24 May 2022 03:54:16 GMT
<< server: nju_ic
<< content-encoding: gzip
<< connection: keep-alive
<< content-type: text/plain; charset=UTF-8
<<
<< You got the place!!!
/* 显示 Body 存储路径 */

>> ==================== HTTP Request Message ==================== <<
>> GET /OS/2022/ HTTP/1.1
>> Accept: */*
>> User-Agent: Wget/1.21.3
>> If-Modified-Since: Sun, 22 May 2022 11:13:51 GMT
>> Host: jyywiki.cn
>> Accept-Encoding: gzip
>>
CLIENT: Status code received: 200
CLIENT: Handle returned directly...
CLIENT: Request complete

<< ==================== HTTP Response Message ==================== >>
<< HTTP/1.1 200 OK
<< date: Tue, 24 May 2022 03:56:37 GMT
<< server: nginx/1.18.0 (Ubuntu)
<< content-encoding: gzip
<< content-type: text/html; charset=utf-8
<< connection: keep-alive
<< Content-Length: 16876
<<
<< Body saved at:
<< file:///.../Data/Client/Cache/jyywiki.cn/OS/2022/index/cache.html

3. 功能

HttpServer 与 HttpClient 均采用 Java NIO.2 模型进行开发,使用了 java.nio.channels.AsynchronousServerSocketChanneljava.nio.channels.AsynchronousSocketChannel 等类。

3.1 HttpServer

3.1.1 支持 GETPOST 请求

相关测试: LoginSystemTests

GET POST

3.1.2 支持以下状态码:

  • 200 OK

200

  • 301 Moved Permanently

301

  • 302 Found

302

  • 304 Not Modified

304

  • 404 Not Found

404

  • 405 Method Not Allowed

405

  • 500 Internal Server Error

500

  • 505 HTTP Version Not Supported

505

3.1.3 支持长连接 (Keep-Alive)

相关测试:KeepAliveTest

Keep-Alive

3.1.4 支持MIME类型:

已测试过的全部类型: mime.json

理论支持任意文件传输

  • HTML: text/html

HTML

  • png: image/png

PNG

  • mp4: video/mp4

MP4

  • svg: image/svg+xml

SVG

3.1.5 支持注册、登录、状态保持系统

相关测试: LoginSystemTests

  1. 用户注册

loginsys_1

  1. 检查登录状态

loginsys_2

  1. 登出

loginsys_3

  1. 检查登录状态

loginsys_4

  1. 登录

loginsys_5

3.2 HttpClient

3.2.1 在CLI界面显示 Http Request&Response Message

相关测试:WANTest

client_cli

3.2.2 对 Status code 301, 302, 304 的处理

相关测试:RequestTest

  1. 301 Moved

301

  1. 302 Found

302

  1. 304 Not Modified

304

3.3 其他

4. 代码结构

main
├── java
│   └── edu.nju.http
│        ├── client  /* Client Package */
│        │   ├── ClientDriver.java      // main 函数入口
│        │   ├── HttpClient.java        // 程序主轴
│        │   └── StatusHandler.java     // Status code 处理类
│        ├── exception  /* Exception Package */
│        │   ├── InvalidCommandException.java   
│        │   │   // 用于 CLI,提示指令不合法
│        │   └── InvalidMessageException.java
│        │       // 用于 Message Parser,提示解析错误
│        ├── message /* Message Package */
│        │   ├── HttpMessage.java           // 抽象类
│        │   ├── HttpRequestMessage.java    // 继承 HttpMessage
│        │   ├── HttpResponseMessage.java   // 继承 HttpMessage
│        │   ├── MessageHelper.java         // 工具类
│        │   ├── ResponseMessageFactory.java
│        │   │      // Http Response Message 制造工厂
│        │   ├── consts /* Constant Package */
│        │   │   ├── Headers.java       // Header 常量类
│        │   │   └── WebMethods.java    // Method 常量类
│        │   ├── packer /* Packer Package */
│        │   │   ├── MessagePacker.java     
│        │   │   │   // 包装并发送 Http Message
│        │   │   └── encode
│        │   │       │ /* Content-Encoding          */
│        │   │       │ /* & Transfer-Encoding 策略类 */ 
│        │   │       ├── ContentGzipEncodeStrategy.java
│        │   │       ├── EncodeStrategy.java
│        │   │       ├── SourceEncodeStrategy.java
│        │   │       ├── TransChunkedEncodeStrategy.java
│        │   │       └── TransContentLengthEncodeStrategy.java
│        │   └── parser /* Parser Package */
│        │       ├── CustomizedReader.java  // 自制字节流读取器
│        │       ├── MessageParser.java // 解析并接收 Http Message
│        │       ├── contentdecode  
│        │       │   │ /* Content-Encoding 策略类 */
│        │       │   ├── ContentDecodeStrategy.java
│        │       │   └── ContentGzipDecodeStrategy.java
│        │       └── transdecode
│        │           │ /* Transfer-Encoding 策略类 */
│        │           ├── TransChunkedDecodeStrategy.java
│        │           ├── TransContentLengthDecodeStrategy.java
│        │           └── TransDecodeStrategy.java
│        ├── server /* Server Package */
│        │   ├── HttpServer.java    // 程序主循环
│        │   ├── ServerDriver.java  // main 函数入口
│        │   ├── TargetHandler.java // Target 处理类
│        │   └── target /* Target Package     */
│        │       │     /*  包含各 Mapping 方法 */
│        │       ├──TargetSet.java   
│        │       │  // 抽象类,其他类应继承此类
│        │       ├── Common.java
│        │       ├── Html.java
│        │       ├── LoginSystem.java
│        │       └── Mapping.java
│        └── util /* Utility Package */
│            ├── ArgIterator.java   // 参数遍历器,用于 CLI
│            ├── Config.java        // 包含各参数信息
│            └── Log.java           // 调试方法类
└── resources
    ├── default_status_text.json    // 默认 Status Code 对应文字
    ├── global_headers.json         // 默认 Server Headers
    ├── mime.json           // Suffix -> Content-Type 映射
    └── target_path.json    // Target 类注册表 
                            //( 用于在 Target Handler 初始化时用 
                            //   Reflection 自动装配 )

About

Term project for Internet Computing, Spring 2022, aiming to implement HTTP client and server with Java socket API.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages