Feature(Go): Screen frame relay end-to-end with graceful client BYE (Phase 4)
This commit is contained in:
@@ -20,6 +20,19 @@ type Parser struct {
|
||||
codec *Codec
|
||||
}
|
||||
|
||||
// findHTTPBodyOffset returns the byte offset of the HTTP body — i.e. one past
|
||||
// the first `\r\n\r\n` separator. Returns -1 if the separator isn't present
|
||||
// yet (caller should wait for more data). Matches the C++ UnMaskHttp scan in
|
||||
// common/mask.h.
|
||||
func findHTTPBodyOffset(data []byte) int {
|
||||
for i := 0; i+4 <= len(data); i++ {
|
||||
if data[i] == '\r' && data[i+1] == '\n' && data[i+2] == '\r' && data[i+3] == '\n' {
|
||||
return i + 4
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// NewParser creates a new parser
|
||||
func NewParser() *Parser {
|
||||
return &Parser{
|
||||
@@ -38,6 +51,22 @@ func (p *Parser) Close() {
|
||||
func (p *Parser) Parse(ctx *connection.Context) ([]byte, error) {
|
||||
buf := ctx.InBuffer
|
||||
|
||||
// Strip optional HTTP-mask wrapper. The client may disguise each outbound
|
||||
// chunk as a `POST /<random> HTTP/1.1\r\n...\r\n\r\n` envelope followed
|
||||
// by the real binary body (see common/mask.h: HttpMask). Each chunk
|
||||
// carries its own envelope so we strip every time we see the prefix.
|
||||
if buf.Len() >= 5 {
|
||||
head := buf.Peek(5)
|
||||
if len(head) == 5 && head[0] == 'P' && head[1] == 'O' && head[2] == 'S' && head[3] == 'T' && head[4] == ' ' {
|
||||
bodyOffset := findHTTPBodyOffset(buf.Bytes())
|
||||
if bodyOffset < 0 {
|
||||
// Headers not fully arrived yet — wait for more bytes.
|
||||
return nil, ErrNeedMore
|
||||
}
|
||||
buf.Skip(bodyOffset)
|
||||
}
|
||||
}
|
||||
|
||||
// Need at least minimum bytes to determine protocol
|
||||
if buf.Len() < MinComLen {
|
||||
return nil, ErrNeedMore
|
||||
|
||||
Reference in New Issue
Block a user