http.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package l7
  2. import (
  3. "bytes"
  4. "strconv"
  5. "strings"
  6. )
  7. func ParseHttp(payload []byte) (string, string) {
  8. method, rest, ok := bytes.Cut(payload, space)
  9. if !ok {
  10. return "", ""
  11. }
  12. if !isHttpMethod(string(method)) {
  13. return "", ""
  14. }
  15. uri, _, ok := bytes.Cut(rest, space)
  16. if !ok {
  17. uri = append(uri, []byte("...")...)
  18. }
  19. return string(method), string(uri)
  20. }
  21. // parseHttpHeader 解析 HTTP 头部字段的值
  22. func parseHttpHeader(payload []byte, headerName string) string {
  23. headerBytes := []byte(headerName)
  24. headerIdx := bytes.Index(payload, headerBytes)
  25. if headerIdx == -1 {
  26. return ""
  27. }
  28. headerStart := headerIdx + len(headerBytes)
  29. if headerStart >= len(payload) {
  30. return ""
  31. }
  32. // 查找头部值的结束位置(\r\n)
  33. headerEnd := bytes.Index(payload[headerStart:], []byte("\r\n"))
  34. if headerEnd == -1 {
  35. // 如果没有找到 \r\n,使用剩余数据的长度
  36. headerEnd = len(payload) - headerStart
  37. }
  38. if headerEnd <= 0 {
  39. return ""
  40. }
  41. headerValue := payload[headerStart : headerStart+headerEnd]
  42. return string(bytes.TrimSpace(headerValue))
  43. }
  44. // parseHttpHostCommon 解析 HTTP 请求的公共逻辑,返回 method, requestURI, host, port, rest
  45. // rest 是解析完 method 和 uri 后剩余的 payload 部分,用于后续解析其他头部
  46. func parseHttpHostCommon(payload []byte, isTls bool) (string, string, string, uint16, []byte) {
  47. method, rest, ok := bytes.Cut(payload, space)
  48. if !ok {
  49. return "", "", "", 0, nil
  50. }
  51. if !isHttpMethod(string(method)) {
  52. return "", "", "", 0, nil
  53. }
  54. uri, rest, ok := bytes.Cut(rest, space)
  55. if !ok {
  56. uri = append(uri, []byte("...")...)
  57. }
  58. // 解析 Host 头部
  59. hostPort := parseHttpHeader(rest, "Host:")
  60. if hostPort == "" {
  61. return string(method), string(uri), "", 0, rest
  62. }
  63. hostParts := strings.Split(hostPort, ":")
  64. host := hostParts[0]
  65. // 根据 TLS 标识设置默认端口
  66. var port uint16
  67. if isTls {
  68. port = 443 // HTTPS 默认端口
  69. } else {
  70. port = 80 // HTTP 默认端口
  71. }
  72. // 如果 Host 头部明确指定了端口,使用指定的端口
  73. if len(hostParts) > 1 {
  74. port64, err := strconv.ParseUint(hostParts[1], 10, 16)
  75. if err == nil {
  76. port = uint16(port64)
  77. }
  78. }
  79. return string(method), string(uri), host, port, rest
  80. }
  81. // ParseHttpHost 解析 HTTP 请求,返回 method, requestURI, host, port
  82. // 不解析 User-Agent,性能更优
  83. func ParseHttpHost(payload []byte, isTls bool) (string, string, string, uint16) {
  84. method, uri, host, port, _ := parseHttpHostCommon(payload, isTls)
  85. return method, uri, host, port
  86. }
  87. // ParseHttpHostWithUserAgent 解析 HTTP 请求,返回 method, requestURI, host, port, userAgent
  88. // 包含 User-Agent 解析,适用于需要 User-Agent 信息的场景
  89. func ParseHttpHostWithUserAgent(payload []byte, isTls bool) (string, string, string, uint16, string) {
  90. method, uri, host, port, rest := parseHttpHostCommon(payload, isTls)
  91. // 解析 User-Agent 头部
  92. userAgent := parseHttpHeader(rest, "User-Agent:")
  93. return method, uri, host, port, userAgent
  94. }