diff --git a/net/http/client.go b/net/http/client.go index e6daef2..0a25ba3 100644 --- a/net/http/client.go +++ b/net/http/client.go @@ -2,6 +2,8 @@ package http import ( "io" + "net/url" + "strings" "time" ) @@ -85,7 +87,9 @@ type Client struct { } // DefaultClient is the default Client and is used by Get, Head, and Post. -var DefaultClient = &Client{} +var DefaultClient = &Client{ + Transport: DefaultTransport, +} // RoundTripper is an interface representing the ability to execute a // single HTTP transaction, obtaining the Response for a given Request. @@ -211,3 +215,41 @@ func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, req.Header.Set("Content-Type", contentType) return c.Do(req) } + +// PostForm issues a POST to the specified URL, with data's keys and +// values URL-encoded as the request body. +// +// The Content-Type header is set to application/x-www-form-urlencoded. +// To set other headers, use NewRequest and DefaultClient.Do. +// +// When err is nil, resp always contains a non-nil resp.Body. +// 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. +// +// To make a request with a specified context.Context, use NewRequestWithContext +// and DefaultClient.Do. +func PostForm(url string, data url.Values) (resp *Response, err error) { + return DefaultClient.PostForm(url, data) +} + +// PostForm issues a POST to the specified URL, +// with data's keys and values URL-encoded as the request body. +// +// The Content-Type header is set to application/x-www-form-urlencoded. +// To set other headers, use NewRequest and Client.Do. +// +// 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. +// +// To make a request with a specified context.Context, use NewRequestWithContext +// and Client.Do. +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())) +} diff --git a/net/http/tinygo.go b/net/http/tinygo.go index 6ac3449..805c35b 100644 --- a/net/http/tinygo.go +++ b/net/http/tinygo.go @@ -25,17 +25,39 @@ func (c *Client) Do(req *Request) (*Response, error) { req.AddCookie(cookie) } } + + res, err := c.Transport.RoundTrip(req) + + if c.Jar != nil { + if rc := res.Cookies(); len(rc) > 0 { + c.Jar.SetCookies(req.URL, rc) + } + } + + return res, err +} + +type Transport struct { +} + +var DefaultTransport RoundTripper + +func init() { + DefaultTransport = &Transport{} +} + +func (t *Transport) RoundTrip(req *Request) (*Response, error) { switch req.URL.Scheme { case "http": - return c.doHTTP(req) + return t.doHTTP(req) case "https": - return c.doHTTPS(req) + return t.doHTTPS(req) default: return nil, fmt.Errorf("invalid schemer : %s", req.URL.Scheme) } } -func (c *Client) doHTTP(req *Request) (*Response, error) { +func (t *Transport) doHTTP(req *Request) (*Response, error) { // make TCP connection ip := net.ParseIP(req.URL.Hostname()) port := 80 @@ -106,10 +128,10 @@ func (c *Client) doHTTP(req *Request) (*Response, error) { } - return c.doResp(conn, req) + return t.doResp(conn, req) } -func (c *Client) doHTTPS(req *Request) (*Response, error) { +func (t *Transport) doHTTPS(req *Request) (*Response, error) { conn, err := tls.Dial("tcp", req.URL.Host, nil) retry := 0 for ; err != nil; conn, err = tls.Dial("tcp", req.URL.Host, nil) { @@ -167,10 +189,10 @@ func (c *Client) doHTTPS(req *Request) (*Response, error) { } - return c.doResp(conn, req) + return t.doResp(conn, req) } -func (c *Client) doResp(conn net.Conn, req *Request) (*Response, error) { +func (t *Transport) doResp(conn net.Conn, req *Request) (*Response, error) { resp := &Response{ Header: map[string][]string{}, } @@ -256,11 +278,6 @@ func (c *Client) doResp(conn net.Conn, req *Request) (*Response, error) { remain -= int64(ofs) if remain <= 0 { resp.Body = io.NopCloser(bytes.NewReader(buf[:ofs])) - if c.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - c.Jar.SetCookies(req.URL, rc) - } - } return resp, conn.Close() } @@ -298,11 +315,5 @@ func (c *Client) doResp(conn net.Conn, req *Request) (*Response, error) { } } - if c.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - c.Jar.SetCookies(req.URL, rc) - } - } - return resp, conn.Close() }