Skip to content
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

feat: Set HEAD routes automatically for each GET route #2700

Merged
merged 16 commits into from
Dec 28, 2020
Merged

feat: Set HEAD routes automatically for each GET route #2700

merged 16 commits into from
Dec 28, 2020

Conversation

metcoder95
Copy link
Member

@metcoder95 metcoder95 commented Nov 20, 2020

Closes #2619

Note

  • The feature affects other tests as collateral. Tests need to be adjusted.
  • All feedback welcome 👍
  • Transformed into a minor feature

Open questions

  • Should be able to pass a global flag to deactivate the feature? Global and Route specific flags will be supported
  • Should be able to ignore specific routes (by RegExps or Strings)? Discarded

Checklist

lib/route.js Show resolved Hide resolved
@Eomm
Copy link
Member

Eomm commented Nov 21, 2020

Should be able to pass a global flag to deactivate the feature?

Reading the issue it seems not necessary: the logic: if the user defines a HEAD endpoint, the sibling GET will not process the request cover it I think

Should be able to ignore specific routes (by RegExps or Strings)?

I would avoid this feature at this first step

@Eomm Eomm added semver-major Issue or PR that should land as semver major v4.x Issue or pr related to Fastify v4 labels Nov 21, 2020
@zekth
Copy link
Member

zekth commented Nov 22, 2020

Thinking out loud:

  • Flag to activate / deactivate the feature is mandatory to me. eg: on some context you simply don't want to expose HEAD
  • Flag to do it on a granular way on routes can be a plus
  • Should be able to ignore specific routes (by RegExps or Strings)? The points enumerated before resolves this issue

@metcoder95
Copy link
Member Author

metcoder95 commented Nov 23, 2020

Thinking out loud:

  • Flag to activate / deactivate the feature is mandatory to me. eg: on some context you simply don't want to expose HEAD
  • Flag to do it on a granular way on routes can be a plus
  • Should be able to ignore specific routes (by RegExps or Strings)? The points enumerated before resolves this issue
  1. Actually I was thinking in the same way, maybe deactivate it by default and activate it on demand, in that way maybe lesser changes will be needed. But not sure if it's the best choice.

  2. Sounds good to me

@jsumners
Copy link
Member

  1. maybe deactivate it by default and activate it on demand

In that case, it wouldn't be a semver major change.

@SimenB
Copy link
Member

SimenB commented Nov 24, 2020

I strongly believe it should be the default, but introducing it in a semver minor disabled by default while allowing people to opt in and then flipping the default for the next major is probably a good path forward 👍

lib/headRoute.js Show resolved Hide resolved
lib/route.js Show resolved Hide resolved
lib/headRoute.js Show resolved Hide resolved
lib/headRoute.js Outdated Show resolved Hide resolved
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work!

