-
Notifications
You must be signed in to change notification settings - Fork 165
Requesting /favicon.ico URL invokes function, ignores its response, logs error to console #191
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
Comments
We should not invoke on those paths, yes. I think this is due to an issue with our routing. We shouldn't call Obviously this an edge case as Functions aren't ideal for rendering web apps. |
Exactly, the I'm using Functions to run CI/CD with a Bitbucket repo, and one invocation is an OAuth2 callback from the browser. So it has only a very little bit of a Web application. I'll send a PR, fixing the Express' 404 nonsense at the same time if you do not mind. |
A PR with a test or two sounds good. Will look Monday. |
Uh, the test is a hard part, considering that my experience with JS/TS is limited to only few hours. But I'll try to figure it out. :) |
No worries. Will be able to help out later if needed, thanks for the issue. |
Other changes: * Send an empty response body for the same with the 404, since these URLs are not intended for human consumption. * Add an invocation count assertion to the test to confirm that these URLs do not in fact result in the function call. * Accept npm's lock of this package version as test dependency. * Nit: wrap long comments at 80 characters. Fixes: #191
Thanks for finding and fixing this issue. It was my change that caused this. |
Unexpected behavior
invoker.ts
handles the URLs '/favicon.ico' and '/robots.txt' specially, by sending back a 404 response. I assume that, by design, this was all what these two URLs were supposed to do, so that the behavior I am seeing is really a bug.Reproduction
Everything goes as expected...
curl localhost:8080
at the last step.npm start
again.curl -s http://localhost:8080
. Observe that, in addition to the reply being returned, a linehelloWorld is invoked
is printed to the server console.curl -sv http://localhost:8080/favicon.ico
. Quite as expected, the command returns a404 Not Found
response¹.____________
¹ And, somewhat less expected, courtesy of Express and on its conscience, also a text/plain body with the text "Not Found" which is not required, provides no extra information and thus unneeded, goes without the terminating
\r\n
as text/plain is supposed to be. But this is what Express does by default....until it does not
But much less than expected, the server console now shows:
This is rather bad. The function is actually invoked, with all its possible side effects. But whatever it returns is not seen by the caller: the framework has already sent a complete response to the HTTP trigger:
and, sure enough, Express gets very angry when the function calls
res.send('Hello, World')
: it has already sent a complete response even before the function was entered.I noticed the problem while trying the function using a Web browser. Every time I did a full refresh (i.e. discarding cache, C+S+r in Chrome), I surprisingly saw 2 invocation log messages from the function to console, and this stack trace.
I found the root cause, will open a PR today. It's quite an obvious bug with a one-line fix, easy to verify by tweaking the framework code under node_modules. Also, the bug certainly slips through tests in test/invoker.ts, but I have no idea how to also verify that /favicons.ico (and /robots.txt) do not cause the function invocation. The test should also verify that the function mock was not in fact called with these two special URLs, and that exceeds my knowledge of the test framework. In fact, I only learned a bit of node.js and JS yesterday morning (really, no kidding, but it's a very simple language, and TypeScript strong-ish typing with VS Intellisense help a lot).
Workaround in production GCP deployment
Compare the
req.path
property to one of the two special URLs (/favicons.ico
and/robots.txt
) and return without attempting to send a response, for example,the first thing in function code. This is especially important if function is designed to accept calls from Web browsers.
The text was updated successfully, but these errors were encountered: