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 InputStream tis = null;
35 Map cookies = new HashMap();
37 protected void connect() throws IOException {
38 if (os == null) os = connection.getOutputStream();
41 protected void write(char c) throws IOException {
46 protected void write(String s) throws IOException {
48 os.write(s.getBytes());
51 protected void newline() throws IOException {
56 protected void writeln(String s) throws IOException {
62 private static Random random = new Random();
64 protected static String randomString() {
65 return Long.toString(random.nextLong(), 36);
68 String boundary = "---------------------------" + randomString() + randomString() + randomString();
70 private void boundary() throws IOException {
76 * Creates a new multipart POST HTTP request on a freshly opened URLConnection
78 * @param connection an already open URL connection
81 public ClientHttpRequest(URLConnection connection) throws IOException {
82 this.connection = connection;
83 connection.setDoOutput(true);
84 connection.setRequestProperty("Content-Type",
85 "multipart/form-data; boundary=" + boundary);
89 * Creates a new multipart POST HTTP request for a specified URL
91 * @param url the URL to send request to
94 public ClientHttpRequest(URL url) throws IOException {
95 this(url.openConnection());
99 * Creates a new multipart POST HTTP request for a specified URL string
101 * @param urlString the string representation of the URL to send request to
102 * @throws IOException
104 public ClientHttpRequest(String urlString) throws IOException {
105 this(new URL(urlString));
109 private void postCookies() {
110 StringBuffer cookieList = new StringBuffer();
112 for (Iterator i = cookies.entrySet().iterator(); i.hasNext();) {
113 Map.Entry entry = (Map.Entry)(i.next());
114 cookieList.append(entry.getKey().toString() + "=" + entry.getValue());
117 cookieList.append("; ");
120 if (cookieList.length() > 0) {
121 connection.setRequestProperty("Cookie", cookieList.toString());
126 * adds a cookie to the requst
127 * @param name cookie name
128 * @param value cookie value
129 * @throws IOException
131 public void setCookie(String name, String value) throws IOException {
132 cookies.put(name, value);
136 * adds cookies to the request
137 * @param cookies the cookie "name-to-value" map
138 * @throws IOException
140 public void setCookies(Map cookies) throws IOException {
141 if (cookies == null) return;
142 this.cookies.putAll(cookies);
146 * adds cookies to the request
147 * @param cookies array of cookie names and values (cookies[2*i] is a name, cookies[2*i + 1] is a value)
148 * @throws IOException
150 public void setCookies(String[] cookies) throws IOException {
151 if (cookies == null) return;
152 for (int i = 0; i < cookies.length - 1; i+=2) {
153 setCookie(cookies[i], cookies[i+1]);
157 private void writeName(String name) throws IOException {
159 write("Content-Disposition: form-data; name=\"");
165 * adds a string parameter to the request
166 * @param name parameter name
167 * @param value parameter value
168 * @throws IOException
170 public void setParameter(String name, String value) throws IOException {
173 newline(); newline();
177 private static void pipe(InputStream in, OutputStream out) throws IOException {
178 byte[] buf = new byte[500000];
183 while((nread = in.read(buf, 0, buf.length)) >= 0) {
184 out.write(buf, 0, nread);
193 * adds a file parameter to the request
194 * @param name parameter name
195 * @param filename the name of the file
196 * @param is input stream to read the contents of the file from
197 * @throws IOException
199 public void setParameter(String name, String filename, InputStream is) throws IOException {
200 String type = connection.guessContentTypeFromName(filename);
201 if (type == null) type = "application/octet-stream";
202 setParameter(name, filename, is, type);
206 * adds a file parameter to the request
207 * @param name parameter name
208 * @param filename the name of the file
209 * @param is input stream to read the contents of the file from
210 * @param type Content-Type of the file
211 * @throws IOException
213 public void setParameter(String name, String filename, InputStream is, String type) throws IOException {
216 write("; filename=\"");
220 write("Content-Type: ");
228 * adds a file parameter to the request
229 * @param name parameter name
230 * @param file the file to upload
231 * @throws IOException
233 public void setParameter(String name, File file) throws IOException {
234 setParameter(name, file.getPath(), new FileInputStream(file));
238 * 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
239 * @param name parameter name
240 * @param object parameter value, a File or anything else that can be stringified
241 * @throws IOException
243 public void setParameter(String name, Object object) throws IOException {
244 if (object instanceof File) {
245 setParameter(name, (File) object);
247 setParameter(name, object.toString());
252 * adds parameters to the request
253 * @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
254 * @throws IOException
256 public void setParameters(Map parameters) throws IOException {
257 if (parameters == null) return;
258 for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) {
259 Map.Entry entry = (Map.Entry)i.next();
260 setParameter(entry.getKey().toString(), entry.getValue());
265 * adds parameters to the request
266 * @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
267 * @throws IOException
269 public void setParameters(Object[] parameters) throws IOException {
270 if (parameters == null) return;
271 for (int i = 0; i < parameters.length - 1; i+=2) {
272 setParameter(parameters[i].toString(), parameters[i+1]);
277 * posts the requests to the server, with all the cookies and parameters that were added
278 * @return input stream with the server response
279 * @throws IOException
281 public boolean post() throws IOException {
287 tis = connection.getInputStream();
289 } catch (IOException e) {
290 tis = ((java.net.HttpURLConnection) connection).getErrorStream();
296 public InputStream resultstream() {
301 * 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
302 * @param parameters request parameters
303 * @return input stream with the server response
304 * @throws IOException
307 public boolean post(Map parameters) throws IOException {
308 setParameters(parameters);
313 * 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
314 * @param parameters request parameters
315 * @return input stream with the server response
316 * @throws IOException
319 public boolean post(Object[] parameters) throws IOException {
320 setParameters(parameters);
325 * 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
326 * @param cookies request cookies
327 * @param parameters request parameters
328 * @return input stream with the server response
329 * @throws IOException
333 public boolean post(Map cookies, Map parameters) throws IOException {
335 setParameters(parameters);
340 * 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
341 * @param cookies request cookies
342 * @param parameters request parameters
343 * @return input stream with the server response
344 * @throws IOException
348 public boolean post(String[] cookies, Object[] parameters) throws IOException {
350 setParameters(parameters);
355 * post the POST request to the server, with the specified parameter
356 * @param name parameter name
357 * @param value parameter value
358 * @return input stream with the server response
359 * @throws IOException
362 public boolean post(String name, Object value) throws IOException {
363 setParameter(name, value);
368 * post the POST request to the server, with the specified parameters
369 * @param name1 first parameter name
370 * @param value1 first parameter value
371 * @param name2 second parameter name
372 * @param value2 second parameter value
373 * @return input stream with the server response
374 * @throws IOException
377 public boolean post(String name1, Object value1, String name2, Object value2) throws IOException {
378 setParameter(name1, value1);
379 return post(name2, value2);
383 * post the POST request to the server, with the specified parameters
384 * @param name1 first parameter name
385 * @param value1 first parameter value
386 * @param name2 second parameter name
387 * @param value2 second parameter value
388 * @param name3 third parameter name
389 * @param value3 third parameter value
390 * @return input stream with the server response
391 * @throws IOException
394 public boolean post(String name1, Object value1, String name2, Object value2, String name3, Object value3) throws IOException {
395 setParameter(name1, value1);
396 return post(name2, value2, name3, value3);
400 * post the POST request to the server, with the specified parameters
401 * @param name1 first parameter name
402 * @param value1 first parameter value
403 * @param name2 second parameter name
404 * @param value2 second parameter value
405 * @param name3 third parameter name
406 * @param value3 third parameter value
407 * @param name4 fourth parameter name
408 * @param value4 fourth parameter value
409 * @return input stream with the server response
410 * @throws IOException
413 public boolean post(String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) throws IOException {
414 setParameter(name1, value1);
415 return post(name2, value2, name3, value3, name4, value4);
419 * posts a new request to specified URL, with parameters that are passed in the argument
420 * @param parameters request parameters
421 * @return input stream with the server response
422 * @throws IOException
425 public static boolean post(URL url, Map parameters) throws IOException {
426 return new ClientHttpRequest(url).post(parameters);
430 * posts a new request to specified URL, with parameters that are passed in the argument
431 * @param parameters request parameters
432 * @return input stream with the server response
433 * @throws IOException
436 public static boolean post(URL url, Object[] parameters) throws IOException {
437 return new ClientHttpRequest(url).post(parameters);
441 * posts a new request to specified URL, with cookies and parameters that are passed in the argument
442 * @param cookies request cookies
443 * @param parameters request parameters
444 * @return input stream with the server response
445 * @throws IOException
449 public static boolean post(URL url, Map cookies, Map parameters) throws IOException {
450 return new ClientHttpRequest(url).post(cookies, parameters);
454 * posts a new request to specified URL, with cookies and parameters that are passed in the argument
455 * @param cookies request cookies
456 * @param parameters request parameters
457 * @return input stream with the server response
458 * @throws IOException
462 public static boolean post(URL url, String[] cookies, Object[] parameters) throws IOException {
463 return new ClientHttpRequest(url).post(cookies, parameters);
467 * post the POST request specified URL, with the specified parameter
468 * @param name parameter name
469 * @param value parameter value
470 * @return input stream with the server response
471 * @throws IOException
474 public static boolean post(URL url, String name1, Object value1) throws IOException {
475 return new ClientHttpRequest(url).post(name1, value1);
479 * post the POST request to specified URL, with the specified parameters
480 * @param name1 first parameter name
481 * @param value1 first parameter value
482 * @param name2 second parameter name
483 * @param value2 second parameter value
484 * @return input stream with the server response
485 * @throws IOException
488 public static boolean post(URL url, String name1, Object value1, String name2, Object value2) throws IOException {
489 return new ClientHttpRequest(url).post(name1, value1, name2, value2);
493 * post the POST request to specified URL, with the specified parameters
494 * @param name1 first parameter name
495 * @param value1 first parameter value
496 * @param name2 second parameter name
497 * @param value2 second parameter value
498 * @param name3 third parameter name
499 * @param value3 third parameter value
500 * @return input stream with the server response
501 * @throws IOException
504 public static boolean post(URL url, String name1, Object value1, String name2, Object value2, String name3, Object value3) throws IOException {
505 return new ClientHttpRequest(url).post(name1, value1, name2, value2, name3, value3);
509 * post the POST request to specified URL, with the specified parameters
510 * @param name1 first parameter name
511 * @param value1 first parameter value
512 * @param name2 second parameter name
513 * @param value2 second parameter value
514 * @param name3 third parameter name
515 * @param value3 third parameter value
516 * @param name4 fourth parameter name
517 * @param value4 fourth parameter value
518 * @return input stream with the server response
519 * @throws IOException
522 public static boolean post(URL url, String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) throws IOException {
523 return new ClientHttpRequest(url).post(name1, value1, name2, value2, name3, value3, name4, value4);