1 package net.chiark.yarrg;
3 import java.net.URLConnection;
5 import java.io.IOException;
6 import java.util.HashMap;
9 import java.io.InputStream;
10 import java.util.Random;
11 import java.io.OutputStream;
12 import java.io.FileInputStream;
13 import java.util.Iterator;
16 * <p>Title: Client HTTP Request class</p>
17 * <p>Description: this class helps to send POST HTTP requests with various form data,
18 * including files. Cookies can be added to be included in the request.</p>
20 * <p>Modified by Ted Pearson(ted@tedpearson.com) 5/4/09</p>
21 * <p>Modified by Owen Dunn and Ian Jackson 2009, 2010<p>
23 * Originally this was called "com.myjavatools.web.ClientHttpRequest"
24 * but since we have changed it to be incompatible and it's a very
25 * old version, we have renamed it. - Ian Jackson September 2010.
27 * @author Vlad Patryshev
31 public class ClientHttpRequest {
32 URLConnection connection;
33 OutputStream os = null;
34 Map cookies = new HashMap();
36 protected void connect() throws IOException {
37 if (os == null) os = connection.getOutputStream();
40 protected void write(char c) throws IOException {
45 protected void write(String s) throws IOException {
47 os.write(s.getBytes());
50 protected void newline() throws IOException {
55 protected void writeln(String s) throws IOException {
61 private static Random random = new Random();
63 protected static String randomString() {
64 return Long.toString(random.nextLong(), 36);
67 String boundary = "---------------------------" + randomString() + randomString() + randomString();
69 private void boundary() throws IOException {
75 * Creates a new multipart POST HTTP request on a freshly opened URLConnection
77 * @param connection an already open URL connection
80 public ClientHttpRequest(URLConnection connection) throws IOException {
81 this.connection = connection;
82 connection.setDoOutput(true);
83 connection.setRequestProperty("Content-Type",
84 "multipart/form-data; boundary=" + boundary);
88 * Creates a new multipart POST HTTP request for a specified URL
90 * @param url the URL to send request to
93 public ClientHttpRequest(URL url) throws IOException {
94 this(url.openConnection());
98 * Creates a new multipart POST HTTP request for a specified URL string
100 * @param urlString the string representation of the URL to send request to
101 * @throws IOException
103 public ClientHttpRequest(String urlString) throws IOException {
104 this(new URL(urlString));
108 private void postCookies() {
109 StringBuffer cookieList = new StringBuffer();
111 for (Iterator i = cookies.entrySet().iterator(); i.hasNext();) {
112 Map.Entry entry = (Map.Entry)(i.next());
113 cookieList.append(entry.getKey().toString() + "=" + entry.getValue());
116 cookieList.append("; ");
119 if (cookieList.length() > 0) {
120 connection.setRequestProperty("Cookie", cookieList.toString());
125 * adds a cookie to the requst
126 * @param name cookie name
127 * @param value cookie value
128 * @throws IOException
130 public void setCookie(String name, String value) throws IOException {
131 cookies.put(name, value);
135 * adds cookies to the request
136 * @param cookies the cookie "name-to-value" map
137 * @throws IOException
139 public void setCookies(Map cookies) throws IOException {
140 if (cookies == null) return;
141 this.cookies.putAll(cookies);
145 * adds cookies to the request
146 * @param cookies array of cookie names and values (cookies[2*i] is a name, cookies[2*i + 1] is a value)
147 * @throws IOException
149 public void setCookies(String[] cookies) throws IOException {
150 if (cookies == null) return;
151 for (int i = 0; i < cookies.length - 1; i+=2) {
152 setCookie(cookies[i], cookies[i+1]);
156 private void writeName(String name) throws IOException {
158 write("Content-Disposition: form-data; name=\"");
164 * adds a string parameter to the request
165 * @param name parameter name
166 * @param value parameter value
167 * @throws IOException
169 public void setParameter(String name, String value) throws IOException {
172 newline(); newline();
176 private static void pipe(InputStream in, OutputStream out) throws IOException {
177 byte[] buf = new byte[500000];
182 while((nread = in.read(buf, 0, buf.length)) >= 0) {
183 out.write(buf, 0, nread);
192 * adds a file parameter to the request
193 * @param name parameter name
194 * @param filename the name of the file
195 * @param is input stream to read the contents of the file from
196 * @throws IOException
198 public void setParameter(String name, String filename, InputStream is) throws IOException {
199 String type = connection.guessContentTypeFromName(filename);
200 if (type == null) type = "application/octet-stream";
201 setParameter(name, filename, is, type);
205 * adds a file parameter to the request
206 * @param name parameter name
207 * @param filename the name of the file
208 * @param is input stream to read the contents of the file from
209 * @param type Content-Type of the file
210 * @throws IOException
212 public void setParameter(String name, String filename, InputStream is, String type) throws IOException {
215 write("; filename=\"");
219 write("Content-Type: ");
227 * adds a file parameter to the request
228 * @param name parameter name
229 * @param file the file to upload
230 * @throws IOException
232 public void setParameter(String name, File file) throws IOException {
233 setParameter(name, file.getPath(), new FileInputStream(file));
237 * adds a parameter to the request; if the parameter is a File, the file is uploaded, otherwise the string value of the parameter is passed in the request
238 * @param name parameter name
239 * @param object parameter value, a File or anything else that can be stringified
240 * @throws IOException
242 public void setParameter(String name, Object object) throws IOException {
243 if (object instanceof File) {
244 setParameter(name, (File) object);
246 setParameter(name, object.toString());
251 * adds parameters to the request
252 * @param parameters "name-to-value" map of parameters; if a value is a file, the file is uploaded, otherwise it is stringified and sent in the request
253 * @throws IOException
255 public void setParameters(Map parameters) throws IOException {
256 if (parameters == null) return;
257 for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) {
258 Map.Entry entry = (Map.Entry)i.next();
259 setParameter(entry.getKey().toString(), entry.getValue());
264 * adds parameters to the request
265 * @param parameters array of parameter names and values (parameters[2*i] is a name, parameters[2*i + 1] is a value); if a value is a file, the file is uploaded, otherwise it is stringified and sent in the request
266 * @throws IOException
268 public void setParameters(Object[] parameters) throws IOException {
269 if (parameters == null) return;
270 for (int i = 0; i < parameters.length - 1; i+=2) {
271 setParameter(parameters[i].toString(), parameters[i+1]);
276 * posts the requests to the server, with all the cookies and parameters that were added
277 * @return input stream with the server response
278 * @throws IOException
280 public InputStream post() throws IOException {
286 tis = connection.getInputStream();
287 } catch (IOException e) {
288 tis = ((java.net.HttpURLConnection) connection).getErrorStream();
294 * posts the requests to the server, with all the cookies and parameters that were added before (if any), and with parameters that are passed in the argument
295 * @param parameters request parameters
296 * @return input stream with the server response
297 * @throws IOException
300 public InputStream post(Map parameters) throws IOException {
301 setParameters(parameters);
306 * posts the requests to the server, with all the cookies and parameters that were added before (if any), and with parameters that are passed in the argument
307 * @param parameters request parameters
308 * @return input stream with the server response
309 * @throws IOException
312 public InputStream post(Object[] parameters) throws IOException {
313 setParameters(parameters);
318 * posts the requests to the server, with all the cookies and parameters that were added before (if any), and with cookies and parameters that are passed in the arguments
319 * @param cookies request cookies
320 * @param parameters request parameters
321 * @return input stream with the server response
322 * @throws IOException
326 public InputStream post(Map cookies, Map parameters) throws IOException {
328 setParameters(parameters);
333 * posts the requests to the server, with all the cookies and parameters that were added before (if any), and with cookies and parameters that are passed in the arguments
334 * @param cookies request cookies
335 * @param parameters request parameters
336 * @return input stream with the server response
337 * @throws IOException
341 public InputStream post(String[] cookies, Object[] parameters) throws IOException {
343 setParameters(parameters);
348 * post the POST request to the server, with the specified parameter
349 * @param name parameter name
350 * @param value parameter value
351 * @return input stream with the server response
352 * @throws IOException
355 public InputStream post(String name, Object value) throws IOException {
356 setParameter(name, value);
361 * post the POST request to the server, with the specified parameters
362 * @param name1 first parameter name
363 * @param value1 first parameter value
364 * @param name2 second parameter name
365 * @param value2 second parameter value
366 * @return input stream with the server response
367 * @throws IOException
370 public InputStream post(String name1, Object value1, String name2, Object value2) throws IOException {
371 setParameter(name1, value1);
372 return post(name2, value2);
376 * post the POST request to the server, with the specified parameters
377 * @param name1 first parameter name
378 * @param value1 first parameter value
379 * @param name2 second parameter name
380 * @param value2 second parameter value
381 * @param name3 third parameter name
382 * @param value3 third parameter value
383 * @return input stream with the server response
384 * @throws IOException
387 public InputStream post(String name1, Object value1, String name2, Object value2, String name3, Object value3) throws IOException {
388 setParameter(name1, value1);
389 return post(name2, value2, name3, value3);
393 * post the POST request to the server, with the specified parameters
394 * @param name1 first parameter name
395 * @param value1 first parameter value
396 * @param name2 second parameter name
397 * @param value2 second parameter value
398 * @param name3 third parameter name
399 * @param value3 third parameter value
400 * @param name4 fourth parameter name
401 * @param value4 fourth parameter value
402 * @return input stream with the server response
403 * @throws IOException
406 public InputStream post(String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) throws IOException {
407 setParameter(name1, value1);
408 return post(name2, value2, name3, value3, name4, value4);
412 * posts a new request to specified URL, with parameters that are passed in the argument
413 * @param parameters request parameters
414 * @return input stream with the server response
415 * @throws IOException
418 public static InputStream post(URL url, Map parameters) throws IOException {
419 return new ClientHttpRequest(url).post(parameters);
423 * posts a new request to specified URL, with parameters that are passed in the argument
424 * @param parameters request parameters
425 * @return input stream with the server response
426 * @throws IOException
429 public static InputStream post(URL url, Object[] parameters) throws IOException {
430 return new ClientHttpRequest(url).post(parameters);
434 * posts a new request to specified URL, with cookies and parameters that are passed in the argument
435 * @param cookies request cookies
436 * @param parameters request parameters
437 * @return input stream with the server response
438 * @throws IOException
442 public static InputStream post(URL url, Map cookies, Map parameters) throws IOException {
443 return new ClientHttpRequest(url).post(cookies, parameters);
447 * posts a new request to specified URL, with cookies and parameters that are passed in the argument
448 * @param cookies request cookies
449 * @param parameters request parameters
450 * @return input stream with the server response
451 * @throws IOException
455 public static InputStream post(URL url, String[] cookies, Object[] parameters) throws IOException {
456 return new ClientHttpRequest(url).post(cookies, parameters);
460 * post the POST request specified URL, with the specified parameter
461 * @param name parameter name
462 * @param value parameter value
463 * @return input stream with the server response
464 * @throws IOException
467 public static InputStream post(URL url, String name1, Object value1) throws IOException {
468 return new ClientHttpRequest(url).post(name1, value1);
472 * post the POST request to specified URL, with the specified parameters
473 * @param name1 first parameter name
474 * @param value1 first parameter value
475 * @param name2 second parameter name
476 * @param value2 second parameter value
477 * @return input stream with the server response
478 * @throws IOException
481 public static InputStream post(URL url, String name1, Object value1, String name2, Object value2) throws IOException {
482 return new ClientHttpRequest(url).post(name1, value1, name2, value2);
486 * post the POST request to specified URL, with the specified parameters
487 * @param name1 first parameter name
488 * @param value1 first parameter value
489 * @param name2 second parameter name
490 * @param value2 second parameter value
491 * @param name3 third parameter name
492 * @param value3 third parameter value
493 * @return input stream with the server response
494 * @throws IOException
497 public static InputStream post(URL url, String name1, Object value1, String name2, Object value2, String name3, Object value3) throws IOException {
498 return new ClientHttpRequest(url).post(name1, value1, name2, value2, name3, value3);
502 * post the POST request to specified URL, with the specified parameters
503 * @param name1 first parameter name
504 * @param value1 first parameter value
505 * @param name2 second parameter name
506 * @param value2 second parameter value
507 * @param name3 third parameter name
508 * @param value3 third parameter value
509 * @param name4 fourth parameter name
510 * @param value4 fourth parameter value
511 * @return input stream with the server response
512 * @throws IOException
515 public static InputStream post(URL url, String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) throws IOException {
516 return new ClientHttpRequest(url).post(name1, value1, name2, value2, name3, value3, name4, value4);