Cannot see status of redirect: manual fetch - fetch

I am using fetch to get information. When I do the following:
fetch('http://somedomain.com/something', { redirect: 'manual' }).then(console.log);
I get a response object with a status of 0. I would like to know if the status was a 301 or 302. Is there any way to determine this?
NOTE: for the purpose of this question assume all requests are within my domain and not cross origin.

Related

What is the correct status code if request URL does not match regex

I'm trying to develop error handling in my REST API and I'm currently working on the response codes. I haven't found a proper answer to what would be the appropriate response code for my problem.
I have routes which are managed like this in the back-end code:
$site->route([
'route' => '/{id:^[a-z]+$}'
]);
Now lets say the user inputs www.example.com/page1 which does not match the regex pattern. What would be the correct response? I am thinking either a 404, page not found, but I also think that a 400 response would be correct, because it describes that there was an error with the request.
I already use 404 if static URLs are invalid, so this is a question of matching dynamic parts of the URLs.
What are the field of use of both of these response codes in the case of REST APIs?
I think 404 is more appropriate.
According to the specification, 400 means:
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error.
While 404 means:
The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target resource or is not
willing to disclose that one exists.
From client point of view, request to /page1 will result in error, because the resource page1 does not exist (no route is matched in server side).
Normally, 400 means the server has already targeted the resource, but cannot return that resource due to client error. In this scenario, server cannot target the resource if no route is matched. Anyway, if the request is sent to /123456 and the status code is 400, what should be the error message? "Your requested URL is incorrect" sounds like 404, and "Your requested URL should follow regular expression: ...^[a-z]+$..." sounds very weird.

How to name my custom HTTP codes?

We're building a backend with a number of APIs. What should be the ideal range of HTTP codes that I should be using?
I've gone through https://en.wikipedia.org/wiki/List_of_HTTP_status_codes and they give a list such as:
1xx Informational
2xx Success
3xx Redirection
4xx Client Error
5xx Server Error
But since I want to implement my own status codes for various purposes such as missing email, I want to name the response accordingly.
So, according to me, a missing email response should trigger a 4xx response as it's a client error. What I'm trying to understand is that should I look for the first open slot such as #419 or should I begin to number the HTTP codes after #451?
You shouldn't use any custom codes at all - they might conflict with future standardization.
If you think you have a use case for a new code that is of general use, propose it in the right place (the HTTP Working Group).
If you just need something specific to your application, use a 400 (in this case), and provide additional information in the response body.

How to get a hold of the first HTTP (redirect) response? [duplicate]

This question already has answers here:
Query URL without redirect in Go
(2 answers)
Closed 6 years ago.
I developed a code by using the Go http package so that I can get the status code of any url . But after a bit of digging I checked to see why the request was taking long and I discovered that the URL keeps redirecting until I get status 200 OK.
I want to manage to get the first response from the web server. I don't want to get always 200 OK, whatever it gives me I want to take it. What should I do?
Example:
https://apple.com responded 301 MOVED PERMANENTLY when I used cURL to get the code.
That's the response I want, not a redirect to 200.
The http.Client offers a possibility to control that via the CheckRedirect member.
From the link above:
// CheckRedirect specifies the policy for handling redirects.
// If CheckRedirect is not nil, the client calls it before
// following an HTTP redirect. The arguments req and via are
// the upcoming request and the requests made already, oldest
// first. If CheckRedirect returns an error, the Client's Get
// method returns both the previous Response and
// CheckRedirect's error (wrapped in a url.Error) instead of
// issuing the Request req.
//
// If CheckRedirect is nil, the Client uses its default policy,
// which is to stop after 10 consecutive requests.
ct func(req *Request, via []*Request) error
Disclaimer: Not tested.

Why do POST request in the Go http.Client not follow 301 redirects?

I'm building a test tool with Go. This tool can retrieve a specific URL by doing a POST request to an endpoint which returns a 303 with the Location to test. Sometimes this location itself is redirected with a 301 which I want to follow as well.
Test tool -> POST /get-url-to-test -> 303 Location: /other -> GET /other -> 301 Location: /new-other (stops here because initial request is POST)
As we can see in Go's source (lines 241 to 257), it seems like GET requests follow 301 redirects, but not POST requests:
http://golang.org/src/net/http/client.go
Why is that? Is that part of an HTTP spec? Is this an decision that was made by the Go community?
The reason I'm asking is because in my case, I'd have to manually do a new GET request to get to the URL redirected to by /other, I think.
EDIT 1: I made a mistake before: the /other resource is being fetched by Go with a GET request. But since it returns a 301 and the initial request was a POST, Go stops redirecting on the 301. That seems odd. Am I missing something?
EDIT 2: This may be a bug, I've opened an issue on Github: https://github.com/golang/go/issues/9348
The HTTP RFC 2616 says:
10.3 Redirection 3xx
This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. The action required MAY be carried out by the user agent
without interaction with the user if and only if the method used in
the second request is GET or HEAD.

