1. [feat] nazahttp: 增加函数ReadHTTPHeader,ParseHTTPRequestLine,ParseHTTPStatusLine,读取HTTP头部信息 2. [refactor] 函数GetHttpFile,DownloadHTttpFile重命名为GetHTTPFile,DownloadHTTPFile

pull/2/head
q191201771 5 years ago
parent fc4933cd45
commit 16b0bef401

@ -16,9 +16,8 @@ import (
"time"
)
// 获取http文件
// @return <error> 成功返回nil
func GetHttpFile(url string, timeoutMSec int) ([]byte, error) {
// 获取http文件保存至字节切片
func GetHTTPFile(url string, timeoutMSec int) ([]byte, error) {
var c http.Client
if timeoutMSec > 0 {
c.Timeout = time.Duration(timeoutMSec) * time.Millisecond
@ -34,7 +33,7 @@ func GetHttpFile(url string, timeoutMSec int) ([]byte, error) {
}
// 获取http文件保存至本地
func DownloadHttpFile(url string, saveTo string, timeoutMSec int) (int64, error) {
func DownloadHTTPFile(url string, saveTo string, timeoutMSec int) (int64, error) {
var c http.Client
if timeoutMSec > 0 {
c.Timeout = time.Duration(timeoutMSec) * time.Millisecond

@ -15,25 +15,25 @@ import (
"github.com/q191201771/naza/pkg/nazahttp"
)
func TestGetHttpFile(t *testing.T) {
content, err := nazahttp.GetHttpFile("http://pengrl.com", 10000)
func TestGetHTTPFile(t *testing.T) {
content, err := nazahttp.GetHTTPFile("http://pengrl.com", 10000)
assert.IsNotNil(t, content)
assert.Equal(t, nil, err)
content, err = nazahttp.GetHttpFile("http://127.0.0.1:12356", 10000)
content, err = nazahttp.GetHTTPFile("http://127.0.0.1:12356", 10000)
assert.Equal(t, nil, content)
assert.IsNotNil(t, err)
}
func TestDownloadHttpFile(t *testing.T) {
n, err := nazahttp.DownloadHttpFile("http://pengrl.com", "/tmp/index.html", 10000)
func TestDownloadHTTPFile(t *testing.T) {
n, err := nazahttp.DownloadHTTPFile("http://pengrl.com", "/tmp/index.html", 10000)
assert.Equal(t, true, n > 0)
assert.Equal(t, nil, err)
n, err = nazahttp.DownloadHttpFile("http://127.0.0.1:12356", "/tmp/index.html", 10000)
n, err = nazahttp.DownloadHTTPFile("http://127.0.0.1:12356", "/tmp/index.html", 10000)
assert.IsNotNil(t, err)
// 保存文件至不存在的本地目录下
n, err = nazahttp.DownloadHttpFile("http://pengrl.com", "/notexist/index.html", 10000)
n, err = nazahttp.DownloadHTTPFile("http://pengrl.com", "/notexist/index.html", 10000)
assert.IsNotNil(t, err)
}

@ -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…
Cancel
Save