mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-22 04:50:43 -05:00
Compare commits
1 Commits
main
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2122e18505 |
2
go.mod
2
go.mod
@@ -34,7 +34,7 @@ require (
|
||||
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
|
||||
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
|
||||
github.com/go-playground/validator/v10 v10.30.1
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/go-resty/resty/v2 v2.17.1
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-cmp v0.7.0
|
||||
|
||||
5
go.sum
5
go.sum
@@ -461,8 +461,8 @@ github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
|
||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4=
|
||||
github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@@ -1464,7 +1464,6 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
|
||||
3
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
3
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
@@ -26,5 +26,6 @@ _testmain.go
|
||||
coverage.out
|
||||
coverage.txt
|
||||
|
||||
# Exclude intellij IDE folders
|
||||
# Exclude IDE folders
|
||||
.idea/*
|
||||
.vscode/*
|
||||
|
||||
17
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
17
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
@@ -1,5 +1,5 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
# gazelle:prefix github.com/go-resty/resty/v2
|
||||
# gazelle:go_naming_convention import_alias
|
||||
@@ -9,6 +9,7 @@ go_library(
|
||||
name = "resty",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"digest.go",
|
||||
"middleware.go",
|
||||
"redirect.go",
|
||||
"request.go",
|
||||
@@ -18,11 +19,17 @@ go_library(
|
||||
"trace.go",
|
||||
"transport.go",
|
||||
"transport112.go",
|
||||
"transport_js.go",
|
||||
"transport_other.go",
|
||||
"util.go",
|
||||
"util_curl.go",
|
||||
],
|
||||
importpath = "github.com/go-resty/resty/v2",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@org_golang_x_net//publicsuffix:go_default_library"],
|
||||
deps = [
|
||||
"//shellescape",
|
||||
"@org_golang_x_net//publicsuffix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
@@ -31,6 +38,7 @@ go_test(
|
||||
"client_test.go",
|
||||
"context_test.go",
|
||||
"example_test.go",
|
||||
"middleware_test.go",
|
||||
"request_test.go",
|
||||
"resty_test.go",
|
||||
"retry_test.go",
|
||||
@@ -38,7 +46,10 @@ go_test(
|
||||
],
|
||||
data = glob([".testdata/*"]),
|
||||
embed = [":resty"],
|
||||
deps = ["@org_golang_x_net//proxy:go_default_library"],
|
||||
deps = [
|
||||
"@org_golang_x_net//proxy:go_default_library",
|
||||
"@org_golang_x_time//rate:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
alias(
|
||||
|
||||
2
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
2
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2021 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
Copyright (c) 2015-2024 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
96
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
96
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
@@ -4,16 +4,12 @@
|
||||
<p align="center"><a href="#features">Features</a> section describes in detail about Resty capabilities</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.7.0-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<h4 align="center">Resty Communication Channels</h4>
|
||||
<p align="center"><a href="https://gitter.im/go_resty/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/go_resty/community.svg" alt="Chat on Gitter - Resty Community"></a> <a href="https://twitter.com/go_resty"><img src="https://img.shields.io/badge/twitter-@go__resty-55acee.svg" alt="Twitter @go_resty"></a></p>
|
||||
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Av2"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg?branch=v2" alt="Build Status"></a> <a href="https://app.codecov.io/gh/go-resty/resty/tree/v2"><img src="https://codecov.io/gh/go-resty/resty/branch/v2/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.17.1-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
|
||||
## News
|
||||
|
||||
* v2.7.0 [released](https://github.com/go-resty/resty/releases/tag/v2.7.0) and tagged on Nov 03, 2021.
|
||||
* v2.17.1 [released](https://github.com/go-resty/resty/releases/tag/v2.17.1) and tagged on Dec 15, 2025.
|
||||
* v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019.
|
||||
* v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019.
|
||||
* v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors).
|
||||
@@ -62,9 +58,10 @@
|
||||
* goroutine concurrent safe
|
||||
* Resty Client trace, see [Client.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableTrace) and [Request.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableTrace)
|
||||
* Since v2.4.0, trace info contains a `RequestAttempt` value, and the `Request` object contains an `Attempt` attribute
|
||||
* Supports on-demand CURL command generation, see [Client.EnableGenerateCurlOnDebug](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableGenerateCurlOnDebug), [Request.EnableGenerateCurlOnDebug](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableGenerateCurlOnDebug). It requires debug mode to be enabled.
|
||||
* Debug mode - clean and informative logging presentation
|
||||
* Gzip - Go does it automatically also resty has fallback handling too
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`, also `HTTP/3` can be used with Resty, see this [comment](https://github.com/go-resty/resty/issues/846#issuecomment-2329696110)
|
||||
* [Bazel support](#bazel-support)
|
||||
* Easily mock Resty for testing, [for e.g.](#mocking-http-requests-using-httpmock-library)
|
||||
* Well tested client library
|
||||
@@ -86,6 +83,8 @@
|
||||
|
||||
#### Supported Go Versions
|
||||
|
||||
Recommended to use `go1.23` and above.
|
||||
|
||||
Initially Resty started supporting `go modules` since `v1.10.0` release.
|
||||
|
||||
Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports:
|
||||
@@ -99,8 +98,6 @@ Starting Resty v2 and higher versions, it fully embraces [go modules](https://gi
|
||||
|
||||
Resty author also published following projects for Go Community.
|
||||
|
||||
* [aah framework](https://aahframework.org) - A secure, flexible, rapid Go web framework.
|
||||
* [THUMBAI](https://thumbai.app) - Go Mod Repository, Go Vanity Service and Simple Proxy Server.
|
||||
* [go-model](https://github.com/jeevatkm/go-model) - Robust & Easy to use model mapper and utility methods for Go `struct`.
|
||||
|
||||
|
||||
@@ -108,7 +105,7 @@ Resty author also published following projects for Go Community.
|
||||
|
||||
```bash
|
||||
# Go Modules
|
||||
require github.com/go-resty/resty/v2 v2.7.0
|
||||
require github.com/go-resty/resty/v2 v2.16.5
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -265,7 +262,7 @@ resp, err := client.R().
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST of raw bytes for file upload. For example: upload file to Dropbox
|
||||
fileBytes, _ := ioutil.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
|
||||
// See we are not setting content-type header, since go-resty automatically detects Content-Type for you
|
||||
resp, err := client.R().
|
||||
@@ -369,13 +366,13 @@ import jsoniter "github.com/json-iterator/go"
|
||||
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
client := resty.New()
|
||||
client.JSONMarshal = json.Marshal
|
||||
client.JSONUnmarshal = json.Unmarshal
|
||||
client := resty.New().
|
||||
SetJSONMarshaler(json.Marshal).
|
||||
SetJSONUnmarshaler(json.Unmarshal)
|
||||
|
||||
// similarly user could do for XML too with -
|
||||
client.XMLMarshal
|
||||
client.XMLUnmarshal
|
||||
client.SetXMLMarshaler(xml.Marshal).
|
||||
SetXMLUnmarshaler(xml.Unmarshal)
|
||||
```
|
||||
|
||||
### Multipart File(s) upload
|
||||
@@ -383,8 +380,8 @@ client.XMLUnmarshal
|
||||
#### Using io.Reader
|
||||
|
||||
```go
|
||||
profileImgBytes, _ := ioutil.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := ioutil.ReadFile("/Users/jeeva/text-file.txt")
|
||||
profileImgBytes, _ := os.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := os.ReadFile("/Users/jeeva/text-file.txt")
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
@@ -475,7 +472,7 @@ resp, err := client.R().
|
||||
client := resty.New()
|
||||
|
||||
// Setting output directory path, If directory not exists then resty creates one!
|
||||
// This is optional one, if you're planning using absoule path in
|
||||
// This is optional one, if you're planning using absolute path in
|
||||
// `Request.SetOutput` and can used together.
|
||||
client.SetOutputDirectory("/Users/jeeva/Downloads")
|
||||
|
||||
@@ -556,6 +553,30 @@ client.OnError(func(req *resty.Request, err error) {
|
||||
})
|
||||
```
|
||||
|
||||
#### Generate CURL Command
|
||||
>Refer: [curl_cmd_test.go](https://github.com/go-resty/resty/blob/v2/curl_cmd_test.go)
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
SetDebug(true).
|
||||
EnableGenerateCurlOnDebug(). // CURL command generated when debug mode enabled with this option
|
||||
SetBody(map[string]string{"name": "Alex"}).
|
||||
Post("https://httpbin.org/post")
|
||||
|
||||
curlCmdExecuted := resp.Request.GenerateCurlCommand()
|
||||
|
||||
// Explore curl command
|
||||
fmt.Println("Curl Command:\n ", curlCmdExecuted+"\n")
|
||||
|
||||
/* Output
|
||||
Curl Command:
|
||||
curl -X POST -H 'Content-Type: application/json' -H 'User-Agent: go-resty/2.14.0 (https://github.com/go-resty/resty)' -d '{"name":"Alex"}' https://httpbin.org/post
|
||||
*/
|
||||
```
|
||||
|
||||
#### Redirect Policy
|
||||
|
||||
Resty provides few ready to use redirect policy(s) also it supports multiple policies together.
|
||||
@@ -635,7 +656,7 @@ client.SetCertificates(cert1, cert2, cert3)
|
||||
|
||||
```go
|
||||
// Custom Root certificates from string
|
||||
// You can pass you certificates throught env variables as strings
|
||||
// You can pass you certificates through env variables as strings
|
||||
// you can add one or more root certificates, its get appended
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
@@ -654,7 +675,7 @@ if err != nil {
|
||||
client.SetCertificates(cert1, cert2, cert3)
|
||||
```
|
||||
|
||||
#### Proxy Settings - Client as well as at Request Level
|
||||
#### Proxy Settings
|
||||
|
||||
Default `Go` supports Proxy via environment variable `HTTP_PROXY`. Resty provides support via `SetProxy` & `RemoveProxy`.
|
||||
Choose as per your need.
|
||||
@@ -700,8 +721,9 @@ client.
|
||||
})
|
||||
```
|
||||
|
||||
Above setup will result in resty retrying requests returned non nil error up to
|
||||
3 times with delay increased after each attempt.
|
||||
By default, resty will retry requests that return a non-nil error during execution.
|
||||
Therefore, the above setup will result in resty retrying requests with non-nil errors up to 3 times,
|
||||
with the delay increasing after each attempt.
|
||||
|
||||
You can optionally provide client with [custom retry conditions](https://pkg.go.dev/github.com/go-resty/resty/v2#RetryConditionFunc):
|
||||
|
||||
@@ -718,10 +740,26 @@ client.AddRetryCondition(
|
||||
)
|
||||
```
|
||||
|
||||
Above example will make resty retry requests ended with `429 Too Many Requests`
|
||||
status code.
|
||||
The above example will make resty retry requests that end with a `429 Too Many Requests` status code.
|
||||
It's important to note that when you specify conditions using `AddRetryCondition`,
|
||||
it will override the default retry behavior, which retries on errors encountered during the request.
|
||||
If you want to retry on errors encountered during the request, similar to the default behavior,
|
||||
you'll need to configure it as follows:
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
client.AddRetryCondition(
|
||||
func(r *resty.Response, err error) bool {
|
||||
// Including "err != nil" emulates the default retry behavior for errors encountered during the request.
|
||||
return err != nil || r.StatusCode() == http.StatusTooManyRequests
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Multiple retry conditions can be added.
|
||||
Note that if multiple conditions are specified, a retry will occur if any of the conditions are met.
|
||||
|
||||
It is also possible to use `resty.Backoff(...)` to get arbitrary retry scenarios
|
||||
implemented. [Reference](retry_test.go).
|
||||
@@ -778,7 +816,7 @@ client.SetTimeout(1 * time.Minute)
|
||||
// You can override all below settings and options at request level if you want to
|
||||
//--------------------------------------------------------------------------------
|
||||
// Host URL for all request. So you can use relative URL in the request
|
||||
client.SetHostURL("http://httpbin.org")
|
||||
client.SetBaseURL("http://httpbin.org")
|
||||
|
||||
// Headers for all request
|
||||
client.SetHeader("Accept", "application/json")
|
||||
@@ -803,7 +841,7 @@ client.SetCookies(cookies)
|
||||
client.SetQueryParam("user_id", "00001")
|
||||
client.SetQueryParams(map[string]string{ // sample of those who use this manner
|
||||
"api_key": "api-key-here",
|
||||
"api_secert": "api-secert",
|
||||
"api_secret": "api-secret",
|
||||
})
|
||||
client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")
|
||||
|
||||
@@ -842,10 +880,10 @@ client := resty.New()
|
||||
|
||||
// Set the previous transport that we created, set the scheme of the communication to the
|
||||
// socket and set the unixSocket as the HostURL.
|
||||
client.SetTransport(&transport).SetScheme("http").SetHostURL(unixSocket)
|
||||
client.SetTransport(&transport).SetScheme("http").SetBaseURL(unixSocket)
|
||||
|
||||
// No need to write the host's URL on the request, just the path.
|
||||
client.R().Get("/index.html")
|
||||
client.R().Get("http://localhost/index.html")
|
||||
```
|
||||
|
||||
#### Bazel Support
|
||||
|
||||
8
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
8
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
@@ -4,10 +4,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "69de5c704a05ff37862f7e0f5534d4f479418afc21806c887db544a316f3cb6b",
|
||||
sha256 = "80a98277ad1311dacd837f9b16db62887702e9f1d1c4c9f796d0121a46c8e184",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
||||
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(version = "1.16")
|
||||
go_register_toolchains(version = "1.19")
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
||||
|
||||
|
||||
1071
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
1071
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
327
vendor/github.com/go-resty/resty/v2/digest.go
generated
vendored
Normal file
327
vendor/github.com/go-resty/resty/v2/digest.go
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com)
|
||||
// 2023 Segev Dagan (https://github.com/segevda)
|
||||
// 2024 Philipp Wolfer (https://github.com/phw)
|
||||
// All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDigestBadChallenge = errors.New("digest: challenge is bad")
|
||||
ErrDigestCharset = errors.New("digest: unsupported charset")
|
||||
ErrDigestAlgNotSupported = errors.New("digest: algorithm is not supported")
|
||||
ErrDigestQopNotSupported = errors.New("digest: no supported qop in list")
|
||||
ErrDigestNoQop = errors.New("digest: qop must be specified")
|
||||
)
|
||||
|
||||
var hashFuncs = map[string]func() hash.Hash{
|
||||
"": md5.New,
|
||||
"MD5": md5.New,
|
||||
"MD5-sess": md5.New,
|
||||
"SHA-256": sha256.New,
|
||||
"SHA-256-sess": sha256.New,
|
||||
"SHA-512-256": sha512.New,
|
||||
"SHA-512-256-sess": sha512.New,
|
||||
}
|
||||
|
||||
type digestCredentials struct {
|
||||
username, password string
|
||||
}
|
||||
|
||||
type digestTransport struct {
|
||||
digestCredentials
|
||||
transport http.RoundTripper
|
||||
}
|
||||
|
||||
func (dt *digestTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
// Copy the request, so we don't modify the input.
|
||||
req2 := new(http.Request)
|
||||
*req2 = *req
|
||||
req2.Header = make(http.Header)
|
||||
for k, s := range req.Header {
|
||||
req2.Header[k] = s
|
||||
}
|
||||
|
||||
// Fix http: ContentLength=xxx with Body length 0
|
||||
if req2.Body == nil {
|
||||
req2.ContentLength = 0
|
||||
} else if req2.GetBody != nil {
|
||||
var err error
|
||||
req2.Body, err = req2.GetBody()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Make a request to get the 401 that contains the challenge.
|
||||
resp, err := dt.transport.RoundTrip(req)
|
||||
if err != nil || resp.StatusCode != http.StatusUnauthorized {
|
||||
return resp, err
|
||||
}
|
||||
chal := resp.Header.Get(hdrWwwAuthenticateKey)
|
||||
if chal == "" {
|
||||
return resp, ErrDigestBadChallenge
|
||||
}
|
||||
|
||||
c, err := parseChallenge(chal)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Form credentials based on the challenge
|
||||
cr := dt.newCredentials(req2, c)
|
||||
auth, err := cr.authorize()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Make authenticated request
|
||||
req2.Header.Set(hdrAuthorizationKey, auth)
|
||||
return dt.transport.RoundTrip(req2)
|
||||
}
|
||||
|
||||
func (dt *digestTransport) newCredentials(req *http.Request, c *challenge) *credentials {
|
||||
return &credentials{
|
||||
username: dt.username,
|
||||
userhash: c.userhash,
|
||||
realm: c.realm,
|
||||
nonce: c.nonce,
|
||||
digestURI: req.URL.RequestURI(),
|
||||
algorithm: c.algorithm,
|
||||
sessionAlg: strings.HasSuffix(c.algorithm, "-sess"),
|
||||
opaque: c.opaque,
|
||||
messageQop: c.qop,
|
||||
nc: 0,
|
||||
method: req.Method,
|
||||
password: dt.password,
|
||||
}
|
||||
}
|
||||
|
||||
type challenge struct {
|
||||
realm string
|
||||
domain string
|
||||
nonce string
|
||||
opaque string
|
||||
stale string
|
||||
algorithm string
|
||||
qop string
|
||||
userhash string
|
||||
}
|
||||
|
||||
func (c *challenge) setValue(k, v string) error {
|
||||
switch k {
|
||||
case "realm":
|
||||
c.realm = v
|
||||
case "domain":
|
||||
c.domain = v
|
||||
case "nonce":
|
||||
c.nonce = v
|
||||
case "opaque":
|
||||
c.opaque = v
|
||||
case "stale":
|
||||
c.stale = v
|
||||
case "algorithm":
|
||||
c.algorithm = v
|
||||
case "qop":
|
||||
c.qop = v
|
||||
case "charset":
|
||||
if strings.ToUpper(v) != "UTF-8" {
|
||||
return ErrDigestCharset
|
||||
}
|
||||
case "userhash":
|
||||
c.userhash = v
|
||||
default:
|
||||
return ErrDigestBadChallenge
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseChallenge(input string) (*challenge, error) {
|
||||
const ws = " \n\r\t"
|
||||
s := strings.Trim(input, ws)
|
||||
if !strings.HasPrefix(s, "Digest ") {
|
||||
return nil, ErrDigestBadChallenge
|
||||
}
|
||||
s = strings.Trim(s[7:], ws)
|
||||
c := &challenge{}
|
||||
b := strings.Builder{}
|
||||
key := ""
|
||||
quoted := false
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case '"':
|
||||
quoted = !quoted
|
||||
case ',':
|
||||
if quoted {
|
||||
b.WriteRune(r)
|
||||
} else {
|
||||
val := strings.Trim(b.String(), ws)
|
||||
b.Reset()
|
||||
if err := c.setValue(key, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = ""
|
||||
}
|
||||
case '=':
|
||||
if quoted {
|
||||
b.WriteRune(r)
|
||||
} else {
|
||||
key = strings.Trim(b.String(), ws)
|
||||
b.Reset()
|
||||
}
|
||||
default:
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
if quoted || (key == "" && b.Len() > 0) {
|
||||
return nil, ErrDigestBadChallenge
|
||||
}
|
||||
if key != "" {
|
||||
val := strings.Trim(b.String(), ws)
|
||||
if err := c.setValue(key, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type credentials struct {
|
||||
username string
|
||||
userhash string
|
||||
realm string
|
||||
nonce string
|
||||
digestURI string
|
||||
algorithm string
|
||||
sessionAlg bool
|
||||
cNonce string
|
||||
opaque string
|
||||
messageQop string
|
||||
nc int
|
||||
method string
|
||||
password string
|
||||
}
|
||||
|
||||
func (c *credentials) authorize() (string, error) {
|
||||
if _, ok := hashFuncs[c.algorithm]; !ok {
|
||||
return "", ErrDigestAlgNotSupported
|
||||
}
|
||||
|
||||
if err := c.validateQop(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := c.resp()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sl := make([]string, 0, 10)
|
||||
if c.userhash == "true" {
|
||||
// RFC 7616 3.4.4
|
||||
c.username = c.h(fmt.Sprintf("%s:%s", c.username, c.realm))
|
||||
sl = append(sl, fmt.Sprintf(`userhash=%s`, c.userhash))
|
||||
}
|
||||
sl = append(sl, fmt.Sprintf(`username="%s"`, c.username))
|
||||
sl = append(sl, fmt.Sprintf(`realm="%s"`, c.realm))
|
||||
sl = append(sl, fmt.Sprintf(`nonce="%s"`, c.nonce))
|
||||
sl = append(sl, fmt.Sprintf(`uri="%s"`, c.digestURI))
|
||||
sl = append(sl, fmt.Sprintf(`response="%s"`, resp))
|
||||
sl = append(sl, fmt.Sprintf(`algorithm=%s`, c.algorithm))
|
||||
if c.opaque != "" {
|
||||
sl = append(sl, fmt.Sprintf(`opaque="%s"`, c.opaque))
|
||||
}
|
||||
if c.messageQop != "" {
|
||||
sl = append(sl, fmt.Sprintf("qop=%s", c.messageQop))
|
||||
sl = append(sl, fmt.Sprintf("nc=%08x", c.nc))
|
||||
sl = append(sl, fmt.Sprintf(`cnonce="%s"`, c.cNonce))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Digest %s", strings.Join(sl, ", ")), nil
|
||||
}
|
||||
|
||||
func (c *credentials) validateQop() error {
|
||||
// Currently only supporting auth quality of protection. TODO: add auth-int support
|
||||
// NOTE: cURL support auth-int qop for requests other than POST and PUT (i.e. w/o body) by hashing an empty string
|
||||
// is this applicable for resty? see: https://github.com/curl/curl/blob/307b7543ea1e73ab04e062bdbe4b5bb409eaba3a/lib/vauth/digest.c#L774
|
||||
if c.messageQop == "" {
|
||||
return ErrDigestNoQop
|
||||
}
|
||||
possibleQops := strings.Split(c.messageQop, ",")
|
||||
var authSupport bool
|
||||
for _, qop := range possibleQops {
|
||||
qop = strings.TrimSpace(qop)
|
||||
if qop == "auth" {
|
||||
authSupport = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !authSupport {
|
||||
return ErrDigestQopNotSupported
|
||||
}
|
||||
|
||||
c.messageQop = "auth"
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *credentials) h(data string) string {
|
||||
hfCtor := hashFuncs[c.algorithm]
|
||||
hf := hfCtor()
|
||||
_, _ = hf.Write([]byte(data)) // Hash.Write never returns an error
|
||||
return fmt.Sprintf("%x", hf.Sum(nil))
|
||||
}
|
||||
|
||||
func (c *credentials) resp() (string, error) {
|
||||
c.nc++
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := io.ReadFull(rand.Reader, b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c.cNonce = fmt.Sprintf("%x", b)[:32]
|
||||
|
||||
ha1 := c.ha1()
|
||||
ha2 := c.ha2()
|
||||
|
||||
return c.kd(ha1, fmt.Sprintf("%s:%08x:%s:%s:%s",
|
||||
c.nonce, c.nc, c.cNonce, c.messageQop, ha2)), nil
|
||||
}
|
||||
|
||||
func (c *credentials) kd(secret, data string) string {
|
||||
return c.h(fmt.Sprintf("%s:%s", secret, data))
|
||||
}
|
||||
|
||||
// RFC 7616 3.4.2
|
||||
func (c *credentials) ha1() string {
|
||||
ret := c.h(fmt.Sprintf("%s:%s:%s", c.username, c.realm, c.password))
|
||||
if c.sessionAlg {
|
||||
return c.h(fmt.Sprintf("%s:%s:%s", ret, c.nonce, c.cNonce))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// RFC 7616 3.4.3
|
||||
func (c *credentials) ha2() string {
|
||||
// currently no auth-int support
|
||||
return c.h(fmt.Sprintf("%s:%s", c.method, c.digestURI))
|
||||
}
|
||||
416
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
416
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -27,15 +27,76 @@ const debugRequestLogKey = "__restyDebugRequestLog"
|
||||
//_______________________________________________________________________
|
||||
|
||||
func parseRequestURL(c *Client, r *Request) error {
|
||||
// GitHub #103 Path Params
|
||||
if len(r.PathParams) > 0 {
|
||||
if l := len(c.PathParams) + len(c.RawPathParams) + len(r.PathParams) + len(r.RawPathParams); l > 0 {
|
||||
params := make(map[string]string, l)
|
||||
|
||||
// GitHub #103 Path Params
|
||||
for p, v := range r.PathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
params[p] = url.PathEscape(v)
|
||||
}
|
||||
}
|
||||
if len(c.PathParams) > 0 {
|
||||
for p, v := range c.PathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = url.PathEscape(v)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #663 Raw Path Params
|
||||
for p, v := range r.RawPathParams {
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = v
|
||||
}
|
||||
}
|
||||
for p, v := range c.RawPathParams {
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = v
|
||||
}
|
||||
}
|
||||
|
||||
if len(params) > 0 {
|
||||
var prev int
|
||||
buf := acquireBuffer()
|
||||
defer releaseBuffer(buf)
|
||||
// search for the next or first opened curly bracket
|
||||
for curr := strings.Index(r.URL, "{"); curr == 0 || curr >= prev; curr = prev + strings.Index(r.URL[prev:], "{") {
|
||||
// write everything from the previous position up to the current
|
||||
if curr > prev {
|
||||
buf.WriteString(r.URL[prev:curr])
|
||||
}
|
||||
// search for the closed curly bracket from current position
|
||||
next := curr + strings.Index(r.URL[curr:], "}")
|
||||
// if not found, then write the remainder and exit
|
||||
if next < curr {
|
||||
buf.WriteString(r.URL[curr:])
|
||||
prev = len(r.URL)
|
||||
break
|
||||
}
|
||||
// special case for {}, without parameter's name
|
||||
if next == curr+1 {
|
||||
buf.WriteString("{}")
|
||||
} else {
|
||||
// check for the replacement
|
||||
key := r.URL[curr+1 : next]
|
||||
value, ok := params[key]
|
||||
/// keep the original string if the replacement not found
|
||||
if !ok {
|
||||
value = r.URL[curr : next+1]
|
||||
}
|
||||
buf.WriteString(value)
|
||||
}
|
||||
|
||||
// set the previous position after the closed curly bracket
|
||||
prev = next + 1
|
||||
if prev >= len(r.URL) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if buf.Len() > 0 {
|
||||
// write remainder
|
||||
if prev < len(r.URL) {
|
||||
buf.WriteString(r.URL[prev:])
|
||||
}
|
||||
r.URL = buf.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +114,12 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
r.URL = "/" + r.URL
|
||||
}
|
||||
|
||||
reqURL, err = url.Parse(c.HostURL + r.URL)
|
||||
// TODO: change to use c.BaseURL only in v3.0.0
|
||||
baseURL := c.BaseURL
|
||||
if len(baseURL) == 0 {
|
||||
baseURL = c.HostURL
|
||||
}
|
||||
reqURL, err = url.Parse(baseURL + r.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,33 +131,36 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
}
|
||||
|
||||
// Adding Query Param
|
||||
query := make(url.Values)
|
||||
for k, v := range c.QueryParam {
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
if len(c.QueryParam)+len(r.QueryParam) > 0 {
|
||||
for k, v := range c.QueryParam {
|
||||
// skip query parameter if it was set in request
|
||||
if _, ok := r.QueryParam[k]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
r.QueryParam[k] = v[:]
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(r.QueryParam) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = r.QueryParam.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + r.QueryParam.Encode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range r.QueryParam {
|
||||
// remove query param from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
query.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(query) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = query.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode()
|
||||
}
|
||||
// GH#797 Unescape query parameters
|
||||
if r.unescapeQueryParams && len(reqURL.RawQuery) > 0 {
|
||||
// at this point, all errors caught up in the above operations
|
||||
// so ignore the return error on query unescape; I realized
|
||||
// while writing the unit test
|
||||
unescapedQuery, _ := url.QueryUnescape(reqURL.RawQuery)
|
||||
reqURL.RawQuery = strings.ReplaceAll(unescapedQuery, " ", "+") // otherwise request becomes bad request
|
||||
}
|
||||
|
||||
r.URL = reqURL.String()
|
||||
@@ -100,71 +169,61 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
}
|
||||
|
||||
func parseRequestHeader(c *Client, r *Request) error {
|
||||
hdr := make(http.Header)
|
||||
for k := range c.Header {
|
||||
hdr[k] = append(hdr[k], c.Header[k]...)
|
||||
for k, v := range c.Header {
|
||||
if _, ok := r.Header[k]; ok {
|
||||
continue
|
||||
}
|
||||
r.Header[k] = v[:]
|
||||
}
|
||||
|
||||
for k := range r.Header {
|
||||
hdr.Del(k)
|
||||
hdr[k] = append(hdr[k], r.Header[k]...)
|
||||
if IsStringEmpty(r.Header.Get(hdrUserAgentKey)) {
|
||||
r.Header.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
}
|
||||
|
||||
if IsStringEmpty(hdr.Get(hdrUserAgentKey)) {
|
||||
hdr.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
if ct := r.Header.Get(hdrContentTypeKey); IsStringEmpty(r.Header.Get(hdrAcceptKey)) && !IsStringEmpty(ct) && (IsJSONType(ct) || IsXMLType(ct)) {
|
||||
r.Header.Set(hdrAcceptKey, r.Header.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
ct := hdr.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(hdr.Get(hdrAcceptKey)) && !IsStringEmpty(ct) &&
|
||||
(IsJSONType(ct) || IsXMLType(ct)) {
|
||||
hdr.Set(hdrAcceptKey, hdr.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
r.Header = hdr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRequestBody(c *Client, r *Request) (err error) {
|
||||
func parseRequestBody(c *Client, r *Request) error {
|
||||
if isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
// Handling Multipart
|
||||
if r.isMultiPart && !(r.Method == MethodPatch) {
|
||||
if err = handleMultipart(c, r); err != nil {
|
||||
return
|
||||
switch {
|
||||
case r.isMultiPart: // Handling Multipart
|
||||
if err := handleMultipart(c, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Form Data
|
||||
if len(c.FormData) > 0 || len(r.FormData) > 0 {
|
||||
case len(c.FormData) > 0 || len(r.FormData) > 0: // Handling Form Data
|
||||
handleFormData(c, r)
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Request body
|
||||
if r.Body != nil {
|
||||
case r.Body == nil && r.bodyBuf == nil: // Handling Request body when nil body
|
||||
// Go http library omits Content-Length if body is nil; use http.NoBody to force it if SetContentLength is true
|
||||
r.Body = http.NoBody
|
||||
fallthrough
|
||||
case r.Body != nil: // Handling Request body
|
||||
handleContentType(c, r)
|
||||
|
||||
if err = handleRequestBody(c, r); err != nil {
|
||||
return
|
||||
if err := handleRequestBody(c, r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CL:
|
||||
// by default resty won't set content length, you can if you want to :)
|
||||
if (c.setContentLength || r.setContentLength) && r.bodyBuf != nil {
|
||||
r.Header.Set(hdrContentLengthKey, fmt.Sprintf("%d", r.bodyBuf.Len()))
|
||||
if c.setContentLength || r.setContentLength {
|
||||
if r.bodyBuf == nil {
|
||||
r.Header.Set(hdrContentLengthKey, "0")
|
||||
} else {
|
||||
r.Header.Set(hdrContentLengthKey, strconv.Itoa(r.bodyBuf.Len()))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
if r.bodyBuf == nil {
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
if reader, ok := r.Body.(io.Reader); ok && isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, reader)
|
||||
} else if c.setContentLength || r.setContentLength {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, http.NoBody)
|
||||
@@ -172,7 +231,9 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil)
|
||||
}
|
||||
} else {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf)
|
||||
// fix data race: must deep copy.
|
||||
bodyBuf := bytes.NewBuffer(append([]byte{}, r.bodyBuf.Bytes()...))
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, bodyBuf)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -206,17 +267,19 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
r.RawRequest = r.RawRequest.WithContext(r.ctx)
|
||||
}
|
||||
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// assign get body func for the underlying raw request instance
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
if bodyCopy != nil {
|
||||
return ioutil.NopCloser(bytes.NewReader(bodyCopy.Bytes())), nil
|
||||
if r.RawRequest.GetBody == nil {
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bodyCopy != nil {
|
||||
buf := bodyCopy.Bytes()
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
b := bytes.NewReader(buf)
|
||||
return io.NopCloser(b), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return
|
||||
@@ -235,43 +298,60 @@ func addCredentials(c *Client, r *Request) error {
|
||||
|
||||
if !c.DisableWarn {
|
||||
if isBasicAuth && !strings.HasPrefix(r.URL, "https") {
|
||||
c.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
r.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Authorization Header Scheme
|
||||
var authScheme string
|
||||
if !IsStringEmpty(r.AuthScheme) {
|
||||
authScheme = r.AuthScheme
|
||||
} else if !IsStringEmpty(c.AuthScheme) {
|
||||
authScheme = c.AuthScheme
|
||||
} else {
|
||||
authScheme = "Bearer"
|
||||
// Build the token Auth header
|
||||
if !IsStringEmpty(r.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, strings.TrimSpace(r.AuthScheme+" "+r.Token))
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, strings.TrimSpace(r.AuthScheme+" "+c.Token))
|
||||
}
|
||||
|
||||
// Build the Token Auth header
|
||||
if !IsStringEmpty(r.Token) { // takes precedence
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+r.Token)
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+c.Token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func createCurlCmd(c *Client, r *Request) (err error) {
|
||||
if r.Debug && r.generateCurlOnDebug {
|
||||
if r.resultCurlCmd == nil {
|
||||
r.resultCurlCmd = new(string)
|
||||
}
|
||||
*r.resultCurlCmd = buildCurlRequest(r.RawRequest, c.httpClient.Jar)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func requestLogger(c *Client, r *Request) error {
|
||||
if c.Debug {
|
||||
if r.Debug {
|
||||
rr := r.RawRequest
|
||||
rl := &RequestLog{Header: copyHeaders(rr.Header), Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
rh := copyHeaders(rr.Header)
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, cookie := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
s := fmt.Sprintf("%s=%s", cookie.Name, cookie.Value)
|
||||
if c := rh.Get("Cookie"); c != "" {
|
||||
rh.Set("Cookie", c+"; "+s)
|
||||
} else {
|
||||
rh.Set("Cookie", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
rl := &RequestLog{Header: rh, Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.requestLog != nil {
|
||||
if err := c.requestLog(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// fmt.Sprintf("COOKIES:\n%s\n", composeCookies(c.GetClient().Jar, *rr.URL)) +
|
||||
|
||||
reqLog := "\n==============================================================================\n" +
|
||||
"~~~ REQUEST ~~~\n" +
|
||||
reqLog := "\n==============================================================================\n"
|
||||
|
||||
if r.Debug && r.generateCurlOnDebug {
|
||||
reqLog += "~~~ REQUEST(CURL) ~~~\n" +
|
||||
fmt.Sprintf(" %v\n", *r.resultCurlCmd)
|
||||
}
|
||||
|
||||
reqLog += "~~~ REQUEST ~~~\n" +
|
||||
fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) +
|
||||
fmt.Sprintf("HOST : %s\n", rr.URL.Host) +
|
||||
fmt.Sprintf("HEADERS:\n%s\n", composeHeaders(c, r, rl.Header)) +
|
||||
@@ -290,7 +370,7 @@ func requestLogger(c *Client, r *Request) error {
|
||||
//_______________________________________________________________________
|
||||
|
||||
func responseLogger(c *Client, res *Response) error {
|
||||
if c.Debug {
|
||||
if res.Request.Debug {
|
||||
rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.responseLog != nil {
|
||||
if err := c.responseLog(rl); err != nil {
|
||||
@@ -301,7 +381,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
debugLog := res.Request.values[debugRequestLogKey].(string)
|
||||
debugLog += "~~~ RESPONSE ~~~\n" +
|
||||
fmt.Sprintf("STATUS : %s\n", res.Status()) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.RawResponse.Proto) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.Proto()) +
|
||||
fmt.Sprintf("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) +
|
||||
fmt.Sprintf("TIME DURATION: %v\n", res.Time()) +
|
||||
"HEADERS :\n" +
|
||||
@@ -313,7 +393,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
}
|
||||
debugLog += "==============================================================================\n"
|
||||
|
||||
c.log.Debugf("%s", debugLog)
|
||||
res.Request.log.Debugf("%s", debugLog)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -321,6 +401,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
|
||||
func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
if res.StatusCode() == http.StatusNoContent {
|
||||
res.Request.Error = nil
|
||||
return
|
||||
}
|
||||
// Handles only JSON or XML content type
|
||||
@@ -343,7 +424,10 @@ func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
}
|
||||
|
||||
if res.Request.Error != nil {
|
||||
err = Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
unmarshalErr := Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
if unmarshalErr != nil {
|
||||
c.log.Warnf("Cannot unmarshal response body: %s", unmarshalErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,13 +435,20 @@ func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func handleMultipart(c *Client, r *Request) (err error) {
|
||||
func handleMultipart(c *Client, r *Request) error {
|
||||
r.bodyBuf = acquireBuffer()
|
||||
w := multipart.NewWriter(r.bodyBuf)
|
||||
|
||||
// Set boundary if not set by user
|
||||
if r.multipartBoundary != "" {
|
||||
if err := w.SetBoundary(r.multipartBoundary); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
if err := w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -366,12 +457,11 @@ func handleMultipart(c *Client, r *Request) (err error) {
|
||||
for k, v := range r.FormData {
|
||||
for _, iv := range v {
|
||||
if strings.HasPrefix(k, "@") { // file
|
||||
err = addFile(w, k[1:], iv)
|
||||
if err != nil {
|
||||
return
|
||||
if err := addFile(w, k[1:], iv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else { // form value
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
if err := w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -379,55 +469,41 @@ func handleMultipart(c *Client, r *Request) (err error) {
|
||||
}
|
||||
|
||||
// #21 - adding io.Reader support
|
||||
if len(r.multipartFiles) > 0 {
|
||||
for _, f := range r.multipartFiles {
|
||||
err = addFileReader(w, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, f := range r.multipartFiles {
|
||||
if err := addFileReader(w, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #130 adding multipart field support with content type
|
||||
if len(r.multipartFields) > 0 {
|
||||
for _, mf := range r.multipartFields {
|
||||
if err = addMultipartFormField(w, mf); err != nil {
|
||||
return
|
||||
}
|
||||
for _, mf := range r.multipartFields {
|
||||
if err := addMultipartFormField(w, mf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Header.Set(hdrContentTypeKey, w.FormDataContentType())
|
||||
err = w.Close()
|
||||
|
||||
return
|
||||
return w.Close()
|
||||
}
|
||||
|
||||
func handleFormData(c *Client, r *Request) {
|
||||
formData := url.Values{}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
if _, ok := r.FormData[k]; ok {
|
||||
continue
|
||||
}
|
||||
r.FormData[k] = v[:]
|
||||
}
|
||||
|
||||
for k, v := range r.FormData {
|
||||
// remove form data field from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
formData.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
r.bodyBuf = bytes.NewBuffer([]byte(formData.Encode()))
|
||||
r.bodyBuf = acquireBuffer()
|
||||
r.bodyBuf.WriteString(r.FormData.Encode())
|
||||
r.Header.Set(hdrContentTypeKey, formContentType)
|
||||
r.isFormData = true
|
||||
}
|
||||
|
||||
func handleContentType(c *Client, r *Request) {
|
||||
if r.Body == http.NoBody {
|
||||
return
|
||||
}
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(contentType) {
|
||||
contentType = DetectContentType(r.Body)
|
||||
@@ -435,45 +511,42 @@ func handleContentType(c *Client, r *Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
func handleRequestBody(c *Client, r *Request) error {
|
||||
var bodyBytes []byte
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
r.bodyBuf = nil
|
||||
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
switch body := r.Body.(type) {
|
||||
case io.Reader:
|
||||
if c.setContentLength || r.setContentLength { // keep backward compatibility
|
||||
r.bodyBuf = acquireBuffer()
|
||||
_, err = r.bodyBuf.ReadFrom(reader)
|
||||
if _, err := r.bodyBuf.ReadFrom(body); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Body = nil
|
||||
} else {
|
||||
// Otherwise buffer less processing for `io.Reader`, sounds good.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
} else if b, ok := r.Body.([]byte); ok {
|
||||
bodyBytes = b
|
||||
} else if s, ok := r.Body.(string); ok {
|
||||
bodyBytes = []byte(s)
|
||||
} else if IsJSONType(contentType) &&
|
||||
(kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
r.bodyBuf, err = jsonMarshal(c, r, r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
case []byte:
|
||||
bodyBytes = body
|
||||
case string:
|
||||
bodyBytes = []byte(body)
|
||||
default:
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
var err error
|
||||
if IsJSONType(contentType) && (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
r.bodyBuf, err = jsonMarshal(c, r, r.Body)
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = c.XMLMarshal(r.Body)
|
||||
}
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = c.XMLMarshal(r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if bodyBytes == nil && r.bodyBuf == nil {
|
||||
err = errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// if any errors during body bytes handling, return it
|
||||
if err != nil {
|
||||
return
|
||||
return errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// []byte into Buffer
|
||||
@@ -482,7 +555,7 @@ func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
_, _ = r.bodyBuf.Write(bodyBytes)
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
@@ -521,20 +594,25 @@ func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
func getBodyCopy(r *Request) (*bytes.Buffer, error) {
|
||||
// If r.bodyBuf present, return the copy
|
||||
if r.bodyBuf != nil {
|
||||
return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
|
||||
bodyCopy := acquireBuffer()
|
||||
if _, err := io.Copy(bodyCopy, bytes.NewReader(r.bodyBuf.Bytes())); err != nil {
|
||||
// cannot use io.Copy(bodyCopy, r.bodyBuf) because io.Copy reset r.bodyBuf
|
||||
return nil, err
|
||||
}
|
||||
return bodyCopy, nil
|
||||
}
|
||||
|
||||
// Maybe body is `io.Reader`.
|
||||
// Note: Resty user have to watchout for large body size of `io.Reader`
|
||||
if r.RawRequest.Body != nil {
|
||||
b, err := ioutil.ReadAll(r.RawRequest.Body)
|
||||
b, err := io.ReadAll(r.RawRequest.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Restore the Body
|
||||
closeq(r.RawRequest.Body)
|
||||
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))
|
||||
r.RawRequest.Body = io.NopCloser(bytes.NewBuffer(b))
|
||||
|
||||
// Return the Body bytes
|
||||
return bytes.NewBuffer(b), nil
|
||||
|
||||
47
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
47
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -12,18 +12,23 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAutoRedirectDisabled = errors.New("auto redirect is disabled")
|
||||
)
|
||||
|
||||
type (
|
||||
// RedirectPolicy to regulate the redirects in the resty client.
|
||||
// Objects implementing the RedirectPolicy interface can be registered as
|
||||
// RedirectPolicy to regulate the redirects in the Resty client.
|
||||
// Objects implementing the [RedirectPolicy] interface can be registered as
|
||||
//
|
||||
// Apply function should return nil to continue the redirect jounery, otherwise
|
||||
// Apply function should return nil to continue the redirect journey; otherwise
|
||||
// return error to stop the redirect.
|
||||
RedirectPolicy interface {
|
||||
Apply(req *http.Request, via []*http.Request) error
|
||||
}
|
||||
|
||||
// The RedirectPolicyFunc type is an adapter to allow the use of ordinary functions as RedirectPolicy.
|
||||
// If f is a function with the appropriate signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls f.
|
||||
// The [RedirectPolicyFunc] type is an adapter to allow the use of ordinary
|
||||
// functions as [RedirectPolicy]. If `f` is a function with the appropriate
|
||||
// signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls `f`.
|
||||
RedirectPolicyFunc func(*http.Request, []*http.Request) error
|
||||
)
|
||||
|
||||
@@ -32,16 +37,18 @@ func (f RedirectPolicyFunc) Apply(req *http.Request, via []*http.Request) error
|
||||
return f(req, via)
|
||||
}
|
||||
|
||||
// NoRedirectPolicy is used to disable redirects in the HTTP client
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
// NoRedirectPolicy is used to disable redirects in the Resty client
|
||||
//
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
func NoRedirectPolicy() RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
return errors.New("auto redirect is disabled")
|
||||
return ErrAutoRedirectDisabled
|
||||
})
|
||||
}
|
||||
|
||||
// FlexibleRedirectPolicy is convenient method to create No of redirect policy for HTTP client.
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
// FlexibleRedirectPolicy method is convenient for creating several redirect policies for Resty clients.
|
||||
//
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= noOfRedirect {
|
||||
@@ -52,9 +59,10 @@ func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
})
|
||||
}
|
||||
|
||||
// DomainCheckRedirectPolicy is convenient method to define domain name redirect rule in resty client.
|
||||
// Redirect is allowed for only mentioned host in the policy.
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
// DomainCheckRedirectPolicy method is convenient for defining domain name redirect rules in Resty clients.
|
||||
// Redirect is allowed only for the host mentioned in the policy.
|
||||
//
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
hosts := make(map[string]bool)
|
||||
for _, h := range hostnames {
|
||||
@@ -72,10 +80,6 @@ func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
return fn
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func getHostname(host string) (hostname string) {
|
||||
if strings.Index(host, ":") > 0 {
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
@@ -84,10 +88,11 @@ func getHostname(host string) (hostname string) {
|
||||
return
|
||||
}
|
||||
|
||||
// By default Golang will not redirect request headers
|
||||
// after go throughing various discussion comments from thread
|
||||
// By default, Golang will not redirect request headers.
|
||||
// After reading through the various discussion comments from the thread -
|
||||
// https://github.com/golang/go/issues/4800
|
||||
// Resty will add all the headers during a redirect for the same host
|
||||
// Resty will add all the headers during a redirect for the same host and
|
||||
// adds library user-agent if the Host is different.
|
||||
func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {
|
||||
curHostname := getHostname(cur.URL.Host)
|
||||
preHostname := getHostname(pre.URL.Host)
|
||||
|
||||
865
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
865
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
File diff suppressed because it is too large
Load Diff
64
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
64
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// Response struct and methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Response struct holds response values of executed request.
|
||||
// Response struct holds response values of executed requests.
|
||||
type Response struct {
|
||||
Request *Request
|
||||
RawResponse *http.Response
|
||||
@@ -27,9 +27,10 @@ type Response struct {
|
||||
receivedAt time.Time
|
||||
}
|
||||
|
||||
// Body method returns HTTP response as []byte array for the executed request.
|
||||
// Body method returns the HTTP response as `[]byte` slice for the executed request.
|
||||
//
|
||||
// Note: `Response.Body` might be nil, if `Request.SetOutput` is used.
|
||||
// NOTE: [Response.Body] might be nil if [Request.SetOutput] is used.
|
||||
// Also see [Request.SetDoNotParseResponse], [Client.SetDoNotParseResponse]
|
||||
func (r *Response) Body() []byte {
|
||||
if r.RawResponse == nil {
|
||||
return []byte{}
|
||||
@@ -37,7 +38,18 @@ func (r *Response) Body() []byte {
|
||||
return r.body
|
||||
}
|
||||
|
||||
// SetBody method sets [Response] body in byte slice. Typically,
|
||||
// It is helpful for test cases.
|
||||
//
|
||||
// resp.SetBody([]byte("This is test body content"))
|
||||
// resp.SetBody(nil)
|
||||
func (r *Response) SetBody(b []byte) *Response {
|
||||
r.body = b
|
||||
return r
|
||||
}
|
||||
|
||||
// Status method returns the HTTP status string for the executed request.
|
||||
//
|
||||
// Example: 200 OK
|
||||
func (r *Response) Status() string {
|
||||
if r.RawResponse == nil {
|
||||
@@ -47,6 +59,7 @@ func (r *Response) Status() string {
|
||||
}
|
||||
|
||||
// StatusCode method returns the HTTP status code for the executed request.
|
||||
//
|
||||
// Example: 200
|
||||
func (r *Response) StatusCode() int {
|
||||
if r.RawResponse == nil {
|
||||
@@ -64,11 +77,15 @@ func (r *Response) Proto() string {
|
||||
}
|
||||
|
||||
// Result method returns the response value as an object if it has one
|
||||
//
|
||||
// See [Request.SetResult]
|
||||
func (r *Response) Result() interface{} {
|
||||
return r.Request.Result
|
||||
}
|
||||
|
||||
// Error method returns the error object if it has one
|
||||
//
|
||||
// See [Request.SetError], [Client.SetError]
|
||||
func (r *Response) Error() interface{} {
|
||||
return r.Request.Error
|
||||
}
|
||||
@@ -81,7 +98,7 @@ func (r *Response) Header() http.Header {
|
||||
return r.RawResponse.Header
|
||||
}
|
||||
|
||||
// Cookies method to access all the response cookies
|
||||
// Cookies method to returns all the response cookies
|
||||
func (r *Response) Cookies() []*http.Cookie {
|
||||
if r.RawResponse == nil {
|
||||
return make([]*http.Cookie, 0)
|
||||
@@ -89,18 +106,20 @@ func (r *Response) Cookies() []*http.Cookie {
|
||||
return r.RawResponse.Cookies()
|
||||
}
|
||||
|
||||
// String method returns the body of the server response as String.
|
||||
// String method returns the body of the HTTP response as a `string`.
|
||||
// It returns an empty string if it is nil or the body is zero length.
|
||||
func (r *Response) String() string {
|
||||
if r.body == nil {
|
||||
if len(r.body) == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(r.body))
|
||||
}
|
||||
|
||||
// Time method returns the time of HTTP response time that from request we sent and received a request.
|
||||
// Time method returns the duration of HTTP response time from the request we sent
|
||||
// and received a request.
|
||||
//
|
||||
// See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know
|
||||
// when client sent a request.
|
||||
// See [Response.ReceivedAt] to know when the client received a response and see
|
||||
// `Response.Request.Time` to know when the client sent a request.
|
||||
func (r *Response) Time() time.Duration {
|
||||
if r.Request.clientTrace != nil {
|
||||
return r.Request.TraceInfo().TotalTime
|
||||
@@ -108,23 +127,25 @@ func (r *Response) Time() time.Duration {
|
||||
return r.receivedAt.Sub(r.Request.Time)
|
||||
}
|
||||
|
||||
// ReceivedAt method returns when response got received from server for the request.
|
||||
// ReceivedAt method returns the time we received a response from the server for the request.
|
||||
func (r *Response) ReceivedAt() time.Time {
|
||||
return r.receivedAt
|
||||
}
|
||||
|
||||
// Size method returns the HTTP response size in bytes. Ya, you can relay on HTTP `Content-Length` header,
|
||||
// however it won't be good for chucked transfer/compressed response. Since Resty calculates response size
|
||||
// at the client end. You will get actual size of the http response.
|
||||
// Size method returns the HTTP response size in bytes. Yeah, you can rely on HTTP `Content-Length`
|
||||
// header, however it won't be available for chucked transfer/compressed response.
|
||||
// Since Resty captures response size details when processing the response body
|
||||
// when possible. So that users get the actual size of response bytes.
|
||||
func (r *Response) Size() int64 {
|
||||
return r.size
|
||||
}
|
||||
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in-conjunction with `SetDoNotParseResponse`
|
||||
// option otherwise you get an error as `read err: http: read on closed response body`.
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in conjunction with
|
||||
// [Client.SetDoNotParseResponse] or [Request.SetDoNotParseResponse]
|
||||
// option; otherwise, you get an error as `read err: http: read on closed response body.`
|
||||
//
|
||||
// Do not forget to close the body, otherwise you might get into connection leaks, no connection reuse.
|
||||
// Basically you have taken over the control of response parsing from `Resty`.
|
||||
// You have taken over the control of response parsing from Resty.
|
||||
func (r *Response) RawBody() io.ReadCloser {
|
||||
if r.RawResponse == nil {
|
||||
return nil
|
||||
@@ -142,10 +163,6 @@ func (r *Response) IsError() bool {
|
||||
return r.StatusCode() > 399
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Response Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (r *Response) setReceivedAt() {
|
||||
r.receivedAt = time.Now()
|
||||
if r.Request.clientTrace != nil {
|
||||
@@ -154,7 +171,10 @@ func (r *Response) setReceivedAt() {
|
||||
}
|
||||
|
||||
func (r *Response) fmtBodyString(sl int64) string {
|
||||
if r.body != nil {
|
||||
if r.Request.client.notParseResponse || r.Request.notParseResponse {
|
||||
return "***** DO NOT PARSE RESPONSE - Enabled *****"
|
||||
}
|
||||
if len(r.body) > 0 {
|
||||
if int64(len(r.body)) > sl {
|
||||
return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body))
|
||||
}
|
||||
|
||||
8
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
8
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// Version # of resty
|
||||
const Version = "2.7.0"
|
||||
const Version = "2.17.1"
|
||||
|
||||
// New method creates a new Resty client.
|
||||
func New() *Client {
|
||||
@@ -24,12 +24,12 @@ func New() *Client {
|
||||
})
|
||||
}
|
||||
|
||||
// NewWithClient method creates a new Resty client with given `http.Client`.
|
||||
// NewWithClient method creates a new Resty client with given [http.Client].
|
||||
func NewWithClient(hc *http.Client) *Client {
|
||||
return createClient(hc)
|
||||
}
|
||||
|
||||
// NewWithLocalAddr method creates a new Resty client with given Local Address
|
||||
// NewWithLocalAddr method creates a new Resty client with the given Local Address.
|
||||
// to dial from.
|
||||
func NewWithLocalAddr(localAddr net.Addr) *Client {
|
||||
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
|
||||
58
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
58
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@ package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sync"
|
||||
@@ -22,7 +23,7 @@ type (
|
||||
// Option is to create convenient retry options like wait time, max retries, etc.
|
||||
Option func(*Options)
|
||||
|
||||
// RetryConditionFunc type is for retry condition function
|
||||
// RetryConditionFunc type is for the retry condition function
|
||||
// input: non-nil Response OR request execution error
|
||||
RetryConditionFunc func(*Response, error) bool
|
||||
|
||||
@@ -32,8 +33,8 @@ type (
|
||||
// RetryAfterFunc returns time to wait before retry
|
||||
// For example, it can parse HTTP Retry-After header
|
||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
// Non-nil error is returned if it is found that request is not retryable
|
||||
// (0, nil) is a special result means 'use default algorithm'
|
||||
// Non-nil error is returned if it is found that the request is not retryable
|
||||
// (0, nil) is a special result that means 'use default algorithm'
|
||||
RetryAfterFunc func(*Client, *Response) (time.Duration, error)
|
||||
|
||||
// Options struct is used to hold retry settings.
|
||||
@@ -43,6 +44,7 @@ type (
|
||||
maxWaitTime time.Duration
|
||||
retryConditions []RetryConditionFunc
|
||||
retryHooks []OnRetryFunc
|
||||
resetReaders bool
|
||||
}
|
||||
)
|
||||
|
||||
@@ -67,7 +69,7 @@ func MaxWaitTime(value time.Duration) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// RetryConditions sets the conditions that will be checked for retry.
|
||||
// RetryConditions sets the conditions that will be checked for retry
|
||||
func RetryConditions(conditions []RetryConditionFunc) Option {
|
||||
return func(o *Options) {
|
||||
o.retryConditions = conditions
|
||||
@@ -81,6 +83,14 @@ func RetryHooks(hooks []OnRetryFunc) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// ResetMultipartReaders sets a boolean value which will lead the start being seeked out
|
||||
// on all multipart file readers if they implement [io.ReadSeeker]
|
||||
func ResetMultipartReaders(value bool) Option {
|
||||
return func(o *Options) {
|
||||
o.resetReaders = value
|
||||
}
|
||||
}
|
||||
|
||||
// Backoff retries with increasing timeout duration up until X amount of retries
|
||||
// (Default is 3 attempts, Override with option Retries(n))
|
||||
func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
@@ -125,6 +135,15 @@ func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.resetReaders {
|
||||
if err := resetFileReaders(resp.Request.multipartFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := resetFieldReaders(resp.Request.multipartFields); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, hook := range opts.retryHooks {
|
||||
hook(resp, err)
|
||||
}
|
||||
@@ -186,13 +205,16 @@ func sleepDuration(resp *Response, min, max time.Duration, attempt int) (time.Du
|
||||
}
|
||||
|
||||
// Return capped exponential backoff with jitter
|
||||
// http://www.awsarchitectureblog.com/2015/03/backoff.html
|
||||
// https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
||||
func jitterBackoff(min, max time.Duration, attempt int) time.Duration {
|
||||
base := float64(min)
|
||||
capLevel := float64(max)
|
||||
|
||||
temp := math.Min(capLevel, base*math.Exp2(float64(attempt)))
|
||||
ri := time.Duration(temp / 2)
|
||||
if ri == 0 {
|
||||
ri = time.Nanosecond
|
||||
}
|
||||
result := randDuration(ri)
|
||||
|
||||
if result < min {
|
||||
@@ -219,3 +241,27 @@ func newRnd() *rand.Rand {
|
||||
var src = rand.NewSource(seed)
|
||||
return rand.New(src)
|
||||
}
|
||||
|
||||
func resetFileReaders(files []*File) error {
|
||||
for _, f := range files {
|
||||
if rs, ok := f.Reader.(io.ReadSeeker); ok {
|
||||
if _, err := rs.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resetFieldReaders(fields []*MultipartField) error {
|
||||
for _, f := range fields {
|
||||
if rs, ok := f.Reader.(io.ReadSeeker); ok {
|
||||
if _, err := rs.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
14
vendor/github.com/go-resty/resty/v2/shellescape/BUILD.bazel
generated
vendored
Normal file
14
vendor/github.com/go-resty/resty/v2/shellescape/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "shellescape",
|
||||
srcs = ["shellescape.go"],
|
||||
importpath = "github.com/go-resty/resty/v2/shellescape",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "go_default_library",
|
||||
actual = ":shellescape",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
40
vendor/github.com/go-resty/resty/v2/shellescape/shellescape.go
generated
vendored
Normal file
40
vendor/github.com/go-resty/resty/v2/shellescape/shellescape.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015-present Jeevanandam M (jeeva@myjeeva.com)
|
||||
// 2024 Ahuigo (https://github.com/ahuigo)
|
||||
// All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package shellescape provides the methods to escape arbitrary
|
||||
strings for a safe use as command line arguments in the most common
|
||||
POSIX shells.
|
||||
|
||||
The original Python package which this work was inspired by can be found
|
||||
at https://pypi.python.org/pypi/shellescape.
|
||||
*/
|
||||
package shellescape
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var pattern *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
pattern = regexp.MustCompile(`[^\w@%+=:,./-]`)
|
||||
}
|
||||
|
||||
// Quote method returns a shell-escaped version of the string. The returned value
|
||||
// can safely be used as one token in a shell command line.
|
||||
func Quote(s string) string {
|
||||
if len(s) == 0 {
|
||||
return "''"
|
||||
}
|
||||
|
||||
if pattern.MatchString(s) {
|
||||
return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'"
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
52
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
52
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http/httptrace"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,32 +17,30 @@ import (
|
||||
// TraceInfo struct
|
||||
//_______________________________________________________________________
|
||||
|
||||
// TraceInfo struct is used provide request trace info such as DNS lookup
|
||||
// TraceInfo struct is used to provide request trace info such as DNS lookup
|
||||
// duration, Connection obtain duration, Server processing duration, etc.
|
||||
//
|
||||
// Since v2.0.0
|
||||
type TraceInfo struct {
|
||||
// DNSLookup is a duration that transport took to perform
|
||||
// DNSLookup is the duration that transport took to perform
|
||||
// DNS lookup.
|
||||
DNSLookup time.Duration
|
||||
|
||||
// ConnTime is a duration that took to obtain a successful connection.
|
||||
// ConnTime is the duration it took to obtain a successful connection.
|
||||
ConnTime time.Duration
|
||||
|
||||
// TCPConnTime is a duration that took to obtain the TCP connection.
|
||||
// TCPConnTime is the duration it took to obtain the TCP connection.
|
||||
TCPConnTime time.Duration
|
||||
|
||||
// TLSHandshake is a duration that TLS handshake took place.
|
||||
// TLSHandshake is the duration of the TLS handshake.
|
||||
TLSHandshake time.Duration
|
||||
|
||||
// ServerTime is a duration that server took to respond first byte.
|
||||
// ServerTime is the server's duration for responding to the first byte.
|
||||
ServerTime time.Duration
|
||||
|
||||
// ResponseTime is a duration since first response byte from server to
|
||||
// ResponseTime is the duration since the first response byte from the server to
|
||||
// request completion.
|
||||
ResponseTime time.Duration
|
||||
|
||||
// TotalTime is a duration that total request took end-to-end.
|
||||
// TotalTime is the duration of the total time request taken end-to-end.
|
||||
TotalTime time.Duration
|
||||
|
||||
// IsConnReused is whether this connection has been previously
|
||||
@@ -52,7 +51,7 @@ type TraceInfo struct {
|
||||
// idle pool.
|
||||
IsConnWasIdle bool
|
||||
|
||||
// ConnIdleTime is a duration how long the connection was previously
|
||||
// ConnIdleTime is the duration how long the connection that was previously
|
||||
// idle, if IsConnWasIdle is true.
|
||||
ConnIdleTime time.Duration
|
||||
|
||||
@@ -68,10 +67,11 @@ type TraceInfo struct {
|
||||
// ClientTrace struct and its methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// tracer struct maps the `httptrace.ClientTrace` hooks into Fields
|
||||
// with same naming for easy understanding. Plus additional insights
|
||||
// Request.
|
||||
// clientTrace struct maps the [httptrace.ClientTrace] hooks into Fields
|
||||
// with the same naming for easy understanding. Plus additional insights
|
||||
// [Request].
|
||||
type clientTrace struct {
|
||||
lock sync.RWMutex
|
||||
getConn time.Time
|
||||
dnsStart time.Time
|
||||
dnsDone time.Time
|
||||
@@ -84,46 +84,60 @@ type clientTrace struct {
|
||||
gotConnInfo httptrace.GotConnInfo
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Trace unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (t *clientTrace) createContext(ctx context.Context) context.Context {
|
||||
return httptrace.WithClientTrace(
|
||||
ctx,
|
||||
&httptrace.ClientTrace{
|
||||
DNSStart: func(_ httptrace.DNSStartInfo) {
|
||||
t.lock.Lock()
|
||||
t.dnsStart = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
DNSDone: func(_ httptrace.DNSDoneInfo) {
|
||||
t.lock.Lock()
|
||||
t.dnsDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
ConnectStart: func(_, _ string) {
|
||||
t.lock.Lock()
|
||||
if t.dnsDone.IsZero() {
|
||||
t.dnsDone = time.Now()
|
||||
}
|
||||
if t.dnsStart.IsZero() {
|
||||
t.dnsStart = t.dnsDone
|
||||
}
|
||||
t.lock.Unlock()
|
||||
},
|
||||
ConnectDone: func(net, addr string, err error) {
|
||||
t.lock.Lock()
|
||||
t.connectDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GetConn: func(_ string) {
|
||||
t.lock.Lock()
|
||||
t.getConn = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GotConn: func(ci httptrace.GotConnInfo) {
|
||||
t.lock.Lock()
|
||||
t.gotConn = time.Now()
|
||||
t.gotConnInfo = ci
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GotFirstResponseByte: func() {
|
||||
t.lock.Lock()
|
||||
t.gotFirstResponseByte = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
TLSHandshakeStart: func() {
|
||||
t.lock.Lock()
|
||||
t.tlsHandshakeStart = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {
|
||||
t.lock.Lock()
|
||||
t.tlsHandshakeDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
5
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
5
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -24,7 +25,7 @@ func createTransport(localAddr net.Addr) *http.Transport {
|
||||
}
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: dialer.DialContext,
|
||||
DialContext: transportDialContext(dialer),
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
|
||||
3
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
3
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
||||
17
vendor/github.com/go-resty/resty/v2/transport_js.go
generated
vendored
Normal file
17
vendor/github.com/go-resty/resty/v2/transport_js.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func transportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return nil
|
||||
}
|
||||
17
vendor/github.com/go-resty/resty/v2/transport_other.go
generated
vendored
Normal file
17
vendor/github.com/go-resty/resty/v2/transport_other.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !(js && wasm)
|
||||
// +build !js !wasm
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func transportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return dialer.DialContext
|
||||
}
|
||||
102
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
102
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@ package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -18,7 +19,6 @@ import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
@@ -64,6 +64,16 @@ func (l *logger) output(format string, v ...interface{}) {
|
||||
l.l.Printf(format, v...)
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Rate Limiter interface
|
||||
//_______________________________________________________________________
|
||||
|
||||
type RateLimiter interface {
|
||||
Allow() bool
|
||||
}
|
||||
|
||||
var ErrRateLimitExceeded = errors.New("rate limit exceeded")
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Helper methods
|
||||
//_______________________________________________________________________
|
||||
@@ -134,10 +144,6 @@ type ResponseLog struct {
|
||||
Body string
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// way to disable the HTML escape as opt-in
|
||||
func jsonMarshal(c *Client, r *Request, d interface{}) (*bytes.Buffer, error) {
|
||||
if !r.jsonEscapeHTML || !c.jsonEscapeHTML {
|
||||
@@ -205,7 +211,7 @@ func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r i
|
||||
return err
|
||||
}
|
||||
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf)))
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf[:size])))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -279,7 +285,13 @@ func functionName(i interface{}) string {
|
||||
}
|
||||
|
||||
func acquireBuffer() *bytes.Buffer {
|
||||
return bufPool.Get().(*bytes.Buffer)
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
if buf.Len() == 0 {
|
||||
buf.Reset()
|
||||
return buf
|
||||
}
|
||||
bufPool.Put(buf)
|
||||
return new(bytes.Buffer)
|
||||
}
|
||||
|
||||
func releaseBuffer(buf *bytes.Buffer) {
|
||||
@@ -289,32 +301,10 @@ func releaseBuffer(buf *bytes.Buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
// requestBodyReleaser wraps requests's body and implements custom Close for it.
|
||||
// The Close method closes original body and releases request body back to sync.Pool.
|
||||
type requestBodyReleaser struct {
|
||||
releaseOnce sync.Once
|
||||
reqBuf *bytes.Buffer
|
||||
io.ReadCloser
|
||||
}
|
||||
|
||||
func newRequestBodyReleaser(respBody io.ReadCloser, reqBuf *bytes.Buffer) io.ReadCloser {
|
||||
if reqBuf == nil {
|
||||
return respBody
|
||||
func backToBufPool(buf *bytes.Buffer) {
|
||||
if buf != nil {
|
||||
bufPool.Put(buf)
|
||||
}
|
||||
|
||||
return &requestBodyReleaser{
|
||||
reqBuf: reqBuf,
|
||||
ReadCloser: respBody,
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *requestBodyReleaser) Close() error {
|
||||
err := rr.ReadCloser.Close()
|
||||
rr.releaseOnce.Do(func() {
|
||||
releaseBuffer(rr.reqBuf)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func closeq(v interface{}) {
|
||||
@@ -328,25 +318,7 @@ func silently(_ ...interface{}) {}
|
||||
func composeHeaders(c *Client, r *Request, hdrs http.Header) string {
|
||||
str := make([]string, 0, len(hdrs))
|
||||
for _, k := range sortHeaderKeys(hdrs) {
|
||||
var v string
|
||||
if k == "Cookie" {
|
||||
cv := strings.TrimSpace(strings.Join(hdrs[k], ", "))
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, c := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
if cv != "" {
|
||||
cv = cv + "; " + c.String()
|
||||
} else {
|
||||
cv = c.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, cv))
|
||||
} else {
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", ")))
|
||||
}
|
||||
if v != "" {
|
||||
str = append(str, "\t"+v)
|
||||
}
|
||||
str = append(str, "\t"+strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", "))))
|
||||
}
|
||||
return strings.Join(str, "\n")
|
||||
}
|
||||
@@ -368,6 +340,32 @@ func copyHeaders(hdrs http.Header) http.Header {
|
||||
return nh
|
||||
}
|
||||
|
||||
func wrapErrors(n error, inner error) error {
|
||||
if inner == nil {
|
||||
return n
|
||||
}
|
||||
if n == nil {
|
||||
return inner
|
||||
}
|
||||
return &restyError{
|
||||
err: n,
|
||||
inner: inner,
|
||||
}
|
||||
}
|
||||
|
||||
type restyError struct {
|
||||
err error
|
||||
inner error
|
||||
}
|
||||
|
||||
func (e *restyError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
func (e *restyError) Unwrap() error {
|
||||
return e.inner
|
||||
}
|
||||
|
||||
type noRetryErr struct {
|
||||
err error
|
||||
}
|
||||
|
||||
78
vendor/github.com/go-resty/resty/v2/util_curl.go
generated
vendored
Normal file
78
vendor/github.com/go-resty/resty/v2/util_curl.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-resty/resty/v2/shellescape"
|
||||
)
|
||||
|
||||
func buildCurlRequest(req *http.Request, httpCookiejar http.CookieJar) (curl string) {
|
||||
// 1. Generate curl raw headers
|
||||
|
||||
curl = "curl -X " + req.Method + " "
|
||||
// req.Host + req.URL.Path + "?" + req.URL.RawQuery + " " + req.Proto + " "
|
||||
headers := dumpCurlHeaders(req)
|
||||
for _, kv := range *headers {
|
||||
curl += `-H ` + shellescape.Quote(kv[0]+": "+kv[1]) + ` `
|
||||
}
|
||||
|
||||
// 2. Generate curl cookies
|
||||
// TODO validate this block of code, I think its not required since cookie captured via Headers
|
||||
if cookieJar, ok := httpCookiejar.(*cookiejar.Jar); ok {
|
||||
cookies := cookieJar.Cookies(req.URL)
|
||||
if len(cookies) > 0 {
|
||||
curl += `-H ` + shellescape.Quote(dumpCurlCookies(cookies)) + " "
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Generate curl body
|
||||
if req.Body != nil {
|
||||
buf, _ := io.ReadAll(req.Body)
|
||||
req.Body = io.NopCloser(bytes.NewBuffer(buf)) // important!!
|
||||
curl += `-d ` + shellescape.Quote(string(buf)) + " "
|
||||
}
|
||||
|
||||
urlString := shellescape.Quote(req.URL.String())
|
||||
if urlString == "''" {
|
||||
urlString = "'http://unexecuted-request'"
|
||||
}
|
||||
curl += urlString
|
||||
return curl
|
||||
}
|
||||
|
||||
// dumpCurlCookies dumps cookies to curl format
|
||||
func dumpCurlCookies(cookies []*http.Cookie) string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("Cookie: ")
|
||||
for _, cookie := range cookies {
|
||||
sb.WriteString(cookie.Name + "=" + url.QueryEscape(cookie.Value) + "&")
|
||||
}
|
||||
return strings.TrimRight(sb.String(), "&")
|
||||
}
|
||||
|
||||
// dumpCurlHeaders dumps headers to curl format
|
||||
func dumpCurlHeaders(req *http.Request) *[][2]string {
|
||||
headers := [][2]string{}
|
||||
for k, vs := range req.Header {
|
||||
for _, v := range vs {
|
||||
headers = append(headers, [2]string{k, v})
|
||||
}
|
||||
}
|
||||
n := len(headers)
|
||||
for i := 0; i < n; i++ {
|
||||
for j := n - 1; j > i; j-- {
|
||||
jj := j - 1
|
||||
h1, h2 := headers[j], headers[jj]
|
||||
if h1[0] < h2[0] {
|
||||
headers[jj], headers[j] = headers[j], headers[jj]
|
||||
}
|
||||
}
|
||||
}
|
||||
return &headers
|
||||
}
|
||||
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
@@ -637,9 +637,10 @@ github.com/go-redis/redis/v8/internal/pool
|
||||
github.com/go-redis/redis/v8/internal/proto
|
||||
github.com/go-redis/redis/v8/internal/rand
|
||||
github.com/go-redis/redis/v8/internal/util
|
||||
# github.com/go-resty/resty/v2 v2.7.0
|
||||
## explicit; go 1.11
|
||||
# github.com/go-resty/resty/v2 v2.17.1
|
||||
## explicit; go 1.23.0
|
||||
github.com/go-resty/resty/v2
|
||||
github.com/go-resty/resty/v2/shellescape
|
||||
# github.com/go-sql-driver/mysql v1.9.3
|
||||
## explicit; go 1.21.0
|
||||
github.com/go-sql-driver/mysql
|
||||
|
||||
Reference in New Issue
Block a user