1 2 29 30 package com.jcraft.jhttptunnel; 31 import java.lang.*; 32 import java.io.*; 33 import java.net.*; 34 import java.util.*; 35 36 public class JHttpTunnelServer extends Thread { 37 38 static int connections=0; 39 static int client_connections=0; 40 static int source_connections=0; 41 42 private ServerSocket serverSocket=null; 43 static int port=8888; 44 static String myaddress=null; 45 static String myURL=null; 46 47 static String default_host; 48 static int default_port; 49 50 JHttpTunnelServer(int port){ 51 super(); 52 connections=0; 53 try{ serverSocket=new ServerSocket(port); } 54 catch(IOException e){ 55 System.exit(1); 57 } 58 try{ 59 if(myaddress==null) 60 myURL="http://"+InetAddress.getLocalHost().getHostAddress()+":"+port; 61 else 62 myURL="http://"+myaddress+":"+port; 63 } 65 catch(Exception e){ 66 System.out.println(e ); 67 } 68 } 69 JHttpTunnelServer(int lport, String fhost, int fport){ 70 this(lport); 71 this.default_host=fhost; 72 this.default_port=fport; 73 } 74 75 public void run(){ 76 Socket socket=null; 77 while(true){ 78 try{socket=serverSocket.accept();} 79 catch(IOException e) { 80 System.out.println("accept error"); 81 System.exit(1); 82 } 83 connections++; 84 final Socket _socket=socket; 86 new Thread (new Runnable (){ 87 public void run(){ 88 try{(new Dispatch(_socket)).doit();} 89 catch(Exception e){} 90 } 91 }).start(); 92 } 93 } 94 95 109 110 public static void main(String [] arg){ 111 112 int port=8888; 113 if(arg.length!=0){ 114 String _port=arg[0]; 115 if(_port!=null){ 116 port=Integer.parseInt(_port); 117 } 118 } 119 120 String fhost=null; 121 int fport=0; 122 String _fw=System.getProperty("F"); 123 if(_fw!=null && _fw.indexOf(':')!=-1){ 124 fport=Integer.parseInt(_fw.substring(_fw.lastIndexOf(':') + 1)); 125 fhost=_fw.substring(0, _fw.lastIndexOf(':')); 126 } 127 if(fport==0 || fhost==null){ 128 System.err.println("forward-port is not given"); 129 System.exit(1); 130 } 131 (new JHttpTunnelServer(port, fhost, fport)).start(); 132 } 133 } 134 135 class Dispatch{ 136 private MySocket mySocket=null; 137 private String rootDirectory="."; 138 private String defaultFile="index.html"; 139 140 Dispatch(Socket s) throws IOException{ 141 super(); 142 mySocket=new MySocket(s); 143 } 144 145 private Vector getHttpHeader(MySocket ms) throws IOException{ 146 Vector v=new Vector(); 147 String foo=null; 148 while(true){ 149 foo=ms.readLine(); 150 if(foo.length()==0){ break; } 151 v.addElement(foo); 152 } 153 return v; 154 } 155 156 byte[] buf=new byte[1024]; 157 158 private void procPOST(String string, Vector httpheader) throws IOException{ 159 String foo; 160 int len=0; 161 int c; 162 String file=string.substring(string.indexOf(' ') + 1); 163 if(file.indexOf(' ')!=-1) 164 file=file.substring(0 , file.indexOf(' ')); 165 166 Hashtable vars=getVars((file.indexOf('?')!=-1)? 167 file.substring(file.indexOf('?')+1):null); 168 String sid=(String )vars.get("SESSIONID"); 169 170 Client client=null; 171 if(sid==null){ 172 sid=new Long (System.currentTimeMillis()).toString(); 173 client=new Client(sid, 174 JHttpTunnelServer.default_host, 175 JHttpTunnelServer.default_port); 176 } 177 else{ 178 client=getClient(sid); 179 } 180 181 183 if(client==null){ 184 notFound(mySocket); 185 return; 186 } 187 188 for(int i=0; i<httpheader.size(); i++){ 189 foo=(String )httpheader.elementAt(i); 190 if(foo.startsWith("Content-Length:") || 191 foo.startsWith("Content-length:") ){ 193 foo=foo.substring(foo.indexOf(' ')+1); 194 foo=foo.trim(); 195 len=Integer.parseInt(foo); 196 } 197 } 198 199 201 if(len==0){ client.command=-1; 203 client.dataremain=0; 204 } 205 206 if(client.dataremain==0 && len>0){ 207 int i=mySocket.read(buf, 0, 1); len--; 209 client.command=buf[0]; 210 int datalen=0; 211 212 if((client.command&JHttpTunnel.TUNNEL_SIMPLE)==0){ 213 i=mySocket.read(buf, 0, 2); 214 len-=2; 215 if(i!=2){ 216 } 217 datalen=(((buf[0])<<8)&0xff00); 218 datalen=datalen|(buf[1]&0xff); 219 } 220 client.dataremain=datalen; 222 } 223 224 226 int i=0; 227 if(len>0){ 228 i=mySocket.read(buf, 0, len); 229 client.dataremain-=len; 231 } 232 233 if(client.dataremain==0){ 234 System.out.println(sid+": "+client.command); 235 switch(client.command){ 236 case JHttpTunnel.TUNNEL_OPEN: 237 client.connect(); 238 break; 239 case JHttpTunnel.TUNNEL_DATA: 240 client.send(buf, 0, len); 241 break; 242 case JHttpTunnel.TUNNEL_CLOSE: 243 client.close(); 244 break; 245 } 246 } 247 248 i=0; 249 if(client.isConnected()){ 250 i=client.pop(buf, 3, buf.length-3); 251 if(i>0){ 252 buf[0]=JHttpTunnel.TUNNEL_DATA; 253 buf[1]=(byte)((i>>>8)&0xff); 254 buf[2]=(byte)(i&0xff); 255 i+=3; 256 } 257 } 258 ok(mySocket, buf, 0, i, sid); 259 } 260 261 private void procGET(String string, Vector httpheader) throws IOException{ 262 String foo; 263 int c; 264 String file=string.substring(string.indexOf(' ') + 1); 265 if(file.indexOf(' ')!=-1) 266 file=file.substring(0 , file.indexOf(' ')); 267 268 if(file.indexOf("..")!=-1){ 269 notFound(mySocket); 270 return; 271 } 272 273 if(file.startsWith("/")) 274 file=file.substring(1); 275 276 try { 277 File _file=new File(file); 278 int len=(int)_file.length(); 279 FileInputStream fis=new FileInputStream(file); 280 ok(mySocket, fis, len, null); 281 fis.close(); 282 } 283 catch(IOException e){ 284 System.out.println(e); 285 } 286 287 288 } 289 290 private void procHEAD(String string, Vector httpheader) throws IOException{ 291 ok(mySocket, null, 0, 0, ""); 292 } 293 294 String decode(String arg){ 295 byte[] foo=arg.getBytes(); 296 StringBuffer sb=new StringBuffer (); 297 for(int i=0; i<foo.length; i++){ 298 if(foo[i]=='+'){ sb.append((char)' '); continue; } 299 if(foo[i]=='%' && i+2<foo.length){ 300 int bar=foo[i+1]; 301 bar=('0'<=bar && bar<='9')? bar-'0' : 302 ('a'<=bar && bar<='z')? bar-'a'+10 : 303 ('A'<=bar && bar<='Z')? bar-'A'+10 : bar; 304 bar*=16; 305 int goo=foo[i+2]; 306 goo=('0'<=goo && goo<='9')? goo-'0' : 307 ('a'<=goo && goo<='f')? goo-'a'+10 : 308 ('A'<=goo && goo<='F')? goo-'A'+10 : goo; 309 bar+=goo; bar&=0xff; 310 sb.append((char)bar); 311 i+=2; 312 continue; 313 } 314 sb.append((char)foo[i]); 315 } 316 return sb.toString(); 317 } 318 319 Hashtable getVars(String arg){ 320 Hashtable vars=new Hashtable(); 321 if(arg==null) return vars; 322 arg=decode(arg); 323 int foo=0; 324 int i=0; 325 int c=0; 326 String key, value; 327 while(true){ 328 key=value=null; 329 foo=arg.indexOf('='); 330 if(foo==-1)break; 331 key=arg.substring(0, foo); 332 arg=arg.substring(foo+1); 333 foo=arg.indexOf('&'); 334 if(foo!=-1){ 335 value=arg.substring(0, foo); 336 arg=arg.substring(foo+1); 337 } 338 else value=arg; 339 vars.put(key, value); 340 if(foo==-1)break; 341 } 342 return vars; 343 } 344 345 public void doit(){ 346 try{ 347 String foo=mySocket.readLine(); 348 349 System.out.println(mySocket.socket.getInetAddress()+": "+foo+" "+(new java.util.Date ())); 350 351 if(foo.indexOf(' ')==-1){ 352 mySocket.close(); 353 return; 354 } 355 356 String bar=foo.substring(0, foo.indexOf(' ')); 357 359 Vector v=getHttpHeader(mySocket); 360 361 363 if(bar.equalsIgnoreCase("POST")){ 364 procPOST(foo, v); 365 return; 366 } 367 368 if(bar.equalsIgnoreCase("GET")){ 369 procGET(foo, v); 370 return; 371 } 372 373 if(bar.equalsIgnoreCase("HEAD")){ 374 procHEAD(foo, v); 375 return; 376 } 377 } 378 catch(Exception e){ 379 } 380 } 381 382 void ok(MySocket mysocket, byte[] buf, int s, int l, String sid) throws IOException{ 383 mysocket.println("HTTP/1.1 200 OK"); 384 mysocket.println("Last-Modified: Thu, 04 Oct 2001 14:09:23 GMT"); 385 if(sid!=null){ 386 mysocket.println("x-SESSIONID: "+sid); 387 } 388 mysocket.println("Content-Length: "+l); 389 mysocket.println("Connection: close"); 390 mysocket.println("Content-Type: text/html; charset=iso-8859-1"); 391 mysocket.println(""); 392 393 if(l>0){ 394 mysocket.write(buf, s, l); 395 } 396 397 mysocket.flush(); 398 mysocket.close(); 399 } 400 401 void ok(MySocket mysocket, InputStream in, int l, String sid) throws IOException{ 402 mysocket.println("HTTP/1.1 200 OK"); 403 mysocket.println("Last-Modified: Thu, 04 Oct 2001 14:09:23 GMT"); 404 if(sid!=null){ 405 mysocket.println("x-SESSIONID: "+sid); 406 } 407 mysocket.println("Content-Length: "+l); 408 mysocket.println("Connection: close"); 409 mysocket.println("Content-Type: text/html; charset=iso-8859-1"); 410 mysocket.println(""); 411 412 if(l>0){ 413 byte[] buf=new byte[1024]; 414 while(true){ 415 int i=in.read(buf, 0, buf.length); 416 if(i<0) break; 417 if(i>0){ 418 mysocket.write(buf, 0, i); 419 } 420 } 421 } 422 mysocket.flush(); 423 mysocket.close(); 424 } 425 426 427 static void notFound(MySocket ms) throws IOException{ 428 ms.println("HTTP/1.1 404 Not Found") ; 429 ms.println("Content-Type: text/html") ; 430 ms.println("Content-Length: 0"); 431 ms.println("Connection: close"); 432 ms.println("") ; 433 ms.flush(); 434 ms.close(); 435 } 436 437 private static Hashtable cpool=new Hashtable(); 438 static Client getClient(String sid){ return (Client)cpool.get(sid); } 439 static void putClient(String sid, Client client){ cpool.put(sid, client); } 440 static void removeClient(String sid){ cpool.remove(sid); } 441 442 class Client extends Thread { 443 444 private String sid; 445 private String host; 446 private int port; 447 448 Client(String sid, String host, int port){ 449 super(); 450 this.sid=sid; 451 this.host=host; 452 this.port=port; 453 putClient(sid, this); 454 } 455 456 public int dataremain=0; 457 public byte command=0; 458 459 private Socket socket=null; 460 private InputStream in; 461 private OutputStream out; 462 463 boolean connected=false; 464 465 boolean isConnected(){ 466 return connected; 467 } 468 469 void connect(){ 470 try{ 471 socket=new Socket(host, port); 472 in=socket.getInputStream(); 474 out=socket.getOutputStream(); 475 connected=true; 476 start(); 477 } 478 catch(Exception e){ 479 System.out.println(e); 480 } 481 } 482 483 public void send(byte[] foo, int s, int l){ 484 try{ 486 out.write(foo, s, l); 487 out.flush(); 488 } 489 catch(Exception e){ 490 System.out.println(e); 491 } 492 } 493 494 public void run(){ 495 byte[] buf=new byte[1024]; 496 while(true){ 497 try{ 498 int space=space(); 499 if(space>0){ 500 if(space>buf.length)space=buf.length; 501 int i=in.read(buf, 0, space); 502 if(i<0){ 504 break; 505 } 506 if(i>0){ 508 push(buf, 0, i); 509 try{ Thread.sleep(1); } 510 catch(Exception ee){} 511 continue; 512 } 513 } 514 while(true){ 515 if(space()>0) break; 516 try{ Thread.sleep(1000); } 517 catch(Exception ee){ 518 } 519 } 520 } 521 catch(java.net.SocketException e){ 522 break; 524 } 525 catch(Exception e){ 526 } 528 } 529 close(); 530 } 531 532 int buflen=0; 533 byte[] buf=new byte[10240]; 536 synchronized int space(){ 537 return buf.length-buflen; 539 } 540 synchronized void push(byte[] foo, int s, int l){ 541 System.arraycopy(foo, s, buf, buflen, l); 543 buflen+=l; 544 } 545 synchronized int pop(byte[] foo, int s, int l){ 546 if(buflen==0){ 547 return 0; 549 } 550 if(l>buflen)l=buflen; 551 System.arraycopy(buf, 0, foo, s, l); 552 System.arraycopy(buf, l, buf, 0, buflen-l); 553 buflen-=l; 554 555 if(socket==null && buflen<=0){ 556 removeClient(sid); 557 } 558 return l; 560 } 561 562 public void close(){ 563 try{ 564 in.close(); 565 out.close(); 566 socket.close(); 567 socket=null; 568 } 569 catch(Exception e){ 570 } 571 if(buflen==0){ 572 removeClient(sid); 573 } 574 } 575 576 } 577 } 578 | Popular Tags |