ajp13.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package ajp13
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "net"
  6. "reflect"
  7. )
  8. // ForwardRequest marks that this request is an actual request
  9. const ForwardRequest = 2
  10. // Shutdown marks that this is a shutdown request
  11. const Shutdown = 7
  12. // Ping marks that this is a ping request
  13. const Ping = 8
  14. // CPing marks that this is a cping request
  15. const CPing = 10
  16. // AJP13 represents the apache java protocol
  17. type AJP13 struct {
  18. len uint16
  19. Type uint8
  20. method HTTPMethod
  21. Version string // e.g. HTTP/1.1
  22. URI string
  23. RemoteAddr net.IP
  24. RemoteHost string
  25. Server string
  26. Port uint16
  27. SSL bool
  28. headers map[string]string
  29. }
  30. // Parse takes a []byte payload and builds
  31. func Parse(payload []byte) (*AJP13, error) {
  32. if !reflect.DeepEqual(payload[0:2], []byte{0x12, 0x34}) {
  33. return nil, fmt.Errorf("The magic signature is not 0x12 0x34 but %v", payload[0:2])
  34. }
  35. a := &AJP13{}
  36. // the data length
  37. a.len = binary.BigEndian.Uint16(payload[2:4])
  38. data := payload[4 : a.len+4]
  39. // the request type
  40. a.Type = uint8(data[0])
  41. switch a.Type {
  42. case ForwardRequest:
  43. a.parseForwardRequest(data)
  44. }
  45. return a, nil
  46. }
  47. func (a *AJP13) parseForwardRequest(data []byte) {
  48. // Method
  49. a.method = HTTPMethod(uint8(data[1]))
  50. offset := uint16(2)
  51. // Version
  52. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  53. versionLen := binary.BigEndian.Uint16(data[offset : offset+2])
  54. a.Version = string(data[offset+2 : offset+2+versionLen])
  55. offset += versionLen + 1
  56. }
  57. offset += 2
  58. // URI
  59. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  60. uriLen := binary.BigEndian.Uint16(data[offset : offset+2])
  61. a.URI = string(data[offset+2 : offset+2+uriLen])
  62. offset += uriLen + 1
  63. }
  64. offset += 2
  65. // RemoteAddr
  66. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  67. raddrLen := binary.BigEndian.Uint16(data[offset : offset+2])
  68. a.RemoteAddr = net.ParseIP(string(data[offset+2 : offset+2+raddrLen]))
  69. offset += raddrLen + 1
  70. }
  71. offset += 2
  72. // RemoteHost
  73. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  74. rhostLen := binary.BigEndian.Uint16(data[offset : offset+2])
  75. a.RemoteHost = string(data[offset+2 : offset+2+rhostLen])
  76. offset += rhostLen + 1
  77. }
  78. offset += 2
  79. // Server
  80. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  81. len := binary.BigEndian.Uint16(data[offset : offset+2])
  82. a.Server = string(data[offset+2 : offset+2+len])
  83. offset += len + 1
  84. }
  85. offset += 2
  86. // Port
  87. a.Port = binary.BigEndian.Uint16(data[offset : offset+2])
  88. offset += 2
  89. // SSL
  90. if data[offset] == 0x1 {
  91. a.SSL = true
  92. }
  93. offset++
  94. // Headers
  95. numHeaders := binary.BigEndian.Uint16(data[offset : offset+2])
  96. offset += 2
  97. headers := make(map[string]string)
  98. for idx := uint16(0); idx < numHeaders; idx++ {
  99. if data[offset] == 0xa0 { // encoded header name
  100. len := binary.BigEndian.Uint16(data[offset+2 : offset+4])
  101. hdrName := HTTPHeader(binary.BigEndian.Uint16(data[offset : offset+2])).String()
  102. if hdrName != "UNKNOWN" {
  103. headers[hdrName] = string(data[offset+4 : offset+4+len])
  104. }
  105. offset = offset + 5 + len
  106. } else { // plain text header name
  107. length := binary.BigEndian.Uint16(data[offset : offset+2])
  108. key := string(data[offset+2 : offset+2+length])
  109. offset = offset + 3 + length
  110. length = binary.BigEndian.Uint16(data[offset : offset+2])
  111. val := string(data[offset+2 : offset+2+length])
  112. headers[key] = val
  113. offset = offset + 3 + length
  114. }
  115. }
  116. a.headers = headers
  117. // don't need Attributes for the time being
  118. }
  119. // Length returns the length of the data this AJP13 request consists of
  120. func (a *AJP13) Length() uint16 {
  121. return a.len
  122. }
  123. // Method returns the name of the method used
  124. func (a *AJP13) Method() string {
  125. return a.method.String()
  126. }
  127. // Header returns the header value refered to by key
  128. func (a *AJP13) Header(key string) (string, bool) {
  129. val, ok := a.headers[key]
  130. return val, ok
  131. }