-
Notifications
You must be signed in to change notification settings - Fork 23
MAID-2488 feat/webFetch: impl multipart range requests #223
Conversation
test/browsing.js
Outdated
)); | ||
const domain = await createRandomDomain(content, '/streaming.mp4'); | ||
const app = await createAnonTestApp(); | ||
return should(app.webFetch(`safe://${domain}/streaming.mp4`, { range: { start: 0, end: content.length + 5 } })) |
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 wouldn't change the end
value to content.length + 5
as the test is trying to make sure that the very first byte out of range gets properly picked up as incorrect, that's where usually the issues are.
@@ -93,6 +93,14 @@ describe('Browsing', () => { | |||
)); | |||
}).timeout(20000); | |||
|
|||
it('fetches file with non-explicit mime type', async () => { |
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's the difference between this test and the test on line 193 named /index.html
?
Also, what do you mean by non-explicit mime type for this test?
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 test differs with the one on line 193 by creating a file without an extension, so a mimetype cannot be detected.
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.
We could then add the validation for the mime types to the tests
@@ -168,9 +168,6 @@ class SAFEApp extends EventEmitter { | |||
if (!url) return Promise.reject(makeError(errConst.MISSING_URL.code, errConst.MISSING_URL.msg)); | |||
|
|||
const parsedUrl = parseUrl(url); | |||
if (!parsedUrl) { |
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.
Why this is not needed anymore?
Also, we need to update the documentation as it seems it now accepts either an object or an array.
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 line isn't needed anymore because !url
is already handled on line 168. If there is an error parsing the url it will be handled by the the parseUrl
function.
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 is it that accepts an object or an array? The webFetch
function for it's url
parameter? I just see that we handle objects for options
parameter.
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.
When you say it will be handled by parseUrl
what do you mean? if the url is not null
but is an invalid url, what will happen?
The url is a string.
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.
Currently Promise.reject(makeError(errConst.MISSING_URL.code, errConst.MISSING_URL.msg));
is returned if !parseUrl
, but this condition can never be met because Node's url.parse function will throw an error if no URL string is passed to it and also the function doesn't consider any string to be an invalid URL, it will simply return an URL object.
src/app.js
Outdated
data = await openedFile.read(start, lengthToRead); | ||
} | ||
|
||
const mimeType = multipart ? 'multipart/byteranges' : 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.
Do we need the false
in the boolean operation?
I would rather break this into and if/else as it's a bit confusing and error prone.
src/app.js
Outdated
const partLengthToRead = (partEnd - partStart) + 1; // account for 0 index | ||
const byteSegment = await openedFile.read(partStart, partLengthToRead); | ||
const partEndByte = (partEnd === fileSize - 1) ? fileSize - 1 : partEnd; | ||
const mimeType = mime.getType(nodePath.extname(filePath)) |
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 seems you don't need this within the iteration
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.
The mimeType variable? That should be different from the parent scope mimeType.
The parent response header mimeType is multipart/byteranges
while the byte range parts should have a mime type that corresponds to the file which they belong.
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.
But the value you are setting to mimeType
is always the same as it doesn't depend on any of the values in each iteration, right?
@@ -326,6 +333,99 @@ describe('Browsing', () => { | |||
.be.rejectedWith('Invalid range start value') | |||
)); | |||
}); // .timeout(20000); | |||
|
|||
it('fetches multipart ranges', async () => { |
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.
We should be testing the headers as we do for single range tests.
Perhaps we can return the array with headers and bodies but with an attributed called
|
@bochaco Yeah, I wasn't sure about this because I can't find documentation about how to encode multipart byte ranges with JSON: https://developer.mozilla.org/en-US/docs/Web/API/Response |
|
||
range = options.range; | ||
multipart = range.length > 1; | ||
start = options.range.start || consts.pubConsts.NFS_FILE_START; |
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.
So are we making the start
optional as well? if so we'd need to add tests for that
If a multipart range is desired, the range value may be an array instead of an object.
What is returned is still an object with
headers
andbody
expect the body is an array of objects withheaders
andbody
properties:This seemed most appropriate way to structure response based on https://stackoverflow.com/questions/41348421/how-to-properly-parse-multipart-byteranges-responses-using-typescript-javascript, https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests, and node-formidable/formidable#390