未验证 提交 7d661e90 编写于 作者: K KubeSphere CI Bot 提交者: GitHub

Merge pull request #3486 from wansir/update-vendor

update vendor directory
......@@ -8,7 +8,9 @@ go 1.13
require (
code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e // indirect
github.com/Masterminds/semver/v3 v3.1.0
github.com/Microsoft/go-winio v0.4.12 // indirect
github.com/PuerkitoBio/goquery v1.5.0
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
github.com/aws/aws-sdk-go v1.33.12
......@@ -21,6 +23,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
github.com/elastic/go-elasticsearch/v5 v5.6.1
github.com/elastic/go-elasticsearch/v6 v6.8.2
github.com/elastic/go-elasticsearch/v7 v7.3.0
......@@ -44,6 +47,7 @@ require (
github.com/google/go-cmp v0.5.0
github.com/google/uuid v1.1.1
github.com/gorilla/websocket v1.4.1
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect
github.com/hashicorp/golang-lru v0.5.4
github.com/json-iterator/go v1.1.10
github.com/jszwec/csvutil v1.5.0
......@@ -65,14 +69,13 @@ require (
github.com/prometheus/client_golang v1.7.1
github.com/prometheus/common v0.11.1
github.com/prometheus/prometheus v1.8.2-0.20200907175821-8219b442c864
github.com/sony/sonyflake v1.0.0
github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
github.com/speps/go-hashids v2.0.0+incompatible
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.6.1
github.com/xanzy/ssh-agent v0.2.1 // indirect
go.etcd.io/etcd v3.3.17+incompatible // indirect
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
......@@ -140,7 +143,6 @@ replace (
github.com/Knetic/govaluate => github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible
github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e
github.com/Masterminds/goutils => github.com/Masterminds/goutils v1.1.0
github.com/Masterminds/semver => github.com/Masterminds/semver v1.5.0
github.com/Masterminds/semver/v3 => github.com/Masterminds/semver/v3 v3.0.1
github.com/Masterminds/sprig/v3 => github.com/Masterminds/sprig/v3 v3.0.0
github.com/Masterminds/squirrel => github.com/Masterminds/squirrel v0.0.0-20161115235646-20f192218cf5
......@@ -156,7 +158,6 @@ replace (
github.com/Shopify/logrus-bugsnag => github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d
github.com/Shopify/sarama => github.com/Shopify/sarama v1.19.0
github.com/Shopify/toxiproxy => github.com/Shopify/toxiproxy v2.1.4+incompatible
github.com/StackExchange/wmi => github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e
github.com/VividCortex/gohistogram => github.com/VividCortex/gohistogram v1.0.0
github.com/afex/hystrix-go => github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
github.com/agnivade/levenshtein => github.com/agnivade/levenshtein v1.0.1
......@@ -205,7 +206,6 @@ replace (
github.com/cespare/xxhash => github.com/cespare/xxhash v1.1.0
github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.1
github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
github.com/chai2010/jsonmap => github.com/chai2010/jsonmap v1.0.0
github.com/chromedp/cdproto => github.com/chromedp/cdproto v0.0.0-20200424080200-0de008e41fa0
github.com/chromedp/chromedp => github.com/chromedp/chromedp v0.5.3
github.com/chzyer/logex => github.com/chzyer/logex v1.1.10
......@@ -252,7 +252,6 @@ replace (
github.com/dgryski/go-bitstream => github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8
github.com/dgryski/go-sip13 => github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b
github.com/dhui/dktest => github.com/dhui/dktest v0.3.0
github.com/disintegration/imaging => github.com/disintegration/imaging v1.6.1
github.com/docker/cli => github.com/docker/cli v0.0.0-20190506213505-d88565df0c2d
github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker => github.com/docker/engine v1.4.2-0.20200203170920-46ec8731fbce
......@@ -282,7 +281,6 @@ replace (
github.com/emirpasic/gods => github.com/emirpasic/gods v1.12.0
github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473
github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.1.0
github.com/erikstmartin/go-testdb => github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5
github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.9.0+incompatible
github.com/evanphx/json-patch/v5 => github.com/evanphx/json-patch/v5 v5.0.0
github.com/exponent-io/jsonpath => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
......@@ -301,8 +299,6 @@ replace (
github.com/fsouza/fake-gcs-server => github.com/fsouza/fake-gcs-server v1.7.0
github.com/garyburd/redigo => github.com/garyburd/redigo v1.6.0
github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0
github.com/gin-contrib/sse => github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.4.0
github.com/gliderlabs/ssh => github.com/gliderlabs/ssh v0.1.1
github.com/glycerine/go-unsnap-stream => github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd
github.com/glycerine/goconvey => github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31
......@@ -311,7 +307,6 @@ replace (
github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.5.0
github.com/go-logr/logr => github.com/go-logr/logr v0.1.0
github.com/go-logr/zapr => github.com/go-logr/zapr v0.1.1
github.com/go-ole/go-ole => github.com/go-ole/go-ole v1.2.1
github.com/go-openapi/analysis => github.com/go-openapi/analysis v0.19.10
github.com/go-openapi/errors => github.com/go-openapi/errors v0.19.4
github.com/go-openapi/jsonpointer => github.com/go-openapi/jsonpointer v0.19.3
......@@ -325,6 +320,7 @@ replace (
github.com/go-playground/locales => github.com/go-playground/locales v0.12.1
github.com/go-playground/universal-translator => github.com/go-playground/universal-translator v0.0.0-20170327191703-71201497bace
github.com/go-redis/redis => github.com/go-redis/redis v6.15.2+incompatible
github.com/go-resty/resty/v2 => github.com/go-resty/resty/v2 v2.5.0
github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.5.0
github.com/go-stack/stack => github.com/go-stack/stack v1.8.0
github.com/gobuffalo/attrs => github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd
......@@ -346,6 +342,7 @@ replace (
github.com/gocql/gocql => github.com/gocql/gocql v0.0.0-20200526081602-cd04bd7f22a7
github.com/gocraft/dbr => github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6
github.com/godbus/dbus => github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968
github.com/godror/godror => github.com/godror/godror v0.13.3
github.com/gofrs/flock => github.com/gofrs/flock v0.7.1
github.com/gofrs/uuid => github.com/gofrs/uuid v3.2.0+incompatible
github.com/gogo/googleapis => github.com/gogo/googleapis v1.1.0
......@@ -372,7 +369,6 @@ replace (
github.com/google/go-github => github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring => github.com/google/go-querystring v1.0.0
github.com/google/gofuzz => github.com/google/gofuzz v1.1.0
github.com/google/gops => github.com/google/gops v0.3.6
github.com/google/martian => github.com/google/martian v2.1.0+incompatible
github.com/google/pprof => github.com/google/pprof v0.0.0-20200417002340-c6e0a841f49a
github.com/google/renameio => github.com/google/renameio v0.1.0
......@@ -431,10 +427,8 @@ replace (
github.com/jackc/pgx => github.com/jackc/pgx v3.2.0+incompatible
github.com/jbenet/go-context => github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
github.com/jessevdk/go-flags => github.com/jessevdk/go-flags v1.4.0
github.com/jinzhu/gorm => github.com/jinzhu/gorm v1.9.2
github.com/jinzhu/inflection => github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a
github.com/jinzhu/now => github.com/jinzhu/now v1.0.0
github.com/jmespath/go-jmespath => github.com/jmespath/go-jmespath v0.3.0
github.com/jmoiron/sqlx => github.com/jmoiron/sqlx v1.2.0
github.com/joeshaw/multierror => github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
github.com/joho/godotenv => github.com/joho/godotenv v1.3.0
github.com/jonboulle/clockwork => github.com/jonboulle/clockwork v0.1.0
......@@ -443,6 +437,7 @@ replace (
github.com/json-iterator/go => github.com/json-iterator/go v1.1.10
github.com/jstemmer/go-junit-report => github.com/jstemmer/go-junit-report v0.9.1
github.com/jsternberg/zap-logfmt => github.com/jsternberg/zap-logfmt v1.0.0
github.com/jszwec/csvutil => github.com/jszwec/csvutil v1.5.0
github.com/jtolds/gls => github.com/jtolds/gls v4.20.0+incompatible
github.com/julienschmidt/httprouter => github.com/julienschmidt/httprouter v1.3.0
github.com/jung-kurt/gofpdf => github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5
......@@ -451,7 +446,6 @@ replace (
github.com/karrick/godirwalk => github.com/karrick/godirwalk v1.10.3
github.com/kelseyhightower/envconfig => github.com/kelseyhightower/envconfig v1.4.0
github.com/kevinburke/ssh_config => github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e
github.com/keybase/go-ps => github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999
github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.2.0
github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0
github.com/klauspost/compress => github.com/klauspost/compress v1.9.5
......@@ -459,7 +453,6 @@ replace (
github.com/klauspost/crc32 => github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6
github.com/klauspost/pgzip => github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada
github.com/knq/sysutil => github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08
github.com/koding/multiconfig => github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2
github.com/kr/pretty => github.com/kr/pretty v0.2.0
github.com/kr/pty => github.com/kr/pty v1.1.5
......@@ -484,6 +477,7 @@ replace (
github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.1.6
github.com/mattn/go-ieproxy => github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe
github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-oci8 => github.com/mattn/go-oci8 v0.0.7
github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.4
github.com/mattn/go-shellwords => github.com/mattn/go-shellwords v1.0.5
github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.11.0
......@@ -580,11 +574,11 @@ replace (
github.com/rafaeljusto/redigomock => github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1
github.com/rcrowley/go-metrics => github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a
github.com/retailnext/hllpp => github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52
github.com/robfig/cron => github.com/robfig/cron v1.2.0
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af
github.com/rogpeppe/go-charset => github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4
github.com/rogpeppe/go-internal => github.com/rogpeppe/go-internal v1.3.0
github.com/rs/cors => github.com/rs/cors v1.6.0
github.com/rubenv/sql-migrate => github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2
github.com/ryanuber/columnize => github.com/ryanuber/columnize v2.1.0+incompatible
github.com/samuel/go-zookeeper => github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da
......@@ -595,8 +589,6 @@ replace (
github.com/segmentio/kafka-go => github.com/segmentio/kafka-go v0.2.0
github.com/sercand/kuberesolver => github.com/sercand/kuberesolver v2.4.0+incompatible
github.com/sergi/go-diff => github.com/sergi/go-diff v1.0.0
github.com/shirou/gopsutil => github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7
github.com/shirou/w32 => github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4
github.com/shopspring/decimal => github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
github.com/shurcooL/httpfs => github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
github.com/shurcooL/vfsgen => github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
......@@ -629,7 +621,6 @@ replace (
github.com/uber/jaeger-client-go => github.com/uber/jaeger-client-go v2.23.0+incompatible
github.com/uber/jaeger-lib => github.com/uber/jaeger-lib v2.2.0+incompatible
github.com/ugorji/go => github.com/ugorji/go v1.1.4
github.com/ugorji/go/codec => github.com/ugorji/go/codec v0.0.0-20190128213124-ee1426cffec0
github.com/urfave/cli => github.com/urfave/cli v1.20.0
github.com/vektah/gqlparser => github.com/vektah/gqlparser v1.1.2
github.com/weaveworks/common => github.com/weaveworks/common v0.0.0-20200820123129-280614068c5e
......@@ -651,6 +642,7 @@ replace (
github.com/yvasiyarov/go-metrics => github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940
github.com/yvasiyarov/gorelic => github.com/yvasiyarov/gorelic v0.0.6
github.com/yvasiyarov/newrelic_platform_go => github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f
github.com/ziutek/mymysql => github.com/ziutek/mymysql v1.5.4
gitlab.com/nyarla/go-crypt => gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b
go.elastic.co/apm => go.elastic.co/apm v1.5.0
go.elastic.co/apm/module/apmhttp => go.elastic.co/apm/module/apmhttp v1.5.0
......@@ -690,7 +682,6 @@ replace (
google.golang.org/protobuf => google.golang.org/protobuf v1.23.0
gopkg.in/airbrake/gobrake.v2 => gopkg.in/airbrake/gobrake.v2 v2.0.9
gopkg.in/alecthomas/kingpin.v2 => gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/alexcesaro/quotedprintable.v3 => gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
gopkg.in/asn1-ber.v1 => gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d
gopkg.in/cas.v2 => gopkg.in/cas.v2 v2.2.0
gopkg.in/check.v1 => gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
......@@ -701,12 +692,10 @@ replace (
gopkg.in/gcfg.v1 => gopkg.in/gcfg.v1 v1.2.3
gopkg.in/gemnasium/logrus-airbrake-hook.v2 => gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2
gopkg.in/go-playground/assert.v1 => gopkg.in/go-playground/assert.v1 v1.2.1
gopkg.in/go-playground/validator.v8 => gopkg.in/go-playground/validator.v8 v8.18.2
gopkg.in/go-playground/validator.v9 => gopkg.in/go-playground/validator.v9 v9.27.0
gopkg.in/gomail.v2 => gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/gorp.v1 => gopkg.in/gorp.v1 v1.7.2
gopkg.in/inf.v0 => gopkg.in/inf.v0 v0.9.1
gopkg.in/ini.v1 => gopkg.in/ini.v1 v1.57.0
gopkg.in/mail.v2 => gopkg.in/mail.v2 v2.3.1
gopkg.in/natefinch/lumberjack.v2 => gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/square/go-jose.v1 => gopkg.in/square/go-jose.v1 v1.1.2
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.4.0
......@@ -742,14 +731,8 @@ replace (
k8s.io/metrics => k8s.io/metrics v0.18.6
k8s.io/utils => k8s.io/utils v0.0.0-20200603063816-c1c6865ac451
kubesphere.io/client-go => ./staging/src/kubesphere.io/client-go
kubesphere.io/im => kubesphere.io/im v0.1.0
openpitrix.io/iam => openpitrix.io/iam v0.1.0
openpitrix.io/libqueue => openpitrix.io/libqueue v0.4.1
openpitrix.io/logger => openpitrix.io/logger v0.1.0
openpitrix.io/notification => openpitrix.io/notification v0.2.2
openpitrix.io/openpitrix => openpitrix.io/openpitrix v0.4.9-0.20200611125425-ae07f141e797
kubesphere.io/monitoring-dashboard => kubesphere.io/monitoring-dashboard v0.1.2
rsc.io/binaryregexp => rsc.io/binaryregexp v0.2.0
rsc.io/goversion => rsc.io/goversion v1.0.0
rsc.io/letsencrypt => rsc.io/letsencrypt v0.0.1
rsc.io/pdf => rsc.io/pdf v0.1.1
rsc.io/quote/v3 => rsc.io/quote/v3 v3.1.0
......
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
coverage.out
coverage.txt
# Exclude intellij IDE folders
.idea/*
language: go
os: linux
go: # use travis ci resource effectively, keep always latest 2 versions and tip :)
- 1.15.x
- 1.14.x
- tip
install:
- go get -v -t ./...
script:
- go test ./... -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)
jobs:
allow_failures:
- go: tip
package(default_visibility = ["//visibility:private"])
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
gazelle(
name = "gazelle",
command = "fix",
prefix = "github.com/go-resty/resty/v2",
)
go_library(
name = "go_default_library",
srcs = glob(
["*.go"],
exclude = ["*_test.go"],
),
importpath = "github.com/go-resty/resty/v2",
visibility = ["//visibility:public"],
deps = ["@org_golang_x_net//publicsuffix:go_default_library"],
)
go_test(
name = "go_default_test",
srcs =
glob(
["*_test.go"],
exclude = ["example_test.go"],
),
data = glob([".testdata/*"]),
embed = [":go_default_library"],
importpath = "github.com/go-resty/resty/v2",
deps = [
"@org_golang_x_net//proxy:go_default_library",
],
)
The MIT License (MIT)
Copyright (c) 2015-2020 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
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
此差异已折叠。
workspace(name = "resty")
git_repository(
name = "io_bazel_rules_go",
remote = "https://github.com/bazelbuild/rules_go.git",
tag = "0.13.0",
)
git_repository(
name = "bazel_gazelle",
remote = "https://github.com/bazelbuild/bazel-gazelle.git",
tag = "0.13.0",
)
load(
"@io_bazel_rules_go//go:def.bzl",
"go_rules_dependencies",
"go_register_toolchains",
)
go_rules_dependencies()
go_register_toolchains()
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
gazelle_dependencies()
此差异已折叠。
module github.com/go-resty/resty/v2
require golang.org/x/net v0.0.0-20201224014010-6772e930b67b
go 1.11
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
// Copyright (c) 2015-2020 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.
package resty
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
"strings"
"time"
)
const debugRequestLogKey = "__restyDebugRequestLog"
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Request Middleware(s)
//_______________________________________________________________________
func parseRequestURL(c *Client, r *Request) error {
// GitHub #103 Path Params
if len(r.pathParams) > 0 {
for p, v := range r.pathParams {
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
}
}
if len(c.pathParams) > 0 {
for p, v := range c.pathParams {
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
}
}
// Parsing request URL
reqURL, err := url.Parse(r.URL)
if err != nil {
return err
}
// If Request.URL is relative path then added c.HostURL into
// the request URL otherwise Request.URL will be used as-is
if !reqURL.IsAbs() {
r.URL = reqURL.String()
if len(r.URL) > 0 && r.URL[0] != '/' {
r.URL = "/" + r.URL
}
reqURL, err = url.Parse(c.HostURL + r.URL)
if err != nil {
return err
}
}
// Adding Query Param
query := make(url.Values)
for k, v := range c.QueryParam {
for _, iv := range v {
query.Add(k, iv)
}
}
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()
}
}
r.URL = reqURL.String()
return nil
}
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 := range r.Header {
hdr.Del(k)
hdr[k] = append(hdr[k], r.Header[k]...)
}
if IsStringEmpty(hdr.Get(hdrUserAgentKey)) {
hdr.Set(hdrUserAgentKey, hdrUserAgentValue)
}
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) {
if isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
// Handling Multipart
if r.isMultiPart && !(r.Method == MethodPatch) {
if err = handleMultipart(c, r); err != nil {
return
}
goto CL
}
// Handling Form Data
if len(c.FormData) > 0 || len(r.FormData) > 0 {
handleFormData(c, r)
goto CL
}
// Handling Request body
if r.Body != nil {
handleContentType(c, r)
if err = handleRequestBody(c, r); err != nil {
return
}
}
}
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()))
}
return
}
func createHTTPRequest(c *Client, r *Request) (err error) {
if r.bodyBuf == nil {
if reader, ok := r.Body.(io.Reader); ok {
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)
} else {
r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil)
}
} else {
r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf)
}
if err != nil {
return
}
// Assign close connection option
r.RawRequest.Close = c.closeConnection
// Add headers into http request
r.RawRequest.Header = r.Header
// Add cookies from client instance into http request
for _, cookie := range c.Cookies {
r.RawRequest.AddCookie(cookie)
}
// Add cookies from request instance into http request
for _, cookie := range r.Cookies {
r.RawRequest.AddCookie(cookie)
}
// it's for non-http scheme option
if r.RawRequest.URL != nil && r.RawRequest.URL.Scheme == "" {
r.RawRequest.URL.Scheme = c.scheme
r.RawRequest.URL.Host = r.URL
}
// Enable trace
if c.trace || r.trace {
r.clientTrace = &clientTrace{}
r.ctx = r.clientTrace.createContext(r.Context())
}
// Use context if it was specified
if r.ctx != nil {
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
}
return nil, nil
}
return
}
func addCredentials(c *Client, r *Request) error {
var isBasicAuth bool
// Basic Auth
if r.UserInfo != nil { // takes precedence
r.RawRequest.SetBasicAuth(r.UserInfo.Username, r.UserInfo.Password)
isBasicAuth = true
} else if c.UserInfo != nil {
r.RawRequest.SetBasicAuth(c.UserInfo.Username, c.UserInfo.Password)
isBasicAuth = true
}
if !c.DisableWarn {
if isBasicAuth && !strings.HasPrefix(r.URL, "https") {
c.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) { // 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 requestLogger(c *Client, r *Request) error {
if c.Debug {
rr := r.RawRequest
rl := &RequestLog{Header: copyHeaders(rr.Header), 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" +
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)) +
fmt.Sprintf("BODY :\n%v\n", rl.Body) +
"------------------------------------------------------------------------------\n"
r.initValuesMap()
r.values[debugRequestLogKey] = reqLog
}
return nil
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Response Middleware(s)
//_______________________________________________________________________
func responseLogger(c *Client, res *Response) error {
if c.Debug {
rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)}
if c.responseLog != nil {
if err := c.responseLog(rl); err != nil {
return err
}
}
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("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) +
fmt.Sprintf("TIME DURATION: %v\n", res.Time()) +
"HEADERS :\n" +
composeHeaders(c, res.Request, rl.Header) + "\n"
if res.Request.isSaveResponse {
debugLog += "BODY :\n***** RESPONSE WRITTEN INTO FILE *****\n"
} else {
debugLog += fmt.Sprintf("BODY :\n%v\n", rl.Body)
}
debugLog += "==============================================================================\n"
c.log.Debugf("%s", debugLog)
}
return nil
}
func parseResponseBody(c *Client, res *Response) (err error) {
if res.StatusCode() == http.StatusNoContent {
return
}
// Handles only JSON or XML content type
ct := firstNonEmpty(res.Request.forceContentType, res.Header().Get(hdrContentTypeKey), res.Request.fallbackContentType)
if IsJSONType(ct) || IsXMLType(ct) {
// HTTP status code > 199 and < 300, considered as Result
if res.IsSuccess() {
res.Request.Error = nil
if res.Request.Result != nil {
err = Unmarshalc(c, ct, res.body, res.Request.Result)
return
}
}
// HTTP status code > 399, considered as Error
if res.IsError() {
// global error interface
if res.Request.Error == nil && c.Error != nil {
res.Request.Error = reflect.New(c.Error).Interface()
}
if res.Request.Error != nil {
err = Unmarshalc(c, ct, res.body, res.Request.Error)
}
}
}
return
}
func handleMultipart(c *Client, r *Request) (err error) {
r.bodyBuf = acquireBuffer()
w := multipart.NewWriter(r.bodyBuf)
for k, v := range c.FormData {
for _, iv := range v {
if err = w.WriteField(k, iv); err != nil {
return err
}
}
}
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
}
} else { // form value
if err = w.WriteField(k, iv); err != nil {
return err
}
}
}
}
// #21 - adding io.Reader support
if len(r.multipartFiles) > 0 {
for _, f := range r.multipartFiles {
err = addFileReader(w, f)
if err != nil {
return
}
}
}
// 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
}
}
}
r.Header.Set(hdrContentTypeKey, w.FormDataContentType())
err = w.Close()
return
}
func handleFormData(c *Client, r *Request) {
formData := url.Values{}
for k, v := range c.FormData {
for _, iv := range v {
formData.Add(k, iv)
}
}
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.Header.Set(hdrContentTypeKey, formContentType)
r.isFormData = true
}
func handleContentType(c *Client, r *Request) {
contentType := r.Header.Get(hdrContentTypeKey)
if IsStringEmpty(contentType) {
contentType = DetectContentType(r.Body)
r.Header.Set(hdrContentTypeKey, contentType)
}
}
func handleRequestBody(c *Client, r *Request) (err error) {
var bodyBytes []byte
contentType := r.Header.Get(hdrContentTypeKey)
kind := kindOf(r.Body)
r.bodyBuf = nil
if reader, ok := r.Body.(io.Reader); ok {
if c.setContentLength || r.setContentLength { // keep backward compatibility
r.bodyBuf = acquireBuffer()
_, err = r.bodyBuf.ReadFrom(reader)
r.Body = nil
} else {
// Otherwise buffer less processing for `io.Reader`, sounds good.
return
}
} 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) {
bodyBytes, err = jsonMarshal(c, r, r.Body)
if err != nil {
return
}
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
bodyBytes, err = xml.Marshal(r.Body)
if err != nil {
return
}
}
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
}
// []byte into Buffer
if bodyBytes != nil && r.bodyBuf == nil {
r.bodyBuf = acquireBuffer()
_, _ = r.bodyBuf.Write(bodyBytes)
}
return
}
func saveResponseIntoFile(c *Client, res *Response) error {
if res.Request.isSaveResponse {
file := ""
if len(c.outputDirectory) > 0 && !filepath.IsAbs(res.Request.outputFile) {
file += c.outputDirectory + string(filepath.Separator)
}
file = filepath.Clean(file + res.Request.outputFile)
if err := createDirectory(filepath.Dir(file)); err != nil {
return err
}
outFile, err := os.Create(file)
if err != nil {
return err
}
defer closeq(outFile)
// io.Copy reads maximum 32kb size, it is perfect for large file download too
defer closeq(res.RawResponse.Body)
written, err := io.Copy(outFile, res.RawResponse.Body)
if err != nil {
return err
}
res.size = written
}
return nil
}
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
}
// 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)
if err != nil {
return nil, err
}
// Restore the Body
closeq(r.RawRequest.Body)
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))
// Return the Body bytes
return bytes.NewBuffer(b), nil
}
return nil, nil
}
// Copyright (c) 2015-2020 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.
package resty
import (
"errors"
"fmt"
"net"
"net/http"
"strings"
)
type (
// 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
// 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.
RedirectPolicyFunc func(*http.Request, []*http.Request) error
)
// Apply calls f(req, via).
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())
func NoRedirectPolicy() RedirectPolicy {
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
return errors.New("auto redirect is disabled")
})
}
// FlexibleRedirectPolicy is convenient method to create No of redirect policy for HTTP client.
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
if len(via) >= noOfRedirect {
return fmt.Errorf("stopped after %d redirects", noOfRedirect)
}
checkHostAndAddHeaders(req, via[0])
return nil
})
}
// 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"))
func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
hosts := make(map[string]bool)
for _, h := range hostnames {
hosts[strings.ToLower(h)] = true
}
fn := RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
if ok := hosts[getHostname(req.URL.Host)]; !ok {
return errors.New("redirect is not allowed as per DomainCheckRedirectPolicy")
}
return nil
})
return fn
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Package Unexported methods
//_______________________________________________________________________
func getHostname(host string) (hostname string) {
if strings.Index(host, ":") > 0 {
host, _, _ = net.SplitHostPort(host)
}
hostname = strings.ToLower(host)
return
}
// By default Golang will not redirect request headers
// after go throughing various discussion comments from thread
// https://github.com/golang/go/issues/4800
// Resty will add all the headers during a redirect for the same host
func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {
curHostname := getHostname(cur.URL.Host)
preHostname := getHostname(pre.URL.Host)
if strings.EqualFold(curHostname, preHostname) {
for key, val := range pre.Header {
cur.Header[key] = val
}
} else { // only library User-Agent header is added
cur.Header.Set(hdrUserAgentKey, hdrUserAgentValue)
}
}
此差异已折叠。
// Copyright (c) 2015-2020 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.
package resty
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
)
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Response struct and methods
//_______________________________________________________________________
// Response struct holds response values of executed request.
type Response struct {
Request *Request
RawResponse *http.Response
body []byte
size int64
receivedAt time.Time
}
// Body method returns HTTP response as []byte array for the executed request.
//
// Note: `Response.Body` might be nil, if `Request.SetOutput` is used.
func (r *Response) Body() []byte {
if r.RawResponse == nil {
return []byte{}
}
return r.body
}
// Status method returns the HTTP status string for the executed request.
// Example: 200 OK
func (r *Response) Status() string {
if r.RawResponse == nil {
return ""
}
return r.RawResponse.Status
}
// StatusCode method returns the HTTP status code for the executed request.
// Example: 200
func (r *Response) StatusCode() int {
if r.RawResponse == nil {
return 0
}
return r.RawResponse.StatusCode
}
// Proto method returns the HTTP response protocol used for the request.
func (r *Response) Proto() string {
if r.RawResponse == nil {
return ""
}
return r.RawResponse.Proto
}
// Result method returns the response value as an object if it has one
func (r *Response) Result() interface{} {
return r.Request.Result
}
// Error method returns the error object if it has one
func (r *Response) Error() interface{} {
return r.Request.Error
}
// Header method returns the response headers
func (r *Response) Header() http.Header {
if r.RawResponse == nil {
return http.Header{}
}
return r.RawResponse.Header
}
// Cookies method to access all the response cookies
func (r *Response) Cookies() []*http.Cookie {
if r.RawResponse == nil {
return make([]*http.Cookie, 0)
}
return r.RawResponse.Cookies()
}
// String method returns the body of the server response as String.
func (r *Response) String() string {
if r.body == nil {
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.
//
// See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know
// when client sent a request.
func (r *Response) Time() time.Duration {
if r.Request.clientTrace != nil {
return r.Request.TraceInfo().TotalTime
}
return r.receivedAt.Sub(r.Request.Time)
}
// ReceivedAt method returns when response got received from 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.
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`.
//
// 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`.
func (r *Response) RawBody() io.ReadCloser {
if r.RawResponse == nil {
return nil
}
return r.RawResponse.Body
}
// IsSuccess method returns true if HTTP status `code >= 200 and <= 299` otherwise false.
func (r *Response) IsSuccess() bool {
return r.StatusCode() > 199 && r.StatusCode() < 300
}
// IsError method returns true if HTTP status `code >= 400` otherwise false.
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 {
r.Request.clientTrace.endTime = r.receivedAt
}
}
func (r *Response) fmtBodyString(sl int64) string {
if r.body != nil {
if int64(len(r.body)) > sl {
return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body))
}
ct := r.Header().Get(hdrContentTypeKey)
if IsJSONType(ct) {
out := acquireBuffer()
defer releaseBuffer(out)
err := json.Indent(out, r.body, "", " ")
if err != nil {
return fmt.Sprintf("*** Error: Unable to format response body - \"%s\" ***\n\nLog Body as-is:\n%s", err, r.String())
}
return out.String()
}
return r.String()
}
return "***** NO CONTENT *****"
}
// Copyright (c) 2015-2020 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.
// Package resty provides Simple HTTP and REST client library for Go.
package resty
import (
"net"
"net/http"
"net/http/cookiejar"
"golang.org/x/net/publicsuffix"
)
// Version # of resty
const Version = "2.6.0"
// New method creates a new Resty client.
func New() *Client {
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
return createClient(&http.Client{
Jar: cookieJar,
})
}
// 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
// to dial from.
func NewWithLocalAddr(localAddr net.Addr) *Client {
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
return createClient(&http.Client{
Jar: cookieJar,
Transport: createTransport(localAddr),
})
}
// Copyright (c) 2015-2020 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.
package resty
import (
"context"
"math"
"math/rand"
"time"
)
const (
defaultMaxRetries = 3
defaultWaitTime = time.Duration(100) * time.Millisecond
defaultMaxWaitTime = time.Duration(2000) * time.Millisecond
)
type (
// Option is to create convenient retry options like wait time, max retries, etc.
Option func(*Options)
// RetryConditionFunc type is for retry condition function
// input: non-nil Response OR request execution error
RetryConditionFunc func(*Response, error) bool
// 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'
RetryAfterFunc func(*Client, *Response) (time.Duration, error)
// Options struct is used to hold retry settings.
Options struct {
maxRetries int
waitTime time.Duration
maxWaitTime time.Duration
retryConditions []RetryConditionFunc
}
)
// Retries sets the max number of retries
func Retries(value int) Option {
return func(o *Options) {
o.maxRetries = value
}
}
// WaitTime sets the default wait time to sleep between requests
func WaitTime(value time.Duration) Option {
return func(o *Options) {
o.waitTime = value
}
}
// MaxWaitTime sets the max wait time to sleep between requests
func MaxWaitTime(value time.Duration) Option {
return func(o *Options) {
o.maxWaitTime = value
}
}
// RetryConditions sets the conditions that will be checked for retry.
func RetryConditions(conditions []RetryConditionFunc) Option {
return func(o *Options) {
o.retryConditions = conditions
}
}
// 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 {
// Defaults
opts := Options{
maxRetries: defaultMaxRetries,
waitTime: defaultWaitTime,
maxWaitTime: defaultMaxWaitTime,
retryConditions: []RetryConditionFunc{},
}
for _, o := range options {
o(&opts)
}
var (
resp *Response
err error
)
for attempt := 0; attempt <= opts.maxRetries; attempt++ {
resp, err = operation()
ctx := context.Background()
if resp != nil && resp.Request.ctx != nil {
ctx = resp.Request.ctx
}
if ctx.Err() != nil {
return err
}
err1 := unwrapNoRetryErr(err) // raw error, it used for return users callback.
needsRetry := err != nil && err == err1 // retry on a few operation errors by default
for _, condition := range opts.retryConditions {
needsRetry = condition(resp, err1)
if needsRetry {
break
}
}
if !needsRetry {
return err
}
waitTime, err2 := sleepDuration(resp, opts.waitTime, opts.maxWaitTime, attempt)
if err2 != nil {
if err == nil {
err = err2
}
return err
}
select {
case <-time.After(waitTime):
case <-ctx.Done():
return ctx.Err()
}
}
return err
}
func sleepDuration(resp *Response, min, max time.Duration, attempt int) (time.Duration, error) {
const maxInt = 1<<31 - 1 // max int for arch 386
if max < 0 {
max = maxInt
}
if resp == nil {
goto defaultCase
}
// 1. Check for custom callback
if retryAfterFunc := resp.Request.client.RetryAfter; retryAfterFunc != nil {
result, err := retryAfterFunc(resp.Request.client, resp)
if err != nil {
return 0, err // i.e. 'API quota exceeded'
}
if result == 0 {
goto defaultCase
}
if result < 0 || max < result {
result = max
}
if result < min {
result = min
}
return result, nil
}
// 2. Return capped exponential backoff with jitter
// http://www.awsarchitectureblog.com/2015/03/backoff.html
defaultCase:
base := float64(min)
capLevel := float64(max)
temp := math.Min(capLevel, base*math.Exp2(float64(attempt)))
ri := int64(temp / 2)
result := time.Duration(math.Abs(float64(ri + rand.Int63n(ri))))
if result < min {
result = min
}
return result, nil
}
// Copyright (c) 2015-2020 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.
package resty
import (
"context"
"crypto/tls"
"net"
"net/http/httptrace"
"time"
)
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// TraceInfo struct
//_______________________________________________________________________
// TraceInfo struct is used 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
// DNS lookup.
DNSLookup time.Duration
// ConnTime is a duration that took to obtain a successful connection.
ConnTime time.Duration
// TCPConnTime is a duration that took to obtain the TCP connection.
TCPConnTime time.Duration
// TLSHandshake is a duration that TLS handshake took place.
TLSHandshake time.Duration
// ServerTime is a duration that server took to respond first byte.
ServerTime time.Duration
// ResponseTime is a duration since first response byte from server to
// request completion.
ResponseTime time.Duration
// TotalTime is a duration that total request took end-to-end.
TotalTime time.Duration
// IsConnReused is whether this connection has been previously
// used for another HTTP request.
IsConnReused bool
// IsConnWasIdle is whether this connection was obtained from an
// idle pool.
IsConnWasIdle bool
// ConnIdleTime is a duration how long the connection was previously
// idle, if IsConnWasIdle is true.
ConnIdleTime time.Duration
// RequestAttempt is to represent the request attempt made during a Resty
// request execution flow, including retry count.
RequestAttempt int
// RemoteAddr returns the remote network address.
RemoteAddr net.Addr
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// ClientTrace struct and its methods
//_______________________________________________________________________
// tracer struct maps the `httptrace.ClientTrace` hooks into Fields
// with same naming for easy understanding. Plus additional insights
// Request.
type clientTrace struct {
getConn time.Time
dnsStart time.Time
dnsDone time.Time
connectDone time.Time
tlsHandshakeStart time.Time
tlsHandshakeDone time.Time
gotConn time.Time
gotFirstResponseByte time.Time
endTime time.Time
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.dnsStart = time.Now()
},
DNSDone: func(_ httptrace.DNSDoneInfo) {
t.dnsDone = time.Now()
},
ConnectStart: func(_, _ string) {
if t.dnsDone.IsZero() {
t.dnsDone = time.Now()
}
if t.dnsStart.IsZero() {
t.dnsStart = t.dnsDone
}
},
ConnectDone: func(net, addr string, err error) {
t.connectDone = time.Now()
},
GetConn: func(_ string) {
t.getConn = time.Now()
},
GotConn: func(ci httptrace.GotConnInfo) {
t.gotConn = time.Now()
t.gotConnInfo = ci
},
GotFirstResponseByte: func() {
t.gotFirstResponseByte = time.Now()
},
TLSHandshakeStart: func() {
t.tlsHandshakeStart = time.Now()
},
TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {
t.tlsHandshakeDone = time.Now()
},
},
)
}
// +build go1.13
// Copyright (c) 2015-2020 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.
package resty
import (
"net"
"net/http"
"runtime"
"time"
)
func createTransport(localAddr net.Addr) *http.Transport {
dialer := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}
if localAddr != nil {
dialer.LocalAddr = localAddr
}
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialer.DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
}
}
// +build !go1.13
// Copyright (c) 2015-2020 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.
package resty
import (
"net"
"net/http"
"runtime"
"time"
)
func createTransport(localAddr net.Addr) *http.Transport {
dialer := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}
if localAddr != nil {
dialer.LocalAddr = localAddr
}
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialer.DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
}
}
// Copyright (c) 2015-2020 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.
package resty
import (
"bytes"
"encoding/xml"
"fmt"
"io"
"log"
"mime/multipart"
"net/http"
"net/textproto"
"os"
"path/filepath"
"reflect"
"runtime"
"sort"
"strings"
)
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Logger interface
//_______________________________________________________________________
// Logger interface is to abstract the logging from Resty. Gives control to
// the Resty users, choice of the logger.
type Logger interface {
Errorf(format string, v ...interface{})
Warnf(format string, v ...interface{})
Debugf(format string, v ...interface{})
}
func createLogger() *logger {
l := &logger{l: log.New(os.Stderr, "", log.Ldate|log.Lmicroseconds)}
return l
}
var _ Logger = (*logger)(nil)
type logger struct {
l *log.Logger
}
func (l *logger) Errorf(format string, v ...interface{}) {
l.output("ERROR RESTY "+format, v...)
}
func (l *logger) Warnf(format string, v ...interface{}) {
l.output("WARN RESTY "+format, v...)
}
func (l *logger) Debugf(format string, v ...interface{}) {
l.output("DEBUG RESTY "+format, v...)
}
func (l *logger) output(format string, v ...interface{}) {
if len(v) == 0 {
l.l.Print(format)
return
}
l.l.Printf(format, v...)
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Package Helper methods
//_______________________________________________________________________
// IsStringEmpty method tells whether given string is empty or not
func IsStringEmpty(str string) bool {
return len(strings.TrimSpace(str)) == 0
}
// DetectContentType method is used to figure out `Request.Body` content type for request header
func DetectContentType(body interface{}) string {
contentType := plainTextType
kind := kindOf(body)
switch kind {
case reflect.Struct, reflect.Map:
contentType = jsonContentType
case reflect.String:
contentType = plainTextType
default:
if b, ok := body.([]byte); ok {
contentType = http.DetectContentType(b)
} else if kind == reflect.Slice {
contentType = jsonContentType
}
}
return contentType
}
// IsJSONType method is to check JSON content type or not
func IsJSONType(ct string) bool {
return jsonCheck.MatchString(ct)
}
// IsXMLType method is to check XML content type or not
func IsXMLType(ct string) bool {
return xmlCheck.MatchString(ct)
}
// Unmarshalc content into object from JSON or XML
func Unmarshalc(c *Client, ct string, b []byte, d interface{}) (err error) {
if IsJSONType(ct) {
err = c.JSONUnmarshal(b, d)
} else if IsXMLType(ct) {
err = xml.Unmarshal(b, d)
}
return
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// RequestLog and ResponseLog type
//_______________________________________________________________________
// RequestLog struct is used to collected information from resty request
// instance for debug logging. It sent to request log callback before resty
// actually logs the information.
type RequestLog struct {
Header http.Header
Body string
}
// ResponseLog struct is used to collected information from resty response
// instance for debug logging. It sent to response log callback before resty
// actually logs the information.
type ResponseLog struct {
Header http.Header
Body string
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Package Unexported methods
//_______________________________________________________________________
// way to disable the HTML escape as opt-in
func jsonMarshal(c *Client, r *Request, d interface{}) ([]byte, error) {
if !r.jsonEscapeHTML {
return noescapeJSONMarshal(d)
} else if !c.jsonEscapeHTML {
return noescapeJSONMarshal(d)
}
return c.JSONMarshal(d)
}
func firstNonEmpty(v ...string) string {
for _, s := range v {
if !IsStringEmpty(s) {
return s
}
}
return ""
}
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
func escapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}
func createMultipartHeader(param, fileName, contentType string) textproto.MIMEHeader {
hdr := make(textproto.MIMEHeader)
var contentDispositionValue string
if IsStringEmpty(fileName) {
contentDispositionValue = fmt.Sprintf(`form-data; name="%s"`, param)
} else {
contentDispositionValue = fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
param, escapeQuotes(fileName))
}
hdr.Set("Content-Disposition", contentDispositionValue)
if !IsStringEmpty(contentType) {
hdr.Set(hdrContentTypeKey, contentType)
}
return hdr
}
func addMultipartFormField(w *multipart.Writer, mf *MultipartField) error {
partWriter, err := w.CreatePart(createMultipartHeader(mf.Param, mf.FileName, mf.ContentType))
if err != nil {
return err
}
_, err = io.Copy(partWriter, mf.Reader)
return err
}
func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r io.Reader) error {
// Auto detect actual multipart content type
cbuf := make([]byte, 512)
size, err := r.Read(cbuf)
if err != nil {
return err
}
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf)))
if err != nil {
return err
}
if _, err = partWriter.Write(cbuf[:size]); err != nil {
return err
}
_, err = io.Copy(partWriter, r)
return err
}
func addFile(w *multipart.Writer, fieldName, path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer closeq(file)
return writeMultipartFormFile(w, fieldName, filepath.Base(path), file)
}
func addFileReader(w *multipart.Writer, f *File) error {
return writeMultipartFormFile(w, f.ParamName, f.Name, f.Reader)
}
func getPointer(v interface{}) interface{} {
vv := valueOf(v)
if vv.Kind() == reflect.Ptr {
return v
}
return reflect.New(vv.Type()).Interface()
}
func isPayloadSupported(m string, allowMethodGet bool) bool {
return !(m == MethodHead || m == MethodOptions || (m == MethodGet && !allowMethodGet))
}
func typeOf(i interface{}) reflect.Type {
return indirect(valueOf(i)).Type()
}
func valueOf(i interface{}) reflect.Value {
return reflect.ValueOf(i)
}
func indirect(v reflect.Value) reflect.Value {
return reflect.Indirect(v)
}
func kindOf(v interface{}) reflect.Kind {
return typeOf(v).Kind()
}
func createDirectory(dir string) (err error) {
if _, err = os.Stat(dir); err != nil {
if os.IsNotExist(err) {
if err = os.MkdirAll(dir, 0755); err != nil {
return
}
}
}
return
}
func canJSONMarshal(contentType string, kind reflect.Kind) bool {
return IsJSONType(contentType) && (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice)
}
func functionName(i interface{}) string {
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
}
func acquireBuffer() *bytes.Buffer {
return bufPool.Get().(*bytes.Buffer)
}
func releaseBuffer(buf *bytes.Buffer) {
if buf != nil {
buf.Reset()
bufPool.Put(buf)
}
}
func closeq(v interface{}) {
if c, ok := v.(io.Closer); ok {
silently(c.Close())
}
}
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)
}
}
return strings.Join(str, "\n")
}
func sortHeaderKeys(hdrs http.Header) []string {
keys := make([]string, 0, len(hdrs))
for key := range hdrs {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
func copyHeaders(hdrs http.Header) http.Header {
nh := http.Header{}
for k, v := range hdrs {
nh[k] = v
}
return nh
}
type noRetryErr struct {
err error
}
func (e *noRetryErr) Error() string {
return e.err.Error()
}
func wrapNoRetryErr(err error) error {
if err != nil {
err = &noRetryErr{err: err}
}
return err
}
func unwrapNoRetryErr(err error) error {
if e, ok := err.(*noRetryErr); ok {
err = e.err
}
return err
}
// Copyright 2012 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:generate go run gen.go
// Package publicsuffix provides a public suffix list based on data from
// https://publicsuffix.org/
//
// A public suffix is one under which Internet users can directly register
// names. It is related to, but different from, a TLD (top level domain).
//
// "com" is a TLD (top level domain). Top level means it has no dots.
//
// "com" is also a public suffix. Amazon and Google have registered different
// siblings under that domain: "amazon.com" and "google.com".
//
// "au" is another TLD, again because it has no dots. But it's not "amazon.au".
// Instead, it's "amazon.com.au".
//
// "com.au" isn't an actual TLD, because it's not at the top level (it has
// dots). But it is an eTLD (effective TLD), because that's the branching point
// for domain name registrars.
//
// Another name for "an eTLD" is "a public suffix". Often, what's more of
// interest is the eTLD+1, or one more label than the public suffix. For
// example, browsers partition read/write access to HTTP cookies according to
// the eTLD+1. Web pages served from "amazon.com.au" can't read cookies from
// "google.com.au", but web pages served from "maps.google.com" can share
// cookies from "www.google.com", so you don't have to sign into Google Maps
// separately from signing into Google Web Search. Note that all four of those
// domains have 3 labels and 2 dots. The first two domains are each an eTLD+1,
// the last two are not (but share the same eTLD+1: "google.com").
//
// All of these domains have the same eTLD+1:
// - "www.books.amazon.co.uk"
// - "books.amazon.co.uk"
// - "amazon.co.uk"
// Specifically, the eTLD+1 is "amazon.co.uk", because the eTLD is "co.uk".
//
// There is no closed form algorithm to calculate the eTLD of a domain.
// Instead, the calculation is data driven. This package provides a
// pre-compiled snapshot of Mozilla's PSL (Public Suffix List) data at
// https://publicsuffix.org/
package publicsuffix // import "golang.org/x/net/publicsuffix"
// TODO: specify case sensitivity and leading/trailing dot behavior for
// func PublicSuffix and func EffectiveTLDPlusOne.
import (
"fmt"
"net/http/cookiejar"
"strings"
)
// List implements the cookiejar.PublicSuffixList interface by calling the
// PublicSuffix function.
var List cookiejar.PublicSuffixList = list{}
type list struct{}
func (list) PublicSuffix(domain string) string {
ps, _ := PublicSuffix(domain)
return ps
}
func (list) String() string {
return version
}
// PublicSuffix returns the public suffix of the domain using a copy of the
// publicsuffix.org database compiled into the library.
//
// icann is whether the public suffix is managed by the Internet Corporation
// for Assigned Names and Numbers. If not, the public suffix is either a
// privately managed domain (and in practice, not a top level domain) or an
// unmanaged top level domain (and not explicitly mentioned in the
// publicsuffix.org list). For example, "foo.org" and "foo.co.uk" are ICANN
// domains, "foo.dyndns.org" and "foo.blogspot.co.uk" are private domains and
// "cromulent" is an unmanaged top level domain.
//
// Use cases for distinguishing ICANN domains like "foo.com" from private
// domains like "foo.appspot.com" can be found at
// https://wiki.mozilla.org/Public_Suffix_List/Use_Cases
func PublicSuffix(domain string) (publicSuffix string, icann bool) {
lo, hi := uint32(0), uint32(numTLD)
s, suffix, icannNode, wildcard := domain, len(domain), false, false
loop:
for {
dot := strings.LastIndex(s, ".")
if wildcard {
icann = icannNode
suffix = 1 + dot
}
if lo == hi {
break
}
f := find(s[1+dot:], lo, hi)
if f == notFound {
break
}
u := nodes[f] >> (nodesBitsTextOffset + nodesBitsTextLength)
icannNode = u&(1<<nodesBitsICANN-1) != 0
u >>= nodesBitsICANN
u = children[u&(1<<nodesBitsChildren-1)]
lo = u & (1<<childrenBitsLo - 1)
u >>= childrenBitsLo
hi = u & (1<<childrenBitsHi - 1)
u >>= childrenBitsHi
switch u & (1<<childrenBitsNodeType - 1) {
case nodeTypeNormal:
suffix = 1 + dot
case nodeTypeException:
suffix = 1 + len(s)
break loop
}
u >>= childrenBitsNodeType
wildcard = u&(1<<childrenBitsWildcard-1) != 0
if !wildcard {
icann = icannNode
}
if dot == -1 {
break
}
s = s[:dot]
}
if suffix == len(domain) {
// If no rules match, the prevailing rule is "*".
return domain[1+strings.LastIndex(domain, "."):], icann
}
return domain[suffix:], icann
}
const notFound uint32 = 1<<32 - 1
// find returns the index of the node in the range [lo, hi) whose label equals
// label, or notFound if there is no such node. The range is assumed to be in
// strictly increasing node label order.
func find(label string, lo, hi uint32) uint32 {
for lo < hi {
mid := lo + (hi-lo)/2
s := nodeLabel(mid)
if s < label {
lo = mid + 1
} else if s == label {
return mid
} else {
hi = mid
}
}
return notFound
}
// nodeLabel returns the label for the i'th node.
func nodeLabel(i uint32) string {
x := nodes[i]
length := x & (1<<nodesBitsTextLength - 1)
x >>= nodesBitsTextLength
offset := x & (1<<nodesBitsTextOffset - 1)
return text[offset : offset+length]
}
// EffectiveTLDPlusOne returns the effective top level domain plus one more
// label. For example, the eTLD+1 for "foo.bar.golang.org" is "golang.org".
func EffectiveTLDPlusOne(domain string) (string, error) {
if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") || strings.Contains(domain, "..") {
return "", fmt.Errorf("publicsuffix: empty label in domain %q", domain)
}
suffix, _ := PublicSuffix(domain)
if len(domain) <= len(suffix) {
return "", fmt.Errorf("publicsuffix: cannot derive eTLD+1 for domain %q", domain)
}
i := len(domain) - len(suffix) - 1
if domain[i] != '.' {
return "", fmt.Errorf("publicsuffix: invalid public suffix %q for domain %q", suffix, domain)
}
return domain[1+strings.LastIndex(domain[:i], "."):], nil
}
此差异已折叠。
此差异已折叠。
/*
Copyright 2020 KubeSphere Authors
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -14,27 +13,24 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package release
import (
"errors"
"net/url"
"k8s.io/apimachinery/pkg/conversion/queryparams"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"helm.sh/helm/v3/pkg/time"
)
var _ runtime.ParameterCodec = NoConversionParamCodec{}
// NoConversionParamCodec is a no-conversion codec for serializing parameters into URL query strings.
// it's useful in scenarios with the unstructured client and arbitrary resouces.
type NoConversionParamCodec struct{}
func (NoConversionParamCodec) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) {
return queryparams.Convert(obj)
}
func (NoConversionParamCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error {
return errors.New("DecodeParameters not implemented on noConversionParamCodec")
// Info describes release information.
type Info struct {
// FirstDeployed is when the release was first deployed.
FirstDeployed time.Time `json:"first_deployed,omitempty"`
// LastDeployed is when the release was last deployed.
LastDeployed time.Time `json:"last_deployed,omitempty"`
// Deleted tracks when this object was deleted.
Deleted time.Time `json:"deleted"`
// Description is human-friendly "log entry" about this release.
Description string `json:"description,omitempty"`
// Status is the current state of the release
Status Status `json:"status,omitempty"`
// Contains the rendered templates/NOTES.txt if available
Notes string `json:"notes,omitempty"`
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
../../staging/src/kubesphere.io/client-go
\ No newline at end of file
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册