View Javadoc
1   package com.foxinmy.weixin4j.http.support.apache3;
2   
3   import java.io.ByteArrayOutputStream;
4   import java.io.IOException;
5   import java.net.InetAddress;
6   import java.net.Socket;
7   import java.net.UnknownHostException;
8   import java.util.List;
9   import java.util.Map.Entry;
10  
11  import javax.net.ssl.SSLContext;
12  
13  import org.apache.commons.httpclient.ConnectTimeoutException;
14  import org.apache.commons.httpclient.URI;
15  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
16  import org.apache.commons.httpclient.methods.DeleteMethod;
17  import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
18  import org.apache.commons.httpclient.methods.GetMethod;
19  import org.apache.commons.httpclient.methods.HeadMethod;
20  import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
21  import org.apache.commons.httpclient.methods.OptionsMethod;
22  import org.apache.commons.httpclient.methods.PostMethod;
23  import org.apache.commons.httpclient.methods.PutMethod;
24  import org.apache.commons.httpclient.methods.RequestEntity;
25  import org.apache.commons.httpclient.methods.TraceMethod;
26  import org.apache.commons.httpclient.params.HttpConnectionParams;
27  import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
28  import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
29  
30  import com.foxinmy.weixin4j.http.AbstractHttpClient;
31  import com.foxinmy.weixin4j.http.HttpClientException;
32  import com.foxinmy.weixin4j.http.HttpHeaders;
33  import com.foxinmy.weixin4j.http.HttpMethod;
34  import com.foxinmy.weixin4j.http.HttpRequest;
35  import com.foxinmy.weixin4j.http.HttpResponse;
36  import com.foxinmy.weixin4j.http.apache.mime.MultipartEntity;
37  import com.foxinmy.weixin4j.http.entity.HttpEntity;
38  import com.foxinmy.weixin4j.util.Consts;
39  import com.foxinmy.weixin4j.util.StringUtil;
40  
41  /**
42   * Requires commons-httpclient 3.0 or higher
43   *
44   * @className HttpComponent3
45   * @author jinyu(foxinmy@gmail.com)
46   * @date 2015年8月18日
47   * @since JDK 1.6
48   * @see
49   */
50  public class HttpComponent3 extends AbstractHttpClient {
51  
52  	private final org.apache.commons.httpclient.HttpClient httpClient;
53  
54  	public HttpComponent3(org.apache.commons.httpclient.HttpClient httpClient) {
55  		this.httpClient = httpClient;
56  	}
57  
58  	@Override
59  	public HttpResponse execute(HttpRequest request) throws HttpClientException {
60  		HttpResponse response = null;
61  		try {
62  			org.apache.commons.httpclient.HttpMethod httpMethod = createRequest(request);
63  			httpClient.executeMethod(httpMethod);
64  			response = new HttpComponent3Response(httpMethod);
65  			handleResponse(response);
66  		} catch (IOException e) {
67  			throw new HttpClientException("I/O error on "
68  					+ request.getMethod().name() + " request for \""
69  					+ request.getURI().toString(), e);
70  		} finally {
71  			if (response != null) {
72  				response.close();
73  			}
74  		}
75  		return response;
76  	}
77  
78  	/**
79  	 * Create HttpRequest
80  	 */
81  	protected org.apache.commons.httpclient.HttpMethod createRequest(
82  			HttpRequest request) throws HttpClientException, IOException {
83  		org.apache.commons.httpclient.HttpMethod httpMethod = createMethod(request);
84  		resolveHeaders(request, httpMethod);
85  		resolveContent(request, httpMethod);
86  		return httpMethod;
87  	}
88  
89  	/**
90  	 * Create HttpMethod
91  	 */
92  	protected org.apache.commons.httpclient.HttpMethod createMethod(
93  			HttpRequest request) throws HttpClientException {
94  		HttpMethod method = request.getMethod();
95  		org.apache.commons.httpclient.HttpMethod httpMethod = null;
96  		try {
97  			URI uri = new URI(request.getURI().toString(), false,
98  					Consts.UTF_8.name());
99  			if (method == HttpMethod.GET) {
100 				httpMethod = new GetMethod();
101 			} else if (method == HttpMethod.HEAD) {
102 				httpMethod = new HeadMethod();
103 			} else if (method == HttpMethod.POST) {
104 				httpMethod = new PostMethod();
105 			} else if (method == HttpMethod.PUT) {
106 				return new PutMethod();
107 			} else if (method == HttpMethod.DELETE) {
108 				httpMethod = new DeleteMethod();
109 			} else if (method == HttpMethod.OPTIONS) {
110 				httpMethod = new OptionsMethod();
111 			} else if (method == HttpMethod.TRACE) {
112 				return new TraceMethod(uri.getEscapedURI());
113 			} else {
114 				throw new HttpClientException("unknown request method "
115 						+ method + " for " + uri);
116 			}
117 			httpMethod.setURI(uri);
118 		} catch (IOException e) {
119 			throw new HttpClientException("I/O error on " + method.name()
120 					+ " setURI for \"" + request.toString() + "\":"
121 					+ e.getMessage(), e);
122 		}
123 		return httpMethod;
124 	}
125 
126 	/**
127 	 * Resolve Headers
128 	 */
129 	protected void resolveHeaders(HttpRequest request,
130 			org.apache.commons.httpclient.HttpMethod httpMethod) {
131 		com.foxinmy.weixin4j.http.HttpHeaders headers = request.getHeaders();
132 		if (headers == null) {
133 			headers = new HttpHeaders();
134 		}
135 		if (!headers.containsKey(HttpHeaders.HOST)) {
136 			headers.set(HttpHeaders.HOST, request.getURI().getHost());
137 		}
138 		// Add default accept headers
139 		if (!headers.containsKey(HttpHeaders.ACCEPT)) {
140 			headers.set(HttpHeaders.ACCEPT, "*/*");
141 		}
142 		// Add default user agent
143 		if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
144 			headers.set(HttpHeaders.USER_AGENT, "apache/httpclient3");
145 		}
146 		for (Entry<String, List<String>> header : headers.entrySet()) {
147 			if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
148 				httpMethod.setRequestHeader(header.getKey(),
149 						StringUtil.join(header.getValue(), ';'));
150 			} else {
151 				for (String headerValue : header.getValue()) {
152 					httpMethod.setRequestHeader(header.getKey(),
153 							headerValue != null ? headerValue : "");
154 				}
155 			}
156 		}
157 	}
158 
159 	/**
160 	 * Resolve Content
161 	 */
162 	protected void resolveContent(HttpRequest request,
163 			org.apache.commons.httpclient.HttpMethod httpMethod)
164 			throws IOException {
165 		HttpEntity entity = request.getEntity();
166 		if (entity != null) {
167 			if (entity.getContentLength() > 0l) {
168 				httpMethod.addRequestHeader(HttpHeaders.CONTENT_LENGTH,
169 						Long.toString(entity.getContentLength()));
170 			}
171 			if (entity.getContentType() != null) {
172 				httpMethod.addRequestHeader(HttpHeaders.CONTENT_TYPE, entity
173 						.getContentType().toString());
174 			}
175 			RequestEntity requestEntity = null;
176 			if (entity instanceof MultipartEntity) {
177 				ByteArrayOutputStream os = new ByteArrayOutputStream();
178 				entity.writeTo(os);
179 				os.flush();
180 				requestEntity = new ByteArrayRequestEntity(os.toByteArray(),
181 						entity.getContentType().toString());
182 				os.close();
183 			} else {
184 				requestEntity = new InputStreamRequestEntity(
185 						entity.getContent(), entity.getContentType().toString());
186 			}
187 			((EntityEnclosingMethod) httpMethod)
188 					.setRequestEntity(requestEntity);
189 		}
190 	}
191 
192 	public static class SSLProtocolSocketFactory implements
193 			SecureProtocolSocketFactory {
194 
195 		private final SSLContext sslContext;
196 
197 		public SSLProtocolSocketFactory(SSLContext sslContext) {
198 			this.sslContext = sslContext;
199 		}
200 
201 		@Override
202 		public Socket createSocket(String host, int port,
203 				InetAddress localAddress, int localPort) throws IOException,
204 				UnknownHostException {
205 			return sslContext.getSocketFactory().createSocket(host, port,
206 					localAddress, localPort);
207 		}
208 
209 		@Override
210 		public Socket createSocket(String host, int port,
211 				InetAddress localAddress, int localPort,
212 				HttpConnectionParams params) throws IOException,
213 				UnknownHostException, ConnectTimeoutException {
214 			if (params == null) {
215 				throw new IllegalArgumentException("Parameters may not be null");
216 			}
217 			int timeout = params.getConnectionTimeout();
218 			if (timeout == 0) {
219 				return createSocket(host, port, localAddress, localPort);
220 			} else {
221 				return ControllerThreadSocketFactory.createSocket(this, host,
222 						port, localAddress, localPort, timeout);
223 			}
224 		}
225 
226 		@Override
227 		public Socket createSocket(String host, int port) throws IOException,
228 				UnknownHostException {
229 			return sslContext.getSocketFactory().createSocket(host, port);
230 		}
231 
232 		@Override
233 		public Socket createSocket(Socket socket, String host, int port,
234 				boolean autoClose) throws IOException, UnknownHostException {
235 			return sslContext.getSocketFactory().createSocket(socket, host,
236 					port, autoClose);
237 		}
238 	}
239 }