2 * Copyright 2017 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.cli.fw.http.connect;
20 import java.io.IOException;
21 import java.net.MalformedURLException;
24 import java.nio.charset.StandardCharsets;
25 import java.security.cert.X509Certificate;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.Map.Entry;
31 import javax.net.ssl.SSLContext;
32 import javax.net.ssl.TrustManager;
33 import javax.net.ssl.X509TrustManager;
35 import org.apache.http.Header;
36 import org.apache.http.HttpEntity;
37 import org.apache.http.HttpResponse;
38 import org.apache.http.ParseException;
39 import org.apache.http.client.CookieStore;
40 import org.apache.http.client.HttpClient;
41 import org.apache.http.client.methods.HttpDelete;
42 import org.apache.http.client.methods.HttpGet;
43 import org.apache.http.client.methods.HttpPost;
44 import org.apache.http.client.methods.HttpPut;
45 import org.apache.http.client.methods.HttpRequestBase;
46 import org.apache.http.client.protocol.ClientContext;
47 import org.apache.http.config.Registry;
48 import org.apache.http.config.RegistryBuilder;
49 import org.apache.http.conn.HttpClientConnectionManager;
50 import org.apache.http.conn.socket.ConnectionSocketFactory;
51 import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
52 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
53 import org.apache.http.conn.ssl.X509HostnameVerifier;
54 import org.apache.http.cookie.Cookie;
55 import org.apache.http.entity.StringEntity;
56 import org.apache.http.entity.mime.MultipartEntity;
57 import org.apache.http.entity.mime.content.FileBody;
58 import org.apache.http.impl.client.BasicCookieStore;
59 import org.apache.http.impl.client.HttpClients;
60 import org.apache.http.impl.client.LaxRedirectStrategy;
61 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
62 import org.apache.http.impl.cookie.BasicClientCookie;
63 import org.apache.http.protocol.BasicHttpContext;
64 import org.apache.http.protocol.HttpContext;
65 import org.apache.http.util.EntityUtils;
66 import org.onap.cli.fw.http.conf.OnapCommandHttpConstants;
67 import org.onap.cli.fw.http.error.OnapCommandHttpFailure;
70 * Helps to make http connection.<br>
72 public class OnapHttpConnection {
74 private HttpClient httpClient = null;
76 Map<String, String> mapCommonHeaders = new HashMap<String, String> ();
78 protected boolean debug = false;
80 private String debugDetails = "";
82 public static class TrustAllX509TrustManager implements X509TrustManager {
85 public X509Certificate[] getAcceptedIssuers() {
86 return new X509Certificate[0];
90 public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
91 // No need to implement.
95 public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
96 // No need to implement.
101 * OnapHttpConnection Constructor.
105 * @throws OnapCommandHttpFailure
108 public OnapHttpConnection(boolean debug) throws OnapCommandHttpFailure {
112 private void initHttpClient(boolean isSecured) throws OnapCommandHttpFailure {
113 if (this.httpClient == null) {
116 SSLContext sslContext = SSLContext.getInstance(OnapCommandHttpConstants.SSLCONTEST_TLS);
117 sslContext.init(null, new TrustManager[] { new TrustAllX509TrustManager() },
118 new java.security.SecureRandom());
119 X509HostnameVerifier hostnameVerifier = new AllowAllHostnameVerifier();
120 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
121 .<ConnectionSocketFactory>create()
122 .register("https", new SSLConnectionSocketFactory(sslContext, hostnameVerifier)).build();
123 HttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
125 this.httpClient = HttpClients.custom().setConnectionManager(connManager)
126 .setRedirectStrategy(new LaxRedirectStrategy()).build();
128 this.httpClient = HttpClients.createDefault();
130 } catch (Exception e) {
131 throw new OnapCommandHttpFailure(e);
136 public String getDebugInfo() {
137 return this.debugDetails;
140 private Map<String, String> getHttpHeaders(HttpResponse resp) {
141 Map<String, String> result = new HashMap<>();
143 Header[] hs = resp.getAllHeaders();
144 for (int i = 0; i < hs.length; i++) {
145 result.put(hs[i].getName(), hs[i].getValue());
151 private String getResponseBody(HttpResponse resp) throws OnapCommandHttpFailure {
152 if (resp.getEntity() == null) {
156 String body = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
157 EntityUtils.consume(resp.getEntity());
159 } catch (IOException e) {
160 throw new OnapCommandHttpFailure(e);
164 private StringEntity getStringEntity(HttpInput input) {
165 return new StringEntity(input.getBody(), StandardCharsets.UTF_8);
174 * @throws OnapCommandHttpFailure
177 public HttpResult post(final HttpInput input) throws OnapCommandHttpFailure {
178 input.setMethod("post");
179 return this.request(input);
188 * @throws OnapCommandHttpFailure
191 public HttpResult get(final HttpInput input) throws OnapCommandHttpFailure {
192 input.setMethod("get");
193 return this.request(input);
202 * @throws OnapCommandHttpFailure
205 public HttpResult put(final HttpInput input) throws OnapCommandHttpFailure {
206 input.setMethod("put");
207 return this.request(input);
216 * @throws OnapCommandHttpFailure
219 public HttpResult delete(final HttpInput input) throws OnapCommandHttpFailure {
220 input.setMethod("delete");
221 return this.request(input);
224 public void setCommonHeaders(Map<String, String> headers) {
225 this.mapCommonHeaders = headers;
228 private void addCommonHeaders(HttpInput input) {
229 if (!input.isBinaryData()) {
230 if (!input.getReqHeaders().containsKey("Content-Type")) {
231 input.getReqHeaders().put("Content-Type", OnapCommandHttpConstants.APPLICATION_JSON);
234 if (!input.getReqHeaders().containsKey("Accept")) {
235 input.getReqHeaders().put("Accept", OnapCommandHttpConstants.APPLICATION_JSON);
238 for (String headerName : this.mapCommonHeaders.keySet()) {
239 input.getReqHeaders().put(headerName, this.mapCommonHeaders.get(headerName));
243 private void addCommonCookies(CookieStore cookieStore) {
244 for (String headerName : this.mapCommonHeaders.keySet()) {
245 Cookie cookie = new BasicClientCookie(headerName, this.mapCommonHeaders.get(headerName));
246 cookieStore.addCookie(cookie);
250 private void updateResultFromCookies(HttpResult result, List<Cookie> cookies) {
251 for (Cookie cookie : cookies) {
252 result.getRespCookies().put(cookie.getName(), cookie.getValue());
256 private String getDomain(String url) {
258 return new URL(url).getHost();
259 } catch (MalformedURLException e) {
260 // url is always proper !!
265 private void updateInputFromCookies(HttpInput input, CookieStore cookieStore) {
266 addCommonCookies(cookieStore);
267 for (String cookieName : input.getReqCookies().keySet()) {
268 BasicClientCookie cookie = new BasicClientCookie(cookieName, input.getReqCookies().get(cookieName));
269 cookie.setDomain(this.getDomain(input.getUri()));
270 cookieStore.addCookie(cookie);
276 * Handles http method requests.
281 * @throws OnapCommandHttpFailure
284 public HttpResult request(HttpInput input) throws OnapCommandHttpFailure {
285 this.addCommonHeaders(input);
287 HttpRequestBase requestBase = null;
288 if ("post".equals(input.getMethod())) {
289 HttpPost httpPost = new HttpPost();
290 if (input.isBinaryData()) {
291 httpPost.setEntity(getMultipartEntity(input));
293 httpPost.setEntity(this.getStringEntity(input));
295 requestBase = httpPost;
296 } else if ("put".equals(input.getMethod())) {
297 HttpPut httpPut = new HttpPut();
298 httpPut.setEntity(this.getStringEntity(input));
299 requestBase = httpPut;
300 } else if ("get".equals(input.getMethod())) {
301 requestBase = new HttpGet();
302 } else if ("delete".equals(input.getMethod())) {
303 requestBase = new HttpDelete();
305 throw new IllegalArgumentException("Invalid HTTP method");
308 requestBase.setURI(URI.create(input.getUri()));
310 for (Entry<String, String> h : input.getReqHeaders().entrySet()) {
311 requestBase.addHeader(h.getKey(), h.getValue());
314 HttpResult result = new HttpResult();
317 this.debugDetails = "";
318 CookieStore cookieStore = new BasicCookieStore();
319 updateInputFromCookies(input, cookieStore);
320 HttpContext localContext = new BasicHttpContext();
321 localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
323 this.initHttpClient(input.getUri().startsWith("https"));
325 HttpResponse resp = this.httpClient.execute(requestBase, localContext);
326 String respContent = this.getResponseBody(resp);
327 result.setBody(respContent);
328 result.setStatus(resp.getStatusLine().getStatusCode());
329 result.setRespHeaders(this.getHttpHeaders(resp));
330 this.updateResultFromCookies(result, cookieStore.getCookies());
331 } catch (ParseException | IOException e) {
332 throw new OnapCommandHttpFailure(e);
335 this.debugDetails = input + " " + result;
342 public void close() {
343 this.mapCommonHeaders.clear();
346 private HttpEntity getMultipartEntity(HttpInput input) {
347 FileBody fileBody = new FileBody(new File(input.getBody().trim()));
348 MultipartEntity multipartEntity = new MultipartEntity();
349 String fileName = input.getMultipartEntityName() != "" ? input.getMultipartEntityName() : "upload";
350 multipartEntity.addPart(fileName, fileBody);
351 return multipartEntity;