request_options.go 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package frankenphp
  2. import (
  3. "path/filepath"
  4. "go.uber.org/zap"
  5. )
  6. // RequestOption instances allow to configure a FrankenPHP Request.
  7. type RequestOption func(h *FrankenPHPContext) error
  8. // WithRequestDocumentRoot sets the root directory of the PHP application.
  9. // if resolveSymlink is true, oath declared as root directory will be resolved
  10. // to its absolute value after the evaluation of any symbolic links.
  11. // Due to the nature of PHP opcache, root directory path is cached: when
  12. // using a symlinked directory as root this could generate errors when
  13. // symlink is changed without PHP being restarted; enabling this
  14. // directive will set $_SERVER['DOCUMENT_ROOT'] to the real directory path.
  15. func WithRequestDocumentRoot(documentRoot string, resolveSymlink bool) RequestOption {
  16. return func(o *FrankenPHPContext) error {
  17. // make sure file root is absolute
  18. root, err := filepath.Abs(documentRoot)
  19. if err != nil {
  20. return err
  21. }
  22. if resolveSymlink {
  23. if root, err = filepath.EvalSymlinks(root); err != nil {
  24. return err
  25. }
  26. }
  27. o.documentRoot = root
  28. return nil
  29. }
  30. }
  31. // WithRequestResolvedDocumentRoot is similar to WithRequestDocumentRoot
  32. // but doesn't does any checks or resolving on the path to improve performance.
  33. func WithRequestResolvedDocumentRoot(documentRoot string) RequestOption {
  34. return func(o *FrankenPHPContext) error {
  35. o.documentRoot = documentRoot
  36. return nil
  37. }
  38. }
  39. // The path in the URL will be split into two, with the first piece ending
  40. // with the value of SplitPath. The first piece will be assumed as the
  41. // actual resource (CGI script) name, and the second piece will be set to
  42. // PATH_INFO for the CGI script to use.
  43. //
  44. // Future enhancements should be careful to avoid CVE-2019-11043,
  45. // which can be mitigated with use of a try_files-like behavior
  46. // that 404s if the fastcgi path info is not found.
  47. func WithRequestSplitPath(splitPath []string) RequestOption {
  48. return func(o *FrankenPHPContext) error {
  49. o.splitPath = splitPath
  50. return nil
  51. }
  52. }
  53. type PreparedEnv = map[string]string
  54. func PrepareEnv(env map[string]string) PreparedEnv {
  55. preparedEnv := make(PreparedEnv, len(env))
  56. for k, v := range env {
  57. preparedEnv[k+"\x00"] = v
  58. }
  59. return preparedEnv
  60. }
  61. // WithRequestEnv set CGI-like environment variables that will be available in $_SERVER.
  62. // Values set with WithEnv always have priority over automatically populated values.
  63. func WithRequestEnv(env map[string]string) RequestOption {
  64. return WithRequestPreparedEnv(PrepareEnv(env))
  65. }
  66. func WithRequestPreparedEnv(env PreparedEnv) RequestOption {
  67. return func(o *FrankenPHPContext) error {
  68. o.env = env
  69. return nil
  70. }
  71. }
  72. // WithRequestLogger sets the logger associated with the current request
  73. func WithRequestLogger(logger *zap.Logger) RequestOption {
  74. return func(o *FrankenPHPContext) error {
  75. o.logger = logger
  76. return nil
  77. }
  78. }