001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: HTTPRequest.java,v $ 023 Revision 1.7 2004/05/05 21:36:35 markl 024 comment block updates 025 026 Revision 1.6 2003/11/07 19:06:05 markl 027 bug fix 028 029 Revision 1.5 2003/01/19 09:37:12 markl 030 Javadoc & comment header updates. 031 032 Revision 1.4 2001/03/12 06:01:18 markl 033 Javadoc cleanup. 034 035 Revision 1.3 2001/03/12 01:58:42 markl 036 Source code cleanup. 037 038 Revision 1.2 2000/08/07 07:56:52 markl 039 *** empty log message *** 040 041 Revision 1.1 1999/06/03 08:07:22 markl 042 Initial revision 043 ---------------------------------------------------------------------------- 044*/ 045 046package kiwi.io; 047 048import java.io.*; 049import java.net.*; 050import java.util.*; 051 052/** This class represents an HTTP request, e.g., a single transaction with an 053 * HTTP server. It may be used to send arbitrary requests to an HTTP server. 054 * This class extends the abstract class 055 * <code>java.net.HttpURLConnection</code>; see the documentation on that class 056 * for more information. 057 * 058 * @author Mark Lindner 059 */ 060 061public class HTTPRequest extends HttpURLConnection 062 { 063 private Socket socket = null; 064 private static final char keySeparator = ':'; 065 private Hashtable keys = new Hashtable(); 066 private Vector headers = new Vector(), keyList = new Vector(); 067 private boolean gotHeaders = false; 068 private static final String CRLF = "\r\n"; 069 070 /** Construct a new <code>HTTPRequest</code> for the given URL. 071 * 072 * @param url The URL identifying the destination of the transaction. 073 */ 074 075 public HTTPRequest(URL url) 076 { 077 super(url); 078 } 079 080 /** Connect to the HTTP server. 081 * 082 * @exception java.io.IOException If the connection failed. 083 */ 084 085 public void connect() throws IOException 086 { 087 if(connected) return; 088 089 InetAddress dest = InetAddress.getByName(getURL().getHost()); 090 int port = getURL().getPort(); 091 if(port < 0) 092 port = 80; 093 094 socket = new Socket(dest, port); 095 OutputStream out = socket.getOutputStream(); 096 097 send(out, getRequestMethod() + " " + url.getFile() + " HTTP/1.0" + CRLF); 098 send(out, "Host: " + getURL().getHost() + CRLF); 099 send(out, CRLF); 100 101 InputStream in = socket.getInputStream(); 102 103 String status = recv(in); 104 105 StringTokenizer st = new StringTokenizer(status); 106 107 if(st.hasMoreTokens()) 108 { 109 st.nextToken(); 110 111 if(st.hasMoreTokens()) 112 { 113 responseCode = Integer.parseInt(st.nextToken()); 114 responseMessage = st.nextToken(""); 115 } 116 } 117 118 connected = true; 119 } 120 121 /** Disconnect from the HTTP server. */ 122 123 public void disconnect() 124 { 125 if(socket != null) 126 { 127 try 128 { 129 socket.close(); 130 } 131 catch(IOException ex) { /* ignore */ } 132 socket = null; 133 } 134 135 connected = false; 136 } 137 138 /** Determine if this implementation uses a proxy. 139 * 140 * @return This implementation returns <code>false</code>. 141 */ 142 143 public boolean usingProxy() 144 { 145 return(false); 146 } 147 148 /** Get the input stream associated with the request. If no connection has 149 * been established yet, an attempt is made to make one. 150 */ 151 152 public InputStream getInputStream() throws IOException 153 { 154 if(!connected) 155 connect(); 156 157 return(socket.getInputStream()); 158 } 159 160 /** Get the output stream associated with the request. If no connection has 161 * been established yet, an attempt is made to make one. 162 */ 163 164 public OutputStream getOutputStream() throws IOException 165 { 166 if(!connected) 167 connect(); 168 169 return(socket.getOutputStream()); 170 } 171 172 /** Get the header field value for the specified key. 173 * 174 * @param key The key. 175 * @return The value of the field. 176 */ 177 178 public String getHeaderField(String key) 179 { 180 getHeaders(); 181 return((String)keys.get(key.toLowerCase())); 182 } 183 184 /** Get the header field key for the specified position. 185 * 186 * @param n The position. 187 * @return The key of the header at the specified position. 188 */ 189 190 public String getHeaderFieldKey(int n) 191 { 192 getHeaders(); 193 if(n >= headers.size()) 194 return(null); 195 196 return((String)keyList.elementAt(n)); 197 } 198 199 /* send a line on a stream */ 200 201 private void send(OutputStream out, String s) throws IOException 202 { 203 //System.out.println("SEND: " + s); 204 205 for(int i = 0; i < s.length(); i++) 206 out.write((byte)s.charAt(i)); 207 208 out.flush(); 209 } 210 211 /* receive a line on a stream */ 212 213 private String recv(InputStream in) throws IOException 214 { 215 StringBuffer result = new StringBuffer(); 216 217 for(;;) 218 { 219 int c = in.read(); 220 221 if((c < 0) || (c == '\n')) 222 break; 223 224 if(c != '\r') 225 result.append((char)c); 226 } 227 228 String s = result.toString(); 229 230 //System.out.println("RECV: " + s); 231 232 return(s); 233 } 234 235 /** Retrieve header key/value pairs. */ 236 237 public void getHeaders() 238 { 239 if(gotHeaders) 240 return; 241 242 gotHeaders = true; 243 244 try 245 { 246 InputStream in = getInputStream(); 247 for(;;) 248 { 249 String header = recv(in); 250 if(header.length() == 0) 251 break; 252 253 // break out key & value 254 255 String key, value; 256 int i = header.indexOf(keySeparator); 257 if(i < 0) 258 { 259 key = header; 260 value = ""; 261 } 262 else 263 { 264 key = header.substring(0, i).toLowerCase(); 265 value = header.substring(++i).trim(); 266 } 267 268 keys.put(key, value); 269 keyList.addElement(key); 270 headers.addElement(header); 271 } 272 } 273 catch(IOException ex) 274 { 275 ex.printStackTrace(); 276 } 277 } 278 279 } 280 281/* end of source file */