Summary of the knowledge points of Go HTTP redirect

Source: Internet
Author: User
Tags http redirect rfc
This is a creation in Article, where the information may have evolved or changed.

The HTTP specification defines a return code to 3xx represent the client that needs to do some extra work to complete the request, mostly 3xx for forwarding (redirect).

A detailed description of the status code can refer to the specification or Wikipedia, Wikipedia, the following is a short introduction to the code.

    • Multiple Choices: Returns multiple resources to choose from
    • 301 Moved Permanently: The requested resource has been permanently moved to a new location, and any future references to this resource should use one of several URIs returned by this response
    • 302 Found: The requested resource is now temporarily responding to requests from different URIs. Since such redirects are temporary, the client should continue to send subsequent requests to the original address, meaning in HTTP 1.0, Moved Temporarily but many browsers are implemented at 303, so HTTP 1.1 adds 303 and 307 status codes to differentiate between different behaviors
    • 303 See other (since http/1.1): The response to the current request can be found on another URI, and the client should access that resource in a get way
    • 304 Not Modified (RFC 7232): The requested resource has not changed
    • 305 Use proxy (since http/1.1): The requested resource must be accessed through the specified proxy
    • 306 Switch Proxy: In the latest version of the specification, the 306 status code is no longer being used
    • 307 temporary Redirect (since http/1.1): The requested resource is now temporarily responding to requests from different URIs, and unlike 303, it still uses the original method
    • 308 Permanent Redirect (RFC 7538): The requested resource has been permanently moved to a new location, and the new requested method cannot be changed

Go HTTP Library in the implementation of the process is also constantly complete and modify the bug, in version 1.8 resolved the previous version of the implementation of the problem (you can search redirect in Go issues to see the relevant issue). This article combs the knowledge of Redirect in Go so that you know what to do when you encounter a forwarded problem.

The forwarding policy and the default number of forwards.

http. The client contains a CheckRedirect field that defines the forwarded policy, which is used by default if you do not set it defaultCheckRedirect :

1234567
func (c *client) Checkredirect (req *request, via []*request) error {fn: = C.checkredirectifnil {fn = DEFAULTC Heckredirect}return fn (req, via)}

This function is called before the forwarding is performed, and you can see that the function returns ERR and no longer forwards.
The first parameter of this function req is the request that is about to be forwarded, the second parameter via has been requested by the requests.

12345678910111213141516171819202122
 for {    ...    //need to be forwarded    {        ...        Err = C.checkredirect (req, reqs)if err = = erruselastresponse {returnnil}//discard Previous response...        if Nil {UE: = Uerr (ERR) UE. (*url. Error). URL = locreturn RESP, UE}    }    ...}

The default forwarding policy is to forward up to 10 times, avoiding high forwarding times or dead loops.

123456
func defaultcheckredirect (req *request, via []*request) error {Iflen(via) >=  {return errors. New ("stopped after redirects")}returnnil}

If you want to implement a different forwarding strategy, you need to define your own CheckRedirect .

Forwarding Security

1) When the forwarded request contains a secure information header, such as,,, Authorization WWW-Authenticate Cookie etc. header, if it is cross-domain, these headers will not be copied to the new request.

123456789
func string BOOL {switch canonicalheaderkey (headerkey) {case"Authorization" "www-authenticate" "Cookie" "Cookie2": ihost: = Strings. ToLower (initial. Host) Dhost: = Strings. ToLower (dest. Host)return isdomainorsubdomain (Dhost, Ihost)}returntrue}

2) If a non-empty cookie jar is set, the forward response modifies the value in the cookie jar, but the next time the header is forwarded, the Cookie headers are processed, ignoring the changed cookie.

When forwarding the ' cookie ' header with a non-nil cookie Jar.
Since Each redirect may mutate the state of the cookie jar,
A redirect may possibly an alter a cookie set in the initial request.
When forwarding the ' Cookie ' header, any mutated cookie would be omitted,
With the expectation, the Jar would insert those mutated cookies
With the updated values (assuming the Origin matches).
If Jar is nil, the initial cookie is forwarded without.

Specifically, you can view makeHeadersCopier the implementation.
You can see that each time redirect deletes the changes caused by the last redirect, and then restores the coookie of the original request.

