in pkg/profiling/task/network/analyze/layer7/protocols/http1/reader/response.go [61:117]
func (r *Reader) ReadResponse(req *Request, buf *buffer.Buffer, readBody bool) (*Response, enums.ParseResult, error) {
bufReader := newPooledReaderFromBuffer(buf)
defer func() {
releasePooledReader(bufReader)
}()
tp := textproto.NewReader(bufReader)
resp := &http.Response{}
result := &Response{original: resp, req: req, reader: r}
result.MessageOpt = &MessageOpt{result}
headerStartPosition := buf.Position()
line, err := tp.ReadLine()
if err != nil {
return nil, enums.ParseResultSkipPackage, fmt.Errorf("read response first line failure: %v", err)
}
indexByte := strings.IndexByte(line, ' ')
if indexByte == -1 {
return nil, enums.ParseResultSkipPackage, fmt.Errorf("parsing response error: %s", line)
}
resp.Proto = line[:indexByte]
resp.Status = strings.TrimLeft(line[indexByte+1:], " ")
statusCode := resp.Status
if i := strings.IndexByte(resp.Status, ' '); i != -1 {
statusCode = resp.Status[:i]
}
if len(statusCode) != 3 {
return nil, enums.ParseResultSkipPackage, fmt.Errorf("parsing response status code failure: %v", statusCode)
}
resp.StatusCode, err = strconv.Atoi(statusCode)
if err != nil || resp.StatusCode < 0 {
return nil, enums.ParseResultSkipPackage, fmt.Errorf("status code not correct: %s", statusCode)
}
var ok bool
if resp.ProtoMajor, resp.ProtoMinor, ok = http.ParseHTTPVersion(resp.Proto); !ok {
return nil, enums.ParseResultSkipPackage, fmt.Errorf("parsing http version failure: %s", resp.Proto)
}
mimeHeader, err := tp.ReadMIMEHeader()
if err != nil {
result.buildHeaderBuffer(headerStartPosition, buf, bufReader)
return result, enums.ParseResultSuccess, nil
}
resp.Header = http.Header(mimeHeader)
result.buildHeaderBuffer(headerStartPosition, buf, bufReader)
if readBody {
if b, r, err := result.readFullResponseBody(bufReader, buf); err != nil {
return nil, enums.ParseResultSkipPackage, err
} else if r != enums.ParseResultSuccess {
return nil, r, nil
} else {
result.bodyBuffer = b
}
}
return result, enums.ParseResultSuccess, nil
}