In basic terms, a proxy relays HTTP requests and responses back and forth between a client and a web server – see Figure 1. A transparent proxy, on the other hand, does the same thing without any configuration on the client’s part. Figure 1: HTTP Proxy Basic Principle This is achieved by modifying DNS records via a DNS server. For example, for the domain “www.google.com”, the DNS server should return its A record “172.217.17.100”. By using a specially-configured DNS server, the IP address can be modified to point to the IP of the transparent proxy. If this modification is done globally, then for every requested domain, the same IP of the transparent proxy can be set to be returned.
Transparent Proxy is a Java-based application that acts as an HTTP/HTTPS proxy server, providing features like content filtering, caching, and logging. Built with JavaFX for the user interface, the proxy server is capable of handling requests, maintaining a resource cache, and allowing users to manage filtered hosts. The system uses token-based authentication to decide whether content filtering is enabled or disabled for each user. The application connects to a PostgreSQL database for logging requests and managing customer data.
This document explains how the proxy server processes client HTTP requests and forwards them to the target server step-by-step. It uses an example request for google.com/images/monkey2.png
and discusses the role of the HeaderUtils
class in processing headers.
The client browser generates an HTTP GET request to access the resource google.com/images/monkey2.png
:
GET /images/monkey2.png HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
This request is sent to the proxy server.
Once the proxy server receives the client's request, the ServerHandler
class manages the connection on a separate thread for each client request, ensuring concurrent processing.
- Socket Initialization: A socket represents the connection between the client and proxy, and streams handle the data transmission:
- Input Stream:
BufferedReader clientInput = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- Output Stream:
DataOutputStream clientOutput = new DataOutputStream(connection.getOutputStream());
- Input Stream:
The handleClientRequest()
method reads the first line of the HTTP request using clientInput.readLine()
:
GET /images/monkey2.png HTTP/1.1
The HTTP method (GET
) and the requested path (/images/monkey2.png
) are extracted, and the remaining headers are read:
Host: google.com
User-Agent: Mozilla/5.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
The proxy uses extractHost()
to retrieve the destination host (google.com
).
The proxy checks if the resource is cached. If not, the request is forwarded to the target server.
The proxy constructs the full URL for the request and opens a new socket to connect to the server:
Socket socket = new Socket(url.getHost(), url.getPort() == -1 ? 80 : url.getPort());
In this case, the socket connects to google.com
on port 80.
The proxy prepares the request headers to be sent to the server using HeaderUtils.processHeaders()
, ensuring there are no duplicates and formatting the request appropriately.
-
Request Line:
GET /images/monkey2.png HTTP/1.1\r\n
-
Host Header:
Host: google.com\r\n
-
Connection Header:
Connection: close\r\n
The processed headers are then sent to the server:
writer.print(processedHeaders);
writer.println();
writer.flush();
The proxy reads the server's response using an InputStream
and stores the data in a buffer:
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = serverInput.read(buffer)) != -1) {
bufferStream.write(buffer, 0, bytesRead);
}
The proxy forwards the server's response back to the client:
byte[] data = bufferStream.toByteArray();
clientOutput.write(data);
clientOutput.flush();
The proxy opens a new socket for each client-server interaction and closes the socket after the request is processed:
if (socket != null && !socket.isClosed()) {
socket.close();
}
Streams are also closed after the data transmission:
clientInput.close();
clientOutput.close();
For HTTPS requests, the proxy processes CONNECT
methods and establishes a tunnel between the client and the destination server to relay data:
Socket targetSocket = new Socket(host, port);
relayData(clientInputStream, serverOutputStream);
relayData(serverInputStream, clientOutputStream);
This document details how a proxy server manages client requests, handles socket and stream management, and forwards requests to the destination server. The HeaderUtils
class ensures headers are processed correctly, and caching optimizes resource delivery. Each request opens a new socket, ensuring efficient communication and proper request-response flow between the client and the server.
- HTTP/HTTPS Proxy: Handles incoming HTTP and HTTPS requests, forwarding them to the destination and managing responses.
- Token-based Authentication: Requires users to authenticate using a token, which enables or disables content filtering.
- Content Filtering: Users can define which hosts should be blocked or allowed.
- Caching: Frequently accessed resources are cached to reduce load times and network traffic.
- Logging: All requests are logged to a PostgreSQL database for future analysis.
- Graphical User Interface (GUI): Simple GUI using JavaFX to manage proxy operations, view logs, and configure filters.
TransparentProxy
: Main class that starts the application and sets up the login screen.HomepageScreen
: Manages the proxy server's start/stop functionality, log display, and user interaction.ServerHandler
: Handles the actual request/response forwarding, caching, and content filtering.DatabaseConnection
: Provides database connectivity to PostgreSQL for storing request logs and user data.
- User Login: Users access the proxy through a login screen. They provide a token to either enable or disable content filtering.
- Proxy Operations: Once logged in, users can start the proxy server to handle HTTP and HTTPS requests. The proxy checks whether a host is filtered or not before forwarding the request.
- Content Caching: The proxy caches resources to improve performance and reduces repeated requests to the same server.
- Request Logging: All requests made through the proxy are logged to the PostgreSQL database with details like IP, domain, and request type.
-
Clone the Repository:
git clone https://github.com/your-repository.git
-
Build and Run the Project: You can run the project using a Java IDE like IntelliJ IDEA or build it using Maven/Gradle.
-
Configure PostgreSQL: Ensure that PostgreSQL is running on your system and is accessible. Update the connection parameters in the
DatabaseConnection
class.private static final String DB_URL = "jdbc:postgresql://localhost:5432/proxy"; private static final String USER = "postgres"; private static final String PASSWORD = "your-password";
-
Start the Proxy: Launch the application and use the GUI to start/stop the proxy server. You can manage the filtered hosts and view logs through the interface.
- Java 17
- JavaFX
- PostgreSQL
- Maven/Gradle for dependency management
The following diagram shows how requests are handled by the Transparent Proxy:
This project is licensed under the MIT License - see the LICENSE file for details.