SAPUI5 OData v4 Batch Requests Header Parsing - http-headers

I'm trying to implement a UI5 service using an OData v4 backend.
In general my bindings seem to work, however, there seems to be a problem parsing the headers of the batch requests. Parsing the batch parts by skipping the code in the debugger works fine.
In the console I get the following error:
2022-10-11 13:14:09.584899 $batch failed - Error: Expected 'OData-Version' header with value '4.0' but received value 'null' in response for http://localhost:8080/odata/$batch
at h.doCheckVersionHeader (http://localhost:1337/resources/sap/ui/core/library-preload.js:4753:314)
at Object.<anonymous> (http://localhost:1337/resources/sap/ui/core/library-preload.js:4786:415)
at Object.<anonymous> (http://localhost:1337/resources/sap-ui-core.js:2099:9272)
at p (http://localhost:1337/resources/sap-ui-core.js:2219:26833)
at Object.fireWith [as resolveWith] (http://localhost:1337/resources/sap-ui-core.js:2219:27676)
at y3 (http://localhost:1337/resources/sap-ui-core.js:2219:84906)
at XMLHttpRequest.<anonymous> (http://localhost:1337/resources/sap-ui-core.js:2219:87536) sap.ui.model.odata.v4.ODataModel`
However, inspecting the headers in the developer tools the OData-Version header seems to be set
HTTP/1.1 202
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
OData-Version: 4.0
Content-Type: multipart/mixed;boundary=batch_63059dbf-3e96-4650-b6b9-c6237b7e3b9e
Content-Length: 3848
Date: Tue, 11 Oct 2022 11:14:06 GMT
Keep-Alive: timeout=60
Connection: keep-alive
In the function h.doCheckVersionHeader only the Content-Type and Content-Length are aviable.
I start my project via ui5 serve and seem to be using version 1.102.1.
Does anyone know how I can get the requests to work?

I have resolved the issue by adding the
Access-Control-Expose-Headers header to the response: https://github.com/SAP/openui5/issues/3613#issuecomment-1274609280

The section "Response Headers" from the documentation topic "Model Instantiation and Data Access" now lists headers that need to be added to the Access-Control-Expose-Headers response header:
The OData model processes some of the response headers, namely:
DataServiceVersion (only when consuming an OData V2 service),
Date,
ETag,
OData-Version,
Preference-Applied,
Retry-After,
SAP-Messages,
X-CSRF-Token.
Some SAP applications will also require the processing of SAP-ContextId, SAP-Err-Id, and SAP-Http-Session-Timeout. When using cross-origin resource sharing (CORS), it is important to add all these headers to the Access-Control-Expose-Headers response header.
Also, make sure that values assigned to the headers are syntactically valid. E.g. no dangling characters: OData-Version: 4.0; → OData-Version: 4.0.

Related

Postman shows "Could not get any response" even though response is OK

I have a WCF service which I make API requests to.
This API call returns a JSON response object and also is able to return it in GZIP compression as well when "gzip" value is used in "Accept-Encoding" header.
The problem is when I try to get the response in GZIP, Postman shows "Could not get any response" although I see response and response's content are OK (200 status code) in Fiddler and can easily decompress the response content in my C# client.
I took a look in Postman Console but all I see is "Error: incorrect header check".
I hardly tried to find any documentation regarding this header check but couldn't find any.
These are the request headers:
POST /correction/v1/document?lang=US HTTP/1.1
Content-Type: text/plain
Accept-Encoding: gzip
User-Agent: PostmanRuntime/7.6.0
Accept: */*
content-length: 630
Connection: close
These are the response headers:
HTTP/1.1 200 OK
Content-Length: 512
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Server: Microsoft-HTTPAPI/2.0
Date: Sun, 24 Feb 2019 14:05:50 GMT
Connection: close
The only thing I suspect is wrong is this message from Fiddler:
I integrated this code into mine in order to use GZIP in WCF.
https://github.com/carlosfigueira/WCFSamples/tree/master/MessageEncoder/GZipEncoderAndAutoFormatSelection
Basically, it captures the response before returning to client and use GZipStream for compression.
I got the same issue, I added the following header to fix this issue.
Accept-Encoding : *
I was able to solve a similar issue by using the header Accept-Encoding: */* or if you want to be specific do Accept-Encoding: */* that way the HTTP client will be able to process the response based on the type of encoding received, in the case of a gzip, it will decode the response and show it as normal text.
For me, I removed 'Accept-Encoding' in the request header.
I got this issue when the REST service was returning a zip content (aka. WinZip format). I solved the error by compressing the data using 7zip to produce true gzip format.

Edge browser appears to discard response payload

I have a web app that returns a PDF to the browser, which works fine in Chrome and Firefox, however it does not work in Edge (version 38.14393.0.0). The response header looks like this:
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Origin: *
Cache-Control: no-store, no-cache, must-revalidate
Content-Disposition: inline; filename="Invoice.PDF"
Content-Length: 9255
Content-Type: application/pdf
Date: Mon, 30 Jan 2017 04:38:25 GMT
Pragma: no-cache
Server: Microsoft-IIS/10.0
I've seen other questions suggesting that 2 requests are sent from Edge, one of which should be ignored, but in my case there is only one, and it appears that the payload is being ignored because Edge reports:
This resource has no response payload data
..which is in the Response Body section for the request in the Network analyzer in Developer Tools. Using attachment instead of inline also does not work, and I wouldn't expect it to if Edge thinks there's no content in the response.
Any clues?
Edit: When the Content-Type is changed to: text/plain, the response body is no longer being discarded (but does not solve the problem), so I assume it's something specific to application/pdf
In my case, it appears the payload data is being discarded because I was attempting to use createObjectURL on the result. This post:
Setting window.location or window.open in AngularJS gives "access is denied" in IE 11
Has a solution that kind of works: Edge still does not actually open the PDF like other browsers are capable of, however it gives the user the option to save it.

Cannot generate an authorization code on API Explorer

I'm trying to collect and download my lifelog user data. The first step into doing this is getting a user-access token. I am encountering problems while requesting authorization.
From the sony developer authenticization page I am told to input the following code into my API explorer:
https://platform.lifelog.sonymobile.com/oauth/2/authorize?client_id=YOUR_CLIENT_ID&scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read
I am supposed to receive the authorization code as such:
https://YOUR_CALLBACK_URL?code=abcdef
However, this is what the current situation is actually like:
I have replaced my actual client ID below with MY_CLIENT_ID for security reasons
INPUT:
GET /oauth/2/authorize?client_id=MY_CLIENT_ID&scope=lifelog.profile.read%2Blifelog.activities.read%2Blifelog.locations.read HTTP/1.1
Authorization:
Bearer kN2Kj5BThn5ZvBnAAPM-8JU0TlU
Host:
platform.lifelog.sonymobile.com
X-Target-URI:
https://platform.lifelog.sonymobile.com
Connection:
Keep-Alive
RESPONSE:
HTTP/1.1 302 Found
Content-Length:
196
Location:
https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Access-Control-Max-Age:
3628800
X-Amz-Cf-Id:
HILH9w3eOm-6ebs_74ghegYQyWS4xyqA1l0gXPRJuuubsoZ6eiiS3g==
Access-Control-Allow-Methods:
GET, PUT, POST, DELETE
X-Request-Id:
76caccfc976d40259ef30415d10980e9
Connection:
keep-alive
Server:
Apigee Router
X-Cache:
Miss from cloudfront
X-Powered-By:
Express
Access-Control-Allow-Headers:
origin, x-requested-with, accept
Date:
Sun, 22 Jan 2017 03:00:42 GMT
Access-Control-Allow-Origin:
*
Vary:
Accept
Via:
1.1 dc698cd00b7ec82887573cfaba9ecca6.cloudfront.net (CloudFront)
Content-Type:
text/plain; charset=utf-8
Found. Redirecting to https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Nowhere can I see the authorization code in the above code. I even tried copying and pasting the URL (on the last line) into my browser, it says "localhost.com took too long to respond"
This is where I input my request
I am not sure whether it is an issue with the callback URL. I don't have an actual website or app made, I just used the default localhost
I am a beginner in this and would really appreciate all help.

Web API Basic Authentication returns 401

I've build a web api service with basic authentication and using a global DelegatingHandler implementation which I hook up to the web API GlobalConfiguration, in order to extract the username:password credentials from the request and hook an IPrincipal to the HttpContext if the credentials map to a valid user.
I've tested my api thoroughly on localhost and it's working fine, but not quite when hosted on IIS on a VPS.
I've hooked up remote debugging on the VPS in order to inspect whats going on and it turns out that whenever I include the authorization header to my request, the breakpoints I have set on the message handler are not getting hit, meaning that the request does not reach the handler. If I remove the Authorization header from the request, the breakpoint is getting hit and the handler is able to process it.
Since the message handlers are the first that will process the request in the pipeline (from what I know of, correct me if I'm wrong) I guess there must be an IIS or setup issue that I'm not aware of that messes the authentication process.
Fiddler Request Headers
GET http://myip/api/v1/route/parameter HTTP/1.1
Content-Type: application/json; charset=utf-8
Authorization: Basic ZHJpdmVyOjEwMTAyMDAz
Host: myip
Fiddler Response Headers
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Basic realm="myip"
X-Powered-By: ASP.NET
Date: Mon, 22 Aug 2016 15:04:15 GMT
Content-Length: 61
{"Message":"Authorization has been denied for this request."}
What could be possibly be wrong, where should I look at for a solution?
EDIT
Had to disable Basic Authentication from the Authentication menu on the right pane setting for the IIS application.

What is reponse.d when returning data from a WCF Service with ContentType of "application/json"?

I have a WCF service that has webHttpBinding and has enableWebScript turned on in it's endpoint behavior configuration.
The response from the service looks something like this
HTTP/1.1 200 OK
Date: Fri, 23 Oct 2009 20:09:02 GMT
Server: Microsoft-IIS/6.0
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 25
{"d":{"__type":"SOMETYPE", ... }}
Its using HTTP 1.1 and so there are the standard headers. The contentType is set to be applciation/json which also makes sense. In the message body (the JSON part), everything is enclosed in an envelope titled "d".
What is that? Who defines that protocol? Is it something specific to WCF?
I couldn't find that defined in any of the protocols involved or the definition of the "application/json" contentType.
Thanks
That is ASP.NET AJAX specific and is caused by applying the WebScriptEnablingBehavior (enableWebScript in config) to your endpoint. The wrapper is required on both input and output and there are also special behaviors added around exception handling.
If you want "pure" JSON, you should remove the WebScriptEnablingBehavior and just use WebHttpBehavior (webHttp in config). Then just make sure you explicitly set the Request/ResponseFormat properties on your WebGet/InvokeAttributes.