antlabs / httparser

高性能http 1.1解析器,为你的异步io库插上http解析的翅膀, 每秒可以处理630.15MB/s流量[从零实现]
Apache License 2.0
41 stars 9 forks source link

一次解析1.5包的问题 #1

Closed lesismal closed 3 years ago

lesismal commented 3 years ago

看注释部分: 注释1: // 两个POST 注释2: // 一个POST 518字节,一共两个POST,第一次解析600字节,第二次解析剩余的

setting有在MessageBegin、MessageComplete加日志,详见代码

只输出了一组:

---- begin
---- complete
package main

import (
    "fmt"
    "github.com/antlabs/httparser"
    "time"
)

// 两个POST
var data = []byte(
    "POST /joyent/http-parser HTTP/1.1\r\n" +
        "Host: github.com\r\n" +
        "DNT: 1\r\n" +
        "Accept-Encoding: gzip, deflate, sdch\r\n" +
        "Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n" +
        "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " +
        "AppleWebKit/537.36 (KHTML, like Gecko) " +
        "Chrome/39.0.2171.65 Safari/537.36\r\n" +
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9," +
        "image/webp,*/*;q=0.8\r\n" +
        "Referer: https://github.com/joyent/http-parser\r\n" +
        "Connection: keep-alive\r\n" +
        "Transfer-Encoding: chunked\r\n" +
        "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n" +

        "POST /joyent/http-parser HTTP/1.1\r\n" +
        "Host: github.com\r\n" +
        "DNT: 1\r\n" +
        "Accept-Encoding: gzip, deflate, sdch\r\n" +
        "Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n" +
        "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " +
        "AppleWebKit/537.36 (KHTML, like Gecko) " +
        "Chrome/39.0.2171.65 Safari/537.36\r\n" +
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9," +
        "image/webp,*/*;q=0.8\r\n" +
        "Referer: https://github.com/joyent/http-parser\r\n" +
        "Connection: keep-alive\r\n" +
        "Transfer-Encoding: chunked\r\n" +
        "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n")

var kBytes = int64(8) << 30

var setting = httparser.Setting{
    MessageBegin: func() {
        fmt.Println("---- begin")
    },
    URL: func(buf []byte) {
    },
    Status: func([]byte) {
        // 响应包才需要用到
    },
    HeaderField: func(buf []byte) {
    },
    HeaderValue: func(buf []byte) {
    },
    HeadersComplete: func() {

    },
    Body: func(buf []byte) {
    },
    MessageComplete: func() {
        fmt.Println("---- complete")
    },
    // MessageEnd: func() {
    // },
}

func bench(iterCount int64, silent bool) {
    var start time.Time
    if !silent {
        start = time.Now()
    }

    p := httparser.New(httparser.REQUEST)
    fmt.Printf("req_len=%d\n", len(data)/2)
    // 一个POST 518,一共两个POST,第一次解析600字节,第二次解析剩余的
    data1, data2 := data[:600], data[600:]
    sucess, err := p.Execute(&setting, data1)
    if err != nil {
        panic(err.Error())
    }
    if sucess < len(data1) {
        data2 = append(data1[sucess:], data2...)
    }

    sucess, err = p.Execute(&setting, data2)
    if err != nil {
        panic(err.Error())
    }
    if sucess != len(data2) {
        panic(fmt.Sprintf("sucess 222 length size:%d", sucess))
    }

    p.Reset()

    if !silent {
        end := time.Now()

        fmt.Printf("Benchmark result:\n")

        elapsed := end.Sub(start) / time.Second

        total := iterCount * int64(len(data))
        bw := float64(total) / float64(elapsed)

        fmt.Printf("%.2f mb | %.2f mb/s | %.2f req/sec | %.2f s\n",
            float64(total)/(1024*1024),
            bw/(1024*1024),
            float64(iterCount)/float64(elapsed),
            float64(elapsed))

    }
}

func main() {
    // iterations := kBytes / int64(len(data))
    // bench(iterations, false)
    bench(1, false)
}
guonaihong commented 3 years ago

good,感谢你提的issue。看了下状态机,目前进入到messageDone状态,但是没有reset它。

lesismal commented 3 years ago

good,感谢你提的issue。看了下状态机,目前进入到messageDone状态,但是没有reset它。

好的

guonaihong commented 3 years ago

看下最新commit,先关闭。有问题重新打开。

lesismal commented 3 years ago

应该是ok了,剩下易用性的问题慢慢优化设计