mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-03 06:27:47 +00:00
Compare commits
1 Commits
espradio
...
roundtripper
| Author | SHA1 | Date | |
|---|---|---|---|
| 349b5ca87e |
+43
-1
@@ -2,6 +2,8 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -85,7 +87,9 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultClient is the default Client and is used by Get, Head, and Post.
|
// 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
|
// RoundTripper is an interface representing the ability to execute a
|
||||||
// single HTTP transaction, obtaining the Response for a given Request.
|
// 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)
|
req.Header.Set("Content-Type", contentType)
|
||||||
return c.Do(req)
|
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()))
|
||||||
|
}
|
||||||
|
|||||||
+29
-18
@@ -25,17 +25,39 @@ func (c *Client) Do(req *Request) (*Response, error) {
|
|||||||
req.AddCookie(cookie)
|
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 {
|
switch req.URL.Scheme {
|
||||||
case "http":
|
case "http":
|
||||||
return c.doHTTP(req)
|
return t.doHTTP(req)
|
||||||
case "https":
|
case "https":
|
||||||
return c.doHTTPS(req)
|
return t.doHTTPS(req)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid schemer : %s", req.URL.Scheme)
|
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
|
// make TCP connection
|
||||||
ip := net.ParseIP(req.URL.Hostname())
|
ip := net.ParseIP(req.URL.Hostname())
|
||||||
port := 80
|
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)
|
conn, err := tls.Dial("tcp", req.URL.Host, nil)
|
||||||
retry := 0
|
retry := 0
|
||||||
for ; err != nil; conn, err = tls.Dial("tcp", req.URL.Host, nil) {
|
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{
|
resp := &Response{
|
||||||
Header: map[string][]string{},
|
Header: map[string][]string{},
|
||||||
}
|
}
|
||||||
@@ -256,11 +278,6 @@ func (c *Client) doResp(conn net.Conn, req *Request) (*Response, error) {
|
|||||||
remain -= int64(ofs)
|
remain -= int64(ofs)
|
||||||
if remain <= 0 {
|
if remain <= 0 {
|
||||||
resp.Body = io.NopCloser(bytes.NewReader(buf[:ofs]))
|
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()
|
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()
|
return resp, conn.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user