Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upAllow Request's Headers to be created with various objects #13802
Conversation
While Headers could be constructed correctly with an array or object (open ended dictionary/MozMap), Request's Headers failed to be created with non-Headers object (such as array or open ended dictionary/MozMap). Before, Request's Headers could be filled with only a Headers object in Step 28. This has been expanded to accommodate array and open ended dictionary. Step 29 empties the Request's Headers list after it had been filled in Step 28, thus resulting in an empty Headers object when it shouldn't be. This step has been removed with a comment in this commit. If a RequestInit Headers is *not* given, but a RequestInfo Headers is given, RequestInfo Headers should be used to construct Request Headers. That step has been added after Step 31. Corresponding wpt result is updated in this commit.
highfive
commented
Oct 17, 2016
| } | ||
| } | ||
|
|
||
| // Step 29 | ||
| r.Headers().empty_header_list(); | ||
| // When r.Headers()'s header list is emptied, | ||
| // r.Headers that was filled in Step 28 becomes empty. |
This comment has been minimized.
This comment has been minimized.
emilio
Oct 23, 2016
Member
This comment seems confusing to me, could you explain or rephrase it? It seems we can't empty these because otherwise we undo the stuff done above?
If that's the case, we should be doing a deep copy in step 27 then instead.
This comment has been minimized.
This comment has been minimized.
jeenalee
Oct 25, 2016
Author
Contributor
That's right! Sorry for the confusing wording. We can't empty them because we would undo the stuff done above. I tried your suggestion on doing a deep copy, and got the following:
I cannot understand why, but the following approach does not make the subtest [Testing request header creations with various objects] in request-headers.html pass.
Step 27: let mut headers_copy = r.Headers().clone();
Step 28: fill in headers_copy using HeadersInit (unchanged from the original pull request)
Step 29: r.Headers().empty_header_list();
Step 30: Check whether Request Mode is NoCors (unchanged from the original pull request)
Step 31: After addressing your suggestion below this comment:
match init.headers {
None => {
// This is equivalent to the specification's concept of
// "associated headers list". If an init headers is not given,
// but an input with headers is given, set request's
// headers as the input's Headers.
if let RequestInfo::Request(ref input_request) = input {
try!(r.Headers().fill(Some(HeadersInit::Headers(input_request.Headers()))));
}
},
Some(_) => try!(r.Headers().fill(Some(HeadersInit::Headers(headers_copy)))),
}
Because we set the headers_copy to be a deep copy of r.Headers(), then fill r.Headers() with the headers_copy in Step 31, I think the subtest shouldn't fail.
When we do a deep clone in Step 27, but not empty r.Headers().empty_header_list(); in Step 29, when running wpt, Servo crashes with a message that begins with DOMRefCell<T> already borrowed: BorrowMutError. Here's the backtrace. The error occurs in Header's fill method.
I'm confused! I feel like I'm missing something. Do you have any insights?
This comment has been minimized.
This comment has been minimized.
emilio
Oct 26, 2016
Member
So that backtrace can come from anywhere in the constructor, so it's hard to diagnose based on that.
But a borrow error indicates that you're reading from something while writing to it in general. Something like filling r.headers() with themselves, or holding a borrow to somewhere inside the Headers object can be potential problems.
This comment has been minimized.
This comment has been minimized.
jeenalee
Oct 27, 2016
Author
Contributor
Hmm. I realized I wasn't making a deep copy. I had to do r.Headers.r().clone() in order to actually make a deep copy.
With this approach though, because r.Headers() is a Root<T>, it becomes difficult to make a mutable reference to r.Headers(). Without the mutable reference, we cannot set r.Headers() to be the deep copied headers in Step 27.
I want to suggest we leave the comment more descriptive (as you wrote above), but not make a deep copy in Step 27.
| // "associated headers list". If an init headers is not given, | ||
| // but an input with headers is given, set request's | ||
| // headers as the input's Headers. | ||
| if let None = init.headers { |
This comment has been minimized.
This comment has been minimized.
emilio
Oct 23, 2016
•
Member
nit: if init.headers.is_none(), though this can probably be more legible with a match statement combined with the above if let.
| if let RequestInfo::Request(ref input_request) = input { | ||
| headers_copy = input_request.Headers(); | ||
| } | ||
|
|
||
| // Step 28 |
This comment has been minimized.
This comment has been minimized.
emilio
Oct 23, 2016
Member
The step numbers seem to have changed (though that's probably my fault!), feel free to update them if you feel like it :).
This comment has been minimized.
This comment has been minimized.
jeenalee
Oct 27, 2016
Author
Contributor
I'll leave them as it is for now! It's probably more straightforward to fix them when we update Request Constructor to match the spec :)
|
@emilio Thanks Emilio! I realized that the Fetch spec has been updated, but our request constructor has not yet. The changes in this PR were based on the older Fetch spec version. Will it make more sense to close this PR, and update the request constructor to match the current Fetch spec first? |
|
Updating the numbers in a separate commit in the same PR is fine; or doing it separately after. I doubt it's necessary to close this one though. |
| // `r.Headers()` is a `Root<T>`, and therefore it is difficult | ||
| // to obtain a mutable reference to `r.Headers()`. Without the | ||
| // mutable reference, we cannot mutate `r.Headers()` to be the | ||
| // deep copied headers in Step 27. |
This comment has been minimized.
This comment has been minimized.
KiChjang
Oct 27, 2016
Member
Does r.headers.set(headers_copy) not work? If so, then you can just create pub fn set_headers(&self, headers: Headers) in impl Request.
This comment has been minimized.
This comment has been minimized.
jeenalee
Oct 28, 2016
Author
Contributor
Good idea! Hmm, though while it compiles, more tests fail with that change. I'm not sure why.
This comment has been minimized.
This comment has been minimized.
emilio
Oct 28, 2016
Member
Hmmm... So it seems to me we'd need to add a method to Request that creates a new Request with a clone of the inner hyper list, is that right?
I'm totally fine doing it as a followup if @jdm agrees.
|
I thought this would be a small change until the request Constructor gets updated to match the Fetch spec. While this patch isn't the perfect fix, I feel like we're starting to go down the rabbit hole... I'd say we move forward with the not-perfect fix, or I can close this pull request and focus on updating the constructor! |
| // `r.Headers()` is a `Root<T>`, and therefore it is difficult | ||
| // to obtain a mutable reference to `r.Headers()`. Without the | ||
| // mutable reference, we cannot mutate `r.Headers()` to be the | ||
| // deep copied headers in Step 27. |
This comment has been minimized.
This comment has been minimized.
emilio
Oct 28, 2016
Member
Hmmm... So it seems to me we'd need to add a method to Request that creates a new Request with a clone of the inner hyper list, is that right?
I'm totally fine doing it as a followup if @jdm agrees.
|
Hi! Just checking in with this PR. Please let me know if there's anything I can do :) |
|
Whoops, I didn't realize this was waiting on my input. I'm not thrilled with either the before or after code (or the spec, for that matter), but I don't have concrete suggestions for how to improve any of those pieces. Let's merge this and move on! @bors-servo: r=emilio |
|
|
Allow Request's Headers to be created with various objects <!-- Please describe your changes on the following line: --> While Headers could be constructed correctly with an array or object (open ended dictionary/MozMap), Request's Headers failed to be created with non-Headers object (such as array or open ended dictionary/MozMap). Before, Request's Headers could be filled with only a Headers object in Step 28. This has been expanded to accommodate array and open ended dictionary. Step 29 empties the Request's Headers list after it had been filled in Step 28, thus resulting in an empty Headers object when it shouldn't be. This step has been removed with a comment in this commit. If a RequestInit Headers is _not_ given, but a RequestInfo Headers is given, RequestInfo Headers should be used to construct Request Headers. That step has been added after Step 31. Corresponding wpt result is updated in this commit. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #13758 (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13802) <!-- Reviewable:end -->
|
|
|
Those are some very unhappy tests! One clear problem:
I suspect this is the case where headers_copy is both the object being used to fill the new request's headers and the headers being filled - we'll be calling borrow_mut on one and borrow on the other, which won't work. |
Instead of filling request's headers whenever a `HeadersInit` is given, this patch fills request's headers only when `HeadersInit` with a type of `Headers` is given. Previously, the constructor tried to fill request's headers with itself, causing Servo to crash.
|
Oopsies, that's bad! The latest commit should fix that crash. |
|
@bors-servo try |
Allow Request's Headers to be created with various objects <!-- Please describe your changes on the following line: --> While Headers could be constructed correctly with an array or object (open ended dictionary/MozMap), Request's Headers failed to be created with non-Headers object (such as array or open ended dictionary/MozMap). Before, Request's Headers could be filled with only a Headers object in Step 28. This has been expanded to accommodate array and open ended dictionary. Step 29 empties the Request's Headers list after it had been filled in Step 28, thus resulting in an empty Headers object when it shouldn't be. This step has been removed with a comment in this commit. If a RequestInit Headers is _not_ given, but a RequestInfo Headers is given, RequestInfo Headers should be used to construct Request Headers. That step has been added after Step 31. Corresponding wpt result is updated in this commit. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #13758 (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13802) <!-- Reviewable:end -->
|
|
highfive
commented
Nov 8, 2016
|
|
|
|
@bors-servo retry clean |
|
@bors-servo: r- |
|
@bors-servo: r+ |
|
|
Allow Request's Headers to be created with various objects <!-- Please describe your changes on the following line: --> While Headers could be constructed correctly with an array or object (open ended dictionary/MozMap), Request's Headers failed to be created with non-Headers object (such as array or open ended dictionary/MozMap). Before, Request's Headers could be filled with only a Headers object in Step 28. This has been expanded to accommodate array and open ended dictionary. Step 29 empties the Request's Headers list after it had been filled in Step 28, thus resulting in an empty Headers object when it shouldn't be. This step has been removed with a comment in this commit. If a RequestInit Headers is _not_ given, but a RequestInfo Headers is given, RequestInfo Headers should be used to construct Request Headers. That step has been added after Step 31. Corresponding wpt result is updated in this commit. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #13758 (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13802) <!-- Reviewable:end -->
|
|
|
|
|
|
jeenalee commentedOct 17, 2016
•
edited by larsbergstrom
While Headers could be constructed correctly with an array or
object (open ended dictionary/MozMap), Request's Headers failed to be
created with non-Headers object (such as array or open ended
dictionary/MozMap).
Before, Request's Headers could be filled with only a Headers object in
Step 28. This has been expanded to accommodate array and open ended
dictionary.
Step 29 empties the Request's Headers list after it had been filled in
Step 28, thus resulting in an empty Headers object when it shouldn't
be. This step has been removed with a comment in this commit.
If a RequestInit Headers is not given, but a RequestInfo Headers is
given, RequestInfo Headers should be used to construct Request
Headers. That step has been added after Step 31.
Corresponding wpt result is updated in this commit.
./mach build -ddoes not report any errors./mach test-tidydoes not report any errorsThis change is