You are here

README.txt in CDN 8.3

Same filename and directory in other branches
  1. 5 README.txt
  2. 6.2 README.txt
  3. 6 README.txt
  4. 7.2 README.txt
CONTENTS OF THIS FILE
---------------------

 * Introduction
 * Installation
 * FAQ
 * Troubleshooting
 * Maintainers

INTRODUCTION
------------

This module provide easy Content Delivery Network integration for Drupal sites.
It alters file URLs, so that files (CSS, JS, images, fonts, videos …) are
downloaded from a CDN instead of your web server.

It does *not* put your entire website behind a CDN.

Only "Origin Pull" CDNs are supported. These are CDNs that only require you to
replace the domain name with another domain name. The CDN will then
automatically fetch (pull) the files from your server (the origin). Nowadays
pretty much every CDN is an Origin Pull CDN.

The CDN module aims to do only one thing and do it well: altering URLs to
point to files on CDNs. It supports:

  * Any sort of CDN mapping
  * DNS prefetching: lets browsers connect to the CDN faster
  * SEO: prevents CDN from serving HTML and REST responses, only allow files
  * Forever cacheable files (optimal far future expiration)
  * Auto-balancing files over multiple CDNs
  * … and many more details that are taken care of automatically

The "CDN UI" module is included, and can be used for configuring the CDN module.
Once set up, it can be uninstalled.


INSTALLATION
------------

1) Place this module directory in your "modules" folder

2) Install the module.

3) Go to your CDN provider's control panel and set up a "CDN instance" (Amazon
   CloudFront calls this a "distribution"). There, you will have to specify
   the origin server (Amazon CloudFront calls this a "custom origin"), which
   is simply the domain name of your Drupal site.
   The CDN will provide you with a "delivery address", this is the address
   that we'll use to download files from the CDN instead of the Drupal server.
   Suppose this is `http://d85nwn7m5gl3y.cloudfront.net`.
   Be sure to forward query strings from the CDN to the origin! Otherwise image
   style derivatives will not work.
   (It acts like a globally distributed, super fast proxy server.)

   Relevant links:
   - Amazon CloudFront gotcha: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/QueryStringParameters.html

4) Optionally, you can create a CNAME alias to the delivery address on your
   DNS server. This way, it's not immediately obvious from the links in the
   HTMl that you're using an external service (that's why it's also called a
   vanity domain name).
   However, if you're going to use your CDN in HTTPS mode, then using vanity
   domains will break things (because SSL certificates are bound to domain
   names).

5) Configure the CDN module. Either modify and import the `cdn.settings.yml`
   configuration file manually or install the included CDN UI module to
   configure it through a UI. Provide the (vanity) domain name that your CDN
   has given you (`d85nwn7m5gl3y.cloudfront.net` in our example).

6) If your site is behind a reverse proxy such as Varnish, so that your stack
   looks like: CDN <-> reverse proxy <-> web server, then you need to take extra
   measures if you want to prevent duplicate content showing up on the CDN. See
   \Drupal\cdn\StackMiddleware\DuplicateContentPreventionMiddleware for details.
   It's possible in this situation to end up with redirect loops; for that
   reason the CDN module adds a debugging header to the 301 redirects it emits
   in order to facilitate troubleshooting.


FAQ
---

Q: Is the CDN module compatible with Drupal's Page Cache?
A: Yes.

Q: Is the CDN module compatible with Drupal's "private files" functionality?
A: Yes. The CDN module won't break private files, they will continue to work
   the same way. However, it cannot serve private files from a CDN. Not every
   CDN supports protected/secured/authenticated file access, and those that do
   each have their own way of doing this (there is no standard). So private
   files will continue to be served by Drupal, which may or may not be
   acceptable for your use case.

Q: Does this module only work with Apache or also with nginx, lighttpd, etc.?
A: This module only affects HTML, so it doesn't matter which web server you use!


TROUBLESHOOTING
---------------

For small sites the 'Forever cacheable files' (farfuture) functionality works
fine out of the box. The CDN module serves all files through PHP with optimal
headers. Since the CDN only occasionally re-requests files, the far-from-great
performance of serving files through PHP is irrelevant.
For big sites, this can be problematic: if your site has so many files that the
CDN cannot cache them all, the CDN may continuously request files, amounting to
a constant load on your server of files being served through PHP. In that case,
you may want to let your web server take care of that for you.

