com.alibaba.nacos.client.naming.net.HttpClient Maven / Gradle / Ivy
The newest version!
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.naming.net;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.naming.utils.IoUtils;
import com.google.common.net.HttpHeaders;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;
import java.util.zip.GZIPInputStream;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* @author nkorange
*/
public class HttpClient {
public static final int TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 50000);
public static final int CON_TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
private static final boolean ENABLE_HTTPS = Boolean
.getBoolean("com.alibaba.nacos.client.naming.tls.enable");
private static final String POST = "POST";
private static final String PUT = "PUT";
static {
// limit max redirection
System.setProperty("http.maxRedirects", "5");
}
public static String getPrefix() {
if (ENABLE_HTTPS) {
return "https://";
}
return "http://";
}
public static HttpResult httpGet(String url, List headers, Map paramValues, String encoding) {
return request(url, headers, paramValues, encoding, "GET");
}
public static HttpResult request(String url, List headers, Map paramValues, String encoding, String method) {
HttpURLConnection conn = null;
try {
String encodedContent = encodingParams(paramValues, encoding);
url += (StringUtils.isEmpty(encodedContent)) ? "" : ("?" + encodedContent);
conn = (HttpURLConnection) new URL(url).openConnection();
setHeaders(conn, headers, encoding);
conn.setConnectTimeout(CON_TIME_OUT_MILLIS);
conn.setReadTimeout(TIME_OUT_MILLIS);
conn.setRequestMethod(method);
conn.setDoOutput(true);
if (POST.equals(method) || PUT.equals(method)) {
// fix: apache http nio framework must set some content to request body
byte[] b = encodedContent.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(b.length));
conn.getOutputStream().write(b, 0, b.length);
conn.getOutputStream().flush();
conn.getOutputStream().close();
}
conn.connect();
NAMING_LOGGER.debug("Request from server: " + url);
return getResult(conn);
} catch (Exception e) {
try {
if (conn != null) {
NAMING_LOGGER.warn("failed to request " + conn.getURL() + " from "
+ InetAddress.getByName(conn.getURL().getHost()).getHostAddress());
}
} catch (Exception e1) {
NAMING_LOGGER.error("[NA] failed to request ", e1);
//ignore
}
NAMING_LOGGER.error("[NA] failed to request ", e);
return new HttpResult(500, e.toString(), Collections.emptyMap());
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
private static HttpResult getResult(HttpURLConnection conn) throws IOException {
int respCode = conn.getResponseCode();
InputStream inputStream;
if (HttpURLConnection.HTTP_OK == respCode
|| HttpURLConnection.HTTP_NOT_MODIFIED == respCode
|| Constants.WRITE_REDIRECT_CODE == respCode) {
inputStream = conn.getInputStream();
} else {
inputStream = conn.getErrorStream();
}
Map respHeaders = new HashMap(conn.getHeaderFields().size());
for (Map.Entry> entry : conn.getHeaderFields().entrySet()) {
respHeaders.put(entry.getKey(), entry.getValue().get(0));
}
String encodingGzip = "gzip";
if (encodingGzip.equals(respHeaders.get(HttpHeaders.CONTENT_ENCODING))) {
inputStream = new GZIPInputStream(inputStream);
}
return new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
}
private static String getCharset(HttpURLConnection conn) {
String contentType = conn.getContentType();
if (StringUtils.isEmpty(contentType)) {
return "UTF-8";
}
String[] values = contentType.split(";");
if (values.length == 0) {
return "UTF-8";
}
String charset = "UTF-8";
for (String value : values) {
value = value.trim();
if (value.toLowerCase().startsWith("charset=")) {
charset = value.substring("charset=".length());
}
}
return charset;
}
private static void setHeaders(HttpURLConnection conn, List headers, String encoding) {
if (null != headers) {
for (Iterator iter = headers.iterator(); iter.hasNext(); ) {
conn.addRequestProperty(iter.next(), iter.next());
}
}
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset="
+ encoding);
conn.addRequestProperty("Accept-Charset", encoding);
}
private static String encodingParams(Map params, String encoding)
throws UnsupportedEncodingException {
if (null == params || params.isEmpty()) {
return "";
}
params.put("encoding", encoding);
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : params.entrySet()) {
if (StringUtils.isEmpty(entry.getValue())) {
continue;
}
sb.append(entry.getKey()).append("=");
sb.append(URLEncoder.encode(entry.getValue(), encoding));
sb.append("&");
}
if (sb.length() > 0) {
sb = sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
public static class HttpResult {
final public int code;
final public String content;
final private Map respHeaders;
public HttpResult(int code, String content, Map respHeaders) {
this.code = code;
this.content = content;
this.respHeaders = respHeaders;
}
public String getHeader(String name) {
return respHeaders.get(name);
}
}
}