Refactored detection logic to include ports and a confidence score
This commit is contained in:
@@ -12,10 +12,17 @@ func init() {
|
||||
Register(Server, "HTTP/?.", detectHTTPResponse)
|
||||
}
|
||||
|
||||
func detectHTTPRequest(dir Direction, data []byte) *Protocol {
|
||||
func detectHTTPRequest(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64) {
|
||||
// A minimal request "GET / HTTP/1.0\r\n" is > 8 bytes.
|
||||
if len(data) < 8 {
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
switch dstPort {
|
||||
case 80, 8080: // Common HTTP ports
|
||||
confidence = +.1
|
||||
case 3128: // Common HTTP proxy port
|
||||
confidence = -.1
|
||||
}
|
||||
|
||||
if Strict {
|
||||
@@ -31,38 +38,27 @@ func detectHTTPRequest(dir Direction, data []byte) *Protocol {
|
||||
Minor: request.ProtoMinor,
|
||||
Patch: -1,
|
||||
},
|
||||
}
|
||||
}, confidence + .85
|
||||
}
|
||||
r.Reset(bytes.NewReader(b))
|
||||
if response, err := http.ReadResponse(r, nil); err == nil {
|
||||
return &Protocol{
|
||||
Name: ProtocolHTTP,
|
||||
Version: Version{
|
||||
Major: response.ProtoMajor,
|
||||
Minor: response.ProtoMinor,
|
||||
Patch: -1,
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
crlfIndex := bytes.IndexFunc(data, func(r rune) bool {
|
||||
return r == '\r' || r == '\n'
|
||||
})
|
||||
if crlfIndex == -1 {
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
// A request has three, space-separated parts.
|
||||
part := bytes.Split(data[:crlfIndex], []byte(" "))
|
||||
if len(part) != 3 {
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
// The last part starts with "HTTP/".
|
||||
if !bytes.HasPrefix(part[2], []byte("HTTP/1")) {
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
var version = Version{Patch: -1}
|
||||
@@ -71,17 +67,42 @@ func detectHTTPRequest(dir Direction, data []byte) *Protocol {
|
||||
return &Protocol{
|
||||
Name: ProtocolHTTP,
|
||||
Version: version,
|
||||
}
|
||||
}, confidence + .75
|
||||
}
|
||||
|
||||
func detectHTTPResponse(dir Direction, data []byte) *Protocol {
|
||||
func detectHTTPResponse(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64) {
|
||||
if !dir.Contains(Server) {
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
// A minimal response "HTTP/1.0 200 OK\r\n" is > 8 bytes.
|
||||
if len(data) < 8 {
|
||||
return nil
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
switch srcPort {
|
||||
case 80, 8080: // Common HTTP ports
|
||||
confidence = +.1
|
||||
case 3128: // Common HTTP proxy port
|
||||
confidence = -.1
|
||||
}
|
||||
|
||||
if Strict {
|
||||
var (
|
||||
b = append(data, '\r', '\n')
|
||||
r = bufio.NewReader(bytes.NewReader(b))
|
||||
)
|
||||
if response, err := http.ReadResponse(r, nil); err == nil {
|
||||
return &Protocol{
|
||||
Name: ProtocolHTTP,
|
||||
Version: Version{
|
||||
Major: response.ProtoMajor,
|
||||
Minor: response.ProtoMinor,
|
||||
Patch: -1,
|
||||
},
|
||||
}, confidence + .85
|
||||
}
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
var version = Version{Patch: -1}
|
||||
@@ -90,5 +111,5 @@ func detectHTTPResponse(dir Direction, data []byte) *Protocol {
|
||||
return &Protocol{
|
||||
Name: ProtocolHTTP,
|
||||
Version: version,
|
||||
}
|
||||
}, confidence + .75
|
||||
}
|
||||
|
Reference in New Issue
Block a user