1234567891011121314151617181920212223242526272829
  ifC.jar! =Nil&& icookies! =Nil{varChangedBOOLRESP: = req. Response//The response that caused the upcoming redirect for_, C: =RangeResp. Cookies () {if_, OK: = Icookies[c.name]; OK {Delete(Icookies, c.name) changed =true}}ifChanged {Ireqhdr. Del ("Cookie")varSS []string for_, cs: =Rangeicookies { for_, C: =RangeCS {ss =Append(SS, c.name+"="+c.value)}}sort. Strings (SS)//Ensure deterministic headersIreqhdr. Set ("Cookie", strings. Join (SS,"; "))}}//Copy The initial request ' s Header values//(at least the safe ones). forK, VV: =RangeIREQHDR {ifShouldcopyheaderonredirect (k, Preq. URL, req. URL) {req. HEADER[K] = VV}}

Forwarding rules

When the server returns a forwarding response, the client first uses the CheckRedirect function to check whether to forward.

The following requests are processed by default:

    • 301 (Moved permanently)
    • 302 (Found)
    • 303 (see other)
    • 307 (Temporary Redirect)
    • 308 (Permanent Redirect)

If you need to forward, for,, 301 302 303 The status code, then the forwarded request will convert the request method into GET method (if the original request method is the HEAD same, or HEAD ), And the body is empty, although the original request may contain the body. For 307 the 308 status code, the Method of the next forwarded request is unchanged, consistent with the original request, and the original body content is used to send the forwarding request.

The logic of code processing is redirectBehavior implemented by functions.

1234567891011121314151617181920212223242526
funcRedirectbehavior (Reqmethodstring, resp *response, Ireq *request) (Redirectmethodstring, Shouldredirect, IncludebodyBOOL) {SwitchResp. StatusCode { Case301,302,303: Redirectmethod = Reqmethodshouldredirect =trueIncludebody =falseifReqmethod! ="GET"&& Reqmethod! ="HEAD"{Redirectmethod ="GET"} Case307,308: Redirectmethod = Reqmethodshouldredirect =trueIncludebody =trueifResp. Header.get ("Location") ==""{Shouldredirect =false Break}ifIreq. GetBody = =Nil&& ireq.outgoinglength ()! =0{Shouldredirect =false}}returnRedirectmethod, Shouldredirect, includebody}

The above is an introduction to the HTTP redirect related content, which is mainly the client's code logic. The following two sections describe something that is a little bit related to HTTP redirect.

Redirecthandler

HTTP defines a convenience type: Redirecthandler, which is a predefined HTTP handler that forwards the specified request to the specified URL, primarily using the set URL and status code settings response Locatio N.

It is used as a server-side development.

1
func string int) Handler

Note that code should be 3xx the status code, usually StatusMovedPermanently , StatusFound or StatusSeeOther .

Roundtripper

Roundtripper is also used as a client development.

The Roundtripper represents an HTTP request. When using redirect, you may redirect multiple times, that is, HTTP requests that execute n times.

123
type Interface {        roundtrip (*request) (*response, error)}

DefaultTransportis the default Roundtripper implementation. It establishes a network connection and caches it for subsequent request reuse. It uses $HTTP_PROXY and $NO_PROXY (or $http _proxy, $no _proxy) environment variables to set the proxy.

Other Roundtripper implementations also have the NewFileTransport Roundtripper created to serve the filesystem and map the file system to HTTP processing.

123456789101112
var Defaulttransport roundtripper = &transport{        proxy:proxyfromenvironment,        dialcontext: (&net. dialer{                Timeout:    * time. Second,                KeepAlive:  * time. Second,                true,        }). Dialcontext,        Maxidleconns: +          ,        idleconntimeout:        * time. Second,        tlshandshaketimeout:   Ten * time. Second,        expectcontinuetimeout: 1 * time. Second,}

When Redirect the default forwarding is the HTTP library automatically to help you achieve, if you want to do in-depth tracking of the forwarding process (simple tracking can use HttpTrace), you can customize a roundtripper, such as the following:

Http://stackoverflow.com/questions/24577494/how-to-get-the-http-redirect-status-codes-in-golang
12345678910111213141516171819
type struct {    Transport http. Roundtripper}func (l logredirects) roundtrip (req *http. Request) (Resp *http. Response, err Error) {    T: = L.transport    ifnil {        t = http. Defaulttransport    }    resp, err = T.roundtrip (req)    ifnil {        return    }    Switch resp. StatusCode {case     http. statusmovedpermanently, http. Statusfound, http. Statusseeother, http. Statustemporaryredirect:        log. Println ("Request for""redirected with Status", resp. StatusCode)    }    return}

ClientYou can use the following code when you create it:

1
Client: = &http. client{transport:logredirects{}}

So we can track each forwarding process.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.