Apache users can add the following rules to <IfModule mod_rewrite.c> section of
your .htaccess file:

  ### CDN START ###
  # See http://drupal.org/node/1413156
  <IfModule mod_headers.c>
    # Transform /cdn/ff/[security token]/[mtime]/[scheme]/X/Y/Z to /X/Y/Z and set
    # environment variable for later Header rules.
    RewriteCond %{REQUEST_URI} ^/cdn/ff/[^/]+/[^/]+/[^/]+/(.+)$
    RewriteRule .* %1 [L,E=FARFUTURE_CDN:1]

    # Apache will change FARFUTURE_CDN to REDIRECT_FARFUTURE_CDN on internal
    # redirects, restore original environment variable.
    # See http://stackoverflow.com/q/3050444
    RewriteCond %{ENV:REDIRECT_FARFUTURE_CDN} =1
    RewriteRule .* - [E=FARFUTURE_CDN:1]


    ###
    ### Always reply "304 Not Modified" to "If-Modified-Since" header.
    ###

    # The redirect works only if URL was actually modified by rewrite rule
    # (probably, to prevent infinite loops). So, we rewrite the URL with
    # website root and this causes the webserver to return 304 status.
    RewriteCond %{ENV:FARFUTURE_CDN} =1
    RewriteCond %{HTTP:If-Modified-Since} !=""
    RewriteRule .* / [R=304,L]


    ###
    ### Generic headers that apply to all /cdn/ff/* requests.
    ###

    # Instead of being powered by Apache, tell the world this resource was
    # powered by the CDN module's .htaccess!
    Header set X-Powered-By "Drupal CDN module (.htaccess)" env=FARFUTURE_CDN

    # Instruct intermediate HTTP caches to store both a compressed (gzipped) and
    # uncompressed version of the resource.
    Header set Vary "Accept-Encoding" env=FARFUTURE_CDN

    # Support partial content requests.
    Header set Accept-Ranges "bytes" env=FARFUTURE_CDN

    # Do not use ETags for cache validation.
    Header unset ETag env=FARFUTURE_CDN

    # Browsers that implement the W3C Access Control specification might refuse
    # to use certain resources such as fonts if those resources violate the
    # same-origin policy. Send a header to explicitly allow cross-domain use of
    # those resources. (This is called Cross-Origin Resource Sharing, or CORS.)
    Header set Access-Control-Allow-Origin "*" env=FARFUTURE_CDN
    Header set Access-Control-Allow-Methods "GET, HEAD" env=FARFUTURE_CDN

    # Set a far future Cache-Control header (480 weeks), which prevents
    # intermediate caches from transforming the data and allows any intermediate
    # cache to cache it, since it's marked as a public resource.
    Header set Cache-Control "max-age=290304000, no-transform, public" env=FARFUTURE_CDN

    # Set a far future Expires header. The maximum UNIX timestamp is somewhere
    # in 2038. Set it to a date in 2037, just to be safe.
    Header set Expires "Tue, 20 Jan 2037 04:20:42 GMT" env=FARFUTURE_CDN

    # Pretend the file was last modified a long time ago in the past, this will
    # prevent browsers that don't support Cache-Control nor Expires headers to
    # still request a new version too soon (these browsers calculate a
    # heuristic to determine when to request a new version, based on the last
    # time the resource has been modified).
    # Also see http://code.google.com/speed/page-speed/docs/caching.html.
    Header set Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT" env=FARFUTURE_CDN
  </IfModule>
  ### CDN END ###

MAINTAINERS
-----------

Current maintainers:
  * Wim Leers - https://wimleers.com/

Version 1 of this module (for Drupal 6) was written as part of the bachelor
thesis of Wim Leers at Hasselt University.

  * https://wimleers.com/tags/bachelor-thesis
  * https://uhasselt.be/

File

