mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-16 12:53:23 +00:00
rtl8720dn: add support for http.Get(), http.Post() and cookie
This commit is contained in:
@@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"mime/multipart"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
urlpkg "net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -248,6 +250,57 @@ func (r *Request) ProtoAtLeast(major, minor int) bool {
|
||||
r.ProtoMajor == major && r.ProtoMinor >= minor
|
||||
}
|
||||
|
||||
// UserAgent returns the client's User-Agent, if sent in the request.
|
||||
func (r *Request) UserAgent() string {
|
||||
return r.Header.Get("User-Agent")
|
||||
}
|
||||
|
||||
// Cookies parses and returns the HTTP cookies sent with the request.
|
||||
func (r *Request) Cookies() []*Cookie {
|
||||
return readCookies(r.Header, "")
|
||||
}
|
||||
|
||||
// ErrNoCookie is returned by Request's Cookie method when a cookie is not found.
|
||||
var ErrNoCookie = errors.New("http: named cookie not present")
|
||||
|
||||
// Cookie returns the named cookie provided in the request or
|
||||
// ErrNoCookie if not found.
|
||||
// If multiple cookies match the given name, only one cookie will
|
||||
// be returned.
|
||||
func (r *Request) Cookie(name string) (*Cookie, error) {
|
||||
for _, c := range readCookies(r.Header, name) {
|
||||
return c, nil
|
||||
}
|
||||
return nil, ErrNoCookie
|
||||
}
|
||||
|
||||
// AddCookie adds a cookie to the request. Per RFC 6265 section 5.4,
|
||||
// AddCookie does not attach more than one Cookie header field. That
|
||||
// means all cookies, if any, are written into the same line,
|
||||
// separated by semicolon.
|
||||
// AddCookie only sanitizes c's name and value, and does not sanitize
|
||||
// a Cookie header already present in the request.
|
||||
func (r *Request) AddCookie(c *Cookie) {
|
||||
s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
|
||||
if c := r.Header.Get("Cookie"); c != "" {
|
||||
r.Header.Set("Cookie", c+"; "+s)
|
||||
} else {
|
||||
r.Header.Set("Cookie", s)
|
||||
}
|
||||
}
|
||||
|
||||
// Referer returns the referring URL, if sent in the request.
|
||||
//
|
||||
// Referer is misspelled as in the request itself, a mistake from the
|
||||
// earliest days of HTTP. This value can also be fetched from the
|
||||
// Header map as Header["Referer"]; the benefit of making it available
|
||||
// as a method is that the compiler can diagnose programs that use the
|
||||
// alternate (correct English) spelling req.Referrer() but cannot
|
||||
// diagnose programs that use Header["Referrer"].
|
||||
func (r *Request) Referer() string {
|
||||
return r.Header.Get("Referer")
|
||||
}
|
||||
|
||||
// isH2Upgrade reports whether r represents the http2 "client preface"
|
||||
// magic string.
|
||||
func (r *Request) isH2Upgrade() bool {
|
||||
@@ -299,6 +352,114 @@ func validMethod(method string) bool {
|
||||
return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1
|
||||
}
|
||||
|
||||
// NewRequest wraps NewRequestWithContext using the background context.
|
||||
func NewRequest(method, url string, body io.Reader) (*Request, error) {
|
||||
return NewRequestWithContext(context.Background(), method, url, body)
|
||||
}
|
||||
|
||||
// NewRequestWithContext returns a new Request given a method, URL, and
|
||||
// optional body.
|
||||
//
|
||||
// If the provided body is also an io.Closer, the returned
|
||||
// Request.Body is set to body and will be closed by the Client
|
||||
// methods Do, Post, and PostForm, and Transport.RoundTrip.
|
||||
//
|
||||
// NewRequestWithContext returns a Request suitable for use with
|
||||
// Client.Do or Transport.RoundTrip. To create a request for use with
|
||||
// testing a Server Handler, either use the NewRequest function in the
|
||||
// net/http/httptest package, use ReadRequest, or manually update the
|
||||
// Request fields. For an outgoing client request, the context
|
||||
// controls the entire lifetime of a request and its response:
|
||||
// obtaining a connection, sending the request, and reading the
|
||||
// response headers and body. 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 NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) {
|
||||
if method == "" {
|
||||
// We document that "" means "GET" for Request.Method, and people have
|
||||
// relied on that from NewRequest, so keep that working.
|
||||
// We still enforce validMethod for non-empty methods.
|
||||
method = "GET"
|
||||
}
|
||||
if !validMethod(method) {
|
||||
return nil, fmt.Errorf("net/http: invalid method %q", method)
|
||||
}
|
||||
if ctx == nil {
|
||||
return nil, errors.New("net/http: nil Context")
|
||||
}
|
||||
u, err := urlpkg.Parse(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc, ok := body.(io.ReadCloser)
|
||||
if !ok && body != nil {
|
||||
rc = io.NopCloser(body)
|
||||
}
|
||||
// The host's colon:port should be normalized. See Issue 14836.
|
||||
u.Host = removeEmptyPort(u.Host)
|
||||
req := &Request{
|
||||
ctx: ctx,
|
||||
Method: method,
|
||||
URL: u,
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
Header: make(Header),
|
||||
Body: rc,
|
||||
Host: u.Host,
|
||||
}
|
||||
if body != nil {
|
||||
switch v := body.(type) {
|
||||
case *bytes.Buffer:
|
||||
req.ContentLength = int64(v.Len())
|
||||
buf := v.Bytes()
|
||||
req.GetBody = func() (io.ReadCloser, error) {
|
||||
r := bytes.NewReader(buf)
|
||||
return io.NopCloser(r), nil
|
||||
}
|
||||
case *bytes.Reader:
|
||||
req.ContentLength = int64(v.Len())
|
||||
snapshot := *v
|
||||
req.GetBody = func() (io.ReadCloser, error) {
|
||||
r := snapshot
|
||||
return io.NopCloser(&r), nil
|
||||
}
|
||||
case *strings.Reader:
|
||||
req.ContentLength = int64(v.Len())
|
||||
snapshot := *v
|
||||
req.GetBody = func() (io.ReadCloser, error) {
|
||||
r := snapshot
|
||||
return io.NopCloser(&r), nil
|
||||
}
|
||||
default:
|
||||
// This is where we'd set it to -1 (at least
|
||||
// if body != NoBody) to mean unknown, but
|
||||
// that broke people during the Go 1.8 testing
|
||||
// period. People depend on it being 0 I
|
||||
// guess. Maybe retry later. See Issue 18117.
|
||||
}
|
||||
// For client requests, Request.ContentLength of 0
|
||||
// means either actually 0, or unknown. The only way
|
||||
// to explicitly say that the ContentLength is zero is
|
||||
// to set the Body to nil. But turns out too much code
|
||||
// depends on NewRequest returning a non-nil Body,
|
||||
// so we use a well-known ReadCloser variable instead
|
||||
// and have the http package also treat that sentinel
|
||||
// variable to mean explicitly zero.
|
||||
if req.GetBody != nil && req.ContentLength == 0 {
|
||||
req.Body = NoBody
|
||||
req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
|
||||
}
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
|
||||
func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
|
||||
s1 := strings.Index(line, " ")
|
||||
|
||||
Reference in New Issue
Block a user