func TestPostRedirects(t *testing.T) { defer afterTest(t) var log struct { sync.Mutex bytes.Buffer } var ts *httptest.Server ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { log.Lock() fmt.Fprintf(&log.Buffer, "%s %s ", r.Method, r.RequestURI) log.Unlock() if v := r.URL.Query().Get("code"); v != "" { code, _ := strconv.Atoi(v) if code/100 == 3 { w.Header().Set("Location", ts.URL) } w.WriteHeader(code) } })) defer ts.Close() tests := []struct { suffix string want int // response code }{ {"/", 200}, {"/?code=301", 301}, {"/?code=302", 200}, {"/?code=303", 200}, {"/?code=404", 404}, } for _, tt := range tests { res, err := Post(ts.URL+tt.suffix, "text/plain", strings.NewReader("Some content")) if err != nil { t.Fatal(err) } if res.StatusCode != tt.want { t.Errorf("POST %s: status code = %d; want %d", tt.suffix, res.StatusCode, tt.want) } } log.Lock() got := log.String() log.Unlock() want := "POST / POST /?code=301 POST /?code=302 GET / POST /?code=303 GET / POST /?code=404 " if got != want { t.Errorf("Log differs.\n Got: %q\nWant: %q", got, want) } }
func TestRedirectCookiesJar(t *testing.T) { defer afterTest(t) var ts *httptest.Server ts = httptest.NewServer(echoCookiesRedirectHandler) defer ts.Close() c := &Client{ Jar: new(TestJar), } u, _ := url.Parse(ts.URL) c.Jar.SetCookies(u, []*Cookie{expectedCookies[0]}) resp, err := c.Get(ts.URL) if err != nil { t.Fatalf("Get: %v", err) } resp.Body.Close() matchReturnedCookies(t, expectedCookies, resp.Cookies()) }
func TestClientRedirects(t *testing.T) { defer afterTest(t) var ts *httptest.Server ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { n, _ := strconv.Atoi(r.FormValue("n")) // Test Referer header. (7 is arbitrary position to test at) if n == 7 { if g, e := r.Referer(), ts.URL+"/?n=6"; e != g { t.Errorf("on request ?n=7, expected referer of %q; got %q", e, g) } } if n < 15 { Redirect(w, r, fmt.Sprintf("/?n=%d", n+1), StatusFound) return } fmt.Fprintf(w, "n=%d", n) })) defer ts.Close() c := &Client{} _, err := c.Get(ts.URL) if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Get, expected error %q, got %q", e, g) } // HEAD request should also have the ability to follow redirects. _, err = c.Head(ts.URL) if e, g := "Head /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Head, expected error %q, got %q", e, g) } // Do should also follow redirects. greq, _ := NewRequest("GET", ts.URL, nil) _, err = c.Do(greq) if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Do, expected error %q, got %q", e, g) } var checkErr error var lastVia []*Request c = &Client{CheckRedirect: func(_ *Request, via []*Request) error { lastVia = via return checkErr }} res, err := c.Get(ts.URL) if err != nil { t.Fatalf("Get error: %v", err) } res.Body.Close() finalUrl := res.Request.URL.String() if e, g := "<nil>", fmt.Sprintf("%v", err); e != g { t.Errorf("with custom client, expected error %q, got %q", e, g) } if !strings.HasSuffix(finalUrl, "/?n=15") { t.Errorf("expected final url to end in /?n=15; got url %q", finalUrl) } if e, g := 15, len(lastVia); e != g { t.Errorf("expected lastVia to have contained %d elements; got %d", e, g) } checkErr = errors.New("no redirects allowed") res, err = c.Get(ts.URL) if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr { t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err) } if res == nil { t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)") } res.Body.Close() if res.Header.Get("Location") == "" { t.Errorf("no Location header in Response") } }