package gnu.java.net.protocol.http;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import gnu.java.net.HeaderFieldHelper;
public final class Connection extends HttpURLConnection
{
private Socket socket;
private static int proxyPort = 80;
private static boolean proxyInUse = false;
private static String proxyHost = null;
static
{
String port = null;
proxyHost = System.getProperty("http.proxyHost");
if (proxyHost != null)
{
proxyInUse = true;
if ((port = System.getProperty("http.proxyPort")) != null)
{
try
{
proxyPort = Integer.parseInt(port);
}
catch (Throwable t)
{
}
}
}
}
private DataInputStream inputStream;
private OutputStream outputStream;
private ByteArrayOutputStream bufferedOutputStream;
private HashMap requestProperties = new HashMap();
private HeaderFieldHelper headers = new HeaderFieldHelper();
protected Connection(URL url)
{
super(url);
doOutput = false;
}
public void connect() throws IOException
{
if (connected)
return;
int port;
if (proxyInUse)
{
port = proxyPort;
socket = new Socket(proxyHost, port);
}
else
{
if ((port = url.getPort()) == -1)
port = 80;
socket = new Socket(url.getHost(), port);
}
inputStream =
new DataInputStream(new BufferedInputStream(socket.getInputStream()));
outputStream = new BufferedOutputStream (socket.getOutputStream());
sendRequest();
receiveReply();
connected = true;
}
public void disconnect()
{
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
}
socket = null;
}
}
void sendRequest() throws IOException
{
PrintWriter outputWriter =
new PrintWriter(new OutputStreamWriter(outputStream, "8859_1"));
outputWriter.print (getRequestMethod() + " " + url.getFile()
+ " HTTP/1.1\r\n");
if (getRequestProperty ("Host") == null)
setRequestProperty ("Host", url.getHost());
if (getRequestProperty ("Connection") == null)
setRequestProperty ("Connection", "Close");
if (getRequestProperty ("user-agent") == null)
setRequestProperty ("user-agent", "gnu-libgcj/"
+ System.getProperty ("java.vm.version"));
if (getRequestProperty ("accept") == null)
setRequestProperty ("accept", "*/*");
if (getRequestProperty ("Content-type") == null)
setRequestProperty ("Content-type", "application/x-www-form-urlencoded");
if (bufferedOutputStream != null)
setRequestProperty ("Content-length", String.valueOf (bufferedOutputStream.size()));
Iterator itr = getRequestProperties().entrySet().iterator();
while (itr.hasNext())
{
Map.Entry e = (Map.Entry) itr.next();
outputWriter.print (e.getKey() + ": " + e.getValue() + "\r\n");
}
outputWriter.print ("\r\n");
outputWriter.flush();
if (bufferedOutputStream != null)
{
bufferedOutputStream.writeTo (outputStream);
outputStream.flush();
}
}
private void receiveReply() throws IOException
{
String line = inputStream.readLine();
String saveline = line;
int idx = line.indexOf (" ");
if ((idx == -1)
|| (line.length() < (idx + 6)))
throw new IOException ("Server reply was unparseable: " + saveline);
headers.addHeaderField (null, line);
line = line.substring (idx + 1);
String code = line.substring (0, 3);
try
{
responseCode = Integer.parseInt (code);
}
catch (NumberFormatException e)
{
throw new IOException ("Server reply was unparseable: " + saveline);
}
responseMessage = line.substring (4);
String key = null, value = null;
while (true)
{
line = inputStream.readLine();
if (line.equals(""))
break;
if (line.startsWith (" ")
|| line.startsWith("\t"))
{
do
{
if (line.length() == 1)
throw new IOException("Server header lines were unparseable: "
+ line);
line = line.substring (1);
}
while (line.startsWith(" ")
|| line.startsWith("\t"));
value = value + " " + line;
}
else
{
if (key != null)
{
headers.addHeaderField (key.toLowerCase(), value);
key = null;
value = null;
}
idx = line.indexOf (":");
if ((idx == -1)
|| (line.length() < (idx + 2)))
throw new IOException ("Server header lines were unparseable: "
+ line);
key = line.substring (0, idx);
value = line.substring (idx + 1);
while (value.startsWith (" ")
|| value.startsWith ("\t"))
{
if (value.length() == 1)
throw new IOException ("Server header lines were unparseable: "
+ line);
value = value.substring (1);
}
}
}
if (key != null)
{
headers.addHeaderField (key.toLowerCase(), value.toLowerCase());
}
}
public boolean usingProxy()
{
return proxyInUse;
}
public InputStream getInputStream() throws IOException
{
if (!connected)
connect();
if (!doInput)
throw new ProtocolException("Can't open InputStream if doInput is false");
return inputStream;
}
public OutputStream getOutputStream() throws IOException
{
if (connected)
throw new ProtocolException
("You cannot get an output stream for an existing http connection");
if (!doOutput)
throw new ProtocolException
("Want output stream while haven't setDoOutput(true)");
if (bufferedOutputStream == null)
bufferedOutputStream = new ByteArrayOutputStream (256);
return bufferedOutputStream;
}
public void setRequestMethod (String method) throws ProtocolException
{
method = method.toUpperCase();
if (method.equals("GET")
|| method.equals("HEAD")
|| method.equals("POST"))
super.setRequestMethod (method);
else
throw new ProtocolException ("Unsupported or unknown request method " +
method);
}
public void addRequestProperty(String key, String value)
{
if (connected)
throw new IllegalStateException("Already connected");
String old = (String) requestProperties.put(key, value);
if (old != null)
requestProperties.put(key, old + "," + value);
}
public String getRequestProperty(String key)
{
if (connected)
throw new IllegalStateException("Already connected");
return (String) requestProperties.get(key);
}
public void setRequestProperty(String key, String value)
{
if (connected)
throw new IllegalStateException("Already connected");
requestProperties.put(key, value);
}
public Map getRequestProperties()
{
if (connected)
throw new IllegalStateException("Already connected");
return requestProperties;
}
public String getHeaderField(String name)
{
if (!connected)
try
{
connect();
}
catch (IOException x)
{
return null;
}
return (String) headers.getHeaderFieldValueByKey(name.toLowerCase());
}
public Map getHeaderFields()
{
if (!connected)
try
{
connect();
}
catch (IOException x)
{
return null;
}
return headers.getHeaderFields();
}
public String getHeaderField(int n)
{
if (!connected)
try
{
connect();
}
catch (IOException x)
{
return null;
}
return headers.getHeaderFieldValueByIndex (n);
}
public String getHeaderFieldKey(int n)
{
if (!connected)
try
{
connect();
}
catch (IOException x)
{
return null;
}
return headers.getHeaderFieldKeyByIndex (n);
}
}