/******************************************************************************* * * The authorship of this code and the accompanying materials is held by * medshare GmbH, Switzerland. All rights reserved. * http://medshare.net * * This code and the accompanying materials are made available under * the terms of the Eclipse Public License v1.0 * * Year of publication: 2012 * *******************************************************************************/ package net.medshare.connector.aerztekasse.invoice; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Random; import javax.net.ssl.HttpsURLConnection; /** * <p> * Title: Client HTTP Request class * </p> * <p> * Description: this class helps to send POST HTTP requests with various form data, including files. * Cookies can be added to be included in the request. * </p> * * @author Vlad Patryshev * @version 1.0 */ public class ClientHttpRequest { HttpsURLConnection connection; OutputStream os = null; Map cookies = new HashMap(); protected void connect() throws IOException{ if (os == null) os = connection.getOutputStream(); } protected void write(char c) throws IOException{ connect(); os.write(c); } protected void write(String s) throws IOException{ connect(); os.write(s.getBytes()); } protected void newline() throws IOException{ connect(); write("\r\n"); //$NON-NLS-1$ } protected void writeln(String s) throws IOException{ connect(); write(s); newline(); } private static Random random = new Random(); protected static String randomString(){ return Long.toString(random.nextLong(), 36); } String boundary = "---------------------------" + randomString() + randomString() //$NON-NLS-1$ + randomString(); private void boundary() throws IOException{ write("--"); //$NON-NLS-1$ write(boundary); } /** * Creates a new multipart POST HTTP request on a freshly opened HttpsURLConnection * * @param connection * an already open URL connection * @throws IOException */ public ClientHttpRequest(HttpsURLConnection connection) throws IOException{ this.connection = connection; connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Creates a new multipart POST HTTP request for a specified URL * * @param url * the URL to send request to * @throws IOException */ public ClientHttpRequest(URL url) throws IOException{ this((HttpsURLConnection) url.openConnection()); } /** * Creates a new multipart POST HTTP request for a specified URL string * * @param urlString * the string representation of the URL to send request to * @throws IOException */ public ClientHttpRequest(String urlString) throws IOException{ this(new URL(urlString)); } private void postCookies(){ StringBuffer cookieList = new StringBuffer(); for (Iterator i = cookies.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) (i.next()); cookieList.append(entry.getKey().toString() + "=" + entry.getValue()); //$NON-NLS-1$ if (i.hasNext()) { cookieList.append("; "); //$NON-NLS-1$ } } if (cookieList.length() > 0) { connection.setRequestProperty("Cookie", cookieList.toString()); //$NON-NLS-1$ } } /** * adds a cookie to the requst * * @param name * cookie name * @param value * cookie value * @throws IOException */ public void setCookie(String name, String value) throws IOException{ cookies.put(name, value); } /** * adds cookies to the request * * @param cookies * the cookie "name-to-value" map * @throws IOException */ public void setCookies(Map cookies) throws IOException{ if (cookies == null) return; this.cookies.putAll(cookies); } /** * adds cookies to the request * * @param cookies * array of cookie names and values (cookies[2*i] is a name, cookies[2*i + 1] is a * value) * @throws IOException */ public void setCookies(String[] cookies) throws IOException{ if (cookies == null) return; for (int i = 0; i < cookies.length - 1; i += 2) { setCookie(cookies[i], cookies[i + 1]); } } private void writeName(String name) throws IOException{ newline(); write("Content-Disposition: form-data; name=\""); //$NON-NLS-1$ write(name); write('"'); } /** * adds a string parameter to the request * * @param name * parameter name * @param value * parameter value * @throws IOException */ public void setParameter(String name, String value) throws IOException{ boundary(); writeName(name); newline(); newline(); writeln(value); } private static void pipe(InputStream in, OutputStream out) throws IOException{ byte[] buf = new byte[500000]; int nread; int navailable; int total = 0; synchronized (in) { while ((nread = in.read(buf, 0, buf.length)) >= 0) { out.write(buf, 0, nread); total += nread; } } out.flush(); buf = null; } /** * adds a file parameter to the request * * @param name * parameter name * @param filename * the name of the file * @param is * input stream to read the contents of the file from * @throws IOException */ public void setParameter(String name, String filename, InputStream is) throws IOException{ boundary(); writeName(name); write("; filename=\""); //$NON-NLS-1$ write(filename); write('"'); newline(); write("Content-Type: "); //$NON-NLS-1$ String type = connection.guessContentTypeFromName(filename); if (type == null) type = "application/octet-stream"; //$NON-NLS-1$ writeln(type); newline(); pipe(is, os); newline(); } /** * adds a file parameter to the request * * @param name * parameter name * @param file * the file to upload * @throws IOException */ public void setParameter(String name, File file) throws IOException{ setParameter(name, file.getPath(), new FileInputStream(file)); } /** * 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 * * @param name * parameter name * @param object * parameter value, a File or anything else that can be stringified * @throws IOException */ public void setParameter(String name, Object object) throws IOException{ if (object instanceof File) { setParameter(name, (File) object); } else { setParameter(name, object.toString()); } } /** * adds parameters to the request * * @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 * @throws IOException */ public void setParameters(Map parameters) throws IOException{ if (parameters == null) return; for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); setParameter(entry.getKey().toString(), entry.getValue()); } } /** * adds parameters to the request * * @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 * @throws IOException */ public void setParameters(Object[] parameters) throws IOException{ if (parameters == null) return; for (int i = 0; i < parameters.length - 1; i += 2) { setParameter(parameters[i].toString(), parameters[i + 1]); } } /** * posts the requests to the server, with all the cookies and parameters that were added * * @return input stream with the server response * @throws IOException */ public InputStream post() throws IOException{ boundary(); writeln("--"); //$NON-NLS-1$ os.close(); return connection.getInputStream(); } /** * 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 * * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setParameters */ public InputStream post(Map parameters) throws IOException{ setParameters(parameters); return post(); } /** * 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 * * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setParameters */ public InputStream post(Object[] parameters) throws IOException{ setParameters(parameters); return post(); } /** * 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 * * @param cookies * request cookies * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setParameters * @see setCookies */ public InputStream post(Map cookies, Map parameters) throws IOException{ setCookies(cookies); setParameters(parameters); return post(); } /** * 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 * * @param cookies * request cookies * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setParameters * @see setCookies */ public InputStream post(String[] cookies, Object[] parameters) throws IOException{ setCookies(cookies); setParameters(parameters); return post(); } /** * post the POST request to the server, with the specified parameter * * @param name * parameter name * @param value * parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public InputStream post(String name, Object value) throws IOException{ setParameter(name, value); return post(); } /** * post the POST request to the server, with the specified parameters * * @param name1 * first parameter name * @param value1 * first parameter value * @param name2 * second parameter name * @param value2 * second parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public InputStream post(String name1, Object value1, String name2, Object value2) throws IOException{ setParameter(name1, value1); return post(name2, value2); } /** * post the POST request to the server, with the specified parameters * * @param name1 * first parameter name * @param value1 * first parameter value * @param name2 * second parameter name * @param value2 * second parameter value * @param name3 * third parameter name * @param value3 * third parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public InputStream post(String name1, Object value1, String name2, Object value2, String name3, Object value3) throws IOException{ setParameter(name1, value1); return post(name2, value2, name3, value3); } /** * post the POST request to the server, with the specified parameters * * @param name1 * first parameter name * @param value1 * first parameter value * @param name2 * second parameter name * @param value2 * second parameter value * @param name3 * third parameter name * @param value3 * third parameter value * @param name4 * fourth parameter name * @param value4 * fourth parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public InputStream post(String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) throws IOException{ setParameter(name1, value1); return post(name2, value2, name3, value3, name4, value4); } /** * posts a new request to specified URL, with parameters that are passed in the argument * * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setParameters */ public static InputStream post(URL url, Map parameters) throws IOException{ return new ClientHttpRequest(url).post(parameters); } /** * posts a new request to specified URL, with parameters that are passed in the argument * * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setParameters */ public static InputStream post(URL url, Object[] parameters) throws IOException{ return new ClientHttpRequest(url).post(parameters); } /** * posts a new request to specified URL, with cookies and parameters that are passed in the * argument * * @param cookies * request cookies * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setCookies * @see setParameters */ public static InputStream post(URL url, Map cookies, Map parameters) throws IOException{ return new ClientHttpRequest(url).post(cookies, parameters); } /** * posts a new request to specified URL, with cookies and parameters that are passed in the * argument * * @param cookies * request cookies * @param parameters * request parameters * @return input stream with the server response * @throws IOException * @see setCookies * @see setParameters */ public static InputStream post(URL url, String[] cookies, Object[] parameters) throws IOException{ return new ClientHttpRequest(url).post(cookies, parameters); } /** * post the POST request specified URL, with the specified parameter * * @param name * parameter name * @param value * parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public static InputStream post(URL url, String name1, Object value1) throws IOException{ return new ClientHttpRequest(url).post(name1, value1); } /** * post the POST request to specified URL, with the specified parameters * * @param name1 * first parameter name * @param value1 * first parameter value * @param name2 * second parameter name * @param value2 * second parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public static InputStream post(URL url, String name1, Object value1, String name2, Object value2) throws IOException{ return new ClientHttpRequest(url).post(name1, value1, name2, value2); } /** * post the POST request to specified URL, with the specified parameters * * @param name1 * first parameter name * @param value1 * first parameter value * @param name2 * second parameter name * @param value2 * second parameter value * @param name3 * third parameter name * @param value3 * third parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public static InputStream post(URL url, String name1, Object value1, String name2, Object value2, String name3, Object value3) throws IOException{ return new ClientHttpRequest(url).post(name1, value1, name2, value2, name3, value3); } /** * post the POST request to specified URL, with the specified parameters * * @param name1 * first parameter name * @param value1 * first parameter value * @param name2 * second parameter name * @param value2 * second parameter value * @param name3 * third parameter name * @param value3 * third parameter value * @param name4 * fourth parameter name * @param value4 * fourth parameter value * @return input stream with the server response * @throws IOException * @see setParameter */ public static InputStream post(URL url, String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) throws IOException{ return new ClientHttpRequest(url).post(name1, value1, name2, value2, name3, value3, name4, value4); } }