-
Notifications
You must be signed in to change notification settings - Fork 687
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
Abort image prefetch if Content-Length
exceeds limit
#1567
Conversation
src/plugins/irc-events/link.js
Outdated
} else { | ||
// response is an image | ||
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch | ||
const contentLength = parseInt(res.headers["content-length"], 10) || NaN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseInt returns NaN on it's own, I would change it to 0 though, then you don't need to the AND check below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing in Chrome's dev console with a simple literal object, running parseInt on a key that didn't exist set the test var to undefined
. But using 0 instead is sensible. I went with NaN and the &&
in case a negative limit (i.e. no limit) is/will be possible.
src/plugins/irc-events/link.js
Outdated
@@ -163,6 +163,13 @@ function fetch(uri, cb) { | |||
// if not image, limit download to 50kb, since we need only meta tags | |||
// twitter.com sends opengraph meta tags within ~20kb of data for individual tweets | |||
limit = 1024 * 50; | |||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you invert the if above, it will look cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you're asking me to do, but my interpretation is to make the first if test for whether it is an image, rather than not, and swap the code blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
b51f7d0
to
0554702
Compare
src/plugins/irc-events/link.js
Outdated
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch | ||
const contentLength = parseInt(res.headers["content-length"], 10) || NaN; | ||
if (contentLength && contentLength > limit) { | ||
res.req.abort(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be res.abort
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I was copying the code in the pipe handler below because I couldn't find a reference to abort()
in the docs for request
. For future reference, where is it documented that you can call abort()
directly on the response
passed to this event handler?
src/plugins/irc-events/link.js
Outdated
if ((/^image\/.+/.test(res.headers["content-type"]))) { | ||
// response is an image | ||
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch | ||
const contentLength = parseInt(res.headers["content-length"], 10) || NaN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the 0 as I suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the other comments in the batch are done.
src/plugins/irc-events/link.js
Outdated
@@ -159,7 +159,14 @@ function fetch(uri, cb) { | |||
var limit = Helper.config.prefetchMaxImageSize * 1024; | |||
req | |||
.on("response", function(res) { | |||
if (!(/^image\/.+/.test(res.headers["content-type"]))) { | |||
if ((/^image\/.+/.test(res.headers["content-type"]))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove extra parenthesis.
0554702
to
2442d76
Compare
2442d76
to
59e311c
Compare
src/plugins/irc-events/link.js
Outdated
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch | ||
const contentLength = parseInt(res.headers["content-length"], 10) || 0; | ||
if (contentLength > limit) { | ||
res.abort(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
abort calls abort on req internally, so yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dgw, mind switching to req.abort()
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no req
parameter passed to this handler, only res
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have access to req
from L160. It's also being used at R179 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What. Has variable scoping changed since I learned JS (over a decade ago, I feel old 😁)? L160 is outside the function definitions in both cases; how does that work? 😕
(Also, L179 seems silly with the req.response.req
thing… It's not related to this PR but now I really want to make it just req.abort()
…)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be req.abort
, yeah.
if (/^image\/.+/.test(res.headers["content-type"])) { | ||
// response is an image | ||
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch | ||
const contentLength = parseInt(res.headers["content-length"], 10) || 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you guys had some discussion about this so sorry if I missed something, but it looks to me that you don't even need || 0
(which I find more misleading than explicit):
> const limit = 2048
undefined
> parseInt({}["content-length"], 10)
NaN
> NaN > limit
false
> null > limit
false
> undefined > limit
false
> 4096 > limit
true
So whatever parseInt
returns, if the value is not an integer, the check below will be false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not misleading as it will force an integer type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary, I don't think we should do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like comparing the wrong data type if I can avoid it. Passing NaN into anything number-related feels kinda dirty…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, I guess.
If the Content-Length header is present in the response when an image is prefetched, The Lounge can avoid wasting bandwidth (both for itself and for the image's host) if the value of the header exceeds the prefetch size limit by aborting the request immediately.
59e311c
to
09cd9ce
Compare
Content-Length
exceeds limit
Does adding this beg for the addition of tests? If so, someone will probably have to guide me in doing that. 😁
Closes #1563.