fastify.js Outdated
@@ -96,6 +96,7 @@ function fastify (options) {
const requestIdLogLabel = options.requestIdLogLabel || 'reqId'
const bodyLimit = options.bodyLimit || defaultInitOptions.bodyLimit
const disableRequestLogging = options.disableRequestLogging || false
const exposeHeadRoutes = options.exposeHeadRoutes != null ? options.exposeHeadRoutes : true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs docs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the default is false, we can land this as minor against master.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with both approaches, setting it as false by default will require way fewer changes to the tests as most of them are broken because of the feature. Should we move forward with a minor version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for default to false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 124fa9e
I'll just need to adjust my PR to point to master

lib/route.js Outdated
@@ -231,6 +234,15 @@ function buildRouting (options) {
return
}

// TODO: @MetCoder95 Implement hability for ignoring paths
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not on the principles of Fastify. There is no ignoring (and regexps, etc). We can support it in an ecapsulation-friendly way if we want to.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, my bad! Actually, it's a leftover as I followed the suggestion of using a single-route/global flag to enable/disable the feature

lib/headRoute.js Outdated Show resolved Hide resolved
@metcoder95 metcoder95 changed the base branch from next to master November 30, 2020 22:04
@metcoder95 metcoder95 marked this pull request as ready for review November 30, 2020 22:04
Copy link
Member

@SimenB SimenB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is missing a change to the TypeScript types.

It probably makes sense to update the change in #2685 as well to mention it is built in from version 3.x (whenever it lands), but needs to be enabled.

docs/Routes.md Outdated Show resolved Hide resolved
docs/Server.md Outdated Show resolved Hide resolved
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@jsumners
Copy link
Member

jsumners commented Dec 1, 2020

this is missing a change to the TypeScript types.

We have a policy that these are updated by those who know them.

@mcollina mcollina added semver-minor Issue or PR that should land as semver minor and removed semver-major Issue or PR that should land as semver major v4.x Issue or pr related to Fastify v4 labels Dec 3, 2020
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'd need to add a test for the types changes.

lib/headRoute.js Outdated

if (typeof payload.resume === 'function') {
payload.on('error', (err) => {
reply.log.error({ err, path: req.url }, 'Error on Stream found for HEAD route')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
reply.log.error({ err, path: req.url }, 'Error on Stream found for HEAD route')
reply.log.error({ err }, 'Error on Stream found for HEAD route')

Path is not needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, done in 130646d

Copy link
Member

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina
Copy link
Member

@Eomm @SimenB anything to add?

const { exposeHeadRoute } = opts
const hasRouteExposeHeadRouteFlag = exposeHeadRoute != null
const shouldExposeHead = hasRouteExposeHeadRouteFlag ? exposeHeadRoute : globalExposeHeadRoutes
const headRouteExists = router.find('HEAD', path) != null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought: if there is a HEAD route and the user sets the route level option hasRouteExposeHeadRouteFlag too, would it be too harsh logging a warning?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think so, would be just adding an else if to see if the headRouteExists and hasRouteExposedHeadRouteFlag it's set to true for printing the warning. What do you think?

Copy link
Member

@Eomm Eomm Dec 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could let users say "oh gosh, it saves me a bad headache"
If you have the chance to add it, I think it will be really appreciated by someone!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha, sure! No issue at all, I think will save someone's day, let me add it 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 976b080
Please have a look 🙂

@metcoder95 metcoder95 requested a review from Eomm December 15, 2020 16:41
@metcoder95
Copy link
Member Author

Any clue why for Windows the tests are failing? Same issue on #2731 because the same issue

@metcoder95
Copy link
Member Author

Hi guys! Is there anything left I should take care of?

@mcollina mcollina merged commit 834a4e5 into fastify:master Dec 28, 2020
@mcollina
Copy link
Member

Nothing, CI got stuck.

@mattbishop
Copy link
Contributor

I'm glad to see this addition. FWIW, HEAD and GET are required according to RFC-7231:

All general-purpose servers MUST support the methods GET and HEAD.
All other methods are OPTIONAL.

@HosseinAgha
Copy link

HosseinAgha commented Apr 18, 2021

@metcoder95 I have a small question about this PR:
I cannot find this option on the fastify instance passed to fastify plugins.
Is this intended?

fastifyApp.resgiter((fastify, opt) => {
  fastify.route({
     url: ...
     exposeHeadRoutes: true // I get a TypeScript error here and when I bypass it using "as any" nothing happens
  })
})

@metcoder95
Copy link
Member Author

Hmm, the type for the route options has the exposeHeadRoute defined on route.d.ts:L25 which used for extending RouteOptions interface, as stated in route.d.ts:L112. Is also giving you troubles by using the singular form? exposeHeadRoute, without the s?

@HosseinAgha
Copy link

The exposeHeadRoute (singular) is added to fastify options after updating to 3.14.2. Thanks.

@github-actions
Copy link

github-actions bot commented May 5, 2022

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
semver-minor Issue or PR that should land as semver minor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically handle HEAD requests in GET handler unless explicit HEAD handler exists
10 participants