TestDoRequestPreservesCheckRedirect pins the difference between Request and DoRequest that motivates DoRequest existing for redirect-sensitive call sites. Request delegates to go-gh, which builds an http.Client of its own from the transport alone, so a redirect policy set on the client cannot surviv
(t *testing.T)
| 397 | // which builds an http.Client of its own from the transport alone, so a redirect policy set on |
| 398 | // the client cannot survive. DoRequest sends through that client and so keeps it. |
| 399 | func TestDoRequestPreservesCheckRedirect(t *testing.T) { |
| 400 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 401 | if r.URL.Path == "/start" { |
| 402 | http.Redirect(w, r, "/final", http.StatusFound) |
| 403 | return |
| 404 | } |
| 405 | w.WriteHeader(http.StatusOK) |
| 406 | })) |
| 407 | defer ts.Close() |
| 408 | |
| 409 | newClient := func(called *bool) *http.Client { |
| 410 | return &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error { |
| 411 | *called = true |
| 412 | return http.ErrUseLastResponse |
| 413 | }} |
| 414 | } |
| 415 | |
| 416 | t.Run("DoRequest honours it", func(t *testing.T) { |
| 417 | var called bool |
| 418 | req, err := http.NewRequest(http.MethodGet, ts.URL+"/start", nil) |
| 419 | require.NoError(t, err) |
| 420 | |
| 421 | // The redirect is not followed, so the 3xx is the final response and, being outside |
| 422 | // the 2xx range, is reported as an error. Call sites such as gh repo delete rely on |
| 423 | // seeing that status to explain that a repo was renamed or transferred. |
| 424 | _, err = NewClientFromHTTP(newClient(&called)).DoRequest(req) |
| 425 | require.Error(t, err) |
| 426 | |
| 427 | var httpErr HTTPError |
| 428 | require.ErrorAs(t, err, &httpErr) |
| 429 | assert.True(t, called, "CheckRedirect should have been consulted") |
| 430 | assert.Equal(t, http.StatusFound, httpErr.StatusCode) |
| 431 | }) |
| 432 | |
| 433 | t.Run("Request cannot honour it", func(t *testing.T) { |
| 434 | var called bool |
| 435 | |
| 436 | resp, err := NewClientFromHTTP(newClient(&called)).Request("github.com", http.MethodGet, ts.URL+"/start", nil) |
| 437 | require.NoError(t, err) |
| 438 | defer resp.Body.Close() |
| 439 | |
| 440 | assert.False(t, called, "go-gh builds its own client, so the policy cannot apply") |
| 441 | assert.Equal(t, http.StatusOK, resp.StatusCode) |
| 442 | }) |
| 443 | } |