1
0
mirror of https://github.com/golang/go synced 2024-11-22 01:54:42 -07:00

http: add Location method to Response

Fixes #2300

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5117041
This commit is contained in:
Brad Fitzpatrick 2011-09-23 10:57:31 -07:00
parent 967d68c00a
commit cf6d0175d9
2 changed files with 68 additions and 0 deletions

View File

@ -13,6 +13,7 @@ import (
"os"
"strconv"
"strings"
"url"
)
var respExcludeHeader = map[string]bool{
@ -77,6 +78,23 @@ func (r *Response) Cookies() []*Cookie {
return readSetCookies(r.Header)
}
var ErrNoLocation = os.NewError("http: no Location header in response")
// Location returns the URL of the response's "Location" header,
// if present. Relative redirects are resolved relative to
// the Response's Request. ErrNoLocation is returned if no
// Location header is present.
func (r *Response) Location() (*url.URL, os.Error) {
lv := r.Header.Get("Location")
if lv == "" {
return nil, ErrNoLocation
}
if r.Request != nil && r.Request.URL != nil {
return r.Request.URL.Parse(lv)
}
return url.Parse(lv)
}
// ReadResponse reads and returns an HTTP response from r. The
// req parameter specifies the Request that corresponds to
// this Response. Clients must call resp.Body.Close when finished

View File

@ -15,6 +15,7 @@ import (
"io/ioutil"
"reflect"
"testing"
"url"
)
type respTest struct {
@ -395,3 +396,52 @@ func diff(t *testing.T, prefix string, have, want interface{}) {
}
}
}
type responseLocationTest struct {
location string // Response's Location header or ""
requrl string // Response.Request.URL or ""
want string
wantErr os.Error
}
var responseLocationTests = []responseLocationTest{
{"/foo", "http://bar.com/baz", "http://bar.com/foo", nil},
{"http://foo.com/", "http://bar.com/baz", "http://foo.com/", nil},
{"", "http://bar.com/baz", "", ErrNoLocation},
}
func TestLocationResponse(t *testing.T) {
for i, tt := range responseLocationTests {
res := new(Response)
res.Header = make(Header)
res.Header.Set("Location", tt.location)
if tt.requrl != "" {
res.Request = &Request{}
var err os.Error
res.Request.URL, err = url.Parse(tt.requrl)
if err != nil {
t.Fatalf("bad test URL %q: %v", tt.requrl, err)
}
}
got, err := res.Location()
if tt.wantErr != nil {
if err == nil {
t.Errorf("%d. err=nil; want %q", i, tt.wantErr)
continue
}
if g, e := err.String(), tt.wantErr.String(); g != e {
t.Errorf("%d. err=%q; want %q", i, g, e)
continue
}
continue
}
if err != nil {
t.Errorf("%d. err=%q", i, err)
continue
}
if g, e := got.String(), tt.want; g != e {
t.Errorf("%d. Location=%q; want %q", i, g, e)
}
}
}