When using an external build process (webpack, grunt) it's helpful for
rails to be able to serve those assets. Brotli has better compression
than gzip and should eventually replace it for static assets.
When using an external build process (webpack, grunt) it's helpful for
rails to be able to serve those assets. Brotli has better compression
than gzip and will eventually replace it for static assets.
The rack gem returns PATH_INFO as an ASCII-8BIT encoded string but it
was being converted to US-ASCII by the match? method because it was
calling Rack::Utils.escape_path. To prevent incompatibile encoding
warnings use ASCII-8BIT strings for the root path and let Ruby handle
any filename encoding conversion.
Fixes#32294, Closes#32314.
A gzip file has a checksum and length for the decompressed data in its
footer which isn't checked by just calling Zlib::GzipReader#read.
Calling Zlib::GzipReader#close must be called after reading to the end
of the file causes this check to be done, which is done by
Zlib::GzipReader.wrap after its block is called.
The `ActionDispatch::Static` middleware is used low down in the stack to serve
static assets before doing much processing. Since it's called from so low in
the stack, we don't have access to the request ID at this point, and generally
won't have any exception handling defined (by default `ShowExceptions` is added
to the stack quite a bit higher and relies on logging and request ID).
Before 8f27d6036a
this middleware would ignore unknown HTTP methods, and an exception about these
would be raised higher in the stack. After that commit, however, that exception
will be raised here.
If we want to keep `ActionDispatch::Static` so low in the stack (I think we do)
we should suppress the `ActionController::UnknownHttpMethod` exception here,
and instead let it be raised higher up the stack, once we've had a chance to
define exception handling behaviour.
This PR updates `ActionDispatch::Static` so it passes `Rack::Request` objects to
`ActionDispatch::FileHandler`, which won't raise an
`ActionController::UnknownHttpMethod` error. If an unknown method is
passed, it should exception higher in the stack instead, once we've had a
chance to define exception handling behaviour.`
Now ActionDispatch::Static can accept HTTP headers so that developers
will have control of returning arbitrary headers like
'Access-Control-Allow-Origin' when a response is delivered. They can
be configured through `#config.public_file_server.headers`:
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=60",
"Access-Control-Allow-Origin" => "http://rubyonrails.org"
}
Also deprecate `config.static_cache_control` in favor of
`config.public_file_server.headers`.
Set `config.static_index` to serve a static directory index file not
named `index`. For example, to serve `main.html` instead of `index.html`
for directory requests, set `config.static_index` to `"main"`.
When 7e504927 was merged setting `Encoding.default_internal` and
`Encoding.default_external` would throw a warning when the ActionPack
tests were run.
Example warning: `actionpack/test/dispatch/static_test.rb:12: warning:
setting Encoding.default_external`
This patch silences the warnings as other similar tests do for setting
default_internal and default_external.
Dir.glob can be a security concern. The original use was to provide logic of fallback files. Example a request to `/` should render the file from `/public/index.html`. We can replace the dir glob with the specific logic it represents. The glob {,index,index.html} will look for the current path, then in the directory of the path with index file and then in the directory of the path with index.html. This PR replaces the glob logic by manually checking each potential match. Best case scenario this results in one less file API request, worst case, this has one more file API request.
Related to #16464
Update: added a test for when a file of a given name (`public/bar.html` and a directory `public/bar` both exist in the same root directory. Changed logic to accommodate this scenario.
- don't mutate PATH_INFO in env, test
- test fallback content type matches Rack::File
- change assertion style
- make HTTP_ACCEPT_ENCODING comparison case insensitive
- return gzip path from method instead of true/false so we don't have to assume later
- don't allocate un-needed hash.
Original comments:
https://github.com/rails/rails/commit/
cfaaacd9763642e91761de54c90669a88d772e5a#commitcomment-7468728
cc @jeremy
If someone is using ActionDispatch::Static to serve assets and makes it past the `match?` then the file exists on disk and it will be served. This PR adds in logic that checks to see if the file being served is already compressed (via gzip) and on disk, if it is it will be served as long as the client can handle gzip encoding. If not, then a non gzip file will be served.
This additional logic slows down an individual asset request but should speed up the consumer experience as compressed files are served and production applications should be delivered with a CDN. This PR allows a CDN to cache a gzip file by setting the `Vary` header appropriately. In net this should speed up a production application that are using Rails as an origin for a CDN. Non-asset request speed is not affected in this PR.
In #5337 we forced the path encoding to ASCII-8BIT to prevent static
file handling from blowing up before an application has had chance to
deal with possibly invalid urls. However this has a negative side
effect of making it an incompatible encoding if the application's
public path has UTF-8 characters in it.
To work around the problem we check to see if the path has a valid
encoding once it has been unescaped. If it is not valid then we can
return early since it will not match any file anyway.
Fixes#13518
This commit inverts the precedence in ActionDispatch::Static so that
dynamic content will be served before static content. This is so that
precompiled assets do not inadvertently get included when running in
development mode - it should have no effect in production where static
files are usually handled by the web server.
Closes#6421
Windows doesn't allow `\ / : * ? " < > |` in filenames so create
the fixture files at runtime and ignore the incompatible ones when
running on Windows.
RFC 3986[1] allows sub-delim characters in path segments unencoded,
however Rack::File requires them to be encoded so we use URI's
unescape method to leave them alone and then escape them again.
Also since the path gets passed to Dir[] we need to escape any glob
characters in the path.
[1]: http://www.ietf.org/rfc/rfc3986.txt