initial commit
This commit is contained in:
commit
ea253cbfb6
19
do.go
Normal file
19
do.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package ezhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Do(req *http.Request) (*http.Response, error) {
|
||||||
|
return http.DefaultClient.Do(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseJsonResponse[T any](r io.Reader) (*T, error) {
|
||||||
|
res := new(T)
|
||||||
|
if err := json.NewDecoder(r).Decode(res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
193
request.go
Normal file
193
request.go
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
package ezhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
urlpkg "net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestModifier func(r *RequestBuilder) *RequestBuilder
|
||||||
|
type ValueProvider[T any] func() T
|
||||||
|
type AuthProvider ValueProvider[string]
|
||||||
|
type RequestBodyProvider func() (io.Reader, string)
|
||||||
|
|
||||||
|
func Request(mods ...RequestModifier) (*http.Request, error) {
|
||||||
|
r := NewRequestBuilder()
|
||||||
|
for _, mod := range mods {
|
||||||
|
r = mod(r)
|
||||||
|
}
|
||||||
|
return r.Build()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Template(req *http.Request) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
return NewRequestBuilderFromRequest(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func URL(url string) RequestModifier {
|
||||||
|
parsedUrl, err := urlpkg.Parse(url)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.URL = parsedUrl
|
||||||
|
return r
|
||||||
|
//return Headers("Host", parsedUrl.Host)(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Scheme(scheme string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.URL.Scheme = scheme
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Host(host string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.URL.Host = host
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Path(path string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.URL.Path = path
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendPath(path ...string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.URL = r.URL.JoinPath(path...)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fragment(fragment string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.URL.Fragment = fragment
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Query(keyValuePairs ...string) RequestModifier {
|
||||||
|
if len(keyValuePairs)%2 != 0 {
|
||||||
|
panic("keyValuePairs must have an even length")
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
q := r.URL.Query()
|
||||||
|
for i := 0; i < len(keyValuePairs)-1; i += 2 {
|
||||||
|
q.Add(keyValuePairs[i], keyValuePairs[i+1])
|
||||||
|
}
|
||||||
|
r.URL.RawQuery = q.Encode()
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func QueryMap(query map[string]string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
q := r.URL.Query()
|
||||||
|
for key, value := range query {
|
||||||
|
q.Add(key, value)
|
||||||
|
}
|
||||||
|
r.URL.RawQuery = q.Encode()
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Method(method string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
r.Method = method
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Headers(keyValuePairs ...string) RequestModifier {
|
||||||
|
if len(keyValuePairs)%2 != 0 {
|
||||||
|
panic("keyValuePairs must have an even length")
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
for i := 0; i < len(keyValuePairs)-1; i += 2 {
|
||||||
|
r.Header.Add(keyValuePairs[i], keyValuePairs[i+1])
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HeadersMap(headers map[string]string) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
for key, value := range headers {
|
||||||
|
r.Header.Add(key, value)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Auth(auth AuthProvider) RequestModifier {
|
||||||
|
return Headers("Authentication", auth())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Basic(username, password string) AuthProvider {
|
||||||
|
return func() string {
|
||||||
|
return "Basic " + base64.StdEncoding.EncodeToString([]byte(username+":"+password))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bearer(token string) AuthProvider {
|
||||||
|
return func() string {
|
||||||
|
return "Bearer " + token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContentType(contentType string) RequestModifier {
|
||||||
|
return Headers("Content-Type", contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Body(bodyProvider RequestBodyProvider) RequestModifier {
|
||||||
|
return func(r *RequestBuilder) *RequestBuilder {
|
||||||
|
body, contentType := bodyProvider()
|
||||||
|
r.Body = body
|
||||||
|
if contentType != "" && r.Header.Get("Content-Type") != "" {
|
||||||
|
r.Header.Set("Content-Type", contentType)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Reader(r io.Reader) RequestBodyProvider {
|
||||||
|
return func() (io.Reader, string) {
|
||||||
|
return r, "application/octet-stream"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func String(s string) RequestBodyProvider {
|
||||||
|
return func() (io.Reader, string) {
|
||||||
|
return strings.NewReader(s), "text/plain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bytes(b []byte) RequestBodyProvider {
|
||||||
|
return func() (io.Reader, string) {
|
||||||
|
return bytes.NewReader(b), "application/octet-stream"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func JSON[T any](value T) RequestBodyProvider {
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
if err := json.NewEncoder(buf).Encode(value); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() (io.Reader, string) {
|
||||||
|
return buf, "application/json"
|
||||||
|
}
|
||||||
|
}
|
41
request_builder.go
Normal file
41
request_builder.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package ezhttp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
urlpkg "net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestBuilder struct {
|
||||||
|
URL *urlpkg.URL
|
||||||
|
Method string
|
||||||
|
Header http.Header
|
||||||
|
Body io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRequestBuilder() *RequestBuilder {
|
||||||
|
return &RequestBuilder{
|
||||||
|
URL: &urlpkg.URL{},
|
||||||
|
Header: make(http.Header),
|
||||||
|
Body: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRequestBuilderFromRequest(r *http.Request) *RequestBuilder {
|
||||||
|
return &RequestBuilder{
|
||||||
|
URL: r.URL,
|
||||||
|
Method: r.Method,
|
||||||
|
Header: r.Header,
|
||||||
|
Body: r.Body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *RequestBuilder) Build() (*http.Request, error) {
|
||||||
|
r, err := http.NewRequest(b.Method, b.URL.String(), b.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Header = b.Header
|
||||||
|
return r, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user