ajp13.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. if len(payload) < int(a.len+4) {
  39. return nil, fmt.Errorf("The payload should be %d bytes long is actually only %d bytes long", a.len+4, len(payload))
  40. }
  41. data := payload[4 : a.len+4]
  42. // the request type
  43. a.Type = uint8(data[0])
  44. var err error
  45. switch a.Type {
  46. case ForwardRequest:
  47. err = a.parseForwardRequest(data)
  48. if err != nil {
  49. return nil, err
  50. }
  51. }
  52. return a, nil
  53. }
  54. func checkLength(data []byte, minLen int, location string) error {
  55. dataLen := len(data)
  56. if dataLen < minLen {
  57. return fmt.Errorf("%s: need %d bytes but have %d", location, minLen, dataLen)
  58. }
  59. return nil
  60. }
  61. func (a *AJP13) parseForwardRequest(data []byte) error {
  62. // Method
  63. a.method = HTTPMethod(uint8(data[1]))
  64. offset := uint16(2)
  65. // Version
  66. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  67. versionLen := binary.BigEndian.Uint16(data[offset : offset+2])
  68. if err := checkLength(data, int(offset+2+versionLen+1), "parseForwardRequest/Version"); err != nil {
  69. return err
  70. }
  71. a.Version = string(data[offset+2 : offset+2+versionLen])
  72. offset += versionLen + 1
  73. }
  74. offset += 2
  75. // URI
  76. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  77. uriLen := binary.BigEndian.Uint16(data[offset : offset+2])
  78. if err := checkLength(data, int(offset+2+uriLen+1), "parseForwardRequest/URI"); err != nil {
  79. return err
  80. }
  81. a.URI = string(data[offset+2 : offset+2+uriLen])
  82. offset += uriLen + 1
  83. }
  84. offset += 2
  85. // RemoteAddr
  86. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  87. raddrLen := binary.BigEndian.Uint16(data[offset : offset+2])
  88. if err := checkLength(data, int(offset+2+raddrLen+1), "parseForwardRequest/RemoteAddr"); err != nil {
  89. return err
  90. }
  91. a.RemoteAddr = net.ParseIP(string(data[offset+2 : offset+2+raddrLen]))
  92. offset += raddrLen + 1
  93. }
  94. offset += 2
  95. // RemoteHost
  96. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  97. rhostLen := binary.BigEndian.Uint16(data[offset : offset+2])
  98. if err := checkLength(data, int(offset+2+rhostLen+1), "parseForwardRequest/RemoteHost"); err != nil {
  99. return err
  100. }
  101. a.RemoteHost = string(data[offset+2 : offset+2+rhostLen])
  102. offset += rhostLen + 1
  103. }
  104. offset += 2
  105. // Server
  106. if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
  107. len := binary.BigEndian.Uint16(data[offset : offset+2])
  108. if err := checkLength(data, int(offset+2+len+1), "parseForwardRequest/Server"); err != nil {
  109. return err
  110. }
  111. a.Server = string(data[offset+2 : offset+2+len])
  112. offset += len + 1
  113. }
  114. offset += 2
  115. // Port
  116. a.Port = binary.BigEndian.Uint16(data[offset : offset+2])
  117. offset += 2
  118. // SSL
  119. if data[offset] == 0x1 {
  120. a.SSL = true
  121. }
  122. offset++
  123. // Headers
  124. numHeaders := binary.BigEndian.Uint16(data[offset : offset+2])
  125. offset += 2
  126. headers := make(map[string]string)
  127. for idx := uint16(0); idx < numHeaders; idx++ {
  128. if data[offset] == 0xa0 { // encoded header name
  129. len := binary.BigEndian.Uint16(data[offset+2 : offset+4])
  130. hdrName := HTTPHeader(binary.BigEndian.Uint16(data[offset : offset+2])).String()
  131. if hdrName != "UNKNOWN" {
  132. headers[hdrName] = string(data[offset+4 : offset+4+len])
  133. }
  134. offset = offset + 5 + len
  135. } else { // plain text header name
  136. length := binary.BigEndian.Uint16(data[offset : offset+2])
  137. key := string(data[offset+2 : offset+2+length])
  138. offset = offset + 3 + length
  139. length = binary.BigEndian.Uint16(data[offset : offset+2])
  140. val := string(data[offset+2 : offset+2+length])
  141. headers[key] = val
  142. offset = offset + 3 + length
  143. }
  144. }
  145. a.headers = headers
  146. // don't need Attributes for the time being
  147. return nil
  148. }
  149. // Length returns the length of the data this AJP13 request consists of
  150. func (a *AJP13) Length() uint16 {
  151. return a.len
  152. }
  153. // Method returns the name of the method used
  154. func (a *AJP13) Method() string {
  155. return a.method.String()
  156. }
  157. // Header returns the header value refered to by key
  158. func (a *AJP13) Header(key string) (string, bool) {
  159. val, ok := a.headers[key]
  160. return val, ok
  161. }
  162. // Headers returns all headers
  163. func (a *AJP13) Headers() map[string]string {
  164. return a.headers
  165. }