001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch;
031:
032: import java.io.*;
033: import java.net.*;
034:
035: public class ProxyHTTP implements Proxy {
036: private static int DEFAULTPORT = 80;
037: private String proxy_host;
038: private int proxy_port;
039: private InputStream in;
040: private OutputStream out;
041: private Socket socket;
042:
043: private String user;
044: private String passwd;
045:
046: public ProxyHTTP(String proxy_host) {
047: int port = DEFAULTPORT;
048: String host = proxy_host;
049: if (proxy_host.indexOf(':') != -1) {
050: try {
051: host = proxy_host.substring(0, proxy_host.indexOf(':'));
052: port = Integer.parseInt(proxy_host.substring(proxy_host
053: .indexOf(':') + 1));
054: } catch (Exception e) {
055: }
056: }
057: this .proxy_host = host;
058: this .proxy_port = port;
059: }
060:
061: public ProxyHTTP(String proxy_host, int proxy_port) {
062: this .proxy_host = proxy_host;
063: this .proxy_port = proxy_port;
064: }
065:
066: public void setUserPasswd(String user, String passwd) {
067: this .user = user;
068: this .passwd = passwd;
069: }
070:
071: public void connect(SocketFactory socket_factory, String host,
072: int port, int timeout) throws JSchException {
073: try {
074: if (socket_factory == null) {
075: socket = Util.createSocket(proxy_host, proxy_port,
076: timeout);
077: in = socket.getInputStream();
078: out = socket.getOutputStream();
079: } else {
080: socket = socket_factory.createSocket(proxy_host,
081: proxy_port);
082: in = socket_factory.getInputStream(socket);
083: out = socket_factory.getOutputStream(socket);
084: }
085: if (timeout > 0) {
086: socket.setSoTimeout(timeout);
087: }
088: socket.setTcpNoDelay(true);
089:
090: out
091: .write(("CONNECT " + host + ":" + port + " HTTP/1.0\r\n")
092: .getBytes());
093:
094: if (user != null && passwd != null) {
095: byte[] code = (user + ":" + passwd).getBytes();
096: code = Util.toBase64(code, 0, code.length);
097: out.write("Proxy-Authorization: Basic ".getBytes());
098: out.write(code);
099: out.write("\r\n".getBytes());
100: }
101:
102: out.write("\r\n".getBytes());
103: out.flush();
104:
105: int foo = 0;
106:
107: StringBuffer sb = new StringBuffer();
108: while (foo >= 0) {
109: foo = in.read();
110: if (foo != 13) {
111: sb.append((char) foo);
112: continue;
113: }
114: foo = in.read();
115: if (foo != 10) {
116: continue;
117: }
118: break;
119: }
120: if (foo < 0) {
121: throw new IOException();
122: }
123:
124: String response = sb.toString();
125: String reason = "Unknow reason";
126: int code = -1;
127: try {
128: foo = response.indexOf(' ');
129: int bar = response.indexOf(' ', foo + 1);
130: code = Integer.parseInt(response
131: .substring(foo + 1, bar));
132: reason = response.substring(bar + 1);
133: } catch (Exception e) {
134: }
135: if (code != 200) {
136: throw new IOException("proxy error: " + reason);
137: }
138:
139: /*
140: while(foo>=0){
141: foo=in.read(); if(foo!=13) continue;
142: foo=in.read(); if(foo!=10) continue;
143: foo=in.read(); if(foo!=13) continue;
144: foo=in.read(); if(foo!=10) continue;
145: break;
146: }
147: */
148:
149: int count = 0;
150: while (true) {
151: count = 0;
152: while (foo >= 0) {
153: foo = in.read();
154: if (foo != 13) {
155: count++;
156: continue;
157: }
158: foo = in.read();
159: if (foo != 10) {
160: continue;
161: }
162: break;
163: }
164: if (foo < 0) {
165: throw new IOException();
166: }
167: if (count == 0)
168: break;
169: }
170: } catch (RuntimeException e) {
171: throw e;
172: } catch (Exception e) {
173: try {
174: if (socket != null)
175: socket.close();
176: } catch (Exception eee) {
177: }
178: String message = "ProxyHTTP: " + e.toString();
179: if (e instanceof Throwable)
180: throw new JSchException(message, (Throwable) e);
181: throw new JSchException(message);
182: }
183: }
184:
185: public InputStream getInputStream() {
186: return in;
187: }
188:
189: public OutputStream getOutputStream() {
190: return out;
191: }
192:
193: public Socket getSocket() {
194: return socket;
195: }
196:
197: public void close() {
198: try {
199: if (in != null)
200: in.close();
201: if (out != null)
202: out.close();
203: if (socket != null)
204: socket.close();
205: } catch (Exception e) {
206: }
207: in = null;
208: out = null;
209: socket = null;
210: }
211:
212: public static int getDefaultPort() {
213: return DEFAULTPORT;
214: }
215: }
|