如何解析原始 HTTP 请求

How to parse a raw HTTP request

问题很简单。在 AutoHotkey 中,您将如何解析原始 HTTP 请求以访问方法、http 版本、cookie 和主机等数据。

;原始 http 请求示例:

rawHttp =
(
POST https://www.example.com/Login HTTP/1.1
Host: www.example.com
Connection: Keep-Alive
Cookie: session=b5j2h46fdthr46t74g5g234g5f3g6753kj73l

username=lalala&password=12345&rememberMe=1
)

;下面函数的用法示例:

httpObj := HttpTxtToObj(rawHttp)
MsgBox % "Request method: " httpObj.requestLine.method
MsgBox % "Request URI: " httpObj.requestLine.uri
MsgBox % "Request http version: " httpObj.requestLine.httpVersion
MsgBox % "Request header (Host): " httpObj.headers["Host"]
MsgBox % "Request header (Connection): " httpObj.headers["Connection"]
MsgBox % "Request header (Cookie): " httpObj.headers["Cookie"]
MsgBox % "Request body: " httpObj.body

;这个函数处理一切:

HttpTxtToObj(rawHttp) {
    ;Split request into "request line", "headers" and "body"(if existent)
    RegExMatch(rawHttp, "OU)^(?P<requestLine>.+)\R(?P<headers>.+)\R\R(?P<body>.*)$",request)
    If !request.Count()
        RegExMatch(rawHttp, "OU)^(?P<requestLine>.+)\R(?P<headers>.+)$",request)

    ;Split request line into "method" "requestUrl" and "httpVersion"
    RegExMatch(request.requestLine, "OU)^(?P<method>[^\s]+)\s(?P<uri>[^\s]+)\s(?P<httpVersion>.+)$", requestLine)

    ;Make a nice key value array for the headers:
    headers := {}
    While (p := RegexMatch(request.headers, "OSU)(?P<key>[^:]+):\s(?P<value>[^\R]+(\R|$))", currentHeader, p?p+1:1))
        headers.Insert(currentHeader.key, currentHeader.value)

    ;The body is usually a query string, json string or just text. When you uplaod a file it may even contain binary data.
    ;All that would make the code quite a bit more complex, so for now we'll just pretend it's normal text, nothing special.

    ;Now lets return a nice multidimensional array 
    Return {requestLine: requestLine, headers: headers, body: request.body}
}