static_files.asciidoc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. [[static_files]]
  2. == Static files
  3. Cowboy comes with a ready to use handler for serving static
  4. files. It is provided as a convenience for serving files
  5. during development.
  6. For systems in production, consider using one of the many
  7. Content Distribution Network (CDN) available on the market,
  8. as they are the best solution for serving files.
  9. The static handler can serve either one file or all files
  10. from a given directory. The etag generation and mime types
  11. can be configured.
  12. === Serve one file
  13. You can use the static handler to serve one specific file
  14. from an application's private directory. This is particularly
  15. useful to serve an 'index.html' file when the client requests
  16. the `/` path, for example. The path configured is relative
  17. to the given application's private directory.
  18. The following rule will serve the file 'static/index.html'
  19. from the application `my_app`'s priv directory whenever the
  20. path `/` is accessed:
  21. [source,erlang]
  22. {"/", cowboy_static, {priv_file, my_app, "static/index.html"}}
  23. You can also specify the absolute path to a file, or the
  24. path to the file relative to the current directory:
  25. [source,erlang]
  26. {"/", cowboy_static, {file, "/var/www/index.html"}}
  27. === Serve all files from a directory
  28. You can also use the static handler to serve all files that
  29. can be found in the configured directory. The handler will
  30. use the `path_info` information to resolve the file location,
  31. which means that your route must end with a `[...]` pattern
  32. for it to work. All files are served, including the ones that
  33. may be found in subfolders.
  34. You can specify the directory relative to the application's
  35. private directory (e.g. `my_app/priv`).
  36. The following rule will serve any file found in the `my_app`
  37. application's private directory in the `my_app/priv/static/assets`
  38. folder whenever the requested path begins with `/assets/`:
  39. [source,erlang]
  40. {"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets"}}
  41. You can also specify the absolute path to the directory or
  42. set it relative to the current directory:
  43. [source,erlang]
  44. {"/assets/[...]", cowboy_static, {dir, "/var/www/assets"}}
  45. === Customize the mimetype detection
  46. By default, Cowboy will attempt to recognize the mimetype
  47. of your static files by looking at the extension.
  48. You can override the function that figures out the mimetype
  49. of the static files. It can be useful when Cowboy is missing
  50. a mimetype you need to handle, or when you want to reduce
  51. the list to make lookups faster. You can also give a
  52. hard-coded mimetype that will be used unconditionally.
  53. Cowboy comes with two functions built-in. The default
  54. function only handles common file types used when building
  55. Web applications. The other function is an extensive list
  56. of hundreds of mimetypes that should cover almost any need
  57. you may have. You can of course create your own function.
  58. To use the default function, you should not have to configure
  59. anything, as it is the default. If you insist, though, the
  60. following will do the job:
  61. [source,erlang]
  62. ----
  63. {"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
  64. [{mimetypes, cow_mimetypes, web}]}}
  65. ----
  66. As you can see, there is an optional field that may contain
  67. a list of less used options, like mimetypes or etag. All option
  68. types have this optional field.
  69. To use the function that will detect almost any mimetype,
  70. the following configuration will do:
  71. [source,erlang]
  72. ----
  73. {"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
  74. [{mimetypes, cow_mimetypes, all}]}}
  75. ----
  76. You probably noticed the pattern by now. The configuration
  77. expects a module and a function name, so you can use any
  78. of your own functions instead:
  79. [source,erlang]
  80. ----
  81. {"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
  82. [{mimetypes, Module, Function}]}}
  83. ----
  84. The function that performs the mimetype detection receives
  85. a single argument that is the path to the file on disk. It
  86. is recommended to return the mimetype in tuple form, although
  87. a binary string is also allowed (but will require extra
  88. processing). If the function can't figure out the mimetype,
  89. then it should return `{<<"application">>, <<"octet-stream">>, []}`.
  90. When the static handler fails to find the extension,
  91. it will send the file as `application/octet-stream`.
  92. A browser receiving such file will attempt to download it
  93. directly to disk.
  94. Finally, the mimetype can be hard-coded for all files.
  95. This is especially useful in combination with the `file`
  96. and `priv_file` options as it avoids needless computation:
  97. [source,erlang]
  98. ----
  99. {"/", cowboy_static, {priv_file, my_app, "static/index.html",
  100. [{mimetypes, {<<"text">>, <<"html">>, []}}]}}
  101. ----
  102. === Generate an etag
  103. By default, the static handler will generate an etag header
  104. value based on the size and modified time. This solution
  105. can not be applied to all systems though. It would perform
  106. rather poorly over a cluster of nodes, for example, as the
  107. file metadata will vary from server to server, giving a
  108. different etag on each server.
  109. You can however change the way the etag is calculated:
  110. [source,erlang]
  111. ----
  112. {"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
  113. [{etag, Module, Function}]}}
  114. ----
  115. This function will receive three arguments: the path to the
  116. file on disk, the size of the file and the last modification
  117. time. In a distributed setup, you would typically use the
  118. file path to retrieve an etag value that is identical across
  119. all your servers.
  120. You can also completely disable etag handling:
  121. [source,erlang]
  122. ----
  123. {"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
  124. [{etag, false}]}}
  125. ----