All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ctrip.framework.apollo.util.http.HttpUtil Maven / Gradle / Ivy

The newest version!
package com.ctrip.framework.apollo.util.http;

import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.exceptions.ApolloConfigStatusCodeException;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.base.Function;
import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

/**
 * @author Jason Song([email protected])
 */
public class HttpUtil {
  private ConfigUtil m_configUtil;
  private Gson gson;
  private static String cookieVal;
  /**
   * Constructor.
   */
  public HttpUtil() {
    m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
    gson = new Gson();
  }

  /**
   * Do get operation for the http request.
   *
   * @param httpRequest  the request
   * @param responseType the response type
   * @return the response
   * @throws ApolloConfigException if any error happened or response code is neither 200 nor 304
   */
  public  HttpResponse doGet(HttpRequest httpRequest, final Class responseType) {
    Function convertResponse = new Function() {
      @Override
      public T apply(String input) {
        return gson.fromJson(input, responseType);
      }
    };

    return doGetWithSerializeFunction(httpRequest, convertResponse);
  }

  /**
   * Do get operation for the http request.
   *
   * @param httpRequest  the request
   * @param responseType the response type
   * @return the response
   * @throws ApolloConfigException if any error happened or response code is neither 200 nor 304
   */
  public  HttpResponse doGet(HttpRequest httpRequest, final Type responseType) {
    Function convertResponse = new Function() {
      @Override
      public T apply(String input) {
        return gson.fromJson(input, responseType);
      }
    };

    return doGetWithSerializeFunction(httpRequest, convertResponse);
  }

  private  HttpResponse doGetWithSerializeFunction(HttpRequest httpRequest,
                                                         Function serializeFunction) {
    InputStreamReader isr = null;
    InputStreamReader esr = null;
    int statusCode;
    try {
      HttpURLConnection conn = (HttpURLConnection) new URL(httpRequest.getUrl()).openConnection();

      conn.setRequestMethod("GET");
      setAuth(conn,httpRequest);
      int connectTimeout = httpRequest.getConnectTimeout();
      if (connectTimeout < 0) {
        connectTimeout = m_configUtil.getConnectTimeout();
      }

      int readTimeout = httpRequest.getReadTimeout();
      if (readTimeout < 0) {
        readTimeout = m_configUtil.getReadTimeout();
      }

      conn.setConnectTimeout(connectTimeout);
      conn.setReadTimeout(readTimeout);
      if (!StringUtils.isEmpty(cookieVal)) {
        conn.setRequestProperty("Cookie", cookieVal);
      }
      conn.connect();

      statusCode = conn.getResponseCode();
      String response;

      try {
        isr = new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8);
        String cookie = conn.getHeaderField("Set-Cookie");
        if(!StringUtils.isEmpty(cookie)){
          cookieVal = cookie;
        }
        response = CharStreams.toString(isr);
      } catch (IOException ex) {
        /**
         * according to https://docs.oracle.com/javase/7/docs/technotes/guides/net/http-keepalive.html,
         * we should clean up the connection by reading the response body so that the connection
         * could be reused.
         */
        InputStream errorStream = conn.getErrorStream();

        if (errorStream != null) {
          esr = new InputStreamReader(errorStream, StandardCharsets.UTF_8);
          try {
            CharStreams.toString(esr);
          } catch (IOException ioe) {
            //ignore
          }
        }

        // 200 and 304 should not trigger IOException, thus we must throw the original exception out
        if (statusCode == 200 || statusCode == 304) {
          throw ex;
        } else {
          // for status codes like 404, IOException is expected when calling conn.getInputStream()
          throw new ApolloConfigStatusCodeException(statusCode, ex);
        }
      }

      if (statusCode == 200) {
        return new HttpResponse<>(statusCode, serializeFunction.apply(response));
      }

      if (statusCode == 304) {
        return new HttpResponse<>(statusCode, null);
      }
    } catch (ApolloConfigStatusCodeException ex) {
      throw ex;
    } catch (Throwable ex) {
      throw new ApolloConfigException("Could not complete get operation", ex);
    } finally {
      if (isr != null) {
        try {
          isr.close();
        } catch (IOException ex) {
          // ignore
        }
      }

      if (esr != null) {
        try {
          esr.close();
        } catch (IOException ex) {
          // ignore
        }
      }
    }

    throw new ApolloConfigStatusCodeException(statusCode,
        String.format("Get operation failed for %s", httpRequest.getUrl()));
  }

  /**
   * 简单添加Authorization授权登录
   * @param conn
   * @param httpRequest
   */
  private void setAuth(HttpURLConnection conn,HttpRequest httpRequest){
    String url = httpRequest.getUrl();
    if(StringUtils.isEmpty(url)){
      return;
    }
    int b = url.indexOf("@");
    if(b<=0){
      return;
    }
    int a = url.indexOf("//");
    if(a<=0||a+2>b){
      return;
    }
    String up = url.substring(a+2,b);
    if(StringUtils.isEmpty(up)){
      return;
    }
    String[] sts = StringUtils.split(up,":");
    if(sts==null||sts.length < 2){
      return;
    }
    try {
      String username = URLDecoder.decode(sts[0], "UTF-8");
      String password = URLDecoder.decode(sts[1], "UTF-8");
      String input = username + ":" + password;
      String encoding = java.util.Base64.getEncoder().encodeToString(input.getBytes());
      //String encoding = new sun.misc.BASE64Encoder().encode(input.getBytes());
      conn.setRequestProperty("Authorization", "Basic " + encoding);
    } catch (UnsupportedEncodingException e) {
      throw new ApolloConfigStatusCodeException(401,
              String.format("Get Authorization failed for %s", httpRequest.getUrl()));
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy