You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
naza/pkg/nazahttp/header.go

83 lines
1.9 KiB
Go

// Copyright 2020, Chef. All rights reserved.
// https://github.com/q191201771/naza
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package nazahttp
import (
"strings"
)
type LineReader interface {
ReadLine() (line []byte, isPrefix bool, err error)
}
// @return firstLine: request的request line或response的status line
// @return headers: request header fileds的键值对
func ReadHTTPHeader(r LineReader) (firstLine string, headers map[string]string, err error) {
headers = make(map[string]string)
var line []byte
var isPrefix bool
line, isPrefix, err = r.ReadLine()
if err != nil {
return
}
if len(line) == 0 || isPrefix {
err = ErrHTTPHeader
return
}
firstLine = string(line)
for {
line, isPrefix, err = r.ReadLine()
if len(line) == 0 { // 读到一个空的 \r\n 表示http头全部读取完毕了
break
}
if isPrefix {
err = ErrHTTPHeader
return
}
if err != nil {
return
}
l := string(line)
pos := strings.Index(l, ":")
if pos == -1 {
err = ErrHTTPHeader
return
}
headers[strings.Trim(l[0:pos], " ")] = strings.Trim(l[pos+1:], " ")
}
return
}
// Request-Line = Method SP URI SP Version CRLF
func ParseHTTPRequestLine(line string) (method string, uri string, version string, err error) {
return parseFirstLine(line)
}
// Status-Line = Version SP Status-Code SP Reason CRLF
func ParseHTTPStatusLine(line string) (version string, statusCode string, reason string, err error) {
return parseFirstLine(line)
}
func parseFirstLine(line string) (item1, item2, item3 string, err error) {
f := strings.Index(line, " ")
if f == -1 {
err = ErrHTTPHeader
return
}
s := strings.Index(line[f+1:], " ")
if s == -1 || f+1+s+1 == len(line) {
err = ErrHTTPHeader
return
}
return line[0:f], line[f+1 : f+1+s], line[f+1+s+1:], nil
}