</li>
<li><!-- CL 31733, CL 29852 -->
- The <code>Client</code> now supports 307 and 308 redirects.
- If the redirect requires resending the request body,
- the request must have the new
+ The <code>Client</code> now supports 301, 307, and 308 redirects.
+
+ For example, <code>Client.Post</code> now follows 301
+ redirects, converting them to <code>GET</code> requests
+ without bodies, like it did for 302 and 303 redirect responses
+ previously.
+
+ The <code>Client</code> now also follows 307 and 308
+ redirects, preserving the original request method and body, if
+ any. If the redirect requires resending the request body, the
+ request must have the new
<a href="/pkg/net/http/#Request"><code>Request.GetBody</code></a>
field defined.
<a href="pkg/net/http/#NewRequest"><code>NewRequest</code></a>
// the returned Response.Body is already closed.
//
// Generally Get, Post, or PostForm will be used instead of Do.
+//
+// If the server replies with a redirect, the Client first uses the
+// CheckRedirect function to determine whether the redirect should be
+// followed. If permitted, a 301, 302, or 303 redirect causes
+// subsequent requests to use HTTP method "GET", with no body.
+// A 307 or 308 redirect preserves the original HTTP method and body,
+// provided that the Request.GetBody function is defined.
+// The NewRequest function automatically sets GetBody for common
+// standard library body types.
func (c *Client) Do(req *Request) (*Response, error) {
if req.URL == nil {
req.closeBody()
// Post is a wrapper around DefaultClient.Post.
//
// To set custom headers, use NewRequest and DefaultClient.Do.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
func Post(url string, contentType string, body io.Reader) (resp *Response, err error) {
return DefaultClient.Post(url, contentType, body)
}
// request.
//
// To set custom headers, use NewRequest and Client.Do.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
func (c *Client) Post(url string, contentType string, body io.Reader) (resp *Response, err error) {
req, err := NewRequest("POST", url, body)
if err != nil {
// Caller should close resp.Body when done reading from it.
//
// PostForm is a wrapper around DefaultClient.PostForm.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
func PostForm(url string, data url.Values) (resp *Response, err error) {
return DefaultClient.PostForm(url, data)
}
//
// When err is nil, resp always contains a non-nil resp.Body.
// Caller should close resp.Body when done reading from it.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
}
// net/http/httptest package, use ReadRequest, or manually update the
// Request fields. See the Request type's documentation for the
// difference between inbound and outbound request fields.
+//
+// If body is of type *bytes.Buffer, *bytes.Reader, or
+// *strings.Reader, the returned request's ContentLength is set to its
+// exact value (instead of -1), GetBody is populated (so 307 and 308
+// redirects can replay the body), and Body is set to NoBody if the
+// ContentLength is 0.
func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
if method == "" {
// We document that "" means "GET" for Request.Method, and people have