@@ -49,76 +49,105 @@ public static void handle(Socket client) {
4949 } catch (IOException e ) {
5050 System .out .println ("Error reading request from client: " + e );
5151 new HttpResponse (400 ).send (client );
52- return ;
5352 }
5453
55- // create key
56- String key = request .getURL ();
57- // Check if key is in cache
58- if ((response = cache .get (key )) != null && response .isValid ()) { // get item from cache if the cache is still fresh
59- // response is set and valid
60- System .out .println ("Retrieved " + key );
61- System .out .println ("Is valid? " + response .isValid ());
62- } else if (!request .method .equals ("CONNECT" )) { // handle requests except special case of CONNECT
63-
64- /* Send request to server */
65- response = request .send ();
54+ if (request .method .equals ("GET" )) { // Only GET requests are cached
55+ // create key
56+ String key = request .getURL ();
57+ // Check if key is in cache
58+ if ((response = cache .get (key )) != null && response .isValid ()) { // get item from cache if the cache is still fresh
59+ // response is set and valid
60+ System .out .println ("Retrieved " + key );
61+ System .out .println ("Is valid? " + response .isValid ());
62+ } else { // handle requests
63+ /* Send request to server */
64+ response = request .send ();
65+
66+ /* Read response and forward it to client */
67+ cache .put (key , response );// Save response to cache
68+ }
6669
67- /* Read response and forward it to client */
68- cache .put (key , response );// Save response to cache
6970 System .out .println ("<--- Response <--- \n " + response .toString ()); // Debug
70- } // end else
71+ try {
72+ /* Write response to client. First headers, then body */
73+ DataOutputStream toClient = new DataOutputStream (client .getOutputStream ());
74+ toClient .writeBytes (response .toString ()); // headers
75+ response .body .writeTo (toClient ); // body
76+ client .close ();
77+ } catch (IOException e ) {
78+ System .out .println ("Error writing response to client (cached): " + e );
79+ // new HttpResponse(500).send(client);
80+ }
81+ }
7182
7283 // http://stackoverflow.com/questions/16358589/implementing-a-simple-https-proxy-application-with-java
7384 // http://stackoverflow.com/questions/18273703/tunneling-two-socket-client-in-java#18274109
74- if (request .method .equals ("CONNECT" )) {
85+ else if (request .method .equals ("CONNECT" )) {
86+ System .out .println ("CONNECT found! Tunnelling connection." );
87+ InputStream fromClient ;
88+ OutputStream toServer ;
7589 try {
76- System .out .println ("CONNECT found! Tunnelling connection." );
7790 server = new Socket (request .getHost (), request .getPort ());
78- InputStream fromClient = client .getInputStream ();
79- OutputStream toClient = client .getOutputStream ();
80- InputStream fromServer = server .getInputStream ();
81- OutputStream toServer = server .getOutputStream ();
91+ fromClient = client .getInputStream ();
92+ toServer = server .getOutputStream ();
8293 new HttpResponse (200 ).setMessage ("Connection established" ).setVersion ("HTTP/1.0" ).send (client );
83-
84- // request
85- while (true ) {
86- for (int i = 0 ; (i = fromClient .read ()) != -1 ; i ++) {
87- toServer .write (i );
88- if (fromClient .available () == 0 ) {
89- break ;
90- }
91- }
92- // response
93- for (int i = 0 ; (i = fromServer .read ()) != -1 ; i ++) {
94- toClient .write (i );
95- if (fromServer .available () == 0 ) {
96- break ;
97- }
98- }
99- }
100- // return;
10194 } catch (UnknownHostException e ) {
10295 System .out .println ("Unknown host: " + request .getHost ());
103- System .out .println (e );
10496 new HttpResponse (404 ).send (client );
10597 return ;
10698 } catch (IOException e ) {
107- System .out .println ("Error writing request to server : " + e );
99+ System .out .println ("Error establishing connection : " + e );
108100 new HttpResponse (500 ).send (client );
109101 return ;
110102 }
111- } else {
103+
112104 try {
113- /* Write response to client. First headers, then body */
114- DataOutputStream toClient = new DataOutputStream (client .getOutputStream ());
115- toClient .writeBytes (response .toString ()); // headers
116- response .body .writeTo (toClient ); // body
105+ client .setSoTimeout (5000 );
106+ server .setSoTimeout (5000 );
107+ byte [] buffer = new byte [2048 ];
108+ int rc = 0 ;
109+
110+ // http://stackoverflow.com/questions/31365522/java-proxy-tunnelling-https
111+ Thread servertToClient = new TunnelThread (server , client );
112+ new Thread (servertToClient ).start (); // from server to client
113+ while (!client .isClosed () && !server .isClosed () && !client .isInputShutdown () && !server .isOutputShutdown ()) {
114+ while ((rc = fromClient .read (buffer )) != -1 ) {
115+ toServer .write (buffer , 0 , rc );
116+ toServer .flush ();
117+ }
118+ }
119+ server .close ();
117120 client .close ();
121+ } catch (SocketTimeoutException e ) {
122+ System .out .println ("Connection Timed out " + e );
123+ // EXIT HERE
124+ // servertToClient.interrupt();
125+ return ;
126+ // new HttpResponse(404).send(client);
118127 } catch (IOException e ) {
119- System .out .println ("Error writing response to client : " + e );
128+ System .out .println ("Error tunnelling request : " + e );
120129 // new HttpResponse(500).send(client);
130+ // return;
131+ // } catch (InterruptedException e) {
132+ // System.out.println("Thread: Interrupted" + e);
121133 }
134+ } else { // e.g POST, HEAD or DELETE requests
135+ new HttpResponse (501 ).send (client );
136+ return ;
137+ // response = request.send();
138+ // System.out.println("<--- Response <--- \n" + response.toString()); // Debug
139+
140+ // try {
141+ // /* Write response to client. First headers, then body */
142+ // DataOutputStream toClient = new DataOutputStream(client.getOutputStream());
143+ // toClient.writeBytes(response.toString()); // headers // broken pipe /Protocol wrong type for socket
144+ // response.body.writeTo(toClient); // body
145+ // client.close();
146+ // } catch (IOException e) {
147+ // System.out.println("Error writing response to client: " + e);
148+ // e.printStackTrace();
149+ // // new HttpResponse(500).send(client);
150+ // }
122151 }
123152 }
124153
@@ -153,7 +182,7 @@ public static void main(String args[]) {
153182 System .out .println ("Error reading request from client: " + e );
154183 /* Definitely cannot continue processing this request,
155184 * so skip to next iteration of while loop. */
156- continue ;
185+ continue ;
157186 }
158187 }
159188 }
@@ -172,5 +201,35 @@ public void run() {
172201 ProxyCache .handle (client );
173202 // System.out.println("Handling client from thread! " + client.toString());
174203 }
204+ }
175205
206+ class TunnelThread extends Thread {
207+ Socket server ;
208+ Socket client ;
209+
210+ TunnelThread (Socket server , Socket client ) {
211+ this .server = server ;
212+ this .client = client ;
213+ }
214+
215+ public void run () {
216+ int rs = 0 ;
217+ byte [] buffer = new byte [2048 ];
218+ try {
219+ OutputStream toClient = client .getOutputStream ();
220+ InputStream fromServer = server .getInputStream ();
221+
222+ while (!server .isClosed () && !client .isClosed () && !server .isInputShutdown () && !client .isOutputShutdown ()) {
223+ while ((rs = fromServer .read (buffer )) != -1 ) {
224+ toClient .write (buffer , 0 , rs );
225+ toClient .flush ();
226+ }
227+ }
228+ System .out .println ("thread ended normally" );
229+ } catch (IOException e ) {
230+ System .out .println ("Thread: IOError: " + e );
231+ interrupt ();
232+ // return;
233+ }
234+ }
176235}
0 commit comments