Accepting code review comments ... simple stuff
[simpleHTTP.git] / src / eu / cepl / network / SimpleHTTP.java
blobe86e1769127c9b24238b9f87ee34677b24031b0f
1 package eu.cepl.network;
3 /*
4 * TODO:
5 * - I have to figure out how to switch on logging for HTTP protocol
6 * - Location:
7 * - Cookies!
8 */
9 import java.io.BufferedInputStream;
10 import java.io.BufferedOutputStream;
11 import java.io.ByteArrayInputStream;
12 import java.io.IOException;
13 import java.io.InputStreamReader;
14 import java.io.UnsupportedEncodingException;
15 import java.net.HttpURLConnection;
16 import java.net.MalformedURLException;
17 import java.net.URL;
18 import java.net.URLConnection;
19 import java.net.URLEncoder;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Map.Entry;
24 public class SimpleHTTP {
26 private URL url = null;
27 private BufferedInputStream inBS = null;
28 private BufferedOutputStream outBS = null;
29 // private ConsoleHandler hand = new ConsoleHandler();
30 private URLConnection conn = null;
31 private int responseCode = 0;
33 final static int BUFMAX = 1024;
35 // private static Logger logger =
36 // Logger.getLogger(SimpleHTTP.class.getName());
37 /**
41 public SimpleHTTP() {
42 // logger.addHandler(hand);
43 // hand.setFormatter(new ReallySimpleFormatter());
45 // if (new Boolean(System.getProperty("debugging"))) {
46 // hand.setLevel(Level.FINE);
47 // logger.setLevel(Level.FINE);
48 // } else {
49 // hand.setLevel(Level.INFO);
50 // logger.setLevel(Level.INFO);
51 // }
54 /**
56 * @param inURL
58 public SimpleHTTP(URL inURL) {
59 init(inURL);
62 /**
64 * @param strURL
65 * @throws MalformedURLException
67 public SimpleHTTP(String strURL) throws MalformedURLException {
68 init(new URL(strURL));
71 /**
73 * @param initURL
75 private void init(URL initURL) {
76 url = initURL;
79 /**
80 * @param responseCode
81 * the responseCode to set
83 protected void setResponseCode(int responseCode) {
84 this.responseCode = responseCode;
87 /**
88 * @return the responseCode
90 public int getResponseCode() {
91 return responseCode;
94 /**
96 * @return
98 public URL getUrl() {
99 return url;
104 * @param headers
105 * @return
106 * @throws IOException
108 private URLConnection getConnection(Map<String, String> headers)
109 throws IOException {
110 if (headers == null) {
111 headers = new HashMap<String, String>();
113 if (conn == null) {
114 conn = url.openConnection();
115 for (Entry<String, String> e : headers.entrySet()) {
116 conn.addRequestProperty(e.getKey(), e.getValue());
119 return conn;
123 * Provides {@link BufferedOutputStream} for writing (via POST method) to
124 * the URL.
126 * @param headers
127 * @return BufferedOutputStream for current URL
128 * @throws IOException
129 * @see getResponseCode
131 * When the stream is later closed, {@literal getResponseCode} returns
132 * response code of the executed HTTP request (if our current URL is
133 * HTTP, that is).
135 public BufferedOutputStream getWriter(Map<String, String> headers)
136 throws IOException {
137 try {
138 conn = getConnection(headers);
139 conn.setDoOutput(true);
140 outBS = new BufferedOutputStream(conn.getOutputStream());
141 } catch (UnsupportedEncodingException e) {
142 // Cannot happen, UTF-8 is correct.
143 } catch (IOException e) {
144 throw new IOException("Cannot read from the HTTP command results.",
147 return outBS;
151 * Provides {@link BufferedInputStream} pointing to the URL.
153 * @param headers
154 * @return BufferedInputStream for reading the remote content from URL
155 * @throws IOException
156 * @see getResponseCode
158 * When the stream is later closed, {@literal getResponseCode} returns
159 * response code of the executed HTTP request (if our current URL is
160 * HTTP, that is).
162 public BufferedInputStream getInputStream(Map<String, String> headers)
163 throws IOException {
164 try {
165 conn = getConnection(headers);
166 inBS = new BufferedInputStream(conn.getInputStream());
167 } catch (IOException e) {
168 System.err.println("Cannot create BufferedInputStream for URL "
169 + url.toString());
170 e.printStackTrace();
171 throw e;
173 return inBS;
177 * reads whole stream into string
179 * @param in
180 * incoming byte stream
181 * @return String in UTF-8 encoding
182 * @throws IOException
184 String suck(BufferedInputStream in) throws IOException {
185 StringBuffer inBuf = new StringBuffer();
186 InputStreamReader inR = null;
187 int count = 0;
189 try {
190 inR = new InputStreamReader(in, "UTF-8");
191 } catch (UnsupportedEncodingException e) {
192 // Cannot happen, UTF-8 is always supported
194 char[] cbuf = new char[BUFMAX];
196 while ((count = inR.read(cbuf)) != -1) {
197 inBuf.append(cbuf, 0, count);
200 inR.close();
201 if (conn instanceof HttpURLConnection) {
202 setResponseCode(((HttpURLConnection) this.conn).getResponseCode());
205 return inBuf.toString();
209 * Convenience method for getting {@link String} from the URL with
210 * possibility to set request headers.
212 * @param headers
213 * Map<String,String> with the name, value pairs of HTTP request
214 * headers.
215 * @return String with the remote content
216 * @throws IOException
218 public String get(Map<String, String> headers) throws IOException {
219 BufferedInputStream inCh;
221 if (headers == null) {
222 headers = new HashMap<String, String>();
225 try {
226 inCh = getInputStream(headers);
227 } catch (IOException e) {
228 throw new IOException("Cannot create Reader for URL "
229 + url.toString(), e);
232 return suck(inCh);
236 * The most simple convenience method for getting {@link String} from the
237 * remote URL.
239 * @return String with the remote content
240 * @throws IOException
242 public String get() throws IOException {
243 return get(null);
248 * @param inStream
249 * @param headers
250 * @param mime
251 * String with MIME type of data in {@literal inStream}
252 * @return BufferedInputStream with the data returned from the server
253 * @throws IOException
255 @SuppressWarnings("unused")
256 public BufferedInputStream post(BufferedInputStream inStream,
257 Map<String, String> headers, String mime) throws IOException {
259 BufferedOutputStream outCh;
260 BufferedInputStream inCh;
261 long inLen = 0;
262 int c = 0;
263 byte[] inBuf = new byte[BUFMAX];
264 String mimeType = "";
266 if (mime == null) {
267 mimeType = "application/octet-stream";
268 } else {
269 mimeType = mime;
272 if (headers == null) {
273 headers = new HashMap<String, String>();
276 if (inLen > 0) {
277 headers.put("Content-Type", mimeType);
278 headers.put("Content-Length", Long.toString(inLen));
281 try {
282 outCh = getWriter(headers);
283 while ((c = inStream.read(inBuf)) != -1) {
284 outCh.write(inBuf);
286 outCh.flush();
287 outCh.close();
288 } catch (IOException e) {
289 throw new IOException("Cannot POST to URL " + url.toString(), e);
292 if (conn instanceof HttpURLConnection) {
293 setResponseCode(((HttpURLConnection) this.conn).getResponseCode());
296 try {
297 inCh = getInputStream(null);
298 } catch (IOException e) {
299 throw new IOException("Cannot create Reader for URL "
300 + url.toString(), e);
303 return inCh;
307 * The main POST method for the object, expected to be used most. Both
308 * accepts data as String and returnes back String as a result.
310 * @param data
311 * String with data to be sent in the body of POST
312 * @param headers
313 * Map with pairs of String ... name of the header and the value
314 * of the header.
315 * @return String with the result of the calling POST
316 * @throws IOException
318 public String post(String data, Map<String, String> headers)
319 throws IOException {
321 return suck(post(new BufferedInputStream(new ByteArrayInputStream(data
322 .getBytes("UTF-8"))), headers,
323 "application/x-www-form-urlencoded"));
328 * @param inDict
329 * @param headers
330 * @return
331 * @throws IOException
333 public String post(Map<String, String> inDict, Map<String, String> headers)
334 throws IOException {
335 String strData = "";
337 for (Entry<String, String> e : inDict.entrySet()) {
338 try {
339 strData += URLEncoder.encode(e.getKey(), "UTF-8") + "="
340 + URLEncoder.encode(e.getValue(), "UTF-8") + "&";
341 } catch (UnsupportedEncodingException e1) {
342 // Never happens, UTF-8 is always supported
345 if (strData.charAt(strData.length() - 1) == '&') {
346 strData = strData.substring(0, strData.length() - 1);
348 return post(strData, headers);
353 * @param inData
354 * @return
355 * @throws IOException
357 public String post(String inData) throws IOException {
358 return post(inData, null);
363 * @param inDict
364 * @return
365 * @throws IOException
367 public String post(Map<String, String> inDict) throws IOException {
368 return post(inDict, null);