This project implements a minimal multi-threaded HTTP server capable of handling GET requests based on the RFC 9112 and serving files from a specified directory. The server can be configured through a properties file.
The server configuration options are defined in a properties file, which is expected at ./config/config.properties
. More specifically, the config.properties
file should be placed inside a config
directory in the working directory where the server is run. If the properties file is not provided or some configurations are missing, default values will be used.
- port: Port number on which the server listens. Default is
7290
. - backlog: Maximum number of incoming connections that can be queued. Default is
50
. - baseDir: Directory from which the files are served. Default is the current working directory.
- corePoolSize: Initial size of the thread pool. Default is half of the available CPU cores.
- maximumPoolSize: Maximum size of the thread pool. Default is the number of available CPU cores.
- keepAliveTime: Time (in milliseconds) that threads in the thread pool will remain idle before being terminated. Default is
3000
.
port=8080
backlog=100
baseDir=../
corePoolSize=4
maximumPoolSize=8
keepAliveTime=5000
The server accepts several request headers that influence its behavior. Below is a list of supported headers and their effects on the server's responses.
-
Content-Length
- Description: Indicates the size of the request body in bytes.
- Effect: Required for requests with a body, otherwise the server may not parse the request correctly.
-
Accept-Encoding
- Description: Indicates the content encodings the client supports.
- Effect: If the client includes
gzip
in theAccept-Encoding
header, the server will compress the response body using GZIP. If this header is absent, the response body will be sent uncompressed.
-
X-Content-Disposition
- Description: Controls the disposition of the content, whether it should be displayed inline or treated as an attachment.
- Effect: If set to
attachment
, the server will include theContent-Disposition
header with the valueattachment; filename="<requested-filename>"
, prompting the client to download the file. If this header is absent, the content will be displayed inline (i.e. directly in the browser tab or the terminal window).
The server sends several response headers to the client to convey information about the response. Below is a list of these headers, their purposes, and what the client can expect.
-
Content-Type
- Description: Indicates the MIME type of the response content.
- Effect: Specifies the media type of the requested resource. The client can use this information to determine how to process the content.
-
Content-Disposition
- Description: Provides information on how the content should be displayed.
- Effect: If set to
inline
, the content will be displayed directly in the browser tab or the terminal window. If set toattachment
, the client will prompt the user to download the file instead.
-
Content-Encoding
- Description: Specifies any encoding transformations applied to the content.
- Effect: If set to
gzip
, it indicates that the content is compressed with GZIP. The client can use this information to decompress the content before processing it.
-
Content-Length
- Description: Indicates the size of the response body in bytes.
- Effect: Helps the client know the size of the response body, and ensuring the entire response has been received.
-
Connection
- Description: Controls whether the network connection stays open after the current request.
- Effect: It is set to
close
, indicating that the server will close the connection after delivering the response.
- 400 Bad Request: Sent when the request is malformed.
- 404 Not Found: Sent when the requested resource does not exist.
- 405 Method Not Allowed: Sent when the HTTP method is not supported.
- 500 Internal Server Error: Sent when an unexpected error occurs on the server (i.e. the socket has been closed).
-
git clone https://github.com/Papajohn77/HTTP-Server.git
-
cd HTTP-Server/http-server
-
mvn clean package
-
java -jar target/http-server.jar
-
Download the JAR from Releases
-
java -jar http-server.jar
The Docker Hub repository can be found here.
-
docker run -p <host-port>:<container-port> -v ${PWD}:/app/workdir papajohn77/http-server
-
docker run -p <host-port>:<container-port> -v $(pwd):/app/workdir papajohn77/http-server
- Assume that there is an
index.html
file present in the specified baseDir with the following contents:
<!DOCTYPE html>
<html>
<head>
<title>Test page</title>
</head>
<body>
<h1>Hello from HTTP server</h1>
</body>
</html>
- Assume that there is no
test.txt
file present in the specified baseDir.
- This is a simple GET request to fetch the
index.html
file:curl -v http://<ip-address>:<port>/index.html
Response:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 126
Content-Disposition: inline
Connection: close
<!DOCTYPE html>
<html>
<head>
<title>Test page</title>
</head>
<body>
<h1>Hello from HTTP server</h1>
</body>
</html>
- This is a GET request to fetch the
index.html
file, specifying that the client can accept gzip-encoded content:curl -H "Accept-Encoding: gzip" -v http://<ip-address>:<port>/index.html
Response:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 117
Content-Disposition: inline
Content-Encoding: gzip
Connection: close
... (compressed content) ...
- This is a GET request to fetch a non-existing file
test.txt
:curl -v http://<ip-address>:<port>/test.txt
Response:
HTTP/1.1 404 Not Found
Content-Type: text/plain
Content-Length: 24
Connection: close
File test.txt not found.
- Ioannis Papadatos