README.txt
View source
  1. CONTENTS OF THIS FILE
  2. ---------------------
  3. * Introduction
  4. * Installation
  5. * FAQ
  6. * Troubleshooting
  7. * Maintainers
  8. INTRODUCTION
  9. ------------
  10. This module provide easy Content Delivery Network integration for Drupal sites.
  11. It alters file URLs, so that files (CSS, JS, images, fonts, videos …) are
  12. downloaded from a CDN instead of your web server.
  13. It does *not* put your entire website behind a CDN.
  14. Only "Origin Pull" CDNs are supported. These are CDNs that only require you to
  15. replace the domain name with another domain name. The CDN will then
  16. automatically fetch (pull) the files from your server (the origin). Nowadays
  17. pretty much every CDN is an Origin Pull CDN.
  18. The CDN module aims to do only one thing and do it well: altering URLs to
  19. point to files on CDNs. It supports:
  20. * Any sort of CDN mapping
  21. * DNS prefetching: lets browsers connect to the CDN faster
  22. * SEO: prevents CDN from serving HTML and REST responses, only allow files
  23. * Forever cacheable files (optimal far future expiration)
  24. * Auto-balancing files over multiple CDNs
  25. * … and many more details that are taken care of automatically
  26. The "CDN UI" module is included, and can be used for configuring the CDN module.
  27. Once set up, it can be uninstalled.
  28. INSTALLATION
  29. ------------
  30. 1) Place this module directory in your "modules" folder
  31. 2) Install the module.
  32. 3) Go to your CDN provider's control panel and set up a "CDN instance" (Amazon
  33. CloudFront calls this a "distribution"). There, you will have to specify
  34. the origin server (Amazon CloudFront calls this a "custom origin"), which
  35. is simply the domain name of your Drupal site.
  36. The CDN will provide you with a "delivery address", this is the address
  37. that we'll use to download files from the CDN instead of the Drupal server.
  38. Suppose this is `http://d85nwn7m5gl3y.cloudfront.net`.
  39. Be sure to forward query strings from the CDN to the origin! Otherwise image
  40. style derivatives will not work.
  41. (It acts like a globally distributed, super fast proxy server.)
  42. Relevant links:
  43. - Amazon CloudFront gotcha: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/QueryStringParameters.html
  44. 4) Optionally, you can create a CNAME alias to the delivery address on your
  45. DNS server. This way, it's not immediately obvious from the links in the
  46. HTMl that you're using an external service (that's why it's also called a
  47. vanity domain name).
  48. However, if you're going to use your CDN in HTTPS mode, then using vanity
  49. domains will break things (because SSL certificates are bound to domain
  50. names).
  51. 5) Configure the CDN module. Either modify and import the `cdn.settings.yml`
  52. configuration file manually or install the included CDN UI module to
  53. configure it through a UI. Provide the (vanity) domain name that your CDN
  54. has given you (`d85nwn7m5gl3y.cloudfront.net` in our example).
  55. 6) If your site is behind a reverse proxy such as Varnish, so that your stack
  56. looks like: CDN <-> reverse proxy <-> web server, then you need to take extra
  57. measures if you want to prevent duplicate content showing up on the CDN. See
  58. \Drupal\cdn\StackMiddleware\DuplicateContentPreventionMiddleware for details.
  59. It's possible in this situation to end up with redirect loops; for that
  60. reason the CDN module adds a debugging header to the 301 redirects it emits
  61. in order to facilitate troubleshooting.
  62. FAQ
  63. ---
  64. Q: Is the CDN module compatible with Drupal's Page Cache?
  65. A: Yes.
  66. Q: Is the CDN module compatible with Drupal's "private files" functionality?
  67. A: Yes. The CDN module won't break private files, they will continue to work
  68. the same way. However, it cannot serve private files from a CDN. Not every
  69. CDN supports protected/secured/authenticated file access, and those that do
  70. each have their own way of doing this (there is no standard). So private
  71. files will continue to be served by Drupal, which may or may not be
  72. acceptable for your use case.
  73. Q: Does this module only work with Apache or also with nginx, lighttpd, etc.?
  74. A: This module only affects HTML, so it doesn't matter which web server you use!
  75. TROUBLESHOOTING
  76. ---------------
  77. For small sites the 'Forever cacheable files' (farfuture) functionality works
  78. fine out of the box. The CDN module serves all files through PHP with optimal
  79. headers. Since the CDN only occasionally re-requests files, the far-from-great
  80. performance of serving files through PHP is irrelevant.
  81. For big sites, this can be problematic: if your site has so many files that the
  82. CDN cannot cache them all, the CDN may continuously request files, amounting to
  83. a constant load on your server of files being served through PHP. In that case,
  84. you may want to let your web server take care of that for you.
  85. Apache users can add the following rules to section of
  86. your .htaccess file:
  87. ### CDN START ###
  88. # See http://drupal.org/node/1413156
  89. # Transform /cdn/ff/[security token]/[mtime]/[scheme]/X/Y/Z to /X/Y/Z and set
  90. # environment variable for later Header rules.
  91. RewriteCond %{REQUEST_URI} ^/cdn/ff/[^/]+/[^/]+/[^/]+/(.+)$
  92. RewriteRule .* %1 [L,E=FARFUTURE_CDN:1]
  93. # Apache will change FARFUTURE_CDN to REDIRECT_FARFUTURE_CDN on internal
  94. # redirects, restore original environment variable.
  95. # See http://stackoverflow.com/q/3050444
  96. RewriteCond %{ENV:REDIRECT_FARFUTURE_CDN} =1
  97. RewriteRule .* - [E=FARFUTURE_CDN:1]
  98. ###
  99. ### Always reply "304 Not Modified" to "If-Modified-Since" header.
  100. ###
  101. # The redirect works only if URL was actually modified by rewrite rule
  102. # (probably, to prevent infinite loops). So, we rewrite the URL with
  103. # website root and this causes the webserver to return 304 status.
  104. RewriteCond %{ENV:FARFUTURE_CDN} =1
  105. RewriteCond %{HTTP:If-Modified-Since} !=""
  106. RewriteRule .* / [R=304,L]
  107. ###
  108. ### Generic headers that apply to all /cdn/ff/* requests.
  109. ###
  110. # Instead of being powered by Apache, tell the world this resource was
  111. # powered by the CDN module's .htaccess!
  112. Header set X-Powered-By "Drupal CDN module (.htaccess)" env=FARFUTURE_CDN
  113. # Instruct intermediate HTTP caches to store both a compressed (gzipped) and
  114. # uncompressed version of the resource.
  115. Header set Vary "Accept-Encoding" env=FARFUTURE_CDN
  116. # Support partial content requests.
  117. Header set Accept-Ranges "bytes" env=FARFUTURE_CDN
  118. # Do not use ETags for cache validation.
  119. Header unset ETag env=FARFUTURE_CDN
  120. # Browsers that implement the W3C Access Control specification might refuse
  121. # to use certain resources such as fonts if those resources violate the
  122. # same-origin policy. Send a header to explicitly allow cross-domain use of
  123. # those resources. (This is called Cross-Origin Resource Sharing, or CORS.)
  124. Header set Access-Control-Allow-Origin "*" env=FARFUTURE_CDN
  125. Header set Access-Control-Allow-Methods "GET, HEAD" env=FARFUTURE_CDN
  126. # Set a far future Cache-Control header (480 weeks), which prevents
  127. # intermediate caches from transforming the data and allows any intermediate
  128. # cache to cache it, since it's marked as a public resource.
  129. Header set Cache-Control "max-age=290304000, no-transform, public" env=FARFUTURE_CDN
  130. # Set a far future Expires header. The maximum UNIX timestamp is somewhere
  131. # in 2038. Set it to a date in 2037, just to be safe.
  132. Header set Expires "Tue, 20 Jan 2037 04:20:42 GMT" env=FARFUTURE_CDN
  133. # Pretend the file was last modified a long time ago in the past, this will
  134. # prevent browsers that don't support Cache-Control nor Expires headers to
  135. # still request a new version too soon (these browsers calculate a
  136. # heuristic to determine when to request a new version, based on the last
  137. # time the resource has been modified).
  138. # Also see http://code.google.com/speed/page-speed/docs/caching.html.
  139. Header set Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT" env=FARFUTURE_CDN
  140. ### CDN END ###
  141. MAINTAINERS
  142. -----------
  143. Current maintainers:
  144. * Wim Leers - https://wimleers.com/
  145. Version 1 of this module (for Drupal 6) was written as part of the bachelor
  146. thesis of Wim Leers at Hasselt University.
  147. * https://wimleers.com/tags/bachelor-thesis
  148. * https://uhasselt.be/