package cn.jiguang.common.connection; import cn.jiguang.common.ClientConfig; import cn.jiguang.common.resp.APIConnectionException; import cn.jiguang.common.resp.APIRequestException; import cn.jiguang.common.resp.ResponseWrapper; import cn.jiguang.common.utils.StringUtils; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.Authenticator; import java.text.MessageFormat; import java.util.concurrent.TimeUnit; public class Http2Client implements IHttpClient { private static final Logger LOG = LoggerFactory.getLogger(Http2Client.class); private static final String KEYWORDS_CONNECT_TIMED_OUT = "connect timed out"; private static final String KEYWORDS_READ_TIMED_OUT = "Read timed out"; public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private final int _connectionTimeout; private final int _readTimeout; private final int _maxRetryTimes; private final String _sslVer; private String _authCode; private HttpProxy _proxy; private final String _encryptType; public Http2Client(String authCode, HttpProxy proxy, ClientConfig config) { _maxRetryTimes = config.getMaxRetryTimes(); _connectionTimeout = config.getConnectionTimeout(); _readTimeout = config.getReadTimeout(); _sslVer = config.getSSLVersion(); _authCode = authCode; _proxy = proxy; _encryptType = config.getEncryptType(); String message = MessageFormat.format("Created instance with " + "connectionTimeout {0}, readTimeout {1}, maxRetryTimes {2}, SSL Version {3}", _connectionTimeout, _readTimeout, _maxRetryTimes, _sslVer); LOG.info(message); if (null != _proxy && _proxy.isAuthenticationNeeded()) { Authenticator.setDefault(new NativeHttpClient.SimpleProxyAuthenticator( _proxy.getUsername(), _proxy.getPassword())); } } @Override public ResponseWrapper sendGet(String url) throws APIConnectionException, APIRequestException { return sendGet(url, null); } public ResponseWrapper sendGet(String url, String content) throws APIConnectionException, APIRequestException { ResponseWrapper wrapper = new ResponseWrapper(); LOG.debug("Send request - Get" + " " + url); if (null != content) { LOG.debug("Request Content - " + content); } try { Request.Builder requestBuilder = new Request.Builder().url(url) .header("User-Agent", JPUSH_USER_AGENT) .addHeader("Accept-Charset", CHARSET) .addHeader("Charset", CHARSET) .addHeader("Connection", "Keep-Alive") .addHeader("Authorization", _authCode) .addHeader("Content-Type", CONTENT_TYPE_JSON); if (!StringUtils.isEmpty(_encryptType)) { requestBuilder.addHeader("X-Encrypt-Type", _encryptType); } Request request = requestBuilder.build(); if (null != content) { byte[] data = content.getBytes(CHARSET); request.newBuilder().header("Content-Length", String.valueOf(data.length)); } handleResponse(wrapper, request); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return wrapper; } public void handleResponse(ResponseWrapper wrapper, Request request) throws IOException { OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(_connectionTimeout, TimeUnit.MILLISECONDS) .readTimeout(_readTimeout, TimeUnit.MILLISECONDS) .build(); okhttp3.Response response = client.newCall(request).execute(); if (response.isSuccessful()) { wrapper.responseCode = 200; wrapper.responseContent = response.body().string(); LOG.debug("Succeed to get response OK - response body: " + wrapper.responseContent); // InputStream in = response.body().byteStream(); // StringBuffer sb = new StringBuffer(); // if (null != in) { // InputStreamReader reader = new InputStreamReader(in, CHARSET); // char[] buff = new char[1024]; // int len; // while ((len = reader.read(buff)) > 0) { // sb.append(buff, 0, len); // } // } } else { int status = response.code(); wrapper.responseCode = status; wrapper.responseContent = response.body().string(); if (status >= 300 && status < 400) { LOG.warn("Normal response but unexpected - responseCode:" + status + ", responseContent:" + wrapper.responseContent); } else { LOG.warn("Got error response - responseCode:" + status + ", responseContent:" + wrapper.responseContent); switch (status) { case 400: LOG.error("Your request params is invalid. Please check them according to error message."); wrapper.setErrorObject(); break; case 401: LOG.error("Authentication failed! Please check authentication params according to docs."); wrapper.setErrorObject(); break; case 403: LOG.error("Request is forbidden! Maybe your appkey is listed in blacklist or your params is invalid."); wrapper.setErrorObject(); break; case 404: LOG.error("Request page is not found! Maybe your params is invalid."); wrapper.setErrorObject(); break; case 410: LOG.error("Request resource is no longer in service. Please according to notice on official website."); wrapper.setErrorObject(); case 429: LOG.error("Too many requests! Please review your appkey's request quota."); wrapper.setErrorObject(); break; case 500: case 502: case 503: case 504: LOG.error("Seems encountered server error. Maybe JPush is in maintenance? Please retry later."); break; default: LOG.error("Unexpected response."); } } LOG.warn("Got error response - response: " + response.body().string()); wrapper.setErrorObject(); } } @Override public ResponseWrapper sendDelete(String url) throws APIConnectionException, APIRequestException { ResponseWrapper wrapper = new ResponseWrapper(); LOG.debug("Send request - Delete url:" + " " + url); Request request; try { Request.Builder requestBuilder = new Request.Builder().url(url) .header("User-Agent", JPUSH_USER_AGENT) .addHeader("Accept-Charset", CHARSET) .addHeader("Charset", CHARSET) .addHeader("Connection", "Keep-Alive") .addHeader("Authorization", _authCode) .addHeader("Content-Type", CONTENT_TYPE_JSON) .delete(); if (!StringUtils.isEmpty(_encryptType)) { requestBuilder.addHeader("X-Encrypt-Type", _encryptType); } request = requestBuilder.build(); handleResponse(wrapper, request); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return wrapper; } @Override public ResponseWrapper sendDelete(String url, String content) throws APIConnectionException, APIRequestException { ResponseWrapper wrapper = new ResponseWrapper(); LOG.debug("Send request - Delete url:" + " " + url + " content: " + content); Request request; try { RequestBody body = RequestBody.create(JSON, content); Request.Builder requestBuilder = new Request.Builder().url(url) .header("User-Agent", JPUSH_USER_AGENT) .addHeader("Accept-Charset", CHARSET) .addHeader("Charset", CHARSET) .addHeader("Connection", "Keep-Alive") .addHeader("Authorization", _authCode) .addHeader("Content-Type", CONTENT_TYPE_JSON) .delete(body); if (!StringUtils.isEmpty(_encryptType)) { requestBuilder.addHeader("X-Encrypt-Type", _encryptType); } request = requestBuilder.build(); handleResponse(wrapper, request); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return wrapper; } @Override public ResponseWrapper sendPost(String url, String content) throws APIConnectionException, APIRequestException { LOG.debug("Send request - Post url:" + " " + url + " content: " + content); ResponseWrapper wrapper = new ResponseWrapper(); try { RequestBody body = RequestBody.create(JSON, content); Request.Builder requestBuilder = new Request.Builder().url(url) .header("User-Agent", JPUSH_USER_AGENT) .addHeader("Accept-Charset", CHARSET) .addHeader("Charset", CHARSET) .addHeader("Connection", "Keep-Alive") .addHeader("Authorization", _authCode) .addHeader("Content-Type", CONTENT_TYPE_JSON) .post(body); if (!StringUtils.isEmpty(_encryptType)) { requestBuilder.addHeader("X-Encrypt-Type", _encryptType); } Request request = requestBuilder.build(); handleResponse(wrapper, request); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return wrapper; } @Override public ResponseWrapper sendPut(String url, String content) throws APIConnectionException, APIRequestException { LOG.debug("Send request - Put url:" + " " + url + " content: " + content); ResponseWrapper wrapper = new ResponseWrapper(); try { RequestBody body = RequestBody.create(JSON, content); Request.Builder requestBuilder = new Request.Builder().url(url) .header("User-Agent", JPUSH_USER_AGENT) .addHeader("Accept-Charset", CHARSET) .addHeader("Charset", CHARSET) .addHeader("Connection", "Keep-Alive") .addHeader("Authorization", _authCode) .addHeader("Content-Type", CONTENT_TYPE_JSON) .put(body); if (!StringUtils.isEmpty(_encryptType)) { requestBuilder.addHeader("X-Encrypt-Type", _encryptType); } Request request = requestBuilder.build(); handleResponse(wrapper, request); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return wrapper; } }