KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcraft > jhttptunnel > JHttpTunnelClient


1 /* -*-mode:java; c-basic-offset:2; -*- */
2 /*
3 Copyright (c) 2004 ymnk, JCraft,Inc. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10
11   2. Redistributions in binary form must reproduce the above copyright
12      notice, this list of conditions and the following disclaimer in
13      the documentation and/or other materials provided with the distribution.
14
15   3. The names of the authors may not be used to endorse or promote products
16      derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */

29
30 package com.jcraft.jhttptunnel;
31
32 import java.io.*;
33
34 public class JHttpTunnelClient{
35 // static final private int CONTENT_LENGTH=1024;
36
static final private int CONTENT_LENGTH=1024*10;
37
38   private boolean init=false;
39   private boolean closed=false;
40
41   private String JavaDoc dest_host=null;
42   private int dest_port=0;
43   private Proxy proxy=null;
44
45   private InBound ib=null;
46   private OutBound ob=null;
47
48 // private int sendCount=CONTENT_LENGTH;
49

50   public JHttpTunnelClient(String JavaDoc host, int port){
51     this.dest_host=host;
52     this.dest_port=port;
53   }
54   public void setProxy(String JavaDoc host, int port){
55     this.proxy=new Proxy(host, port);
56   }
57
58   public void connect() throws JHttpTunnelException{
59
60     if(ib==null){
61       /*
62       try{
63     Class c=Class.forName("com.jcraft.jhttptunnel.InBoundSocket");
64     ib=(InBound)c.newInstance();
65       }
66       catch(Exception e){}
67       */

68       throw new JHttpTunnelException("InBound is not given");
69     }
70     ib.setHost(dest_host);
71     ib.setPort(dest_port);
72     ib.setProxy(proxy);
73
74     if(ob==null){
75       /*
76       try{
77     Class c=Class.forName("com.jcraft.jhttptunnel.OutBoundSocket");
78     ob=(OutBound)c.newInstance();
79       }
80       catch(Exception e){}
81       */

82       throw new JHttpTunnelException("OutBound is not given");
83     }
84     ob.setHost(dest_host);
85     ob.setPort(dest_port);
86     ob.setProxy(proxy);
87     ob.setContentLength(CONTENT_LENGTH);
88
89     try{
90       getOutbound();
91       getInbound();
92     }
93     catch(Exception JavaDoc e){
94       throw new JHttpTunnelException(e.toString());
95     }
96   }
97
98   private void getOutbound() throws IOException{
99 // System.out.println("getOutbound()");
100
if(closed){
101       throw new IOException("broken pipe");
102     }
103     ob.connect();
104     if(!init){
105       openChannel(1);
106       init=true;
107     }
108   }
109
110   private void getInbound() throws IOException{
111 // System.out.println("getInbound()");
112
ib.connect();
113   }
114
115   private byte[] command=new byte[4];
116   public void openChannel(int i) throws IOException{
117     command[0]=JHttpTunnel.TUNNEL_OPEN;
118     command[1]=0;
119     command[2]=1;
120     command[3]=0;
121     ob.sendData(command, 0, 4, true);
122   }
123   public void sendDisconnect() throws IOException{
124 //System.out.println("sendDisconnect: "+sendCount);
125
command[0]=JHttpTunnel.TUNNEL_DISCONNECT;
126     ob.sendData(command, 0, 1, true);
127   }
128   public void sendClose() throws IOException{
129 //System.out.println("sendClose: ");
130
command[0]=JHttpTunnel.TUNNEL_CLOSE;
131     ob.sendData(command, 0, 1, true);
132   }
133   public void sendPad1(boolean flush) throws IOException{
134     command[0]=JHttpTunnel.TUNNEL_PAD1;
135     ob.sendData(command, 0, 1, flush);
136   }
137   public void write(byte[] foo, int s, int l) throws IOException{
138     //System.out.println("write: l="+l+", sendCount="+sendCount);
139

140     if(l<=0) return;
141
142     if(ob.sendCount<=4){
143 //System.out.println("ob.sendCount<=4: "+ob.sendCount);
144
if(0<ob.sendCount){
145         while(ob.sendCount>1){
146       sendPad1(false);
147         }
148         sendDisconnect();
149       }
150       getOutbound();
151     }
152
153     while((ob.sendCount-1-3)<l){
154       int len=(ob.sendCount-1-3);
155       command[0]=JHttpTunnel.TUNNEL_DATA;
156       command[1]=(byte)((len>>>8)&0xff);
157       command[2]=(byte)(len&0xff);
158 //System.out.println("send "+(len));
159
ob.sendData(command, 0, 3, true);
160       ob.sendData(foo, s, len, true);
161       s+=len;
162       l-=len;
163
164 // sendCount=1;
165

166       sendDisconnect();
167       if(l>0){
168     getOutbound();
169       }
170     }
171     if(l<=0)return;
172
173     command[0]=JHttpTunnel.TUNNEL_DATA;
174     command[1]=(byte)((l>>>8)&0xff);
175     command[2]=(byte)(l&0xff);
176     ob.sendData(command, 0, 3, false);
177     ob.sendData(foo, s, l, true);
178   }
179
180   int buf_len=0;
181   public int read(byte[] foo, int s, int l) throws IOException{
182     if(closed)return -1;
183
184     try{
185       if(buf_len>0){
186     int len=buf_len;
187     if(l<buf_len){
188       len=l;
189     }
190     int i=ib.receiveData(foo, s, len);
191     buf_len-=i;
192     return i;
193       }
194
195       int len=0;
196       while(!closed){
197     int i=ib.receiveData(foo, s, 1);
198     if(i<=0){
199       return -1;
200     }
201     int request=foo[s]&0xff;
202     //System.out.println("request: "+request);
203
if((request&JHttpTunnel.TUNNEL_SIMPLE)==0){
204       i=ib.receiveData(foo, s, 1);
205       len=(((foo[s])<<8)&0xff00);
206       i=ib.receiveData(foo, s, 1);
207       len=len|(foo[s]&0xff);
208     }
209     //System.out.println("request: "+request);
210
switch(request){
211     case JHttpTunnel.TUNNEL_DATA:
212       buf_len=len;
213 //System.out.println("buf_len="+buf_len);
214
if(l<buf_len){
215         len=l;
216       }
217       int orgs=s;
218       while(len>0){
219         i=ib.receiveData(foo, s, len);
220         if(i<0)break;
221         buf_len-=i;
222         s+=i;
223         len-=i;
224       }
225 //System.out.println("receiveData: "+(s-orgs));
226
return s-orgs;
227     case JHttpTunnel.TUNNEL_PADDING:
228       ib.receiveData(null, 0, len);
229       continue;
230     case JHttpTunnel.TUNNEL_ERROR:
231       byte[] error=new byte[len];
232       ib.receiveData(error, 0, len);
233 // System.out.println(new String(error, 0, len));
234
throw new IOException("JHttpTunnel: "+new String JavaDoc(error, 0, len));
235     case JHttpTunnel.TUNNEL_PAD1:
236         continue;
237     case JHttpTunnel.TUNNEL_CLOSE:
238       closed=true;
239       //close();
240
// System.out.println("CLOSE");
241
break;
242     case JHttpTunnel.TUNNEL_DISCONNECT:
243 // System.out.println("DISCONNECT");
244
continue;
245     default:
246 // System.out.println("request="+request);
247
// System.out.println(Integer.toHexString(request&0xff)+ " "+new Character((char)request));
248
throw new IOException("JHttpTunnel: protocol error 0x"+Integer.toHexString(request&0xff));
249     }
250       }
251     }
252     catch(IOException e){
253       throw e;
254     }
255     catch(Exception JavaDoc e){
256 // System.out.println("JHttpTunnelClient.read: "+e);
257
}
258     return -1;
259   }
260
261   private InputStream in=null;
262   public InputStream getInputStream(){
263     if(in!=null) return in;
264     in=
265       new InputStream(){
266         byte[] tmp=new byte[1];
267     public int read() throws IOException{
268       int i=JHttpTunnelClient.this.read(tmp, 0, 1);
269       return (i==-1?-1:tmp[0]);
270     }
271     public int read(byte[] foo) throws IOException{
272       return JHttpTunnelClient.this.read(foo, 0, foo.length);
273     }
274     public int read(byte[] foo, int s, int l) throws IOException{
275       return JHttpTunnelClient.this.read(foo, s, l);
276     }
277       };
278     return in;
279   }
280
281   private OutputStream out=null;
282   public OutputStream getOutputStream(){
283     if(out!=null) return out;
284     out=
285       new OutputStream(){
286         final byte[] tmp=new byte[1];
287     public void write(int foo) throws IOException{
288       tmp[0]=(byte)foo;
289       JHttpTunnelClient.this.write(tmp, 0, 1);
290     }
291     public void write(byte[] foo) throws IOException{
292       JHttpTunnelClient.this.write(foo, 0, foo.length);
293     }
294     public void write(byte[] foo, int s, int l) throws IOException{
295       JHttpTunnelClient.this.write(foo, s, l);
296     }
297       };
298     return out;
299   }
300
301   public void close(){
302     //System.out.println("close");
303
try{sendClose();}catch(Exception JavaDoc e){}
304     try{ib.close();}catch(Exception JavaDoc e){}
305     try{ob.close();}catch(Exception JavaDoc e){}
306     closed=true;
307   }
308
309   public void setInBound(InBound ib){ this.ib=ib; }
310   public void setOutBound(OutBound ob){ this.ob=ob; }
311
312   /*
313   public static void main(String[] arg){
314     try{
315
316       if(arg.length==0){
317     System.err.println("Enter hostname[:port]");
318     System.exit(1);
319       }
320
321       String host=arg[0];
322       int hport=8888;
323       if(host.indexOf(':')!=-1){
324     hport=Integer.parseInt(host.substring(host.lastIndexOf(':') + 1));
325     host=host.substring(0, host.lastIndexOf(':'));
326       }
327
328       int port=2323;
329       String _port=System.getProperty("F");
330       if(_port!=null){
331     port=Integer.parseInt(_port);
332       }
333
334       String proxy_host=System.getProperty("P");
335       int proxy_port=8080;
336       if(proxy_host!=null && proxy_host.indexOf(':')!=-1){
337     proxy_port=Integer.parseInt(proxy_host.substring(proxy_host.lastIndexOf(':') + 1));
338     proxy_host=proxy_host.substring(0, proxy_host.lastIndexOf(':'));
339       }
340
341       ServerSocket ss=new ServerSocket(port);
342       while(true){
343     final Socket socket=ss.accept();
344     socket.setTcpNoDelay(true);
345
346     //System.out.println("accept: "+socket);
347
348         final InputStream sin=socket.getInputStream();
349         final OutputStream sout=socket.getOutputStream();
350
351     final JHttpTunnelClient jhtc=new JHttpTunnelClient(host, hport);
352     if(proxy_host!=null){
353       jhtc.setProxy(proxy_host, proxy_port);
354     }
355
356 // jhtc.setInBound(new InBoundURL());
357 // jhtc.setOutBound(new OutBoundURL());
358
359     jhtc.setInBound(new InBoundSocket());
360     jhtc.setOutBound(new OutBoundSocket());
361
362     jhtc.connect();
363         final InputStream jin=jhtc.getInputStream();
364         final OutputStream jout=jhtc.getOutputStream();
365
366     Runnable runnable=new Runnable(){
367         public void run(){
368           byte[] tmp=new byte[1024];
369           try{
370         while(true){
371           int i=jin.read(tmp);
372           if(i>0){
373             sout.write(tmp, 0, i);
374             continue;
375           }
376           break;
377         }
378           }
379           catch(Exception e){
380           }
381           try{
382         sout.close();
383         sin.close();
384         socket.close();
385         jin.close();
386         jhtc.close();
387           }
388           catch(Exception e){
389           }
390         }
391       };
392     (new Thread(runnable)).start();
393
394     byte[] tmp=new byte[1024];
395     try{
396       while(true){
397         int i=sin.read(tmp);
398         if(i>0){
399           jout.write(tmp, 0, i);
400           continue;
401         }
402         break;
403       }
404     }
405     catch(Exception e){
406     }
407     try{
408       socket.close();
409       jin.close();
410       jhtc.close();
411     }
412     catch(Exception e){
413     }
414       }
415     }
416     catch(JHttpTunnelException e){
417       System.err.println(e);
418     }
419     catch(IOException e){
420       System.err.println(e);
421     }
422   }
423   */

424 }
425
Popular Tags