REST HTTP status code for "success, and thus you no longer have access"

My RESTful service includes a resource representing an item ACL. To update this ACL, a client does a PUT request with the new ACL as its entity. On success, the PUT response entity contains the sanitized, canonical version of the new ACL.
In most cases, the HTTP response status code is fairly obvious. 200 on success, 403 if the user isn't permitted to edit the ACL, 400 if the new ACL is malformed, 404 if they try to set an ACL on a nonexistent item, 412 if the If-Match header doesn't match, and the like.
There is one case, however, where the correct HTTP status code isn't obvious. What if the authenticated user uses PUT to remove themselves from the ACL? We need to indicate that the request has succeeded but that they no longer have access to the resource.
I've considered returning 200 with the new ACL in the PUT entity, but this lacks any indication that they no longer have the ability to GET the resource. I've considered directly returning 403, but this doesn't indicate that the PUT was successful. I've considered returning 303 with the Location pointing back to the same resource (where a subsequent GET will give a 403), but this seems like a misuse of 303 given that the resource hasn't moved.
So what's the right REST HTTP status code for "success, and thus you no longer have access"?
200 is the appropriate response, because it indicates success (as any 2xx code implies). You may distinguish the user's lack of permission in the response (or, if you don't wish to, 204 is fine). Status codes make no contract that future requests will return the same code: a 200 response to the PUT does not mean a subsequent GET can't return 403. In general, servers should never try to tell clients what will happen if they issue a particular request. HTTP clients should almost always leap before they look and be prepared to handle almost any response code.
You should read the updated description of the PUT method in httpbis; it discusses not only the use of 200/204 but indicates on a careful reading that returning a transformed representation in immediate response to the PUT is not appropriate; instead, use an ETag or Last-Modified header to indicate whether the entity the client sent was transformed or not. If it was, the client should issue a subsequent GET rather than expecting the new representation to be sent in response to the PUT, if for no other reason than to update any caches along the way (because the response to a PUT is not cacheable). Section 6.3.1 agrees: the response to a PUT should represent the status of the action, not the resource itself. Note also that, for a new ACL, you MUST return 201, not 200.
You're confusing two semantic ideas, and trying to combine them into a single response code.
The first: That you successfully created an ACL at the location that you were attempting to. The correct semantic response (in either a RESTful or non-RESTful scenario) is a 201 Created. From the RFC: "The request has been fulfilled and resulted in a new resource being created."
The second: That the user who executed the PUT does not have access to this resource any more. This is a transient idea - what if the ACL is updated, or something changes before the next request? The idea that a user does not have access to a resource of any kind (and this includes an ACL resource) only matters for the scope of that request. Before the next request is executed, something could change. On a single request where a user does not have access to something you should return a 403 Forbidden.
Your PUT method should return a 201. If the client is worried about whether it has access any more, it should make a subsequent request to determine it's status.
You might want to take a look at HTTP response code "204 No Content" (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), indicating that the "server has fulfilled the request [to be removed from the ACL] but does not need to return an entity-body, and might want to return updated metainformation" (here, as a result of the successful removal). Although you're not allowed to return a message body with 204, you can return entity headers indicating changes to the user's access to the resource. I got the idea from Amazon S3 - they return a 204 on a successful DELETE request (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html), which seems to resemble your situation since by removing yourself from an ACL, you've blocked access to that resource in the future.
Very interesting question :-) This is why I love REST, sometimes it might get you crazy. Reading w3 http status code definitions I would choose (this of course is just my humble opinion) one of those:
202 Accepted - since this mean "well yes I got your request, I will process it but come back later and see what happens" - and when the user comes back later she'll get a 403(which should be expected behavior)
205 Reset Content - "Yep, I understood you want to remove yourself please make a new request, when you come back you'll get 403"
On the other hand (just popped-up in my mind), why should you introduce a separate logic and differentiate that case and not using 200 ? Is this rest going to be used from some client application that has an UI? And the user of the rest should show a pop-up to the end-user "Are you sure you want to remove yourself from the ACL?" well here the case can be handled if your rest returns 200 and just show a pop-up "Are you sure you want to remove user with name from the ACL?", no need to differentiate the two cases. If this rest will be used for some service-to-service communication(i.e. invoked only from another program) again why should you differentiate the cases here the program wouldn't care which user will be removed from the ACL.
Hope that helps.

Resources