|
|
@ -2,6 +2,7 @@ package http
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"bytes"
|
|
|
|
|
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"io"
|
|
|
|
"net"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"net/http"
|
|
|
@ -17,11 +18,13 @@ const (
|
|
|
|
CRLF = "\r\n"
|
|
|
|
CRLF = "\r\n"
|
|
|
|
ENDING = CRLF + CRLF
|
|
|
|
ENDING = CRLF + CRLF
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// max length of HTTP header. Safety precaution for DDoS attack.
|
|
|
|
maxHeaderLength = 8192
|
|
|
|
maxHeaderLength = 8192
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
var (
|
|
|
|
writeCRLF = serial.WriteString(CRLF)
|
|
|
|
ErrHeaderToLong = errors.New("Header too long.")
|
|
|
|
|
|
|
|
writeCRLF = serial.WriteString(CRLF)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type Reader interface {
|
|
|
|
type Reader interface {
|
|
|
@ -50,6 +53,7 @@ type HeaderReader struct {
|
|
|
|
func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {
|
|
|
|
func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {
|
|
|
|
buffer := buf.NewSmall()
|
|
|
|
buffer := buf.NewSmall()
|
|
|
|
totalBytes := 0
|
|
|
|
totalBytes := 0
|
|
|
|
|
|
|
|
endingDetected := false
|
|
|
|
for totalBytes < maxHeaderLength {
|
|
|
|
for totalBytes < maxHeaderLength {
|
|
|
|
err := buffer.AppendSupplier(buf.ReadFrom(reader))
|
|
|
|
err := buffer.AppendSupplier(buf.ReadFrom(reader))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -57,6 +61,7 @@ func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if n := bytes.Index(buffer.Bytes(), []byte(ENDING)); n != -1 {
|
|
|
|
if n := bytes.Index(buffer.Bytes(), []byte(ENDING)); n != -1 {
|
|
|
|
buffer.SliceFrom(n + len(ENDING))
|
|
|
|
buffer.SliceFrom(n + len(ENDING))
|
|
|
|
|
|
|
|
endingDetected = true
|
|
|
|
break
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if buffer.Len() >= len(ENDING) {
|
|
|
|
if buffer.Len() >= len(ENDING) {
|
|
|
@ -71,6 +76,10 @@ func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {
|
|
|
|
buffer.Release()
|
|
|
|
buffer.Release()
|
|
|
|
return nil, nil
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !endingDetected {
|
|
|
|
|
|
|
|
buffer.Release()
|
|
|
|
|
|
|
|
return nil, ErrHeaderToLong
|
|
|
|
|
|
|
|
}
|
|
|
|
return buffer, nil
|
|
|
|
return buffer, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|