1 // Copyright (C) 2004, 2014 Christian Jaekl
3 package net.jaekl.qd.http;
5 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9 import java.io.UnsupportedEncodingException;
10 import java.lang.reflect.InvocationTargetException;
11 import java.nio.charset.Charset;
12 import java.util.ArrayList;
14 import net.jaekl.qd.QDException;
15 import net.jaekl.qd.util.ExceptionUtils;
16 import net.jaekl.qd.util.InputStreamWrapper;
17 import net.jaekl.qd.xml.ParseErrorHandler;
18 import net.jaekl.qd.xml.ParseHandler;
19 import net.jaekl.qd.xml.ParseResult;
21 import org.apache.http.HttpEntity;
22 import org.apache.http.HttpResponse;
23 import org.apache.http.NameValuePair;
24 import org.apache.http.client.HttpClient;
25 import org.apache.http.client.config.RequestConfig;
26 import org.apache.http.client.entity.UrlEncodedFormEntity;
27 import org.apache.http.client.methods.HttpPost;
28 import org.apache.http.impl.client.HttpClientBuilder;
29 import org.xml.sax.InputSource;
30 import org.xml.sax.SAXException;
31 import org.xml.sax.SAXParseException;
32 import org.xml.sax.XMLReader;
33 import org.xml.sax.helpers.XMLReaderFactory;
35 public class RequestBroker
37 final String UTF_8 = "UTF-8";
38 final int TIMEOUT_MSEC = 5000; // Allow at most 5 seconds before we declare the server to be unresponsive
41 ArrayList<NameValuePair> m_baseParams;
43 public RequestBroker(String gatewayUrl, ArrayList<NameValuePair> baseParams)
45 m_gatewayUrl = gatewayUrl;
46 m_baseParams = new ArrayList<NameValuePair>(baseParams);
49 // NB: Caller is responsible for close()ing the returned InputStream
51 InputStream doSubmit(String method, ArrayList<NameValuePair> passedParams) throws QDException
53 ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(m_baseParams);
54 params.addAll(passedParams);
57 RequestConfig.Builder requestBuilder = RequestConfig.custom();
58 requestBuilder = requestBuilder.setConnectTimeout(TIMEOUT_MSEC);
59 requestBuilder = requestBuilder.setSocketTimeout(TIMEOUT_MSEC);
60 HttpClientBuilder builder = HttpClientBuilder.create();
61 builder.setDefaultRequestConfig(requestBuilder.build());
62 HttpClient httpClient = builder.build();
63 HttpPost httpPost = new HttpPost(m_gatewayUrl + "/" + method + "/");
64 httpPost.setEntity(new UrlEncodedFormEntity(params, UTF_8));
65 HttpResponse response = httpClient.execute(httpPost);
66 HttpEntity entity = response.getEntity();
69 InputStream is = entity.getContent();
73 catch (UnsupportedEncodingException uee) {
74 // We should actually be guaranteed that this never happens,
75 // because all JVMs are required to support UTF-8
79 catch (IOException ioe) {
80 throw new QDException(ioe);
86 public String submit(String method, ArrayList<NameValuePair> passedParams) throws QDException
88 StringBuilder sb = new StringBuilder();
89 InputStream is = null;
92 is = doSubmit(method, passedParams);
93 BufferedReader br = new BufferedReader(new InputStreamReader(is));
94 String line = br.readLine();
95 while (null != line) {
96 sb.append(line).append("\n");
100 catch (IOException ioe) {
101 throw new QDException(ioe);
104 ExceptionUtils.tryClose(is);
107 return sb.toString();
110 public ParseResult submitAndParse(String method,
111 ArrayList<NameValuePair> passedParams,
112 Class<? extends ParseResult> rootParserClass)
115 return submitAndParse(method, passedParams, rootParserClass, null);
118 public ParseResult submitAndParse(String method,
119 ArrayList<NameValuePair> passedParams,
120 Class<? extends ParseResult> rootParserClass,
124 ParseResult result = null;
125 InputStreamWrapper isw = null;
129 utf8 = Charset.forName(UTF_8);
130 if (null == rootTagName) {
131 result = (ParseResult) rootParserClass.newInstance();
134 result = (ParseResult) rootParserClass.getDeclaredConstructor(String.class).newInstance(rootTagName);
136 isw = new InputStreamWrapper(doSubmit(method, passedParams));
137 XMLReader reader = XMLReaderFactory.createXMLReader();
138 ParseHandler ph = new ParseHandler(result);
139 ParseErrorHandler peh = new ParseErrorHandler();
140 reader.setContentHandler(ph);
141 reader.setErrorHandler(peh);
142 reader.parse(new InputSource(isw));
144 catch ( SAXParseException saxpe ) {
145 String response = "<n/a>";
147 response = new String(isw.getHeadBytes(), utf8);
149 throw new InvalidResponseException(saxpe, m_gatewayUrl, method, response);
151 catch ( InstantiationException
152 | InvocationTargetException
153 | IllegalAccessException
155 | NoSuchMethodException
159 throw new QDException(e);
162 ExceptionUtils.tryClose(isw);