View Javadoc
1   package cn.home1.oss.lib.common;
2   
3   import static cn.home1.oss.lib.common.RequestUtlis.findWrapper;
4   import static com.google.common.collect.Lists.newArrayList;
5   import static org.apache.commons.lang3.StringUtils.isBlank;
6   import static org.apache.commons.lang3.StringUtils.isNotBlank;
7   import static org.springframework.http.HttpHeaders.ACCEPT;
8   import static org.springframework.http.HttpHeaders.AUTHORIZATION;
9   import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
10  import static org.springframework.http.MediaType.ALL;
11  import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
12  import static org.springframework.http.MediaType.APPLICATION_JSON;
13  import static org.springframework.http.MediaType.APPLICATION_XML;
14  import static org.springframework.http.MediaType.parseMediaType;
15  
16  import com.google.common.collect.ImmutableSet;
17  
18  import lombok.SneakyThrows;
19  import lombok.extern.slf4j.Slf4j;
20  
21  import org.springframework.http.MediaType;
22  import org.springframework.util.StreamUtils;
23  import org.springframework.web.util.ContentCachingRequestWrapper;
24  
25  import java.io.IOException;
26  import java.nio.charset.Charset;
27  import java.util.Collection;
28  import java.util.Enumeration;
29  
30  import javax.servlet.http.HttpServletRequest;
31  
32  /**
33   * build curl from request
34   *
35   * <p>
36   * Created by zhanghaolun on 16/7/4.
37   * </p>
38   */
39  @Slf4j
40  public abstract class CurlUtils {
41  
42    private CurlUtils() {
43    }
44  
45    private static final Collection<String> RETAIN_HEADERS =
46      ImmutableSet.copyOf(newArrayList(ACCEPT, CONTENT_TYPE, AUTHORIZATION));
47  
48    /**
49     * 安置http请求, 生成curl命令.
50     *
51     * @param request {@link HttpServletRequest}
52     * @return curl command
53     */
54    public static String curl(final HttpServletRequest request) {
55      final String result;
56      if (request != null) {
57        final MediaType contentType =
58          isNotBlank(request.getContentType()) ? parseMediaType(request.getContentType()) : ALL;
59        final String headers = curlHeaders(request);
60        final String parameters = curlParameters(request);
61  
62        final StringBuilder curl = new StringBuilder("curl ").append(headers).append(" ")
63          .append("-X ").append(request.getMethod()).append(" ");
64        if (APPLICATION_JSON.includes(contentType) || APPLICATION_XML.includes(contentType)) {
65          curl.append("--data '").append(curlBody(request)).append("' ");
66        } else if (APPLICATION_FORM_URLENCODED == contentType) {
67          curl.append("--data '").append(parameters).append("' ");
68        } else if (isNotBlank(parameters)) {
69          curl.append('?').append(parameters).append(' ');
70  
71        }
72        curl.append(request.getRequestURL());
73        result = curl.toString();
74      } else {
75        result = "";
76      }
77      return result;
78    }
79  
80    static String curlHeaders(final HttpServletRequest request) {
81      @SuppressWarnings("rawtypes")
82      final Enumeration headerNames = request.getHeaderNames();
83      final StringBuilder hBuilder = new StringBuilder();
84      while (headerNames.hasMoreElements()) {
85        final String name = (String) headerNames.nextElement();
86        final String value = request.getHeader(name);
87        if (RETAIN_HEADERS.contains(name)) {
88          hBuilder.append("-H '").append(name).append(": ").append(value).append("' ");
89        }
90      }
91      return hBuilder.toString();
92    }
93  
94    @SneakyThrows
95    static String curlParameters(final HttpServletRequest request) {
96      @SuppressWarnings("rawtypes")
97      final Enumeration parameterNames = request.getParameterNames();
98      final StringBuilder pBuilder = new StringBuilder();
99      while (parameterNames.hasMoreElements()) {
100       final String name = (String) parameterNames.nextElement();
101       final String value = request.getParameter(name);
102       pBuilder //
103         .append('&') //
104         .append(name) //
105         .append('=') //
106         .append(CodecUtils.urlEncode(value));
107     }
108     return pBuilder.length() > 0 ? pBuilder.substring(1) : "";
109   }
110 
111   @SneakyThrows
112   public static String curlBody(final HttpServletRequest request) {
113     final Charset charset = RequestUtlis.findCharset(request);
114     try {
115       // read raw inputStream first. (may be has not been read, for example 404)
116       final String raw = StreamUtils.copyToString(request.getInputStream(), charset);
117       final String result;
118       if (isBlank(raw)) { // if no content in raw inputStream, 那应该是读过了, try to read cached.
119         final ContentCachingRequestWrapper wrapper = findWrapper(request, ContentCachingRequestWrapper.class);
120         if (wrapper != null) {
121           result = new String(((ContentCachingRequestWrapper) request).getContentAsByteArray(), charset);
122         } else {
123           result = "";
124         }
125       } else {
126         result = raw;
127       }
128       return result;
129     } catch (final IOException ex) {
130       log.warn("error reading request body.", ex);
131     }
132     return "";
133   }
134 }