1 // Connection.java - Implementation of HttpURLConnection for http protocol.
3 /* Copyright (C) 1999, 2000, 2003 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
11 package gnu
.gcj
.protocol
.http
;
16 import java
.util
.Vector
;
17 import java
.util
.Hashtable
;
18 import java
.util
.Enumeration
;
21 * @author Warren Levy <warrenl@cygnus.com>
22 * @date March 29, 1999.
26 * Written using on-line Java Platform 1.2 API Specification, as well
27 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
28 * Status: Minimal subset of functionality. Proxies only partially
29 * handled; Redirects not yet handled. FileNameMap handling needs to
30 * be considered. useCaches, ifModifiedSince, and
31 * allowUserInteraction need consideration as well as doInput and
35 class Connection
extends HttpURLConnection
37 protected Socket sock
= null;
38 private static Hashtable defRequestProperties
= new Hashtable();
39 private Hashtable requestProperties
;
40 private Hashtable hdrHash
= new Hashtable();
41 private Vector hdrVec
= new Vector();
42 private BufferedInputStream bufferedIn
;
44 private static int proxyPort
= 80;
45 private static boolean proxyInUse
= false;
46 private static String proxyHost
= null;
50 // Recognize some networking properties listed at
51 // http://java.sun.com/j2se/1.4/docs/guide/net/properties.html.
53 proxyHost
= System
.getProperty("http.proxyHost");
54 if (proxyHost
!= null)
57 if ((port
= System
.getProperty("http.proxyPort")) != null)
61 proxyPort
= Integer
.parseInt(port
);
71 public Connection(URL url
)
74 requestProperties
= (Hashtable
) defRequestProperties
.clone();
77 // Override method in URLConnection.
78 public static void setDefaultRequestProperty(String key
, String value
)
80 defRequestProperties
.put(key
, value
);
83 // Override method in URLConnection.
84 public static String
getDefaultRequestProperty(String key
)
86 return (String
) defRequestProperties
.get(key
);
89 // Override method in URLConnection.
90 public void setRequestProperty(String key
, String value
)
93 throw new IllegalAccessError("Connection already established.");
95 requestProperties
.put(key
, value
);
98 // Override method in URLConnection.
99 public String
getRequestProperty(String key
)
102 throw new IllegalAccessError("Connection already established.");
104 return (String
) requestProperties
.get(key
);
107 // Implementation of abstract method.
108 public void connect() throws IOException
110 // Call is ignored if already connected.
114 // Get address and port number.
119 sock
= new Socket(proxyHost
, port
);
123 InetAddress destAddr
= InetAddress
.getByName(url
.getHost());
124 if ((port
= url
.getPort()) == -1)
126 // Open socket and output stream.
127 sock
= new Socket(destAddr
, port
);
130 PrintWriter out
= new PrintWriter(sock
.getOutputStream());
132 // Send request including any request properties that were set.
133 out
.print(getRequestMethod() + " " + url
.getFile() + " HTTP/1.0\n");
134 out
.print("Host: " + url
.getHost() + ":" + port
+ "\n");
135 Enumeration reqKeys
= requestProperties
.keys();
136 Enumeration reqVals
= requestProperties
.elements();
137 while (reqKeys
.hasMoreElements())
138 out
.print(reqKeys
.nextElement() + ": " + reqVals
.nextElement() + "\n");
145 // Implementation of abstract method.
146 public void disconnect()
154 catch (IOException ex
)
156 ; // Ignore errors in closing socket.
162 public boolean usingProxy()
167 // Override default method in URLConnection.
168 public InputStream
getInputStream() throws IOException
174 throw new ProtocolException("Can't open InputStream if doInput is false");
178 // Override default method in URLConnection.
179 public OutputStream
getOutputStream() throws IOException
186 ProtocolException("Can't open OutputStream if doOutput is false");
187 return sock
.getOutputStream();
190 // Override default method in URLConnection.
191 public String
getHeaderField(String name
)
198 catch (IOException x
)
203 return (String
) hdrHash
.get(name
.toLowerCase());
206 // Override default method in URLConnection.
207 public Map
getHeaderFields()
214 catch (IOException x
)
222 // Override default method in URLConnection.
223 public String
getHeaderField(int n
)
230 catch (IOException x
)
235 if (n
< hdrVec
.size())
236 return getField((String
) hdrVec
.elementAt(n
));
240 // Override default method in URLConnection.
241 public String
getHeaderFieldKey(int n
)
248 catch (IOException x
)
253 if (n
< hdrVec
.size())
254 return getKey((String
) hdrVec
.elementAt(n
));
258 private String
getKey(String str
)
262 int index
= str
.indexOf(':');
264 return str
.substring(0, index
);
269 private String
getField(String str
)
273 int index
= str
.indexOf(':');
275 return str
.substring(index
+ 1).trim();
280 private void getHttpHeaders() throws IOException
282 // Originally tried using a BufferedReader here to take advantage of
283 // the readLine method and avoid the following, but the buffer read
284 // past the end of the headers so the first part of the content was lost.
285 // It is probably more robust than it needs to be, e.g. the byte[]
286 // is unlikely to overflow and a '\r' should always be followed by a '\n',
287 // but it is better to be safe just in case.
288 bufferedIn
= new BufferedInputStream(sock
.getInputStream());
291 byte[] buf
= new byte[buflen
];
293 boolean gotnl
= false;
294 byte[] ch
= new byte[1];
299 // Check for leftover byte from non-'\n' after a '\r'.
301 line
= line
+ '\r' + new String(ch
, 0, 1);
304 // FIXME: This is rather inefficient.
305 for (i
= 0; i
< buflen
; i
++)
307 buf
[i
] = (byte) bufferedIn
.read();
309 throw new IOException("Malformed HTTP header");
312 bufferedIn
.read(ch
, 0, 1);
318 line
= line
+ new String(buf
, 0, i
);
320 // A '\r' '\n' combo indicates the end of the header entry.
321 // If it wasn't found, cycle back through the loop and append
322 // to 'line' until one is found.
325 // A zero length entry signals the end of the headers.
326 if (line
.length() == 0)
329 // Store the header and reinitialize for next cycle.
330 hdrVec
.addElement(line
);
331 String key
= getKey(line
);
333 hdrHash
.put(key
.toLowerCase(), getField(line
));