简体   繁体   中英

Java proxy to intercept requests

We would like to create a simple JAVA proxy server that would gather info from the request headers if need be.

We have implemented the proxy server, pointed our browser to the host and port, and we are able to browse sites that use simple HTTP protocol without an issue.

We support the GET and HEAD HTTP methods.

However, sites that use HTTPS cause an issue, as these initiate a CONNECT method, and we can't get the secure connection up, we are not sure what to send in the response. (Or if we would be able to monitor further requests from that point onward.)

Any suggestions? Any 3rd party implementation would do. But we would like to support HTTP and HTTPS in the same process.

private void intercept() throws IOException {
        final DataInputStream socketInput = new DataInputStream(this.socket.getInputStream());
        final String httpMessage = RequestHeader.readHttpHeader(socketInput);
        //Request header is our own convenience file with utility methods that parses the request header.
        requestHeader = new RequestHeader(httpMessage);
        try {
            if ("GET".equals(requestHeader.getType()) || "HEAD".equals(requestHeader.getType())) {
                final URL url = new URL(requestHeader.getUrl());
                final HttpURLConnection connectionHttp = (HttpURLConnection) url.openConnection();
                connectionHttp.setRequestMethod(requestHeader.getType());
                // Send response back to client
                final DataInputStream dis = new DataInputStream(connectionHttp.getInputStream());

                // Add response header
                final StringBuilder sb = new StringBuilder();
                sb.append(requestHeader.getHttpVersion() + " " + connectionHttp.getResponseCode() + " "
                        + connectionHttp.getResponseMessage() + "\r\n");
                final Map<String, List<String>> map = connectionHttp.getHeaderFields();
                for (final Map.Entry<String, List<String>> entry : map.entrySet()) {
                    final String key = entry.getKey();
                    sb.append(key + " : "
                            + entry.getValue().toString().replace("[", "").replace("]", "").replace(",", " ") + "\r\n");
                }
                sb.append("\r\n");

                // Add response content
                final DataOutputStream socketOutput = new DataOutputStream(this.socket.getOutputStream());
                socketOutput.write(sb.toString().getBytes(), 0, sb.toString().getBytes().length);
                final byte[] data = new byte[(int) Short.MAX_VALUE];
                int index = dis.read(data, 0, (int) Short.MAX_VALUE);
                while (index != -1) {
                    socketOutput.write(data, 0, index);
                    index = dis.read(data, 0, (int) Short.MAX_VALUE);
                }
                socketOutput.flush();

                // NOTE this works perfectly fine for HTTP sites. We can intercept the communication properly.

            } else if ("CONNECT".equals(requestHeader.getType())) {
                // TODO establish connection
                // First line of header: CONNECT www.facebook.com:443 HTTP/1.1

                // We have tried to send back 200 ok response, but no further requests were sent.
            } else {
                //Nothing else is supported
                return;
            }
        } catch (final MalformedURLException e) {
            System.out.print("MalformedURLException " + e.getMessage());
            // return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
        } catch (final IOException e) {
            System.out.print("IOException " + e.getMessage());
            // return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
        } finally {
            System.out.println("Finished.");
        }
    }

HTTPComponents supports HTTPS. Also, you don't have to write the socket logic yourself, so there's that.

If I recall right, HTTPS works out of the box, no need for any odd configuration or special ssl calls.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM