mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 18:13:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package httpbinding
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	contentLengthHeader = "Content-Length"
 | 
						|
	floatNaN            = "NaN"
 | 
						|
	floatInfinity       = "Infinity"
 | 
						|
	floatNegInfinity    = "-Infinity"
 | 
						|
)
 | 
						|
 | 
						|
// An Encoder provides encoding of REST URI path, query, and header components
 | 
						|
// of an HTTP request. Can also encode a stream as the payload.
 | 
						|
//
 | 
						|
// Does not support SetFields.
 | 
						|
type Encoder struct {
 | 
						|
	path, rawPath, pathBuffer []byte
 | 
						|
 | 
						|
	query  url.Values
 | 
						|
	header http.Header
 | 
						|
}
 | 
						|
 | 
						|
// NewEncoder creates a new encoder from the passed in request. All query and
 | 
						|
// header values will be added on top of the request's existing values. Overwriting
 | 
						|
// duplicate values.
 | 
						|
func NewEncoder(path, query string, headers http.Header) (*Encoder, error) {
 | 
						|
	parseQuery, err := url.ParseQuery(query)
 | 
						|
	if err != nil {
 | 
						|
		return nil, fmt.Errorf("failed to parse query string: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	e := &Encoder{
 | 
						|
		path:    []byte(path),
 | 
						|
		rawPath: []byte(path),
 | 
						|
		query:   parseQuery,
 | 
						|
		header:  headers.Clone(),
 | 
						|
	}
 | 
						|
 | 
						|
	return e, nil
 | 
						|
}
 | 
						|
 | 
						|
// Encode returns a REST protocol encoder for encoding HTTP bindings.
 | 
						|
//
 | 
						|
// Due net/http requiring `Content-Length` to be specified on the http.Request#ContentLength directly. Encode
 | 
						|
// will look for whether the header is present, and if so will remove it and set the respective value on http.Request.
 | 
						|
//
 | 
						|
// Returns any error occurring during encoding.
 | 
						|
func (e *Encoder) Encode(req *http.Request) (*http.Request, error) {
 | 
						|
	req.URL.Path, req.URL.RawPath = string(e.path), string(e.rawPath)
 | 
						|
	req.URL.RawQuery = e.query.Encode()
 | 
						|
 | 
						|
	// net/http ignores Content-Length header and requires it to be set on http.Request
 | 
						|
	if v := e.header.Get(contentLengthHeader); len(v) > 0 {
 | 
						|
		iv, err := strconv.ParseInt(v, 10, 64)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		req.ContentLength = iv
 | 
						|
		e.header.Del(contentLengthHeader)
 | 
						|
	}
 | 
						|
 | 
						|
	req.Header = e.header
 | 
						|
 | 
						|
	return req, nil
 | 
						|
}
 | 
						|
 | 
						|
// AddHeader returns a HeaderValue for appending to the given header name
 | 
						|
func (e *Encoder) AddHeader(key string) HeaderValue {
 | 
						|
	return newHeaderValue(e.header, key, true)
 | 
						|
}
 | 
						|
 | 
						|
// SetHeader returns a HeaderValue for setting the given header name
 | 
						|
func (e *Encoder) SetHeader(key string) HeaderValue {
 | 
						|
	return newHeaderValue(e.header, key, false)
 | 
						|
}
 | 
						|
 | 
						|
// Headers returns a Header used for encoding headers with the given prefix
 | 
						|
func (e *Encoder) Headers(prefix string) Headers {
 | 
						|
	return Headers{
 | 
						|
		header: e.header,
 | 
						|
		prefix: strings.TrimSpace(prefix),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// HasHeader returns if a header with the key specified exists with one or
 | 
						|
// more value.
 | 
						|
func (e Encoder) HasHeader(key string) bool {
 | 
						|
	return len(e.header[key]) != 0
 | 
						|
}
 | 
						|
 | 
						|
// SetURI returns a URIValue used for setting the given path key
 | 
						|
func (e *Encoder) SetURI(key string) URIValue {
 | 
						|
	return newURIValue(&e.path, &e.rawPath, &e.pathBuffer, key)
 | 
						|
}
 | 
						|
 | 
						|
// SetQuery returns a QueryValue used for setting the given query key
 | 
						|
func (e *Encoder) SetQuery(key string) QueryValue {
 | 
						|
	return NewQueryValue(e.query, key, false)
 | 
						|
}
 | 
						|
 | 
						|
// AddQuery returns a QueryValue used for appending the given query key
 | 
						|
func (e *Encoder) AddQuery(key string) QueryValue {
 | 
						|
	return NewQueryValue(e.query, key, true)
 | 
						|
}
 | 
						|
 | 
						|
// HasQuery returns if a query with the key specified exists with one or
 | 
						|
// more values.
 | 
						|
func (e *Encoder) HasQuery(key string) bool {
 | 
						|
	return len(e.query.Get(key)) != 0
 | 
						|
}
 |