HTTP/HTTPS协议详解(1)HTTP

正文

HTTP报文格式

HTTP报文格式
在http协议中采用制表符(\r)+ 换行符(\n)将每个节点数据分割开,每个节点包含不同信息,需要进一步处理。具体处理为:

  • 请求行:请求行中包括3个信息 依次为:请求方法 、url(访问路由地址)、 Http版本。
  1. 请求方法:标识表示该报文采用的是那种请求方式,在HTTP报文中的第一个字节。包含如下值 G(GET)、H(HEAD)、P(POST)、D(DELETE)、O(OPTIONS)、T(TRACE)、C(CONNECT)。若为22则为HTTPs请求。请求方法在HTTP报文中第一个字节。
  2. url:这里的url代表的是需要访问的数据在主机中的路由地址。主机 + url就得到一个数据访问地址去访问特定数据。
  3. HTTP版本:这里存储的是HTTP版本号 格式如:HTTP/1.0
  • 报文头:报文头中包括一系列的信息包括主机信息。每个信息以键值对的形式存储,键与值之间以冒号加一个空格‘: ’分开,每个信息以制表符加换行符分割。具体参见HTTP请求头大全
  • 空行: 空行的作用是将数据头与数据体分开。HTTP协议规定报头与数据体之间必须要用空行分割,没有数据体时任需要有。
  • 数据体:数据体中包含所有需要发送给应用处理的信息,信息与信息以符号‘&’连接,信息以键值对存储,键与值间用符号‘=’连接。

以下是具体实现的代码:

public class HttpPacket extends Packet{
    private boolean isHttp;
    private boolean isHttps;
    private boolean isOther;
    private String requestMethod;
    private String requestUrl;
    private String httpVersion;
    private String httpHost;
    private String httpUrl;
    private String dataLien;
    private String[] keyLines;
    private Map<String,String> keys = new HashMap<>();
    private Map<String,String> datas = new HashMap<>();

    public HttpPacket(byte[] bytes, int... parameters) {
        super(bytes, parameters);
        parse();
    }

    /**
     * 解析数据
     *  G : GET
     *  H : HEAD
     *  P : POST
     *  D : DELETE
     *  O : OPTIONS
     *  T : TRACE
     *  C : CONNECT
     */
    private void parse(){
        switch (bytes[offset]){
            case 'G':
            case 'H':
            case 'P':
            case 'D':
            case 'O':
            case 'T':
            case 'C':
                isHttp = true;
                isHttps = false;
                parseHttp();
                break;
            case 22:
                isHttp = false;
                isHttps = true;
                break;
                default:
                    isOther = true;
                    isHttp = false;
                    isHttps = false;
        }
    }

    private void parseHttp(){
        if(validLength - offset < 10) return;
        String dataString = new String(bytes,offset,validLength);
        keyLines = dataString.split("\\r\\n");
        for(int i = 0; i < keyLines.length; i++){
            if(i == 0){
                String requestLine = keyLines[i].trim();
                String[] data = requestLine.split(" ");

                if(data.length > 0){
                    requestMethod = data[0];
                }

                if(data.length > 1){
                    requestUrl = data[1];
                }

                if(data.length >= 2){
                    httpVersion = data[2];
                }
            }else if(i == keyLines.length - 1){
                dataLien = keyLines[keyLines.length - 1].trim();
                if(dataLien.isEmpty())return;
                String[] data = dataLien.split("&");
                for(int j = 0;j < data.length;j++){
                    if(data[i].indexOf("=") != -1){
                        String[] keys = data[i].trim().split("=",2);
                        if(keys[0].isEmpty())continue;
                        if(keys.length == 1){
                           datas.put(keys[0].trim(),"");
                        }else
                        if(keys.length == 2){
                            datas.put(keys[0].trim(),keys[1].trim());
                        }
                    }
                }

            }else{
                String requestLine = keyLines[i].trim();
                if(requestLine.indexOf(": ") != -1){
                    String[] data = requestLine.split(": ",2);
                    String key = data[0].trim();
                    String value = data[1].trim();
                    if(key.isEmpty())continue;
                    keys.put(key,value);

                    if(key.equals("host")){
                        httpHost = value;
                        if(requestUrl != null) httpUrl = "http://" + httpHost+"/" + requestUrl;
                    }
                }
            }
        }
    }

    public boolean isHttp() {
        return isHttp;
    }

    public boolean isHttps() {
        return isHttps;
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public String getRequestUrl() {
        return requestUrl;
    }

    public String getHttpVersion() {
        return httpVersion;
    }

    public String getHttpHost() {
        return httpHost;
    }

    public String getHttpUrl() {
        return httpUrl;
    }

    public String getDataLien() {
        return dataLien;
    }

    public boolean isOther() {
        return isOther;
    }

    public Map<String, String> getKeys() {
        return keys;
    }

    public Map<String, String> getDatas() {
        return datas;
    }
}