mirror of https://github.com/q191201771/naza
1. [feat] nazahttp: 增加函数ReadHTTPHeader,ParseHTTPRequestLine,ParseHTTPStatusLine,读取HTTP头部信息 2. [refactor] 函数GetHttpFile,DownloadHTttpFile重命名为GetHTTPFile,DownloadHTTPFile
parent
fc4933cd45
commit
16b0bef401
@ -0,0 +1,80 @@
|
||||
// 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 (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ErrHTTPHeader = errors.New("nazahttp: fxxk")
|
||||
|
||||
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) {
|
||||
items := strings.Split(line, " ")
|
||||
if len(items) != 3 {
|
||||
err = ErrHTTPHeader
|
||||
return
|
||||
}
|
||||
return items[0], items[1], items[2], nil
|
||||
}
|
||||
|
||||
// Status-Line = Version SP Status-Code SP Reason CRLF
|
||||
func ParseHTTPStatusLine(line string) (version string, statusCode string, reason string, err error) {
|
||||
items := strings.Split(line, " ")
|
||||
if len(items) != 3 {
|
||||
err = ErrHTTPHeader
|
||||
return
|
||||
}
|
||||
return items[0], items[1], items[2], nil
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
// 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_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/q191201771/naza/pkg/assert"
|
||||
|
||||
"github.com/q191201771/naza/pkg/nazalog"
|
||||
|
||||
"github.com/q191201771/naza/pkg/nazahttp"
|
||||
)
|
||||
|
||||
func TestHeader(t *testing.T) {
|
||||
for port := 8080; port != 8090; port++ {
|
||||
addr := fmt.Sprintf(":%d", port)
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
go func() {
|
||||
_, _ = nazahttp.GetHTTPFile(fmt.Sprintf("http://%s/test", addr), 100)
|
||||
}()
|
||||
|
||||
conn, err := ln.Accept()
|
||||
r := bufio.NewReader(conn)
|
||||
fl, hs, err := nazahttp.ReadHTTPHeader(r)
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, true, len(hs) > 0)
|
||||
nazalog.Debugf("first line:%s", fl)
|
||||
nazalog.Debugf("header fields:%+v", hs)
|
||||
m, u, v, err := nazahttp.ParseHTTPRequestLine(fl)
|
||||
assert.Equal(t, nil, err)
|
||||
nazalog.Debugf("method:%s, uri:%s, version:%s", m, u, v)
|
||||
assert.Equal(t, "GET", m)
|
||||
assert.Equal(t, "/test", u)
|
||||
assert.Equal(t, "HTTP/1.1", v)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHTTPStatusLine(t *testing.T) {
|
||||
v, c, r, e := nazahttp.ParseHTTPStatusLine("HTTP/1.0 200 OK")
|
||||
assert.Equal(t, nil, e)
|
||||
assert.Equal(t, "HTTP/1.0", v)
|
||||
assert.Equal(t, "200", c)
|
||||
assert.Equal(t, "OK", r)
|
||||
}
|
Loading…
Reference in New Issue