I'm performing a multi-path update to Firebase that results in receiving the undocumented error code 18.
I can perform the multi-path update in smaller chunks, and I receive a successful 200, but when it is all in one, the request fails. Also, I know the request is formed correctly as I've made sure to beware the multi-path update pitfall explained here.
So, what's the deal?
The deal is, quite unexpectedly, that I have the "debug" claim set to true in the Authentication token.
Because the multi-path update tests the security rules at each supplied path, and the “x-firebase-auth-debug” response header contains the results of each security rule, that can lead to a very large header. So large that it causes Firebase to return status code 18, which is the cURL Partial File error.
Now, apparently there is no actual header-size limit defined by HTTP, but most web servers impose some sort of limit for size of headers in and out. If the size is too large, servers should return a “413 Entity Too large”, which Firebase is not doing and is the cause of the issue (I believe).
Removing the "debug" claim from the token and performing the exact same multi-path update results in success.
EDIT:
On other occasions, I've received other cURL errors rather than the expected HTTP response codes - is there a reason that these remain undocumented? (I guess it could be the server that I'm sending requests from, so I'll check there and update later, but I figured I'd ask just in case...)
Related
I am looking at the digest-fetch.js over the fetch API, and I am finding some problems. The issue is that in my scenario a POST call is made, responded first with 401 with the challenge and then retried with the authentication header, then succeeds. So far, so good.
But our server responds deliberately with 303, giving a different URI (on same server) to pick up the final result.
The fetch API does not allow me to manually handle the redirect (which I totally don't get why this would be considered "insecure" and hence hidden) but when the core fetch API will retry that, it gets a 401 again from our server. At that point it will fail.
I think this is because the fetch API re-uses the headers, namely the Authorization header, as a constant string. That same header is used for the follow-up GET request on the 303 redirection. The server barks that the nc has not been increased.
As [https://en.wikipedia.org/wiki/Digest_access_authentication] says:
[...] the client may make another request, reusing the server nonce value (the server only issues a new nonce for each "401" response) but providing a new client nonce (cnonce). For subsequent requests, the hexadecimal request counter (nc) must be greater than the last value it used [...]
I consider this a bug in digest-fetch but worse in the Fetch API (of Chrome and Firefox anyway).
I have tried not to provide a String header, but an object with a toString method, hoping that this would be called every time a request is made. So, instead of:
options.headers.Authorization = digest;
I did:
options.headers.Authorization = {
toString: function() {
alert(new Error("Gotcha! " + digest));
return digest;
}
}
Yet sadly, that gets called only once. I think out of the core fetch API function, where I am afraid a string is stored, and the toString() method will not again be called.
Any workaround this problem?
When hitting https://login.salesforce.com/services/oauth2/token, using Postman.
POST https://login.salesforce.com/services/oauth2/token
Response:
I receive a token, but when I try to do something as simple as GET /limits,
GET https://na73.salesforce.com/services/data/v45.0/limits
the response is:
[
{
"message": "Session expired or invalid",
"errorCode": "INVALID_SESSION_ID"
}
]
The strange thing is that when I change all my credentials to a free "developer account" created with a different email address, everything works fine. All requests and headers are the exact same, with the exception of the values from either account.
After digging through a lot of threads on here I thought that maybe my production account (the one I'm posting from now) was not API ENABLED. It turns out my production account is API ENABLED.
I also tried changing https://login.salesforce.com/services/oauth2/token to https://na73.salesforce.com/services/oauth2/token as some threads have suggested, but that just times out.
When comparing both account permissions, they seem identical and I've confirmed I have no issues with the credentials (client id, client secret, security token, access-token), all of them seem to be copied in correctly.
Any ideas for a salesforce noob?
I actually fixed this after banging my head on it forever. You need to go into the settings tab and turn on the Follow Authorization Header setting.
I'm here in 2021 and for me the solution was not 'Follow Authorization Header', but the access token had a different instance_url than expected. Use this instance_url value in _endpoint and you are fine.
After fighting with this for a few days, I've ruled out this is an issue with Postman. What garbage. Just follow https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart_code.htm and use curl commands instead. If I copy a raw curl command into postman then run, it continues to fail with INVALID_SESSION_ID, but works fine in ZSH
So much for a useful GUI
In my case, the _endpoint variable was not getting set after successfully authorising via the browser (should that not happen automatically?), so I had to set it manually -- but, I put the wrong URL for it (
https://whatever.lightning.force.com instead of
https://whatever.my.salesforce.com),
so I would get a 302 redirect to the correct URL, but then that one would return this message.
So changing the _endpoint variable to the correct URL fixed it for me.
I had the same issue, even when activating the Follow Authorization Header
Basically, the Authorisation Bearer is not set directly, so I added it in the Pre-request script tab
pm.request.headers.add({key: 'Authorization', value: 'Bearer {{_accessToken}}' });
Works like a charm now.
I want to fetch an URL and determine what status code it has, especially if it has an HTTP 301 or HTTP 302 status code:
fetch('https://httpstat.us/301', {
redirect: 'true'})
.then(response => {
console.log(response);
const headers = response.headers.entries();
for (h of headers) {
console.log(h);
}
}).catch(err => {
console.log("in error case")
console.log(err);
})
This does give me a lot of information, especially it tells me via:
response.redirected
Which is true. But this only tells me that it redirected, not what the status code was.
Is there a way to use Fetch API to determine the real status code of the request?
As far as why the code can’t just check response.status: In the case of redirects, that will be the status code of whatever response ultimately comes back as the result of any redirects.
So if redirects end up taking things somewhere that returns a 200, then response.status will just be 200. No intermediate status codes are exposed to frontend JavaScript running in a browser—as the previous (very good) answer posted here already points out.
This does give me a lot of information, especially it tells me via:
response.redirected
It’s worth noting: to just detect if there’s been a redirect, you actually don’t even need to check that. That’s the easiest way to check, but you could also just check response.url, and if that’s different from the request URL you gave to the fetch(…) call, you know it was redirected.
That used to be the typical way to check before response.redirected was first introduced.
Also worth noting: redirect: 'true' in the code in the question isn’t valid; it’ll cause the code to fail prematurely. See https://developer.mozilla.org/en-US/docs/Web/API/Request/redirect:
Value A RequestRedirect enum value, which can be one the following strings:
follow
error
manual
So what the code in the question seems to intend is redirect: 'follow'. But that’s actually the default for redirect, so you don’t need to explicitly specify it and can instead just omit it.
As far as the other redirect values: As explained in an answer to another question here at Stack Overflow, you almost certainly never want to specify manual except for some Service Worker cases. And error means to treat any redirect as a network error.
In that case, for the code in the example, redirect: 'true' would cause the catch to get hit and you’d have no access to any details of the response, including whether it got redirected.
So to loop back to your original question:
I want to fetch an URL and determine what status code it has, especially if it has an HTTP 301 or HTTP 302 status code
…the answer is that for redirected requests there really is no way from frontend JavaScript code running in a browser to detect the exact status codes of any redirect.
So if you need to know the exact status code for any redirects that may happen for a request to a given URL, you must make the request from backend code, and handle the response there.
OK first to answer your question no you cannot determine the difference between 301 and 302 without some changes in the backend.(Follow this SO dicussion for backend solution).
The other thing you can do is to set redirect to 'error' in which cases fetch will throw an error on all redirects and you can handle what happens if it was a redirect.
The main reason why this is like that is (from my understanding) is because the difference between 301 and 302 is mainly useful to browsers which needs to handle how subsequent request should behave (whether to permanently change the cache or just this request).
But in terms of the user the spec specifies both cases to handled transparently meaning you need to know there is a redirect but what status code caused the redirect does not matter. Hence only the response.redirected flag. But if you still need to please follow the above backend solution.
I'm implementing my own http module.
As I'm reading the official node.js http module api, I couldn't understand a few things:
If the user is using the response.writeHead(statusCode, [reasonPhrase], [headers]) function, are the headers should be written immidiatly to the socket or are they first supposed to be saved as a member to the object? and then written only after .end() function?
What is the meaning of implicit headers that should be used whenever the user didn't use writeHead()? are they supposed to be set ahead? and if the user didn't set them? what should be the behavior? thanks
Answers:
Anything that you write into response either headers with writeHead or body with write is buffered and sent. You see they use socket buffers. They can only hold fixed amount of data, before being sent. The important fact to remember is that you can only set headers before you start writing the body. If you do, some headers will set for you by the http server itself.
Implicit headers are ones which you don't write specifically but are still sent. Setup a simple http server, by responding a request without setting any header. Then view the request headers opening the site in browser. There will be headers like Date, Server, Host etc which are added to every request automatically without user's volition.
I found answer for the first question, but still don't understand the second one.
The first time response.write() is called, it will send the buffered header information and the first body to the client. The second time response.write() is called, Node assumes you're going to be streaming data, and sends that separately. That is, the response is buffered up to the first chunk of body.
I'm implementing a Web service that returns a JSON-encoded payload. If the service call fails -- say, due to invalid parameters -- a JSON-encoded error is returned. I'm unsure, however, what HTTP status code should be returned in that situation.
On one hand, it seems like HTTP status codes are for HTTP: even though an application error is being returned, the HTTP transfer itself was successful, suggesting a 200 OK response.
On the other hand, a RESTful approach would seem to suggest that if the caller is attempting to post to a resource, and the JSON parameters of the request are invalid somehow, that a 400 Bad Request is appropriate.
I'm using Prototype on the client side, which has a nice mechanism for automatically dispatching to different callbacks based on HTTP status code (onSuccess and onFailure), so I'm tempted to use status codes to indicate service success or failure, but I'd be interested to hear if anyone has opinions or experience with common practice in this matter.
Thanks!
http status code are just for indicating the status of the application response.
and as you said, if json parameters as somehow invalid, a 400 status code is an appropriate answer.
so yes, it is a really good idea to use http status code. de plus, status code are then easy to understand as they don't change from an application (web services) to another
You should definitely use the proper status codes since they are exactly for this purpose, not to indicate the status of the HTTP request itself. By this way you can redirect the response to the appropriate function/branch before parsing it which will lead to a much tidier code in the client side.