// Redirect returns the redirect target as an absolute URL. // If the Response is not a redirect of the pointed URL is // not valid, an error is returned. func (r *Response) Redirect() (string, error) { if r.IsRedirect() { location := r.Header.Get("Location") return urlutil.Join(r.Request.URL.String(), location) } return "", fmt.Errorf("response is not a redirect (status code %d)", r.StatusCode) }
// Next returns true iff the Iter could perform a trip // using Client.Trip with the current *http.Request. // Calling Next() closes the previous *Response automatically // if it was a redirect. func (i *Iter) Next() bool { if i.err != nil { return false } if i.resp == nil { // First request, do some sanity checks if i.req.Method == "POST" || i.req.Method == "PUT" { i.err = fmt.Errorf("can't iter over Request with method %s", i.req.Method) return false } if i.req.Body != nil { i.err = errors.New("can't iter over Request with a body") return false } } else { // 2nd and subsequent requests if !i.resp.IsRedirect() { return false } i.resp.Close() location := i.resp.Header.Get("Location") next, err := urlutil.Join(i.req.URL.String(), location) if err != nil { i.err = err return false } req, err := http.NewRequest(i.req.Method, next, nil) if err != nil { i.err = err return false } i.req = req } resp, err := i.c.Trip(i.req) if err != nil { i.err = err return false } i.resp = resp return resp.IsRedirect() }