// HttpURLConnection.java
// $Id: HttpURLConnection.java,v 1.20 2002/07/25 17:45:29 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.www.protocol.http ;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import org.w3c.www.mime.MimeType;
import org.w3c.www.http.HeaderDescription;
import org.w3c.www.http.HttpEntityMessage;
import org.w3c.www.http.HttpMessage;
import org.w3c.www.http.HttpReplyMessage;
import org.w3c.www.http.HttpRequestMessage;
public class HttpURLConnection extends java.net.HttpURLConnection
{
protected Request request = null;
protected Reply reply = null;
protected ByteArrayOutputStream output = null;
protected final synchronized void checkRequest() {
if ( request == null ) {
request = HttpManager.getManager().createRequest();
request.setMethod(method);
if ( ifModifiedSince > 0 )
request.setIfModifiedSince(ifModifiedSince*1000);
if ( ! useCaches ) {
request.addPragma("no-cache");
request.setNoCache();
}
request.setURL(url);
}
}
protected final void checkReply() {
if ((reply == null) && connected) {
error("Was connected but didn't get any reply !");
} else if ( ! connected ) {
try {
connect();
} catch (IOException ex) {
ex.printStackTrace();
error("Error while silently connecting.");
}
}
}
protected void error(String msg) {
debug("ERROR \""+msg+"\"");
throw new RuntimeException(msg);
}
protected final void debug(String m) {
// System.out.println("[http]: "
// + ((request != null)
// ? ":"+request.getURL().toExternalForm()+"]: "
// : "]: ")
// + m);
}
public boolean usingProxy() {
return HttpManager.getManager().usingProxy();
}
public synchronized void disconnect() {
if ( request != null )
request.interruptRequest();
}
public void connect()
throws IOException
{
// Check if we have already connected ourself:
debug("connect");
if ( connected )
return;
// Check for a valid request, and update stream if needed:
checkRequest();
if ( doOutput ) {
byte data[] = output.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(data);
request.setOutputStream(in);
if ( ! request.hasHeader(Request.H_CONTENT_LENGTH) )
request.setContentLength(data.length);
if ( ! request.hasHeader(Request.H_CONTENT_TYPE) ) {
MimeType t = (request.getMethod().equals("POST")
? MimeType.APPLICATION_X_WWW_FORM_URLENCODED
: MimeType.TEXT_PLAIN);
request.setContentType(t);
}
}
try {
// Run the reply, handling redirection:
int redirects = 0;
redir:
while ( redirects < 5 ) {
if ( redirects == 1 ) {
// Reinit the request, cope with URLConnnection brokeness
request.setOutputStream(null);
request.setContentLength(-1);
request.setMethod("GET");
}
reply = request.getManager().runRequest(request);
// Take care of redirects:
if ((reply.getStatus() / 100) == 3) {
String reloc = reply.getLocation();
if ( reloc == null )
break redir;
reply.getInputStream().close();
URL orig = request.getURL();
try {
url = new URL(orig, reloc);
request.setURL(url);
} catch (MalformedURLException ex) {
break redir;
}
} else {
break redir;
}
if ( ! getFollowRedirects() )
break redir;
redirects++;
}
} catch (HttpException ex) {
ex.printStackTrace();
throw new IOException(ex.getMessage());
}
connected = true;
}
public int getResponseCode()
throws IOException
{
checkReply();
return reply.getStatus();
}
public int getContentLength() {
checkReply();
return reply.getContentLength();
}
public String getContentType() {
checkReply();
MimeType t = reply.getContentType();
if (t == null) {
return null;
}
return t.toString();
}
public long getExpiration() {
checkReply();
return reply.getExpires();
}
public long getDate() {
checkReply();
return reply.getDate();
}
public long getLastModified() {
checkReply();
return reply.getLastModified();
}
public String getHeaderField(String name) {
checkReply();
return reply.getValue(name);
}
public String getHeaderFieldKey(int n) {
Enumeration e = reply.enumerateHeaderDescriptions(true);
HeaderDescription d = null;
while ( --n >= 0 ) {
if ( e.hasMoreElements() )
d = (HeaderDescription) e.nextElement();
return null;
}
if ( d != null )
return d.getName();
return null;
}
public String getHeaderField(int n) {
String key = getHeaderFieldKey(n);
if ( key != null )
return reply.getValue(key);
return null;
}
public InputStream getInputStream()
throws IOException
{
debug("getInputStream");
checkReply();
return reply.getInputStream();
}
public OutputStream getOutputStream()
throws IOException
{
debug("getOutputStream");
// We can still catch some of the deficiencies here:
if ((! connected) && (! doOutput)) {
setDoOutput(true);
} else if ( connected ) {
error("Already connected, too late for getOutputStream.");
}
// Now return a fake output stream:
// I am really ashame of this (having to buffer the data before
// emiting it), but I cannot see any better way of using this
// broken API (?)
output = new ByteArrayOutputStream();
return output;
}
public InputStream getErrorStream() {
debug("getErrorStream");
try {
int errorCat = reply.getStatus()/100 ;
if (connected && (errorCat == 4 || errorCat == 5)) {
return reply.getInputStream() ;
}
// the next catch the case where there is no reply
// as well as errors while handling the reply (no useful info...)
} catch (Exception ex) {
return null;
}
return null;
}
public void setRequestProperty(String key, String value) {
checkRequest();
request.setValue(key, value);
}
public String getRequestProperty(String key) {
checkRequest();
return request.getValue(key);
}
public static void setGlobalRequestProperty(String key, String value) {
HttpManager.getManager().setGlobalHeader(key, value);
}
public static String getDefaultRequestProperty(String key) {
return HttpManager.getManager().getGlobalHeader(key);
}
public void setDoOutput(boolean doinput) {
debug("DoOutput !!");
super.setDoOutput(doinput);
checkRequest();
if ( request.getContentType() == null )
request.setContentType(MimeType.APPLICATION_X_WWW_FORM_URLENCODED);
}
HttpURLConnection(URL u) {
super(u) ;
}
}