AUTH-2105: Adds support for local forwarding. Refactor auditlogger creation.
AUTH-2088: Adds dynamic destination routing
This commit is contained in:
parent
dbde3870da
commit
91d9dca34e
|
@ -18,7 +18,7 @@
|
||||||
revision = "648efa622239a2f6ff949fed78ee37b48d499ba4"
|
revision = "648efa622239a2f6ff949fed78ee37b48d499ba4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:4a296b8f487dab7ea37c4558d6e84be8103eb6bd297202e870266ff99ebd769d"
|
digest = "1:1df548d2da31574a48a7e2adbd228fe2171a7d5f1b4a2d7ca367cc57436c706a"
|
||||||
name = "github.com/aws/aws-sdk-go"
|
name = "github.com/aws/aws-sdk-go"
|
||||||
packages = [
|
packages = [
|
||||||
"aws",
|
"aws",
|
||||||
|
@ -42,6 +42,7 @@
|
||||||
"internal/ini",
|
"internal/ini",
|
||||||
"internal/s3err",
|
"internal/s3err",
|
||||||
"internal/sdkio",
|
"internal/sdkio",
|
||||||
|
"internal/sdkmath",
|
||||||
"internal/sdkrand",
|
"internal/sdkrand",
|
||||||
"internal/sdkuri",
|
"internal/sdkuri",
|
||||||
"internal/shareddefaults",
|
"internal/shareddefaults",
|
||||||
|
@ -59,16 +60,16 @@
|
||||||
"service/sts/stsiface",
|
"service/sts/stsiface",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "2eb9a651f22769d792f974e8a8efe16afea3370f"
|
revision = "6bb638a9cf6177e3cc9748a95a2410bb26f1f426"
|
||||||
version = "v1.23.9"
|
version = "v1.25.8"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d"
|
digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d"
|
||||||
name = "github.com/beorn7/perks"
|
name = "github.com/beorn7/perks"
|
||||||
packages = ["quantile"]
|
packages = ["quantile"]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "4b2b341e8d7715fae06375aa633dbb6e91b3fb46"
|
revision = "37c8de3658fcb183f997c4e13e8337516ab753e6"
|
||||||
version = "v1.0.0"
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:fed1f537c2f1269fe475a8556c393fe466641682d73ef8fd0491cd3aa1e47bad"
|
digest = "1:fed1f537c2f1269fe475a8556c393fe466641682d73ef8fd0491cd3aa1e47bad"
|
||||||
|
@ -137,16 +138,8 @@
|
||||||
name = "github.com/coreos/go-systemd"
|
name = "github.com/coreos/go-systemd"
|
||||||
packages = ["daemon"]
|
packages = ["daemon"]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "95778dfbb74eb7e4dbaf43bf7d71809650ef8076"
|
revision = "e64a0ec8b42a61e2a9801dc1d0abe539dea79197"
|
||||||
version = "v19"
|
version = "v20"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:385dff5bf83bf1c9d40ef2b0f2e697f0d1973fc9e24ae9401cf41698612bbebc"
|
|
||||||
name = "github.com/creack/pty"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "2769f65a3a94eb8f876f44a0459d24ae7ad2e488"
|
|
||||||
version = "v1.1.7"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
|
digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
|
||||||
|
@ -202,12 +195,11 @@
|
||||||
revision = "ed7bcb39ff10f39ab08e317ce16df282845852fa"
|
revision = "ed7bcb39ff10f39ab08e317ce16df282845852fa"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:0a01355005024757ae2a1f62e8fe68a30b4f5fde7a08ac88b3685e7999ac354b"
|
digest = "1:9f9a357116172beefdf218cada11a5123d84c6975c24a4380c75354c703ae0cf"
|
||||||
name = "github.com/gliderlabs/ssh"
|
name = "github.com/gliderlabs/ssh"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "5b6cc7030f17095c0cf23bb063b0bfe824fe5f8b"
|
revision = "63518b5243e0fe306cc35cb382f459de123e550e"
|
||||||
version = "v0.2.2"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -218,7 +210,7 @@
|
||||||
revision = "604e922904d35e97f98a774db7881f049cd8d970"
|
revision = "604e922904d35e97f98a774db7881f049cd8d970"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:239c4c7fd2159585454003d9be7207167970194216193a8a210b8d29576f19c9"
|
digest = "1:f5ce1529abc1204444ec73779f44f94e2fa8fcdb7aca3c355b0c95947e4005c6"
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
packages = [
|
packages = [
|
||||||
"proto",
|
"proto",
|
||||||
|
@ -228,8 +220,8 @@
|
||||||
"ptypes/timestamp",
|
"ptypes/timestamp",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30"
|
revision = "6c65a5562fc06764971b7c5d05c76c75e84bdbf7"
|
||||||
version = "v1.3.1"
|
version = "v1.3.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:582b704bebaa06b48c29b0cec224a6058a09c86883aaddabde889cd1a5f73e1b"
|
digest = "1:582b704bebaa06b48c29b0cec224a6058a09c86883aaddabde889cd1a5f73e1b"
|
||||||
|
@ -240,12 +232,12 @@
|
||||||
version = "v1.1.1"
|
version = "v1.1.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:d5f97fc268267ec1b61c3453058c738246fc3e746f14b1ae25161513b7367b0c"
|
digest = "1:cbec35fe4d5a4fba369a656a8cd65e244ea2c743007d8f6c1ccb132acf9d1296"
|
||||||
name = "github.com/gorilla/mux"
|
name = "github.com/gorilla/mux"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "c5c6c98bc25355028a63748a498942a6398ccd22"
|
revision = "00bdffe0f3c77e27d2cf6f5c70232a2d3e4d9c15"
|
||||||
version = "v1.7.1"
|
version = "v1.7.3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:43dd08a10854b2056e615d1b1d22ac94559d822e1f8b6fcc92c1a1057e85188e"
|
digest = "1:43dd08a10854b2056e615d1b1d22ac94559d822e1f8b6fcc92c1a1057e85188e"
|
||||||
|
@ -270,17 +262,6 @@
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "c2b33e84"
|
revision = "c2b33e84"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:6c41d4f998a03b6604227ccad36edaed6126c397e5d78709ef4814a1145a6757"
|
|
||||||
name = "github.com/jmoiron/sqlx"
|
|
||||||
packages = [
|
|
||||||
".",
|
|
||||||
"reflectx",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "d161d7a76b5661016ad0b085869f77fd410f3e6a"
|
|
||||||
version = "v1.2.0"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de"
|
digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de"
|
||||||
name = "github.com/konsorten/go-windows-terminal-sequences"
|
name = "github.com/konsorten/go-windows-terminal-sequences"
|
||||||
|
@ -290,7 +271,7 @@
|
||||||
version = "v1.0.2"
|
version = "v1.0.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:bc1c0be40c67b6b4aee09d7508d5a2a52c1c116b1fa43806dad2b0d6b4d4003b"
|
digest = "1:12cb143f2148bf54bcd9fe622abac17325e85eeb1d84b8ec6caf1c80232108fd"
|
||||||
name = "github.com/lib/pq"
|
name = "github.com/lib/pq"
|
||||||
packages = [
|
packages = [
|
||||||
".",
|
".",
|
||||||
|
@ -298,24 +279,24 @@
|
||||||
"scram",
|
"scram",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "51e2106eed1cea199c802d2a49e91e2491b02056"
|
revision = "3427c32cb71afc948325f299f040e53c1dd78979"
|
||||||
version = "v1.1.0"
|
version = "v1.2.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:2fa7b0155cd54479a755c629de26f888a918e13f8857a2c442205d825368e084"
|
digest = "1:4a29eeb25603debe8f2098a9902c4d3851034cf70d33be428826e86e8c30a1b0"
|
||||||
name = "github.com/mattn/go-colorable"
|
name = "github.com/mattn/go-colorable"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "3a70a971f94a22f2fa562ffcc7a0eb45f5daf045"
|
revision = "98ec13f34aabf44cc914c65a1cfb7b9bc815aef1"
|
||||||
version = "v0.1.1"
|
version = "v0.1.4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:e150b5fafbd7607e2d638e4e5cf43aa4100124e5593385147b0a74e2733d8b0d"
|
digest = "1:d62282425ffb75047679d7e2c3b980eea7f82c05ef5fb9142ee617ebac6e7432"
|
||||||
name = "github.com/mattn/go-isatty"
|
name = "github.com/mattn/go-isatty"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "c2a7a6ca930a4cd0bc33a3f298eb71960732a3a7"
|
revision = "88ba11cfdc67c7588b30042edf244b2875f892b6"
|
||||||
version = "v0.0.7"
|
version = "v0.0.10"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc"
|
digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc"
|
||||||
|
@ -352,14 +333,6 @@
|
||||||
revision = "af06845cf3004701891bf4fdb884bfe4920b3727"
|
revision = "af06845cf3004701891bf4fdb884bfe4920b3727"
|
||||||
version = "v1.1.0"
|
version = "v1.1.0"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318"
|
|
||||||
name = "github.com/mitchellh/mapstructure"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
|
|
||||||
version = "v1.1.2"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:11e62d6050198055e6cd87ed57e5d8c669e84f839c16e16f192374d913d1a70d"
|
digest = "1:11e62d6050198055e6cd87ed57e5d8c669e84f839c16e16f192374d913d1a70d"
|
||||||
name = "github.com/opentracing/opentracing-go"
|
name = "github.com/opentracing/opentracing-go"
|
||||||
|
@ -405,10 +378,10 @@
|
||||||
name = "github.com/prometheus/client_model"
|
name = "github.com/prometheus/client_model"
|
||||||
packages = ["go"]
|
packages = ["go"]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "fd36f4220a901265f90734c3183c5f0c91daa0b8"
|
revision = "14fe0d1b01d4d5fc031dd4bec1823bd3ebbe8016"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:35cf6bdf68db765988baa9c4f10cc5d7dda1126a54bd62e252dbcd0b1fc8da90"
|
digest = "1:f119e3205d3a1f0f19dbd7038eb37528e2c6f0933269dc344e305951fb87d632"
|
||||||
name = "github.com/prometheus/common"
|
name = "github.com/prometheus/common"
|
||||||
packages = [
|
packages = [
|
||||||
"expfmt",
|
"expfmt",
|
||||||
|
@ -416,16 +389,20 @@
|
||||||
"model",
|
"model",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "a82f4c12f983cc2649298185f296632953e50d3e"
|
revision = "287d3e634a1e550c9e463dd7e5a75a422c614505"
|
||||||
version = "v0.3.0"
|
version = "v0.7.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
digest = "1:a210815b437763623ecca8eb91e6a0bf4f2d6773c5a6c9aec0e28f19e5fd6deb"
|
||||||
digest = "1:49b09905e781d7775c086604cc00083e1832d0783f1f421b79f42657c457d029"
|
|
||||||
name = "github.com/prometheus/procfs"
|
name = "github.com/prometheus/procfs"
|
||||||
packages = ["."]
|
packages = [
|
||||||
|
".",
|
||||||
|
"internal/fs",
|
||||||
|
"internal/util",
|
||||||
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "8368d24ba045f26503eb745b624d930cbe214c79"
|
revision = "499c85531f756d1129edd26485a5f73871eeb308"
|
||||||
|
version = "v0.0.5"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:1a23fdd843129ef761ffe7651bc5fe7c5b09fbe933e92783ab06cc11c37b7b37"
|
digest = "1:1a23fdd843129ef761ffe7651bc5fe7c5b09fbe933e92783ab06cc11c37b7b37"
|
||||||
|
@ -436,12 +413,9 @@
|
||||||
version = "v2.4"
|
version = "v2.4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:31538f8d774e8bf2fb9380d2d2a82d69e206a7d0603946586926f1819c546c26"
|
digest = "1:04457f9f6f3ffc5fea48e71d62f2ca256637dee0a04d710288e27e05c8b41976"
|
||||||
name = "github.com/sirupsen/logrus"
|
name = "github.com/sirupsen/logrus"
|
||||||
packages = [
|
packages = ["."]
|
||||||
".",
|
|
||||||
"hooks/test",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "839c75faf7f98a33d445d181f3018b5c3409a45e"
|
revision = "839c75faf7f98a33d445d181f3018b5c3409a45e"
|
||||||
version = "v1.4.2"
|
version = "v1.4.2"
|
||||||
|
@ -459,7 +433,7 @@
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:a84d5ec8b40a827962ea250f2cf03434138ccae9d83fcac12fb49b70c70b80cc"
|
digest = "1:d9e4eb3f377dca21b3be66fc471106c3150cdbe43f1fba67fe79f6321b9731a8"
|
||||||
name = "golang.org/x/crypto"
|
name = "golang.org/x/crypto"
|
||||||
packages = [
|
packages = [
|
||||||
"curve25519",
|
"curve25519",
|
||||||
|
@ -475,11 +449,11 @@
|
||||||
"ssh/terminal",
|
"ssh/terminal",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "f416ebab96af27ca70b6e5c23d6a0747530da626"
|
revision = "34f69633bfdcf9db92f698f8487115767eebef81"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:52d140f7ab52e491cc1cbc93e6637aa5e9a7f3beae7545d675b02e52ca9d7290"
|
digest = "1:ded5b1b804f079c993f887e0da394aa54cdf8d2a6a31e62c66d94ebe6f75bc2a"
|
||||||
name = "golang.org/x/net"
|
name = "golang.org/x/net"
|
||||||
packages = [
|
packages = [
|
||||||
"bpf",
|
"bpf",
|
||||||
|
@ -497,7 +471,7 @@
|
||||||
"websocket",
|
"websocket",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "1da14a5a36f220ea3f03470682b737b1dfd5de22"
|
revision = "72f939374954d0a1b2a1e27dcda950e2724dd5c1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:39ebcc2b11457b703ae9ee2e8cca0f68df21969c6102cb3b705f76cca0ea0239"
|
digest = "1:39ebcc2b11457b703ae9ee2e8cca0f68df21969c6102cb3b705f76cca0ea0239"
|
||||||
|
@ -508,7 +482,7 @@
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:77751d02e939d7078faedaeec10c09af575a09c528d84d18f2cb45a84bd1889a"
|
digest = "1:122914ab6dc8ee219eeb0d11276704e7ac3854feb55dad10f71081b9639ed28e"
|
||||||
name = "golang.org/x/sys"
|
name = "golang.org/x/sys"
|
||||||
packages = [
|
packages = [
|
||||||
"cpu",
|
"cpu",
|
||||||
|
@ -520,16 +494,18 @@
|
||||||
"windows/svc/mgr",
|
"windows/svc/mgr",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "12500544f89f9420afe9529ba8940bf72d294972"
|
revision = "543471e840be449c53d44b32c7adf1261ad67e37"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
|
digest = "1:8d8faad6b12a3a4c819a3f9618cb6ee1fa1cfc33253abeeea8b55336721e3405"
|
||||||
name = "golang.org/x/text"
|
name = "golang.org/x/text"
|
||||||
packages = [
|
packages = [
|
||||||
"collate",
|
"collate",
|
||||||
"collate/build",
|
"collate/build",
|
||||||
"internal/colltab",
|
"internal/colltab",
|
||||||
"internal/gen",
|
"internal/gen",
|
||||||
|
"internal/language",
|
||||||
|
"internal/language/compact",
|
||||||
"internal/tag",
|
"internal/tag",
|
||||||
"internal/triegen",
|
"internal/triegen",
|
||||||
"internal/ucd",
|
"internal/ucd",
|
||||||
|
@ -542,19 +518,19 @@
|
||||||
"unicode/rangetable",
|
"unicode/rangetable",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||||
version = "v0.3.0"
|
version = "v0.3.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:c3076e7defee87de1236f1814beb588f40a75544c60121e6eb38b3b3721783e2"
|
digest = "1:583a0c80f5e3a9343d33aea4aead1e1afcc0043db66fdf961ddd1fe8cd3a4faf"
|
||||||
name = "google.golang.org/genproto"
|
name = "google.golang.org/genproto"
|
||||||
packages = ["googleapis/rpc/status"]
|
packages = ["googleapis/rpc/status"]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "d1146b9035b912113a38af3b138eb2af567b2c67"
|
revision = "a023cd5227bd25fd1f5c5633743ff3eacc93d169"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:31d87f39886fb38a2b6c097ff3b9f985d6960772170d64a68246f7790e955746"
|
digest = "1:6cd77d0b616d2dcebd363dfecba593f27b0151fc82cdb5fbfb96c5a7cfbc95b5"
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
packages = [
|
packages = [
|
||||||
".",
|
".",
|
||||||
|
@ -586,13 +562,14 @@
|
||||||
"resolver",
|
"resolver",
|
||||||
"resolver/dns",
|
"resolver/dns",
|
||||||
"resolver/passthrough",
|
"resolver/passthrough",
|
||||||
|
"serviceconfig",
|
||||||
"stats",
|
"stats",
|
||||||
"status",
|
"status",
|
||||||
"tap",
|
"tap",
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "236199dd5f8031d698fb64091194aecd1c3895b2"
|
revision = "f6d0f9ee430895e87ef1ceb5ac8f39725bafceef"
|
||||||
version = "v1.20.0"
|
version = "v1.24.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "altsrc-parse-durations"
|
branch = "altsrc-parse-durations"
|
||||||
|
@ -607,12 +584,12 @@
|
||||||
source = "https://github.com/cbranch/cli"
|
source = "https://github.com/cbranch/cli"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
|
digest = "1:59f10c1537d2199d9115d946927fe31165959a95190849c82ff11e05803528b0"
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
pruneopts = "UT"
|
||||||
revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
|
revision = "f221b8435cfb71e54062f6c6e99e9ade30b124d5"
|
||||||
version = "v2.2.2"
|
version = "v2.2.4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:8ffc3ddc31414c0a71220957bb723b16510d7fcb5b3880dc0da4cf6d39c31642"
|
digest = "1:8ffc3ddc31414c0a71220957bb723b16510d7fcb5b3880dc0da4cf6d39c31642"
|
||||||
|
@ -642,7 +619,6 @@
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
input-imports = [
|
input-imports = [
|
||||||
"github.com/DATA-DOG/go-sqlmock",
|
|
||||||
"github.com/aws/aws-sdk-go/aws",
|
"github.com/aws/aws-sdk-go/aws",
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials",
|
"github.com/aws/aws-sdk-go/aws/credentials",
|
||||||
"github.com/aws/aws-sdk-go/aws/session",
|
"github.com/aws/aws-sdk-go/aws/session",
|
||||||
|
@ -658,7 +634,6 @@
|
||||||
"github.com/coredns/coredns/request",
|
"github.com/coredns/coredns/request",
|
||||||
"github.com/coreos/go-oidc/jose",
|
"github.com/coreos/go-oidc/jose",
|
||||||
"github.com/coreos/go-systemd/daemon",
|
"github.com/coreos/go-systemd/daemon",
|
||||||
"github.com/creack/pty",
|
|
||||||
"github.com/elgs/gosqljson",
|
"github.com/elgs/gosqljson",
|
||||||
"github.com/equinox-io/equinox",
|
"github.com/equinox-io/equinox",
|
||||||
"github.com/facebookgo/grace/gracenet",
|
"github.com/facebookgo/grace/gracenet",
|
||||||
|
@ -672,13 +647,11 @@
|
||||||
"github.com/mattn/go-colorable",
|
"github.com/mattn/go-colorable",
|
||||||
"github.com/miekg/dns",
|
"github.com/miekg/dns",
|
||||||
"github.com/mitchellh/go-homedir",
|
"github.com/mitchellh/go-homedir",
|
||||||
"github.com/mitchellh/mapstructure",
|
|
||||||
"github.com/pkg/errors",
|
"github.com/pkg/errors",
|
||||||
"github.com/prometheus/client_golang/prometheus",
|
"github.com/prometheus/client_golang/prometheus",
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp",
|
"github.com/prometheus/client_golang/prometheus/promhttp",
|
||||||
"github.com/rifflock/lfshook",
|
"github.com/rifflock/lfshook",
|
||||||
"github.com/sirupsen/logrus",
|
"github.com/sirupsen/logrus",
|
||||||
"github.com/sirupsen/logrus/hooks/test",
|
|
||||||
"github.com/stretchr/testify/assert",
|
"github.com/stretchr/testify/assert",
|
||||||
"github.com/stretchr/testify/require",
|
"github.com/stretchr/testify/require",
|
||||||
"golang.org/x/crypto/nacl/box",
|
"golang.org/x/crypto/nacl/box",
|
||||||
|
|
|
@ -86,13 +86,9 @@
|
||||||
name = "github.com/google/uuid"
|
name = "github.com/google/uuid"
|
||||||
version = "=1.1.1"
|
version = "=1.1.1"
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/mitchellh/mapstructure"
|
|
||||||
version = "1.1.2"
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/gliderlabs/ssh"
|
name = "github.com/gliderlabs/ssh"
|
||||||
version = "0.2.2"
|
revision = "63518b5243e0fe306cc35cb382f459de123e550e"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/aws/aws-sdk-go"
|
name = "github.com/aws/aws-sdk-go"
|
||||||
|
|
|
@ -34,6 +34,12 @@ func ssh(c *cli.Context) error {
|
||||||
headers.Add("CF-Access-Client-Secret", c.String(sshTokenSecretFlag))
|
headers.Add("CF-Access-Client-Secret", c.String(sshTokenSecretFlag))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destination := c.String(sshDestinationFlag)
|
||||||
|
if destination == "" {
|
||||||
|
return cli.ShowCommandHelp(c, "ssh")
|
||||||
|
}
|
||||||
|
headers.Add("CF-Access-SSH-Destination", destination)
|
||||||
|
|
||||||
options := &carrier.StartOptions{
|
options := &carrier.StartOptions{
|
||||||
OriginURL: originURL,
|
OriginURL: originURL,
|
||||||
Headers: headers,
|
Headers: headers,
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sshHostnameFlag = "hostname"
|
sshHostnameFlag = "hostname"
|
||||||
|
sshDestinationFlag = "destination"
|
||||||
sshURLFlag = "url"
|
sshURLFlag = "url"
|
||||||
sshHeaderFlag = "header"
|
sshHeaderFlag = "header"
|
||||||
sshTokenIDFlag = "service-token-id"
|
sshTokenIDFlag = "service-token-id"
|
||||||
|
@ -127,6 +128,10 @@ func Commands() []*cli.Command {
|
||||||
Name: sshHostnameFlag,
|
Name: sshHostnameFlag,
|
||||||
Usage: "specify the hostname of your application.",
|
Usage: "specify the hostname of your application.",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: sshDestinationFlag,
|
||||||
|
Usage: "specify the destination address of your SSH server.",
|
||||||
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: sshURLFlag,
|
Name: sshURLFlag,
|
||||||
Usage: "specify the host:port to forward data to Cloudflare edge.",
|
Usage: "specify the host:port to forward data to Cloudflare edge.",
|
||||||
|
|
|
@ -45,7 +45,7 @@ import (
|
||||||
const (
|
const (
|
||||||
sentryDSN = "https://56a9c9fa5c364ab28f34b14f35ea0f1b:3e8827f6f9f740738eb11138f7bebb68@sentry.io/189878"
|
sentryDSN = "https://56a9c9fa5c364ab28f34b14f35ea0f1b:3e8827f6f9f740738eb11138f7bebb68@sentry.io/189878"
|
||||||
|
|
||||||
sshLogFileDirectory = "/var/log/cloudflared/"
|
sshLogFileDirectory = "/usr/local/var/log/cloudflared/"
|
||||||
|
|
||||||
// sshPortFlag is the port on localhost the cloudflared ssh server will run on
|
// sshPortFlag is the port on localhost the cloudflared ssh server will run on
|
||||||
sshPortFlag = "local-ssh-port"
|
sshPortFlag = "local-ssh-port"
|
||||||
|
@ -383,7 +383,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||||
return errors.Wrap(err, msg)
|
return errors.Wrap(err, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(sshLogFileDirectory, 0600); err != nil {
|
if err := os.MkdirAll(sshLogFileDirectory, 0700); err != nil {
|
||||||
msg := fmt.Sprintf("Cannot create SSH log file directory %s", sshLogFileDirectory)
|
msg := fmt.Sprintf("Cannot create SSH log file directory %s", sshLogFileDirectory)
|
||||||
logger.WithError(err).Errorf(msg)
|
logger.WithError(err).Errorf(msg)
|
||||||
return errors.Wrap(err, msg)
|
return errors.Wrap(err, msg)
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
package sshserver
|
package sshserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/url"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -28,6 +30,8 @@ const (
|
||||||
auditEventShell = "shell"
|
auditEventShell = "shell"
|
||||||
sshContextSessionID = "sessionID"
|
sshContextSessionID = "sessionID"
|
||||||
sshContextEventLogger = "eventLogger"
|
sshContextEventLogger = "eventLogger"
|
||||||
|
sshContextDestination = "sshDest"
|
||||||
|
sshPreambleLength = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
type auditEvent struct {
|
type auditEvent struct {
|
||||||
|
@ -37,7 +41,7 @@ type auditEvent struct {
|
||||||
User string `json:"user,omitempty"`
|
User string `json:"user,omitempty"`
|
||||||
Login string `json:"login,omitempty"`
|
Login string `json:"login,omitempty"`
|
||||||
Datetime string `json:"datetime,omitempty"`
|
Datetime string `json:"datetime,omitempty"`
|
||||||
IPAddress string `json:"ip_address,omitempty"`
|
Destination string `json:"destination,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SSHProxy struct {
|
type SSHProxy struct {
|
||||||
|
@ -61,18 +65,12 @@ func New(logManager sshlog.Manager, logger *logrus.Logger, version, address stri
|
||||||
MaxTimeout: maxTimeout,
|
MaxTimeout: maxTimeout,
|
||||||
IdleTimeout: idleTimeout,
|
IdleTimeout: idleTimeout,
|
||||||
Version: fmt.Sprintf("SSH-2.0-Cloudflare-Access_%s_%s", version, runtime.GOOS),
|
Version: fmt.Sprintf("SSH-2.0-Cloudflare-Access_%s_%s", version, runtime.GOOS),
|
||||||
|
ConnCallback: sshProxy.connCallback,
|
||||||
ChannelHandlers: map[string]ssh.ChannelHandler{
|
ChannelHandlers: map[string]ssh.ChannelHandler{
|
||||||
"session": sshProxy.channelHandler,
|
"default": sshProxy.channelHandler,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUTH-2050: This is a temporary workaround of a timing issue in the tunnel muxer to allow further testing.
|
|
||||||
// TODO: Remove this
|
|
||||||
sshProxy.ConnCallback = func(conn net.Conn) net.Conn {
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
return conn
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := sshProxy.configureHostKeys(); err != nil {
|
if err := sshProxy.configureHostKeys(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -94,25 +92,36 @@ func (s *SSHProxy) Start() error {
|
||||||
return s.ListenAndServe()
|
return s.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SSHProxy) connCallback(ctx ssh.Context, conn net.Conn) net.Conn {
|
||||||
|
// AUTH-2050: This is a temporary workaround of a timing issue in the tunnel muxer to allow further testing.
|
||||||
|
// TODO: Remove this
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
if err := s.configureSSHDestination(conn, ctx); err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
s.logger.WithError(err).Error("failed to read SSH destination")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.configureLogger(ctx); err != nil {
|
||||||
|
s.logger.WithError(err).Error("failed to configure logger")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return conn
|
||||||
|
}
|
||||||
|
|
||||||
// channelHandler proxies incoming and outgoing SSH traffic back and forth over an SSH Channel
|
// channelHandler proxies incoming and outgoing SSH traffic back and forth over an SSH Channel
|
||||||
func (s *SSHProxy) channelHandler(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context) {
|
func (s *SSHProxy) channelHandler(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context) {
|
||||||
if err := s.configureAuditLogger(ctx); err != nil {
|
if newChan.ChannelType() != "session" && newChan.ChannelType() != "direct-tcpip" {
|
||||||
s.logger.WithError(err).Error("Failed to configure audit logging")
|
msg := fmt.Sprintf("channel type %s is not supported", newChan.ChannelType())
|
||||||
|
s.logger.Info(msg)
|
||||||
|
if err := newChan.Reject(gossh.UnknownChannelType, msg); err != nil {
|
||||||
|
s.logger.WithError(err).Error("Error rejecting SSH channel")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
clientConfig := &gossh.ClientConfig{
|
|
||||||
User: conn.User(),
|
|
||||||
// AUTH-2103 TODO: proper host key check
|
|
||||||
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
|
|
||||||
// AUTH-2114 TODO: replace with short lived cert auth
|
|
||||||
Auth: []gossh.AuthMethod{gossh.Password("test")},
|
|
||||||
ClientVersion: s.Version,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch newChan.ChannelType() {
|
|
||||||
case "session":
|
|
||||||
// Accept incoming channel request from client
|
|
||||||
localChan, localChanReqs, err := newChan.Accept()
|
localChan, localChanReqs, err := newChan.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.WithError(err).Error("Failed to accept session channel")
|
s.logger.WithError(err).Error("Failed to accept session channel")
|
||||||
|
@ -120,17 +129,15 @@ func (s *SSHProxy) channelHandler(srv *ssh.Server, conn *gossh.ServerConn, newCh
|
||||||
}
|
}
|
||||||
defer localChan.Close()
|
defer localChan.Close()
|
||||||
|
|
||||||
// AUTH-2088 TODO: retrieve ssh target from tunnel
|
// AUTH-2136 TODO: multiplex ssh client between channels
|
||||||
// Create outgoing ssh connection to destination SSH server
|
client, err := s.createSSHClient(ctx)
|
||||||
client, err := gossh.Dial("tcp", "localhost:22", clientConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.WithError(err).Error("Failed to dial remote server")
|
s.logger.WithError(err).Error("Failed to dial remote server")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
// Open channel session channel to destination server
|
remoteChan, remoteChanReqs, err := client.OpenChannel(newChan.ChannelType(), newChan.ExtraData())
|
||||||
remoteChan, remoteChanReqs, err := client.OpenChannel("session", []byte{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.WithError(err).Error("Failed to open remote channel")
|
s.logger.WithError(err).Error("Failed to open remote channel")
|
||||||
return
|
return
|
||||||
|
@ -141,7 +148,6 @@ func (s *SSHProxy) channelHandler(srv *ssh.Server, conn *gossh.ServerConn, newCh
|
||||||
// Proxy ssh traffic back and forth between client and destination
|
// Proxy ssh traffic back and forth between client and destination
|
||||||
s.proxyChannel(localChan, remoteChan, localChanReqs, remoteChanReqs, conn, ctx)
|
s.proxyChannel(localChan, remoteChan, localChanReqs, remoteChanReqs, conn, ctx)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// proxyChannel couples two SSH channels and proxies SSH traffic and channel requests back and forth.
|
// proxyChannel couples two SSH channels and proxies SSH traffic and channel requests back and forth.
|
||||||
func (s *SSHProxy) proxyChannel(localChan, remoteChan gossh.Channel, localChanReqs, remoteChanReqs <-chan *gossh.Request, conn *gossh.ServerConn, ctx ssh.Context) {
|
func (s *SSHProxy) proxyChannel(localChan, remoteChan gossh.Channel, localChanReqs, remoteChanReqs <-chan *gossh.Request, conn *gossh.ServerConn, ctx ssh.Context) {
|
||||||
|
@ -190,6 +196,54 @@ func (s *SSHProxy) proxyChannel(localChan, remoteChan gossh.Channel, localChanRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// configureSSHDestination reads a preamble from the SSH connection before any SSH traffic is sent.
|
||||||
|
// This preamble contains the ultimate SSH destination the proxy will connect too.
|
||||||
|
// The first 4 bytes contain the length of the destination which follows immediately.
|
||||||
|
func (s *SSHProxy) configureSSHDestination(conn net.Conn, ctx ssh.Context) error {
|
||||||
|
size := make([]byte, sshPreambleLength)
|
||||||
|
if _, err := io.ReadFull(conn, size); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
payloadLength := binary.BigEndian.Uint32(size)
|
||||||
|
data := make([]byte, payloadLength)
|
||||||
|
if _, err := io.ReadFull(conn, data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
destAddr := string(data)
|
||||||
|
destUrl, err := url.Parse(destAddr)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to parse URL")
|
||||||
|
}
|
||||||
|
if destUrl.Port() == "" {
|
||||||
|
destAddr += ":22"
|
||||||
|
}
|
||||||
|
ctx.SetValue(sshContextDestination, destAddr)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// createSSHClient creates a new SSH client and dials the destination server
|
||||||
|
func (s *SSHProxy) createSSHClient(ctx ssh.Context) (*gossh.Client, error) {
|
||||||
|
clientConfig := &gossh.ClientConfig{
|
||||||
|
User: ctx.User(),
|
||||||
|
// AUTH-2103 TODO: proper host key check
|
||||||
|
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
|
||||||
|
// AUTH-2114 TODO: replace with short lived cert auth
|
||||||
|
Auth: []gossh.AuthMethod{gossh.Password("test")},
|
||||||
|
ClientVersion: ctx.ServerVersion(),
|
||||||
|
}
|
||||||
|
|
||||||
|
address, ok := ctx.Value(sshContextDestination).(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("failed to retrieve SSH destination from context")
|
||||||
|
}
|
||||||
|
client, err := gossh.Dial("tcp", address, clientConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
// forwardChannelRequest sends request req to SSH channel sshChan, waits for reply, and sends the reply back.
|
// forwardChannelRequest sends request req to SSH channel sshChan, waits for reply, and sends the reply back.
|
||||||
func (s *SSHProxy) forwardChannelRequest(sshChan gossh.Channel, req *gossh.Request) error {
|
func (s *SSHProxy) forwardChannelRequest(sshChan gossh.Channel, req *gossh.Request) error {
|
||||||
reply, err := sshChan.SendRequest(req.Type, req.WantReply, req.Payload)
|
reply, err := sshChan.SendRequest(req.Type, req.WantReply, req.Payload)
|
||||||
|
@ -222,37 +276,39 @@ func (s *SSHProxy) logChannelRequest(req *gossh.Request, conn *gossh.ServerConn,
|
||||||
eventType = auditEventShell
|
eventType = auditEventShell
|
||||||
case "window-change":
|
case "window-change":
|
||||||
eventType = auditEventResize
|
eventType = auditEventResize
|
||||||
|
default:
|
||||||
|
return
|
||||||
}
|
}
|
||||||
s.logAuditEvent(conn, event, eventType, ctx)
|
s.logAuditEvent(conn, event, eventType, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSHProxy) configureAuditLogger(ctx ssh.Context) error {
|
func (s *SSHProxy) configureLogger(ctx ssh.Context) error {
|
||||||
sessionUUID, err := uuid.NewRandom()
|
sessionUUID, err := uuid.NewRandom()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to generate session ID")
|
return errors.Wrap(err, "failed to create sessionID")
|
||||||
}
|
}
|
||||||
sessionID := sessionUUID.String()
|
sessionID := sessionUUID.String()
|
||||||
|
|
||||||
eventLogger, err := s.logManager.NewLogger(fmt.Sprintf("%s-event.log", sessionID), s.logger)
|
writer, err := s.logManager.NewLogger(fmt.Sprintf("%s-event.log", sessionID), s.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to create event log")
|
return errors.Wrap(err, "failed to create logger")
|
||||||
}
|
}
|
||||||
|
ctx.SetValue(sshContextEventLogger, writer)
|
||||||
ctx.SetValue(sshContextSessionID, sessionID)
|
ctx.SetValue(sshContextSessionID, sessionID)
|
||||||
ctx.SetValue(sshContextEventLogger, eventLogger)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSHProxy) logAuditEvent(conn *gossh.ServerConn, event, eventType string, ctx ssh.Context) {
|
func (s *SSHProxy) logAuditEvent(conn *gossh.ServerConn, event, eventType string, ctx ssh.Context) {
|
||||||
sessionID, ok := ctx.Value(sshContextSessionID).(string)
|
sessionID, sessionIDOk := ctx.Value(sshContextSessionID).(string)
|
||||||
if !ok {
|
writer, writerOk := ctx.Value(sshContextEventLogger).(io.WriteCloser)
|
||||||
s.logger.Error("Failed to retrieve sessionID from context")
|
if !writerOk || !sessionIDOk {
|
||||||
|
s.logger.Error("Failed to retrieve audit logger from context")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writer, ok := ctx.Value(sshContextEventLogger).(io.WriteCloser)
|
|
||||||
if !ok {
|
destination, destOk := ctx.Value(sshContextDestination).(string)
|
||||||
s.logger.Error("Failed to retrieve eventLogger from context")
|
if !destOk {
|
||||||
return
|
s.logger.Error("Failed to retrieve SSH destination from context")
|
||||||
}
|
}
|
||||||
|
|
||||||
ae := auditEvent{
|
ae := auditEvent{
|
||||||
|
@ -262,7 +318,7 @@ func (s *SSHProxy) logAuditEvent(conn *gossh.ServerConn, event, eventType string
|
||||||
User: conn.User(),
|
User: conn.User(),
|
||||||
Login: conn.User(),
|
Login: conn.User(),
|
||||||
Datetime: time.Now().UTC().Format(time.RFC3339),
|
Datetime: time.Now().UTC().Format(time.RFC3339),
|
||||||
IPAddress: conn.RemoteAddr().String(),
|
Destination: destination,
|
||||||
}
|
}
|
||||||
data, err := json.Marshal(&ae)
|
data, err := json.Marshal(&ae)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -273,5 +329,4 @@ func (s *SSHProxy) logAuditEvent(conn *gossh.ServerConn, event, eventType string
|
||||||
if _, err := writer.Write([]byte(line)); err != nil {
|
if _, err := writer.Write([]byte(line)); err != nil {
|
||||||
s.logger.WithError(err).Error("Failed to write audit event.")
|
s.logger.WithError(err).Error("Failed to write audit event.")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, op
|
||||||
default:
|
default:
|
||||||
maxRetries := aws.IntValue(cfg.MaxRetries)
|
maxRetries := aws.IntValue(cfg.MaxRetries)
|
||||||
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
|
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
|
||||||
maxRetries = 3
|
maxRetries = DefaultRetryerMaxNumRetries
|
||||||
}
|
}
|
||||||
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
|
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -9,69 +10,142 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultRetryer implements basic retry logic using exponential backoff for
|
// DefaultRetryer implements basic retry logic using exponential backoff for
|
||||||
// most services. If you want to implement custom retry logic, implement the
|
// most services. If you want to implement custom retry logic, you can implement the
|
||||||
// request.Retryer interface or create a structure type that composes this
|
// request.Retryer interface.
|
||||||
// struct and override the specific methods. For example, to override only
|
|
||||||
// the MaxRetries method:
|
|
||||||
//
|
//
|
||||||
// type retryer struct {
|
|
||||||
// client.DefaultRetryer
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // This implementation always has 100 max retries
|
|
||||||
// func (d retryer) MaxRetries() int { return 100 }
|
|
||||||
type DefaultRetryer struct {
|
type DefaultRetryer struct {
|
||||||
|
// Num max Retries is the number of max retries that will be performed.
|
||||||
|
// By default, this is zero.
|
||||||
NumMaxRetries int
|
NumMaxRetries int
|
||||||
|
|
||||||
|
// MinRetryDelay is the minimum retry delay after which retry will be performed.
|
||||||
|
// If not set, the value is 0ns.
|
||||||
|
MinRetryDelay time.Duration
|
||||||
|
|
||||||
|
// MinThrottleRetryDelay is the minimum retry delay when throttled.
|
||||||
|
// If not set, the value is 0ns.
|
||||||
|
MinThrottleDelay time.Duration
|
||||||
|
|
||||||
|
// MaxRetryDelay is the maximum retry delay before which retry must be performed.
|
||||||
|
// If not set, the value is 0ns.
|
||||||
|
MaxRetryDelay time.Duration
|
||||||
|
|
||||||
|
// MaxThrottleDelay is the maximum retry delay when throttled.
|
||||||
|
// If not set, the value is 0ns.
|
||||||
|
MaxThrottleDelay time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultRetryerMaxNumRetries sets maximum number of retries
|
||||||
|
DefaultRetryerMaxNumRetries = 3
|
||||||
|
|
||||||
|
// DefaultRetryerMinRetryDelay sets minimum retry delay
|
||||||
|
DefaultRetryerMinRetryDelay = 30 * time.Millisecond
|
||||||
|
|
||||||
|
// DefaultRetryerMinThrottleDelay sets minimum delay when throttled
|
||||||
|
DefaultRetryerMinThrottleDelay = 500 * time.Millisecond
|
||||||
|
|
||||||
|
// DefaultRetryerMaxRetryDelay sets maximum retry delay
|
||||||
|
DefaultRetryerMaxRetryDelay = 300 * time.Second
|
||||||
|
|
||||||
|
// DefaultRetryerMaxThrottleDelay sets maximum delay when throttled
|
||||||
|
DefaultRetryerMaxThrottleDelay = 300 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
// MaxRetries returns the number of maximum returns the service will use to make
|
// MaxRetries returns the number of maximum returns the service will use to make
|
||||||
// an individual API request.
|
// an individual API request.
|
||||||
func (d DefaultRetryer) MaxRetries() int {
|
func (d DefaultRetryer) MaxRetries() int {
|
||||||
return d.NumMaxRetries
|
return d.NumMaxRetries
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetryRules returns the delay duration before retrying this request again
|
// setRetryerDefaults sets the default values of the retryer if not set
|
||||||
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
func (d *DefaultRetryer) setRetryerDefaults() {
|
||||||
// Set the upper limit of delay in retrying at ~five minutes
|
if d.MinRetryDelay == 0 {
|
||||||
minTime := 30
|
d.MinRetryDelay = DefaultRetryerMinRetryDelay
|
||||||
isThrottle := r.IsErrorThrottle()
|
}
|
||||||
if isThrottle {
|
if d.MaxRetryDelay == 0 {
|
||||||
if delay, ok := getRetryDelay(r); ok {
|
d.MaxRetryDelay = DefaultRetryerMaxRetryDelay
|
||||||
return delay
|
}
|
||||||
|
if d.MinThrottleDelay == 0 {
|
||||||
|
d.MinThrottleDelay = DefaultRetryerMinThrottleDelay
|
||||||
|
}
|
||||||
|
if d.MaxThrottleDelay == 0 {
|
||||||
|
d.MaxThrottleDelay = DefaultRetryerMaxThrottleDelay
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minTime = 500
|
// RetryRules returns the delay duration before retrying this request again
|
||||||
|
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
||||||
|
|
||||||
|
// if number of max retries is zero, no retries will be performed.
|
||||||
|
if d.NumMaxRetries == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets default value for retryer members
|
||||||
|
d.setRetryerDefaults()
|
||||||
|
|
||||||
|
// minDelay is the minimum retryer delay
|
||||||
|
minDelay := d.MinRetryDelay
|
||||||
|
|
||||||
|
var initialDelay time.Duration
|
||||||
|
|
||||||
|
isThrottle := r.IsErrorThrottle()
|
||||||
|
if isThrottle {
|
||||||
|
if delay, ok := getRetryAfterDelay(r); ok {
|
||||||
|
initialDelay = delay
|
||||||
|
}
|
||||||
|
minDelay = d.MinThrottleDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
retryCount := r.RetryCount
|
retryCount := r.RetryCount
|
||||||
if isThrottle && retryCount > 8 {
|
|
||||||
retryCount = 8
|
// maxDelay the maximum retryer delay
|
||||||
} else if retryCount > 13 {
|
maxDelay := d.MaxRetryDelay
|
||||||
retryCount = 13
|
|
||||||
|
if isThrottle {
|
||||||
|
maxDelay = d.MaxThrottleDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
delay := (1 << uint(retryCount)) * (sdkrand.SeededRand.Intn(minTime) + minTime)
|
var delay time.Duration
|
||||||
return time.Duration(delay) * time.Millisecond
|
|
||||||
|
// Logic to cap the retry count based on the minDelay provided
|
||||||
|
actualRetryCount := int(math.Log2(float64(minDelay))) + 1
|
||||||
|
if actualRetryCount < 63-retryCount {
|
||||||
|
delay = time.Duration(1<<uint64(retryCount)) * getJitterDelay(minDelay)
|
||||||
|
if delay > maxDelay {
|
||||||
|
delay = getJitterDelay(maxDelay / 2)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delay = getJitterDelay(maxDelay / 2)
|
||||||
|
}
|
||||||
|
return delay + initialDelay
|
||||||
|
}
|
||||||
|
|
||||||
|
// getJitterDelay returns a jittered delay for retry
|
||||||
|
func getJitterDelay(duration time.Duration) time.Duration {
|
||||||
|
return time.Duration(sdkrand.SeededRand.Int63n(int64(duration)) + int64(duration))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldRetry returns true if the request should be retried.
|
// ShouldRetry returns true if the request should be retried.
|
||||||
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
||||||
|
|
||||||
|
// ShouldRetry returns false if number of max retries is 0.
|
||||||
|
if d.NumMaxRetries == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// If one of the other handlers already set the retry state
|
// If one of the other handlers already set the retry state
|
||||||
// we don't want to override it based on the service's state
|
// we don't want to override it based on the service's state
|
||||||
if r.Retryable != nil {
|
if r.Retryable != nil {
|
||||||
return *r.Retryable
|
return *r.Retryable
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.HTTPResponse.StatusCode >= 500 && r.HTTPResponse.StatusCode != 501 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.IsErrorRetryable() || r.IsErrorThrottle()
|
return r.IsErrorRetryable() || r.IsErrorThrottle()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will look in the Retry-After header, RFC 7231, for how long
|
// This will look in the Retry-After header, RFC 7231, for how long
|
||||||
// it will wait before attempting another request
|
// it will wait before attempting another request
|
||||||
func getRetryDelay(r *request.Request) (time.Duration, bool) {
|
func getRetryAfterDelay(r *request.Request) (time.Duration, bool) {
|
||||||
if !canUseRetryAfterHeader(r) {
|
if !canUseRetryAfterHeader(r) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoOpRetryer provides a retryer that performs no retries.
|
||||||
|
// It should be used when we do not want retries to be performed.
|
||||||
|
type NoOpRetryer struct{}
|
||||||
|
|
||||||
|
// MaxRetries returns the number of maximum returns the service will use to make
|
||||||
|
// an individual API; For NoOpRetryer the MaxRetries will always be zero.
|
||||||
|
func (d NoOpRetryer) MaxRetries() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldRetry will always return false for NoOpRetryer, as it should never retry.
|
||||||
|
func (d NoOpRetryer) ShouldRetry(_ *request.Request) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetryRules returns the delay duration before retrying this request again;
|
||||||
|
// since NoOpRetryer does not retry, RetryRules always returns 0.
|
||||||
|
func (d NoOpRetryer) RetryRules(_ *request.Request) time.Duration {
|
||||||
|
return 0
|
||||||
|
}
|
|
@ -179,6 +179,242 @@ func IntValueMap(src map[string]*int) map[string]int {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uint returns a pointer to the uint value passed in.
|
||||||
|
func Uint(v uint) *uint {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// UintValue returns the value of the uint pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func UintValue(v *uint) uint {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// UintSlice converts a slice of uint values uinto a slice of
|
||||||
|
// uint pointers
|
||||||
|
func UintSlice(src []uint) []*uint {
|
||||||
|
dst := make([]*uint, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UintValueSlice converts a slice of uint pointers uinto a slice of
|
||||||
|
// uint values
|
||||||
|
func UintValueSlice(src []*uint) []uint {
|
||||||
|
dst := make([]uint, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UintMap converts a string map of uint values uinto a string
|
||||||
|
// map of uint pointers
|
||||||
|
func UintMap(src map[string]uint) map[string]*uint {
|
||||||
|
dst := make(map[string]*uint)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// UintValueMap converts a string map of uint pointers uinto a string
|
||||||
|
// map of uint values
|
||||||
|
func UintValueMap(src map[string]*uint) map[string]uint {
|
||||||
|
dst := make(map[string]uint)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8 returns a pointer to the int8 value passed in.
|
||||||
|
func Int8(v int8) *int8 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8Value returns the value of the int8 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Int8Value(v *int8) int8 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8Slice converts a slice of int8 values into a slice of
|
||||||
|
// int8 pointers
|
||||||
|
func Int8Slice(src []int8) []*int8 {
|
||||||
|
dst := make([]*int8, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8ValueSlice converts a slice of int8 pointers into a slice of
|
||||||
|
// int8 values
|
||||||
|
func Int8ValueSlice(src []*int8) []int8 {
|
||||||
|
dst := make([]int8, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8Map converts a string map of int8 values into a string
|
||||||
|
// map of int8 pointers
|
||||||
|
func Int8Map(src map[string]int8) map[string]*int8 {
|
||||||
|
dst := make(map[string]*int8)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int8ValueMap converts a string map of int8 pointers into a string
|
||||||
|
// map of int8 values
|
||||||
|
func Int8ValueMap(src map[string]*int8) map[string]int8 {
|
||||||
|
dst := make(map[string]int8)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16 returns a pointer to the int16 value passed in.
|
||||||
|
func Int16(v int16) *int16 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16Value returns the value of the int16 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Int16Value(v *int16) int16 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16Slice converts a slice of int16 values into a slice of
|
||||||
|
// int16 pointers
|
||||||
|
func Int16Slice(src []int16) []*int16 {
|
||||||
|
dst := make([]*int16, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16ValueSlice converts a slice of int16 pointers into a slice of
|
||||||
|
// int16 values
|
||||||
|
func Int16ValueSlice(src []*int16) []int16 {
|
||||||
|
dst := make([]int16, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16Map converts a string map of int16 values into a string
|
||||||
|
// map of int16 pointers
|
||||||
|
func Int16Map(src map[string]int16) map[string]*int16 {
|
||||||
|
dst := make(map[string]*int16)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16ValueMap converts a string map of int16 pointers into a string
|
||||||
|
// map of int16 values
|
||||||
|
func Int16ValueMap(src map[string]*int16) map[string]int16 {
|
||||||
|
dst := make(map[string]int16)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32 returns a pointer to the int32 value passed in.
|
||||||
|
func Int32(v int32) *int32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32Value returns the value of the int32 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Int32Value(v *int32) int32 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32Slice converts a slice of int32 values into a slice of
|
||||||
|
// int32 pointers
|
||||||
|
func Int32Slice(src []int32) []*int32 {
|
||||||
|
dst := make([]*int32, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32ValueSlice converts a slice of int32 pointers into a slice of
|
||||||
|
// int32 values
|
||||||
|
func Int32ValueSlice(src []*int32) []int32 {
|
||||||
|
dst := make([]int32, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32Map converts a string map of int32 values into a string
|
||||||
|
// map of int32 pointers
|
||||||
|
func Int32Map(src map[string]int32) map[string]*int32 {
|
||||||
|
dst := make(map[string]*int32)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32ValueMap converts a string map of int32 pointers into a string
|
||||||
|
// map of int32 values
|
||||||
|
func Int32ValueMap(src map[string]*int32) map[string]int32 {
|
||||||
|
dst := make(map[string]int32)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
// Int64 returns a pointer to the int64 value passed in.
|
// Int64 returns a pointer to the int64 value passed in.
|
||||||
func Int64(v int64) *int64 {
|
func Int64(v int64) *int64 {
|
||||||
return &v
|
return &v
|
||||||
|
@ -238,6 +474,301 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uint8 returns a pointer to the uint8 value passed in.
|
||||||
|
func Uint8(v uint8) *uint8 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8Value returns the value of the uint8 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Uint8Value(v *uint8) uint8 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8Slice converts a slice of uint8 values into a slice of
|
||||||
|
// uint8 pointers
|
||||||
|
func Uint8Slice(src []uint8) []*uint8 {
|
||||||
|
dst := make([]*uint8, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8ValueSlice converts a slice of uint8 pointers into a slice of
|
||||||
|
// uint8 values
|
||||||
|
func Uint8ValueSlice(src []*uint8) []uint8 {
|
||||||
|
dst := make([]uint8, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8Map converts a string map of uint8 values into a string
|
||||||
|
// map of uint8 pointers
|
||||||
|
func Uint8Map(src map[string]uint8) map[string]*uint8 {
|
||||||
|
dst := make(map[string]*uint8)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint8ValueMap converts a string map of uint8 pointers into a string
|
||||||
|
// map of uint8 values
|
||||||
|
func Uint8ValueMap(src map[string]*uint8) map[string]uint8 {
|
||||||
|
dst := make(map[string]uint8)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16 returns a pointer to the uint16 value passed in.
|
||||||
|
func Uint16(v uint16) *uint16 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16Value returns the value of the uint16 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Uint16Value(v *uint16) uint16 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16Slice converts a slice of uint16 values into a slice of
|
||||||
|
// uint16 pointers
|
||||||
|
func Uint16Slice(src []uint16) []*uint16 {
|
||||||
|
dst := make([]*uint16, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16ValueSlice converts a slice of uint16 pointers into a slice of
|
||||||
|
// uint16 values
|
||||||
|
func Uint16ValueSlice(src []*uint16) []uint16 {
|
||||||
|
dst := make([]uint16, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16Map converts a string map of uint16 values into a string
|
||||||
|
// map of uint16 pointers
|
||||||
|
func Uint16Map(src map[string]uint16) map[string]*uint16 {
|
||||||
|
dst := make(map[string]*uint16)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint16ValueMap converts a string map of uint16 pointers into a string
|
||||||
|
// map of uint16 values
|
||||||
|
func Uint16ValueMap(src map[string]*uint16) map[string]uint16 {
|
||||||
|
dst := make(map[string]uint16)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32 returns a pointer to the uint32 value passed in.
|
||||||
|
func Uint32(v uint32) *uint32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32Value returns the value of the uint32 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Uint32Value(v *uint32) uint32 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32Slice converts a slice of uint32 values into a slice of
|
||||||
|
// uint32 pointers
|
||||||
|
func Uint32Slice(src []uint32) []*uint32 {
|
||||||
|
dst := make([]*uint32, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
|
||||||
|
// uint32 values
|
||||||
|
func Uint32ValueSlice(src []*uint32) []uint32 {
|
||||||
|
dst := make([]uint32, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32Map converts a string map of uint32 values into a string
|
||||||
|
// map of uint32 pointers
|
||||||
|
func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
||||||
|
dst := make(map[string]*uint32)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32ValueMap converts a string map of uint32 pointers into a string
|
||||||
|
// map of uint32 values
|
||||||
|
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
||||||
|
dst := make(map[string]uint32)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 returns a pointer to the uint64 value passed in.
|
||||||
|
func Uint64(v uint64) *uint64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64Value returns the value of the uint64 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Uint64Value(v *uint64) uint64 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64Slice converts a slice of uint64 values into a slice of
|
||||||
|
// uint64 pointers
|
||||||
|
func Uint64Slice(src []uint64) []*uint64 {
|
||||||
|
dst := make([]*uint64, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
|
||||||
|
// uint64 values
|
||||||
|
func Uint64ValueSlice(src []*uint64) []uint64 {
|
||||||
|
dst := make([]uint64, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64Map converts a string map of uint64 values into a string
|
||||||
|
// map of uint64 pointers
|
||||||
|
func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
||||||
|
dst := make(map[string]*uint64)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64ValueMap converts a string map of uint64 pointers into a string
|
||||||
|
// map of uint64 values
|
||||||
|
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
|
||||||
|
dst := make(map[string]uint64)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 returns a pointer to the float32 value passed in.
|
||||||
|
func Float32(v float32) *float32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32Value returns the value of the float32 pointer passed in or
|
||||||
|
// 0 if the pointer is nil.
|
||||||
|
func Float32Value(v *float32) float32 {
|
||||||
|
if v != nil {
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32Slice converts a slice of float32 values into a slice of
|
||||||
|
// float32 pointers
|
||||||
|
func Float32Slice(src []float32) []*float32 {
|
||||||
|
dst := make([]*float32, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
dst[i] = &(src[i])
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32ValueSlice converts a slice of float32 pointers into a slice of
|
||||||
|
// float32 values
|
||||||
|
func Float32ValueSlice(src []*float32) []float32 {
|
||||||
|
dst := make([]float32, len(src))
|
||||||
|
for i := 0; i < len(src); i++ {
|
||||||
|
if src[i] != nil {
|
||||||
|
dst[i] = *(src[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32Map converts a string map of float32 values into a string
|
||||||
|
// map of float32 pointers
|
||||||
|
func Float32Map(src map[string]float32) map[string]*float32 {
|
||||||
|
dst := make(map[string]*float32)
|
||||||
|
for k, val := range src {
|
||||||
|
v := val
|
||||||
|
dst[k] = &v
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32ValueMap converts a string map of float32 pointers into a string
|
||||||
|
// map of float32 values
|
||||||
|
func Float32ValueMap(src map[string]*float32) map[string]float32 {
|
||||||
|
dst := make(map[string]float32)
|
||||||
|
for k, val := range src {
|
||||||
|
if val != nil {
|
||||||
|
dst[k] = *val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
// Float64 returns a pointer to the float64 value passed in.
|
// Float64 returns a pointer to the float64 value passed in.
|
||||||
func Float64(v float64) *float64 {
|
func Float64(v float64) *float64 {
|
||||||
return &v
|
return &v
|
||||||
|
|
|
@ -16,25 +16,26 @@ var (
|
||||||
|
|
||||||
type metricChan struct {
|
type metricChan struct {
|
||||||
ch chan metric
|
ch chan metric
|
||||||
paused int64
|
paused *int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMetricChan(size int) metricChan {
|
func newMetricChan(size int) metricChan {
|
||||||
return metricChan{
|
return metricChan{
|
||||||
ch: make(chan metric, size),
|
ch: make(chan metric, size),
|
||||||
|
paused: new(int64),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ch *metricChan) Pause() {
|
func (ch *metricChan) Pause() {
|
||||||
atomic.StoreInt64(&ch.paused, pausedEnum)
|
atomic.StoreInt64(ch.paused, pausedEnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ch *metricChan) Continue() {
|
func (ch *metricChan) Continue() {
|
||||||
atomic.StoreInt64(&ch.paused, runningEnum)
|
atomic.StoreInt64(ch.paused, runningEnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ch *metricChan) IsPaused() bool {
|
func (ch *metricChan) IsPaused() bool {
|
||||||
v := atomic.LoadInt64(&ch.paused)
|
v := atomic.LoadInt64(ch.paused)
|
||||||
return v == pausedEnum
|
return v == pausedEnum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,7 @@ type EC2IAMInfo struct {
|
||||||
// an instance identity document
|
// an instance identity document
|
||||||
type EC2InstanceIdentityDocument struct {
|
type EC2InstanceIdentityDocument struct {
|
||||||
DevpayProductCodes []string `json:"devpayProductCodes"`
|
DevpayProductCodes []string `json:"devpayProductCodes"`
|
||||||
|
MarketplaceProductCodes []string `json:"marketplaceProductCodes"`
|
||||||
AvailabilityZone string `json:"availabilityZone"`
|
AvailabilityZone string `json:"availabilityZone"`
|
||||||
PrivateIP string `json:"privateIp"`
|
PrivateIP string `json:"privateIp"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
|
|
|
@ -11,6 +11,8 @@ const (
|
||||||
AwsPartitionID = "aws" // AWS Standard partition.
|
AwsPartitionID = "aws" // AWS Standard partition.
|
||||||
AwsCnPartitionID = "aws-cn" // AWS China partition.
|
AwsCnPartitionID = "aws-cn" // AWS China partition.
|
||||||
AwsUsGovPartitionID = "aws-us-gov" // AWS GovCloud (US) partition.
|
AwsUsGovPartitionID = "aws-us-gov" // AWS GovCloud (US) partition.
|
||||||
|
AwsIsoPartitionID = "aws-iso" // AWS ISO (US) partition.
|
||||||
|
AwsIsoBPartitionID = "aws-iso-b" // AWS ISOB (US) partition.
|
||||||
)
|
)
|
||||||
|
|
||||||
// AWS Standard partition's regions.
|
// AWS Standard partition's regions.
|
||||||
|
@ -47,8 +49,18 @@ const (
|
||||||
UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US).
|
UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US).
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AWS ISO (US) partition's regions.
|
||||||
|
const (
|
||||||
|
UsIsoEast1RegionID = "us-iso-east-1" // US ISO East.
|
||||||
|
)
|
||||||
|
|
||||||
|
// AWS ISOB (US) partition's regions.
|
||||||
|
const (
|
||||||
|
UsIsobEast1RegionID = "us-isob-east-1" // US ISOB East (Ohio).
|
||||||
|
)
|
||||||
|
|
||||||
// DefaultResolver returns an Endpoint resolver that will be able
|
// DefaultResolver returns an Endpoint resolver that will be able
|
||||||
// to resolve endpoints for: AWS Standard, AWS China, and AWS GovCloud (US).
|
// to resolve endpoints for: AWS Standard, AWS China, AWS GovCloud (US), AWS ISO (US), and AWS ISOB (US).
|
||||||
//
|
//
|
||||||
// Use DefaultPartitions() to get the list of the default partitions.
|
// Use DefaultPartitions() to get the list of the default partitions.
|
||||||
func DefaultResolver() Resolver {
|
func DefaultResolver() Resolver {
|
||||||
|
@ -56,7 +68,7 @@ func DefaultResolver() Resolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultPartitions returns a list of the partitions the SDK is bundled
|
// DefaultPartitions returns a list of the partitions the SDK is bundled
|
||||||
// with. The available partitions are: AWS Standard, AWS China, and AWS GovCloud (US).
|
// with. The available partitions are: AWS Standard, AWS China, AWS GovCloud (US), AWS ISO (US), and AWS ISOB (US).
|
||||||
//
|
//
|
||||||
// partitions := endpoints.DefaultPartitions
|
// partitions := endpoints.DefaultPartitions
|
||||||
// for _, p := range partitions {
|
// for _, p := range partitions {
|
||||||
|
@ -70,6 +82,8 @@ var defaultPartitions = partitions{
|
||||||
awsPartition,
|
awsPartition,
|
||||||
awscnPartition,
|
awscnPartition,
|
||||||
awsusgovPartition,
|
awsusgovPartition,
|
||||||
|
awsisoPartition,
|
||||||
|
awsisobPartition,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AwsPartition returns the Resolver for AWS Standard.
|
// AwsPartition returns the Resolver for AWS Standard.
|
||||||
|
@ -467,6 +481,12 @@ var awsPartition = partition{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"fips": endpoint{
|
||||||
|
Hostname: "appstream2-fips.us-west-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-west-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
|
@ -490,6 +510,7 @@ var awsPartition = partition{
|
||||||
"athena": service{
|
"athena": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-east-1": endpoint{},
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
@ -910,6 +931,7 @@ var awsPartition = partition{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
|
"eu-north-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
@ -1038,6 +1060,16 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"connect": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"cur": service{
|
"cur": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -1074,8 +1106,11 @@ var awsPartition = partition{
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
|
"eu-west-3": endpoint{},
|
||||||
"fips-us-east-1": endpoint{
|
"fips-us-east-1": endpoint{
|
||||||
Hostname: "datasync-fips.us-east-1.amazonaws.com",
|
Hostname: "datasync-fips.us-east-1.amazonaws.com",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -1100,6 +1135,7 @@ var awsPartition = partition{
|
||||||
Region: "us-west-2",
|
Region: "us-west-2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-1": endpoint{},
|
"us-west-1": endpoint{},
|
||||||
|
@ -1131,6 +1167,7 @@ var awsPartition = partition{
|
||||||
"directconnect": service{
|
"directconnect": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-east-1": endpoint{},
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
@ -1706,6 +1743,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1757,6 +1795,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-1-fips": endpoint{
|
"us-east-1-fips": endpoint{
|
||||||
|
@ -1846,6 +1885,7 @@ var awsPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-east-1": endpoint{},
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
@ -1857,6 +1897,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1942,6 +1983,7 @@ var awsPartition = partition{
|
||||||
},
|
},
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
@ -2217,6 +2259,7 @@ var awsPartition = partition{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
@ -2514,6 +2557,16 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"qldb": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"eu-west-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"ram": service{
|
"ram": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -2614,6 +2667,30 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"fips-us-east-1": endpoint{
|
||||||
|
Hostname: "resource-groups-fips.us-east-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fips-us-east-2": endpoint{
|
||||||
|
Hostname: "resource-groups-fips.us-east-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-east-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fips-us-west-1": endpoint{
|
||||||
|
Hostname: "resource-groups-fips.us-west-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-west-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fips-us-west-2": endpoint{
|
||||||
|
Hostname: "resource-groups-fips.us-west-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-west-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
"me-south-1": endpoint{},
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
@ -3023,6 +3100,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3133,6 +3211,7 @@ var awsPartition = partition{
|
||||||
"servicediscovery": service{
|
"servicediscovery": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-east-1": endpoint{},
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
@ -3140,9 +3219,11 @@ var awsPartition = partition{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
|
"eu-north-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3150,6 +3231,16 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"session.qldb": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"eu-west-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"shield": service{
|
"shield": service{
|
||||||
IsRegionalized: boxedFalse,
|
IsRegionalized: boxedFalse,
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
|
@ -4164,7 +4255,7 @@ var awscnPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"aws-cn-global": endpoint{
|
"aws-cn-global": endpoint{
|
||||||
Hostname: "support.cn-north-1.amazonaws.com",
|
Hostname: "support.cn-north-1.amazonaws.com.cn",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
Region: "cn-north-1",
|
Region: "cn-north-1",
|
||||||
},
|
},
|
||||||
|
@ -4698,6 +4789,7 @@ var awsusgovPartition = partition{
|
||||||
"ram": service{
|
"ram": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"us-gov-east-1": endpoint{},
|
||||||
"us-gov-west-1": endpoint{},
|
"us-gov-west-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -4721,6 +4813,25 @@ var awsusgovPartition = partition{
|
||||||
"us-gov-west-1": endpoint{},
|
"us-gov-west-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"resource-groups": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"fips-us-gov-east-1": endpoint{
|
||||||
|
Hostname: "resource-groups.us-gov-east-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-gov-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"fips-us-gov-west-1": endpoint{
|
||||||
|
Hostname: "resource-groups.us-gov-west-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-gov-west-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"us-gov-east-1": endpoint{},
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"route53": service{
|
"route53": service{
|
||||||
PartitionEndpoint: "aws-us-gov-global",
|
PartitionEndpoint: "aws-us-gov-global",
|
||||||
IsRegionalized: boxedFalse,
|
IsRegionalized: boxedFalse,
|
||||||
|
@ -4822,6 +4933,18 @@ var awsusgovPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"servicecatalog": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
"us-gov-west-1-fips": endpoint{
|
||||||
|
Hostname: "servicecatalog-fips.us-gov-west-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-gov-west-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"sms": service{
|
"sms": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -4947,3 +5070,612 @@ var awsusgovPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AwsIsoPartition returns the Resolver for AWS ISO (US).
|
||||||
|
func AwsIsoPartition() Partition {
|
||||||
|
return awsisoPartition.Partition()
|
||||||
|
}
|
||||||
|
|
||||||
|
var awsisoPartition = partition{
|
||||||
|
ID: "aws-iso",
|
||||||
|
Name: "AWS ISO (US)",
|
||||||
|
DNSSuffix: "c2s.ic.gov",
|
||||||
|
RegionRegex: regionRegex{
|
||||||
|
Regexp: func() *regexp.Regexp {
|
||||||
|
reg, _ := regexp.Compile("^us\\-iso\\-\\w+\\-\\d+$")
|
||||||
|
return reg
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
Defaults: endpoint{
|
||||||
|
Hostname: "{service}.{region}.{dnsSuffix}",
|
||||||
|
Protocols: []string{"https"},
|
||||||
|
SignatureVersions: []string{"v4"},
|
||||||
|
},
|
||||||
|
Regions: regions{
|
||||||
|
"us-iso-east-1": region{
|
||||||
|
Description: "US ISO East",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Services: services{
|
||||||
|
"api.ecr": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Hostname: "api.ecr.us-iso-east-1.c2s.ic.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-iso-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"application-autoscaling": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Hostname: "autoscaling.{region}.amazonaws.com",
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "application-autoscaling",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"autoscaling": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cloudformation": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cloudtrail": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"codedeploy": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"config": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"datapipeline": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"directconnect": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dms": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ds": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dynamodb": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ec2": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ec2metadata": service{
|
||||||
|
PartitionEndpoint: "aws-global",
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-global": endpoint{
|
||||||
|
Hostname: "169.254.169.254/latest",
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ecs": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"elasticache": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"elasticloadbalancing": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"elasticmapreduce": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"events": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"glacier": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"health": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iam": service{
|
||||||
|
PartitionEndpoint: "aws-iso-global",
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-iso-global": endpoint{
|
||||||
|
Hostname: "iam.us-iso-east-1.c2s.ic.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-iso-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kinesis": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kms": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ProdFips": endpoint{
|
||||||
|
Hostname: "kms-fips.us-iso-east-1.c2s.ic.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-iso-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"lambda": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"logs": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"monitoring": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"rds": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"redshift": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"route53": service{
|
||||||
|
PartitionEndpoint: "aws-iso-global",
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-iso-global": endpoint{
|
||||||
|
Hostname: "route53.c2s.ic.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-iso-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"s3": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
SignatureVersions: []string{"s3v4"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
SignatureVersions: []string{"s3v4"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"snowball": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sns": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sqs": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"states": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"streams.dynamodb": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "dynamodb",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sts": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"support": service{
|
||||||
|
PartitionEndpoint: "aws-iso-global",
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-iso-global": endpoint{
|
||||||
|
Hostname: "support.us-iso-east-1.c2s.ic.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-iso-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"swf": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"workspaces": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-iso-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// AwsIsoBPartition returns the Resolver for AWS ISOB (US).
|
||||||
|
func AwsIsoBPartition() Partition {
|
||||||
|
return awsisobPartition.Partition()
|
||||||
|
}
|
||||||
|
|
||||||
|
var awsisobPartition = partition{
|
||||||
|
ID: "aws-iso-b",
|
||||||
|
Name: "AWS ISOB (US)",
|
||||||
|
DNSSuffix: "sc2s.sgov.gov",
|
||||||
|
RegionRegex: regionRegex{
|
||||||
|
Regexp: func() *regexp.Regexp {
|
||||||
|
reg, _ := regexp.Compile("^us\\-isob\\-\\w+\\-\\d+$")
|
||||||
|
return reg
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
Defaults: endpoint{
|
||||||
|
Hostname: "{service}.{region}.{dnsSuffix}",
|
||||||
|
Protocols: []string{"https"},
|
||||||
|
SignatureVersions: []string{"v4"},
|
||||||
|
},
|
||||||
|
Regions: regions{
|
||||||
|
"us-isob-east-1": region{
|
||||||
|
Description: "US ISOB East (Ohio)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Services: services{
|
||||||
|
"application-autoscaling": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Hostname: "autoscaling.{region}.amazonaws.com",
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "application-autoscaling",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"autoscaling": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cloudformation": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cloudtrail": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"config": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"directconnect": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dms": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dynamodb": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ec2": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ec2metadata": service{
|
||||||
|
PartitionEndpoint: "aws-global",
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-global": endpoint{
|
||||||
|
Hostname: "169.254.169.254/latest",
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"elasticache": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"elasticloadbalancing": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{
|
||||||
|
Protocols: []string{"https"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"elasticmapreduce": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"events": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"glacier": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"health": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iam": service{
|
||||||
|
PartitionEndpoint: "aws-iso-b-global",
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-iso-b-global": endpoint{
|
||||||
|
Hostname: "iam.us-isob-east-1.sc2s.sgov.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-isob-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kinesis": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kms": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ProdFips": endpoint{
|
||||||
|
Hostname: "kms-fips.us-isob-east-1.sc2s.sgov.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-isob-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"logs": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"monitoring": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"rds": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"redshift": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"s3": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
SignatureVersions: []string{"s3v4"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"snowball": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sns": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sqs": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
SSLCommonName: "{region}.queue.{dnsSuffix}",
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"states": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"streams.dynamodb": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "dynamodb",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sts": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"support": service{
|
||||||
|
PartitionEndpoint: "aws-iso-b-global",
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-iso-b-global": endpoint{
|
||||||
|
Hostname: "support.us-isob-east-1.sc2s.sgov.gov",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-isob-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"swf": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-isob-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ type Handlers struct {
|
||||||
Complete HandlerList
|
Complete HandlerList
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy returns of this handler's lists.
|
// Copy returns a copy of this handler's lists.
|
||||||
func (h *Handlers) Copy() Handlers {
|
func (h *Handlers) Copy() Handlers {
|
||||||
return Handlers{
|
return Handlers{
|
||||||
Validate: h.Validate.copy(),
|
Validate: h.Validate.copy(),
|
||||||
|
@ -42,7 +42,7 @@ func (h *Handlers) Copy() Handlers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear removes callback functions for all handlers
|
// Clear removes callback functions for all handlers.
|
||||||
func (h *Handlers) Clear() {
|
func (h *Handlers) Clear() {
|
||||||
h.Validate.Clear()
|
h.Validate.Clear()
|
||||||
h.Build.Clear()
|
h.Build.Clear()
|
||||||
|
|
|
@ -94,10 +94,6 @@ var validParentCodes = map[string]struct{}{
|
||||||
ErrCodeRead: {},
|
ErrCodeRead: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
type temporaryError interface {
|
|
||||||
Temporary() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
||||||
if parentErr == nil {
|
if parentErr == nil {
|
||||||
return false
|
return false
|
||||||
|
@ -116,7 +112,7 @@ func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
||||||
return isCodeRetryable(aerr.Code())
|
return isCodeRetryable(aerr.Code())
|
||||||
}
|
}
|
||||||
|
|
||||||
if t, ok := err.(temporaryError); ok {
|
if t, ok := err.(temporary); ok {
|
||||||
return t.Temporary() || isErrConnectionReset(err)
|
return t.Temporary() || isErrConnectionReset(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +219,16 @@ func (r *Request) IsErrorRetryable() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTP response status code 501 should not be retried.
|
||||||
|
// 501 represents Not Implemented which means the request method is not
|
||||||
|
// supported by the server and cannot be handled.
|
||||||
|
if r.HTTPResponse != nil {
|
||||||
|
// HTTP response status code 500 represents internal server error and
|
||||||
|
// should be retried without any throttle.
|
||||||
|
if r.HTTPResponse.StatusCode == 500 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
return IsErrorRetryable(r.Error)
|
return IsErrorRetryable(r.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +243,11 @@ func (r *Request) IsErrorThrottle() bool {
|
||||||
|
|
||||||
if r.HTTPResponse != nil {
|
if r.HTTPResponse != nil {
|
||||||
switch r.HTTPResponse.StatusCode {
|
switch r.HTTPResponse.StatusCode {
|
||||||
case 429, 502, 503, 504:
|
case
|
||||||
|
429, // error caused due to too many requests
|
||||||
|
502, // Bad Gateway error should be throttled
|
||||||
|
503, // caused when service is unavailable
|
||||||
|
504: // error occurred due to gateway timeout
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ func New(cfgs ...*aws.Config) *Session {
|
||||||
// to be built with retrieving credentials with AssumeRole set in the config.
|
// to be built with retrieving credentials with AssumeRole set in the config.
|
||||||
//
|
//
|
||||||
// See the NewSessionWithOptions func for information on how to override or
|
// See the NewSessionWithOptions func for information on how to override or
|
||||||
// control through code how the Session will be created. Such as specifying the
|
// control through code how the Session will be created, such as specifying the
|
||||||
// config profile, and controlling if shared config is enabled or not.
|
// config profile, and controlling if shared config is enabled or not.
|
||||||
func NewSession(cfgs ...*aws.Config) (*Session, error) {
|
func NewSession(cfgs ...*aws.Config) (*Session, error) {
|
||||||
opts := Options{}
|
opts := Options{}
|
||||||
|
@ -571,7 +571,7 @@ func initHandlers(s *Session) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy creates and returns a copy of the current Session, coping the config
|
// Copy creates and returns a copy of the current Session, copying the config
|
||||||
// and handlers. If any additional configs are provided they will be merged
|
// and handlers. If any additional configs are provided they will be merged
|
||||||
// on top of the Session's copied config.
|
// on top of the Session's copied config.
|
||||||
//
|
//
|
||||||
|
|
|
@ -5,4 +5,4 @@ package aws
|
||||||
const SDKName = "aws-sdk-go"
|
const SDKName = "aws-sdk-go"
|
||||||
|
|
||||||
// SDKVersion is the version of this SDK
|
// SDKVersion is the version of this SDK
|
||||||
const SDKVersion = "1.23.9"
|
const SDKVersion = "1.25.8"
|
||||||
|
|
|
@ -162,7 +162,7 @@ loop:
|
||||||
if len(tokens) == 0 {
|
if len(tokens) == 0 {
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
|
// if should skip is true, we skip the tokens until should skip is set to false.
|
||||||
step = SkipTokenState
|
step = SkipTokenState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ loop:
|
||||||
// S -> equal_expr' expr_stmt'
|
// S -> equal_expr' expr_stmt'
|
||||||
switch k.Kind {
|
switch k.Kind {
|
||||||
case ASTKindEqualExpr:
|
case ASTKindEqualExpr:
|
||||||
// assiging a value to some key
|
// assigning a value to some key
|
||||||
k.AppendChild(newExpression(tok))
|
k.AppendChild(newExpression(tok))
|
||||||
stack.Push(newExprStatement(k))
|
stack.Push(newExprStatement(k))
|
||||||
case ASTKindExpr:
|
case ASTKindExpr:
|
||||||
|
@ -250,6 +250,13 @@ loop:
|
||||||
if !runeCompare(tok.Raw(), openBrace) {
|
if !runeCompare(tok.Raw(), openBrace) {
|
||||||
return nil, NewParseError("expected '['")
|
return nil, NewParseError("expected '['")
|
||||||
}
|
}
|
||||||
|
// If OpenScopeState is not at the start, we must mark the previous ast as complete
|
||||||
|
//
|
||||||
|
// for example: if previous ast was a skip statement;
|
||||||
|
// we should mark it as complete before we create a new statement
|
||||||
|
if k.Kind != ASTKindStart {
|
||||||
|
stack.MarkComplete(k)
|
||||||
|
}
|
||||||
|
|
||||||
stmt := newStatement()
|
stmt := newStatement()
|
||||||
stack.Push(stmt)
|
stack.Push(stmt)
|
||||||
|
|
|
@ -22,24 +22,24 @@ func newSkipper() skipper {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *skipper) ShouldSkip(tok Token) bool {
|
func (s *skipper) ShouldSkip(tok Token) bool {
|
||||||
|
// should skip state will be modified only if previous token was new line (NL);
|
||||||
|
// and the current token is not WhiteSpace (WS).
|
||||||
if s.shouldSkip &&
|
if s.shouldSkip &&
|
||||||
s.prevTok.Type() == TokenNL &&
|
s.prevTok.Type() == TokenNL &&
|
||||||
tok.Type() != TokenWS {
|
tok.Type() != TokenWS {
|
||||||
|
|
||||||
s.Continue()
|
s.Continue()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
s.prevTok = tok
|
s.prevTok = tok
|
||||||
|
|
||||||
return s.shouldSkip
|
return s.shouldSkip
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *skipper) Skip() {
|
func (s *skipper) Skip() {
|
||||||
s.shouldSkip = true
|
s.shouldSkip = true
|
||||||
s.prevTok = emptyToken
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *skipper) Continue() {
|
func (s *skipper) Continue() {
|
||||||
s.shouldSkip = false
|
s.shouldSkip = false
|
||||||
|
// empty token is assigned as we return to default state, when should skip is false
|
||||||
s.prevTok = emptyToken
|
s.prevTok = emptyToken
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package sdkio
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Byte is 8 bits
|
||||||
|
Byte int64 = 1
|
||||||
|
// KibiByte (KiB) is 1024 Bytes
|
||||||
|
KibiByte = Byte * 1024
|
||||||
|
// MebiByte (MiB) is 1024 KiB
|
||||||
|
MebiByte = KibiByte * 1024
|
||||||
|
// GibiByte (GiB) is 1024 MiB
|
||||||
|
GibiByte = MebiByte * 1024
|
||||||
|
)
|
|
@ -0,0 +1,15 @@
|
||||||
|
// +build go1.10
|
||||||
|
|
||||||
|
package sdkmath
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// Round returns the nearest integer, rounding half away from zero.
|
||||||
|
//
|
||||||
|
// Special cases are:
|
||||||
|
// Round(±0) = ±0
|
||||||
|
// Round(±Inf) = ±Inf
|
||||||
|
// Round(NaN) = NaN
|
||||||
|
func Round(x float64) float64 {
|
||||||
|
return math.Round(x)
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
// +build !go1.10
|
||||||
|
|
||||||
|
package sdkmath
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// Copied from the Go standard library's (Go 1.12) math/floor.go for use in
|
||||||
|
// Go version prior to Go 1.10.
|
||||||
|
const (
|
||||||
|
uvone = 0x3FF0000000000000
|
||||||
|
mask = 0x7FF
|
||||||
|
shift = 64 - 11 - 1
|
||||||
|
bias = 1023
|
||||||
|
signMask = 1 << 63
|
||||||
|
fracMask = 1<<shift - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Round returns the nearest integer, rounding half away from zero.
|
||||||
|
//
|
||||||
|
// Special cases are:
|
||||||
|
// Round(±0) = ±0
|
||||||
|
// Round(±Inf) = ±Inf
|
||||||
|
// Round(NaN) = NaN
|
||||||
|
//
|
||||||
|
// Copied from the Go standard library's (Go 1.12) math/floor.go for use in
|
||||||
|
// Go version prior to Go 1.10.
|
||||||
|
func Round(x float64) float64 {
|
||||||
|
// Round is a faster implementation of:
|
||||||
|
//
|
||||||
|
// func Round(x float64) float64 {
|
||||||
|
// t := Trunc(x)
|
||||||
|
// if Abs(x-t) >= 0.5 {
|
||||||
|
// return t + Copysign(1, x)
|
||||||
|
// }
|
||||||
|
// return t
|
||||||
|
// }
|
||||||
|
bits := math.Float64bits(x)
|
||||||
|
e := uint(bits>>shift) & mask
|
||||||
|
if e < bias {
|
||||||
|
// Round abs(x) < 1 including denormals.
|
||||||
|
bits &= signMask // +-0
|
||||||
|
if e == bias-1 {
|
||||||
|
bits |= uvone // +-1
|
||||||
|
}
|
||||||
|
} else if e < bias+shift {
|
||||||
|
// Round any abs(x) >= 1 containing a fractional component [0,1).
|
||||||
|
//
|
||||||
|
// Numbers with larger exponents are returned unchanged since they
|
||||||
|
// must be either an integer, infinity, or NaN.
|
||||||
|
const half = 1 << (shift - 1)
|
||||||
|
e -= bias
|
||||||
|
bits += half >> e
|
||||||
|
bits &^= fracMask >> e
|
||||||
|
}
|
||||||
|
return math.Float64frombits(bits)
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// +build go1.6
|
||||||
|
|
||||||
|
package sdkrand
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
// Read provides the stub for math.Rand.Read method support for go version's
|
||||||
|
// 1.6 and greater.
|
||||||
|
func Read(r *rand.Rand, p []byte) (int, error) {
|
||||||
|
return r.Read(p)
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// +build !go1.6
|
||||||
|
|
||||||
|
package sdkrand
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
// Read backfills Go 1.6's math.Rand.Reader for Go 1.5
|
||||||
|
func Read(r *rand.Rand, p []byte) (n int, err error) {
|
||||||
|
// Copy of Go standard libraries math package's read function not added to
|
||||||
|
// standard library until Go 1.6.
|
||||||
|
var pos int8
|
||||||
|
var val int64
|
||||||
|
for n = 0; n < len(p); n++ {
|
||||||
|
if pos == 0 {
|
||||||
|
val = r.Int63()
|
||||||
|
pos = 7
|
||||||
|
}
|
||||||
|
p[n] = byte(val)
|
||||||
|
val >>= 8
|
||||||
|
pos--
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, err
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/internal/sdkmath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Names of time formats supported by the SDK
|
// Names of time formats supported by the SDK
|
||||||
|
@ -13,12 +16,19 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Time formats supported by the SDK
|
// Time formats supported by the SDK
|
||||||
|
// Output time is intended to not contain decimals
|
||||||
const (
|
const (
|
||||||
// RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT
|
// RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT
|
||||||
RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
|
RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
|
||||||
|
|
||||||
|
// This format is used for output time without seconds precision
|
||||||
|
RFC822OutputTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
|
||||||
|
|
||||||
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
|
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
|
||||||
ISO8601TimeFormat = "2006-01-02T15:04:05Z"
|
ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z"
|
||||||
|
|
||||||
|
// This format is used for output time without seconds precision
|
||||||
|
ISO8601OutputTimeFormat = "2006-01-02T15:04:05Z"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsKnownTimestampFormat returns if the timestamp format name
|
// IsKnownTimestampFormat returns if the timestamp format name
|
||||||
|
@ -42,9 +52,9 @@ func FormatTime(name string, t time.Time) string {
|
||||||
|
|
||||||
switch name {
|
switch name {
|
||||||
case RFC822TimeFormatName:
|
case RFC822TimeFormatName:
|
||||||
return t.Format(RFC822TimeFormat)
|
return t.Format(RFC822OutputTimeFormat)
|
||||||
case ISO8601TimeFormatName:
|
case ISO8601TimeFormatName:
|
||||||
return t.Format(ISO8601TimeFormat)
|
return t.Format(ISO8601OutputTimeFormat)
|
||||||
case UnixTimeFormatName:
|
case UnixTimeFormatName:
|
||||||
return strconv.FormatInt(t.Unix(), 10)
|
return strconv.FormatInt(t.Unix(), 10)
|
||||||
default:
|
default:
|
||||||
|
@ -62,10 +72,12 @@ func ParseTime(formatName, value string) (time.Time, error) {
|
||||||
return time.Parse(ISO8601TimeFormat, value)
|
return time.Parse(ISO8601TimeFormat, value)
|
||||||
case UnixTimeFormatName:
|
case UnixTimeFormatName:
|
||||||
v, err := strconv.ParseFloat(value, 64)
|
v, err := strconv.ParseFloat(value, 64)
|
||||||
|
_, dec := math.Modf(v)
|
||||||
|
dec = sdkmath.Round(dec*1e3) / 1e3 //Rounds 0.1229999 to 0.123
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
return time.Unix(int64(v), 0), nil
|
return time.Unix(int64(v), int64(dec*(1e9))), nil
|
||||||
default:
|
default:
|
||||||
panic("unknown timestamp format name, " + formatName)
|
panic("unknown timestamp format name, " + formatName)
|
||||||
}
|
}
|
||||||
|
|
32
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/sort.go
generated
vendored
Normal file
32
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/sort.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package xmlutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type xmlAttrSlice []xml.Attr
|
||||||
|
|
||||||
|
func (x xmlAttrSlice) Len() int {
|
||||||
|
return len(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x xmlAttrSlice) Less(i, j int) bool {
|
||||||
|
spaceI, spaceJ := x[i].Name.Space, x[j].Name.Space
|
||||||
|
localI, localJ := x[i].Name.Local, x[j].Name.Local
|
||||||
|
valueI, valueJ := x[i].Value, x[j].Value
|
||||||
|
|
||||||
|
spaceCmp := strings.Compare(spaceI, spaceJ)
|
||||||
|
localCmp := strings.Compare(localI, localJ)
|
||||||
|
valueCmp := strings.Compare(valueI, valueJ)
|
||||||
|
|
||||||
|
if spaceCmp == -1 || (spaceCmp == 0 && (localCmp == -1 || (localCmp == 0 && valueCmp == -1))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x xmlAttrSlice) Swap(i, j int) {
|
||||||
|
x[i], x[j] = x[j], x[i]
|
||||||
|
}
|
13
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go
generated
vendored
|
@ -119,7 +119,18 @@ func (n *XMLNode) findElem(name string) (string, bool) {
|
||||||
|
|
||||||
// StructToXML writes an XMLNode to a xml.Encoder as tokens.
|
// StructToXML writes an XMLNode to a xml.Encoder as tokens.
|
||||||
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
|
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
|
||||||
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
|
// Sort Attributes
|
||||||
|
attrs := node.Attr
|
||||||
|
if sorted {
|
||||||
|
sortedAttrs := make([]xml.Attr, len(attrs))
|
||||||
|
for _, k := range node.Attr {
|
||||||
|
sortedAttrs = append(sortedAttrs, k)
|
||||||
|
}
|
||||||
|
sort.Sort(xmlAttrSlice(sortedAttrs))
|
||||||
|
attrs = sortedAttrs
|
||||||
|
}
|
||||||
|
|
||||||
|
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: attrs})
|
||||||
|
|
||||||
if node.Text != "" {
|
if node.Text != "" {
|
||||||
e.EncodeToken(xml.CharData([]byte(node.Text)))
|
e.EncodeToken(xml.CharData([]byte(node.Text)))
|
||||||
|
|
|
@ -7043,7 +7043,7 @@ func (s *AbortIncompleteMultipartUpload) SetDaysAfterInitiation(v int64) *AbortI
|
||||||
}
|
}
|
||||||
|
|
||||||
type AbortMultipartUploadInput struct {
|
type AbortMultipartUploadInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"AbortMultipartUploadRequest" type:"structure"`
|
||||||
|
|
||||||
// Name of the bucket to which the multipart upload was initiated.
|
// Name of the bucket to which the multipart upload was initiated.
|
||||||
//
|
//
|
||||||
|
@ -8084,7 +8084,7 @@ func (s *CommonPrefix) SetPrefix(v string) *CommonPrefix {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompleteMultipartUploadInput struct {
|
type CompleteMultipartUploadInput struct {
|
||||||
_ struct{} `type:"structure" payload:"MultipartUpload"`
|
_ struct{} `locationName:"CompleteMultipartUploadRequest" type:"structure" payload:"MultipartUpload"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -8404,7 +8404,7 @@ func (s *ContinuationEvent) UnmarshalEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
type CopyObjectInput struct {
|
type CopyObjectInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"CopyObjectRequest" type:"structure"`
|
||||||
|
|
||||||
// The canned ACL to apply to the object.
|
// The canned ACL to apply to the object.
|
||||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
||||||
|
@ -9025,7 +9025,7 @@ func (s *CreateBucketConfiguration) SetLocationConstraint(v string) *CreateBucke
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateBucketInput struct {
|
type CreateBucketInput struct {
|
||||||
_ struct{} `type:"structure" payload:"CreateBucketConfiguration"`
|
_ struct{} `locationName:"CreateBucketRequest" type:"structure" payload:"CreateBucketConfiguration"`
|
||||||
|
|
||||||
// The canned ACL to apply to the bucket.
|
// The canned ACL to apply to the bucket.
|
||||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"`
|
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"`
|
||||||
|
@ -9166,7 +9166,7 @@ func (s *CreateBucketOutput) SetLocation(v string) *CreateBucketOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateMultipartUploadInput struct {
|
type CreateMultipartUploadInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"CreateMultipartUploadRequest" type:"structure"`
|
||||||
|
|
||||||
// The canned ACL to apply to the object.
|
// The canned ACL to apply to the object.
|
||||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
||||||
|
@ -9708,7 +9708,7 @@ func (s *Delete) SetQuiet(v bool) *Delete {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketAnalyticsConfigurationInput struct {
|
type DeleteBucketAnalyticsConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketAnalyticsConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket from which an analytics configuration is deleted.
|
// The name of the bucket from which an analytics configuration is deleted.
|
||||||
//
|
//
|
||||||
|
@ -9784,7 +9784,7 @@ func (s DeleteBucketAnalyticsConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketCorsInput struct {
|
type DeleteBucketCorsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketCorsRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -9844,7 +9844,7 @@ func (s DeleteBucketCorsOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketEncryptionInput struct {
|
type DeleteBucketEncryptionInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketEncryptionRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the server-side encryption configuration
|
// The name of the bucket containing the server-side encryption configuration
|
||||||
// to delete.
|
// to delete.
|
||||||
|
@ -9907,7 +9907,7 @@ func (s DeleteBucketEncryptionOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketInput struct {
|
type DeleteBucketInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -9953,7 +9953,7 @@ func (s *DeleteBucketInput) getBucket() (v string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketInventoryConfigurationInput struct {
|
type DeleteBucketInventoryConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketInventoryConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the inventory configuration to delete.
|
// The name of the bucket containing the inventory configuration to delete.
|
||||||
//
|
//
|
||||||
|
@ -10029,7 +10029,7 @@ func (s DeleteBucketInventoryConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketLifecycleInput struct {
|
type DeleteBucketLifecycleInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketLifecycleRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10089,7 +10089,7 @@ func (s DeleteBucketLifecycleOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketMetricsConfigurationInput struct {
|
type DeleteBucketMetricsConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketMetricsConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the metrics configuration to delete.
|
// The name of the bucket containing the metrics configuration to delete.
|
||||||
//
|
//
|
||||||
|
@ -10179,7 +10179,7 @@ func (s DeleteBucketOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketPolicyInput struct {
|
type DeleteBucketPolicyInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketPolicyRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10239,7 +10239,7 @@ func (s DeleteBucketPolicyOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketReplicationInput struct {
|
type DeleteBucketReplicationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketReplicationRequest" type:"structure"`
|
||||||
|
|
||||||
// The bucket name.
|
// The bucket name.
|
||||||
//
|
//
|
||||||
|
@ -10304,7 +10304,7 @@ func (s DeleteBucketReplicationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketTaggingInput struct {
|
type DeleteBucketTaggingInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketTaggingRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10364,7 +10364,7 @@ func (s DeleteBucketTaggingOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteBucketWebsiteInput struct {
|
type DeleteBucketWebsiteInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteBucketWebsiteRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10510,7 +10510,7 @@ func (s *DeleteMarkerReplication) SetStatus(v string) *DeleteMarkerReplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteObjectInput struct {
|
type DeleteObjectInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteObjectRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10656,7 +10656,7 @@ func (s *DeleteObjectOutput) SetVersionId(v string) *DeleteObjectOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteObjectTaggingInput struct {
|
type DeleteObjectTaggingInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeleteObjectTaggingRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10749,7 +10749,7 @@ func (s *DeleteObjectTaggingOutput) SetVersionId(v string) *DeleteObjectTaggingO
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteObjectsInput struct {
|
type DeleteObjectsInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Delete"`
|
_ struct{} `locationName:"DeleteObjectsRequest" type:"structure" payload:"Delete"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -10885,7 +10885,7 @@ func (s *DeleteObjectsOutput) SetRequestCharged(v string) *DeleteObjectsOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeletePublicAccessBlockInput struct {
|
type DeletePublicAccessBlockInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"DeletePublicAccessBlockRequest" type:"structure"`
|
||||||
|
|
||||||
// The Amazon S3 bucket whose PublicAccessBlock configuration you want to delete.
|
// The Amazon S3 bucket whose PublicAccessBlock configuration you want to delete.
|
||||||
//
|
//
|
||||||
|
@ -11341,7 +11341,7 @@ func (s *FilterRule) SetValue(v string) *FilterRule {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketAccelerateConfigurationInput struct {
|
type GetBucketAccelerateConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketAccelerateConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// Name of the bucket for which the accelerate configuration is retrieved.
|
// Name of the bucket for which the accelerate configuration is retrieved.
|
||||||
//
|
//
|
||||||
|
@ -11412,7 +11412,7 @@ func (s *GetBucketAccelerateConfigurationOutput) SetStatus(v string) *GetBucketA
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketAclInput struct {
|
type GetBucketAclInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketAclRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -11489,7 +11489,7 @@ func (s *GetBucketAclOutput) SetOwner(v *Owner) *GetBucketAclOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketAnalyticsConfigurationInput struct {
|
type GetBucketAnalyticsConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketAnalyticsConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket from which an analytics configuration is retrieved.
|
// The name of the bucket from which an analytics configuration is retrieved.
|
||||||
//
|
//
|
||||||
|
@ -11574,7 +11574,7 @@ func (s *GetBucketAnalyticsConfigurationOutput) SetAnalyticsConfiguration(v *Ana
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketCorsInput struct {
|
type GetBucketCorsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketCorsRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -11642,7 +11642,7 @@ func (s *GetBucketCorsOutput) SetCORSRules(v []*CORSRule) *GetBucketCorsOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketEncryptionInput struct {
|
type GetBucketEncryptionInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketEncryptionRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket from which the server-side encryption configuration
|
// The name of the bucket from which the server-side encryption configuration
|
||||||
// is retrieved.
|
// is retrieved.
|
||||||
|
@ -11714,7 +11714,7 @@ func (s *GetBucketEncryptionOutput) SetServerSideEncryptionConfiguration(v *Serv
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketInventoryConfigurationInput struct {
|
type GetBucketInventoryConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketInventoryConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the inventory configuration to retrieve.
|
// The name of the bucket containing the inventory configuration to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -11799,7 +11799,7 @@ func (s *GetBucketInventoryConfigurationOutput) SetInventoryConfiguration(v *Inv
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketLifecycleConfigurationInput struct {
|
type GetBucketLifecycleConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketLifecycleConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -11867,7 +11867,7 @@ func (s *GetBucketLifecycleConfigurationOutput) SetRules(v []*LifecycleRule) *Ge
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketLifecycleInput struct {
|
type GetBucketLifecycleInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketLifecycleRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -11935,7 +11935,7 @@ func (s *GetBucketLifecycleOutput) SetRules(v []*Rule) *GetBucketLifecycleOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketLocationInput struct {
|
type GetBucketLocationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketLocationRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12003,7 +12003,7 @@ func (s *GetBucketLocationOutput) SetLocationConstraint(v string) *GetBucketLoca
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketLoggingInput struct {
|
type GetBucketLoggingInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketLoggingRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12075,7 +12075,7 @@ func (s *GetBucketLoggingOutput) SetLoggingEnabled(v *LoggingEnabled) *GetBucket
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketMetricsConfigurationInput struct {
|
type GetBucketMetricsConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketMetricsConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the metrics configuration to retrieve.
|
// The name of the bucket containing the metrics configuration to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -12160,7 +12160,7 @@ func (s *GetBucketMetricsConfigurationOutput) SetMetricsConfiguration(v *Metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketNotificationConfigurationRequest struct {
|
type GetBucketNotificationConfigurationRequest struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketNotificationConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// Name of the bucket to get the notification configuration for.
|
// Name of the bucket to get the notification configuration for.
|
||||||
//
|
//
|
||||||
|
@ -12208,7 +12208,7 @@ func (s *GetBucketNotificationConfigurationRequest) getBucket() (v string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketPolicyInput struct {
|
type GetBucketPolicyInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketPolicyRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12277,7 +12277,7 @@ func (s *GetBucketPolicyOutput) SetPolicy(v string) *GetBucketPolicyOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketPolicyStatusInput struct {
|
type GetBucketPolicyStatusInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketPolicyStatusRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the Amazon S3 bucket whose policy status you want to retrieve.
|
// The name of the Amazon S3 bucket whose policy status you want to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -12348,7 +12348,7 @@ func (s *GetBucketPolicyStatusOutput) SetPolicyStatus(v *PolicyStatus) *GetBucke
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketReplicationInput struct {
|
type GetBucketReplicationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketReplicationRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12418,7 +12418,7 @@ func (s *GetBucketReplicationOutput) SetReplicationConfiguration(v *ReplicationC
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketRequestPaymentInput struct {
|
type GetBucketRequestPaymentInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketRequestPaymentRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12487,7 +12487,7 @@ func (s *GetBucketRequestPaymentOutput) SetPayer(v string) *GetBucketRequestPaym
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketTaggingInput struct {
|
type GetBucketTaggingInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketTaggingRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12556,7 +12556,7 @@ func (s *GetBucketTaggingOutput) SetTagSet(v []*Tag) *GetBucketTaggingOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketVersioningInput struct {
|
type GetBucketVersioningInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketVersioningRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12636,7 +12636,7 @@ func (s *GetBucketVersioningOutput) SetStatus(v string) *GetBucketVersioningOutp
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetBucketWebsiteInput struct {
|
type GetBucketWebsiteInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetBucketWebsiteRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12730,7 +12730,7 @@ func (s *GetBucketWebsiteOutput) SetRoutingRules(v []*RoutingRule) *GetBucketWeb
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectAclInput struct {
|
type GetObjectAclInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectAclRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -12853,7 +12853,7 @@ func (s *GetObjectAclOutput) SetRequestCharged(v string) *GetObjectAclOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectInput struct {
|
type GetObjectInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -13090,7 +13090,7 @@ func (s *GetObjectInput) SetVersionId(v string) *GetObjectInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectLegalHoldInput struct {
|
type GetObjectLegalHoldInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectLegalHoldRequest" type:"structure"`
|
||||||
|
|
||||||
// The bucket containing the object whose Legal Hold status you want to retrieve.
|
// The bucket containing the object whose Legal Hold status you want to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -13199,7 +13199,7 @@ func (s *GetObjectLegalHoldOutput) SetLegalHold(v *ObjectLockLegalHold) *GetObje
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectLockConfigurationInput struct {
|
type GetObjectLockConfigurationInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectLockConfigurationRequest" type:"structure"`
|
||||||
|
|
||||||
// The bucket whose object lock configuration you want to retrieve.
|
// The bucket whose object lock configuration you want to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -13581,7 +13581,7 @@ func (s *GetObjectOutput) SetWebsiteRedirectLocation(v string) *GetObjectOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectRetentionInput struct {
|
type GetObjectRetentionInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectRetentionRequest" type:"structure"`
|
||||||
|
|
||||||
// The bucket containing the object whose retention settings you want to retrieve.
|
// The bucket containing the object whose retention settings you want to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -13690,7 +13690,7 @@ func (s *GetObjectRetentionOutput) SetRetention(v *ObjectLockRetention) *GetObje
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectTaggingInput struct {
|
type GetObjectTaggingInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectTaggingRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -13790,7 +13790,7 @@ func (s *GetObjectTaggingOutput) SetVersionId(v string) *GetObjectTaggingOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectTorrentInput struct {
|
type GetObjectTorrentInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetObjectTorrentRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -13895,7 +13895,7 @@ func (s *GetObjectTorrentOutput) SetRequestCharged(v string) *GetObjectTorrentOu
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetPublicAccessBlockInput struct {
|
type GetPublicAccessBlockInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"GetPublicAccessBlockRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the Amazon S3 bucket whose PublicAccessBlock configuration you
|
// The name of the Amazon S3 bucket whose PublicAccessBlock configuration you
|
||||||
// want to retrieve.
|
// want to retrieve.
|
||||||
|
@ -14126,7 +14126,7 @@ func (s *Grantee) SetURI(v string) *Grantee {
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeadBucketInput struct {
|
type HeadBucketInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"HeadBucketRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -14186,7 +14186,7 @@ func (s HeadBucketOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeadObjectInput struct {
|
type HeadObjectInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"HeadObjectRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -15661,7 +15661,7 @@ func (s *LifecycleRuleFilter) SetTag(v *Tag) *LifecycleRuleFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListBucketAnalyticsConfigurationsInput struct {
|
type ListBucketAnalyticsConfigurationsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListBucketAnalyticsConfigurationsRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket from which analytics configurations are retrieved.
|
// The name of the bucket from which analytics configurations are retrieved.
|
||||||
//
|
//
|
||||||
|
@ -15773,7 +15773,7 @@ func (s *ListBucketAnalyticsConfigurationsOutput) SetNextContinuationToken(v str
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListBucketInventoryConfigurationsInput struct {
|
type ListBucketInventoryConfigurationsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListBucketInventoryConfigurationsRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the inventory configurations to retrieve.
|
// The name of the bucket containing the inventory configurations to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -15887,7 +15887,7 @@ func (s *ListBucketInventoryConfigurationsOutput) SetNextContinuationToken(v str
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListBucketMetricsConfigurationsInput struct {
|
type ListBucketMetricsConfigurationsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListBucketMetricsConfigurationsRequest" type:"structure"`
|
||||||
|
|
||||||
// The name of the bucket containing the metrics configurations to retrieve.
|
// The name of the bucket containing the metrics configurations to retrieve.
|
||||||
//
|
//
|
||||||
|
@ -16047,7 +16047,7 @@ func (s *ListBucketsOutput) SetOwner(v *Owner) *ListBucketsOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListMultipartUploadsInput struct {
|
type ListMultipartUploadsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListMultipartUploadsRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -16291,7 +16291,7 @@ func (s *ListMultipartUploadsOutput) SetUploads(v []*MultipartUpload) *ListMulti
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListObjectVersionsInput struct {
|
type ListObjectVersionsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListObjectVersionsRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -16524,7 +16524,7 @@ func (s *ListObjectVersionsOutput) SetVersions(v []*ObjectVersion) *ListObjectVe
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListObjectsInput struct {
|
type ListObjectsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListObjectsRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -16736,7 +16736,7 @@ func (s *ListObjectsOutput) SetPrefix(v string) *ListObjectsOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListObjectsV2Input struct {
|
type ListObjectsV2Input struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListObjectsV2Request" type:"structure"`
|
||||||
|
|
||||||
// Name of the bucket to list.
|
// Name of the bucket to list.
|
||||||
//
|
//
|
||||||
|
@ -16997,7 +16997,7 @@ func (s *ListObjectsV2Output) SetStartAfter(v string) *ListObjectsV2Output {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListPartsInput struct {
|
type ListPartsInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"ListPartsRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -18622,7 +18622,7 @@ func (s *PublicAccessBlockConfiguration) SetRestrictPublicBuckets(v bool) *Publi
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketAccelerateConfigurationInput struct {
|
type PutBucketAccelerateConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"AccelerateConfiguration"`
|
_ struct{} `locationName:"PutBucketAccelerateConfigurationRequest" type:"structure" payload:"AccelerateConfiguration"`
|
||||||
|
|
||||||
// Specifies the Accelerate Configuration you want to set for the bucket.
|
// Specifies the Accelerate Configuration you want to set for the bucket.
|
||||||
//
|
//
|
||||||
|
@ -18698,7 +18698,7 @@ func (s PutBucketAccelerateConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketAclInput struct {
|
type PutBucketAclInput struct {
|
||||||
_ struct{} `type:"structure" payload:"AccessControlPolicy"`
|
_ struct{} `locationName:"PutBucketAclRequest" type:"structure" payload:"AccessControlPolicy"`
|
||||||
|
|
||||||
// The canned ACL to apply to the bucket.
|
// The canned ACL to apply to the bucket.
|
||||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"`
|
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"`
|
||||||
|
@ -18827,7 +18827,7 @@ func (s PutBucketAclOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketAnalyticsConfigurationInput struct {
|
type PutBucketAnalyticsConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"AnalyticsConfiguration"`
|
_ struct{} `locationName:"PutBucketAnalyticsConfigurationRequest" type:"structure" payload:"AnalyticsConfiguration"`
|
||||||
|
|
||||||
// The configuration and any analyses for the analytics filter.
|
// The configuration and any analyses for the analytics filter.
|
||||||
//
|
//
|
||||||
|
@ -18922,7 +18922,7 @@ func (s PutBucketAnalyticsConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketCorsInput struct {
|
type PutBucketCorsInput struct {
|
||||||
_ struct{} `type:"structure" payload:"CORSConfiguration"`
|
_ struct{} `locationName:"PutBucketCorsRequest" type:"structure" payload:"CORSConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19004,7 +19004,7 @@ func (s PutBucketCorsOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketEncryptionInput struct {
|
type PutBucketEncryptionInput struct {
|
||||||
_ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"`
|
_ struct{} `locationName:"PutBucketEncryptionRequest" type:"structure" payload:"ServerSideEncryptionConfiguration"`
|
||||||
|
|
||||||
// Specifies default encryption for a bucket using server-side encryption with
|
// Specifies default encryption for a bucket using server-side encryption with
|
||||||
// Amazon S3-managed keys (SSE-S3) or AWS KMS-managed keys (SSE-KMS). For information
|
// Amazon S3-managed keys (SSE-S3) or AWS KMS-managed keys (SSE-KMS). For information
|
||||||
|
@ -19089,7 +19089,7 @@ func (s PutBucketEncryptionOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketInventoryConfigurationInput struct {
|
type PutBucketInventoryConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"InventoryConfiguration"`
|
_ struct{} `locationName:"PutBucketInventoryConfigurationRequest" type:"structure" payload:"InventoryConfiguration"`
|
||||||
|
|
||||||
// The name of the bucket where the inventory configuration will be stored.
|
// The name of the bucket where the inventory configuration will be stored.
|
||||||
//
|
//
|
||||||
|
@ -19184,7 +19184,7 @@ func (s PutBucketInventoryConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketLifecycleConfigurationInput struct {
|
type PutBucketLifecycleConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"LifecycleConfiguration"`
|
_ struct{} `locationName:"PutBucketLifecycleConfigurationRequest" type:"structure" payload:"LifecycleConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19260,7 +19260,7 @@ func (s PutBucketLifecycleConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketLifecycleInput struct {
|
type PutBucketLifecycleInput struct {
|
||||||
_ struct{} `type:"structure" payload:"LifecycleConfiguration"`
|
_ struct{} `locationName:"PutBucketLifecycleRequest" type:"structure" payload:"LifecycleConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19333,7 +19333,7 @@ func (s PutBucketLifecycleOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketLoggingInput struct {
|
type PutBucketLoggingInput struct {
|
||||||
_ struct{} `type:"structure" payload:"BucketLoggingStatus"`
|
_ struct{} `locationName:"PutBucketLoggingRequest" type:"structure" payload:"BucketLoggingStatus"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19410,7 +19410,7 @@ func (s PutBucketLoggingOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketMetricsConfigurationInput struct {
|
type PutBucketMetricsConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"MetricsConfiguration"`
|
_ struct{} `locationName:"PutBucketMetricsConfigurationRequest" type:"structure" payload:"MetricsConfiguration"`
|
||||||
|
|
||||||
// The name of the bucket for which the metrics configuration is set.
|
// The name of the bucket for which the metrics configuration is set.
|
||||||
//
|
//
|
||||||
|
@ -19505,7 +19505,7 @@ func (s PutBucketMetricsConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketNotificationConfigurationInput struct {
|
type PutBucketNotificationConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"NotificationConfiguration"`
|
_ struct{} `locationName:"PutBucketNotificationConfigurationRequest" type:"structure" payload:"NotificationConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19585,7 +19585,7 @@ func (s PutBucketNotificationConfigurationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketNotificationInput struct {
|
type PutBucketNotificationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"NotificationConfiguration"`
|
_ struct{} `locationName:"PutBucketNotificationRequest" type:"structure" payload:"NotificationConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19657,7 +19657,7 @@ func (s PutBucketNotificationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketPolicyInput struct {
|
type PutBucketPolicyInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Policy"`
|
_ struct{} `locationName:"PutBucketPolicyRequest" type:"structure" payload:"Policy"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19741,7 +19741,7 @@ func (s PutBucketPolicyOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketReplicationInput struct {
|
type PutBucketReplicationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"ReplicationConfiguration"`
|
_ struct{} `locationName:"PutBucketReplicationRequest" type:"structure" payload:"ReplicationConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19830,7 +19830,7 @@ func (s PutBucketReplicationOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketRequestPaymentInput struct {
|
type PutBucketRequestPaymentInput struct {
|
||||||
_ struct{} `type:"structure" payload:"RequestPaymentConfiguration"`
|
_ struct{} `locationName:"PutBucketRequestPaymentRequest" type:"structure" payload:"RequestPaymentConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19907,7 +19907,7 @@ func (s PutBucketRequestPaymentOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketTaggingInput struct {
|
type PutBucketTaggingInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Tagging"`
|
_ struct{} `locationName:"PutBucketTaggingRequest" type:"structure" payload:"Tagging"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -19984,7 +19984,7 @@ func (s PutBucketTaggingOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketVersioningInput struct {
|
type PutBucketVersioningInput struct {
|
||||||
_ struct{} `type:"structure" payload:"VersioningConfiguration"`
|
_ struct{} `locationName:"PutBucketVersioningRequest" type:"structure" payload:"VersioningConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -20070,7 +20070,7 @@ func (s PutBucketVersioningOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutBucketWebsiteInput struct {
|
type PutBucketWebsiteInput struct {
|
||||||
_ struct{} `type:"structure" payload:"WebsiteConfiguration"`
|
_ struct{} `locationName:"PutBucketWebsiteRequest" type:"structure" payload:"WebsiteConfiguration"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -20149,7 +20149,7 @@ func (s PutBucketWebsiteOutput) GoString() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutObjectAclInput struct {
|
type PutObjectAclInput struct {
|
||||||
_ struct{} `type:"structure" payload:"AccessControlPolicy"`
|
_ struct{} `locationName:"PutObjectAclRequest" type:"structure" payload:"AccessControlPolicy"`
|
||||||
|
|
||||||
// The canned ACL to apply to the object.
|
// The canned ACL to apply to the object.
|
||||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
||||||
|
@ -20324,7 +20324,7 @@ func (s *PutObjectAclOutput) SetRequestCharged(v string) *PutObjectAclOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutObjectInput struct {
|
type PutObjectInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Body"`
|
_ struct{} `locationName:"PutObjectRequest" type:"structure" payload:"Body"`
|
||||||
|
|
||||||
// The canned ACL to apply to the object.
|
// The canned ACL to apply to the object.
|
||||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
|
||||||
|
@ -20671,7 +20671,7 @@ func (s *PutObjectInput) SetWebsiteRedirectLocation(v string) *PutObjectInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutObjectLegalHoldInput struct {
|
type PutObjectLegalHoldInput struct {
|
||||||
_ struct{} `type:"structure" payload:"LegalHold"`
|
_ struct{} `locationName:"PutObjectLegalHoldRequest" type:"structure" payload:"LegalHold"`
|
||||||
|
|
||||||
// The bucket containing the object that you want to place a Legal Hold on.
|
// The bucket containing the object that you want to place a Legal Hold on.
|
||||||
//
|
//
|
||||||
|
@ -20791,7 +20791,7 @@ func (s *PutObjectLegalHoldOutput) SetRequestCharged(v string) *PutObjectLegalHo
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutObjectLockConfigurationInput struct {
|
type PutObjectLockConfigurationInput struct {
|
||||||
_ struct{} `type:"structure" payload:"ObjectLockConfiguration"`
|
_ struct{} `locationName:"PutObjectLockConfigurationRequest" type:"structure" payload:"ObjectLockConfiguration"`
|
||||||
|
|
||||||
// The bucket whose object lock configuration you want to create or replace.
|
// The bucket whose object lock configuration you want to create or replace.
|
||||||
//
|
//
|
||||||
|
@ -20998,7 +20998,7 @@ func (s *PutObjectOutput) SetVersionId(v string) *PutObjectOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutObjectRetentionInput struct {
|
type PutObjectRetentionInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Retention"`
|
_ struct{} `locationName:"PutObjectRetentionRequest" type:"structure" payload:"Retention"`
|
||||||
|
|
||||||
// The bucket that contains the object you want to apply this Object Retention
|
// The bucket that contains the object you want to apply this Object Retention
|
||||||
// configuration to.
|
// configuration to.
|
||||||
|
@ -21129,7 +21129,7 @@ func (s *PutObjectRetentionOutput) SetRequestCharged(v string) *PutObjectRetenti
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutObjectTaggingInput struct {
|
type PutObjectTaggingInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Tagging"`
|
_ struct{} `locationName:"PutObjectTaggingRequest" type:"structure" payload:"Tagging"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -21237,7 +21237,7 @@ func (s *PutObjectTaggingOutput) SetVersionId(v string) *PutObjectTaggingOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
type PutPublicAccessBlockInput struct {
|
type PutPublicAccessBlockInput struct {
|
||||||
_ struct{} `type:"structure" payload:"PublicAccessBlockConfiguration"`
|
_ struct{} `locationName:"PutPublicAccessBlockRequest" type:"structure" payload:"PublicAccessBlockConfiguration"`
|
||||||
|
|
||||||
// The name of the Amazon S3 bucket whose PublicAccessBlock configuration you
|
// The name of the Amazon S3 bucket whose PublicAccessBlock configuration you
|
||||||
// want to set.
|
// want to set.
|
||||||
|
@ -21999,7 +21999,7 @@ func (s *RequestProgress) SetEnabled(v bool) *RequestProgress {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RestoreObjectInput struct {
|
type RestoreObjectInput struct {
|
||||||
_ struct{} `type:"structure" payload:"RestoreRequest"`
|
_ struct{} `locationName:"RestoreObjectRequest" type:"structure" payload:"RestoreRequest"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -23715,7 +23715,7 @@ func (s *Transition) SetStorageClass(v string) *Transition {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UploadPartCopyInput struct {
|
type UploadPartCopyInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `locationName:"UploadPartCopyRequest" type:"structure"`
|
||||||
|
|
||||||
// Bucket is a required field
|
// Bucket is a required field
|
||||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||||
|
@ -24045,7 +24045,7 @@ func (s *UploadPartCopyOutput) SetServerSideEncryption(v string) *UploadPartCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
type UploadPartInput struct {
|
type UploadPartInput struct {
|
||||||
_ struct{} `type:"structure" payload:"Body"`
|
_ struct{} `locationName:"UploadPartRequest" type:"structure" payload:"Body"`
|
||||||
|
|
||||||
// Object data.
|
// Object data.
|
||||||
Body io.ReadSeeker `type:"blob"`
|
Body io.ReadSeeker `type:"blob"`
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[568].out
|
|
||||||
_go*
|
|
||||||
_test*
|
|
||||||
_obj
|
|
|
@ -1,14 +0,0 @@
|
||||||
FROM golang:1.12
|
|
||||||
|
|
||||||
# Clone and complie a riscv compatible version of the go compiler.
|
|
||||||
RUN git clone https://review.gerrithub.io/riscv/riscv-go /riscv-go
|
|
||||||
# riscvdev branch HEAD as of 2019-06-29.
|
|
||||||
RUN cd /riscv-go && git checkout 04885fddd096d09d4450726064d06dd107e374bf
|
|
||||||
ENV PATH=/riscv-go/misc/riscv:/riscv-go/bin:$PATH
|
|
||||||
RUN cd /riscv-go/src && GOROOT_BOOTSTRAP=$(go env GOROOT) ./make.bash
|
|
||||||
ENV GOROOT=/riscv-go
|
|
||||||
|
|
||||||
# Make sure we compile.
|
|
||||||
WORKDIR pty
|
|
||||||
ADD . .
|
|
||||||
RUN GOOS=linux GOARCH=riscv go build
|
|
|
@ -1,23 +0,0 @@
|
||||||
Copyright (c) 2011 Keith Rarick
|
|
||||||
|
|
||||||
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.
|
|
|
@ -1,100 +0,0 @@
|
||||||
# pty
|
|
||||||
|
|
||||||
Pty is a Go package for using unix pseudo-terminals.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
go get github.com/creack/pty
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
### Command
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/creack/pty"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
c := exec.Command("grep", "--color=auto", "bar")
|
|
||||||
f, err := pty.Start(c)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
f.Write([]byte("foo\n"))
|
|
||||||
f.Write([]byte("bar\n"))
|
|
||||||
f.Write([]byte("baz\n"))
|
|
||||||
f.Write([]byte{4}) // EOT
|
|
||||||
}()
|
|
||||||
io.Copy(os.Stdout, f)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Shell
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/creack/pty"
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
)
|
|
||||||
|
|
||||||
func test() error {
|
|
||||||
// Create arbitrary command.
|
|
||||||
c := exec.Command("bash")
|
|
||||||
|
|
||||||
// Start the command with a pty.
|
|
||||||
ptmx, err := pty.Start(c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Make sure to close the pty at the end.
|
|
||||||
defer func() { _ = ptmx.Close() }() // Best effort.
|
|
||||||
|
|
||||||
// Handle pty size.
|
|
||||||
ch := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(ch, syscall.SIGWINCH)
|
|
||||||
go func() {
|
|
||||||
for range ch {
|
|
||||||
if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
|
|
||||||
log.Printf("error resizing pty: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
ch <- syscall.SIGWINCH // Initial resize.
|
|
||||||
|
|
||||||
// Set stdin in raw mode.
|
|
||||||
oldState, err := terminal.MakeRaw(int(os.Stdin.Fd()))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
|
|
||||||
|
|
||||||
// Copy stdin to the pty and the pty to stdout.
|
|
||||||
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
|
|
||||||
_, _ = io.Copy(os.Stdout, ptmx)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := test(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,16 +0,0 @@
|
||||||
// Package pty provides functions for working with Unix terminals.
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrUnsupported is returned if a function is not
|
|
||||||
// available on the current platform.
|
|
||||||
var ErrUnsupported = errors.New("unsupported")
|
|
||||||
|
|
||||||
// Opens a pty and its corresponding tty.
|
|
||||||
func Open() (pty, tty *os.File, err error) {
|
|
||||||
return open()
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
// +build !windows,!solaris
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func ioctl(fd, cmd, ptr uintptr) error {
|
|
||||||
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
|
|
||||||
if e != 0 {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
// from <sys/ioccom.h>
|
|
||||||
const (
|
|
||||||
_IOC_VOID uintptr = 0x20000000
|
|
||||||
_IOC_OUT uintptr = 0x40000000
|
|
||||||
_IOC_IN uintptr = 0x80000000
|
|
||||||
_IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN
|
|
||||||
_IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN
|
|
||||||
|
|
||||||
_IOC_PARAM_SHIFT = 13
|
|
||||||
_IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
func _IOC_PARM_LEN(ioctl uintptr) uintptr {
|
|
||||||
return (ioctl >> 16) & _IOC_PARAM_MASK
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IO(group byte, ioctl_num uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_VOID, group, ioctl_num, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_OUT, group, ioctl_num, param_len)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_IN, group, ioctl_num, param_len)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len)
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// see /usr/include/sys/stropts.h
|
|
||||||
I_PUSH = uintptr((int32('S')<<8 | 002))
|
|
||||||
I_STR = uintptr((int32('S')<<8 | 010))
|
|
||||||
I_FIND = uintptr((int32('S')<<8 | 013))
|
|
||||||
// see /usr/include/sys/ptms.h
|
|
||||||
ISPTM = (int32('P') << 8) | 1
|
|
||||||
UNLKPT = (int32('P') << 8) | 2
|
|
||||||
PTSSTTY = (int32('P') << 8) | 3
|
|
||||||
ZONEPT = (int32('P') << 8) | 4
|
|
||||||
OWNERPT = (int32('P') << 8) | 5
|
|
||||||
)
|
|
||||||
|
|
||||||
type strioctl struct {
|
|
||||||
ic_cmd int32
|
|
||||||
ic_timout int32
|
|
||||||
ic_len int32
|
|
||||||
ic_dp unsafe.Pointer
|
|
||||||
}
|
|
||||||
|
|
||||||
func ioctl(fd, cmd, ptr uintptr) error {
|
|
||||||
return unix.IoctlSetInt(int(fd), uint(cmd), int(ptr))
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
GOOSARCH="${GOOS}_${GOARCH}"
|
|
||||||
case "$GOOSARCH" in
|
|
||||||
_* | *_ | _)
|
|
||||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
GODEFS="go tool cgo -godefs"
|
|
||||||
|
|
||||||
$GODEFS types.go |gofmt > ztypes_$GOARCH.go
|
|
||||||
|
|
||||||
case $GOOS in
|
|
||||||
freebsd|dragonfly|openbsd)
|
|
||||||
$GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go
|
|
||||||
;;
|
|
||||||
esac
|
|
|
@ -1,65 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
p := os.NewFile(uintptr(pFD), "/dev/ptmx")
|
|
||||||
// In case of error after this point, make sure we close the ptmx fd.
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
_ = p.Close() // Best effort.
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sname, err := ptsname(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := grantpt(p); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := unlockpt(p); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := os.OpenFile(sname, os.O_RDWR, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return p, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ptsname(f *os.File) (string, error) {
|
|
||||||
n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
|
|
||||||
|
|
||||||
err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range n {
|
|
||||||
if c == 0 {
|
|
||||||
return string(n[:i]), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
|
||||||
}
|
|
||||||
|
|
||||||
func grantpt(f *os.File) error {
|
|
||||||
return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func unlockpt(f *os.File) error {
|
|
||||||
return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0)
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// same code as pty_darwin.go
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
// In case of error after this point, make sure we close the ptmx fd.
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
_ = p.Close() // Best effort.
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sname, err := ptsname(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := grantpt(p); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := unlockpt(p); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := os.OpenFile(sname, os.O_RDWR, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return p, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func grantpt(f *os.File) error {
|
|
||||||
_, err := isptmaster(f.Fd())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func unlockpt(f *os.File) error {
|
|
||||||
_, err := isptmaster(f.Fd())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func isptmaster(fd uintptr) (bool, error) {
|
|
||||||
err := ioctl(fd, syscall.TIOCISPTMASTER, 0)
|
|
||||||
return err == nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
emptyFiodgnameArg fiodgnameArg
|
|
||||||
ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
|
|
||||||
)
|
|
||||||
|
|
||||||
func ptsname(f *os.File) (string, error) {
|
|
||||||
name := make([]byte, _C_SPECNAMELEN)
|
|
||||||
fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}}
|
|
||||||
|
|
||||||
err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa)))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range name {
|
|
||||||
if c == 0 {
|
|
||||||
s := "/dev/" + string(name[:i])
|
|
||||||
return strings.Replace(s, "ptm", "pts", -1), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func posixOpenpt(oflag int) (fd int, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0)
|
|
||||||
fd = int(r0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = e1
|
|
||||||
}
|
|
||||||
return fd, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
p := os.NewFile(uintptr(fd), "/dev/pts")
|
|
||||||
// In case of error after this point, make sure we close the pts fd.
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
_ = p.Close() // Best effort.
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sname, err := ptsname(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return p, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isptmaster(fd uintptr) (bool, error) {
|
|
||||||
err := ioctl(fd, syscall.TIOCPTMASTER, 0)
|
|
||||||
return err == nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
emptyFiodgnameArg fiodgnameArg
|
|
||||||
ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg))
|
|
||||||
)
|
|
||||||
|
|
||||||
func ptsname(f *os.File) (string, error) {
|
|
||||||
master, err := isptmaster(f.Fd())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if !master {
|
|
||||||
return "", syscall.EINVAL
|
|
||||||
}
|
|
||||||
|
|
||||||
const n = _C_SPECNAMELEN + 1
|
|
||||||
var (
|
|
||||||
buf = make([]byte, n)
|
|
||||||
arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))}
|
|
||||||
)
|
|
||||||
if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range buf {
|
|
||||||
if c == 0 {
|
|
||||||
return string(buf[:i]), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", errors.New("FIODGNAME string not NUL-terminated")
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
// In case of error after this point, make sure we close the ptmx fd.
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
_ = p.Close() // Best effort.
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sname, err := ptsname(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := unlockpt(p); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return p, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ptsname(f *os.File) (string, error) {
|
|
||||||
var n _C_uint
|
|
||||||
err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return "/dev/pts/" + strconv.Itoa(int(n)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unlockpt(f *os.File) error {
|
|
||||||
var u _C_int
|
|
||||||
// use TIOCSPTLCK with a pointer to zero to clear the lock
|
|
||||||
return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
/*
|
|
||||||
* from ptm(4):
|
|
||||||
* The PTMGET command allocates a free pseudo terminal, changes its
|
|
||||||
* ownership to the caller, revokes the access privileges for all previous
|
|
||||||
* users, opens the file descriptors for the pty and tty devices and
|
|
||||||
* returns them to the caller in struct ptmget.
|
|
||||||
*/
|
|
||||||
|
|
||||||
p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
var ptm ptmget
|
|
||||||
if err := ioctl(p.Fd(), uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pty = os.NewFile(uintptr(ptm.Cfd), "/dev/ptm")
|
|
||||||
tty = os.NewFile(uintptr(ptm.Sfd), "/dev/ptm")
|
|
||||||
|
|
||||||
return pty, tty, nil
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
package pty
|
|
||||||
|
|
||||||
/* based on:
|
|
||||||
http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/pt.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const NODEV = ^uint64(0)
|
|
||||||
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|unix.O_NOCTTY, 0)
|
|
||||||
//masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC|unix.O_NOCTTY, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
p := os.NewFile(uintptr(masterfd), "/dev/ptmx")
|
|
||||||
|
|
||||||
sname, err := ptsname(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = grantpt(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = unlockpt(p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
slavefd, err := syscall.Open(sname, os.O_RDWR|unix.O_NOCTTY, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
t := os.NewFile(uintptr(slavefd), sname)
|
|
||||||
|
|
||||||
// pushing terminal driver STREAMS modules as per pts(7)
|
|
||||||
for _, mod := range([]string{"ptem", "ldterm", "ttcompat"}) {
|
|
||||||
err = streams_push(t, mod)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func minor(x uint64) uint64 {
|
|
||||||
return x & 0377
|
|
||||||
}
|
|
||||||
|
|
||||||
func ptsdev(fd uintptr) uint64 {
|
|
||||||
istr := strioctl{ISPTM, 0, 0, nil}
|
|
||||||
err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr)))
|
|
||||||
if err != nil {
|
|
||||||
return NODEV
|
|
||||||
}
|
|
||||||
var status unix.Stat_t
|
|
||||||
err = unix.Fstat(int(fd), &status)
|
|
||||||
if err != nil {
|
|
||||||
return NODEV
|
|
||||||
}
|
|
||||||
return uint64(minor(status.Rdev))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ptsname(f *os.File) (string, error) {
|
|
||||||
dev := ptsdev(f.Fd())
|
|
||||||
if dev == NODEV {
|
|
||||||
return "", errors.New("not a master pty")
|
|
||||||
}
|
|
||||||
fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10)
|
|
||||||
// access(2) creates the slave device (if the pty exists)
|
|
||||||
// F_OK == 0 (unistd.h)
|
|
||||||
err := unix.Access(fn, 0)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return fn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type pt_own struct {
|
|
||||||
pto_ruid int32
|
|
||||||
pto_rgid int32
|
|
||||||
}
|
|
||||||
|
|
||||||
func grantpt(f *os.File) error {
|
|
||||||
if ptsdev(f.Fd()) == NODEV {
|
|
||||||
return errors.New("not a master pty")
|
|
||||||
}
|
|
||||||
var pto pt_own
|
|
||||||
pto.pto_ruid = int32(os.Getuid())
|
|
||||||
// XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty"
|
|
||||||
pto.pto_rgid = int32(os.Getgid())
|
|
||||||
var istr strioctl
|
|
||||||
istr.ic_cmd = OWNERPT
|
|
||||||
istr.ic_timout = 0
|
|
||||||
istr.ic_len = int32(unsafe.Sizeof(istr))
|
|
||||||
istr.ic_dp = unsafe.Pointer(&pto)
|
|
||||||
err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr)))
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("access denied")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unlockpt(f *os.File) error {
|
|
||||||
istr := strioctl{UNLKPT, 0, 0, nil}
|
|
||||||
return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// push STREAMS modules if not already done so
|
|
||||||
func streams_push(f *os.File, mod string) error {
|
|
||||||
var err error
|
|
||||||
buf := []byte(mod)
|
|
||||||
// XXX I_FIND is not returning an error when the module
|
|
||||||
// is already pushed even though truss reports a return
|
|
||||||
// value of 1. A bug in the Go Solaris syscall interface?
|
|
||||||
// XXX without this we are at risk of the issue
|
|
||||||
// https://www.illumos.org/issues/9042
|
|
||||||
// but since we are not using libc or XPG4.2, we should not be
|
|
||||||
// double-pushing modules
|
|
||||||
|
|
||||||
err = ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0])))
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0])))
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
// +build !linux,!darwin,!freebsd,!dragonfly,!openbsd,!solaris
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func open() (pty, tty *os.File, err error) {
|
|
||||||
return nil, nil, ErrUnsupported
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
|
|
||||||
// and c.Stderr, calls c.Start, and returns the File of the tty's
|
|
||||||
// corresponding pty.
|
|
||||||
func Start(c *exec.Cmd) (pty *os.File, err error) {
|
|
||||||
return StartWithSize(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
|
|
||||||
// and c.Stderr, calls c.Start, and returns the File of the tty's
|
|
||||||
// corresponding pty.
|
|
||||||
//
|
|
||||||
// This will resize the pty to the specified size before starting the command
|
|
||||||
func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) {
|
|
||||||
pty, tty, err := Open()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer tty.Close()
|
|
||||||
if sz != nil {
|
|
||||||
err = Setsize(pty, sz)
|
|
||||||
if err != nil {
|
|
||||||
pty.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if c.Stdout == nil {
|
|
||||||
c.Stdout = tty
|
|
||||||
}
|
|
||||||
if c.Stderr == nil {
|
|
||||||
c.Stderr = tty
|
|
||||||
}
|
|
||||||
if c.Stdin == nil {
|
|
||||||
c.Stdin = tty
|
|
||||||
}
|
|
||||||
if c.SysProcAttr == nil {
|
|
||||||
c.SysProcAttr = &syscall.SysProcAttr{}
|
|
||||||
}
|
|
||||||
c.SysProcAttr.Setctty = true
|
|
||||||
c.SysProcAttr.Setsid = true
|
|
||||||
c.SysProcAttr.Ctty = int(tty.Fd())
|
|
||||||
err = c.Start()
|
|
||||||
if err != nil {
|
|
||||||
pty.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return pty, err
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
# Test script checking that all expected os/arch compile properly.
|
|
||||||
# Does not actually test the logic, just the compilation so we make sure we don't break code depending on the lib.
|
|
||||||
|
|
||||||
echo2() {
|
|
||||||
echo $@ >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
trap end 0
|
|
||||||
end() {
|
|
||||||
[ "$?" = 0 ] && echo2 "Pass." || (echo2 "Fail."; exit 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
cross() {
|
|
||||||
os=$1
|
|
||||||
shift
|
|
||||||
echo2 "Build for $os."
|
|
||||||
for arch in $@; do
|
|
||||||
echo2 " - $os/$arch"
|
|
||||||
GOOS=$os GOARCH=$arch go build
|
|
||||||
done
|
|
||||||
echo2
|
|
||||||
}
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
cross linux amd64 386 arm arm64 ppc64 ppc64le s390x mips mipsle mips64 mips64le
|
|
||||||
cross darwin amd64 386 arm arm64
|
|
||||||
cross freebsd amd64 386 arm
|
|
||||||
cross netbsd amd64 386 arm
|
|
||||||
cross openbsd amd64 386
|
|
||||||
cross dragonfly amd64
|
|
||||||
cross solaris amd64
|
|
||||||
|
|
||||||
# Not expected to work but should still compile.
|
|
||||||
cross windows amd64 386 arm
|
|
||||||
|
|
||||||
# TODO: Fix compilation error on openbsd/arm.
|
|
||||||
# TODO: Merge the solaris PR.
|
|
||||||
|
|
||||||
# Some os/arch require a different compiler. Run in docker.
|
|
||||||
if ! hash docker; then
|
|
||||||
# If docker is not present, stop here.
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo2 "Build for linux."
|
|
||||||
echo2 " - linux/riscv"
|
|
||||||
docker build -t test -f Dockerfile.riscv .
|
|
|
@ -1,10 +0,0 @@
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int C.int
|
|
||||||
_C_uint C.uint
|
|
||||||
)
|
|
|
@ -1,17 +0,0 @@
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define _KERNEL
|
|
||||||
#include <sys/conf.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/filio.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
_C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */
|
|
||||||
)
|
|
||||||
|
|
||||||
type fiodgnameArg C.struct_fiodname_args
|
|
|
@ -1,15 +0,0 @@
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/filio.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
_C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */
|
|
||||||
)
|
|
||||||
|
|
||||||
type fiodgnameArg C.struct_fiodgname_arg
|
|
|
@ -1,14 +0,0 @@
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/tty.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
type ptmget C.struct_ptmget
|
|
||||||
|
|
||||||
var ioctl_PTMGET = C.PTMGET
|
|
|
@ -1,64 +0,0 @@
|
||||||
// +build !windows,!solaris
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InheritSize applies the terminal size of pty to tty. This should be run
|
|
||||||
// in a signal handler for syscall.SIGWINCH to automatically resize the tty when
|
|
||||||
// the pty receives a window size change notification.
|
|
||||||
func InheritSize(pty, tty *os.File) error {
|
|
||||||
size, err := GetsizeFull(pty)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = Setsize(tty, size)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setsize resizes t to s.
|
|
||||||
func Setsize(t *os.File, ws *Winsize) error {
|
|
||||||
return windowRectCall(ws, t.Fd(), syscall.TIOCSWINSZ)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetsizeFull returns the full terminal size description.
|
|
||||||
func GetsizeFull(t *os.File) (size *Winsize, err error) {
|
|
||||||
var ws Winsize
|
|
||||||
err = windowRectCall(&ws, t.Fd(), syscall.TIOCGWINSZ)
|
|
||||||
return &ws, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getsize returns the number of rows (lines) and cols (positions
|
|
||||||
// in each line) in terminal t.
|
|
||||||
func Getsize(t *os.File) (rows, cols int, err error) {
|
|
||||||
ws, err := GetsizeFull(t)
|
|
||||||
return int(ws.Rows), int(ws.Cols), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Winsize describes the terminal size.
|
|
||||||
type Winsize struct {
|
|
||||||
Rows uint16 // ws_row: Number of rows (in cells)
|
|
||||||
Cols uint16 // ws_col: Number of columns (in cells)
|
|
||||||
X uint16 // ws_xpixel: Width in pixels
|
|
||||||
Y uint16 // ws_ypixel: Height in pixels
|
|
||||||
}
|
|
||||||
|
|
||||||
func windowRectCall(ws *Winsize, fd, a2 uintptr) error {
|
|
||||||
_, _, errno := syscall.Syscall(
|
|
||||||
syscall.SYS_IOCTL,
|
|
||||||
fd,
|
|
||||||
a2,
|
|
||||||
uintptr(unsafe.Pointer(ws)),
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
return syscall.Errno(errno)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
//
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
TIOCGWINSZ = 21608 // 'T' << 8 | 104
|
|
||||||
TIOCSWINSZ = 21607 // 'T' << 8 | 103
|
|
||||||
)
|
|
||||||
|
|
||||||
// Winsize describes the terminal size.
|
|
||||||
type Winsize struct {
|
|
||||||
Rows uint16 // ws_row: Number of rows (in cells)
|
|
||||||
Cols uint16 // ws_col: Number of columns (in cells)
|
|
||||||
X uint16 // ws_xpixel: Width in pixels
|
|
||||||
Y uint16 // ws_ypixel: Height in pixels
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetsizeFull returns the full terminal size description.
|
|
||||||
func GetsizeFull(t *os.File) (size *Winsize, err error) {
|
|
||||||
var wsz *unix.Winsize
|
|
||||||
wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return &Winsize{wsz.Row, wsz.Col, wsz.Xpixel, wsz.Ypixel}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Windows Size
|
|
||||||
func Getsize(t *os.File) (rows, cols int, err error) {
|
|
||||||
var wsz *unix.Winsize
|
|
||||||
wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 80, 25, err
|
|
||||||
} else {
|
|
||||||
return int(wsz.Row), int(wsz.Col), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setsize resizes t to s.
|
|
||||||
func Setsize(t *os.File, ws *Winsize) error {
|
|
||||||
wsz := unix.Winsize{ws.Rows, ws.Cols, ws.X, ws.Y}
|
|
||||||
return unix.IoctlSetWinsize(int(t.Fd()), TIOCSWINSZ, &wsz)
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
// +build arm64
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,14 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_dragonfly.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
const (
|
|
||||||
_C_SPECNAMELEN = 0x3f
|
|
||||||
)
|
|
||||||
|
|
||||||
type fiodgnameArg struct {
|
|
||||||
Name *byte
|
|
||||||
Len uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_freebsd.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
const (
|
|
||||||
_C_SPECNAMELEN = 0x3f
|
|
||||||
)
|
|
||||||
|
|
||||||
type fiodgnameArg struct {
|
|
||||||
Len int32
|
|
||||||
Buf *byte
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_freebsd.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
const (
|
|
||||||
_C_SPECNAMELEN = 0x3f
|
|
||||||
)
|
|
||||||
|
|
||||||
type fiodgnameArg struct {
|
|
||||||
Len int32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Buf *byte
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_freebsd.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
const (
|
|
||||||
_C_SPECNAMELEN = 0x3f
|
|
||||||
)
|
|
||||||
|
|
||||||
type fiodgnameArg struct {
|
|
||||||
Len int32
|
|
||||||
Buf *byte
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
// +build mips mipsle mips64 mips64le
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_openbsd.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type ptmget struct {
|
|
||||||
Cfd int32
|
|
||||||
Sfd int32
|
|
||||||
Cn [16]int8
|
|
||||||
Sn [16]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
var ioctl_PTMGET = 0x40287401
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types_openbsd.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type ptmget struct {
|
|
||||||
Cfd int32
|
|
||||||
Sfd int32
|
|
||||||
Cn [16]int8
|
|
||||||
Sn [16]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
var ioctl_PTMGET = 0x40287401
|
|
|
@ -1,11 +0,0 @@
|
||||||
// +build ppc64
|
|
||||||
|
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
// +build ppc64le
|
|
||||||
|
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
// +build riscv riscv64
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
// +build s390x
|
|
||||||
|
|
||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs types.go
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_int int32
|
|
||||||
_C_uint uint32
|
|
||||||
)
|
|
|
@ -130,6 +130,7 @@ func (srv *Server) config(ctx Context) *gossh.ServerConfig {
|
||||||
}
|
}
|
||||||
if srv.KeyboardInteractiveHandler != nil {
|
if srv.KeyboardInteractiveHandler != nil {
|
||||||
config.KeyboardInteractiveCallback = func(conn gossh.ConnMetadata, challenger gossh.KeyboardInteractiveChallenge) (*gossh.Permissions, error) {
|
config.KeyboardInteractiveCallback = func(conn gossh.ConnMetadata, challenger gossh.KeyboardInteractiveChallenge) (*gossh.Permissions, error) {
|
||||||
|
applyConnMetadata(ctx, conn)
|
||||||
if ok := srv.KeyboardInteractiveHandler(ctx, challenger); !ok {
|
if ok := srv.KeyboardInteractiveHandler(ctx, challenger); !ok {
|
||||||
return ctx.Permissions().Permissions, fmt.Errorf("permission denied")
|
return ctx.Permissions().Permissions, fmt.Errorf("permission denied")
|
||||||
}
|
}
|
||||||
|
@ -227,20 +228,20 @@ func (srv *Server) Serve(l net.Listener) error {
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
go srv.handleConn(conn)
|
go srv.HandleConn(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) handleConn(newConn net.Conn) {
|
func (srv *Server) HandleConn(newConn net.Conn) {
|
||||||
|
ctx, cancel := newContext(srv)
|
||||||
if srv.ConnCallback != nil {
|
if srv.ConnCallback != nil {
|
||||||
cbConn := srv.ConnCallback(newConn)
|
cbConn := srv.ConnCallback(ctx, newConn)
|
||||||
if cbConn == nil {
|
if cbConn == nil {
|
||||||
newConn.Close()
|
newConn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newConn = cbConn
|
newConn = cbConn
|
||||||
}
|
}
|
||||||
ctx, cancel := newContext(srv)
|
|
||||||
conn := &serverConn{
|
conn := &serverConn{
|
||||||
Conn: newConn,
|
Conn: newConn,
|
||||||
idleTimeout: srv.IdleTimeout,
|
idleTimeout: srv.IdleTimeout,
|
||||||
|
|
|
@ -53,7 +53,7 @@ type SessionRequestCallback func(sess Session, requestType string) bool
|
||||||
// ConnCallback is a hook for new connections before handling.
|
// ConnCallback is a hook for new connections before handling.
|
||||||
// It allows wrapping for timeouts and limiting by returning
|
// It allows wrapping for timeouts and limiting by returning
|
||||||
// the net.Conn that will be used as the underlying connection.
|
// the net.Conn that will be used as the underlying connection.
|
||||||
type ConnCallback func(conn net.Conn) net.Conn
|
type ConnCallback func(ctx Context, conn net.Conn) net.Conn
|
||||||
|
|
||||||
// LocalPortForwardingCallback is a hook for allowing port forwarding
|
// LocalPortForwardingCallback is a hook for allowing port forwarding
|
||||||
type LocalPortForwardingCallback func(ctx Context, destinationHost string, destinationPort uint32) bool
|
type LocalPortForwardingCallback func(ctx Context, destinationHost string, destinationPort uint32) bool
|
||||||
|
|
|
@ -38,7 +38,6 @@ package proto
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -194,7 +193,7 @@ func (p *Properties) Parse(s string) {
|
||||||
// "bytes,49,opt,name=foo,def=hello!"
|
// "bytes,49,opt,name=foo,def=hello!"
|
||||||
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
||||||
if len(fields) < 2 {
|
if len(fields) < 2 {
|
||||||
fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
|
log.Printf("proto: tag has too few fields: %q", s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +213,7 @@ func (p *Properties) Parse(s string) {
|
||||||
p.WireType = WireBytes
|
p.WireType = WireBytes
|
||||||
// no numeric converter for non-numeric types
|
// no numeric converter for non-numeric types
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
|
log.Printf("proto: tag has unknown wire type: %q", s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- go: 1.7.x
|
|
||||||
- go: 1.8.x
|
|
||||||
- go: 1.9.x
|
|
||||||
- go: 1.10.x
|
|
||||||
- go: 1.11.x
|
|
||||||
- go: 1.x
|
|
||||||
env: LATEST=true
|
|
||||||
- go: tip
|
|
||||||
allow_failures:
|
|
||||||
- go: tip
|
|
||||||
|
|
||||||
install:
|
|
||||||
- # Skip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go get -t -v ./...
|
|
||||||
- diff -u <(echo -n) <(gofmt -d .)
|
|
||||||
- if [[ "$LATEST" = true ]]; then go vet .; fi
|
|
||||||
- go test -v -race ./...
|
|
|
@ -1,11 +0,0 @@
|
||||||
**What version of Go are you running?** (Paste the output of `go version`)
|
|
||||||
|
|
||||||
|
|
||||||
**What version of gorilla/mux are you at?** (Paste the output of `git rev-parse HEAD` inside `$GOPATH/src/github.com/gorilla/mux`)
|
|
||||||
|
|
||||||
|
|
||||||
**Describe your problem** (and what you have tried so far)
|
|
||||||
|
|
||||||
|
|
||||||
**Paste a minimal, runnable, reproduction of your issue below** (use backticks to format it)
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
|
[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
|
||||||
[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
|
[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
|
||||||
|
[![CircleCI](https://circleci.com/gh/gorilla/mux.svg?style=svg)](https://circleci.com/gh/gorilla/mux)
|
||||||
[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge)
|
[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge)
|
||||||
|
|
||||||
![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)
|
![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)
|
||||||
|
@ -29,6 +30,7 @@ The name mux stands for "HTTP request multiplexer". Like the standard `http.Serv
|
||||||
* [Walking Routes](#walking-routes)
|
* [Walking Routes](#walking-routes)
|
||||||
* [Graceful Shutdown](#graceful-shutdown)
|
* [Graceful Shutdown](#graceful-shutdown)
|
||||||
* [Middleware](#middleware)
|
* [Middleware](#middleware)
|
||||||
|
* [Handling CORS Requests](#handling-cors-requests)
|
||||||
* [Testing Handlers](#testing-handlers)
|
* [Testing Handlers](#testing-handlers)
|
||||||
* [Full Example](#full-example)
|
* [Full Example](#full-example)
|
||||||
|
|
||||||
|
@ -491,6 +493,73 @@ r.Use(amw.Middleware)
|
||||||
|
|
||||||
Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. Middlewares _should_ write to `ResponseWriter` if they _are_ going to terminate the request, and they _should not_ write to `ResponseWriter` if they _are not_ going to terminate it.
|
Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. Middlewares _should_ write to `ResponseWriter` if they _are_ going to terminate the request, and they _should not_ write to `ResponseWriter` if they _are not_ going to terminate it.
|
||||||
|
|
||||||
|
### Handling CORS Requests
|
||||||
|
|
||||||
|
[CORSMethodMiddleware](https://godoc.org/github.com/gorilla/mux#CORSMethodMiddleware) intends to make it easier to strictly set the `Access-Control-Allow-Methods` response header.
|
||||||
|
|
||||||
|
* You will still need to use your own CORS handler to set the other CORS headers such as `Access-Control-Allow-Origin`
|
||||||
|
* The middleware will set the `Access-Control-Allow-Methods` header to all the method matchers (e.g. `r.Methods(http.MethodGet, http.MethodPut, http.MethodOptions)` -> `Access-Control-Allow-Methods: GET,PUT,OPTIONS`) on a route
|
||||||
|
* If you do not specify any methods, then:
|
||||||
|
> _Important_: there must be an `OPTIONS` method matcher for the middleware to set the headers.
|
||||||
|
|
||||||
|
Here is an example of using `CORSMethodMiddleware` along with a custom `OPTIONS` handler to set all the required CORS headers:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := mux.NewRouter()
|
||||||
|
|
||||||
|
// IMPORTANT: you must specify an OPTIONS method matcher for the middleware to set CORS headers
|
||||||
|
r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions)
|
||||||
|
r.Use(mux.CORSMethodMiddleware(r))
|
||||||
|
|
||||||
|
http.ListenAndServe(":8080", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fooHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
if r.Method == http.MethodOptions {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte("foo"))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And an request to `/foo` using something like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl localhost:8080/foo -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Would look like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
* Trying ::1...
|
||||||
|
* TCP_NODELAY set
|
||||||
|
* Connected to localhost (::1) port 8080 (#0)
|
||||||
|
> GET /foo HTTP/1.1
|
||||||
|
> Host: localhost:8080
|
||||||
|
> User-Agent: curl/7.59.0
|
||||||
|
> Accept: */*
|
||||||
|
>
|
||||||
|
< HTTP/1.1 200 OK
|
||||||
|
< Access-Control-Allow-Methods: GET,PUT,PATCH,OPTIONS
|
||||||
|
< Access-Control-Allow-Origin: *
|
||||||
|
< Date: Fri, 28 Jun 2019 20:13:30 GMT
|
||||||
|
< Content-Length: 3
|
||||||
|
< Content-Type: text/plain; charset=utf-8
|
||||||
|
<
|
||||||
|
* Connection #0 to host localhost left intact
|
||||||
|
foo
|
||||||
|
```
|
||||||
|
|
||||||
### Testing Handlers
|
### Testing Handlers
|
||||||
|
|
||||||
Testing handlers in a Go web application is straightforward, and _mux_ doesn't complicate this any further. Given two files: `endpoints.go` and `endpoints_test.go`, here's how we'd test an application using _mux_.
|
Testing handlers in a Go web application is straightforward, and _mux_ doesn't complicate this any further. Given two files: `endpoints.go` and `endpoints_test.go`, here's how we'd test an application using _mux_.
|
||||||
|
|
|
@ -295,7 +295,7 @@ A more complex authentication middleware, which maps session token to users, cou
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.HandleFunc("/", handler)
|
r.HandleFunc("/", handler)
|
||||||
|
|
||||||
amw := authenticationMiddleware{}
|
amw := authenticationMiddleware{tokenUsers: make(map[string]string)}
|
||||||
amw.Populate()
|
amw.Populate()
|
||||||
|
|
||||||
r.Use(amw.Middleware)
|
r.Use(amw.Middleware)
|
||||||
|
|
|
@ -32,13 +32,30 @@ func (r *Router) useInterface(mw middleware) {
|
||||||
r.middlewares = append(r.middlewares, mw)
|
r.middlewares = append(r.middlewares, mw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CORSMethodMiddleware sets the Access-Control-Allow-Methods response header
|
// CORSMethodMiddleware automatically sets the Access-Control-Allow-Methods response header
|
||||||
// on a request, by matching routes based only on paths. It also handles
|
// on requests for routes that have an OPTIONS method matcher to all the method matchers on
|
||||||
// OPTIONS requests, by settings Access-Control-Allow-Methods, and then
|
// the route. Routes that do not explicitly handle OPTIONS requests will not be processed
|
||||||
// returning without calling the next http handler.
|
// by the middleware. See examples for usage.
|
||||||
func CORSMethodMiddleware(r *Router) MiddlewareFunc {
|
func CORSMethodMiddleware(r *Router) MiddlewareFunc {
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
allMethods, err := getAllMethodsForRoute(r, req)
|
||||||
|
if err == nil {
|
||||||
|
for _, v := range allMethods {
|
||||||
|
if v == http.MethodOptions {
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", strings.Join(allMethods, ","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, req)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAllMethodsForRoute returns all the methods from method matchers matching a given
|
||||||
|
// request.
|
||||||
|
func getAllMethodsForRoute(r *Router, req *http.Request) ([]string, error) {
|
||||||
var allMethods []string
|
var allMethods []string
|
||||||
|
|
||||||
err := r.Walk(func(route *Route, _ *Router, _ []*Route) error {
|
err := r.Walk(func(route *Route, _ *Router, _ []*Route) error {
|
||||||
|
@ -58,15 +75,5 @@ func CORSMethodMiddleware(r *Router) MiddlewareFunc {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err == nil {
|
return allMethods, err
|
||||||
w.Header().Set("Access-Control-Allow-Methods", strings.Join(append(allMethods, "OPTIONS"), ","))
|
|
||||||
|
|
||||||
if req.Method == "OPTIONS" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
next.ServeHTTP(w, req)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,13 @@ func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptions) (*ro
|
||||||
if typ != regexpTypePrefix {
|
if typ != regexpTypePrefix {
|
||||||
pattern.WriteByte('$')
|
pattern.WriteByte('$')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var wildcardHostPort bool
|
||||||
|
if typ == regexpTypeHost {
|
||||||
|
if !strings.Contains(pattern.String(), ":") {
|
||||||
|
wildcardHostPort = true
|
||||||
|
}
|
||||||
|
}
|
||||||
reverse.WriteString(raw)
|
reverse.WriteString(raw)
|
||||||
if endSlash {
|
if endSlash {
|
||||||
reverse.WriteByte('/')
|
reverse.WriteByte('/')
|
||||||
|
@ -138,6 +145,7 @@ func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptions) (*ro
|
||||||
reverse: reverse.String(),
|
reverse: reverse.String(),
|
||||||
varsN: varsN,
|
varsN: varsN,
|
||||||
varsR: varsR,
|
varsR: varsR,
|
||||||
|
wildcardHostPort: wildcardHostPort,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,11 +166,22 @@ type routeRegexp struct {
|
||||||
varsN []string
|
varsN []string
|
||||||
// Variable regexps (validators).
|
// Variable regexps (validators).
|
||||||
varsR []*regexp.Regexp
|
varsR []*regexp.Regexp
|
||||||
|
// Wildcard host-port (no strict port match in hostname)
|
||||||
|
wildcardHostPort bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match matches the regexp against the URL host or path.
|
// Match matches the regexp against the URL host or path.
|
||||||
func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
|
func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
|
||||||
if r.regexpType != regexpTypeHost {
|
if r.regexpType == regexpTypeHost {
|
||||||
|
host := getHost(req)
|
||||||
|
if r.wildcardHostPort {
|
||||||
|
// Don't be strict on the port match
|
||||||
|
if i := strings.Index(host, ":"); i != -1 {
|
||||||
|
host = host[:i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r.regexp.MatchString(host)
|
||||||
|
} else {
|
||||||
if r.regexpType == regexpTypeQuery {
|
if r.regexpType == regexpTypeQuery {
|
||||||
return r.matchQueryString(req)
|
return r.matchQueryString(req)
|
||||||
}
|
}
|
||||||
|
@ -172,8 +191,6 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
|
||||||
}
|
}
|
||||||
return r.regexp.MatchString(path)
|
return r.regexp.MatchString(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.regexp.MatchString(getHost(req))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// url builds a URL part using the given values.
|
// url builds a URL part using the given values.
|
||||||
|
|
|
@ -70,17 +70,4 @@ postgresql_uninstall() {
|
||||||
sudo rm -rf /var/lib/postgresql
|
sudo rm -rf /var/lib/postgresql
|
||||||
}
|
}
|
||||||
|
|
||||||
megacheck_install() {
|
|
||||||
# Lock megacheck version at $MEGACHECK_VERSION to prevent spontaneous
|
|
||||||
# new error messages in old code.
|
|
||||||
go get -d honnef.co/go/tools/...
|
|
||||||
git -C $GOPATH/src/honnef.co/go/tools/ checkout $MEGACHECK_VERSION
|
|
||||||
go install honnef.co/go/tools/cmd/megacheck
|
|
||||||
megacheck --version
|
|
||||||
}
|
|
||||||
|
|
||||||
golint_install() {
|
|
||||||
go get golang.org/x/lint/golint
|
|
||||||
}
|
|
||||||
|
|
||||||
$1
|
$1
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.9.x
|
|
||||||
- 1.10.x
|
|
||||||
- 1.11.x
|
- 1.11.x
|
||||||
|
- 1.12.x
|
||||||
- master
|
- master
|
||||||
|
|
||||||
sudo: true
|
sudo: true
|
||||||
|
@ -14,16 +13,11 @@ env:
|
||||||
- PQGOSSLTESTS=1
|
- PQGOSSLTESTS=1
|
||||||
- PQSSLCERTTEST_PATH=$PWD/certs
|
- PQSSLCERTTEST_PATH=$PWD/certs
|
||||||
- PGHOST=127.0.0.1
|
- PGHOST=127.0.0.1
|
||||||
- MEGACHECK_VERSION=2017.2.2
|
|
||||||
matrix:
|
matrix:
|
||||||
- PGVERSION=10
|
- PGVERSION=10
|
||||||
- PGVERSION=9.6
|
- PGVERSION=9.6
|
||||||
- PGVERSION=9.5
|
- PGVERSION=9.5
|
||||||
- PGVERSION=9.4
|
- PGVERSION=9.4
|
||||||
- PGVERSION=9.3
|
|
||||||
- PGVERSION=9.2
|
|
||||||
- PGVERSION=9.1
|
|
||||||
- PGVERSION=9.0
|
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- ./.travis.sh postgresql_uninstall
|
- ./.travis.sh postgresql_uninstall
|
||||||
|
@ -31,9 +25,9 @@ before_install:
|
||||||
- ./.travis.sh postgresql_install
|
- ./.travis.sh postgresql_install
|
||||||
- ./.travis.sh postgresql_configure
|
- ./.travis.sh postgresql_configure
|
||||||
- ./.travis.sh client_configure
|
- ./.travis.sh client_configure
|
||||||
- ./.travis.sh megacheck_install
|
|
||||||
- ./.travis.sh golint_install
|
|
||||||
- go get golang.org/x/tools/cmd/goimports
|
- go get golang.org/x/tools/cmd/goimports
|
||||||
|
- go get golang.org/x/lint/golint
|
||||||
|
- GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2019.2.1
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- createdb pqgotest
|
- createdb pqgotest
|
||||||
|
@ -44,7 +38,7 @@ script:
|
||||||
- >
|
- >
|
||||||
goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
|
goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
|
||||||
- go vet ./...
|
- go vet ./...
|
||||||
- megacheck -go 1.9 ./...
|
- staticcheck -go 1.11 ./...
|
||||||
- golint ./...
|
- golint ./...
|
||||||
- PQTEST_BINARY_PARAMETERS=no go test -race -v ./...
|
- PQTEST_BINARY_PARAMETERS=no go test -race -v ./...
|
||||||
- PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
|
- PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
|
||||||
|
|
|
@ -66,7 +66,7 @@ func (b *writeBuf) int16(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *writeBuf) string(s string) {
|
func (b *writeBuf) string(s string) {
|
||||||
b.buf = append(b.buf, (s + "\000")...)
|
b.buf = append(append(b.buf, s...), '\000')
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *writeBuf) byte(c byte) {
|
func (b *writeBuf) byte(c byte) {
|
||||||
|
|
|
@ -92,6 +92,7 @@ type Dialer interface {
|
||||||
DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
|
DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialerContext is the context-aware dialer interface.
|
||||||
type DialerContext interface {
|
type DialerContext interface {
|
||||||
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
}
|
}
|
||||||
|
@ -301,6 +302,9 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
|
||||||
|
|
||||||
err = cn.ssl(o)
|
err = cn.ssl(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cn.c != nil {
|
||||||
|
cn.c.Close()
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +550,7 @@ func (cn *conn) Commit() (err error) {
|
||||||
// would get the same behaviour if you issued a COMMIT in a failed
|
// would get the same behaviour if you issued a COMMIT in a failed
|
||||||
// transaction, so it's also the least surprising thing to do here.
|
// transaction, so it's also the least surprising thing to do here.
|
||||||
if cn.txnStatus == txnStatusInFailedTransaction {
|
if cn.txnStatus == txnStatusInFailedTransaction {
|
||||||
if err := cn.Rollback(); err != nil {
|
if err := cn.rollback(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ErrInFailedTransaction
|
return ErrInFailedTransaction
|
||||||
|
@ -573,7 +577,10 @@ func (cn *conn) Rollback() (err error) {
|
||||||
return driver.ErrBadConn
|
return driver.ErrBadConn
|
||||||
}
|
}
|
||||||
defer cn.errRecover(&err)
|
defer cn.errRecover(&err)
|
||||||
|
return cn.rollback()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cn *conn) rollback() (err error) {
|
||||||
cn.checkIsInTransaction(true)
|
cn.checkIsInTransaction(true)
|
||||||
_, commandTag, err := cn.simpleExec("ROLLBACK")
|
_, commandTag, err := cn.simpleExec("ROLLBACK")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1500,6 +1507,39 @@ func QuoteIdentifier(name string) string {
|
||||||
return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
|
return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal
|
||||||
|
// to DDL and other statements that do not accept parameters) to be used as part
|
||||||
|
// of an SQL statement. For example:
|
||||||
|
//
|
||||||
|
// exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
|
||||||
|
// err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
|
||||||
|
//
|
||||||
|
// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be
|
||||||
|
// replaced by two backslashes (i.e. "\\") and the C-style escape identifier
|
||||||
|
// that PostgreSQL provides ('E') will be prepended to the string.
|
||||||
|
func QuoteLiteral(literal string) string {
|
||||||
|
// This follows the PostgreSQL internal algorithm for handling quoted literals
|
||||||
|
// from libpq, which can be found in the "PQEscapeStringInternal" function,
|
||||||
|
// which is found in the libpq/fe-exec.c source file:
|
||||||
|
// https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/libpq/fe-exec.c
|
||||||
|
//
|
||||||
|
// substitute any single-quotes (') with two single-quotes ('')
|
||||||
|
literal = strings.Replace(literal, `'`, `''`, -1)
|
||||||
|
// determine if the string has any backslashes (\) in it.
|
||||||
|
// if it does, replace any backslashes (\) with two backslashes (\\)
|
||||||
|
// then, we need to wrap the entire string with a PostgreSQL
|
||||||
|
// C-style escape. Per how "PQEscapeStringInternal" handles this case, we
|
||||||
|
// also add a space before the "E"
|
||||||
|
if strings.Contains(literal, `\`) {
|
||||||
|
literal = strings.Replace(literal, `\`, `\\`, -1)
|
||||||
|
literal = ` E'` + literal + `'`
|
||||||
|
} else {
|
||||||
|
// otherwise, we can just wrap the literal with a pair of single quotes
|
||||||
|
literal = `'` + literal + `'`
|
||||||
|
}
|
||||||
|
return literal
|
||||||
|
}
|
||||||
|
|
||||||
func md5s(s string) string {
|
func md5s(s string) string {
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
h.Write([]byte(s))
|
h.Write([]byte(s))
|
||||||
|
|
|
@ -117,11 +117,10 @@ func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interfa
|
||||||
}
|
}
|
||||||
return i
|
return i
|
||||||
case oid.T_float4, oid.T_float8:
|
case oid.T_float4, oid.T_float8:
|
||||||
bits := 64
|
// We always use 64 bit parsing, regardless of whether the input text is for
|
||||||
if typ == oid.T_float4 {
|
// a float4 or float8, because clients expect float64s for all float datatypes
|
||||||
bits = 32
|
// and returning a 32-bit parsed float64 produces lossy results.
|
||||||
}
|
f, err := strconv.ParseFloat(string(s), 64)
|
||||||
f, err := strconv.ParseFloat(string(s), bits)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorf("%s", err)
|
errorf("%s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,13 +478,13 @@ func errRecoverNoErrBadConn(err *error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) errRecover(err *error) {
|
func (cn *conn) errRecover(err *error) {
|
||||||
e := recover()
|
e := recover()
|
||||||
switch v := e.(type) {
|
switch v := e.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
// Do nothing
|
// Do nothing
|
||||||
case runtime.Error:
|
case runtime.Error:
|
||||||
c.bad = true
|
cn.bad = true
|
||||||
panic(v)
|
panic(v)
|
||||||
case *Error:
|
case *Error:
|
||||||
if v.Fatal() {
|
if v.Fatal() {
|
||||||
|
@ -493,7 +493,7 @@ func (c *conn) errRecover(err *error) {
|
||||||
*err = v
|
*err = v
|
||||||
}
|
}
|
||||||
case *net.OpError:
|
case *net.OpError:
|
||||||
c.bad = true
|
cn.bad = true
|
||||||
*err = v
|
*err = v
|
||||||
case error:
|
case error:
|
||||||
if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
|
if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
|
||||||
|
@ -503,13 +503,13 @@ func (c *conn) errRecover(err *error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
c.bad = true
|
cn.bad = true
|
||||||
panic(fmt.Sprintf("unknown error: %#v", e))
|
panic(fmt.Sprintf("unknown error: %#v", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any time we return ErrBadConn, we need to remember it since *Tx doesn't
|
// Any time we return ErrBadConn, we need to remember it since *Tx doesn't
|
||||||
// mark the connection bad in database/sql.
|
// mark the connection bad in database/sql.
|
||||||
if *err == driver.ErrBadConn {
|
if *err == driver.ErrBadConn {
|
||||||
c.bad = true
|
cn.bad = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// Pacakage scram implements a SCRAM-{SHA-1,etc} client per RFC5802.
|
// Package scram implements a SCRAM-{SHA-1,etc} client per RFC5802.
|
||||||
//
|
//
|
||||||
// http://tools.ietf.org/html/rfc5802
|
// http://tools.ietf.org/html/rfc5802
|
||||||
//
|
//
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
_ "github.com/mattn/go-isatty"
|
_ "github.com/mattn/go-isatty"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewColorable return new instance of Writer which handle escape sequence.
|
// NewColorable returns new instance of Writer which handles escape sequence.
|
||||||
func NewColorable(file *os.File) io.Writer {
|
func NewColorable(file *os.File) io.Writer {
|
||||||
if file == nil {
|
if file == nil {
|
||||||
panic("nil passed instead of *os.File to NewColorable()")
|
panic("nil passed instead of *os.File to NewColorable()")
|
||||||
|
@ -18,12 +18,12 @@ func NewColorable(file *os.File) io.Writer {
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
|
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||||
func NewColorableStdout() io.Writer {
|
func NewColorableStdout() io.Writer {
|
||||||
return os.Stdout
|
return os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
|
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||||
func NewColorableStderr() io.Writer {
|
func NewColorableStderr() io.Writer {
|
||||||
return os.Stderr
|
return os.Stderr
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
_ "github.com/mattn/go-isatty"
|
_ "github.com/mattn/go-isatty"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewColorable return new instance of Writer which handle escape sequence.
|
// NewColorable returns new instance of Writer which handles escape sequence.
|
||||||
func NewColorable(file *os.File) io.Writer {
|
func NewColorable(file *os.File) io.Writer {
|
||||||
if file == nil {
|
if file == nil {
|
||||||
panic("nil passed instead of *os.File to NewColorable()")
|
panic("nil passed instead of *os.File to NewColorable()")
|
||||||
|
@ -19,12 +19,12 @@ func NewColorable(file *os.File) io.Writer {
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
|
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||||
func NewColorableStdout() io.Writer {
|
func NewColorableStdout() io.Writer {
|
||||||
return os.Stdout
|
return os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
|
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||||
func NewColorableStderr() io.Writer {
|
func NewColorableStderr() io.Writer {
|
||||||
return os.Stderr
|
return os.Stderr
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ var (
|
||||||
procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer")
|
procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Writer provide colorable Writer to the console
|
// Writer provides colorable Writer to the console
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
out io.Writer
|
out io.Writer
|
||||||
handle syscall.Handle
|
handle syscall.Handle
|
||||||
|
@ -91,7 +91,7 @@ type Writer struct {
|
||||||
rest bytes.Buffer
|
rest bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorable return new instance of Writer which handle escape sequence from File.
|
// NewColorable returns new instance of Writer which handles escape sequence from File.
|
||||||
func NewColorable(file *os.File) io.Writer {
|
func NewColorable(file *os.File) io.Writer {
|
||||||
if file == nil {
|
if file == nil {
|
||||||
panic("nil passed instead of *os.File to NewColorable()")
|
panic("nil passed instead of *os.File to NewColorable()")
|
||||||
|
@ -106,12 +106,12 @@ func NewColorable(file *os.File) io.Writer {
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
|
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||||
func NewColorableStdout() io.Writer {
|
func NewColorableStdout() io.Writer {
|
||||||
return NewColorable(os.Stdout)
|
return NewColorable(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
|
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||||
func NewColorableStderr() io.Writer {
|
func NewColorableStderr() io.Writer {
|
||||||
return NewColorable(os.Stderr)
|
return NewColorable(os.Stderr)
|
||||||
}
|
}
|
||||||
|
@ -414,7 +414,15 @@ func doTitleSequence(er *bytes.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write write data on console
|
// returns Atoi(s) unless s == "" in which case it returns def
|
||||||
|
func atoiWithDefault(s string, def int) (int, error) {
|
||||||
|
if s == "" {
|
||||||
|
return def, nil
|
||||||
|
}
|
||||||
|
return strconv.Atoi(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes data on console
|
||||||
func (w *Writer) Write(data []byte) (n int, err error) {
|
func (w *Writer) Write(data []byte) (n int, err error) {
|
||||||
var csbi consoleScreenBufferInfo
|
var csbi consoleScreenBufferInfo
|
||||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
||||||
|
@ -500,7 +508,7 @@ loop:
|
||||||
|
|
||||||
switch m {
|
switch m {
|
||||||
case 'A':
|
case 'A':
|
||||||
n, err = strconv.Atoi(buf.String())
|
n, err = atoiWithDefault(buf.String(), 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -508,7 +516,7 @@ loop:
|
||||||
csbi.cursorPosition.y -= short(n)
|
csbi.cursorPosition.y -= short(n)
|
||||||
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||||
case 'B':
|
case 'B':
|
||||||
n, err = strconv.Atoi(buf.String())
|
n, err = atoiWithDefault(buf.String(), 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -516,7 +524,7 @@ loop:
|
||||||
csbi.cursorPosition.y += short(n)
|
csbi.cursorPosition.y += short(n)
|
||||||
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||||
case 'C':
|
case 'C':
|
||||||
n, err = strconv.Atoi(buf.String())
|
n, err = atoiWithDefault(buf.String(), 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -524,7 +532,7 @@ loop:
|
||||||
csbi.cursorPosition.x += short(n)
|
csbi.cursorPosition.x += short(n)
|
||||||
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||||
case 'D':
|
case 'D':
|
||||||
n, err = strconv.Atoi(buf.String())
|
n, err = atoiWithDefault(buf.String(), 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -557,6 +565,9 @@ loop:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if n < 1 {
|
||||||
|
n = 1
|
||||||
|
}
|
||||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||||
csbi.cursorPosition.x = short(n - 1)
|
csbi.cursorPosition.x = short(n - 1)
|
||||||
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
|
||||||
|
@ -635,6 +646,20 @@ loop:
|
||||||
}
|
}
|
||||||
procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||||
procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||||
|
case 'X':
|
||||||
|
n := 0
|
||||||
|
if buf.Len() > 0 {
|
||||||
|
n, err = strconv.Atoi(buf.String())
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||||
|
var cursor coord
|
||||||
|
var written dword
|
||||||
|
cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
|
||||||
|
procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||||
|
procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
|
||||||
case 'm':
|
case 'm':
|
||||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
||||||
attr := csbi.attributes
|
attr := csbi.attributes
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module github.com/mattn/go-colorable
|
module github.com/mattn/go-colorable
|
||||||
|
|
||||||
require github.com/mattn/go-isatty v0.0.5
|
require github.com/mattn/go-isatty v0.0.8
|
||||||
|
|
|
@ -5,17 +5,17 @@ import (
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NonColorable hold writer but remove escape sequence.
|
// NonColorable holds writer but removes escape sequence.
|
||||||
type NonColorable struct {
|
type NonColorable struct {
|
||||||
out io.Writer
|
out io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNonColorable return new instance of Writer which remove escape sequence from Writer.
|
// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.
|
||||||
func NewNonColorable(w io.Writer) io.Writer {
|
func NewNonColorable(w io.Writer) io.Writer {
|
||||||
return &NonColorable{out: w}
|
return &NonColorable{out: w}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write write data on console
|
// Write writes data on console
|
||||||
func (w *NonColorable) Write(data []byte) (n int, err error) {
|
func (w *NonColorable) Write(data []byte) (n int, err error) {
|
||||||
er := bytes.NewReader(data)
|
er := bytes.NewReader(data)
|
||||||
var bw [1]byte
|
var bw [1]byte
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
module github.com/mattn/go-isatty
|
module github.com/mattn/go-isatty
|
||||||
|
|
||||||
require golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
|
require golang.org/x/sys v0.0.0-20191008105621-543471e840be
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// +build appengine js
|
// +build appengine js nacl
|
||||||
|
|
||||||
package isatty
|
package isatty
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// +build plan9
|
||||||
|
|
||||||
|
package isatty
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||||
|
func IsTerminal(fd uintptr) bool {
|
||||||
|
path, err := syscall.Fd2path(fd)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return path == "/dev/cons" || path == "/mnt/term/dev/cons"
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
||||||
|
// terminal. This is also always false on this environment.
|
||||||
|
func IsCygwinTerminal(fd uintptr) bool {
|
||||||
|
return false
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build linux
|
// +build linux aix
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
// +build !android
|
// +build !android
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package isatty
|
package isatty
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
|
@ -11,15 +12,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fileNameInfo uintptr = 2
|
objectNameInfo uintptr = 1
|
||||||
|
fileNameInfo = 2
|
||||||
fileTypePipe = 3
|
fileTypePipe = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
ntdll = syscall.NewLazyDLL("ntdll.dll")
|
||||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||||
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
||||||
procGetFileType = kernel32.NewProc("GetFileType")
|
procGetFileType = kernel32.NewProc("GetFileType")
|
||||||
|
procNtQueryObject = ntdll.NewProc("NtQueryObject")
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -45,7 +49,10 @@ func isCygwinPipeName(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if token[0] != `\msys` && token[0] != `\cygwin` {
|
if token[0] != `\msys` &&
|
||||||
|
token[0] != `\cygwin` &&
|
||||||
|
token[0] != `\Device\NamedPipe\msys` &&
|
||||||
|
token[0] != `\Device\NamedPipe\cygwin` {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,12 +75,36 @@ func isCygwinPipeName(name string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
|
||||||
|
// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion
|
||||||
|
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
|
||||||
|
// Windows vista to 10
|
||||||
|
// see https://stackoverflow.com/a/18792477 for details
|
||||||
|
func getFileNameByHandle(fd uintptr) (string, error) {
|
||||||
|
if procNtQueryObject == nil {
|
||||||
|
return "", errors.New("ntdll.dll: NtQueryObject not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf [4 + syscall.MAX_PATH]uint16
|
||||||
|
var result int
|
||||||
|
r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
|
||||||
|
fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
|
||||||
|
if r != 0 {
|
||||||
|
return "", e
|
||||||
|
}
|
||||||
|
return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
|
||||||
|
}
|
||||||
|
|
||||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||||
// terminal.
|
// terminal.
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
func IsCygwinTerminal(fd uintptr) bool {
|
||||||
if procGetFileInformationByHandleEx == nil {
|
if procGetFileInformationByHandleEx == nil {
|
||||||
|
name, err := getFileNameByHandle(fd)
|
||||||
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return isCygwinPipeName(name)
|
||||||
|
}
|
||||||
|
|
||||||
// Cygwin/msys's pty is a pipe.
|
// Cygwin/msys's pty is a pipe.
|
||||||
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
|
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "1.11.x"
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test
|
|
|
@ -1,21 +0,0 @@
|
||||||
## 1.1.2
|
|
||||||
|
|
||||||
* Fix error when decode hook decodes interface implementation into interface
|
|
||||||
type. [GH-140]
|
|
||||||
|
|
||||||
## 1.1.1
|
|
||||||
|
|
||||||
* Fix panic that can happen in `decodePtr`
|
|
||||||
|
|
||||||
## 1.1.0
|
|
||||||
|
|
||||||
* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133]
|
|
||||||
* Support struct to struct decoding [GH-137]
|
|
||||||
* If source map value is nil, then destination map value is nil (instead of empty)
|
|
||||||
* If source slice value is nil, then destination slice value is nil (instead of empty)
|
|
||||||
* If source pointer is nil, then destination pointer is set to nil (instead of
|
|
||||||
allocated zero value of type)
|
|
||||||
|
|
||||||
## 1.0.0
|
|
||||||
|
|
||||||
* Initial tagged stable release.
|
|
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2013 Mitchell Hashimoto
|
|
||||||
|
|
||||||
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.
|
|
|
@ -1,46 +0,0 @@
|
||||||
# mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure)
|
|
||||||
|
|
||||||
mapstructure is a Go library for decoding generic map values to structures
|
|
||||||
and vice versa, while providing helpful error handling.
|
|
||||||
|
|
||||||
This library is most useful when decoding values from some data stream (JSON,
|
|
||||||
Gob, etc.) where you don't _quite_ know the structure of the underlying data
|
|
||||||
until you read a part of it. You can therefore read a `map[string]interface{}`
|
|
||||||
and use this library to decode it into the proper underlying native Go
|
|
||||||
structure.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Standard `go get`:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/mitchellh/mapstructure
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage & Example
|
|
||||||
|
|
||||||
For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure).
|
|
||||||
|
|
||||||
The `Decode` function has examples associated with it there.
|
|
||||||
|
|
||||||
## But Why?!
|
|
||||||
|
|
||||||
Go offers fantastic standard libraries for decoding formats such as JSON.
|
|
||||||
The standard method is to have a struct pre-created, and populate that struct
|
|
||||||
from the bytes of the encoded format. This is great, but the problem is if
|
|
||||||
you have configuration or an encoding that changes slightly depending on
|
|
||||||
specific fields. For example, consider this JSON:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "person",
|
|
||||||
"name": "Mitchell"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Perhaps we can't populate a specific structure without first reading
|
|
||||||
the "type" field from the JSON. We could always do two passes over the
|
|
||||||
decoding of the JSON (reading the "type" first, and the rest later).
|
|
||||||
However, it is much simpler to just decode this into a `map[string]interface{}`
|
|
||||||
structure, read the "type" key, then use something like this library
|
|
||||||
to decode it into the proper structure.
|
|
|
@ -1,217 +0,0 @@
|
||||||
package mapstructure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns
|
|
||||||
// it into the proper DecodeHookFunc type, such as DecodeHookFuncType.
|
|
||||||
func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
|
|
||||||
// Create variables here so we can reference them with the reflect pkg
|
|
||||||
var f1 DecodeHookFuncType
|
|
||||||
var f2 DecodeHookFuncKind
|
|
||||||
|
|
||||||
// Fill in the variables into this interface and the rest is done
|
|
||||||
// automatically using the reflect package.
|
|
||||||
potential := []interface{}{f1, f2}
|
|
||||||
|
|
||||||
v := reflect.ValueOf(h)
|
|
||||||
vt := v.Type()
|
|
||||||
for _, raw := range potential {
|
|
||||||
pt := reflect.ValueOf(raw).Type()
|
|
||||||
if vt.ConvertibleTo(pt) {
|
|
||||||
return v.Convert(pt).Interface()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeHookExec executes the given decode hook. This should be used
|
|
||||||
// since it'll naturally degrade to the older backwards compatible DecodeHookFunc
|
|
||||||
// that took reflect.Kind instead of reflect.Type.
|
|
||||||
func DecodeHookExec(
|
|
||||||
raw DecodeHookFunc,
|
|
||||||
from reflect.Type, to reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
switch f := typedDecodeHook(raw).(type) {
|
|
||||||
case DecodeHookFuncType:
|
|
||||||
return f(from, to, data)
|
|
||||||
case DecodeHookFuncKind:
|
|
||||||
return f(from.Kind(), to.Kind(), data)
|
|
||||||
default:
|
|
||||||
return nil, errors.New("invalid decode hook signature")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComposeDecodeHookFunc creates a single DecodeHookFunc that
|
|
||||||
// automatically composes multiple DecodeHookFuncs.
|
|
||||||
//
|
|
||||||
// The composed funcs are called in order, with the result of the
|
|
||||||
// previous transformation.
|
|
||||||
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
|
|
||||||
return func(
|
|
||||||
f reflect.Type,
|
|
||||||
t reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
var err error
|
|
||||||
for _, f1 := range fs {
|
|
||||||
data, err = DecodeHookExec(f1, f, t, data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modify the from kind to be correct with the new data
|
|
||||||
f = nil
|
|
||||||
if val := reflect.ValueOf(data); val.IsValid() {
|
|
||||||
f = val.Type()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringToSliceHookFunc returns a DecodeHookFunc that converts
|
|
||||||
// string to []string by splitting on the given sep.
|
|
||||||
func StringToSliceHookFunc(sep string) DecodeHookFunc {
|
|
||||||
return func(
|
|
||||||
f reflect.Kind,
|
|
||||||
t reflect.Kind,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
if f != reflect.String || t != reflect.Slice {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
raw := data.(string)
|
|
||||||
if raw == "" {
|
|
||||||
return []string{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Split(raw, sep), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts
|
|
||||||
// strings to time.Duration.
|
|
||||||
func StringToTimeDurationHookFunc() DecodeHookFunc {
|
|
||||||
return func(
|
|
||||||
f reflect.Type,
|
|
||||||
t reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
if f.Kind() != reflect.String {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
if t != reflect.TypeOf(time.Duration(5)) {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert it by parsing
|
|
||||||
return time.ParseDuration(data.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringToIPHookFunc returns a DecodeHookFunc that converts
|
|
||||||
// strings to net.IP
|
|
||||||
func StringToIPHookFunc() DecodeHookFunc {
|
|
||||||
return func(
|
|
||||||
f reflect.Type,
|
|
||||||
t reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
if f.Kind() != reflect.String {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
if t != reflect.TypeOf(net.IP{}) {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert it by parsing
|
|
||||||
ip := net.ParseIP(data.(string))
|
|
||||||
if ip == nil {
|
|
||||||
return net.IP{}, fmt.Errorf("failed parsing ip %v", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringToIPNetHookFunc returns a DecodeHookFunc that converts
|
|
||||||
// strings to net.IPNet
|
|
||||||
func StringToIPNetHookFunc() DecodeHookFunc {
|
|
||||||
return func(
|
|
||||||
f reflect.Type,
|
|
||||||
t reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
if f.Kind() != reflect.String {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
if t != reflect.TypeOf(net.IPNet{}) {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert it by parsing
|
|
||||||
_, net, err := net.ParseCIDR(data.(string))
|
|
||||||
return net, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringToTimeHookFunc returns a DecodeHookFunc that converts
|
|
||||||
// strings to time.Time.
|
|
||||||
func StringToTimeHookFunc(layout string) DecodeHookFunc {
|
|
||||||
return func(
|
|
||||||
f reflect.Type,
|
|
||||||
t reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
if f.Kind() != reflect.String {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
if t != reflect.TypeOf(time.Time{}) {
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert it by parsing
|
|
||||||
return time.Parse(layout, data.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to
|
|
||||||
// the decoder.
|
|
||||||
//
|
|
||||||
// Note that this is significantly different from the WeaklyTypedInput option
|
|
||||||
// of the DecoderConfig.
|
|
||||||
func WeaklyTypedHook(
|
|
||||||
f reflect.Kind,
|
|
||||||
t reflect.Kind,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
dataVal := reflect.ValueOf(data)
|
|
||||||
switch t {
|
|
||||||
case reflect.String:
|
|
||||||
switch f {
|
|
||||||
case reflect.Bool:
|
|
||||||
if dataVal.Bool() {
|
|
||||||
return "1", nil
|
|
||||||
}
|
|
||||||
return "0", nil
|
|
||||||
case reflect.Float32:
|
|
||||||
return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil
|
|
||||||
case reflect.Int:
|
|
||||||
return strconv.FormatInt(dataVal.Int(), 10), nil
|
|
||||||
case reflect.Slice:
|
|
||||||
dataType := dataVal.Type()
|
|
||||||
elemKind := dataType.Elem().Kind()
|
|
||||||
if elemKind == reflect.Uint8 {
|
|
||||||
return string(dataVal.Interface().([]uint8)), nil
|
|
||||||
}
|
|
||||||
case reflect.Uint:
|
|
||||||
return strconv.FormatUint(dataVal.Uint(), 10), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package mapstructure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Error implements the error interface and can represents multiple
|
|
||||||
// errors that occur in the course of a single decode.
|
|
||||||
type Error struct {
|
|
||||||
Errors []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
points := make([]string, len(e.Errors))
|
|
||||||
for i, err := range e.Errors {
|
|
||||||
points[i] = fmt.Sprintf("* %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(points)
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"%d error(s) decoding:\n\n%s",
|
|
||||||
len(e.Errors), strings.Join(points, "\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WrappedErrors implements the errwrap.Wrapper interface to make this
|
|
||||||
// return value more useful with the errwrap and go-multierror libraries.
|
|
||||||
func (e *Error) WrappedErrors() []error {
|
|
||||||
if e == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
result := make([]error, len(e.Errors))
|
|
||||||
for i, e := range e.Errors {
|
|
||||||
result[i] = errors.New(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendErrors(errors []string, err error) []string {
|
|
||||||
switch e := err.(type) {
|
|
||||||
case *Error:
|
|
||||||
return append(errors, e.Errors...)
|
|
||||||
default:
|
|
||||||
return append(errors, e.Error())
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue