request.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package fasthttpadaptor
  2. import (
  3. "bytes"
  4. "io"
  5. "net/http"
  6. "net/url"
  7. "strings"
  8. "github.com/valyala/fasthttp"
  9. )
  10. // ConvertRequest converts a fasthttp.Request to an http.Request.
  11. // forServer should be set to true when the http.Request is going to be passed to a http.Handler.
  12. //
  13. // The http.Request must not be used after the fasthttp handler has returned!
  14. // Memory in use by the http.Request will be reused after your handler has returned!
  15. func ConvertRequest(ctx *fasthttp.RequestCtx, r *http.Request, forServer bool) error {
  16. body := ctx.PostBody()
  17. strRequestURI := b2s(ctx.RequestURI())
  18. rURL, err := url.ParseRequestURI(strRequestURI)
  19. if err != nil {
  20. return err
  21. }
  22. r.Method = b2s(ctx.Method())
  23. r.Proto = b2s(ctx.Request.Header.Protocol())
  24. if r.Proto == "HTTP/2" {
  25. r.ProtoMajor = 2
  26. } else {
  27. r.ProtoMajor = 1
  28. }
  29. r.ProtoMinor = 1
  30. r.ContentLength = int64(len(body))
  31. r.RemoteAddr = ctx.RemoteAddr().String()
  32. r.Host = b2s(ctx.Host())
  33. r.TLS = ctx.TLSConnectionState()
  34. r.Body = io.NopCloser(bytes.NewReader(body))
  35. r.URL = rURL
  36. if forServer {
  37. r.RequestURI = strRequestURI
  38. }
  39. if r.Header == nil {
  40. r.Header = make(http.Header)
  41. } else if len(r.Header) > 0 {
  42. for k := range r.Header {
  43. delete(r.Header, k)
  44. }
  45. }
  46. ctx.Request.Header.VisitAll(func(k, v []byte) {
  47. sk := b2s(k)
  48. sv := b2s(v)
  49. switch sk {
  50. case "Transfer-Encoding":
  51. r.TransferEncoding = append(r.TransferEncoding, sv)
  52. default:
  53. if sk == fasthttp.HeaderCookie {
  54. sv = strings.Clone(sv)
  55. }
  56. r.Header.Set(sk, sv)
  57. }
  58. })
  59. return nil
  60. }