I have a bucket set up in Google Cloud Storage, with the "object default permissions" set to grant the "User" group "allUsers" with permission "Reader".
In the bucket there are a number of files, and I have a client checking if a particular file is present by trying to access it. Most of the time we get a 404 response, but fairly often we see a 403 response for the first few tries.
The 403 response body is (with my own formatting and replacement of private info):
<?xml version='1.0' encoding='UTF-8'?>
<Error>
<Code>AccessDenied</Code>
<Message>Access denied.</Message>
<Details>Anonymous users does not have storage.objects.get access to object mybucket/myfile.gz.</Details>
</Error>
So my question is why do I sometimes get a 403 and sometimes a 404 response when trying to open a file that doesn't exist?
I know that there will be changes from 29 May 2017, but they are not in effect yet, and so it appears that either something is wrong or Google have been randomly applying the new logic early.
I have a definitive answer on this via an email from Google, so I'm giving the response for completeness.
It has been found out that there was a miscommunication between the Engineers. Originally, the changes were supposed to be scheduled on 5/22 but due to some internal delays, they decided to announce it on a later date which is 5/29. Due to this confusion, the Engineers rolled this feature out on the original date (5/22) instead of 5/29.
TL;DR: Google screwed up and rolled out breaking changes a week early.
Related
Linkedin has a whole slew of fields to pull them with their API. But they say they want you to apply for something before you can request the fields (see a screenshot below). My question is, can I query those fields during development to test my app? Now Linkein returns error, if I try to request them. And Linkedin doesn't say anything about it in their API docs.
InternalOAuthError: Failed to obtain request token
Here is a screenshot.
I still don't know the answer whether I can test the behavior during development.
However, with trial and error method I found what permissions generate error in Linkedin. Lol thing is that you can request fields from those permissions just fine (no error throws), but cannot request permissions.
Fields from forbidden permissions (do not throw even if permissions are omitted in a request):
['languages', 'date-of-birth', 'phone-numbers', 'im-accounts'],
Forbidden permissions that throw:
['r_fullprofile', 'r_contactinfo'],
The same thing seems to have happened two years ago public-profile-url causing error, but the approved solution on that question is not solving this problem.
Any connections requests requesting the field 'public-profile-url' throws the following error:
https://api.linkedin.com/v1/people/~/connections:(public-profile-url)?start=0&oauth2_access_token=<token>
<error>
<status>500</status>
<timestamp>1491329264595</timestamp>
<request-id>8IJSBKJHQR</request-id>
<error-code>0</error-code>
<message>Internal API server error</message>
</error>
If this is just an issue with their API, I'd love to get LinkedIn's attention on the matter.
Edit: Interestingly, I found a specific Linkedin connection that is causing the failure (by adjusting the 'start' and 'count' args). It's probably not wise to post that here, but I can provide that information to LinkedIn staff, if need be.
Edit 2: I found replacing 'public-profile' with 'site-standard-profile-request' does function as a workaround. It's not exactly the same thing, but close enough if your user is already using oauth
Same problem, in my case solved removing the "site-standard-profile-request" and the "current-share" attributes from the linkedin v1 people request.
Here is the working api url:
https://api.linkedin.com/v1/people/~:(id,first-name,last-name,maiden-name,formatted-name,phonetic-first-name,phonetic-last-name,formatted-phonetic-name,headline,location,industry,num-connections,num-connections-capped,summary,specialties,positions,picture-url,picture-urls::(original),site-standard-profile-request,api-standard-profile-request)
When I send a one-off document to RightSignature via their API, I'm specifying a callback location in the XML document as specified in RightSignature's schema definition. I then get a signer-link value back from their API for the document. I display the HTML response from the signer-link URL in an iFrame on our website. When our user signs the document in this iFrame, which is rendering the responses from their website, I want their website to post to our callback location.
Can I do this with the RightSignature API and does it make sense?
So far, I'm only getting content in the iFrame that indicates that the signing was successful. The callback location does not seem to be getting called.
I got it solved just now. Basically, i was doing two things wrong first you have to go in RightSignature Account and set it there the CallBack url
Account > Settings > Advanced Settings
But the thing which RS is unable to mention to us that this url can not be of localhost, but it should be of https i mean like Live URL of your site like
https://stagingmysite.azurewebsites.net/User/CallBackFunction
And then in your CallBack just write these two lines and you will receive complete XML which would have the GUID and document status as well.
byte[] data = Request.BinaryRead(Request.TotalBytes);
string callBackXML = System.Text.Encoding.UTF8.GetString(data);
I found the answer with some help from the API team at RightSignature. I was using callback_location but what I really wanted is redirect_location. Their online documentation was difficult to follow and did not clearly point out the difference.
I got this working after a lot of trial and error.
I have 2 API-Proxies running. I am able to call both directly through a browser. But when I am trying to call them through Apigee Console, they are throwing HTTP500.
Here is the link I am using:
http://ritwik_chatterjee-test.apigee.net/v1/yahoo-weather/forecastrss?w=2471390
Response in Apigee Console:
HTTP/1.1 500 Internal Server Error
X-APIGEE-STATUS:
failure
X-APIGEE-ERROR:
internal-error
Content-Length:
199
<?xml version="1.0" encoding="UTF-8"?>
<Error messageid="-4868f6ff:143f9f156c9:-7995">
<reason>An internal error has occurred. Please retry your request.</reason>
</Error>
Please help.
Worked through it and found a bug. The problem is that you have underscores in your org name (ritwik_chatterjee). I tested with a new org named test_my_underscores and got the same problem:
http://test_my_underscores-test.apigee.net/v0/weather
Returns the same 500 error as
http://ritwik_chatterjee-test.apigee.net/v1/yahoo-weather/forcastrss
Email me at michaelb#apigee.com and I'll get you an org with dashes in it.
Per RFC 952, underscores are not allowed in domain names.
While org names can contain underscores, Apigee creates the default hostnames based on the org name, so if an underscore exists, this will always fail without manual manipulation of the hostname and/or organization name.
This can cause user confusion, so I will recommend we simply update the platform to allow only characters allowed in hostnames (a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and period (.)) upon org creation. I will add additional notes to YTD-3120 mentioned above.
I think i got the issue. There is seems to be bug in Apigee Console. If the host name has a underscore("_") in it the Host header and X-Target-URI go bonkers. For now, try change your URL to ritwik-chatterjee-test.apigee.net if possible.
I will raise a bug and post the ticket number here
There must have been an intermittent issue. This seems to be working now.
I have a REST endpoint accepting a POST request to mark a code as redeemed. The code can only be redeemed between certain dates.
How should I respond if someone attempts to redeem the code early?
I suspect HTTP 403, Forbidden, is the right choice but then the w3c states that "the request SHOULD NOT be repeated" whereas in this case I would anticipate the request being repeated, just at a later date.
409 Conflict
The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict.
Ideally, the response entity would include enough information for the
user or user agent to fix the problem; however, that might not be
possible and is not required.
403 Forbidden makes more sense if they are trying to redeem a coupon that has already been redeemed, though 410 Gone seams elegant in this situation as well.
404 Not Found isn't ideal because the resource does in fact exist, however you can use it if you don't want to specify a reason with the 403 or if you want to hide the existence of the resource for security reasons.
If you are using HATEOAS, then you can also head you clients off at the pass (so to speak) by only including a redeem hypermedia control in the coupon resource (retrieved via a GET) when the coupon can be redeemed; though this won't stop overly bound clients from trying to redeem it anyway.
EDIT: Thanks to some good critiques (see below), I want to caveat this answer. It is based on Richardson & Ruby's writeup, which arguably doesn't mesh well with the httpbis writing on 403 Forbidden. (Personally, now I'm learning towards 409 as explained by Tom in a separate answer.)
403 Forbidden is the best choice. I will cite RESTful Web Services by Richardson & Ruby line by line. As you will see, 403 is a great fit:
The client's request is formed correctly, but the server doesn't want to carry it out.
Check!
This is not merely the case of insufficient credentials: that would be a 401 ("Unauthorized"). This is more like a resource that is only accessible at certain times, or from certain IP addresses.
Check!
A response of 403 implies that the client requested a resource that really exists. As with with 401 ("Unauthorized"), if the server doesn't want to give out even this information, it can lie and send a 404 ("Not Found") instead.
You wrote above: "The Code representation is available to be GETted before it goes live." So, you aren't trying to hide anything. So, stick with the 403. Check!
If the client's request is well-formed, why is this status code in the 4xx series (client-side error) instead of the 5xx series (server-side error)? Because the serve made it decision based on some aspect of the request other than its form; say, the time of day the request was made.
Check! The client's request was formed corrected, but it was inappropriate for the particular time.
We went four for four. The 403 code is a winner. No other codes match as well.
All of this said, a plain, non-specific 400 wouldn't be wrong, but would not be as specific or useful.
Another answer suggested the 409 Conflict code. Although worth considering, it isn't as good a fit. Here is why. According to Richardson & Ruby again:
Getting this [409] response response means that you tried to put the server's resources into an impossible or inconsistent state. Amazon S3 gives this response code when you try to delete a bucket that is not empty.
Claiming a promotion before it is 'active' wouldn't "put a server resource into an inconsistent state." It would break some business rules -- and result in cheating -- but it wouldn't cause a logical contradiction that I see.
So, whether you realized it at the onset of asking your question or not, 403 is a great choice. :)
Since Rest URLs should represent resources I would reply with 404 - Not Found
The resource is only available between certain dates, so on any other date it is not found.
When it says the request "SHOULD NOT be repeated", it is referring to the message that you should send to the viewer.
It has nothing to do with whether an actual request is repeated. (The user will get the same 403 message over and over again if s/he so desires.)
That said, a 404 is not appropriate for this because the resource is available - just that the code is not redeemable/forbidden to redeem. It is actually harmful because it tells the user that you probably made a mistake in your URL link or server configuration.
Of course, this assumes that on the appropriate date you return a 200 instead.