Skip to content
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

v4.ODataModel evaluates preflight requests #3150

Closed
boghyon opened this issue Feb 8, 2021 · 12 comments
Closed

v4.ODataModel evaluates preflight requests #3150

boghyon opened this issue Feb 8, 2021 · 12 comments

Comments

@boghyon
Copy link
Contributor

boghyon commented Feb 8, 2021

The standard TripPin service is getting a CORS support (OData/ODataSamples#29). The responses from preflight (OPTIONS) there, however, don't include e.g. OData-Version: 4.0 in the header unlike the responses from the real GET requests.
Here is a minimal sample: https://embed.plnkr.co/IAM5TBfKWaTW8vbg?show=manifest.json,preview&deferRun

This leads to the error Expected 'OData-Version' header with value '4.0' but received value 'null' from the _Requestor:

throw new Error("Expected 'OData-Version' header with value '4.0' but received value '"
+ sODataVersion + "' in response for " + this.sServiceUrl + sResourcePath);

See OData/ODataSamples#29 (comment). Is this a client issue? Can the _Requestor "ignore" responses from the preflight requests or assume missing headers if possible? Or are services supposed to replicate all headers from the real responses (here: GET) to the OPTIONS responses too?

@IlianaB
Copy link
Member

IlianaB commented Feb 8, 2021

Hello @boghyon ,
Thank you for sharing this finding. I've created an internal incident 2180087416 for your question.
The status of the issue will be updated here in GitHub.

Regards,
Iliana

@UweReeder
Copy link
Member

Hi @boghyon,

No, OData V4 services are not expected to replicate the client's version header. They are expected to deliver the version they support. See the spec:

8.1.5 Header OData-Version
OData clients SHOULD use the OData-Version header on a request to specify the version of the protocol used to generate the request.
If present on a request, the service MUST interpret the request according to the rules defined in the specified version of the protocol, or fail the request with a 4xx response code.
If not specified in a request, the service MUST assume the request is generated using the minimum of the OData-MaxVersion, if specified, and the maximum version of the protocol that the service understands.
OData services MUST include the OData-Version header on a response to specify the version of the protocol used to generate the response. The client MUST interpret the response according to the rules defined in the specified version of the protocol.

@boghyon
Copy link
Contributor Author

boghyon commented Feb 9, 2021

@UweReeder I see my mistake in my initial issue description.

are services supposed to replicate all headers from the real requests responses [...]

Should be "responses" not "requests". Sorry about the wrong wording. Edited now.

For better understanding of this issue, please refer to the linked discussion in the ODataSamples repo.

As this issue is not resolved, would be nice if this issue could be reopened.

@UweReeder
Copy link
Member

Hi @boghyon,

I get a code 500 response when following the link to the samples repo.

But nevertheless I think that this is a server issue. According to the OData V4 spec services MUST send the OData-Version header in their responses.

Regards,
Uwe

@UweReeder
Copy link
Member

Hi @boghyon,

unfortunately I am not able to see the issue OData/ODataSamples#29. I get a code 500 response (only for this issue).

Nevertheless I think that this is a server issue. The OData V4 spec specifies that a service MUST send the OData-Version header in its responses.

Regards,
Uwe

@UweReeder UweReeder reopened this Feb 9, 2021
@boghyon
Copy link
Contributor Author

boghyon commented Feb 9, 2021

@UweReeder Unfortunately, GitHub has an issue with serving some of its pages currently: https://github.community/t/github-issue-responds-with-a-status-of-500/160550. Bad timing! I'll let you know when the issue is accessible again.

In the meantime, the issue can be reproduced in https://embed.plnkr.co/IAM5TBfKWaTW8vbg?show=manifest.json,preview&deferRun.

  1. Open the above sample.
  2. Open the browser console.
  3. Run the preview (We can see two requests for the /People entities: OPTIONS and GET as expected)
  4. Analyze the headers from the /People responses:
    • While GET does contain the OData-Version header in the response,
    • The OPTIONS (preflight) response doesn't include OData-Version — And IMHO it's not even required to do so since it was simply a preflight request which is not related to OData at all. Why does the browser have to know the context of the preflight request (in our case, OData)?

I think this is worth discussing among V4 maintainers here, since the OPTIONS is not really talked about in the OData specification (according to Michael Pizzo from the discussion). Hence my question: "Can the _Requestor 'ignore' responses from the preflight requests or assume missing headers if possible?" i.e. being less strict if the specification doesn't explicitly mention what to do in this case.

@ThomasChadzelek ThomasChadzelek self-assigned this Feb 9, 2021
@boghyon
Copy link
Contributor Author

boghyon commented Feb 9, 2021

@ThomasChadzelek I just enhanced my last comment with the steps. Hopefully it helps to clarify the issue.

@ThomasChadzelek
Copy link
Member

Hello @boghyon !

@UweReeder and myself had a look in debugger, our code only has access to a few response headers:
l.getAllResponseHeaders() "cache-control: no-cache content-length: 611 content-type: application/json; odata.metadata=minimal expires: -1 pragma: no-cache "
To us, it looks like an Access-Control-Expose-Headers is missing in the server's data response (see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#the_http_response_headers).

Best regards,
Thomas

P.S.: I don't think that our code is actually evaluating the preflight response. That should be completely transparent to JS code. From the debugger, it is clear that we are evaluating the actual data response, but have no access to the OData-Version header (although it is present).

@codeworrior
Copy link
Member

I can confirm that CORS preflight requests are in general not visible to the client code. The browser handles them transparently.

@boghyon
Copy link
Contributor Author

boghyon commented Feb 9, 2021

To us, it looks like an Access-Control-Expose-Headers is missing in the server's data response

This is what I also observed. The OPTIONS response had Access-Control-Allow-Origin and Access-Control-Allow-Headers but neither Access-Control-Expose-Headers nor the OData-Version header, whereas the real data (GET) response had OData-Version: 4.0 and none of the Access-Control-* headers except of Access-Control-Allow-Origin.

I guess Access-Control-Expose-Headers needs to be explicitly included in the response header of OPTIONS (not sure if it also needs to be included in the real data response headers?), in order to perform getResponseHeader / getAllResponseHeaders.

Thank you for the hints! I'll let Michael know about it as soon as the linked issue is accessible again.

Closing for now..

@boghyon
Copy link
Contributor Author

boghyon commented Aug 25, 2021

Just an update for this thread: as @ThomasChadzelek and @UweReeder pointed out, Access-Control-Expose-Headers was missing in the response header. After OData/ODataSamples#29 (comment), the header info OData-Version: 4.0 could be accessed from the client.

The OData V4 Trippin service now supports CORS.

@boghyon
Copy link
Contributor Author

boghyon commented Aug 6, 2024

Duplicate of #2686

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants