001package org.dcm4che3.net.proxy; 002 003import java.io.ByteArrayOutputStream; 004import java.io.IOException; 005import java.io.InputStream; 006import java.io.OutputStream; 007import java.net.Socket; 008 009import org.dcm4che3.util.Base64; 010 011/** 012 * Define basic proxy authentication processing. This code come from old 013 * Connection.doProxyHandshake() method (before refactoring). 014 * 015 * @author Amaury Pernette 016 * 017 */ 018public class BasicProxyManager implements ProxyManager { 019 020 public static final String PROVIDER_NAME = "org.dcm4che.basic"; 021 public static final String VERSION = "1.0"; 022 023 @Override 024 public String getProviderName() { 025 return PROVIDER_NAME; 026 } 027 028 @Override 029 public String getVersion() { 030 return VERSION; 031 } 032 033 @Override 034 public void doProxyHandshake(Socket s, String hostname, int port, String userauth, int connectTimeout) 035 throws IOException { 036 037 StringBuilder request = new StringBuilder(128); 038 request.append("CONNECT ").append(hostname).append(':').append(port).append(" HTTP/1.1\r\nHost: ") 039 .append(hostname).append(':').append(port); 040 if (userauth != null) { 041 byte[] b = userauth.getBytes("UTF-8"); 042 char[] base64 = new char[(b.length + 2) / 3 * 4]; 043 Base64.encode(b, 0, b.length, base64, 0); 044 request.append("\r\nProxy-Authorization: basic ").append(base64); 045 } 046 request.append("\r\n\r\n"); 047 OutputStream out = s.getOutputStream(); 048 out.write(request.toString().getBytes("US-ASCII")); 049 out.flush(); 050 051 s.setSoTimeout(connectTimeout); 052 @SuppressWarnings("resource") 053 String response = new HTTPResponse(s).toString(); 054 s.setSoTimeout(0); 055 if (!response.startsWith("HTTP/1.1 2")) 056 throw new IOException("Unable to tunnel through " + s + ". Proxy returns \"" + response + '\"'); 057 058 } 059 060 private static class HTTPResponse extends ByteArrayOutputStream { 061 062 private final String rsp; 063 064 public HTTPResponse(Socket s) throws IOException { 065 super(64); 066 InputStream in = s.getInputStream(); 067 boolean eol = false; 068 int b; 069 while ((b = in.read()) != -1) { 070 write(b); 071 if (b == '\n') { 072 if (eol) { 073 rsp = new String(super.buf, 0, super.count, "US-ASCII"); 074 return; 075 } 076 eol = true; 077 } else if (b != '\r') { 078 eol = false; 079 } 080 } 081 throw new IOException("Unexpected EOF from " + s); 082 } 083 084 @Override 085 public String toString() { 086 return rsp; 087 } 088 } 089}