-
Notifications
You must be signed in to change notification settings - Fork 19
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
Implement Response.clone (#125) #178
base: main
Are you sure you want to change the base?
Conversation
* Implement `Response.clone` This is largely based on the existing `Request.clone` implementation * Add tests for `Response` to match `Request` tests
This is amazing, thank you for sharing. If you are able to get the tests running it would be great to get the WPT coverage working here. In order to get the test coverage updated, we run the tests with With regards to your question, Let me know if I can assist further at all with getting the WPT setup working for you. |
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 looks really really solid, thank you so much! ❤️
Assuming you get the tests situation sorted out and everything looks good there, I think this is ready to go.
RootedValue cloned_headers_val(cx, JS::NullValue()); | ||
RootedObject headers(cx, RequestOrResponse::maybe_headers(self)); | ||
if (headers) { | ||
RootedValue headers_val(cx, ObjectValue(*headers)); | ||
JSObject *cloned_headers = Headers::create(cx, headers_val, Headers::guard(headers)); | ||
if (!cloned_headers) { | ||
return false; | ||
} | ||
cloned_headers_val.set(ObjectValue(*cloned_headers)); | ||
} else if (RequestOrResponse::maybe_handle(self)) { | ||
auto handle = RequestOrResponse::headers_handle_clone(cx, self); | ||
JSObject *cloned_headers = | ||
Headers::create(cx, handle.release(), | ||
RequestOrResponse::is_incoming(self) ? Headers::HeadersGuard::Immutable | ||
: Headers::HeadersGuard::Response); | ||
if (!cloned_headers) { | ||
return false; | ||
} | ||
cloned_headers_val.set(ObjectValue(*cloned_headers)); | ||
} |
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 think you should be able to use RequestOrResponse::headers_handle_clone
for this, reducing complexity a bunch. If that's not quite correct to use here, perhaps it can instead be tweaked?
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 was unable to work out a simple way to use RequestOrResponse::headers_handle_clone
for this, however the solution I've added in a recent commit that constructs a RootedObject
based on RequestOrResponse::headers
appears to do the trick. I'd love an extra set of eyes on that approach though as I'm still wrapping my head around internal object apis.
RootedObject cloned_headers(cx, RequestOrResponse::headers(cx, self));
if (!cloned_headers) {
return 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.
Unfortunately this isn't quite right: it will always return an instance of builtins::web::fetch::Headers
tied to self
, not a clone of that each time it's called. You should be able to see this if you create a response, clone it using Response.clone
, and then do something like response.headers.set("foo", "bar")
: this should now show up on both responses.
Can you say what didn't work when using headers_handle_clone
?
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 gave it another look over and was able to get headers_handle_clone
to work for this. I'll chalk it up to my own ignorance regarding the codebase. I've mirrored the changes to Request::clone
as well and wrote up some changes to the tests to check that the headers are properly cloned rather than shared.
Once any further changes are worked through, do you prefer keeping the individual commits in this PR or would a force-push of squashed commits be preferred?
// ENGINE->dump_value(status_val, stderr); | ||
// ENGINE->dump_value(status_message_val, stderr); | ||
|
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.
Remove this?
SetReservedSlot(new_response, static_cast<uint32_t>(Slots::Status), status_val); | ||
SetReservedSlot(new_response, static_cast<uint32_t>(Slots::StatusMessage), status_message_val); | ||
|
||
// 3. If response’s body is non-null, then set newResponse’s body to the result of cloning response’s body. |
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.
// 3. If response’s body is non-null, then set newResponse’s body to the result of cloning response’s body. | |
// 3. If response’s body is non-null, then set newResponse’s body to the result of cloning response’s body. |
Accessing can of course be done via the `url` accessor in the base class, this is just here for consistency's sake.
* greatly simplifies the cloning code to rely on `RequestOrResponse::headers`, which appears to do a lot of the necessary work for us. * Also modified `Request.clone` to be consistent with this change. * `Response.clone` now also copies the `URL` slot
The latest commits expose the I was able to get WPT running on my machine and it is reporting:
This would imply that some amount of tests are failing, so I will dig into these further to see if I can aim for higher success rate in WPT. |
…clone` in order to properly clone headers rather than make a reference to existing headers.
…haring them between clones
This simple commit takes the existing
Request.clone
implementation and adapts it to work forResponse.clone
. This was done largely as a learning exercise.I did have a question regarding the current
Response
class. It appears that aURL
slot is missing fromResponse
where it appears inRequest
. The spec shows aurl
attribute which would imply that this slot should be implemented.Is this intentionally left out or something that just hasn't been added yet?
I have yet to get the WPT tests running properly on my machine, so this has not been tested against those. As such, I am leaving this as a draft until I can validate against those.