If the upstream response doesn't include an `ETag` header, the ETag
middleware needs to clone the response so it can read the body to
compute an ETag. This commit simplifies the management of the original
and cloned responses.
* perf(deno/middlewares/serveStatic): serve static with stream
* Revert "perf(deno/middlewares/serveStatic): serve static with stream"
This reverts commit 0360966d1e.
* fix(deno/middlewares/serveStatic): fix position and test for serve static with stream
* chore(deno/middlewares/serveStatic): clean temp dist files
`Request.prototype.header` has two overloads:
1. with a string name, it returns that header value if present
2. with no argument, it returns all the headers as an object
Previously, the implementation built the whole object for (2) even when
returning a single header. This was wasteful. This commit changes it to
return the header by name if specified and only iterate over all the
headers when the caller asks for the whole object.
* chore(etag): reduce global state in tests
Previously, the `etag` tests used a single Hono `app` that was
instantiated statically before the tests. Having a shared app increases
the chances of inter-test conflicts and makes it impossible to modify
the app for a single test. This, in turn, makes it harder for test
maintainers to see the connection between the app configuration and the
expectations.
This commit moves the creation of the `app` into a `beforeEach` block
and moves any app configuration that relates to a single test case into
that test case.
* perf(etag): don't override ETags from upstream
Previously, the `etag` middleware would always compute an `ETag`
header based on the SHA-1 of the `Response` body. In cases where the
upstream response already includes the header, this wastefully
clones the response, reads the body into memory, and computes a hash.
This commit changes the middleware to bypass the hash computation if
the `Response` already has an ETag.
* perf(etag): 304s include only necessary headers
The spec[^1] for 304 Not Modified says,
> The server generating a 304 response MUST generate any of the
> following header fields that would have been sent in a 200 (OK)
> response to the same request:
>
> * Content-Location, Date, ETag, and Vary
> * Cache-Control and Expires (see [CACHING])
>
> Since the goal of a 304 response is to minimize information transfer
> when the recipient already has one or more cached representations, a
> sender SHOULD NOT generate representation metadata other than the
> above listed fields unless said metadata exists for the purpose of
> guiding cache updates (e.g., Last-Modified might be useful if the
> response does not have an ETag field).
Previously, the `etag` middleware was sending all headers from the
original response except for `content-type` (omitted by
`Context.prototype.set res`) and `content-length` (omitted by the `etag`
middleware itself).
This commit changes the middleware to include only the headers
required with the spec, upgrading it from _conditionally compliant_ to
_fully compliant_. The list is configurable as
`options.retainedHeaders`.
[^1]: https://www.rfc-editor.org/rfc/rfc9110#name-304-not-modified
* fix(etag): Support multi-value If-None-Match
The spec[^1] for `If-None-Match` says,
> If the field value is a list of entity tags, the condition is false if
> one of the listed tags matches the entity tag of the selected
> representation.
and provides these examples:
```
If-None-Match: "xyzzy"
If-None-Match: W/"xyzzy"
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-None-Match: *
```
The value `*` isn't relevant for this middleware, but the other values
are.
This commit adds support for multi-value comma-separated ETags in the
`If-None-Match` header.
[^1]: https://www.rfc-editor.org/rfc/rfc9110#name-if-none-match
* perf(etag): prefer Header.prototype.get
Previously, the `etag` middleware used `c.req.header(...)` to access the
`If-None-Match` header. This method works, but is less efficient than
accessing the value via the raw `Headers` object.
Additionally, the middleware was trying multiple case versions for the
same header, but header-lookup is case-insensitive, so it was wasting
time on requests that lacked the header altogether.
This change also makes `etag` consistent with the other middleware in
this repo (e.g. `basic-auth`, `compress`), which all use
`c.req.headers.get(...)` to access headers.
* Allow setting cookie's maxAge to 0.
* fix(cookie): `maxAge` should be positive
* denoify
---------
Co-authored-by: David Manouchehri <david.manouchehri@ai.moda>
The current logic for decoding application/x-www-form-urlencoded is
overly restrictive and misses `Content-Type` headers with a character
encoding set, i.e., application/x-www-form-urlencoded; charset=UTF-8.
This fix harmonizes the logic for handling multipart/form-data
and application/x-www-form-urlencoded in the `parseBody` method of
request objects.
* fix(trie-router): fixed the named capture issue
* denoify
* denoify
* refactor(pattern-router): Use Object.assign for shortening the code. (#1154)
* refactor(pattern-router): Use `Object.assign` for shortening the code.
* chore: denoify
---------
Co-authored-by: Taku Amano <taku@taaas.jp>
* feat: handle HEAD method
* remove `head` from `METHOS`
* fixed the lagon test
* show `depracated` message (will be removed next minor? version)
* denoify
* use `request.url`
* denoify
* Invoke dispatch() without changing request.method for HEAD method. (#1152)
* Invoke `dispatch()` without changing request.method for HEAD method.
* chore: denoify
* refactored
* denoify
* refactor: dispatch() arguments can no longer be omitted (#1156)
* Revert "refactored"
This reverts commit 2f8dacc42d.
* refactor: `dispatch()` arguments can no longer be omitted
* denoifiy
---------
Co-authored-by: Taku Amano <taku@taaas.jp>
* feat(context): `c.routerName()`
* chore: denoify
* Enable to get router name via `app.routerName`. (#1110)
---------
Co-authored-by: Taku Amano <taku@taaas.jp>
* Allow validator to apply validation to path param.
* chore: denoify
* feat(validator): Enable passing the path to ValidationFunction as a template parameter.
* chore: denoify
Co-authored-by: yusukebe <yusuke@kamawada.com>
* feat: `route()` with one argument is renamed `basePath()`.
* chore: denoify.
* refactor: Use `private` instead of hard private fields.
* refactor: The `route()` with one argument has reverted and deprecated.
* chore: denoify
* feat: `env` support enviroment variables for multi runtimes
* typo
* denoify
* fixed ci settings
* fixed deno command
* comment out lagon test
* remove warnings