-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
18.0.0 Release Notes #3871
Comments
I looked into Additionally, I found that the Watch out if you use any of these modules. |
According to the hapi 18 release notes, request.url.path has gone away in favor of request.path or request.url.pathname. The same release notes also state that request.url.pathname has not changed. Refs: hapijs/hapi#3871
@hueniverse
… to avoid subtle mistakes during migration. |
Has anyone confirmed Bell working with v18? I was having trouble and was going to try and investigate this week. Possibly related to this behavior: hapijs/bell#394 |
@rluba we just had the exactly same subtile issue, a regression, because both Thanks for pointing that out. |
@framerate I’ve just published a PR that fixes your issue with bell (hapijs/bell#397). |
This PR includes two fixes related to [hapi 18](hapijs/hapi#3871): 1. Many tests broke because hapi now strips the default port from `request.info.host` (a side effect of using the WHATWG URL API) – causing lots of assertions to fail. I decided to use a non-default port in the tests instead of removing the default port from the assertions. This verifies that port info is still propagated correctly. 2. `request.url.query` is no longer available. I’ve changed it to `request.query` which works for hapi 18 and older versions. (I’ve tested it with hapi 17 and 18). This fixes #394.
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions. |
Summary
hapi v18.0.0 is a small size release with a few changes to improve performance and standards compliance.
Breaking Changes
Note: changes marked with validated are validated by the framework and will fail to execute if not properly migrated. They are considered safe / easy changes since they will throw an error immediately.
server.options.cache
andserver.cache.provision()
configuration restructured. validatedUrl.parse()
method to the WHATWG URL API.server.inject()
authentication options. validatedrequest.response
being forced tonull
), including aborted/closed requests.server.auth.test()
return value changed fromcredentials
to{ credentials, artifacts }
.request.info.responded
now only set when response transmitted successfully.New Features
server.options.query.parser
- new configuration to customize query parameters processing.minCleanupIntervalMsec
andcloneBuffersOnGet
.route.options.response.disconnectStatusCode
- allows setting a default status code for disconnected client errors. Defaults to499
.route.options.validate.state
as well as access to state inputs in other validations.Bug fixes
application/octet-stream
(No Content-Type header when returning a stream #3891)onRequest
("Cannot set headers after they are sent to the client" after returning h.abandon #3884)Updated dependencies
Migration Checklist
Server Cache Configuration
This release streamlines the configuration and provisioning of server caches. It was done to prevent confusion when configuring cache strategies and prevent deep cloning of options passed which prevent some combination from operating properly.
The
engine
property no longer supports passing a class of constructor function. Instead, a newprovider
configuration key was added. In addition, thepartition
option was moved into the newprovider.options
.For example:
Checklist:
engine
config references and where found, rework the config to match the new format.In-Memory Cache
This release replaces the implementation of the catbox-memory cache which is the default cache implementation provided with every server instance. Before this change, every item stored in the cache created a system timer which fired when the item expired. This worked fine for small number of items but in some cases with many items, the timer count could become a problem. This was made significantly worse if node domains are used since they increase the memory footprint of each timer.
The new implementation uses a single timer which is only set when a value is stored in the cache. If the cache contains a large number of items with very small timeouts, the processing overhead may cause a different load pattern than before (repeated cache iterations vs. repeated timers management).
Note that the in memory cache was never designed to be a replacement for a proper cache such as Memcached or Redis. It is a useful tool for simple use cases. If you are using it in any meaningful scale, you should test how this change impacts your server's performance under load.
To help control the new behavior, the following new cache configuration option is available:
minCleanupIntervalMsec
- the minimum number of milliseconds in between each cache cleanup. Defaults to 1 second (1000
).Checklist:
WHATWG URL
Following node's move to deprecate its
Url.parse()
andUrl.format()
methods, this release migrates its URL format to use the new WHATWG URL object. Since most applications use therequest.path
,request.query
, andrequest.info
properties, those will remain unaffected.However, for those accessing
request.url
, the following changes apply:request.url.pathname
request.url.search
null
):request.url.protocol
request.url.host
request.url.hostname
request.url.hash
request.url.href
- new value is now always the full absolute URL (previously it was often relative URL)request.url.slashes
request.url.auth
- replaced by the newrequest.url.username
andrequest.url.password
propertiesrequest.url.query
- userequest.query
insteadrequest.url.path
- userequest.path
orrequest.url.pathname
request.url.origin
request.url.username
request.url.password
request.url.searchParams
When calling
request.setUrl(url)
, theurl
argument must be one of:Url.URL
Previously it was possible to pass a
Url.parse()
object with a stringquery
which causedrequest.query
to be a string instead of an object. This is no longer a possible side effect. Passing the result ofUrl.parse()
asurl
is no longer supported.In
onRequest
extensions, if the request path is invalid,request.url
will now be set tonull
and if it is not corrected viarequest.setUrl()
, the request will result in a bad request error response. Previously, therequest.url
was set to best effort parsing which was mostly invalid.Checklist:
request.url
references in your code and make sure the changes to the available properties do not impact you (or adjust accordingly).request.setUrl()
references in your code and ensure you are only passing valid arguments.request.setUrl()
to override query processing (e.g. using the qs module), consider switching to the much simplerserver.options.query.parser
option.onRequest
extension handlers, make sure your code can handlerequest.url
being set tonull
if therequest.path
received is invalid.server.inject()
AuthenticationIn order to fully support request injection authentication as a production-ready feature, the injection options were changed to require passing the name of the strategy being simulated to authenticate the request. Previously, a special
'bypass'
strategy name was set for all injected credentials.To use the new format simply wrap the
credentials
and optionalartifacts
with anauth
object and add a newstrategy
key with a name matching a configured authentication strategy.For example:
await server.inject({ url: '/', credentials: { user: 'steve' } });
changes toawait server.inject({ url: '/', auth: { credentials: { user: 'steve' }, strategy: 'default' } });
.Checklist:
Scan your code for
server.inject
withcredentials
option and adjust to the new format.Scan your code for references to
'bypass'
to ensure you are not relying on the fake strategy name in your code. If you need to know if a request has been injected with credentials, userequest.auth.isInjected
.Response Errors
In previous versions, when a response failed to transmit fully, the error was logged as a request error but then the
request.response
value was forced tonull
. This had the side effect of causing logs to have no access to the actual status code and default to200
. It also made it more difficult to handle such errors via theresponse
event since by then therequest.response
value was already forced tonull
.In addition,
request.info.responded
was always set to a timestamp when request processing completed, regardless if a response was actually successfully transmitted. Instead,request.info.responded
will now only be set to a non0
value if the response was successfully sent. A newrequest.info.completed
value will always contain a valid timestamp indicating when the request completed processing (right before the'response'
event is emitted).Checklist:
Review how you handle
request.response
values when a request ends (e.g. theresponse
event). If you currently check fornull
, check for errors instead. Internal transmit errors will use status code 500 and client disconnections will use status code 499 (which can be customized viaroute.options.response.disconnectStatusCode
.Consider updating your logging facilities to handle the change in how client disconnections are reported (from a default of
200
to the new499
value). You may want to ignore499
errors if you do not care about disconnections, or produce new reports based on the new data.If you access
request.info.responded
(usually in logging logic), consider switching torequest.info.completed
if you want to know when the server finished processing and use the existence ofrequest.info.responded
to log if a response was successful.server.auth.test()
Return ValueThe return value changed from plain
credentials
to{ credentials, artifacts }
. Simply replace:const credentials = server.test.auth(...)
withconst { credentials } = server.test.auth(...)
.Checklist:
server.auth.test
(or maybe just.auth.test
in case you call the server object something else, and fix the assignment of the return value accordingly.The text was updated successfully, but these errors were encountered: