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

cn.schoolwow.quickhttp.handler.ResponseHandler Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
package cn.schoolwow.quickhttp.handler;

import cn.schoolwow.quickhttp.document.Document;
import cn.schoolwow.quickhttp.document.element.Element;
import cn.schoolwow.quickhttp.document.element.Elements;
import cn.schoolwow.quickhttp.domain.MetaWrapper;
import cn.schoolwow.quickhttp.response.ResponseImpl;
import cn.schoolwow.quickhttp.response.SpeedLimitInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.net.www.MessageHeader;
import sun.net.www.protocol.https.DelegateHttpsURLConnection;
import sun.net.www.protocol.https.HttpsURLConnectionImpl;

import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

public class ResponseHandler extends AbstractHandler{
    private static Logger logger = LoggerFactory.getLogger(ResponseHandler.class);

    public ResponseHandler(MetaWrapper metaWrapper) {
        super(metaWrapper);
    }

    @Override
    public Handler handle() throws IOException {
        getStatusCode();
        getRequestHeader();
        getResponseHeader();
        getBody();
        getCharset();
        //提取Cookie信息
        try {
            URI uri = responseMeta.httpURLConnection.getURL().toURI();
            clientConfig.cookieManager.put(uri, responseMeta.httpURLConnection.getHeaderFields());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        metaWrapper.response = new ResponseImpl(requestMeta, responseMeta,clientConfig);
        return new EventSourceHandler(metaWrapper);
    }

    /**
     * 获取响应状态码
     * */
    private void getStatusCode() throws IOException {
        HttpURLConnection httpURLConnection = responseMeta.httpURLConnection;
        try {
            responseMeta.statusCode = httpURLConnection.getResponseCode();
            responseMeta.statusMessage = httpURLConnection.getResponseMessage();
        } catch (FileNotFoundException e) {
            responseMeta.statusCode = 404;
            responseMeta.statusMessage = "Not Found";
        }
        if (null == responseMeta.statusMessage) {
            responseMeta.statusMessage = "";
        }
        //获取顶级域
        responseMeta.topHost = httpURLConnection.getURL().getHost();
        if(responseMeta.topHost.contains(".")){
            String substring = responseMeta.topHost.substring(0,responseMeta.topHost.lastIndexOf("."));
            if(substring.contains(".")){
                responseMeta.topHost = responseMeta.topHost.substring(substring.lastIndexOf(".")+1);
            }
        }
    }

    /**
     * 获取请求头部
     *
     */
    private void getRequestHeader(){
        //提取请求头信息
        try {
            Field requestsMessageHeaderField = sun.net.www.protocol.http.HttpURLConnection.class.getDeclaredField("requests");
            requestsMessageHeaderField.setAccessible(true);
            MessageHeader requestsMessageHeader = null;
            if (responseMeta.httpURLConnection instanceof HttpsURLConnection) {
                Field delegateField = HttpsURLConnectionImpl.class.getDeclaredField("delegate");
                delegateField.setAccessible(true);
                DelegateHttpsURLConnection delegateHttpsURLConnection = (DelegateHttpsURLConnection) delegateField.get(responseMeta.httpURLConnection);
                requestsMessageHeader = (MessageHeader) requestsMessageHeaderField.get(delegateHttpsURLConnection);
            } else {
                requestsMessageHeader = (MessageHeader) requestsMessageHeaderField.get(responseMeta.httpURLConnection);
            }
            //添加请求头部
            Map> headerMap = requestsMessageHeader.getHeaders();
            Set>> entrySet = headerMap.entrySet();
            requestMeta.headerMap.clear();
            for (Map.Entry> entry : entrySet) {
                if (null == entry.getValue().get(0)) {
                    requestMeta.statusLine = entry.getKey();
                    continue;
                }
                requestMeta.headerMap.put(entry.getKey(), entry.getValue());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 获取响应头部
     * */
    private void getResponseHeader(){
        try {
            Field responsesMessageHeaderField = sun.net.www.protocol.http.HttpURLConnection.class.getDeclaredField("responses");
            responsesMessageHeaderField.setAccessible(true);
            MessageHeader responsesMessageHeader = null;
            if(responseMeta.httpURLConnection instanceof HttpsURLConnection){
                Field delegateField = HttpsURLConnectionImpl.class.getDeclaredField("delegate");
                delegateField.setAccessible(true);
                DelegateHttpsURLConnection delegateHttpsURLConnection = (DelegateHttpsURLConnection) delegateField.get(responseMeta.httpURLConnection);
                responsesMessageHeader = (MessageHeader) responsesMessageHeaderField.get(delegateHttpsURLConnection);
            }else {
                responsesMessageHeader = (MessageHeader) responsesMessageHeaderField.get(responseMeta.httpURLConnection);
            }
            Map> headerMap = responsesMessageHeader.getHeaders();
            Set>> entrySet = headerMap.entrySet();
            for(Map.Entry> entry:entrySet){
                if(null==entry.getKey()){
                    responseMeta.statusLine = entry.getValue().get(0);
                    continue;
                }
                List values = entry.getValue();
                List newValues = new ArrayList<>(values.size());
                for(int i=0;i400){
            logger.warn("[跳过获取请求体]当前状态码无法获取请求体,当前状态码:{}",responseMeta.statusCode);
            return;
        }
        try {
            String contentEncoding = responseMeta.httpURLConnection.getContentEncoding();
            InputStream inputStream = responseMeta.httpURLConnection.getErrorStream() != null ? responseMeta.httpURLConnection.getErrorStream() : responseMeta.httpURLConnection.getInputStream();
            if (contentEncoding != null && !contentEncoding.isEmpty()) {
                if (contentEncoding.equals("gzip")) {
                    inputStream = new GZIPInputStream(inputStream);
                } else if (contentEncoding.equals("deflate")) {
                    inputStream = new InflaterInputStream(inputStream, new Inflater(true));
                }
            }
            responseMeta.inputStream = inputStream;
            responseMeta.inputStream = new BufferedInputStream(inputStream);
            responseMeta.inputStream = new SpeedLimitInputStream(responseMeta.inputStream);
        } catch (FileNotFoundException e) {
            logger.warn("[读取输入流失败]");
        }
    }

    /**
     * 提取编码信息
     */
    private void getCharset() throws IOException {
        getCharsetFromContentType(responseMeta.httpURLConnection.getContentType());
        if (responseMeta.charset == null&&null!=responseMeta.inputStream) {
            byte[] bytes = new byte[1024 * 5];
            responseMeta.inputStream.mark(bytes.length);
            responseMeta.inputStream.read(bytes, 0, bytes.length);
            boolean readFully = (responseMeta.inputStream.read() == -1);
            responseMeta.inputStream.reset();
            ByteBuffer firstBytes = ByteBuffer.wrap(bytes);
            getCharsetFromBOM(firstBytes);
            if (responseMeta.charset == null) {
                getCharsetFromMeta(firstBytes, readFully);
            }
        }
        if (responseMeta.charset == null) {
            responseMeta.charset = "utf-8";
        }
    }

    /**
     * 从meta标签里面获取编码信息
     */
    private void getCharsetFromMeta(ByteBuffer byteBuffer, boolean readFully) {
        String docData = StandardCharsets.UTF_8.decode(byteBuffer).toString();
        //判断是否是HTML或者XML文档
        if (!docData.startsWith("= bom.length) {
            byteBuffer.get(bom);
            buffer.rewind();
        }
        if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == (byte) 0xFE && bom[3] == (byte) 0xFF ||
                bom[0] == (byte) 0xFF && bom[1] == (byte) 0xFE && bom[2] == 0x00 && bom[3] == 0x00) {
            responseMeta.charset = "utf-32";
        } else if (bom[0] == (byte) 0xFE && bom[1] == (byte) 0xFF ||
                bom[0] == (byte) 0xFF && bom[1] == (byte) 0xFE) {
            responseMeta.charset = "utf-16";
        } else if (bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF) {
            responseMeta.charset = "utf-8";
        }
        if (responseMeta.charset != null) {
            responseMeta.inputStream.skip(1);
        }
    }

    /**
     * 从Content-Type头部获取编码信息
     */
    private void getCharsetFromContentType(String contentType) {
        String prefix = "charset=";
        if (contentType != null && contentType.contains(prefix)) {
            int startIndex = contentType.indexOf(prefix);
            if (startIndex >= 0) {
                int endIndex = contentType.lastIndexOf(";");
                if (endIndex > startIndex) {
                    responseMeta.charset = contentType.substring(startIndex + prefix.length(), endIndex).trim();
                } else if (endIndex < startIndex) {
                    responseMeta.charset = contentType.substring(startIndex + prefix.length()).trim();
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy