// 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 ( "io" "net/http" "strconv" ) // e.g. bufio.Reader type HttpReader interface { LineReader io.Reader } type HttpMsgCtx struct { ReqMethodOrRespVersion string ReqUriOrRespStatusCode string ReqVersionOrRespReason string Headers http.Header Body []byte } type HttpReqMsgCtx struct { Method string Uri string Version string Headers http.Header Body []byte } type HttpRespMsgCtx struct { Version string StatusCode string Reason string Headers http.Header Body []byte } func ReadHttpRequestMessage(r HttpReader) (ctx HttpReqMsgCtx, err error) { msgCtx, err := ReadHttpMessage(r) if err != nil { return } ctx.Method = msgCtx.ReqMethodOrRespVersion ctx.Uri = msgCtx.ReqUriOrRespStatusCode ctx.Version = msgCtx.ReqVersionOrRespReason ctx.Headers = msgCtx.Headers ctx.Body = msgCtx.Body return } func ReadHttpResponseMessage(r HttpReader) (ctx HttpRespMsgCtx, err error) { msgCtx, err := ReadHttpMessage(r) if err != nil { return } ctx.Version = msgCtx.ReqMethodOrRespVersion ctx.StatusCode = msgCtx.ReqUriOrRespStatusCode ctx.Reason = msgCtx.ReqVersionOrRespReason ctx.Headers = msgCtx.Headers ctx.Body = msgCtx.Body return } // ReadHttpMessage // // 注意,如果HTTP Header中不包含`Content-Length`,则不会读取HTTP Body,并且err返回值为nil // func ReadHttpMessage(r HttpReader) (ctx HttpMsgCtx, err error) { var requestLine string requestLine, ctx.Headers, err = ReadHttpHeader(r) if err != nil { return ctx, err } ctx.ReqMethodOrRespVersion, ctx.ReqUriOrRespStatusCode, ctx.ReqVersionOrRespReason, err = ParseHttpRequestLine(requestLine) if err != nil { return ctx, err } contentLength := ctx.Headers.Get(HeaderFieldContentLength) if len(contentLength) == 0 { return ctx, nil } cl, err := strconv.Atoi(contentLength) if err != nil { return ctx, err } ctx.Body = make([]byte, cl) _, err = io.ReadFull(r, ctx.Body) return ctx, err }