mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 06:12:25 -05:00 
			
		
		
		
	[feature] Support OTLP HTTP, drop Jaeger (#2184)
* [feature] Add http trace exporter, drop Jaeger Jaeger supports ingesting traces using the OpenTelemetry gRPC or HTTP methods. The Jaeger project has deprecated the old jaeger transport. * Add support for submitting traces over HTTP * Drop support for the old Jaeger protocol * Upgrade the trace libraries to v1.17 Fixes: #2176 Fixes: #2179
This commit is contained in:
		
					parent
					
						
							
								916c6d07ba
							
						
					
				
			
			
				commit
				
					
						14ef098099
					
				
			
		
					 199 changed files with 12972 additions and 18581 deletions
				
			
		|  | @ -18,21 +18,20 @@ request-id-header: "X-Request-Id" | ||||||
| # Default: false | # Default: false | ||||||
| tracing-enabled: false | tracing-enabled: false | ||||||
| 
 | 
 | ||||||
| # String. Set the transport protocol for the tracing system. Can either be "grpc" for | # String. Set the transport protocol for the tracing system. Can either be "grpc"  | ||||||
| # OTLP gRPC or "jaeger" for jaeger based ingesters. | # for OTLP gRPC, or "http" for OTLP HTTP. | ||||||
| # Options: ["grpc", "jaeger"] | # Options: ["grpc", "http"] | ||||||
| # Default: "grpc" | # Default: "grpc" | ||||||
| tracing-transport: "grpc" | tracing-transport: "grpc" | ||||||
| 
 | 
 | ||||||
| # String. Endpoint of the trace ingester. When using the gRPC based transport, the | # String. Endpoint of the trace ingester. When using the gRPC or HTTP based  | ||||||
| # endpoint is usually a single address/port combination. For the jaeger transport it | # transports, provide the endpoint as a single address/port combination without a  | ||||||
| # should be a fully qualified URL. | # protocol scheme. | ||||||
| # OTLP gRPC or "jaeger" for jaeger based ingesters | # Examples: ["localhost:4317"] | ||||||
| # Examples: ["localhost:4317", "http://localhost:14268/api/traces"] |  | ||||||
| # Default: "" | # Default: "" | ||||||
| tracing-endpoint: "" | tracing-endpoint: "" | ||||||
| 
 | 
 | ||||||
| # Bool. Disable HTTPS for the gRPC transport protocol. | # Bool. Disable TLS for the gRPC and HTTP transport protocols. | ||||||
| # Default: false | # Default: false | ||||||
| tracing-insecure-transport: false | tracing-insecure-transport: false | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | @ -724,21 +724,19 @@ request-id-header: "X-Request-Id" | ||||||
| # Default: false | # Default: false | ||||||
| tracing-enabled: false | tracing-enabled: false | ||||||
| 
 | 
 | ||||||
| # String. Set the transport protocol for the tracing system. Can either be "grpc" for | # String. Set the transport protocol for the tracing system. Can either be "grpc" | ||||||
| # OTLP gRPC or "jaeger" for jaeger based ingesters. | # for OTLP gRPC, or "http" for OTLP HTTP. | ||||||
| # Options: ["grpc", "jaeger"] | # Options: ["grpc", "http"] | ||||||
| # Default: "grpc" | # Default: "grpc" | ||||||
| tracing-transport: "grpc" | tracing-transport: "grpc" | ||||||
| 
 | 
 | ||||||
| # String. Endpoint of the trace ingester. When using the gRPC based transport, the | # String. Endpoint of the trace ingester. When using the gRPC or HTTP based transports, | ||||||
| # endpoint is usually a single address/port combination. For the jaeger transport it | # provide the endpoint as a single address/port combination without a protocol scheme. | ||||||
| # should be a fully qualified URL. | # Examples: ["localhost:4317"] | ||||||
| # OTLP gRPC or "jaeger" for jaeger based ingesters |  | ||||||
| # Examples: ["localhost:4317", "http://localhost:14268/api/traces"] |  | ||||||
| # Default: "" | # Default: "" | ||||||
| tracing-endpoint: "" | tracing-endpoint: "" | ||||||
| 
 | 
 | ||||||
| # Bool. Disable HTTPS for the gRPC transport protocol. | # Bool. Disable TLS for the gRPC and HTTP transport protocols. | ||||||
| # Default: false | # Default: false | ||||||
| tracing-insecure-transport: false | tracing-insecure-transport: false | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -53,11 +53,11 @@ require ( | ||||||
| 	github.com/uptrace/bun/extra/bunotel v1.1.14 | 	github.com/uptrace/bun/extra/bunotel v1.1.14 | ||||||
| 	github.com/wagslane/go-password-validator v0.3.0 | 	github.com/wagslane/go-password-validator v0.3.0 | ||||||
| 	github.com/yuin/goldmark v1.5.6 | 	github.com/yuin/goldmark v1.5.6 | ||||||
| 	go.opentelemetry.io/otel v1.16.0 | 	go.opentelemetry.io/otel v1.17.0 | ||||||
| 	go.opentelemetry.io/otel/exporters/jaeger v1.16.0 | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0 | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.17.0 | ||||||
| 	go.opentelemetry.io/otel/sdk v1.16.0 | 	go.opentelemetry.io/otel/sdk v1.17.0 | ||||||
| 	go.opentelemetry.io/otel/trace v1.16.0 | 	go.opentelemetry.io/otel/trace v1.17.0 | ||||||
| 	go.uber.org/automaxprocs v1.5.3 | 	go.uber.org/automaxprocs v1.5.3 | ||||||
| 	golang.org/x/crypto v0.12.0 | 	golang.org/x/crypto v0.12.0 | ||||||
| 	golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 | 	golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 | ||||||
|  | @ -118,7 +118,7 @@ require ( | ||||||
| 	github.com/gorilla/css v1.0.0 // indirect | 	github.com/gorilla/css v1.0.0 // indirect | ||||||
| 	github.com/gorilla/securecookie v1.1.1 // indirect | 	github.com/gorilla/securecookie v1.1.1 // indirect | ||||||
| 	github.com/gorilla/sessions v1.2.1 // indirect | 	github.com/gorilla/sessions v1.2.1 // indirect | ||||||
| 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect | 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect | ||||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||||
| 	github.com/inconshreveable/mousetrap v1.1.0 // indirect | 	github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||||
| 	github.com/jackc/chunkreader/v2 v2.0.1 // indirect | 	github.com/jackc/chunkreader/v2 v2.0.1 // indirect | ||||||
|  | @ -159,17 +159,17 @@ require ( | ||||||
| 	github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.1 // indirect | 	github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.1 // indirect | ||||||
| 	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect | 	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect | ||||||
| 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect | 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect | 	go.opentelemetry.io/otel/metric v1.17.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/metric v1.16.0 // indirect | 	go.opentelemetry.io/proto/otlp v1.0.0 // indirect | ||||||
| 	go.opentelemetry.io/proto/otlp v0.19.0 // indirect |  | ||||||
| 	golang.org/x/arch v0.3.0 // indirect | 	golang.org/x/arch v0.3.0 // indirect | ||||||
| 	golang.org/x/mod v0.10.0 // indirect | 	golang.org/x/mod v0.10.0 // indirect | ||||||
| 	golang.org/x/sys v0.11.0 // indirect | 	golang.org/x/sys v0.11.0 // indirect | ||||||
| 	golang.org/x/tools v0.6.0 // indirect | 	golang.org/x/tools v0.6.0 // indirect | ||||||
| 	google.golang.org/appengine v1.6.7 // indirect | 	google.golang.org/appengine v1.6.7 // indirect | ||||||
| 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect | 	google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect | ||||||
| 	google.golang.org/grpc v1.55.0 // indirect | 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect | ||||||
|  | 	google.golang.org/grpc v1.57.0 // indirect | ||||||
| 	google.golang.org/protobuf v1.31.0 // indirect | 	google.golang.org/protobuf v1.31.0 // indirect | ||||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||||
|  |  | ||||||
							
								
								
									
										82
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										82
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -91,14 +91,12 @@ github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW5 | ||||||
| github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= | github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= | ||||||
| github.com/KimMachineGun/automemlimit v0.3.0 h1:khgwM5ESVN85cE6Bq2ozMAAWDfrOEwQ51D/YlmThE04= | github.com/KimMachineGun/automemlimit v0.3.0 h1:khgwM5ESVN85cE6Bq2ozMAAWDfrOEwQ51D/YlmThE04= | ||||||
| github.com/KimMachineGun/automemlimit v0.3.0/go.mod h1:pJhTW/nWJMj6SnWSU2TEKSlCaM+1N5Mej+IfS/5/Ol0= | github.com/KimMachineGun/automemlimit v0.3.0/go.mod h1:pJhTW/nWJMj6SnWSU2TEKSlCaM+1N5Mej+IfS/5/Ol0= | ||||||
| github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= |  | ||||||
| github.com/abema/go-mp4 v0.13.0 h1:gjEZLt7g0ePpYA5sUDrI2r8X+WuI8o+USkgG5wMgmkI= | github.com/abema/go-mp4 v0.13.0 h1:gjEZLt7g0ePpYA5sUDrI2r8X+WuI8o+USkgG5wMgmkI= | ||||||
| github.com/abema/go-mp4 v0.13.0/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws= | github.com/abema/go-mp4 v0.13.0/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws= | ||||||
| github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= | github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= | ||||||
| github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= | github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= | ||||||
| github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= | github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= | ||||||
| github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= | github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= | ||||||
| github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= |  | ||||||
| github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= | github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= | ||||||
| github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= | github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= | ||||||
| github.com/buckket/go-blurhash v1.1.0 h1:X5M6r0LIvwdvKiUtiNcRL2YlmOfMzYobI3VCKCZc9Do= | github.com/buckket/go-blurhash v1.1.0 h1:X5M6r0LIvwdvKiUtiNcRL2YlmOfMzYobI3VCKCZc9Do= | ||||||
|  | @ -109,8 +107,6 @@ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX | ||||||
| github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= | github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= | ||||||
| github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= | github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= | ||||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||||
| github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= |  | ||||||
| github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= |  | ||||||
| github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= | ||||||
| github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= | ||||||
| github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= | ||||||
|  | @ -123,11 +119,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk | ||||||
| github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= | ||||||
| github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | ||||||
| github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | ||||||
| github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |  | ||||||
| github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ= | github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ= | ||||||
| github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= | github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= | ||||||
| github.com/containerd/cgroups/v3 v3.0.1 h1:4hfGvu8rfGIwVIDd+nLzn/B9ZXx4BcCjzt5ToenJRaE= | github.com/containerd/cgroups/v3 v3.0.1 h1:4hfGvu8rfGIwVIDd+nLzn/B9ZXx4BcCjzt5ToenJRaE= | ||||||
|  | @ -175,8 +166,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m | ||||||
| github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= | ||||||
| github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= | ||||||
| github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= | ||||||
| github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= |  | ||||||
| github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= |  | ||||||
| github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | ||||||
| github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= | github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= | ||||||
| github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= | github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= | ||||||
|  | @ -191,7 +180,6 @@ github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q | ||||||
| github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= | github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= | ||||||
| github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= | github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= | ||||||
| github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= | github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= | ||||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= |  | ||||||
| github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g= | github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g= | ||||||
| github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs= | github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs= | ||||||
| github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= | github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= | ||||||
|  | @ -251,7 +239,6 @@ github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgR | ||||||
| github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo= | github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo= | ||||||
| github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= | github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= | ||||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||||
| github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= |  | ||||||
| github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= | github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= | ||||||
| github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||||
| github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||||
|  | @ -281,7 +268,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD | ||||||
| github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||||
| github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||||
| github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||||||
| github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= |  | ||||||
| github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | ||||||
| github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||||
|  | @ -296,7 +282,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ | ||||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= |  | ||||||
| github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||||
| github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | ||||||
| github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | ||||||
|  | @ -338,9 +323,8 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z | ||||||
| github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||||||
| github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= | ||||||
| github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||||||
| github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= | github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= | ||||||
| github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= | github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= | ||||||
| github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= |  | ||||||
| github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= | github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= | ||||||
| github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= | github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= | ||||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||||
|  | @ -494,7 +478,6 @@ github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTep | ||||||
| github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= | github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= | ||||||
| github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= | ||||||
| github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= | ||||||
| github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= |  | ||||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||||
| github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | ||||||
| github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= | ||||||
|  | @ -518,7 +501,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE | ||||||
| github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | ||||||
| github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= | github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= | ||||||
| github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | ||||||
| github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= |  | ||||||
| github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= | github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= | ||||||
| github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= | github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= | ||||||
| github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= | github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= | ||||||
|  | @ -535,7 +517,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ | ||||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
| github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= | ||||||
| github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||||||
| github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= |  | ||||||
| github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||||
|  | @ -647,25 +628,22 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||||
| go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||||
| go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | ||||||
| go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= | ||||||
| go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= | go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM= | ||||||
| go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= | go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= | ||||||
| go.opentelemetry.io/otel/exporters/jaeger v1.16.0 h1:YhxxmXZ011C0aDZKoNw+juVWAmEfv/0W2XBOv9aHTaA= | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 h1:U5GYackKpVKlPrd/5gKMlrTlP2dCESAAFU682VCpieY= | ||||||
| go.opentelemetry.io/otel/exporters/jaeger v1.16.0/go.mod h1:grYbBo/5afWlPpdPZYhyn78Bk04hnvxn2+hvxQhKIQM= | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0/go.mod h1:aFsJfCEnLzEu9vRRAcUiB/cpRTbVsNdF3OHSPpdjxZQ= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0 h1:iGeIsSYwpYSvh5UGzWrJfTDJvPjrXtxl3GUppj6IXQU= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0/go.mod h1:1j3H3G1SBYpZFti6OI4P0uRQCW20MXkG5v4UWXppLLE= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.17.0 h1:kvWMtSUNVylLVrOE4WLUmBtgziYoCIYUNSpTYtMzVJI= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.17.0/go.mod h1:SExUrRYIXhDgEKG4tkiQovd2HTaELiHUsuK08s5Nqx4= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= | go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= | go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= | ||||||
| go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= | go.opentelemetry.io/otel/sdk v1.17.0 h1:FLN2X66Ke/k5Sg3V623Q7h7nt3cHXaW1FOvKKrW0IpE= | ||||||
| go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= | go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ= | ||||||
| go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= | go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= | ||||||
| go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= | go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= | ||||||
| go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= | go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= | ||||||
| go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= | go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= | ||||||
| go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= |  | ||||||
| go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= |  | ||||||
| go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= |  | ||||||
| go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||||
| go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||||
| go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= | go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= | ||||||
|  | @ -771,7 +749,6 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY | ||||||
| golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= |  | ||||||
| golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||||||
| golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||||
|  | @ -787,7 +764,6 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ | ||||||
| golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | ||||||
| golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | ||||||
| golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | ||||||
| golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= |  | ||||||
| golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= | golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= | ||||||
| golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= | golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= | ||||||
| golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | @ -848,10 +824,8 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w | ||||||
| golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |  | ||||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | @ -875,7 +849,6 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 | ||||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
| golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
| golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |  | ||||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
| golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||||||
| golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||||||
|  | @ -993,7 +966,6 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG | ||||||
| google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= | ||||||
| google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= | ||||||
| google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= | ||||||
| google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= |  | ||||||
| google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= | ||||||
| google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= | ||||||
| google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= | ||||||
|  | @ -1007,9 +979,11 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D | ||||||
| google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | ||||||
| google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | ||||||
| google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= | ||||||
| google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= | google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw= | ||||||
| google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= | google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= | ||||||
| google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= | google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= | ||||||
|  | google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= | ||||||
|  | google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= | ||||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||||
| google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||||
|  | @ -1023,15 +997,11 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji | ||||||
| google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= | ||||||
| google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= | ||||||
| google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= | ||||||
| google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= |  | ||||||
| google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= | ||||||
| google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= | ||||||
| google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= | ||||||
| google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= | google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= | ||||||
| google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= | google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= | ||||||
| google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= |  | ||||||
| google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= |  | ||||||
| google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= |  | ||||||
| google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||||
| google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||||
| google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | ||||||
|  | @ -1044,7 +1014,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj | ||||||
| google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= | ||||||
| google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||||
| google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||||
| google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= |  | ||||||
| google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||||
| google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= | ||||||
| google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||||
|  | @ -1064,7 +1033,6 @@ gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg | ||||||
| gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= | gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= | ||||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |  | ||||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
|  |  | ||||||
|  | @ -131,9 +131,9 @@ type Configuration struct { | ||||||
| 	OIDCAdminGroups      []string `name:"oidc-admin-groups" usage:"Membership of one of the listed groups makes someone a GtS admin"` | 	OIDCAdminGroups      []string `name:"oidc-admin-groups" usage:"Membership of one of the listed groups makes someone a GtS admin"` | ||||||
| 
 | 
 | ||||||
| 	TracingEnabled           bool   `name:"tracing-enabled" usage:"Enable OTLP Tracing"` | 	TracingEnabled           bool   `name:"tracing-enabled" usage:"Enable OTLP Tracing"` | ||||||
| 	TracingTransport         string `name:"tracing-transport" usage:"grpc or jaeger"` | 	TracingTransport         string `name:"tracing-transport" usage:"grpc or http"` | ||||||
| 	TracingEndpoint          string `name:"tracing-endpoint" usage:"Endpoint of your trace collector. Eg., 'localhost:4317' for gRPC, 'http://localhost:14268/api/traces' for jaeger"` | 	TracingEndpoint          string `name:"tracing-endpoint" usage:"Endpoint of your trace collector. Eg., 'localhost:4317' for gRPC, 'localhost:4318' for http"` | ||||||
| 	TracingInsecureTransport bool   `name:"tracing-insecure" usage:"Disable HTTPS for the gRPC transport protocol"` | 	TracingInsecureTransport bool   `name:"tracing-insecure-transport" usage:"Disable TLS for the gRPC or HTTP transport protocol"` | ||||||
| 
 | 
 | ||||||
| 	SMTPHost               string `name:"smtp-host" usage:"Host of the smtp server. Eg., 'smtp.eu.mailgun.org'"` | 	SMTPHost               string `name:"smtp-host" usage:"Host of the smtp server. Eg., 'smtp.eu.mailgun.org'"` | ||||||
| 	SMTPPort               int    `name:"smtp-port" usage:"Port of the smtp server. Eg., 587"` | 	SMTPPort               int    `name:"smtp-port" usage:"Port of the smtp server. Eg., 587"` | ||||||
|  |  | ||||||
|  | @ -1991,7 +1991,7 @@ func (st *ConfigState) SetTracingInsecureTransport(v bool) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TracingInsecureTransportFlag returns the flag name for the 'TracingInsecureTransport' field | // TracingInsecureTransportFlag returns the flag name for the 'TracingInsecureTransport' field | ||||||
| func TracingInsecureTransportFlag() string { return "tracing-insecure" } | func TracingInsecureTransportFlag() string { return "tracing-insecure-transport" } | ||||||
| 
 | 
 | ||||||
| // GetTracingInsecureTransport safely fetches the value for global configuration 'TracingInsecureTransport' field | // GetTracingInsecureTransport safely fetches the value for global configuration 'TracingInsecureTransport' field | ||||||
| func GetTracingInsecureTransport() bool { return global.GetTracingInsecureTransport() } | func GetTracingInsecureTransport() bool { return global.GetTracingInsecureTransport() } | ||||||
|  |  | ||||||
|  | @ -29,8 +29,8 @@ import ( | ||||||
| 	"github.com/uptrace/bun/extra/bunotel" | 	"github.com/uptrace/bun/extra/bunotel" | ||||||
| 	"go.opentelemetry.io/otel" | 	"go.opentelemetry.io/otel" | ||||||
| 	"go.opentelemetry.io/otel/attribute" | 	"go.opentelemetry.io/otel/attribute" | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" | 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" | ||||||
|  | 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" | ||||||
| 	"go.opentelemetry.io/otel/propagation" | 	"go.opentelemetry.io/otel/propagation" | ||||||
| 	"go.opentelemetry.io/otel/sdk/resource" | 	"go.opentelemetry.io/otel/sdk/resource" | ||||||
| 	"go.opentelemetry.io/otel/sdk/trace" | 	"go.opentelemetry.io/otel/sdk/trace" | ||||||
|  | @ -69,8 +69,14 @@ func Initialize() error { | ||||||
| 			return fmt.Errorf("building tracing exporter: %w", err) | 			return fmt.Errorf("building tracing exporter: %w", err) | ||||||
| 		} | 		} | ||||||
| 		tpo = trace.WithBatcher(exp) | 		tpo = trace.WithBatcher(exp) | ||||||
| 	case "jaeger": | 	case "http": | ||||||
| 		exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(config.GetTracingEndpoint()))) | 		opts := []otlptracehttp.Option{ | ||||||
|  | 			otlptracehttp.WithEndpoint(config.GetTracingEndpoint()), | ||||||
|  | 		} | ||||||
|  | 		if insecure { | ||||||
|  | 			opts = append(opts, otlptracehttp.WithInsecure()) | ||||||
|  | 		} | ||||||
|  | 		exp, err := otlptracehttp.New(context.Background(), opts...) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("building tracing exporter: %w", err) | 			return fmt.Errorf("building tracing exporter: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -146,7 +146,7 @@ EXPECT=$(cat << "EOF" | ||||||
|     "tls-certificate-key": "", |     "tls-certificate-key": "", | ||||||
|     "tracing-enabled": false, |     "tracing-enabled": false, | ||||||
|     "tracing-endpoint": "localhost:4317", |     "tracing-endpoint": "localhost:4317", | ||||||
|     "tracing-insecure": false, |     "tracing-insecure-transport": true, | ||||||
|     "tracing-transport": "grpc", |     "tracing-transport": "grpc", | ||||||
|     "trusted-proxies": [ |     "trusted-proxies": [ | ||||||
|         "127.0.0.1/32", |         "127.0.0.1/32", | ||||||
|  | @ -242,6 +242,7 @@ GTS_SYSLOG_ENABLED=true \ | ||||||
| GTS_SYSLOG_PROTOCOL='udp' \ | GTS_SYSLOG_PROTOCOL='udp' \ | ||||||
| GTS_SYSLOG_ADDRESS='127.0.0.1:6969' \ | GTS_SYSLOG_ADDRESS='127.0.0.1:6969' \ | ||||||
| GTS_TRACING_ENDPOINT='localhost:4317' \ | GTS_TRACING_ENDPOINT='localhost:4317' \ | ||||||
|  | GTS_TRACING_INSECURE_TRANSPORT=true \ | ||||||
| GTS_ADVANCED_COOKIES_SAMESITE='strict' \ | GTS_ADVANCED_COOKIES_SAMESITE='strict' \ | ||||||
| GTS_ADVANCED_RATE_LIMIT_EXCEPTIONS="192.0.2.0/24,127.0.0.1/32" \ | GTS_ADVANCED_RATE_LIMIT_EXCEPTIONS="192.0.2.0/24,127.0.0.1/32" \ | ||||||
| GTS_ADVANCED_RATE_LIMIT_REQUESTS=6969 \ | GTS_ADVANCED_RATE_LIMIT_REQUESTS=6969 \ | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,10 +1,10 @@ | ||||||
|  | //go:build gofuzz | ||||||
| // +build gofuzz | // +build gofuzz | ||||||
| 
 | 
 | ||||||
| package httprule | package httprule | ||||||
| 
 | 
 | ||||||
| func Fuzz(data []byte) int { | func Fuzz(data []byte) int { | ||||||
| 	_, err := Parse(string(data)) | 	if _, err := Parse(string(data)); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return 0 | 		return 0 | ||||||
| 	} | 	} | ||||||
| 	return 0 | 	return 0 | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,7 @@ | ||||||
| package httprule | package httprule | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
|  | @ -164,9 +165,9 @@ func (p *parser) segment() (segment, error) { | ||||||
| 
 | 
 | ||||||
| 	v, err := p.variable() | 	v, err := p.variable() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("segment neither wildcards, literal or variable: %v", err) | 		return nil, fmt.Errorf("segment neither wildcards, literal or variable: %w", err) | ||||||
| 	} | 	} | ||||||
| 	return v, err | 	return v, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *parser) literal() (segment, error) { | func (p *parser) literal() (segment, error) { | ||||||
|  | @ -191,7 +192,7 @@ func (p *parser) variable() (segment, error) { | ||||||
| 	if _, err := p.accept("="); err == nil { | 	if _, err := p.accept("="); err == nil { | ||||||
| 		segs, err = p.segments() | 		segs, err = p.segments() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("invalid segment in variable %q: %v", path, err) | 			return nil, fmt.Errorf("invalid segment in variable %q: %w", path, err) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		segs = []segment{wildcard{}} | 		segs = []segment{wildcard{}} | ||||||
|  | @ -213,12 +214,12 @@ func (p *parser) fieldPath() (string, error) { | ||||||
| 	} | 	} | ||||||
| 	components := []string{c} | 	components := []string{c} | ||||||
| 	for { | 	for { | ||||||
| 		if _, err = p.accept("."); err != nil { | 		if _, err := p.accept("."); err != nil { | ||||||
| 			return strings.Join(components, "."), nil | 			return strings.Join(components, "."), nil | ||||||
| 		} | 		} | ||||||
| 		c, err := p.accept(typeIdent) | 		c, err := p.accept(typeIdent) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return "", fmt.Errorf("invalid field path component: %v", err) | 			return "", fmt.Errorf("invalid field path component: %w", err) | ||||||
| 		} | 		} | ||||||
| 		components = append(components, c) | 		components = append(components, c) | ||||||
| 	} | 	} | ||||||
|  | @ -237,10 +238,8 @@ const ( | ||||||
| 	typeEOF     = termType("$") | 	typeEOF     = termType("$") | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | // eof is the terminal symbol which always appears at the end of token sequence. | ||||||
| 	// eof is the terminal symbol which always appears at the end of token sequence. | const eof = "\u0000" | ||||||
| 	eof = "\u0000" |  | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| // accept tries to accept a token in "p". | // accept tries to accept a token in "p". | ||||||
| // This function consumes a token and returns it if it matches to the specified "term". | // This function consumes a token and returns it if it matches to the specified "term". | ||||||
|  | @ -275,11 +274,12 @@ func (p *parser) accept(term termType) (string, error) { | ||||||
| // expectPChars determines if "t" consists of only pchars defined in RFC3986. | // expectPChars determines if "t" consists of only pchars defined in RFC3986. | ||||||
| // | // | ||||||
| // https://www.ietf.org/rfc/rfc3986.txt, P.49 | // https://www.ietf.org/rfc/rfc3986.txt, P.49 | ||||||
| //   pchar         = unreserved / pct-encoded / sub-delims / ":" / "@" | // | ||||||
| //   unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~" | //	pchar         = unreserved / pct-encoded / sub-delims / ":" / "@" | ||||||
| //   sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" | //	unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~" | ||||||
| //                 / "*" / "+" / "," / ";" / "=" | //	sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" | ||||||
| //   pct-encoded   = "%" HEXDIG HEXDIG | //	              / "*" / "+" / "," / ";" / "=" | ||||||
|  | //	pct-encoded   = "%" HEXDIG HEXDIG | ||||||
| func expectPChars(t string) error { | func expectPChars(t string) error { | ||||||
| 	const ( | 	const ( | ||||||
| 		init = iota | 		init = iota | ||||||
|  | @ -333,7 +333,7 @@ func expectPChars(t string) error { | ||||||
| // expectIdent determines if "ident" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*). | // expectIdent determines if "ident" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*). | ||||||
| func expectIdent(ident string) error { | func expectIdent(ident string) error { | ||||||
| 	if ident == "" { | 	if ident == "" { | ||||||
| 		return fmt.Errorf("empty identifier") | 		return errors.New("empty identifier") | ||||||
| 	} | 	} | ||||||
| 	for pos, r := range ident { | 	for pos, r := range ident { | ||||||
| 		switch { | 		switch { | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -27,9 +27,9 @@ go_library( | ||||||
|         "//internal/httprule", |         "//internal/httprule", | ||||||
|         "//utilities", |         "//utilities", | ||||||
|         "@go_googleapis//google/api:httpbody_go_proto", |         "@go_googleapis//google/api:httpbody_go_proto", | ||||||
|         "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", |  | ||||||
|         "@org_golang_google_grpc//codes", |         "@org_golang_google_grpc//codes", | ||||||
|         "@org_golang_google_grpc//grpclog", |         "@org_golang_google_grpc//grpclog", | ||||||
|  |         "@org_golang_google_grpc//health/grpc_health_v1", | ||||||
|         "@org_golang_google_grpc//metadata", |         "@org_golang_google_grpc//metadata", | ||||||
|         "@org_golang_google_grpc//status", |         "@org_golang_google_grpc//status", | ||||||
|         "@org_golang_google_protobuf//encoding/protojson", |         "@org_golang_google_protobuf//encoding/protojson", | ||||||
|  | @ -37,6 +37,8 @@ go_library( | ||||||
|         "@org_golang_google_protobuf//reflect/protoreflect", |         "@org_golang_google_protobuf//reflect/protoreflect", | ||||||
|         "@org_golang_google_protobuf//reflect/protoregistry", |         "@org_golang_google_protobuf//reflect/protoregistry", | ||||||
|         "@org_golang_google_protobuf//types/known/durationpb", |         "@org_golang_google_protobuf//types/known/durationpb", | ||||||
|  |         "@org_golang_google_protobuf//types/known/fieldmaskpb", | ||||||
|  |         "@org_golang_google_protobuf//types/known/structpb", | ||||||
|         "@org_golang_google_protobuf//types/known/timestamppb", |         "@org_golang_google_protobuf//types/known/timestamppb", | ||||||
|         "@org_golang_google_protobuf//types/known/wrapperspb", |         "@org_golang_google_protobuf//types/known/wrapperspb", | ||||||
|     ], |     ], | ||||||
|  | @ -56,8 +58,10 @@ go_test( | ||||||
|         "marshal_jsonpb_test.go", |         "marshal_jsonpb_test.go", | ||||||
|         "marshal_proto_test.go", |         "marshal_proto_test.go", | ||||||
|         "marshaler_registry_test.go", |         "marshaler_registry_test.go", | ||||||
|  |         "mux_internal_test.go", | ||||||
|         "mux_test.go", |         "mux_test.go", | ||||||
|         "pattern_test.go", |         "pattern_test.go", | ||||||
|  |         "query_fuzz_test.go", | ||||||
|         "query_test.go", |         "query_test.go", | ||||||
|     ], |     ], | ||||||
|     embed = [":runtime"], |     embed = [":runtime"], | ||||||
|  | @ -69,8 +73,9 @@ go_test( | ||||||
|         "@go_googleapis//google/api:httpbody_go_proto", |         "@go_googleapis//google/api:httpbody_go_proto", | ||||||
|         "@go_googleapis//google/rpc:errdetails_go_proto", |         "@go_googleapis//google/rpc:errdetails_go_proto", | ||||||
|         "@go_googleapis//google/rpc:status_go_proto", |         "@go_googleapis//google/rpc:status_go_proto", | ||||||
|         "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", |         "@org_golang_google_grpc//:go_default_library", | ||||||
|         "@org_golang_google_grpc//codes", |         "@org_golang_google_grpc//codes", | ||||||
|  |         "@org_golang_google_grpc//health/grpc_health_v1", | ||||||
|         "@org_golang_google_grpc//metadata", |         "@org_golang_google_grpc//metadata", | ||||||
|         "@org_golang_google_grpc//status", |         "@org_golang_google_grpc//status", | ||||||
|         "@org_golang_google_protobuf//encoding/protojson", |         "@org_golang_google_protobuf//encoding/protojson", | ||||||
|  | @ -78,6 +83,7 @@ go_test( | ||||||
|         "@org_golang_google_protobuf//testing/protocmp", |         "@org_golang_google_protobuf//testing/protocmp", | ||||||
|         "@org_golang_google_protobuf//types/known/durationpb", |         "@org_golang_google_protobuf//types/known/durationpb", | ||||||
|         "@org_golang_google_protobuf//types/known/emptypb", |         "@org_golang_google_protobuf//types/known/emptypb", | ||||||
|  |         "@org_golang_google_protobuf//types/known/fieldmaskpb", | ||||||
|         "@org_golang_google_protobuf//types/known/structpb", |         "@org_golang_google_protobuf//types/known/structpb", | ||||||
|         "@org_golang_google_protobuf//types/known/timestamppb", |         "@org_golang_google_protobuf//types/known/timestamppb", | ||||||
|         "@org_golang_google_protobuf//types/known/wrapperspb", |         "@org_golang_google_protobuf//types/known/wrapperspb", | ||||||
|  |  | ||||||
							
								
								
									
										72
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -13,6 +13,7 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/grpclog" | ||||||
| 	"google.golang.org/grpc/metadata" | 	"google.golang.org/grpc/metadata" | ||||||
| 	"google.golang.org/grpc/status" | 	"google.golang.org/grpc/status" | ||||||
| ) | ) | ||||||
|  | @ -35,11 +36,15 @@ const metadataHeaderBinarySuffix = "-Bin" | ||||||
| const xForwardedFor = "X-Forwarded-For" | const xForwardedFor = "X-Forwarded-For" | ||||||
| const xForwardedHost = "X-Forwarded-Host" | const xForwardedHost = "X-Forwarded-Host" | ||||||
| 
 | 
 | ||||||
| var ( | // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound | ||||||
| 	// DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound | // header isn't present. If the value is 0 the sent `context` will not have a timeout. | ||||||
| 	// header isn't present. If the value is 0 the sent `context` will not have a timeout. | var DefaultContextTimeout = 0 * time.Second | ||||||
| 	DefaultContextTimeout = 0 * time.Second | 
 | ||||||
| ) | // malformedHTTPHeaders lists the headers that the gRPC server may reject outright as malformed. | ||||||
|  | // See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more context. | ||||||
|  | var malformedHTTPHeaders = map[string]struct{}{ | ||||||
|  | 	"connection": {}, | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| type ( | type ( | ||||||
| 	rpcMethodKey       struct{} | 	rpcMethodKey       struct{} | ||||||
|  | @ -95,12 +100,43 @@ func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Reque | ||||||
| 	return metadata.NewIncomingContext(ctx, md), nil | 	return metadata.NewIncomingContext(ctx, md), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func isValidGRPCMetadataKey(key string) bool { | ||||||
|  | 	// Must be a valid gRPC "Header-Name" as defined here: | ||||||
|  | 	//   https://github.com/grpc/grpc/blob/4b05dc88b724214d0c725c8e7442cbc7a61b1374/doc/PROTOCOL-HTTP2.md | ||||||
|  | 	// This means 0-9 a-z _ - . | ||||||
|  | 	// Only lowercase letters are valid in the wire protocol, but the client library will normalize | ||||||
|  | 	// uppercase ASCII to lowercase, so uppercase ASCII is also acceptable. | ||||||
|  | 	bytes := []byte(key) // gRPC validates strings on the byte level, not Unicode. | ||||||
|  | 	for _, ch := range bytes { | ||||||
|  | 		validLowercaseLetter := ch >= 'a' && ch <= 'z' | ||||||
|  | 		validUppercaseLetter := ch >= 'A' && ch <= 'Z' | ||||||
|  | 		validDigit := ch >= '0' && ch <= '9' | ||||||
|  | 		validOther := ch == '.' || ch == '-' || ch == '_' | ||||||
|  | 		if !validLowercaseLetter && !validUppercaseLetter && !validDigit && !validOther { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func isValidGRPCMetadataTextValue(textValue string) bool { | ||||||
|  | 	// Must be a valid gRPC "ASCII-Value" as defined here: | ||||||
|  | 	//   https://github.com/grpc/grpc/blob/4b05dc88b724214d0c725c8e7442cbc7a61b1374/doc/PROTOCOL-HTTP2.md | ||||||
|  | 	// This means printable ASCII (including/plus spaces); 0x20 to 0x7E inclusive. | ||||||
|  | 	bytes := []byte(textValue) // gRPC validates strings on the byte level, not Unicode. | ||||||
|  | 	for _, ch := range bytes { | ||||||
|  | 		if ch < 0x20 || ch > 0x7E { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, metadata.MD, error) { | func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, metadata.MD, error) { | ||||||
| 	ctx = withRPCMethod(ctx, rpcMethodName) | 	ctx = withRPCMethod(ctx, rpcMethodName) | ||||||
| 	for _, o := range options { | 	for _, o := range options { | ||||||
| 		ctx = o(ctx) | 		ctx = o(ctx) | ||||||
| 	} | 	} | ||||||
| 	var pairs []string |  | ||||||
| 	timeout := DefaultContextTimeout | 	timeout := DefaultContextTimeout | ||||||
| 	if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { | 	if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { | ||||||
| 		var err error | 		var err error | ||||||
|  | @ -109,7 +145,7 @@ func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcM | ||||||
| 			return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) | 			return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 	var pairs []string | ||||||
| 	for key, vals := range req.Header { | 	for key, vals := range req.Header { | ||||||
| 		key = textproto.CanonicalMIMEHeaderKey(key) | 		key = textproto.CanonicalMIMEHeaderKey(key) | ||||||
| 		for _, val := range vals { | 		for _, val := range vals { | ||||||
|  | @ -118,6 +154,10 @@ func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcM | ||||||
| 				pairs = append(pairs, "authorization", val) | 				pairs = append(pairs, "authorization", val) | ||||||
| 			} | 			} | ||||||
| 			if h, ok := mux.incomingHeaderMatcher(key); ok { | 			if h, ok := mux.incomingHeaderMatcher(key); ok { | ||||||
|  | 				if !isValidGRPCMetadataKey(h) { | ||||||
|  | 					grpclog.Errorf("HTTP header name %q is not valid as gRPC metadata key; skipping", h) | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
| 				// Handles "-bin" metadata in grpc, since grpc will do another base64 | 				// Handles "-bin" metadata in grpc, since grpc will do another base64 | ||||||
| 				// encode before sending to server, we need to decode it first. | 				// encode before sending to server, we need to decode it first. | ||||||
| 				if strings.HasSuffix(key, metadataHeaderBinarySuffix) { | 				if strings.HasSuffix(key, metadataHeaderBinarySuffix) { | ||||||
|  | @ -127,6 +167,9 @@ func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcM | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					val = string(b) | 					val = string(b) | ||||||
|  | 				} else if !isValidGRPCMetadataTextValue(val) { | ||||||
|  | 					grpclog.Errorf("Value of HTTP header %q contains non-ASCII value (not valid as gRPC metadata): skipping", h) | ||||||
|  | 					continue | ||||||
| 				} | 				} | ||||||
| 				pairs = append(pairs, h, val) | 				pairs = append(pairs, h, val) | ||||||
| 			} | 			} | ||||||
|  | @ -172,11 +215,17 @@ type serverMetadataKey struct{} | ||||||
| 
 | 
 | ||||||
| // NewServerMetadataContext creates a new context with ServerMetadata | // NewServerMetadataContext creates a new context with ServerMetadata | ||||||
| func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { | func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { | ||||||
|  | 	if ctx == nil { | ||||||
|  | 		ctx = context.Background() | ||||||
|  | 	} | ||||||
| 	return context.WithValue(ctx, serverMetadataKey{}, md) | 	return context.WithValue(ctx, serverMetadataKey{}, md) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ServerMetadataFromContext returns the ServerMetadata in ctx | // ServerMetadataFromContext returns the ServerMetadata in ctx | ||||||
| func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { | func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { | ||||||
|  | 	if ctx == nil { | ||||||
|  | 		return md, false | ||||||
|  | 	} | ||||||
| 	md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) | 	md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  | @ -269,8 +318,8 @@ func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { | ||||||
| 	case 'n': | 	case 'n': | ||||||
| 		return time.Nanosecond, true | 		return time.Nanosecond, true | ||||||
| 	default: | 	default: | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| 	return |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // isPermanentHTTPHeader checks whether hdr belongs to the list of | // isPermanentHTTPHeader checks whether hdr belongs to the list of | ||||||
|  | @ -308,6 +357,13 @@ func isPermanentHTTPHeader(hdr string) bool { | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // isMalformedHTTPHeader checks whether header belongs to the list of | ||||||
|  | // "malformed headers" and would be rejected by the gRPC server. | ||||||
|  | func isMalformedHTTPHeader(header string) bool { | ||||||
|  | 	_, isMalformed := malformedHTTPHeaders[strings.ToLower(header)] | ||||||
|  | 	return isMalformed | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // RPCMethod returns the method string for the server context. The returned | // RPCMethod returns the method string for the server context. The returned | ||||||
| // string is in the format of "/package.service/method". | // string is in the format of "/package.service/method". | ||||||
| func RPCMethod(ctx context.Context) (string, bool) { | func RPCMethod(ctx context.Context) (string, bool) { | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -37,7 +37,7 @@ func BoolSlice(val, sep string) ([]bool, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Bool(v) | 		value, err := Bool(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -57,7 +57,7 @@ func Float64Slice(val, sep string) ([]float64, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Float64(v) | 		value, err := Float64(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -81,7 +81,7 @@ func Float32Slice(val, sep string) ([]float32, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Float32(v) | 		value, err := Float32(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -101,7 +101,7 @@ func Int64Slice(val, sep string) ([]int64, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Int64(v) | 		value, err := Int64(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -125,7 +125,7 @@ func Int32Slice(val, sep string) ([]int32, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Int32(v) | 		value, err := Int32(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -145,7 +145,7 @@ func Uint64Slice(val, sep string) ([]uint64, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Uint64(v) | 		value, err := Uint64(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -169,7 +169,7 @@ func Uint32Slice(val, sep string) ([]uint32, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Uint32(v) | 		value, err := Uint32(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -197,7 +197,7 @@ func BytesSlice(val, sep string) ([][]byte, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Bytes(v) | 		value, err := Bytes(v) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
|  | @ -209,8 +209,7 @@ func Timestamp(val string) (*timestamppb.Timestamp, error) { | ||||||
| 	var r timestamppb.Timestamp | 	var r timestamppb.Timestamp | ||||||
| 	val = strconv.Quote(strings.Trim(val, `"`)) | 	val = strconv.Quote(strings.Trim(val, `"`)) | ||||||
| 	unmarshaler := &protojson.UnmarshalOptions{} | 	unmarshaler := &protojson.UnmarshalOptions{} | ||||||
| 	err := unmarshaler.Unmarshal([]byte(val), &r) | 	if err := unmarshaler.Unmarshal([]byte(val), &r); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &r, nil | 	return &r, nil | ||||||
|  | @ -221,8 +220,7 @@ func Duration(val string) (*durationpb.Duration, error) { | ||||||
| 	var r durationpb.Duration | 	var r durationpb.Duration | ||||||
| 	val = strconv.Quote(strings.Trim(val, `"`)) | 	val = strconv.Quote(strings.Trim(val, `"`)) | ||||||
| 	unmarshaler := &protojson.UnmarshalOptions{} | 	unmarshaler := &protojson.UnmarshalOptions{} | ||||||
| 	err := unmarshaler.Unmarshal([]byte(val), &r) | 	if err := unmarshaler.Unmarshal([]byte(val), &r); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &r, nil | 	return &r, nil | ||||||
|  | @ -257,66 +255,64 @@ func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) { | ||||||
| 	for i, v := range s { | 	for i, v := range s { | ||||||
| 		value, err := Enum(v, enumValMap) | 		value, err := Enum(v, enumValMap) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return values, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		values[i] = value | 		values[i] = value | ||||||
| 	} | 	} | ||||||
| 	return values, nil | 	return values, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | // Support for google.protobuf.wrappers on top of primitive types | ||||||
| 	Support fot google.protobuf.wrappers on top of primitive types |  | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
| // StringValue well-known type support as wrapper around string type | // StringValue well-known type support as wrapper around string type | ||||||
| func StringValue(val string) (*wrapperspb.StringValue, error) { | func StringValue(val string) (*wrapperspb.StringValue, error) { | ||||||
| 	return &wrapperspb.StringValue{Value: val}, nil | 	return wrapperspb.String(val), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FloatValue well-known type support as wrapper around float32 type | // FloatValue well-known type support as wrapper around float32 type | ||||||
| func FloatValue(val string) (*wrapperspb.FloatValue, error) { | func FloatValue(val string) (*wrapperspb.FloatValue, error) { | ||||||
| 	parsedVal, err := Float32(val) | 	parsedVal, err := Float32(val) | ||||||
| 	return &wrapperspb.FloatValue{Value: parsedVal}, err | 	return wrapperspb.Float(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DoubleValue well-known type support as wrapper around float64 type | // DoubleValue well-known type support as wrapper around float64 type | ||||||
| func DoubleValue(val string) (*wrapperspb.DoubleValue, error) { | func DoubleValue(val string) (*wrapperspb.DoubleValue, error) { | ||||||
| 	parsedVal, err := Float64(val) | 	parsedVal, err := Float64(val) | ||||||
| 	return &wrapperspb.DoubleValue{Value: parsedVal}, err | 	return wrapperspb.Double(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // BoolValue well-known type support as wrapper around bool type | // BoolValue well-known type support as wrapper around bool type | ||||||
| func BoolValue(val string) (*wrapperspb.BoolValue, error) { | func BoolValue(val string) (*wrapperspb.BoolValue, error) { | ||||||
| 	parsedVal, err := Bool(val) | 	parsedVal, err := Bool(val) | ||||||
| 	return &wrapperspb.BoolValue{Value: parsedVal}, err | 	return wrapperspb.Bool(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Int32Value well-known type support as wrapper around int32 type | // Int32Value well-known type support as wrapper around int32 type | ||||||
| func Int32Value(val string) (*wrapperspb.Int32Value, error) { | func Int32Value(val string) (*wrapperspb.Int32Value, error) { | ||||||
| 	parsedVal, err := Int32(val) | 	parsedVal, err := Int32(val) | ||||||
| 	return &wrapperspb.Int32Value{Value: parsedVal}, err | 	return wrapperspb.Int32(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UInt32Value well-known type support as wrapper around uint32 type | // UInt32Value well-known type support as wrapper around uint32 type | ||||||
| func UInt32Value(val string) (*wrapperspb.UInt32Value, error) { | func UInt32Value(val string) (*wrapperspb.UInt32Value, error) { | ||||||
| 	parsedVal, err := Uint32(val) | 	parsedVal, err := Uint32(val) | ||||||
| 	return &wrapperspb.UInt32Value{Value: parsedVal}, err | 	return wrapperspb.UInt32(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Int64Value well-known type support as wrapper around int64 type | // Int64Value well-known type support as wrapper around int64 type | ||||||
| func Int64Value(val string) (*wrapperspb.Int64Value, error) { | func Int64Value(val string) (*wrapperspb.Int64Value, error) { | ||||||
| 	parsedVal, err := Int64(val) | 	parsedVal, err := Int64(val) | ||||||
| 	return &wrapperspb.Int64Value{Value: parsedVal}, err | 	return wrapperspb.Int64(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UInt64Value well-known type support as wrapper around uint64 type | // UInt64Value well-known type support as wrapper around uint64 type | ||||||
| func UInt64Value(val string) (*wrapperspb.UInt64Value, error) { | func UInt64Value(val string) (*wrapperspb.UInt64Value, error) { | ||||||
| 	parsedVal, err := Uint64(val) | 	parsedVal, err := Uint64(val) | ||||||
| 	return &wrapperspb.UInt64Value{Value: parsedVal}, err | 	return wrapperspb.UInt64(parsedVal), err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // BytesValue well-known type support as wrapper around bytes[] type | // BytesValue well-known type support as wrapper around bytes[] type | ||||||
| func BytesValue(val string) (*wrapperspb.BytesValue, error) { | func BytesValue(val string) (*wrapperspb.BytesValue, error) { | ||||||
| 	parsedVal, err := Bytes(val) | 	parsedVal, err := Bytes(val) | ||||||
| 	return &wrapperspb.BytesValue{Value: parsedVal}, err | 	return wrapperspb.Bytes(parsedVal), err | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -38,7 +38,7 @@ func HTTPStatusFromCode(code codes.Code) int { | ||||||
| 	case codes.OK: | 	case codes.OK: | ||||||
| 		return http.StatusOK | 		return http.StatusOK | ||||||
| 	case codes.Canceled: | 	case codes.Canceled: | ||||||
| 		return http.StatusRequestTimeout | 		return 499 | ||||||
| 	case codes.Unknown: | 	case codes.Unknown: | ||||||
| 		return http.StatusInternalServerError | 		return http.StatusInternalServerError | ||||||
| 	case codes.InvalidArgument: | 	case codes.InvalidArgument: | ||||||
|  | @ -70,10 +70,10 @@ func HTTPStatusFromCode(code codes.Code) int { | ||||||
| 		return http.StatusServiceUnavailable | 		return http.StatusServiceUnavailable | ||||||
| 	case codes.DataLoss: | 	case codes.DataLoss: | ||||||
| 		return http.StatusInternalServerError | 		return http.StatusInternalServerError | ||||||
|  | 	default: | ||||||
|  | 		grpclog.Infof("Unknown gRPC error code: %v", code) | ||||||
|  | 		return http.StatusInternalServerError | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	grpclog.Infof("Unknown gRPC error code: %v", code) |  | ||||||
| 	return http.StatusInternalServerError |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // HTTPError uses the mux-configured error handler. | // HTTPError uses the mux-configured error handler. | ||||||
|  | @ -162,10 +162,11 @@ func DefaultStreamErrorHandler(_ context.Context, err error) *status.Status { | ||||||
| 
 | 
 | ||||||
| // DefaultRoutingErrorHandler is our default handler for routing errors. | // DefaultRoutingErrorHandler is our default handler for routing errors. | ||||||
| // By default http error codes mapped on the following error codes: | // By default http error codes mapped on the following error codes: | ||||||
| //   NotFound -> grpc.NotFound | // | ||||||
| //   StatusBadRequest -> grpc.InvalidArgument | //	NotFound -> grpc.NotFound | ||||||
| //   MethodNotAllowed -> grpc.Unimplemented | //	StatusBadRequest -> grpc.InvalidArgument | ||||||
| //   Other -> grpc.Internal, method is not expecting to be called for anything else | //	MethodNotAllowed -> grpc.Unimplemented | ||||||
|  | //	Other -> grpc.Internal, method is not expecting to be called for anything else | ||||||
| func DefaultRoutingErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) { | func DefaultRoutingErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) { | ||||||
| 	sterr := status.Error(codes.Internal, "Unexpected routing error") | 	sterr := status.Error(codes.Internal, "Unexpected routing error") | ||||||
| 	switch httpStatus { | 	switch httpStatus { | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -2,13 +2,14 @@ package runtime | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"sort" | 	"sort" | ||||||
| 
 | 
 | ||||||
| 	"google.golang.org/genproto/protobuf/field_mask" |  | ||||||
| 	"google.golang.org/protobuf/proto" | 	"google.golang.org/protobuf/proto" | ||||||
| 	"google.golang.org/protobuf/reflect/protoreflect" | 	"google.golang.org/protobuf/reflect/protoreflect" | ||||||
|  | 	field_mask "google.golang.org/protobuf/types/known/fieldmaskpb" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func getFieldByName(fields protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor { | func getFieldByName(fields protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor { | ||||||
|  | @ -44,7 +45,7 @@ func FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.Field | ||||||
| 			// if the item is an object, then enqueue all of its children | 			// if the item is an object, then enqueue all of its children | ||||||
| 			for k, v := range m { | 			for k, v := range m { | ||||||
| 				if item.msg == nil { | 				if item.msg == nil { | ||||||
| 					return nil, fmt.Errorf("JSON structure did not match request type") | 					return nil, errors.New("JSON structure did not match request type") | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				fd := getFieldByName(item.msg.Descriptor().Fields(), k) | 				fd := getFieldByName(item.msg.Descriptor().Fields(), k) | ||||||
|  | @ -53,7 +54,7 @@ func FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.Field | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if isDynamicProtoMessage(fd.Message()) { | 				if isDynamicProtoMessage(fd.Message()) { | ||||||
| 					for _, p := range buildPathsBlindly(k, v) { | 					for _, p := range buildPathsBlindly(string(fd.FullName().Name()), v) { | ||||||
| 						newPath := p | 						newPath := p | ||||||
| 						if item.path != "" { | 						if item.path != "" { | ||||||
| 							newPath = item.path + "." + newPath | 							newPath = item.path + "." + newPath | ||||||
|  | @ -63,7 +64,7 @@ func FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.Field | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if isProtobufAnyMessage(fd.Message()) { | 				if isProtobufAnyMessage(fd.Message()) && !fd.IsList() { | ||||||
| 					_, hasTypeField := v.(map[string]interface{})["@type"] | 					_, hasTypeField := v.(map[string]interface{})["@type"] | ||||||
| 					if hasTypeField { | 					if hasTypeField { | ||||||
| 						queue = append(queue, fieldMaskPathItem{path: k}) | 						queue = append(queue, fieldMaskPathItem{path: k}) | ||||||
|  |  | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -52,11 +52,11 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) | 			handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { | 		if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { | ||||||
| 			handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) | 			handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -82,15 +82,15 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal | ||||||
| 
 | 
 | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			grpclog.Infof("Failed to marshal response chunk: %v", err) | 			grpclog.Infof("Failed to marshal response chunk: %v", err) | ||||||
| 			handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) | 			handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if _, err = w.Write(buf); err != nil { | 		if _, err := w.Write(buf); err != nil { | ||||||
| 			grpclog.Infof("Failed to send response chunk: %v", err) | 			grpclog.Infof("Failed to send response chunk: %v", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		wroteHeader = true | 		wroteHeader = true | ||||||
| 		if _, err = w.Write(delimiter); err != nil { | 		if _, err := w.Write(delimiter); err != nil { | ||||||
| 			grpclog.Infof("Failed to send delimiter chunk: %v", err) | 			grpclog.Infof("Failed to send delimiter chunk: %v", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | @ -200,20 +200,24 @@ func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, re | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) { | func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error, delimiter []byte) { | ||||||
| 	st := mux.streamErrorHandler(ctx, err) | 	st := mux.streamErrorHandler(ctx, err) | ||||||
| 	msg := errorChunk(st) | 	msg := errorChunk(st) | ||||||
| 	if !wroteHeader { | 	if !wroteHeader { | ||||||
| 		w.Header().Set("Content-Type", marshaler.ContentType(msg)) | 		w.Header().Set("Content-Type", marshaler.ContentType(msg)) | ||||||
| 		w.WriteHeader(HTTPStatusFromCode(st.Code())) | 		w.WriteHeader(HTTPStatusFromCode(st.Code())) | ||||||
| 	} | 	} | ||||||
| 	buf, merr := marshaler.Marshal(msg) | 	buf, err := marshaler.Marshal(msg) | ||||||
| 	if merr != nil { | 	if err != nil { | ||||||
| 		grpclog.Infof("Failed to marshal an error: %v", merr) | 		grpclog.Infof("Failed to marshal an error: %v", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if _, werr := w.Write(buf); werr != nil { | 	if _, err := w.Write(buf); err != nil { | ||||||
| 		grpclog.Infof("Failed to notify error to client: %v", werr) | 		grpclog.Infof("Failed to notify error to client: %v", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if _, err := w.Write(delimiter); err != nil { | ||||||
|  | 		grpclog.Infof("Failed to send delimiter chunk: %v", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -92,23 +92,20 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { | ||||||
| 
 | 
 | ||||||
| 		if rv.Type().Elem().Implements(protoMessageType) { | 		if rv.Type().Elem().Implements(protoMessageType) { | ||||||
| 			var buf bytes.Buffer | 			var buf bytes.Buffer | ||||||
| 			err := buf.WriteByte('[') | 			if err := buf.WriteByte('['); err != nil { | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 			for i := 0; i < rv.Len(); i++ { | 			for i := 0; i < rv.Len(); i++ { | ||||||
| 				if i != 0 { | 				if i != 0 { | ||||||
| 					err = buf.WriteByte(',') | 					if err := buf.WriteByte(','); err != nil { | ||||||
| 					if err != nil { |  | ||||||
| 						return nil, err | 						return nil, err | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if err = j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { | 				if err := j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { | ||||||
| 					return nil, err | 					return nil, err | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			err = buf.WriteByte(']') | 			if err := buf.WriteByte(']'); err != nil { | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -117,17 +114,16 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { | ||||||
| 
 | 
 | ||||||
| 		if rv.Type().Elem().Implements(typeProtoEnum) { | 		if rv.Type().Elem().Implements(typeProtoEnum) { | ||||||
| 			var buf bytes.Buffer | 			var buf bytes.Buffer | ||||||
| 			err := buf.WriteByte('[') | 			if err := buf.WriteByte('['); err != nil { | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 			for i := 0; i < rv.Len(); i++ { | 			for i := 0; i < rv.Len(); i++ { | ||||||
| 				if i != 0 { | 				if i != 0 { | ||||||
| 					err = buf.WriteByte(',') | 					if err := buf.WriteByte(','); err != nil { | ||||||
| 					if err != nil { |  | ||||||
| 						return nil, err | 						return nil, err | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				var err error | ||||||
| 				if j.UseEnumNumbers { | 				if j.UseEnumNumbers { | ||||||
| 					_, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10)) | 					_, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10)) | ||||||
| 				} else { | 				} else { | ||||||
|  | @ -137,8 +133,7 @@ func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { | ||||||
| 					return nil, err | 					return nil, err | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			err = buf.WriteByte(']') | 			if err := buf.WriteByte(']'); err != nil { | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -219,8 +214,7 @@ func decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v int | ||||||
| 
 | 
 | ||||||
| 	// Decode into bytes for marshalling | 	// Decode into bytes for marshalling | ||||||
| 	var b json.RawMessage | 	var b json.RawMessage | ||||||
| 	err := d.Decode(&b) | 	if err := d.Decode(&b); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -239,8 +233,7 @@ func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions | ||||||
| 		if rv.Type().ConvertibleTo(typeProtoMessage) { | 		if rv.Type().ConvertibleTo(typeProtoMessage) { | ||||||
| 			// Decode into bytes for marshalling | 			// Decode into bytes for marshalling | ||||||
| 			var b json.RawMessage | 			var b json.RawMessage | ||||||
| 			err := d.Decode(&b) | 			if err := d.Decode(&b); err != nil { | ||||||
| 			if err != nil { |  | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -280,6 +273,17 @@ func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if rv.Kind() == reflect.Slice { | 	if rv.Kind() == reflect.Slice { | ||||||
|  | 		if rv.Type().Elem().Kind() == reflect.Uint8 { | ||||||
|  | 			var sl []byte | ||||||
|  | 			if err := d.Decode(&sl); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if sl != nil { | ||||||
|  | 				rv.SetBytes(sl) | ||||||
|  | 			} | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		var sl []json.RawMessage | 		var sl []json.RawMessage | ||||||
| 		if err := d.Decode(&sl); err != nil { | 		if err := d.Decode(&sl); err != nil { | ||||||
| 			return err | 			return err | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,10 +1,8 @@ | ||||||
| package runtime | package runtime | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"io" |  | ||||||
| 
 |  | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io/ioutil" | 	"io" | ||||||
| 
 | 
 | ||||||
| 	"google.golang.org/protobuf/proto" | 	"google.golang.org/protobuf/proto" | ||||||
| ) | ) | ||||||
|  | @ -38,7 +36,7 @@ func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error { | ||||||
| // NewDecoder returns a Decoder which reads proto stream from "reader". | // NewDecoder returns a Decoder which reads proto stream from "reader". | ||||||
| func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder { | func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder { | ||||||
| 	return DecoderFunc(func(value interface{}) error { | 	return DecoderFunc(func(value interface{}) error { | ||||||
| 		buffer, err := ioutil.ReadAll(reader) | 		buffer, err := io.ReadAll(reader) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  | @ -53,8 +51,7 @@ func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		_, err = writer.Write(buffer) | 		if _, err := writer.Write(buffer); err != nil { | ||||||
| 		if err != nil { |  | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										162
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -6,10 +6,13 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/textproto" | 	"net/textproto" | ||||||
|  | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule" | 	"github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/grpclog" | ||||||
|  | 	"google.golang.org/grpc/health/grpc_health_v1" | ||||||
| 	"google.golang.org/grpc/metadata" | 	"google.golang.org/grpc/metadata" | ||||||
| 	"google.golang.org/grpc/status" | 	"google.golang.org/grpc/status" | ||||||
| 	"google.golang.org/protobuf/proto" | 	"google.golang.org/protobuf/proto" | ||||||
|  | @ -23,15 +26,15 @@ const ( | ||||||
| 	// path string before doing any routing. | 	// path string before doing any routing. | ||||||
| 	UnescapingModeLegacy UnescapingMode = iota | 	UnescapingModeLegacy UnescapingMode = iota | ||||||
| 
 | 
 | ||||||
| 	// EscapingTypeExceptReserved unescapes all path parameters except RFC 6570 | 	// UnescapingModeAllExceptReserved unescapes all path parameters except RFC 6570 | ||||||
| 	// reserved characters. | 	// reserved characters. | ||||||
| 	UnescapingModeAllExceptReserved | 	UnescapingModeAllExceptReserved | ||||||
| 
 | 
 | ||||||
| 	// EscapingTypeExceptSlash unescapes URL path parameters except path | 	// UnescapingModeAllExceptSlash unescapes URL path parameters except path | ||||||
| 	// seperators, which will be left as "%2F". | 	// separators, which will be left as "%2F". | ||||||
| 	UnescapingModeAllExceptSlash | 	UnescapingModeAllExceptSlash | ||||||
| 
 | 
 | ||||||
| 	// URL path parameters will be fully decoded. | 	// UnescapingModeAllCharacters unescapes all URL path parameters. | ||||||
| 	UnescapingModeAllCharacters | 	UnescapingModeAllCharacters | ||||||
| 
 | 
 | ||||||
| 	// UnescapingModeDefault is the default escaping type. | 	// UnescapingModeDefault is the default escaping type. | ||||||
|  | @ -40,6 +43,8 @@ const ( | ||||||
| 	UnescapingModeDefault = UnescapingModeLegacy | 	UnescapingModeDefault = UnescapingModeLegacy | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | var encodedPathSplitter = regexp.MustCompile("(/|%2F)") | ||||||
|  | 
 | ||||||
| // A HandlerFunc handles a specific pair of path pattern and HTTP method. | // A HandlerFunc handles a specific pair of path pattern and HTTP method. | ||||||
| type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) | type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) | ||||||
| 
 | 
 | ||||||
|  | @ -75,7 +80,7 @@ func WithForwardResponseOption(forwardResponseOption func(context.Context, http. | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // WithEscapingType sets the escaping type. See the definitions of UnescapingMode | // WithUnescapingMode sets the escaping type. See the definitions of UnescapingMode | ||||||
| // for more information. | // for more information. | ||||||
| func WithUnescapingMode(mode UnescapingMode) ServeMuxOption { | func WithUnescapingMode(mode UnescapingMode) ServeMuxOption { | ||||||
| 	return func(serveMux *ServeMux) { | 	return func(serveMux *ServeMux) { | ||||||
|  | @ -96,13 +101,14 @@ func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMux | ||||||
| type HeaderMatcherFunc func(string) (string, bool) | type HeaderMatcherFunc func(string) (string, bool) | ||||||
| 
 | 
 | ||||||
| // DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header | // DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header | ||||||
| // keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with | // keys (as specified by the IANA, e.g: Accept, Cookie, Host) to the gRPC metadata with the grpcgateway- prefix. If you want to know which headers are considered permanent, you can view the isPermanentHTTPHeader function. | ||||||
| // 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'. | // HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata after removing the prefix 'Grpc-Metadata-'. | ||||||
|  | // Other headers are not added to the gRPC metadata. | ||||||
| func DefaultHeaderMatcher(key string) (string, bool) { | func DefaultHeaderMatcher(key string) (string, bool) { | ||||||
| 	key = textproto.CanonicalMIMEHeaderKey(key) | 	switch key = textproto.CanonicalMIMEHeaderKey(key); { | ||||||
| 	if isPermanentHTTPHeader(key) { | 	case isPermanentHTTPHeader(key): | ||||||
| 		return MetadataPrefix + key, true | 		return MetadataPrefix + key, true | ||||||
| 	} else if strings.HasPrefix(key, MetadataHeaderPrefix) { | 	case strings.HasPrefix(key, MetadataHeaderPrefix): | ||||||
| 		return key[len(MetadataHeaderPrefix):], true | 		return key[len(MetadataHeaderPrefix):], true | ||||||
| 	} | 	} | ||||||
| 	return "", false | 	return "", false | ||||||
|  | @ -113,11 +119,30 @@ func DefaultHeaderMatcher(key string) (string, bool) { | ||||||
| // This matcher will be called with each header in http.Request. If matcher returns true, that header will be | // This matcher will be called with each header in http.Request. If matcher returns true, that header will be | ||||||
| // passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. | // passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. | ||||||
| func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { | func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { | ||||||
|  | 	for _, header := range fn.matchedMalformedHeaders() { | ||||||
|  | 		grpclog.Warningf("The configured forwarding filter would allow %q to be sent to the gRPC server, which will likely cause errors. See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more information.", header) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return func(mux *ServeMux) { | 	return func(mux *ServeMux) { | ||||||
| 		mux.incomingHeaderMatcher = fn | 		mux.incomingHeaderMatcher = fn | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // matchedMalformedHeaders returns the malformed headers that would be forwarded to gRPC server. | ||||||
|  | func (fn HeaderMatcherFunc) matchedMalformedHeaders() []string { | ||||||
|  | 	if fn == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	headers := make([]string, 0) | ||||||
|  | 	for header := range malformedHTTPHeaders { | ||||||
|  | 		out, accept := fn(header) | ||||||
|  | 		if accept && isMalformedHTTPHeader(out) { | ||||||
|  | 			headers = append(headers, out) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return headers | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. | // WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. | ||||||
| // | // | ||||||
| // This matcher will be called with each header in response header metadata. If matcher returns true, that header will be | // This matcher will be called with each header in response header metadata. If matcher returns true, that header will be | ||||||
|  | @ -179,6 +204,56 @@ func WithDisablePathLengthFallback() ServeMuxOption { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // WithHealthEndpointAt returns a ServeMuxOption that will add an endpoint to the created ServeMux at the path specified by endpointPath. | ||||||
|  | // When called the handler will forward the request to the upstream grpc service health check (defined in the | ||||||
|  | // gRPC Health Checking Protocol). | ||||||
|  | // | ||||||
|  | // See here https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/health_check/ for more information on how | ||||||
|  | // to setup the protocol in the grpc server. | ||||||
|  | // | ||||||
|  | // If you define a service as query parameter, this will also be forwarded as service in the HealthCheckRequest. | ||||||
|  | func WithHealthEndpointAt(healthCheckClient grpc_health_v1.HealthClient, endpointPath string) ServeMuxOption { | ||||||
|  | 	return func(s *ServeMux) { | ||||||
|  | 		// error can be ignored since pattern is definitely valid | ||||||
|  | 		_ = s.HandlePath( | ||||||
|  | 			http.MethodGet, endpointPath, func(w http.ResponseWriter, r *http.Request, _ map[string]string, | ||||||
|  | 			) { | ||||||
|  | 				_, outboundMarshaler := MarshalerForRequest(s, r) | ||||||
|  | 
 | ||||||
|  | 				resp, err := healthCheckClient.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{ | ||||||
|  | 					Service: r.URL.Query().Get("service"), | ||||||
|  | 				}) | ||||||
|  | 				if err != nil { | ||||||
|  | 					s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err) | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				w.Header().Set("Content-Type", "application/json") | ||||||
|  | 
 | ||||||
|  | 				if resp.GetStatus() != grpc_health_v1.HealthCheckResponse_SERVING { | ||||||
|  | 					switch resp.GetStatus() { | ||||||
|  | 					case grpc_health_v1.HealthCheckResponse_NOT_SERVING, grpc_health_v1.HealthCheckResponse_UNKNOWN: | ||||||
|  | 						err = status.Error(codes.Unavailable, resp.String()) | ||||||
|  | 					case grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN: | ||||||
|  | 						err = status.Error(codes.NotFound, resp.String()) | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err) | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				_ = outboundMarshaler.NewEncoder(w).Encode(resp) | ||||||
|  | 			}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHealthzEndpoint returns a ServeMuxOption that will add a /healthz endpoint to the created ServeMux. | ||||||
|  | // | ||||||
|  | // See WithHealthEndpointAt for the general implementation. | ||||||
|  | func WithHealthzEndpoint(healthCheckClient grpc_health_v1.HealthClient) ServeMuxOption { | ||||||
|  | 	return WithHealthEndpointAt(healthCheckClient, "/healthz") | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // NewServeMux returns a new ServeMux whose internal mapping is empty. | // NewServeMux returns a new ServeMux whose internal mapping is empty. | ||||||
| func NewServeMux(opts ...ServeMuxOption) *ServeMux { | func NewServeMux(opts ...ServeMuxOption) *ServeMux { | ||||||
| 	serveMux := &ServeMux{ | 	serveMux := &ServeMux{ | ||||||
|  | @ -229,7 +304,7 @@ func (s *ServeMux) HandlePath(meth string, pathPattern string, h HandlerFunc) er | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. | // ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.URL.Path. | ||||||
| func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 	ctx := r.Context() | 	ctx := r.Context() | ||||||
| 
 | 
 | ||||||
|  | @ -245,8 +320,6 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 		path = r.URL.RawPath | 		path = r.URL.RawPath | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	components := strings.Split(path[1:], "/") |  | ||||||
| 
 |  | ||||||
| 	if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { | 	if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { | ||||||
| 		r.Method = strings.ToUpper(override) | 		r.Method = strings.ToUpper(override) | ||||||
| 		if err := r.ParseForm(); err != nil { | 		if err := r.ParseForm(); err != nil { | ||||||
|  | @ -257,8 +330,18 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Verb out here is to memoize for the fallback case below | 	var pathComponents []string | ||||||
| 	var verb string | 	// since in UnescapeModeLegacy, the URL will already have been fully unescaped, if we also split on "%2F" | ||||||
|  | 	// in this escaping mode we would be double unescaping but in UnescapingModeAllCharacters, we still do as the | ||||||
|  | 	// path is the RawPath (i.e. unescaped). That does mean that the behavior of this function will change its default | ||||||
|  | 	// behavior when the UnescapingModeDefault gets changed from UnescapingModeLegacy to UnescapingModeAllExceptReserved | ||||||
|  | 	if s.unescapingMode == UnescapingModeAllCharacters { | ||||||
|  | 		pathComponents = encodedPathSplitter.Split(path[1:], -1) | ||||||
|  | 	} else { | ||||||
|  | 		pathComponents = strings.Split(path[1:], "/") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lastPathComponent := pathComponents[len(pathComponents)-1] | ||||||
| 
 | 
 | ||||||
| 	for _, h := range s.handlers[r.Method] { | 	for _, h := range s.handlers[r.Method] { | ||||||
| 		// If the pattern has a verb, explicitly look for a suffix in the last | 		// If the pattern has a verb, explicitly look for a suffix in the last | ||||||
|  | @ -269,23 +352,28 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 		// parser because we know what verb we're looking for, however, there | 		// parser because we know what verb we're looking for, however, there | ||||||
| 		// are still some cases that the parser itself cannot disambiguate. See | 		// are still some cases that the parser itself cannot disambiguate. See | ||||||
| 		// the comment there if interested. | 		// the comment there if interested. | ||||||
|  | 
 | ||||||
|  | 		var verb string | ||||||
| 		patVerb := h.pat.Verb() | 		patVerb := h.pat.Verb() | ||||||
| 		l := len(components) | 
 | ||||||
| 		lastComponent := components[l-1] | 		idx := -1 | ||||||
| 		var idx int = -1 | 		if patVerb != "" && strings.HasSuffix(lastPathComponent, ":"+patVerb) { | ||||||
| 		if patVerb != "" && strings.HasSuffix(lastComponent, ":"+patVerb) { | 			idx = len(lastPathComponent) - len(patVerb) - 1 | ||||||
| 			idx = len(lastComponent) - len(patVerb) - 1 |  | ||||||
| 		} | 		} | ||||||
| 		if idx == 0 { | 		if idx == 0 { | ||||||
| 			_, outboundMarshaler := MarshalerForRequest(s, r) | 			_, outboundMarshaler := MarshalerForRequest(s, r) | ||||||
| 			s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) | 			s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		comps := make([]string, len(pathComponents)) | ||||||
|  | 		copy(comps, pathComponents) | ||||||
|  | 
 | ||||||
| 		if idx > 0 { | 		if idx > 0 { | ||||||
| 			components[l-1], verb = lastComponent[:idx], lastComponent[idx+1:] | 			comps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:] | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode) | 		pathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			var mse MalformedSequenceError | 			var mse MalformedSequenceError | ||||||
| 			if ok := errors.As(err, &mse); ok { | 			if ok := errors.As(err, &mse); ok { | ||||||
|  | @ -301,14 +389,33 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// lookup other methods to handle fallback from GET to POST and | 	// if no handler has found for the request, lookup for other methods | ||||||
| 	// to determine if it is NotImplemented or NotFound. | 	// to handle POST -> GET fallback if the request is subject to path | ||||||
|  | 	// length fallback. | ||||||
|  | 	// Note we are not eagerly checking the request here as we want to return the | ||||||
|  | 	// right HTTP status code, and we need to process the fallback candidates in | ||||||
|  | 	// order to do that. | ||||||
| 	for m, handlers := range s.handlers { | 	for m, handlers := range s.handlers { | ||||||
| 		if m == r.Method { | 		if m == r.Method { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		for _, h := range handlers { | 		for _, h := range handlers { | ||||||
| 			pathParams, err := h.pat.MatchAndEscape(components, verb, s.unescapingMode) | 			var verb string | ||||||
|  | 			patVerb := h.pat.Verb() | ||||||
|  | 
 | ||||||
|  | 			idx := -1 | ||||||
|  | 			if patVerb != "" && strings.HasSuffix(lastPathComponent, ":"+patVerb) { | ||||||
|  | 				idx = len(lastPathComponent) - len(patVerb) - 1 | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			comps := make([]string, len(pathComponents)) | ||||||
|  | 			copy(comps, pathComponents) | ||||||
|  | 
 | ||||||
|  | 			if idx > 0 { | ||||||
|  | 				comps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:] | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			pathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				var mse MalformedSequenceError | 				var mse MalformedSequenceError | ||||||
| 				if ok := errors.As(err, &mse); ok { | 				if ok := errors.As(err, &mse); ok { | ||||||
|  | @ -320,8 +427,11 @@ func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 				} | 				} | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
| 			// X-HTTP-Method-Override is optional. Always allow fallback to POST. | 			// X-HTTP-Method-Override is optional. Always allow fallback to POST. | ||||||
| 			if s.isPathLengthFallback(r) { | 			// Also, only consider POST -> GET fallbacks, and avoid falling back to | ||||||
|  | 			// potentially dangerous operations like DELETE. | ||||||
|  | 			if s.isPathLengthFallback(r) && m == http.MethodGet { | ||||||
| 				if err := r.ParseForm(); err != nil { | 				if err := r.ParseForm(); err != nil { | ||||||
| 					_, outboundMarshaler := MarshalerForRequest(s, r) | 					_, outboundMarshaler := MarshalerForRequest(s, r) | ||||||
| 					sterr := status.Error(codes.InvalidArgument, err.Error()) | 					sterr := status.Error(codes.InvalidArgument, err.Error()) | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -15,8 +15,6 @@ var ( | ||||||
| 	ErrNotMatch = errors.New("not match to the path pattern") | 	ErrNotMatch = errors.New("not match to the path pattern") | ||||||
| 	// ErrInvalidPattern indicates that the given definition of Pattern is not valid. | 	// ErrInvalidPattern indicates that the given definition of Pattern is not valid. | ||||||
| 	ErrInvalidPattern = errors.New("invalid pattern") | 	ErrInvalidPattern = errors.New("invalid pattern") | ||||||
| 	// ErrMalformedSequence indicates that an escape sequence was malformed. |  | ||||||
| 	ErrMalformedSequence = errors.New("malformed escape sequence") |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type MalformedSequenceError string | type MalformedSequenceError string | ||||||
|  |  | ||||||
							
								
								
									
										69
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										69
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,7 +1,6 @@ | ||||||
| package runtime | package runtime | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"encoding/base64" |  | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  | @ -11,19 +10,21 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities" | 	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities" | ||||||
| 	"google.golang.org/genproto/protobuf/field_mask" |  | ||||||
| 	"google.golang.org/grpc/grpclog" | 	"google.golang.org/grpc/grpclog" | ||||||
|  | 	"google.golang.org/protobuf/encoding/protojson" | ||||||
| 	"google.golang.org/protobuf/proto" | 	"google.golang.org/protobuf/proto" | ||||||
| 	"google.golang.org/protobuf/reflect/protoreflect" | 	"google.golang.org/protobuf/reflect/protoreflect" | ||||||
| 	"google.golang.org/protobuf/reflect/protoregistry" | 	"google.golang.org/protobuf/reflect/protoregistry" | ||||||
| 	"google.golang.org/protobuf/types/known/durationpb" | 	"google.golang.org/protobuf/types/known/durationpb" | ||||||
|  | 	field_mask "google.golang.org/protobuf/types/known/fieldmaskpb" | ||||||
|  | 	"google.golang.org/protobuf/types/known/structpb" | ||||||
| 	"google.golang.org/protobuf/types/known/timestamppb" | 	"google.golang.org/protobuf/types/known/timestamppb" | ||||||
| 	"google.golang.org/protobuf/types/known/wrapperspb" | 	"google.golang.org/protobuf/types/known/wrapperspb" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var valuesKeyRegexp = regexp.MustCompile(`^(.*)\[(.*)\]$`) | var valuesKeyRegexp = regexp.MustCompile(`^(.*)\[(.*)\]$`) | ||||||
| 
 | 
 | ||||||
| var currentQueryParser QueryParameterParser = &defaultQueryParser{} | var currentQueryParser QueryParameterParser = &DefaultQueryParser{} | ||||||
| 
 | 
 | ||||||
| // QueryParameterParser defines interface for all query parameter parsers | // QueryParameterParser defines interface for all query parameter parsers | ||||||
| type QueryParameterParser interface { | type QueryParameterParser interface { | ||||||
|  | @ -36,14 +37,17 @@ func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utili | ||||||
| 	return currentQueryParser.Parse(msg, values, filter) | 	return currentQueryParser.Parse(msg, values, filter) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type defaultQueryParser struct{} | // DefaultQueryParser is a QueryParameterParser which implements the default | ||||||
|  | // query parameters parsing behavior. | ||||||
|  | // | ||||||
|  | // See https://github.com/grpc-ecosystem/grpc-gateway/issues/2632 for more context. | ||||||
|  | type DefaultQueryParser struct{} | ||||||
| 
 | 
 | ||||||
| // Parse populates "values" into "msg". | // Parse populates "values" into "msg". | ||||||
| // A value is ignored if its key starts with one of the elements in "filter". | // A value is ignored if its key starts with one of the elements in "filter". | ||||||
| func (*defaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { | func (*DefaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { | ||||||
| 	for key, values := range values { | 	for key, values := range values { | ||||||
| 		match := valuesKeyRegexp.FindStringSubmatch(key) | 		if match := valuesKeyRegexp.FindStringSubmatch(key); len(match) == 3 { | ||||||
| 		if len(match) == 3 { |  | ||||||
| 			key = match[1] | 			key = match[1] | ||||||
| 			values = append([]string{match[2]}, values...) | 			values = append([]string{match[2]}, values...) | ||||||
| 		} | 		} | ||||||
|  | @ -175,10 +179,10 @@ func parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (pro | ||||||
| 		return protoreflect.ValueOfBool(v), nil | 		return protoreflect.ValueOfBool(v), nil | ||||||
| 	case protoreflect.EnumKind: | 	case protoreflect.EnumKind: | ||||||
| 		enum, err := protoregistry.GlobalTypes.FindEnumByName(fieldDescriptor.Enum().FullName()) | 		enum, err := protoregistry.GlobalTypes.FindEnumByName(fieldDescriptor.Enum().FullName()) | ||||||
| 		switch { | 		if err != nil { | ||||||
| 		case errors.Is(err, protoregistry.NotFound): | 			if errors.Is(err, protoregistry.NotFound) { | ||||||
| 			return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", fieldDescriptor.Enum().FullName()) | 				return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", fieldDescriptor.Enum().FullName()) | ||||||
| 		case err != nil: | 			} | ||||||
| 			return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", err) | 			return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", err) | ||||||
| 		} | 		} | ||||||
| 		// Look for enum by name | 		// Look for enum by name | ||||||
|  | @ -189,8 +193,7 @@ func parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (pro | ||||||
| 				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) | 				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) | ||||||
| 			} | 			} | ||||||
| 			// Look for enum by number | 			// Look for enum by number | ||||||
| 			v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i)) | 			if v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i)); v == nil { | ||||||
| 			if v == nil { |  | ||||||
| 				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) | 				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -234,7 +237,7 @@ func parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (pro | ||||||
| 	case protoreflect.StringKind: | 	case protoreflect.StringKind: | ||||||
| 		return protoreflect.ValueOfString(value), nil | 		return protoreflect.ValueOfString(value), nil | ||||||
| 	case protoreflect.BytesKind: | 	case protoreflect.BytesKind: | ||||||
| 		v, err := base64.URLEncoding.DecodeString(value) | 		v, err := Bytes(value) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
|  | @ -250,18 +253,12 @@ func parseMessage(msgDescriptor protoreflect.MessageDescriptor, value string) (p | ||||||
| 	var msg proto.Message | 	var msg proto.Message | ||||||
| 	switch msgDescriptor.FullName() { | 	switch msgDescriptor.FullName() { | ||||||
| 	case "google.protobuf.Timestamp": | 	case "google.protobuf.Timestamp": | ||||||
| 		if value == "null" { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		t, err := time.Parse(time.RFC3339Nano, value) | 		t, err := time.Parse(time.RFC3339Nano, value) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = timestamppb.New(t) | 		msg = timestamppb.New(t) | ||||||
| 	case "google.protobuf.Duration": | 	case "google.protobuf.Duration": | ||||||
| 		if value == "null" { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		d, err := time.ParseDuration(value) | 		d, err := time.ParseDuration(value) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
|  | @ -272,55 +269,67 @@ func parseMessage(msgDescriptor protoreflect.MessageDescriptor, value string) (p | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.DoubleValue{Value: v} | 		msg = wrapperspb.Double(v) | ||||||
| 	case "google.protobuf.FloatValue": | 	case "google.protobuf.FloatValue": | ||||||
| 		v, err := strconv.ParseFloat(value, 32) | 		v, err := strconv.ParseFloat(value, 32) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.FloatValue{Value: float32(v)} | 		msg = wrapperspb.Float(float32(v)) | ||||||
| 	case "google.protobuf.Int64Value": | 	case "google.protobuf.Int64Value": | ||||||
| 		v, err := strconv.ParseInt(value, 10, 64) | 		v, err := strconv.ParseInt(value, 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.Int64Value{Value: v} | 		msg = wrapperspb.Int64(v) | ||||||
| 	case "google.protobuf.Int32Value": | 	case "google.protobuf.Int32Value": | ||||||
| 		v, err := strconv.ParseInt(value, 10, 32) | 		v, err := strconv.ParseInt(value, 10, 32) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.Int32Value{Value: int32(v)} | 		msg = wrapperspb.Int32(int32(v)) | ||||||
| 	case "google.protobuf.UInt64Value": | 	case "google.protobuf.UInt64Value": | ||||||
| 		v, err := strconv.ParseUint(value, 10, 64) | 		v, err := strconv.ParseUint(value, 10, 64) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.UInt64Value{Value: v} | 		msg = wrapperspb.UInt64(v) | ||||||
| 	case "google.protobuf.UInt32Value": | 	case "google.protobuf.UInt32Value": | ||||||
| 		v, err := strconv.ParseUint(value, 10, 32) | 		v, err := strconv.ParseUint(value, 10, 32) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.UInt32Value{Value: uint32(v)} | 		msg = wrapperspb.UInt32(uint32(v)) | ||||||
| 	case "google.protobuf.BoolValue": | 	case "google.protobuf.BoolValue": | ||||||
| 		v, err := strconv.ParseBool(value) | 		v, err := strconv.ParseBool(value) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.BoolValue{Value: v} | 		msg = wrapperspb.Bool(v) | ||||||
| 	case "google.protobuf.StringValue": | 	case "google.protobuf.StringValue": | ||||||
| 		msg = &wrapperspb.StringValue{Value: value} | 		msg = wrapperspb.String(value) | ||||||
| 	case "google.protobuf.BytesValue": | 	case "google.protobuf.BytesValue": | ||||||
| 		v, err := base64.URLEncoding.DecodeString(value) | 		v, err := Bytes(value) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return protoreflect.Value{}, err | 			return protoreflect.Value{}, err | ||||||
| 		} | 		} | ||||||
| 		msg = &wrapperspb.BytesValue{Value: v} | 		msg = wrapperspb.Bytes(v) | ||||||
| 	case "google.protobuf.FieldMask": | 	case "google.protobuf.FieldMask": | ||||||
| 		fm := &field_mask.FieldMask{} | 		fm := &field_mask.FieldMask{} | ||||||
| 		fm.Paths = append(fm.Paths, strings.Split(value, ",")...) | 		fm.Paths = append(fm.Paths, strings.Split(value, ",")...) | ||||||
| 		msg = fm | 		msg = fm | ||||||
|  | 	case "google.protobuf.Value": | ||||||
|  | 		var v structpb.Value | ||||||
|  | 		if err := protojson.Unmarshal([]byte(value), &v); err != nil { | ||||||
|  | 			return protoreflect.Value{}, err | ||||||
|  | 		} | ||||||
|  | 		msg = &v | ||||||
|  | 	case "google.protobuf.Struct": | ||||||
|  | 		var v structpb.Struct | ||||||
|  | 		if err := protojson.Unmarshal([]byte(value), &v); err != nil { | ||||||
|  | 			return protoreflect.Value{}, err | ||||||
|  | 		} | ||||||
|  | 		msg = &v | ||||||
| 	default: | 	default: | ||||||
| 		return protoreflect.Value{}, fmt.Errorf("unsupported message type: %q", string(msgDescriptor.FullName())) | 		return protoreflect.Value{}, fmt.Errorf("unsupported message type: %q", string(msgDescriptor.FullName())) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -8,6 +8,7 @@ go_library( | ||||||
|         "doc.go", |         "doc.go", | ||||||
|         "pattern.go", |         "pattern.go", | ||||||
|         "readerfactory.go", |         "readerfactory.go", | ||||||
|  |         "string_array_flag.go", | ||||||
|         "trie.go", |         "trie.go", | ||||||
|     ], |     ], | ||||||
|     importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", |     importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", | ||||||
|  | @ -16,7 +17,10 @@ go_library( | ||||||
| go_test( | go_test( | ||||||
|     name = "utilities_test", |     name = "utilities_test", | ||||||
|     size = "small", |     size = "small", | ||||||
|     srcs = ["trie_test.go"], |     srcs = [ | ||||||
|  |         "string_array_flag_test.go", | ||||||
|  |         "trie_test.go", | ||||||
|  |     ], | ||||||
|     deps = [":utilities"], |     deps = [":utilities"], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -3,13 +3,12 @@ package utilities | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"io" | 	"io" | ||||||
| 	"io/ioutil" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins | // IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins | ||||||
| // at the start of the stream | // at the start of the stream | ||||||
| func IOReaderFactory(r io.Reader) (func() io.Reader, error) { | func IOReaderFactory(r io.Reader) (func() io.Reader, error) { | ||||||
| 	b, err := ioutil.ReadAll(r) | 	b, err := io.ReadAll(r) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | package utilities | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // flagInterface is an cut down interface to `flag` | ||||||
|  | type flagInterface interface { | ||||||
|  | 	Var(value flag.Value, name string, usage string) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringArrayFlag defines a flag with the specified name and usage string. | ||||||
|  | // The return value is the address of a `StringArrayFlags` variable that stores the repeated values of the flag. | ||||||
|  | func StringArrayFlag(f flagInterface, name string, usage string) *StringArrayFlags { | ||||||
|  | 	value := &StringArrayFlags{} | ||||||
|  | 	f.Var(value, name, usage) | ||||||
|  | 	return value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringArrayFlags is a wrapper of `[]string` to provider an interface for `flag.Var` | ||||||
|  | type StringArrayFlags []string | ||||||
|  | 
 | ||||||
|  | // String returns a string representation of `StringArrayFlags` | ||||||
|  | func (i *StringArrayFlags) String() string { | ||||||
|  | 	return strings.Join(*i, ",") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set appends a value to `StringArrayFlags` | ||||||
|  | func (i *StringArrayFlags) Set(value string) error { | ||||||
|  | 	*i = append(*i, value) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -40,7 +40,7 @@ func NewDoubleArray(seqs [][]string) *DoubleArray { | ||||||
| func registerTokens(da *DoubleArray, seqs [][]string) [][]int { | func registerTokens(da *DoubleArray, seqs [][]string) [][]int { | ||||||
| 	var result [][]int | 	var result [][]int | ||||||
| 	for _, seq := range seqs { | 	for _, seq := range seqs { | ||||||
| 		var encoded []int | 		encoded := make([]int, 0, len(seq)) | ||||||
| 		for _, token := range seq { | 		for _, token := range seq { | ||||||
| 			if _, ok := da.Encoding[token]; !ok { | 			if _, ok := da.Encoding[token]; !ok { | ||||||
| 				da.Encoding[token] = len(da.Encoding) | 				da.Encoding[token] = len(da.Encoding) | ||||||
|  |  | ||||||
							
								
								
									
										84
									
								
								vendor/go.opentelemetry.io/otel/.golangci.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										84
									
								
								vendor/go.opentelemetry.io/otel/.golangci.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -61,28 +61,68 @@ issues: | ||||||
| 
 | 
 | ||||||
| linters-settings: | linters-settings: | ||||||
|   depguard: |   depguard: | ||||||
|     # Check the list against standard lib. |     rules: | ||||||
|     # Default: false |       non-tests: | ||||||
|     include-go-root: true |         files: | ||||||
|     # A list of packages for the list type specified. |           - "!$test" | ||||||
|     # Default: [] |           - "!**/*test/*.go" | ||||||
|     packages: |           - "!**/internal/matchers/*.go" | ||||||
|       - "crypto/md5" |         deny: | ||||||
|       - "crypto/sha1" |           - pkg: "testing" | ||||||
|       - "crypto/**/pkix" |           - pkg: "github.com/stretchr/testify" | ||||||
|     ignore-file-rules: |           - pkg: "crypto/md5" | ||||||
|       - "**/*_test.go" |           - pkg: "crypto/sha1" | ||||||
|     additional-guards: |           - pkg: "crypto/**/pkix" | ||||||
|       # Do not allow testing packages in non-test files. |       otlp-internal: | ||||||
|       - list-type: denylist |         files: | ||||||
|         include-go-root: true |           - "!**/exporters/otlp/internal/**/*.go" | ||||||
|         packages: |           # TODO: remove the following when otlpmetric/internal is removed. | ||||||
|           - testing |           - "!**/exporters/otlp/otlpmetric/internal/oconf/envconfig.go" | ||||||
|           - github.com/stretchr/testify |           - "!**/exporters/otlp/otlpmetric/internal/oconf/options.go" | ||||||
|         ignore-file-rules: |           - "!**/exporters/otlp/otlpmetric/internal/oconf/options_test.go" | ||||||
|           - "**/*_test.go" |           - "!**/exporters/otlp/otlpmetric/internal/otest/client_test.go" | ||||||
|           - "**/*test/*.go" |         deny: | ||||||
|           - "**/internal/matchers/*.go" |           - pkg: "go.opentelemetry.io/otel/exporters/otlp/internal" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|  |       otlptrace-internal: | ||||||
|  |         files: | ||||||
|  |           - "!**/exporters/otlp/otlptrace/*.go" | ||||||
|  |           - "!**/exporters/otlp/otlptrace/internal/**.go" | ||||||
|  |         deny: | ||||||
|  |           - pkg: "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|  |       otlpmetric-internal: | ||||||
|  |         files: | ||||||
|  |           - "!**/exporters/otlp/otlpmetric/internal/*.go" | ||||||
|  |           - "!**/exporters/otlp/otlpmetric/internal/**/*.go" | ||||||
|  |         deny: | ||||||
|  |           - pkg: "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|  |       otel-internal: | ||||||
|  |         files: | ||||||
|  |           - "**/sdk/*.go" | ||||||
|  |           - "**/sdk/**/*.go" | ||||||
|  |           - "**/exporters/*.go" | ||||||
|  |           - "**/exporters/**/*.go" | ||||||
|  |           - "**/schema/*.go" | ||||||
|  |           - "**/schema/**/*.go" | ||||||
|  |           - "**/metric/*.go" | ||||||
|  |           - "**/metric/**/*.go" | ||||||
|  |           - "**/bridge/*.go" | ||||||
|  |           - "**/bridge/**/*.go" | ||||||
|  |           - "**/example/*.go" | ||||||
|  |           - "**/example/**/*.go" | ||||||
|  |           - "**/trace/*.go" | ||||||
|  |           - "**/trace/**/*.go" | ||||||
|  |         deny: | ||||||
|  |           - pkg: "go.opentelemetry.io/otel/internal$" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|  |           - pkg: "go.opentelemetry.io/otel/internal/attribute" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|  |           - pkg: "go.opentelemetry.io/otel/internal/internaltest" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|  |           - pkg: "go.opentelemetry.io/otel/internal/matchers" | ||||||
|  |             desc: Do not use cross-module internal packages. | ||||||
|   godot: |   godot: | ||||||
|     exclude: |     exclude: | ||||||
|       # Exclude links. |       # Exclude links. | ||||||
|  |  | ||||||
							
								
								
									
										102
									
								
								vendor/go.opentelemetry.io/otel/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								vendor/go.opentelemetry.io/otel/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -8,6 +8,99 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm | ||||||
| 
 | 
 | ||||||
| ## [Unreleased] | ## [Unreleased] | ||||||
| 
 | 
 | ||||||
|  | ## [1.17.0/0.40.0/0.0.5] 2023-08-28 | ||||||
|  | 
 | ||||||
|  | ### Added | ||||||
|  | 
 | ||||||
|  | - Export the `ManualReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244) | ||||||
|  | - Export the `PeriodicReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244) | ||||||
|  | - Add support for exponential histogram aggregations. | ||||||
|  |   A histogram can be configured as an exponential histogram using a view with `"go.opentelemetry.io/otel/sdk/metric".ExponentialHistogram` as the aggregation. (#4245) | ||||||
|  | - Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4272) | ||||||
|  | - Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4272) | ||||||
|  | - The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable. (#4287) | ||||||
|  | - Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#4306) | ||||||
|  | - Add info and debug logging to the metric SDK in `go.opentelemetry.io/otel/sdk/metric`. (#4315) | ||||||
|  | - The `go.opentelemetry.io/otel/semconv/v1.21.0` package. | ||||||
|  |   The package contains semantic conventions from the `v1.21.0` version of the OpenTelemetry Semantic Conventions. (#4362) | ||||||
|  | - Accept 201 to 299 HTTP status as success in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4365) | ||||||
|  | - Document the `Temporality` and `Aggregation` methods of the `"go.opentelemetry.io/otel/sdk/metric".Exporter"` need to be concurrent safe. (#4381) | ||||||
|  | - Expand the set of units supported by the Prometheus exporter, and don't add unit suffixes if they are already present in `go.opentelemetry.op/otel/exporters/prometheus` (#4374) | ||||||
|  | - Move the `Aggregation` interface and its implementations from `go.opentelemetry.io/otel/sdk/metric/aggregation` to `go.opentelemetry.io/otel/sdk/metric`. (#4435) | ||||||
|  | - The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` environment variable. (#4437) | ||||||
|  | - Add the `NewAllowKeysFilter` and `NewDenyKeysFilter` functions to `go.opentelemetry.io/otel/attribute` to allow convenient creation of allow-keys and deny-keys filters. (#4444) | ||||||
|  | - Support Go 1.21. (#4463) | ||||||
|  | 
 | ||||||
|  | ### Changed | ||||||
|  | 
 | ||||||
|  | - Starting from `v1.21.0` of semantic conventions, `go.opentelemetry.io/otel/semconv/{version}/httpconv` and `go.opentelemetry.io/otel/semconv/{version}/netconv` packages will no longer be published. (#4145) | ||||||
|  | - Log duplicate instrument conflict at a warning level instead of info in `go.opentelemetry.io/otel/sdk/metric`. (#4202) | ||||||
|  | - Return an error on the creation of new instruments in `go.opentelemetry.io/otel/sdk/metric` if their name doesn't pass regexp validation. (#4210) | ||||||
|  | - `NewManualReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*ManualReader` instead of `Reader`. (#4244) | ||||||
|  | - `NewPeriodicReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*PeriodicReader` instead of `Reader`. (#4244) | ||||||
|  | - Count the Collect time in the `PeriodicReader` timeout in `go.opentelemetry.io/otel/sdk/metric`. (#4221) | ||||||
|  | - The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` returns `*Exporter` instead of `"go.opentelemetry.io/otel/sdk/metric".Exporter`. (#4272) | ||||||
|  | - The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` returns `*Exporter` instead of `"go.opentelemetry.io/otel/sdk/metric".Exporter`. (#4272) | ||||||
|  | - If an attribute set is omitted from an async callback, the previous value will no longer be exported in `go.opentelemetry.io/otel/sdk/metric`. (#4290) | ||||||
|  | - If an attribute set is observed multiple times in an async callback in `go.opentelemetry.io/otel/sdk/metric`, the values will be summed instead of the last observation winning. (#4289) | ||||||
|  | - Allow the explicit bucket histogram aggregation to be used for the up-down counter, observable counter, observable up-down counter, and observable gauge in the `go.opentelemetry.io/otel/sdk/metric` package. (#4332) | ||||||
|  | - Restrict `Meter`s in `go.opentelemetry.io/otel/sdk/metric` to only register and collect instruments it created. (#4333) | ||||||
|  | - `PeriodicReader.Shutdown` and `PeriodicReader.ForceFlush` in `go.opentelemetry.io/otel/sdk/metric` now apply the periodic reader's timeout to the operation if the user provided context does not contain a deadline. (#4356, #4377) | ||||||
|  | - Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.21.0`. (#4408) | ||||||
|  | - Increase instrument name maximum length from 63 to 255 characters in `go.opentelemetry.io/otel/sdk/metric`. (#4434) | ||||||
|  | - Add `go.opentelemetry.op/otel/sdk/metric.WithProducer` as an `Option` for `"go.opentelemetry.io/otel/sdk/metric".NewManualReader` and `"go.opentelemetry.io/otel/sdk/metric".NewPeriodicReader`. (#4346) | ||||||
|  | 
 | ||||||
|  | ### Removed | ||||||
|  | 
 | ||||||
|  | - Remove `Reader.RegisterProducer` in `go.opentelemetry.io/otel/metric`. | ||||||
|  |   Use the added `WithProducer` option instead. (#4346) | ||||||
|  | - Remove `Reader.ForceFlush` in `go.opentelemetry.io/otel/metric`. | ||||||
|  |   Notice that `PeriodicReader.ForceFlush` is still available. (#4375) | ||||||
|  | 
 | ||||||
|  | ### Fixed | ||||||
|  | 
 | ||||||
|  | - Correctly format log messages from the `go.opentelemetry.io/otel/exporters/zipkin` exporter. (#4143) | ||||||
|  | - Log an error for calls to `NewView` in `go.opentelemetry.io/otel/sdk/metric` that have empty criteria. (#4307) | ||||||
|  | - Fix `"go.opentelemetry.io/otel/sdk/resource".WithHostID()` to not set an empty `host.id`. (#4317) | ||||||
|  | - Use the instrument identifying fields to cache aggregators and determine duplicate instrument registrations in `go.opentelemetry.io/otel/sdk/metric`. (#4337) | ||||||
|  | - Detect duplicate instruments for case-insensitive names in `go.opentelemetry.io/otel/sdk/metric`. (#4338) | ||||||
|  | - The `ManualReader` will not panic if `AggregationSelector` returns `nil` in `go.opentelemetry.io/otel/sdk/metric`. (#4350) | ||||||
|  | - If a `Reader`'s `AggregationSelector` returns `nil` or `DefaultAggregation` the pipeline will use the default aggregation. (#4350) | ||||||
|  | - Log a suggested view that fixes instrument conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4349) | ||||||
|  | - Fix possible panic, deadlock and race condition in batch span processor in `go.opentelemetry.io/otel/sdk/trace`. (#4353) | ||||||
|  | - Improve context cancellation handling in batch span processor's `ForceFlush` in  `go.opentelemetry.io/otel/sdk/trace`. (#4369) | ||||||
|  | - Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` using gotmpl. (#4397, #3846) | ||||||
|  | - Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4404, #3846) | ||||||
|  | - Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4407, #3846) | ||||||
|  | - Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4400, #3846) | ||||||
|  | - Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4401, #3846) | ||||||
|  | - Do not block the metric SDK when OTLP metric exports are blocked in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#3925, #4395) | ||||||
|  | - Do not append `_total` if the counter already has that suffix for the Prometheus exproter in `go.opentelemetry.io/otel/exporter/prometheus`. (#4373) | ||||||
|  | - Fix resource detection data race in `go.opentelemetry.io/otel/sdk/resource`. (#4409) | ||||||
|  | - Use the first-seen instrument name during instrument name conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4428) | ||||||
|  | 
 | ||||||
|  | ### Deprecated | ||||||
|  | 
 | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/jaeger` package is deprecated. | ||||||
|  |   OpenTelemetry dropped support for Jaeger exporter in July 2023. | ||||||
|  |   Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` | ||||||
|  |   or `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` instead. (#4423) | ||||||
|  | - The `go.opentelemetry.io/otel/example/jaeger` package is deprecated. (#4423) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` package is deprecated. (#4420) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/oconf` package is deprecated. (#4420) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otest` package is deprecated. (#4420) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/transform` package is deprecated. (#4420) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/internal` package is deprecated. (#4421) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/internal/envconfig` package is deprecated. (#4421) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/internal/retry` package is deprecated. (#4421) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` package is deprecated. (#4425) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/envconfig` package is deprecated. (#4425) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig` package is deprecated. (#4425) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlptracetest` package is deprecated. (#4425) | ||||||
|  | - The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry` package is deprecated. (#4425) | ||||||
|  | - The `go.opentelemetry.io/otel/sdk/metric/aggregation` package is deprecated. | ||||||
|  |   Use the aggregation types added to `go.opentelemetry.io/otel/sdk/metric` instead. (#4435) | ||||||
|  | 
 | ||||||
| ## [1.16.0/0.39.0] 2023-05-18 | ## [1.16.0/0.39.0] 2023-05-18 | ||||||
| 
 | 
 | ||||||
| This release contains the first stable release of the OpenTelemetry Go [metric API]. | This release contains the first stable release of the OpenTelemetry Go [metric API]. | ||||||
|  | @ -20,10 +113,14 @@ See our [versioning policy](VERSIONING.md) for more information about these stab | ||||||
|   The package contains semantic conventions from the `v1.19.0` version of the OpenTelemetry specification. (#3848) |   The package contains semantic conventions from the `v1.19.0` version of the OpenTelemetry specification. (#3848) | ||||||
| - The `go.opentelemetry.io/otel/semconv/v1.20.0` package. | - The `go.opentelemetry.io/otel/semconv/v1.20.0` package. | ||||||
|   The package contains semantic conventions from the `v1.20.0` version of the OpenTelemetry specification. (#4078) |   The package contains semantic conventions from the `v1.20.0` version of the OpenTelemetry specification. (#4078) | ||||||
|  | - The Exponential Histogram data types in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#4165) | ||||||
|  | - OTLP metrics exporter now supports the Exponential Histogram Data Type. (#4222) | ||||||
|  | - Fix serialization of `time.Time` zero values in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` packages. (#4271) | ||||||
| 
 | 
 | ||||||
| ### Changed | ### Changed | ||||||
| 
 | 
 | ||||||
| - Use `strings.Cut()` instead of `string.SplitN()` for better readability and memory use. (#4049) | - Use `strings.Cut()` instead of `string.SplitN()` for better readability and memory use. (#4049) | ||||||
|  | - `MeterProvider` returns noop meters once it has been shutdown. (#4154) | ||||||
| 
 | 
 | ||||||
| ### Removed | ### Removed | ||||||
| 
 | 
 | ||||||
|  | @ -188,6 +285,8 @@ This release drops the compatibility guarantee of [Go 1.18]. | ||||||
| 
 | 
 | ||||||
| - Handle empty environment variable as it they were not set. (#3764) | - Handle empty environment variable as it they were not set. (#3764) | ||||||
| - Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823) | - Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823) | ||||||
|  | - Fix race conditions in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic. (#3899) | ||||||
|  | - Fix sending nil `scopeInfo` to metrics channel in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic in `github.com/prometheus/client_golang/prometheus`. (#3899) | ||||||
| 
 | 
 | ||||||
| ### Deprecated | ### Deprecated | ||||||
| 
 | 
 | ||||||
|  | @ -2492,7 +2591,8 @@ It contains api and sdk for trace and meter. | ||||||
| - CircleCI build CI manifest files. | - CircleCI build CI manifest files. | ||||||
| - CODEOWNERS file to track owners of this project. | - CODEOWNERS file to track owners of this project. | ||||||
| 
 | 
 | ||||||
| [Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.16.0...HEAD | [Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.17.0...HEAD | ||||||
|  | [1.17.0/0.40.0/0.0.5]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.17.0 | ||||||
| [1.16.0/0.39.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0 | [1.16.0/0.39.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0 | ||||||
| [1.16.0-rc.1/0.39.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0-rc.1 | [1.16.0-rc.1/0.39.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0-rc.1 | ||||||
| [1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1 | [1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/go.opentelemetry.io/otel/CODEOWNERS
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/go.opentelemetry.io/otel/CODEOWNERS
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -14,4 +14,4 @@ | ||||||
| 
 | 
 | ||||||
| * @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu | * @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu | ||||||
| 
 | 
 | ||||||
| CODEOWNERS @MrAlias @Aneurysm9 @MadVikingGod | CODEOWNERS @MrAlias @MadVikingGod @pellared | ||||||
							
								
								
									
										90
									
								
								vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										90
									
								
								vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -179,23 +179,23 @@ For a deeper discussion, see | ||||||
| 
 | 
 | ||||||
| ## Documentation | ## Documentation | ||||||
| 
 | 
 | ||||||
| Each non-example Go Module should have its own `README.md` containing: | Each (non-internal, non-test) package must be documented using | ||||||
|  | [Go Doc Comments](https://go.dev/doc/comment), | ||||||
|  | preferably in a `doc.go` file. | ||||||
| 
 | 
 | ||||||
| - A pkg.go.dev badge which can be generated [here](https://pkg.go.dev/badge/). | Prefer using [Examples](https://pkg.go.dev/testing#hdr-Examples) | ||||||
| - Brief description. | instead of putting code snippets in Go doc comments. | ||||||
| - Installation instructions (and requirements if applicable). | In some cases, you can even create [Testable Examples](https://go.dev/blog/examples). | ||||||
| - Hyperlink to an example. Depending on the component the example can be: |  | ||||||
|   - An `example_test.go` like [here](exporters/stdout/stdouttrace/example_test.go). |  | ||||||
|   - A sample Go application with its own `README.md`, like [here](example/zipkin). |  | ||||||
| - Additional documentation sections such us: |  | ||||||
|   - Configuration, |  | ||||||
|   - Contributing, |  | ||||||
|   - References. |  | ||||||
| 
 | 
 | ||||||
| [Here](exporters/jaeger/README.md) is an example of a concise `README.md`. | You can install and run a "local Go Doc site" in the following way: | ||||||
| 
 | 
 | ||||||
| Moreover, it should be possible to navigate to any `README.md` from the |   ```sh | ||||||
| root `README.md`. |   go install golang.org/x/pkgsite/cmd/pkgsite@latest | ||||||
|  |   pkgsite | ||||||
|  |   ``` | ||||||
|  | 
 | ||||||
|  | [`go.opentelemetry.io/otel/metric`](https://pkg.go.dev/go.opentelemetry.io/otel/metric) | ||||||
|  | is an example of a very well-documented package. | ||||||
| 
 | 
 | ||||||
| ## Style Guide | ## Style Guide | ||||||
| 
 | 
 | ||||||
|  | @ -475,8 +475,33 @@ documentation are allowed to be extended with additional methods. | ||||||
| 
 | 
 | ||||||
| > Warning: methods may be added to this interface in minor releases. | > Warning: methods may be added to this interface in minor releases. | ||||||
| 
 | 
 | ||||||
|  | These interfaces are defined by the OpenTelemetry specification and will be | ||||||
|  | updated as the specification evolves. | ||||||
|  | 
 | ||||||
| Otherwise, stable interfaces MUST NOT be modified. | Otherwise, stable interfaces MUST NOT be modified. | ||||||
| 
 | 
 | ||||||
|  | #### How to Change Specification Interfaces | ||||||
|  | 
 | ||||||
|  | When an API change must be made, we will update the SDK with the new method one | ||||||
|  | release before the API change. This will allow the SDK one version before the | ||||||
|  | API change to work seamlessly with the new API. | ||||||
|  | 
 | ||||||
|  | If an incompatible version of the SDK is used with the new API the application | ||||||
|  | will fail to compile. | ||||||
|  | 
 | ||||||
|  | #### How Not to Change Specification Interfaces | ||||||
|  | 
 | ||||||
|  | We have explored using a v2 of the API to change interfaces and found that there | ||||||
|  | was no way to introduce a v2 and have it work seamlessly with the v1 of the API. | ||||||
|  | Problems happened with libraries that upgraded to v2 when an application did not, | ||||||
|  | and would not produce any telemetry. | ||||||
|  | 
 | ||||||
|  | More detail of the approaches considered and their limitations can be found in | ||||||
|  | the [Use a V2 API to evolve interfaces](https://github.com/open-telemetry/opentelemetry-go/issues/3920) | ||||||
|  | issue. | ||||||
|  | 
 | ||||||
|  | #### How to Change Other Interfaces | ||||||
|  | 
 | ||||||
| If new functionality is needed for an interface that cannot be changed it MUST | If new functionality is needed for an interface that cannot be changed it MUST | ||||||
| be added by including an additional interface. That added interface can be a | be added by including an additional interface. That added interface can be a | ||||||
| simple interface for the specific functionality that you want to add or it can | simple interface for the specific functionality that you want to add or it can | ||||||
|  | @ -531,6 +556,37 @@ functionality should be added, each one will need their own super-set | ||||||
| interfaces and will duplicate the pattern. For this reason, the simple targeted | interfaces and will duplicate the pattern. For this reason, the simple targeted | ||||||
| interface that defines the specific functionality should be preferred. | interface that defines the specific functionality should be preferred. | ||||||
| 
 | 
 | ||||||
|  | ### Testing | ||||||
|  | 
 | ||||||
|  | The tests should never leak goroutines. | ||||||
|  | 
 | ||||||
|  | Use the term `ConcurrentSafe` in the test name when it aims to verify the | ||||||
|  | absence of race conditions. | ||||||
|  | 
 | ||||||
|  | ### Internal packages | ||||||
|  | 
 | ||||||
|  | The use of internal packages should be scoped to a single module. A sub-module | ||||||
|  | should never import from a parent internal package. This creates a coupling | ||||||
|  | between the two modules where a user can upgrade the parent without the child | ||||||
|  | and if the internal package API has changed it will fail to upgrade[^3]. | ||||||
|  | 
 | ||||||
|  | There are two known exceptions to this rule: | ||||||
|  | 
 | ||||||
|  | - `go.opentelemetry.io/otel/internal/global` | ||||||
|  |   - This package manages global state for all of opentelemetry-go. It needs to | ||||||
|  |   be a single package in order to ensure the uniqueness of the global state. | ||||||
|  | - `go.opentelemetry.io/otel/internal/baggage` | ||||||
|  |   - This package provides values in a `context.Context` that need to be | ||||||
|  |   recognized by `go.opentelemetry.io/otel/baggage` and | ||||||
|  |   `go.opentelemetry.io/otel/bridge/opentracing` but remain private. | ||||||
|  | 
 | ||||||
|  | If you have duplicate code in multiple modules, make that code into a Go | ||||||
|  | template stored in `go.opentelemetry.io/otel/internal/shared` and use [gotmpl] | ||||||
|  | to render the templates in the desired locations. See [#4404] for an example of | ||||||
|  | this. | ||||||
|  | 
 | ||||||
|  | [^3]: https://github.com/open-telemetry/opentelemetry-go/issues/3548 | ||||||
|  | 
 | ||||||
| ## Approvers and Maintainers | ## Approvers and Maintainers | ||||||
| 
 | 
 | ||||||
| ### Approvers | ### Approvers | ||||||
|  | @ -538,14 +594,14 @@ interface that defines the specific functionality should be preferred. | ||||||
| - [Evan Torrie](https://github.com/evantorrie), Verizon Media | - [Evan Torrie](https://github.com/evantorrie), Verizon Media | ||||||
| - [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics | - [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics | ||||||
| - [David Ashpole](https://github.com/dashpole), Google | - [David Ashpole](https://github.com/dashpole), Google | ||||||
| - [Robert Pająk](https://github.com/pellared), Splunk |  | ||||||
| - [Chester Cheung](https://github.com/hanyuancheung), Tencent | - [Chester Cheung](https://github.com/hanyuancheung), Tencent | ||||||
| - [Damien Mathieu](https://github.com/dmathieu), Elastic | - [Damien Mathieu](https://github.com/dmathieu), Elastic | ||||||
|  | - [Anthony Mirabella](https://github.com/Aneurysm9), AWS | ||||||
| 
 | 
 | ||||||
| ### Maintainers | ### Maintainers | ||||||
| 
 | 
 | ||||||
| - [Aaron Clawson](https://github.com/MadVikingGod), LightStep | - [Aaron Clawson](https://github.com/MadVikingGod), LightStep | ||||||
| - [Anthony Mirabella](https://github.com/Aneurysm9), AWS | - [Robert Pająk](https://github.com/pellared), Splunk | ||||||
| - [Tyler Yahn](https://github.com/MrAlias), Splunk | - [Tyler Yahn](https://github.com/MrAlias), Splunk | ||||||
| 
 | 
 | ||||||
| ### Emeritus | ### Emeritus | ||||||
|  | @ -560,3 +616,5 @@ repo](https://github.com/open-telemetry/community/blob/main/community-membership | ||||||
| 
 | 
 | ||||||
| [Approver]: #approvers | [Approver]: #approvers | ||||||
| [Maintainer]: #maintainers | [Maintainer]: #maintainers | ||||||
|  | [gotmpl]: https://pkg.go.dev/go.opentelemetry.io/build-tools/gotmpl | ||||||
|  | [#4404]: https://github.com/open-telemetry/opentelemetry-go/pull/4404 | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								vendor/go.opentelemetry.io/otel/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/go.opentelemetry.io/otel/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -25,7 +25,7 @@ TIMEOUT = 60 | ||||||
| .DEFAULT_GOAL := precommit | .DEFAULT_GOAL := precommit | ||||||
| 
 | 
 | ||||||
| .PHONY: precommit ci | .PHONY: precommit ci | ||||||
| precommit: generate dependabot-generate license-check vanity-import-fix misspell go-mod-tidy golangci-lint-fix test-default | precommit: generate dependabot-generate license-check misspell go-mod-tidy golangci-lint-fix test-default | ||||||
| ci: generate dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage | ci: generate dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage | ||||||
| 
 | 
 | ||||||
| # Tools
 | # Tools
 | ||||||
|  | @ -71,8 +71,14 @@ $(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto | ||||||
| GOJQ = $(TOOLS)/gojq | GOJQ = $(TOOLS)/gojq | ||||||
| $(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq | $(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq | ||||||
| 
 | 
 | ||||||
|  | GOTMPL = $(TOOLS)/gotmpl | ||||||
|  | $(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl | ||||||
|  | 
 | ||||||
|  | GORELEASE = $(TOOLS)/gorelease | ||||||
|  | $(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease | ||||||
|  | 
 | ||||||
| .PHONY: tools | .PHONY: tools | ||||||
| tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) | tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) | ||||||
| 
 | 
 | ||||||
| # Virtualized python tools via docker
 | # Virtualized python tools via docker
 | ||||||
| 
 | 
 | ||||||
|  | @ -110,13 +116,24 @@ $(CODESPELL): PACKAGE=codespell | ||||||
| # Generate
 | # Generate
 | ||||||
| 
 | 
 | ||||||
| .PHONY: generate | .PHONY: generate | ||||||
|  | generate: go-generate vanity-import-fix | ||||||
| 
 | 
 | ||||||
| generate: $(OTEL_GO_MOD_DIRS:%=generate/%) | .PHONY: go-generate | ||||||
| generate/%: DIR=$* | go-generate: $(OTEL_GO_MOD_DIRS:%=go-generate/%) | ||||||
| generate/%: | $(STRINGER) $(PORTO) | go-generate/%: DIR=$* | ||||||
|  | go-generate/%: | $(STRINGER) $(GOTMPL) | ||||||
| 	@echo "$(GO) generate $(DIR)/..." \
 | 	@echo "$(GO) generate $(DIR)/..." \
 | ||||||
| 		&& cd $(DIR) \
 | 		&& cd $(DIR) \
 | ||||||
| 		&& PATH="$(TOOLS):$${PATH}" $(GO) generate ./... && $(PORTO) -w . | 		&& PATH="$(TOOLS):$${PATH}" $(GO) generate ./... | ||||||
|  | 
 | ||||||
|  | .PHONY: vanity-import-fix | ||||||
|  | vanity-import-fix: | $(PORTO) | ||||||
|  | 	@$(PORTO) --include-internal -w . | ||||||
|  | 
 | ||||||
|  | # Generate go.work file for local development.
 | ||||||
|  | .PHONY: go-work | ||||||
|  | go-work: | $(CROSSLINK) | ||||||
|  | 	$(CROSSLINK) work --root=$(shell pwd) | ||||||
| 
 | 
 | ||||||
| # Build
 | # Build
 | ||||||
| 
 | 
 | ||||||
|  | @ -203,11 +220,7 @@ lint: misspell lint-modules golangci-lint | ||||||
| 
 | 
 | ||||||
| .PHONY: vanity-import-check | .PHONY: vanity-import-check | ||||||
| vanity-import-check: | $(PORTO) | vanity-import-check: | $(PORTO) | ||||||
| 	@$(PORTO) --include-internal -l . || echo "(run: make vanity-import-fix)" | 	@$(PORTO) --include-internal -l . || ( echo "(run: make vanity-import-fix)"; exit 1 ) | ||||||
| 
 |  | ||||||
| .PHONY: vanity-import-fix |  | ||||||
| vanity-import-fix: | $(PORTO) |  | ||||||
| 	@$(PORTO) --include-internal -w . |  | ||||||
| 
 | 
 | ||||||
| .PHONY: misspell | .PHONY: misspell | ||||||
| misspell: | $(MISSPELL) | misspell: | $(MISSPELL) | ||||||
|  | @ -220,7 +233,7 @@ codespell: | $(CODESPELL) | ||||||
| .PHONY: license-check | .PHONY: license-check | ||||||
| license-check: | license-check: | ||||||
| 	@licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \
 | 	@licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \
 | ||||||
| 	           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \
 | 	           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=4 { found=1; next } END { if (!found) print FILENAME }' $$f; \
 | ||||||
| 	   done); \
 | 	   done); \
 | ||||||
| 	   if [ -n "$${licRes}" ]; then \
 | 	   if [ -n "$${licRes}" ]; then \
 | ||||||
| 	           echo "license header checking failed:"; echo "$${licRes}"; \
 | 	           echo "license header checking failed:"; echo "$${licRes}"; \
 | ||||||
|  | @ -230,7 +243,7 @@ license-check: | ||||||
| DEPENDABOT_CONFIG = .github/dependabot.yml | DEPENDABOT_CONFIG = .github/dependabot.yml | ||||||
| .PHONY: dependabot-check | .PHONY: dependabot-check | ||||||
| dependabot-check: | $(DBOTCONF) | dependabot-check: | $(DBOTCONF) | ||||||
| 	@$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || echo "(run: make dependabot-generate)" | 	@$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || ( echo "(run: make dependabot-generate)"; exit 1 ) | ||||||
| 
 | 
 | ||||||
| .PHONY: dependabot-generate | .PHONY: dependabot-generate | ||||||
| dependabot-generate: | $(DBOTCONF) | dependabot-generate: | $(DBOTCONF) | ||||||
|  | @ -249,14 +262,23 @@ check-clean-work-tree: | ||||||
| SEMCONVPKG ?= "semconv/" | SEMCONVPKG ?= "semconv/" | ||||||
| .PHONY: semconv-generate | .PHONY: semconv-generate | ||||||
| semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT) | semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT) | ||||||
| 	[ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry specification tag"; exit 1 ) | 	[ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry semantic-conventions tag"; exit 1 ) | ||||||
| 	[ "$(OTEL_SPEC_REPO)" ] || ( echo "OTEL_SPEC_REPO unset: missing path to opentelemetry specification repo"; exit 1 ) | 	[ "$(OTEL_SEMCONV_REPO)" ] || ( echo "OTEL_SEMCONV_REPO unset: missing path to opentelemetry semantic-conventions repo"; exit 1 ) | ||||||
| 	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=span -p conventionType=trace -f trace.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | 	$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=span -p conventionType=trace -f trace.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | ||||||
| 	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=attribute_group -p conventionType=trace -f attribute_group.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | 	$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=attribute_group -p conventionType=trace -f attribute_group.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | ||||||
| 	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=event -p conventionType=event -f event.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | 	$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=event -p conventionType=event -f event.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | ||||||
| 	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=resource -p conventionType=resource -f resource.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | 	$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=resource -p conventionType=resource -f resource.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" | ||||||
| 	$(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)" | 	$(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)" | ||||||
| 
 | 
 | ||||||
|  | .PHONY: gorelease | ||||||
|  | gorelease: $(OTEL_GO_MOD_DIRS:%=gorelease/%) | ||||||
|  | gorelease/%: DIR=$* | ||||||
|  | gorelease/%:| $(GORELEASE) | ||||||
|  | 	@echo "gorelease in $(DIR):" \
 | ||||||
|  | 		&& cd $(DIR) \
 | ||||||
|  | 		&& $(GORELEASE) \
 | ||||||
|  | 		|| echo "" | ||||||
|  | 
 | ||||||
| .PHONY: prerelease | .PHONY: prerelease | ||||||
| prerelease: | $(MULTIMOD) | prerelease: | $(MULTIMOD) | ||||||
| 	@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) | 	@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								vendor/go.opentelemetry.io/otel/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/go.opentelemetry.io/otel/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -11,22 +11,25 @@ It provides a set of APIs to directly measure performance and behavior of your s | ||||||
| 
 | 
 | ||||||
| ## Project Status | ## Project Status | ||||||
| 
 | 
 | ||||||
| | Signal  | Status     | Project | | | Signal  | Status     | Project               | | ||||||
| | ------- | ---------- | ------- | | |---------|------------|-----------------------| | ||||||
| | Traces  | Stable     | N/A     | | | Traces  | Stable     | N/A                   | | ||||||
| | Metrics | Beta       | N/A     | | | Metrics | Mixed [1]  | [Go: Metric SDK (GA)] | | ||||||
| | Logs    | Frozen [1] | N/A     | | | Logs    | Frozen [2] | N/A                   | | ||||||
| 
 | 
 | ||||||
| - [1]: The Logs signal development is halted for this project while we develop both Traces and Metrics. | [Go: Metric SDK (GA)]: https://github.com/orgs/open-telemetry/projects/34 | ||||||
|  | 
 | ||||||
|  | - [1]: [Metrics API](https://pkg.go.dev/go.opentelemetry.io/otel/metric) is Stable. [Metrics SDK](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) is Beta. | ||||||
|  | - [2]: The Logs signal development is halted for this project while we stabilize the Metrics SDK. | ||||||
|    No Logs Pull Requests are currently being accepted. |    No Logs Pull Requests are currently being accepted. | ||||||
| 
 | 
 | ||||||
| Progress and status specific to this repository is tracked in our local | Progress and status specific to this repository is tracked in our | ||||||
| [project boards](https://github.com/open-telemetry/opentelemetry-go/projects) | [project boards](https://github.com/open-telemetry/opentelemetry-go/projects) | ||||||
| and | and | ||||||
| [milestones](https://github.com/open-telemetry/opentelemetry-go/milestones). | [milestones](https://github.com/open-telemetry/opentelemetry-go/milestones). | ||||||
| 
 | 
 | ||||||
| Project versioning information and stability guarantees can be found in the | Project versioning information and stability guarantees can be found in the | ||||||
| [versioning documentation](./VERSIONING.md). | [versioning documentation](VERSIONING.md). | ||||||
| 
 | 
 | ||||||
| ### Compatibility | ### Compatibility | ||||||
| 
 | 
 | ||||||
|  | @ -49,15 +52,20 @@ stop ensuring compatibility with these versions in the following manner: | ||||||
| Currently, this project supports the following environments. | Currently, this project supports the following environments. | ||||||
| 
 | 
 | ||||||
| | OS      | Go Version | Architecture | | | OS      | Go Version | Architecture | | ||||||
| | ------- | ---------- | ------------ | | |---------|------------|--------------| | ||||||
|  | | Ubuntu  | 1.21       | amd64        | | ||||||
| | Ubuntu  | 1.20       | amd64        | | | Ubuntu  | 1.20       | amd64        | | ||||||
| | Ubuntu  | 1.19       | amd64        | | | Ubuntu  | 1.19       | amd64        | | ||||||
|  | | Ubuntu  | 1.21       | 386          | | ||||||
| | Ubuntu  | 1.20       | 386          | | | Ubuntu  | 1.20       | 386          | | ||||||
| | Ubuntu  | 1.19       | 386          | | | Ubuntu  | 1.19       | 386          | | ||||||
|  | | MacOS   | 1.21       | amd64        | | ||||||
| | MacOS   | 1.20       | amd64        | | | MacOS   | 1.20       | amd64        | | ||||||
| | MacOS   | 1.19       | amd64        | | | MacOS   | 1.19       | amd64        | | ||||||
|  | | Windows | 1.21       | amd64        | | ||||||
| | Windows | 1.20       | amd64        | | | Windows | 1.20       | amd64        | | ||||||
| | Windows | 1.19       | amd64        | | | Windows | 1.19       | amd64        | | ||||||
|  | | Windows | 1.21       | 386          | | ||||||
| | Windows | 1.20       | 386          | | | Windows | 1.20       | 386          | | ||||||
| | Windows | 1.19       | 386          | | | Windows | 1.19       | 386          | | ||||||
| 
 | 
 | ||||||
|  | @ -97,12 +105,11 @@ export pipeline to send that telemetry to an observability platform. | ||||||
| All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters). | All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters). | ||||||
| 
 | 
 | ||||||
| | Exporter                              | Metrics | Traces | | | Exporter                              | Metrics | Traces | | ||||||
| | :-----------------------------------: | :-----: | :----: | | |---------------------------------------|:-------:|:------:| | ||||||
| | [Jaeger](./exporters/jaeger/)         |         | ✓      | | | [OTLP](./exporters/otlp/)             |    ✓    |   ✓    | | ||||||
| | [OTLP](./exporters/otlp/)             | ✓       | ✓      | | | [Prometheus](./exporters/prometheus/) |    ✓    |        | | ||||||
| | [Prometheus](./exporters/prometheus/) | ✓       |        | | | [stdout](./exporters/stdout/)         |    ✓    |   ✓    | | ||||||
| | [stdout](./exporters/stdout/)         | ✓       | ✓      | | | [Zipkin](./exporters/zipkin/)         |         |   ✓    | | ||||||
| | [Zipkin](./exporters/zipkin/)         |         | ✓      | |  | ||||||
| 
 | 
 | ||||||
| ## Contributing | ## Contributing | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								vendor/go.opentelemetry.io/otel/RELEASING.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/go.opentelemetry.io/otel/RELEASING.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -2,27 +2,30 @@ | ||||||
| 
 | 
 | ||||||
| ## Semantic Convention Generation | ## Semantic Convention Generation | ||||||
| 
 | 
 | ||||||
| New versions of the [OpenTelemetry Specification] mean new versions of the `semconv` package need to be generated. | New versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated. | ||||||
| The `semconv-generate` make target is used for this. | The `semconv-generate` make target is used for this. | ||||||
| 
 | 
 | ||||||
| 1. Checkout a local copy of the [OpenTelemetry Specification] to the desired release tag. | 1. Checkout a local copy of the [OpenTelemetry Semantic Conventions] to the desired release tag. | ||||||
| 2. Pull the latest `otel/semconvgen` image: `docker pull otel/semconvgen:latest` | 2. Pull the latest `otel/semconvgen` image: `docker pull otel/semconvgen:latest` | ||||||
| 3. Run the `make semconv-generate ...` target from this repository. | 3. Run the `make semconv-generate ...` target from this repository. | ||||||
| 
 | 
 | ||||||
| For example, | For example, | ||||||
| 
 | 
 | ||||||
| ```sh | ```sh | ||||||
| export TAG="v1.13.0" # Change to the release version you are generating. | export TAG="v1.21.0" # Change to the release version you are generating. | ||||||
| export OTEL_SPEC_REPO="/absolute/path/to/opentelemetry-specification" | export OTEL_SEMCONV_REPO="/absolute/path/to/opentelemetry/semantic-conventions" | ||||||
| docker pull otel/semconvgen:latest | docker pull otel/semconvgen:latest | ||||||
| make semconv-generate # Uses the exported TAG and OTEL_SPEC_REPO. | make semconv-generate # Uses the exported TAG and OTEL_SEMCONV_REPO. | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| This should create a new sub-package of [`semconv`](./semconv). | This should create a new sub-package of [`semconv`](./semconv). | ||||||
| Ensure things look correct before submitting a pull request to include the addition. | Ensure things look correct before submitting a pull request to include the addition. | ||||||
| 
 | 
 | ||||||
| **Note**, the generation code was changed to generate versions >= 1.13. | ## Breaking changes validation | ||||||
| To generate versions prior to this, checkout the old release of this repository (i.e. [2fe8861](https://github.com/open-telemetry/opentelemetry-go/commit/2fe8861a24e20088c065b116089862caf9e3cd8b)). | 
 | ||||||
|  | You can run `make gorelease` that runs [gorelease](https://pkg.go.dev/golang.org/x/exp/cmd/gorelease) to ensure that there are no unwanted changes done in the public API. | ||||||
|  | 
 | ||||||
|  | You can check/report problems with `gorelease` [here](https://golang.org/issues/26420). | ||||||
| 
 | 
 | ||||||
| ## Pre-Release | ## Pre-Release | ||||||
| 
 | 
 | ||||||
|  | @ -120,7 +123,17 @@ Once verified be sure to [make a release for the `contrib` repository](https://g | ||||||
| 
 | 
 | ||||||
| ### Website Documentation | ### Website Documentation | ||||||
| 
 | 
 | ||||||
| Update [the documentation](./website_docs) for [the OpenTelemetry website](https://opentelemetry.io/docs/go/). | Update the [Go instrumentation documentation] in the OpenTelemetry website under [content/en/docs/instrumentation/go]. | ||||||
| Importantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate. | Importantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate. | ||||||
| 
 | 
 | ||||||
| [OpenTelemetry Specification]: https://github.com/open-telemetry/opentelemetry-specification | [OpenTelemetry Semantic Conventions]: https://github.com/open-telemetry/semantic-conventions | ||||||
|  | [Go instrumentation documentation]: https://opentelemetry.io/docs/instrumentation/go/ | ||||||
|  | [content/en/docs/instrumentation/go]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/go | ||||||
|  | 
 | ||||||
|  | ### Demo Repository | ||||||
|  | 
 | ||||||
|  | Bump the dependencies in the following Go services: | ||||||
|  | 
 | ||||||
|  | - [`accountingservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/accountingservice) | ||||||
|  | - [`checkoutservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/checkoutservice) | ||||||
|  | - [`productcatalogservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice) | ||||||
|  |  | ||||||
							
								
								
									
										60
									
								
								vendor/go.opentelemetry.io/otel/attribute/filter.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/go.opentelemetry.io/otel/attribute/filter.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,60 @@ | ||||||
|  | // Copyright The OpenTelemetry Authors | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package attribute // import "go.opentelemetry.io/otel/attribute" | ||||||
|  | 
 | ||||||
|  | // Filter supports removing certain attributes from attribute sets. When | ||||||
|  | // the filter returns true, the attribute will be kept in the filtered | ||||||
|  | // attribute set. When the filter returns false, the attribute is excluded | ||||||
|  | // from the filtered attribute set, and the attribute instead appears in | ||||||
|  | // the removed list of excluded attributes. | ||||||
|  | type Filter func(KeyValue) bool | ||||||
|  | 
 | ||||||
|  | // NewAllowKeysFilter returns a Filter that only allows attributes with one of | ||||||
|  | // the provided keys. | ||||||
|  | // | ||||||
|  | // If keys is empty a deny-all filter is returned. | ||||||
|  | func NewAllowKeysFilter(keys ...Key) Filter { | ||||||
|  | 	if len(keys) <= 0 { | ||||||
|  | 		return func(kv KeyValue) bool { return false } | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	allowed := make(map[Key]struct{}) | ||||||
|  | 	for _, k := range keys { | ||||||
|  | 		allowed[k] = struct{}{} | ||||||
|  | 	} | ||||||
|  | 	return func(kv KeyValue) bool { | ||||||
|  | 		_, ok := allowed[kv.Key] | ||||||
|  | 		return ok | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewDenyKeysFilter returns a Filter that only allows attributes | ||||||
|  | // that do not have one of the provided keys. | ||||||
|  | // | ||||||
|  | // If keys is empty an allow-all filter is returned. | ||||||
|  | func NewDenyKeysFilter(keys ...Key) Filter { | ||||||
|  | 	if len(keys) <= 0 { | ||||||
|  | 		return func(kv KeyValue) bool { return true } | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	forbid := make(map[Key]struct{}) | ||||||
|  | 	for _, k := range keys { | ||||||
|  | 		forbid[k] = struct{}{} | ||||||
|  | 	} | ||||||
|  | 	return func(kv KeyValue) bool { | ||||||
|  | 		_, ok := forbid[kv.Key] | ||||||
|  | 		return !ok | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								vendor/go.opentelemetry.io/otel/attribute/set.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/go.opentelemetry.io/otel/attribute/set.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -39,13 +39,6 @@ type ( | ||||||
| 		iface interface{} | 		iface interface{} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Filter supports removing certain attributes from attribute sets. When |  | ||||||
| 	// the filter returns true, the attribute will be kept in the filtered |  | ||||||
| 	// attribute set. When the filter returns false, the attribute is excluded |  | ||||||
| 	// from the filtered attribute set, and the attribute instead appears in |  | ||||||
| 	// the removed list of excluded attributes. |  | ||||||
| 	Filter func(KeyValue) bool |  | ||||||
| 
 |  | ||||||
| 	// Sortable implements sort.Interface, used for sorting KeyValue. This is | 	// Sortable implements sort.Interface, used for sorting KeyValue. This is | ||||||
| 	// an exported type to support a memory optimization. A pointer to one of | 	// an exported type to support a memory optimization. A pointer to one of | ||||||
| 	// these is needed for the call to sort.Stable(), which the caller may | 	// these is needed for the call to sort.Stable(), which the caller may | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								vendor/go.opentelemetry.io/otel/baggage/baggage.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/go.opentelemetry.io/otel/baggage/baggage.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -61,11 +61,6 @@ type Property struct { | ||||||
| 	// hasValue indicates if a zero-value value means the property does not | 	// hasValue indicates if a zero-value value means the property does not | ||||||
| 	// have a value or if it was the zero-value. | 	// have a value or if it was the zero-value. | ||||||
| 	hasValue bool | 	hasValue bool | ||||||
| 
 |  | ||||||
| 	// hasData indicates whether the created property contains data or not. |  | ||||||
| 	// Properties that do not contain data are invalid with no other check |  | ||||||
| 	// required. |  | ||||||
| 	hasData bool |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewKeyProperty returns a new Property for key. | // NewKeyProperty returns a new Property for key. | ||||||
|  | @ -76,7 +71,7 @@ func NewKeyProperty(key string) (Property, error) { | ||||||
| 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key) | 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	p := Property{key: key, hasData: true} | 	p := Property{key: key} | ||||||
| 	return p, nil | 	return p, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -95,7 +90,6 @@ func NewKeyValueProperty(key, value string) (Property, error) { | ||||||
| 		key:      key, | 		key:      key, | ||||||
| 		value:    value, | 		value:    value, | ||||||
| 		hasValue: true, | 		hasValue: true, | ||||||
| 		hasData:  true, |  | ||||||
| 	} | 	} | ||||||
| 	return p, nil | 	return p, nil | ||||||
| } | } | ||||||
|  | @ -117,7 +111,7 @@ func parseProperty(property string) (Property, error) { | ||||||
| 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidProperty, property) | 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidProperty, property) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	p := Property{hasData: true} | 	var p Property | ||||||
| 	if match[1] != "" { | 	if match[1] != "" { | ||||||
| 		p.key = match[1] | 		p.key = match[1] | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -136,10 +130,6 @@ func (p Property) validate() error { | ||||||
| 		return fmt.Errorf("invalid property: %w", err) | 		return fmt.Errorf("invalid property: %w", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !p.hasData { |  | ||||||
| 		return errFunc(fmt.Errorf("%w: %q", errInvalidProperty, p)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !keyRe.MatchString(p.key) { | 	if !keyRe.MatchString(p.key) { | ||||||
| 		return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key)) | 		return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,50 +0,0 @@ | ||||||
| # OpenTelemetry-Go Jaeger Exporter |  | ||||||
| 
 |  | ||||||
| [](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger) |  | ||||||
| 
 |  | ||||||
| [OpenTelemetry span exporter for Jaeger](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/sdk_exporters/jaeger.md) implementation. |  | ||||||
| 
 |  | ||||||
| ## Installation |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| go get -u go.opentelemetry.io/otel/exporters/jaeger |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## Example |  | ||||||
| 
 |  | ||||||
| See [../../example/jaeger](../../example/jaeger). |  | ||||||
| 
 |  | ||||||
| ## Configuration |  | ||||||
| 
 |  | ||||||
| The exporter can be used to send spans to: |  | ||||||
| 
 |  | ||||||
| - Jaeger agent using `jaeger.thrift` over compact thrift protocol via |  | ||||||
|   [`WithAgentEndpoint`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithAgentEndpoint) option. |  | ||||||
| - Jaeger collector using `jaeger.thrift` over HTTP via |  | ||||||
|   [`WithCollectorEndpoint`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithCollectorEndpoint) option. |  | ||||||
| 
 |  | ||||||
| ### Environment Variables |  | ||||||
| 
 |  | ||||||
| The following environment variables can be used |  | ||||||
| (instead of options objects) to override the default configuration. |  | ||||||
| 
 |  | ||||||
| | Environment variable              | Option                                                                                        | Default value                       | |  | ||||||
| | --------------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------- | |  | ||||||
| | `OTEL_EXPORTER_JAEGER_AGENT_HOST` | [`WithAgentHost`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithAgentHost) | `localhost`                         | |  | ||||||
| | `OTEL_EXPORTER_JAEGER_AGENT_PORT` | [`WithAgentPort`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithAgentPort) | `6831`                              | |  | ||||||
| | `OTEL_EXPORTER_JAEGER_ENDPOINT`   | [`WithEndpoint`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithEndpoint)   | `http://localhost:14268/api/traces` | |  | ||||||
| | `OTEL_EXPORTER_JAEGER_USER`       | [`WithUsername`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithUsername)   |                                     | |  | ||||||
| | `OTEL_EXPORTER_JAEGER_PASSWORD`   | [`WithPassword`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/jaeger#WithPassword)   |                                     | |  | ||||||
| 
 |  | ||||||
| Configuration using options have precedence over the environment variables. |  | ||||||
| 
 |  | ||||||
| ## Contributing |  | ||||||
| 
 |  | ||||||
| This exporter uses a vendored copy of the Apache Thrift library (v0.14.1) at a custom import path. |  | ||||||
| When re-generating Thrift code in the future, please adapt import paths as necessary. |  | ||||||
| 
 |  | ||||||
| ## References |  | ||||||
| 
 |  | ||||||
| - [Jaeger](https://www.jaegertracing.io/) |  | ||||||
| - [OpenTelemetry to Jaeger Transformation](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/sdk_exporters/jaeger.md) |  | ||||||
| - [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/sdk-environment-variables.md#jaeger-exporter) |  | ||||||
							
								
								
									
										213
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/agent.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										213
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/agent.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,213 +0,0 @@ | ||||||
| // Copyright The OpenTelemetry Authors |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
| 
 |  | ||||||
| package jaeger // import "go.opentelemetry.io/otel/exporters/jaeger" |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"net" |  | ||||||
| 	"strings" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"github.com/go-logr/logr" |  | ||||||
| 
 |  | ||||||
| 	genAgent "go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent" |  | ||||||
| 	gen "go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	// udpPacketMaxLength is the max size of UDP packet we want to send, synced with jaeger-agent. |  | ||||||
| 	udpPacketMaxLength = 65000 |  | ||||||
| 	// emitBatchOverhead is the additional overhead bytes used for enveloping the datagram, |  | ||||||
| 	// synced with jaeger-agent https://github.com/jaegertracing/jaeger-client-go/blob/master/transport_udp.go#L37 |  | ||||||
| 	emitBatchOverhead = 70 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // agentClientUDP is a UDP client to Jaeger agent that implements gen.Agent interface. |  | ||||||
| type agentClientUDP struct { |  | ||||||
| 	genAgent.Agent |  | ||||||
| 	io.Closer |  | ||||||
| 
 |  | ||||||
| 	connUDP        udpConn |  | ||||||
| 	client         *genAgent.AgentClient |  | ||||||
| 	maxPacketSize  int                   // max size of datagram in bytes |  | ||||||
| 	thriftBuffer   *thrift.TMemoryBuffer // buffer used to calculate byte size of a span |  | ||||||
| 	thriftProtocol thrift.TProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type udpConn interface { |  | ||||||
| 	Write([]byte) (int, error) |  | ||||||
| 	SetWriteBuffer(int) error |  | ||||||
| 	Close() error |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type agentClientUDPParams struct { |  | ||||||
| 	Host                     string |  | ||||||
| 	Port                     string |  | ||||||
| 	MaxPacketSize            int |  | ||||||
| 	Logger                   logr.Logger |  | ||||||
| 	AttemptReconnecting      bool |  | ||||||
| 	AttemptReconnectInterval time.Duration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // newAgentClientUDP creates a client that sends spans to Jaeger Agent over UDP. |  | ||||||
| func newAgentClientUDP(params agentClientUDPParams) (*agentClientUDP, error) { |  | ||||||
| 	hostPort := net.JoinHostPort(params.Host, params.Port) |  | ||||||
| 	// validate hostport |  | ||||||
| 	if _, _, err := net.SplitHostPort(hostPort); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if params.MaxPacketSize <= 0 || params.MaxPacketSize > udpPacketMaxLength { |  | ||||||
| 		params.MaxPacketSize = udpPacketMaxLength |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if params.AttemptReconnecting && params.AttemptReconnectInterval <= 0 { |  | ||||||
| 		params.AttemptReconnectInterval = time.Second * 30 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	thriftBuffer := thrift.NewTMemoryBufferLen(params.MaxPacketSize) |  | ||||||
| 	protocolFactory := thrift.NewTCompactProtocolFactoryConf(&thrift.TConfiguration{}) |  | ||||||
| 	thriftProtocol := protocolFactory.GetProtocol(thriftBuffer) |  | ||||||
| 	client := genAgent.NewAgentClientFactory(thriftBuffer, protocolFactory) |  | ||||||
| 
 |  | ||||||
| 	var connUDP udpConn |  | ||||||
| 	var err error |  | ||||||
| 
 |  | ||||||
| 	if params.AttemptReconnecting { |  | ||||||
| 		// host is hostname, setup resolver loop in case host record changes during operation |  | ||||||
| 		connUDP, err = newReconnectingUDPConn(hostPort, params.MaxPacketSize, params.AttemptReconnectInterval, net.ResolveUDPAddr, net.DialUDP, params.Logger) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		destAddr, err := net.ResolveUDPAddr("udp", hostPort) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		connUDP, err = net.DialUDP(destAddr.Network(), nil, destAddr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := connUDP.SetWriteBuffer(params.MaxPacketSize); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return &agentClientUDP{ |  | ||||||
| 		connUDP:        connUDP, |  | ||||||
| 		client:         client, |  | ||||||
| 		maxPacketSize:  params.MaxPacketSize, |  | ||||||
| 		thriftBuffer:   thriftBuffer, |  | ||||||
| 		thriftProtocol: thriftProtocol, |  | ||||||
| 	}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // EmitBatch buffers batch to fit into UDP packets and sends the data to the agent. |  | ||||||
| func (a *agentClientUDP) EmitBatch(ctx context.Context, batch *gen.Batch) error { |  | ||||||
| 	var errs []error |  | ||||||
| 	processSize, err := a.calcSizeOfSerializedThrift(ctx, batch.Process) |  | ||||||
| 	if err != nil { |  | ||||||
| 		// drop the batch if serialization of process fails. |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	maxPacketSize := a.maxPacketSize |  | ||||||
| 	if maxPacketSize > udpPacketMaxLength-emitBatchOverhead { |  | ||||||
| 		maxPacketSize = udpPacketMaxLength - emitBatchOverhead |  | ||||||
| 	} |  | ||||||
| 	totalSize := processSize |  | ||||||
| 	var spans []*gen.Span |  | ||||||
| 	for _, span := range batch.Spans { |  | ||||||
| 		spanSize, err := a.calcSizeOfSerializedThrift(ctx, span) |  | ||||||
| 		if err != nil { |  | ||||||
| 			errs = append(errs, fmt.Errorf("thrift serialization failed: %v", span)) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if spanSize+processSize >= maxPacketSize { |  | ||||||
| 			// drop the span that exceeds the limit. |  | ||||||
| 			errs = append(errs, fmt.Errorf("span too large to send: %v", span)) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if totalSize+spanSize >= maxPacketSize { |  | ||||||
| 			if err := a.flush(ctx, &gen.Batch{ |  | ||||||
| 				Process: batch.Process, |  | ||||||
| 				Spans:   spans, |  | ||||||
| 			}); err != nil { |  | ||||||
| 				errs = append(errs, err) |  | ||||||
| 			} |  | ||||||
| 			spans = spans[:0] |  | ||||||
| 			totalSize = processSize |  | ||||||
| 		} |  | ||||||
| 		totalSize += spanSize |  | ||||||
| 		spans = append(spans, span) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(spans) > 0 { |  | ||||||
| 		if err := a.flush(ctx, &gen.Batch{ |  | ||||||
| 			Process: batch.Process, |  | ||||||
| 			Spans:   spans, |  | ||||||
| 		}); err != nil { |  | ||||||
| 			errs = append(errs, err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(errs) == 1 { |  | ||||||
| 		return errs[0] |  | ||||||
| 	} else if len(errs) > 1 { |  | ||||||
| 		joined := a.makeJoinedErrorString(errs) |  | ||||||
| 		return fmt.Errorf("multiple errors during transform: %s", joined) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // makeJoinedErrorString join all the errors to one error message. |  | ||||||
| func (a *agentClientUDP) makeJoinedErrorString(errs []error) string { |  | ||||||
| 	var errMsgs []string |  | ||||||
| 	for _, err := range errs { |  | ||||||
| 		errMsgs = append(errMsgs, err.Error()) |  | ||||||
| 	} |  | ||||||
| 	return strings.Join(errMsgs, ", ") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // flush will send the batch of spans to the agent. |  | ||||||
| func (a *agentClientUDP) flush(ctx context.Context, batch *gen.Batch) error { |  | ||||||
| 	a.thriftBuffer.Reset() |  | ||||||
| 	if err := a.client.EmitBatch(ctx, batch); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if a.thriftBuffer.Len() > a.maxPacketSize { |  | ||||||
| 		return fmt.Errorf("data does not fit within one UDP packet; size %d, max %d, spans %d", |  | ||||||
| 			a.thriftBuffer.Len(), a.maxPacketSize, len(batch.Spans)) |  | ||||||
| 	} |  | ||||||
| 	_, err := a.connUDP.Write(a.thriftBuffer.Bytes()) |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // calcSizeOfSerializedThrift calculate the serialized thrift packet size. |  | ||||||
| func (a *agentClientUDP) calcSizeOfSerializedThrift(ctx context.Context, thriftStruct thrift.TStruct) (int, error) { |  | ||||||
| 	a.thriftBuffer.Reset() |  | ||||||
| 	err := thriftStruct.Write(ctx, a.thriftProtocol) |  | ||||||
| 	return a.thriftBuffer.Len(), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Close implements Close() of io.Closer and closes the underlying UDP connection. |  | ||||||
| func (a *agentClientUDP) Close() error { |  | ||||||
| 	return a.connUDP.Close() |  | ||||||
| } |  | ||||||
							
								
								
									
										44
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/env.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/env.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,44 +0,0 @@ | ||||||
| // Copyright The OpenTelemetry Authors |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
| 
 |  | ||||||
| package jaeger // import "go.opentelemetry.io/otel/exporters/jaeger" |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"os" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Environment variable names. |  | ||||||
| const ( |  | ||||||
| 	// Hostname for the Jaeger agent, part of address where exporter sends spans |  | ||||||
| 	// i.e.	"localhost". |  | ||||||
| 	envAgentHost = "OTEL_EXPORTER_JAEGER_AGENT_HOST" |  | ||||||
| 	// Port for the Jaeger agent, part of address where exporter sends spans |  | ||||||
| 	// i.e. 6831. |  | ||||||
| 	envAgentPort = "OTEL_EXPORTER_JAEGER_AGENT_PORT" |  | ||||||
| 	// The HTTP endpoint for sending spans directly to a collector, |  | ||||||
| 	// i.e. http://jaeger-collector:14268/api/traces. |  | ||||||
| 	envEndpoint = "OTEL_EXPORTER_JAEGER_ENDPOINT" |  | ||||||
| 	// Username to send as part of "Basic" authentication to the collector endpoint. |  | ||||||
| 	envUser = "OTEL_EXPORTER_JAEGER_USER" |  | ||||||
| 	// Password to send as part of "Basic" authentication to the collector endpoint. |  | ||||||
| 	envPassword = "OTEL_EXPORTER_JAEGER_PASSWORD" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // envOr returns an env variable's value if it is exists or the default if not. |  | ||||||
| func envOr(key, defaultValue string) string { |  | ||||||
| 	if v := os.Getenv(key); v != "" { |  | ||||||
| 		return v |  | ||||||
| 	} |  | ||||||
| 	return defaultValue |  | ||||||
| } |  | ||||||
|  | @ -1,6 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package agent |  | ||||||
| 
 |  | ||||||
| var GoUnusedProtection__ int; |  | ||||||
| 
 |  | ||||||
							
								
								
									
										27
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent/agent-consts.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent/agent-consts.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,27 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package agent |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // (needed to ensure safety because of naive import list construction.) |  | ||||||
| var _ = thrift.ZERO |  | ||||||
| var _ = fmt.Printf |  | ||||||
| var _ = context.Background |  | ||||||
| var _ = time.Now |  | ||||||
| var _ = bytes.Equal |  | ||||||
| 
 |  | ||||||
| var _ = jaeger.GoUnusedProtection__ |  | ||||||
| var _ = zipkincore.GoUnusedProtection__ |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| } |  | ||||||
							
								
								
									
										412
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent/agent.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										412
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent/agent.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,412 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package agent |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // (needed to ensure safety because of naive import list construction.) |  | ||||||
| var _ = thrift.ZERO |  | ||||||
| var _ = fmt.Printf |  | ||||||
| var _ = context.Background |  | ||||||
| var _ = time.Now |  | ||||||
| var _ = bytes.Equal |  | ||||||
| 
 |  | ||||||
| var _ = jaeger.GoUnusedProtection__ |  | ||||||
| var _ = zipkincore.GoUnusedProtection__ |  | ||||||
| 
 |  | ||||||
| type Agent interface { |  | ||||||
| 	// Parameters: |  | ||||||
| 	//  - Spans |  | ||||||
| 	EmitZipkinBatch(ctx context.Context, spans []*zipkincore.Span) (_err error) |  | ||||||
| 	// Parameters: |  | ||||||
| 	//  - Batch |  | ||||||
| 	EmitBatch(ctx context.Context, batch *jaeger.Batch) (_err error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type AgentClient struct { |  | ||||||
| 	c    thrift.TClient |  | ||||||
| 	meta thrift.ResponseMeta |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewAgentClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *AgentClient { |  | ||||||
| 	return &AgentClient{ |  | ||||||
| 		c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewAgentClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *AgentClient { |  | ||||||
| 	return &AgentClient{ |  | ||||||
| 		c: thrift.NewTStandardClient(iprot, oprot), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewAgentClient(c thrift.TClient) *AgentClient { |  | ||||||
| 	return &AgentClient{ |  | ||||||
| 		c: c, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentClient) Client_() thrift.TClient { |  | ||||||
| 	return p.c |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentClient) LastResponseMeta_() thrift.ResponseMeta { |  | ||||||
| 	return p.meta |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentClient) SetLastResponseMeta_(meta thrift.ResponseMeta) { |  | ||||||
| 	p.meta = meta |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Parameters: |  | ||||||
| //  - Spans |  | ||||||
| func (p *AgentClient) EmitZipkinBatch(ctx context.Context, spans []*zipkincore.Span) (_err error) { |  | ||||||
| 	var _args0 AgentEmitZipkinBatchArgs |  | ||||||
| 	_args0.Spans = spans |  | ||||||
| 	p.SetLastResponseMeta_(thrift.ResponseMeta{}) |  | ||||||
| 	if _, err := p.Client_().Call(ctx, "emitZipkinBatch", &_args0, nil); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Parameters: |  | ||||||
| //  - Batch |  | ||||||
| func (p *AgentClient) EmitBatch(ctx context.Context, batch *jaeger.Batch) (_err error) { |  | ||||||
| 	var _args1 AgentEmitBatchArgs |  | ||||||
| 	_args1.Batch = batch |  | ||||||
| 	p.SetLastResponseMeta_(thrift.ResponseMeta{}) |  | ||||||
| 	if _, err := p.Client_().Call(ctx, "emitBatch", &_args1, nil); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type AgentProcessor struct { |  | ||||||
| 	processorMap map[string]thrift.TProcessorFunction |  | ||||||
| 	handler      Agent |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { |  | ||||||
| 	p.processorMap[key] = processor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { |  | ||||||
| 	processor, ok = p.processorMap[key] |  | ||||||
| 	return processor, ok |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { |  | ||||||
| 	return p.processorMap |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewAgentProcessor(handler Agent) *AgentProcessor { |  | ||||||
| 
 |  | ||||||
| 	self2 := &AgentProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} |  | ||||||
| 	self2.processorMap["emitZipkinBatch"] = &agentProcessorEmitZipkinBatch{handler: handler} |  | ||||||
| 	self2.processorMap["emitBatch"] = &agentProcessorEmitBatch{handler: handler} |  | ||||||
| 	return self2 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { |  | ||||||
| 	name, _, seqId, err2 := iprot.ReadMessageBegin(ctx) |  | ||||||
| 	if err2 != nil { |  | ||||||
| 		return false, thrift.WrapTException(err2) |  | ||||||
| 	} |  | ||||||
| 	if processor, ok := p.GetProcessorFunction(name); ok { |  | ||||||
| 		return processor.Process(ctx, seqId, iprot, oprot) |  | ||||||
| 	} |  | ||||||
| 	iprot.Skip(ctx, thrift.STRUCT) |  | ||||||
| 	iprot.ReadMessageEnd(ctx) |  | ||||||
| 	x3 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) |  | ||||||
| 	oprot.WriteMessageBegin(ctx, name, thrift.EXCEPTION, seqId) |  | ||||||
| 	x3.Write(ctx, oprot) |  | ||||||
| 	oprot.WriteMessageEnd(ctx) |  | ||||||
| 	oprot.Flush(ctx) |  | ||||||
| 	return false, x3 |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type agentProcessorEmitZipkinBatch struct { |  | ||||||
| 	handler Agent |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *agentProcessorEmitZipkinBatch) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { |  | ||||||
| 	args := AgentEmitZipkinBatchArgs{} |  | ||||||
| 	var err2 error |  | ||||||
| 	if err2 = args.Read(ctx, iprot); err2 != nil { |  | ||||||
| 		iprot.ReadMessageEnd(ctx) |  | ||||||
| 		return false, thrift.WrapTException(err2) |  | ||||||
| 	} |  | ||||||
| 	iprot.ReadMessageEnd(ctx) |  | ||||||
| 
 |  | ||||||
| 	tickerCancel := func() {} |  | ||||||
| 	_ = tickerCancel |  | ||||||
| 
 |  | ||||||
| 	if err2 = p.handler.EmitZipkinBatch(ctx, args.Spans); err2 != nil { |  | ||||||
| 		tickerCancel() |  | ||||||
| 		return true, thrift.WrapTException(err2) |  | ||||||
| 	} |  | ||||||
| 	tickerCancel() |  | ||||||
| 	return true, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type agentProcessorEmitBatch struct { |  | ||||||
| 	handler Agent |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *agentProcessorEmitBatch) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { |  | ||||||
| 	args := AgentEmitBatchArgs{} |  | ||||||
| 	var err2 error |  | ||||||
| 	if err2 = args.Read(ctx, iprot); err2 != nil { |  | ||||||
| 		iprot.ReadMessageEnd(ctx) |  | ||||||
| 		return false, thrift.WrapTException(err2) |  | ||||||
| 	} |  | ||||||
| 	iprot.ReadMessageEnd(ctx) |  | ||||||
| 
 |  | ||||||
| 	tickerCancel := func() {} |  | ||||||
| 	_ = tickerCancel |  | ||||||
| 
 |  | ||||||
| 	if err2 = p.handler.EmitBatch(ctx, args.Batch); err2 != nil { |  | ||||||
| 		tickerCancel() |  | ||||||
| 		return true, thrift.WrapTException(err2) |  | ||||||
| 	} |  | ||||||
| 	tickerCancel() |  | ||||||
| 	return true, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // HELPER FUNCTIONS AND STRUCTURES |  | ||||||
| 
 |  | ||||||
| // Attributes: |  | ||||||
| //  - Spans |  | ||||||
| type AgentEmitZipkinBatchArgs struct { |  | ||||||
| 	Spans []*zipkincore.Span `thrift:"spans,1" db:"spans" json:"spans"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewAgentEmitZipkinBatchArgs() *AgentEmitZipkinBatchArgs { |  | ||||||
| 	return &AgentEmitZipkinBatchArgs{} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitZipkinBatchArgs) GetSpans() []*zipkincore.Span { |  | ||||||
| 	return p.Spans |  | ||||||
| } |  | ||||||
| func (p *AgentEmitZipkinBatchArgs) Read(ctx context.Context, iprot thrift.TProtocol) error { |  | ||||||
| 	if _, err := iprot.ReadStructBegin(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for { |  | ||||||
| 		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) |  | ||||||
| 		} |  | ||||||
| 		if fieldTypeId == thrift.STOP { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		switch fieldId { |  | ||||||
| 		case 1: |  | ||||||
| 			if fieldTypeId == thrift.LIST { |  | ||||||
| 				if err := p.ReadField1(ctx, iprot); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				if err := iprot.Skip(ctx, fieldTypeId); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 			if err := iprot.Skip(ctx, fieldTypeId); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if err := iprot.ReadFieldEnd(ctx); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := iprot.ReadStructEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitZipkinBatchArgs) ReadField1(ctx context.Context, iprot thrift.TProtocol) error { |  | ||||||
| 	_, size, err := iprot.ReadListBegin(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return thrift.PrependError("error reading list begin: ", err) |  | ||||||
| 	} |  | ||||||
| 	tSlice := make([]*zipkincore.Span, 0, size) |  | ||||||
| 	p.Spans = tSlice |  | ||||||
| 	for i := 0; i < size; i++ { |  | ||||||
| 		_elem4 := &zipkincore.Span{} |  | ||||||
| 		if err := _elem4.Read(ctx, iprot); err != nil { |  | ||||||
| 			return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem4), err) |  | ||||||
| 		} |  | ||||||
| 		p.Spans = append(p.Spans, _elem4) |  | ||||||
| 	} |  | ||||||
| 	if err := iprot.ReadListEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError("error reading list end: ", err) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitZipkinBatchArgs) Write(ctx context.Context, oprot thrift.TProtocol) error { |  | ||||||
| 	if err := oprot.WriteStructBegin(ctx, "emitZipkinBatch_args"); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	if p != nil { |  | ||||||
| 		if err := p.writeField1(ctx, oprot); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteFieldStop(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError("write field stop error: ", err) |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteStructEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError("write struct stop error: ", err) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitZipkinBatchArgs) writeField1(ctx context.Context, oprot thrift.TProtocol) (err error) { |  | ||||||
| 	if err := oprot.WriteFieldBegin(ctx, "spans", thrift.LIST, 1); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:spans: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteListBegin(ctx, thrift.STRUCT, len(p.Spans)); err != nil { |  | ||||||
| 		return thrift.PrependError("error writing list begin: ", err) |  | ||||||
| 	} |  | ||||||
| 	for _, v := range p.Spans { |  | ||||||
| 		if err := v.Write(ctx, oprot); err != nil { |  | ||||||
| 			return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteListEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError("error writing list end: ", err) |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteFieldEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:spans: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitZipkinBatchArgs) String() string { |  | ||||||
| 	if p == nil { |  | ||||||
| 		return "<nil>" |  | ||||||
| 	} |  | ||||||
| 	return fmt.Sprintf("AgentEmitZipkinBatchArgs(%+v)", *p) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Attributes: |  | ||||||
| //  - Batch |  | ||||||
| type AgentEmitBatchArgs struct { |  | ||||||
| 	Batch *jaeger.Batch `thrift:"batch,1" db:"batch" json:"batch"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewAgentEmitBatchArgs() *AgentEmitBatchArgs { |  | ||||||
| 	return &AgentEmitBatchArgs{} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var AgentEmitBatchArgs_Batch_DEFAULT *jaeger.Batch |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitBatchArgs) GetBatch() *jaeger.Batch { |  | ||||||
| 	if !p.IsSetBatch() { |  | ||||||
| 		return AgentEmitBatchArgs_Batch_DEFAULT |  | ||||||
| 	} |  | ||||||
| 	return p.Batch |  | ||||||
| } |  | ||||||
| func (p *AgentEmitBatchArgs) IsSetBatch() bool { |  | ||||||
| 	return p.Batch != nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitBatchArgs) Read(ctx context.Context, iprot thrift.TProtocol) error { |  | ||||||
| 	if _, err := iprot.ReadStructBegin(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for { |  | ||||||
| 		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) |  | ||||||
| 		} |  | ||||||
| 		if fieldTypeId == thrift.STOP { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		switch fieldId { |  | ||||||
| 		case 1: |  | ||||||
| 			if fieldTypeId == thrift.STRUCT { |  | ||||||
| 				if err := p.ReadField1(ctx, iprot); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				if err := iprot.Skip(ctx, fieldTypeId); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 			if err := iprot.Skip(ctx, fieldTypeId); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if err := iprot.ReadFieldEnd(ctx); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := iprot.ReadStructEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitBatchArgs) ReadField1(ctx context.Context, iprot thrift.TProtocol) error { |  | ||||||
| 	p.Batch = &jaeger.Batch{} |  | ||||||
| 	if err := p.Batch.Read(ctx, iprot); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Batch), err) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitBatchArgs) Write(ctx context.Context, oprot thrift.TProtocol) error { |  | ||||||
| 	if err := oprot.WriteStructBegin(ctx, "emitBatch_args"); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	if p != nil { |  | ||||||
| 		if err := p.writeField1(ctx, oprot); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteFieldStop(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError("write field stop error: ", err) |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteStructEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError("write struct stop error: ", err) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitBatchArgs) writeField1(ctx context.Context, oprot thrift.TProtocol) (err error) { |  | ||||||
| 	if err := oprot.WriteFieldBegin(ctx, "batch", thrift.STRUCT, 1); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:batch: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	if err := p.Batch.Write(ctx, oprot); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Batch), err) |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteFieldEnd(ctx); err != nil { |  | ||||||
| 		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:batch: ", p), err) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *AgentEmitBatchArgs) String() string { |  | ||||||
| 	if p == nil { |  | ||||||
| 		return "<nil>" |  | ||||||
| 	} |  | ||||||
| 	return fmt.Sprintf("AgentEmitBatchArgs(%+v)", *p) |  | ||||||
| } |  | ||||||
|  | @ -1,6 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package jaeger |  | ||||||
| 
 |  | ||||||
| var GoUnusedProtection__ int; |  | ||||||
| 
 |  | ||||||
							
								
								
									
										22
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger/jaeger-consts.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger/jaeger-consts.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,22 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package jaeger |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // (needed to ensure safety because of naive import list construction.) |  | ||||||
| var _ = thrift.ZERO |  | ||||||
| var _ = fmt.Printf |  | ||||||
| var _ = context.Background |  | ||||||
| var _ = time.Now |  | ||||||
| var _ = bytes.Equal |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| } |  | ||||||
							
								
								
									
										3022
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger/jaeger.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3022
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger/jaeger.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,6 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package zipkincore |  | ||||||
| 
 |  | ||||||
| var GoUnusedProtection__ int; |  | ||||||
| 
 |  | ||||||
|  | @ -1,39 +0,0 @@ | ||||||
| // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. |  | ||||||
| 
 |  | ||||||
| package zipkincore |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // (needed to ensure safety because of naive import list construction.) |  | ||||||
| var _ = thrift.ZERO |  | ||||||
| var _ = fmt.Printf |  | ||||||
| var _ = context.Background |  | ||||||
| var _ = time.Now |  | ||||||
| var _ = bytes.Equal |  | ||||||
| 
 |  | ||||||
| const CLIENT_SEND = "cs" |  | ||||||
| const CLIENT_RECV = "cr" |  | ||||||
| const SERVER_SEND = "ss" |  | ||||||
| const SERVER_RECV = "sr" |  | ||||||
| const MESSAGE_SEND = "ms" |  | ||||||
| const MESSAGE_RECV = "mr" |  | ||||||
| const WIRE_SEND = "ws" |  | ||||||
| const WIRE_RECV = "wr" |  | ||||||
| const CLIENT_SEND_FRAGMENT = "csf" |  | ||||||
| const CLIENT_RECV_FRAGMENT = "crf" |  | ||||||
| const SERVER_SEND_FRAGMENT = "ssf" |  | ||||||
| const SERVER_RECV_FRAGMENT = "srf" |  | ||||||
| const LOCAL_COMPONENT = "lc" |  | ||||||
| const CLIENT_ADDR = "ca" |  | ||||||
| const SERVER_ADDR = "sa" |  | ||||||
| const MESSAGE_ADDR = "ma" |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| } |  | ||||||
							
								
								
									
										2067
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore/zipkincore.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2067
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore/zipkincore.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										306
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										306
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,306 +0,0 @@ | ||||||
| 
 |  | ||||||
|                                  Apache License |  | ||||||
|                            Version 2.0, January 2004 |  | ||||||
|                         http://www.apache.org/licenses/ |  | ||||||
| 
 |  | ||||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |  | ||||||
| 
 |  | ||||||
|    1. Definitions. |  | ||||||
| 
 |  | ||||||
|       "License" shall mean the terms and conditions for use, reproduction, |  | ||||||
|       and distribution as defined by Sections 1 through 9 of this document. |  | ||||||
| 
 |  | ||||||
|       "Licensor" shall mean the copyright owner or entity authorized by |  | ||||||
|       the copyright owner that is granting the License. |  | ||||||
| 
 |  | ||||||
|       "Legal Entity" shall mean the union of the acting entity and all |  | ||||||
|       other entities that control, are controlled by, or are under common |  | ||||||
|       control with that entity. For the purposes of this definition, |  | ||||||
|       "control" means (i) the power, direct or indirect, to cause the |  | ||||||
|       direction or management of such entity, whether by contract or |  | ||||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the |  | ||||||
|       outstanding shares, or (iii) beneficial ownership of such entity. |  | ||||||
| 
 |  | ||||||
|       "You" (or "Your") shall mean an individual or Legal Entity |  | ||||||
|       exercising permissions granted by this License. |  | ||||||
| 
 |  | ||||||
|       "Source" form shall mean the preferred form for making modifications, |  | ||||||
|       including but not limited to software source code, documentation |  | ||||||
|       source, and configuration files. |  | ||||||
| 
 |  | ||||||
|       "Object" form shall mean any form resulting from mechanical |  | ||||||
|       transformation or translation of a Source form, including but |  | ||||||
|       not limited to compiled object code, generated documentation, |  | ||||||
|       and conversions to other media types. |  | ||||||
| 
 |  | ||||||
|       "Work" shall mean the work of authorship, whether in Source or |  | ||||||
|       Object form, made available under the License, as indicated by a |  | ||||||
|       copyright notice that is included in or attached to the work |  | ||||||
|       (an example is provided in the Appendix below). |  | ||||||
| 
 |  | ||||||
|       "Derivative Works" shall mean any work, whether in Source or Object |  | ||||||
|       form, that is based on (or derived from) the Work and for which the |  | ||||||
|       editorial revisions, annotations, elaborations, or other modifications |  | ||||||
|       represent, as a whole, an original work of authorship. For the purposes |  | ||||||
|       of this License, Derivative Works shall not include works that remain |  | ||||||
|       separable from, or merely link (or bind by name) to the interfaces of, |  | ||||||
|       the Work and Derivative Works thereof. |  | ||||||
| 
 |  | ||||||
|       "Contribution" shall mean any work of authorship, including |  | ||||||
|       the original version of the Work and any modifications or additions |  | ||||||
|       to that Work or Derivative Works thereof, that is intentionally |  | ||||||
|       submitted to Licensor for inclusion in the Work by the copyright owner |  | ||||||
|       or by an individual or Legal Entity authorized to submit on behalf of |  | ||||||
|       the copyright owner. For the purposes of this definition, "submitted" |  | ||||||
|       means any form of electronic, verbal, or written communication sent |  | ||||||
|       to the Licensor or its representatives, including but not limited to |  | ||||||
|       communication on electronic mailing lists, source code control systems, |  | ||||||
|       and issue tracking systems that are managed by, or on behalf of, the |  | ||||||
|       Licensor for the purpose of discussing and improving the Work, but |  | ||||||
|       excluding communication that is conspicuously marked or otherwise |  | ||||||
|       designated in writing by the copyright owner as "Not a Contribution." |  | ||||||
| 
 |  | ||||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity |  | ||||||
|       on behalf of whom a Contribution has been received by Licensor and |  | ||||||
|       subsequently incorporated within the Work. |  | ||||||
| 
 |  | ||||||
|    2. Grant of Copyright License. Subject to the terms and conditions of |  | ||||||
|       this License, each Contributor hereby grants to You a perpetual, |  | ||||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable |  | ||||||
|       copyright license to reproduce, prepare Derivative Works of, |  | ||||||
|       publicly display, publicly perform, sublicense, and distribute the |  | ||||||
|       Work and such Derivative Works in Source or Object form. |  | ||||||
| 
 |  | ||||||
|    3. Grant of Patent License. Subject to the terms and conditions of |  | ||||||
|       this License, each Contributor hereby grants to You a perpetual, |  | ||||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable |  | ||||||
|       (except as stated in this section) patent license to make, have made, |  | ||||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, |  | ||||||
|       where such license applies only to those patent claims licensable |  | ||||||
|       by such Contributor that are necessarily infringed by their |  | ||||||
|       Contribution(s) alone or by combination of their Contribution(s) |  | ||||||
|       with the Work to which such Contribution(s) was submitted. If You |  | ||||||
|       institute patent litigation against any entity (including a |  | ||||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work |  | ||||||
|       or a Contribution incorporated within the Work constitutes direct |  | ||||||
|       or contributory patent infringement, then any patent licenses |  | ||||||
|       granted to You under this License for that Work shall terminate |  | ||||||
|       as of the date such litigation is filed. |  | ||||||
| 
 |  | ||||||
|    4. Redistribution. You may reproduce and distribute copies of the |  | ||||||
|       Work or Derivative Works thereof in any medium, with or without |  | ||||||
|       modifications, and in Source or Object form, provided that You |  | ||||||
|       meet the following conditions: |  | ||||||
| 
 |  | ||||||
|       (a) You must give any other recipients of the Work or |  | ||||||
|           Derivative Works a copy of this License; and |  | ||||||
| 
 |  | ||||||
|       (b) You must cause any modified files to carry prominent notices |  | ||||||
|           stating that You changed the files; and |  | ||||||
| 
 |  | ||||||
|       (c) You must retain, in the Source form of any Derivative Works |  | ||||||
|           that You distribute, all copyright, patent, trademark, and |  | ||||||
|           attribution notices from the Source form of the Work, |  | ||||||
|           excluding those notices that do not pertain to any part of |  | ||||||
|           the Derivative Works; and |  | ||||||
| 
 |  | ||||||
|       (d) If the Work includes a "NOTICE" text file as part of its |  | ||||||
|           distribution, then any Derivative Works that You distribute must |  | ||||||
|           include a readable copy of the attribution notices contained |  | ||||||
|           within such NOTICE file, excluding those notices that do not |  | ||||||
|           pertain to any part of the Derivative Works, in at least one |  | ||||||
|           of the following places: within a NOTICE text file distributed |  | ||||||
|           as part of the Derivative Works; within the Source form or |  | ||||||
|           documentation, if provided along with the Derivative Works; or, |  | ||||||
|           within a display generated by the Derivative Works, if and |  | ||||||
|           wherever such third-party notices normally appear. The contents |  | ||||||
|           of the NOTICE file are for informational purposes only and |  | ||||||
|           do not modify the License. You may add Your own attribution |  | ||||||
|           notices within Derivative Works that You distribute, alongside |  | ||||||
|           or as an addendum to the NOTICE text from the Work, provided |  | ||||||
|           that such additional attribution notices cannot be construed |  | ||||||
|           as modifying the License. |  | ||||||
| 
 |  | ||||||
|       You may add Your own copyright statement to Your modifications and |  | ||||||
|       may provide additional or different license terms and conditions |  | ||||||
|       for use, reproduction, or distribution of Your modifications, or |  | ||||||
|       for any such Derivative Works as a whole, provided Your use, |  | ||||||
|       reproduction, and distribution of the Work otherwise complies with |  | ||||||
|       the conditions stated in this License. |  | ||||||
| 
 |  | ||||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, |  | ||||||
|       any Contribution intentionally submitted for inclusion in the Work |  | ||||||
|       by You to the Licensor shall be under the terms and conditions of |  | ||||||
|       this License, without any additional terms or conditions. |  | ||||||
|       Notwithstanding the above, nothing herein shall supersede or modify |  | ||||||
|       the terms of any separate license agreement you may have executed |  | ||||||
|       with Licensor regarding such Contributions. |  | ||||||
| 
 |  | ||||||
|    6. Trademarks. This License does not grant permission to use the trade |  | ||||||
|       names, trademarks, service marks, or product names of the Licensor, |  | ||||||
|       except as required for reasonable and customary use in describing the |  | ||||||
|       origin of the Work and reproducing the content of the NOTICE file. |  | ||||||
| 
 |  | ||||||
|    7. Disclaimer of Warranty. Unless required by applicable law or |  | ||||||
|       agreed to in writing, Licensor provides the Work (and each |  | ||||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, |  | ||||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |  | ||||||
|       implied, including, without limitation, any warranties or conditions |  | ||||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |  | ||||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the |  | ||||||
|       appropriateness of using or redistributing the Work and assume any |  | ||||||
|       risks associated with Your exercise of permissions under this License. |  | ||||||
| 
 |  | ||||||
|    8. Limitation of Liability. In no event and under no legal theory, |  | ||||||
|       whether in tort (including negligence), contract, or otherwise, |  | ||||||
|       unless required by applicable law (such as deliberate and grossly |  | ||||||
|       negligent acts) or agreed to in writing, shall any Contributor be |  | ||||||
|       liable to You for damages, including any direct, indirect, special, |  | ||||||
|       incidental, or consequential damages of any character arising as a |  | ||||||
|       result of this License or out of the use or inability to use the |  | ||||||
|       Work (including but not limited to damages for loss of goodwill, |  | ||||||
|       work stoppage, computer failure or malfunction, or any and all |  | ||||||
|       other commercial damages or losses), even if such Contributor |  | ||||||
|       has been advised of the possibility of such damages. |  | ||||||
| 
 |  | ||||||
|    9. Accepting Warranty or Additional Liability. While redistributing |  | ||||||
|       the Work or Derivative Works thereof, You may choose to offer, |  | ||||||
|       and charge a fee for, acceptance of support, warranty, indemnity, |  | ||||||
|       or other liability obligations and/or rights consistent with this |  | ||||||
|       License. However, in accepting such obligations, You may act only |  | ||||||
|       on Your own behalf and on Your sole responsibility, not on behalf |  | ||||||
|       of any other Contributor, and only if You agree to indemnify, |  | ||||||
|       defend, and hold each Contributor harmless for any liability |  | ||||||
|       incurred by, or claims asserted against, such Contributor by reason |  | ||||||
|       of your accepting any such warranty or additional liability. |  | ||||||
| 
 |  | ||||||
|    END OF TERMS AND CONDITIONS |  | ||||||
| 
 |  | ||||||
|    APPENDIX: How to apply the Apache License to your work. |  | ||||||
| 
 |  | ||||||
|       To apply the Apache License to your work, attach the following |  | ||||||
|       boilerplate notice, with the fields enclosed by brackets "[]" |  | ||||||
|       replaced with your own identifying information. (Don't include |  | ||||||
|       the brackets!)  The text should be enclosed in the appropriate |  | ||||||
|       comment syntax for the file format. We also recommend that a |  | ||||||
|       file or class name and description of purpose be included on the |  | ||||||
|       same "printed page" as the copyright notice for easier |  | ||||||
|       identification within third-party archives. |  | ||||||
| 
 |  | ||||||
|    Copyright [yyyy] [name of copyright owner] |  | ||||||
| 
 |  | ||||||
|    Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|    you may not use this file except in compliance with the License. |  | ||||||
|    You may obtain a copy of the License at |  | ||||||
| 
 |  | ||||||
|        http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| 
 |  | ||||||
|    Unless required by applicable law or agreed to in writing, software |  | ||||||
|    distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|    See the License for the specific language governing permissions and |  | ||||||
|    limitations under the License. |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| SOFTWARE DISTRIBUTED WITH THRIFT: |  | ||||||
| 
 |  | ||||||
| The Apache Thrift software includes a number of subcomponents with |  | ||||||
| separate copyright notices and license terms. Your use of the source |  | ||||||
| code for the these subcomponents is subject to the terms and |  | ||||||
| conditions of the following licenses. |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| Portions of the following files are licensed under the MIT License: |  | ||||||
| 
 |  | ||||||
|   lib/erl/src/Makefile.am |  | ||||||
| 
 |  | ||||||
| Please see doc/otp-base-license.txt for the full terms of this license. |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components: |  | ||||||
| 
 |  | ||||||
| #   Copyright (c) 2007 Thomas Porschberg <thomas@randspringer.de> |  | ||||||
| # |  | ||||||
| #   Copying and distribution of this file, with or without |  | ||||||
| #   modification, are permitted in any medium without royalty provided |  | ||||||
| #   the copyright notice and this notice are preserved. |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| For the lib/nodejs/lib/thrift/json_parse.js: |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|     json_parse.js |  | ||||||
|     2015-05-02 |  | ||||||
|     Public Domain. |  | ||||||
|     NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. |  | ||||||
| 
 |  | ||||||
| */ |  | ||||||
| (By Douglas Crockford <douglas@crockford.com>) |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| For lib/cpp/src/thrift/windows/SocketPair.cpp |  | ||||||
| 
 |  | ||||||
| /* socketpair.c |  | ||||||
|  * Copyright 2007 by Nathan C. Myers <ncm@cantrip.org>; some rights reserved. |  | ||||||
|  * This code is Free Software.  It may be copied freely, in original or |  | ||||||
|  * modified form, subject only to the restrictions that (1) the author is |  | ||||||
|  * relieved from all responsibilities for any use for any purpose, and (2) |  | ||||||
|  * this copyright notice must be retained, unchanged, in its entirety.  If |  | ||||||
|  * for any reason the author might be held responsible for any consequences |  | ||||||
|  * of copying or use, license is withheld. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| For lib/py/compat/win32/stdint.h |  | ||||||
| 
 |  | ||||||
| // ISO C9x  compliant stdint.h for Microsoft Visual Studio |  | ||||||
| // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 |  | ||||||
| // |  | ||||||
| //  Copyright (c) 2006-2008 Alexander Chemeris |  | ||||||
| // |  | ||||||
| // Redistribution and use in source and binary forms, with or without |  | ||||||
| // modification, are permitted provided that the following conditions are met: |  | ||||||
| // |  | ||||||
| //   1. Redistributions of source code must retain the above copyright notice, |  | ||||||
| //      this list of conditions and the following disclaimer. |  | ||||||
| // |  | ||||||
| //   2. Redistributions in binary form must reproduce the above copyright |  | ||||||
| //      notice, this list of conditions and the following disclaimer in the |  | ||||||
| //      documentation and/or other materials provided with the distribution. |  | ||||||
| // |  | ||||||
| //   3. The name of the author may be used to endorse or promote products |  | ||||||
| //      derived from this software without specific prior written permission. |  | ||||||
| // |  | ||||||
| // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |  | ||||||
| // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |  | ||||||
| // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |  | ||||||
| // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | ||||||
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |  | ||||||
| // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |  | ||||||
| // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |  | ||||||
| // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |  | ||||||
| // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |  | ||||||
| // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
| // |  | ||||||
| /////////////////////////////////////////////////////////////////////////////// |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| -------------------------------------------------- |  | ||||||
| Codegen template in t_html_generator.h |  | ||||||
| 
 |  | ||||||
| * Bootstrap v2.0.3 |  | ||||||
| * |  | ||||||
| * Copyright 2012 Twitter, Inc |  | ||||||
| * Licensed under the Apache License v2.0 |  | ||||||
| * http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| * |  | ||||||
| * Designed and built with all the love in the world @twitter by @mdo and @fat. |  | ||||||
| 
 |  | ||||||
| --------------------------------------------------- |  | ||||||
| For t_cl_generator.cc |  | ||||||
| 
 |  | ||||||
|  * Copyright (c) 2008- Patrick Collison <patrick@collison.ie> |  | ||||||
|  * Copyright (c) 2006- Facebook |  | ||||||
| 
 |  | ||||||
| --------------------------------------------------- |  | ||||||
							
								
								
									
										5
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/NOTICE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/NOTICE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,5 +0,0 @@ | ||||||
| Apache Thrift |  | ||||||
| Copyright (C) 2006 - 2019, The Apache Software Foundation |  | ||||||
| 
 |  | ||||||
| This product includes software developed at |  | ||||||
| The Apache Software Foundation (http://www.apache.org/). |  | ||||||
|  | @ -1,180 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	UNKNOWN_APPLICATION_EXCEPTION  = 0 |  | ||||||
| 	UNKNOWN_METHOD                 = 1 |  | ||||||
| 	INVALID_MESSAGE_TYPE_EXCEPTION = 2 |  | ||||||
| 	WRONG_METHOD_NAME              = 3 |  | ||||||
| 	BAD_SEQUENCE_ID                = 4 |  | ||||||
| 	MISSING_RESULT                 = 5 |  | ||||||
| 	INTERNAL_ERROR                 = 6 |  | ||||||
| 	PROTOCOL_ERROR                 = 7 |  | ||||||
| 	INVALID_TRANSFORM              = 8 |  | ||||||
| 	INVALID_PROTOCOL               = 9 |  | ||||||
| 	UNSUPPORTED_CLIENT_TYPE        = 10 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var defaultApplicationExceptionMessage = map[int32]string{ |  | ||||||
| 	UNKNOWN_APPLICATION_EXCEPTION:  "unknown application exception", |  | ||||||
| 	UNKNOWN_METHOD:                 "unknown method", |  | ||||||
| 	INVALID_MESSAGE_TYPE_EXCEPTION: "invalid message type", |  | ||||||
| 	WRONG_METHOD_NAME:              "wrong method name", |  | ||||||
| 	BAD_SEQUENCE_ID:                "bad sequence ID", |  | ||||||
| 	MISSING_RESULT:                 "missing result", |  | ||||||
| 	INTERNAL_ERROR:                 "unknown internal error", |  | ||||||
| 	PROTOCOL_ERROR:                 "unknown protocol error", |  | ||||||
| 	INVALID_TRANSFORM:              "Invalid transform", |  | ||||||
| 	INVALID_PROTOCOL:               "Invalid protocol", |  | ||||||
| 	UNSUPPORTED_CLIENT_TYPE:        "Unsupported client type", |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Application level Thrift exception |  | ||||||
| type TApplicationException interface { |  | ||||||
| 	TException |  | ||||||
| 	TypeId() int32 |  | ||||||
| 	Read(ctx context.Context, iprot TProtocol) error |  | ||||||
| 	Write(ctx context.Context, oprot TProtocol) error |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tApplicationException struct { |  | ||||||
| 	message string |  | ||||||
| 	type_   int32 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TApplicationException = (*tApplicationException)(nil) |  | ||||||
| 
 |  | ||||||
| func (tApplicationException) TExceptionType() TExceptionType { |  | ||||||
| 	return TExceptionTypeApplication |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (e tApplicationException) Error() string { |  | ||||||
| 	if e.message != "" { |  | ||||||
| 		return e.message |  | ||||||
| 	} |  | ||||||
| 	return defaultApplicationExceptionMessage[e.type_] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTApplicationException(type_ int32, message string) TApplicationException { |  | ||||||
| 	return &tApplicationException{message, type_} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tApplicationException) TypeId() int32 { |  | ||||||
| 	return p.type_ |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tApplicationException) Read(ctx context.Context, iprot TProtocol) error { |  | ||||||
| 	// TODO: this should really be generated by the compiler |  | ||||||
| 	_, err := iprot.ReadStructBegin(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	message := "" |  | ||||||
| 	type_ := int32(UNKNOWN_APPLICATION_EXCEPTION) |  | ||||||
| 
 |  | ||||||
| 	for { |  | ||||||
| 		_, ttype, id, err := iprot.ReadFieldBegin(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		if ttype == STOP { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		switch id { |  | ||||||
| 		case 1: |  | ||||||
| 			if ttype == STRING { |  | ||||||
| 				if message, err = iprot.ReadString(ctx); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		case 2: |  | ||||||
| 			if ttype == I32 { |  | ||||||
| 				if type_, err = iprot.ReadI32(ctx); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 			if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if err = iprot.ReadFieldEnd(ctx); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := iprot.ReadStructEnd(ctx); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	p.message = message |  | ||||||
| 	p.type_ = type_ |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tApplicationException) Write(ctx context.Context, oprot TProtocol) (err error) { |  | ||||||
| 	err = oprot.WriteStructBegin(ctx, "TApplicationException") |  | ||||||
| 	if len(p.Error()) > 0 { |  | ||||||
| 		err = oprot.WriteFieldBegin(ctx, "message", STRING, 1) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		err = oprot.WriteString(ctx, p.Error()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		err = oprot.WriteFieldEnd(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	err = oprot.WriteFieldBegin(ctx, "type", I32, 2) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	err = oprot.WriteI32(ctx, p.type_) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	err = oprot.WriteFieldEnd(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	err = oprot.WriteFieldStop(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	err = oprot.WriteStructEnd(ctx) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  | @ -1,555 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"math" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TBinaryProtocol struct { |  | ||||||
| 	trans         TRichTransport |  | ||||||
| 	origTransport TTransport |  | ||||||
| 	cfg           *TConfiguration |  | ||||||
| 	buffer        [64]byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TBinaryProtocolFactory struct { |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTBinaryProtocolConf instead. |  | ||||||
| func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol { |  | ||||||
| 	return NewTBinaryProtocolConf(t, &TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTBinaryProtocolConf instead. |  | ||||||
| func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol { |  | ||||||
| 	return NewTBinaryProtocolConf(t, &TConfiguration{ |  | ||||||
| 		TBinaryStrictRead:  &strictRead, |  | ||||||
| 		TBinaryStrictWrite: &strictWrite, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTBinaryProtocolConf(t TTransport, conf *TConfiguration) *TBinaryProtocol { |  | ||||||
| 	PropagateTConfiguration(t, conf) |  | ||||||
| 	p := &TBinaryProtocol{ |  | ||||||
| 		origTransport: t, |  | ||||||
| 		cfg:           conf, |  | ||||||
| 	} |  | ||||||
| 	if et, ok := t.(TRichTransport); ok { |  | ||||||
| 		p.trans = et |  | ||||||
| 	} else { |  | ||||||
| 		p.trans = NewTRichTransport(t) |  | ||||||
| 	} |  | ||||||
| 	return p |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTBinaryProtocolFactoryConf instead. |  | ||||||
| func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory { |  | ||||||
| 	return NewTBinaryProtocolFactoryConf(&TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTBinaryProtocolFactoryConf instead. |  | ||||||
| func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory { |  | ||||||
| 	return NewTBinaryProtocolFactoryConf(&TConfiguration{ |  | ||||||
| 		TBinaryStrictRead:  &strictRead, |  | ||||||
| 		TBinaryStrictWrite: &strictWrite, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTBinaryProtocolFactoryConf(conf *TConfiguration) *TBinaryProtocolFactory { |  | ||||||
| 	return &TBinaryProtocolFactory{ |  | ||||||
| 		cfg: conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol { |  | ||||||
| 	return NewTBinaryProtocolConf(t, p.cfg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocolFactory) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	p.cfg = conf |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Writing Methods |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error { |  | ||||||
| 	if p.cfg.GetTBinaryStrictWrite() { |  | ||||||
| 		version := uint32(VERSION_1) | uint32(typeId) |  | ||||||
| 		e := p.WriteI32(ctx, int32(version)) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return e |  | ||||||
| 		} |  | ||||||
| 		e = p.WriteString(ctx, name) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return e |  | ||||||
| 		} |  | ||||||
| 		e = p.WriteI32(ctx, seqId) |  | ||||||
| 		return e |  | ||||||
| 	} else { |  | ||||||
| 		e := p.WriteString(ctx, name) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return e |  | ||||||
| 		} |  | ||||||
| 		e = p.WriteByte(ctx, int8(typeId)) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return e |  | ||||||
| 		} |  | ||||||
| 		e = p.WriteI32(ctx, seqId) |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteMessageEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteStructBegin(ctx context.Context, name string) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteStructEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { |  | ||||||
| 	e := p.WriteByte(ctx, int8(typeId)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	e = p.WriteI16(ctx, id) |  | ||||||
| 	return e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteFieldEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteFieldStop(ctx context.Context) error { |  | ||||||
| 	e := p.WriteByte(ctx, STOP) |  | ||||||
| 	return e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { |  | ||||||
| 	e := p.WriteByte(ctx, int8(keyType)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	e = p.WriteByte(ctx, int8(valueType)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	e = p.WriteI32(ctx, int32(size)) |  | ||||||
| 	return e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteMapEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	e := p.WriteByte(ctx, int8(elemType)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	e = p.WriteI32(ctx, int32(size)) |  | ||||||
| 	return e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteListEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	e := p.WriteByte(ctx, int8(elemType)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	e = p.WriteI32(ctx, int32(size)) |  | ||||||
| 	return e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteSetEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteBool(ctx context.Context, value bool) error { |  | ||||||
| 	if value { |  | ||||||
| 		return p.WriteByte(ctx, 1) |  | ||||||
| 	} |  | ||||||
| 	return p.WriteByte(ctx, 0) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteByte(ctx context.Context, value int8) error { |  | ||||||
| 	e := p.trans.WriteByte(byte(value)) |  | ||||||
| 	return NewTProtocolException(e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteI16(ctx context.Context, value int16) error { |  | ||||||
| 	v := p.buffer[0:2] |  | ||||||
| 	binary.BigEndian.PutUint16(v, uint16(value)) |  | ||||||
| 	_, e := p.trans.Write(v) |  | ||||||
| 	return NewTProtocolException(e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteI32(ctx context.Context, value int32) error { |  | ||||||
| 	v := p.buffer[0:4] |  | ||||||
| 	binary.BigEndian.PutUint32(v, uint32(value)) |  | ||||||
| 	_, e := p.trans.Write(v) |  | ||||||
| 	return NewTProtocolException(e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteI64(ctx context.Context, value int64) error { |  | ||||||
| 	v := p.buffer[0:8] |  | ||||||
| 	binary.BigEndian.PutUint64(v, uint64(value)) |  | ||||||
| 	_, err := p.trans.Write(v) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteDouble(ctx context.Context, value float64) error { |  | ||||||
| 	return p.WriteI64(ctx, int64(math.Float64bits(value))) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteString(ctx context.Context, value string) error { |  | ||||||
| 	e := p.WriteI32(ctx, int32(len(value))) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	_, err := p.trans.WriteString(value) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) WriteBinary(ctx context.Context, value []byte) error { |  | ||||||
| 	e := p.WriteI32(ctx, int32(len(value))) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	_, err := p.trans.Write(value) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Reading methods |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { |  | ||||||
| 	size, e := p.ReadI32(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return "", typeId, 0, NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	if size < 0 { |  | ||||||
| 		typeId = TMessageType(size & 0x0ff) |  | ||||||
| 		version := int64(int64(size) & VERSION_MASK) |  | ||||||
| 		if version != VERSION_1 { |  | ||||||
| 			return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin")) |  | ||||||
| 		} |  | ||||||
| 		name, e = p.ReadString(ctx) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return name, typeId, seqId, NewTProtocolException(e) |  | ||||||
| 		} |  | ||||||
| 		seqId, e = p.ReadI32(ctx) |  | ||||||
| 		if e != nil { |  | ||||||
| 			return name, typeId, seqId, NewTProtocolException(e) |  | ||||||
| 		} |  | ||||||
| 		return name, typeId, seqId, nil |  | ||||||
| 	} |  | ||||||
| 	if p.cfg.GetTBinaryStrictRead() { |  | ||||||
| 		return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Missing version in ReadMessageBegin")) |  | ||||||
| 	} |  | ||||||
| 	name, e2 := p.readStringBody(size) |  | ||||||
| 	if e2 != nil { |  | ||||||
| 		return name, typeId, seqId, e2 |  | ||||||
| 	} |  | ||||||
| 	b, e3 := p.ReadByte(ctx) |  | ||||||
| 	if e3 != nil { |  | ||||||
| 		return name, typeId, seqId, e3 |  | ||||||
| 	} |  | ||||||
| 	typeId = TMessageType(b) |  | ||||||
| 	seqId, e4 := p.ReadI32(ctx) |  | ||||||
| 	if e4 != nil { |  | ||||||
| 		return name, typeId, seqId, e4 |  | ||||||
| 	} |  | ||||||
| 	return name, typeId, seqId, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadMessageEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadStructEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, seqId int16, err error) { |  | ||||||
| 	t, err := p.ReadByte(ctx) |  | ||||||
| 	typeId = TType(t) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return name, typeId, seqId, err |  | ||||||
| 	} |  | ||||||
| 	if t != STOP { |  | ||||||
| 		seqId, err = p.ReadI16(ctx) |  | ||||||
| 	} |  | ||||||
| 	return name, typeId, seqId, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadFieldEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var invalidDataLength = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Invalid data length")) |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadMapBegin(ctx context.Context) (kType, vType TType, size int, err error) { |  | ||||||
| 	k, e := p.ReadByte(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	kType = TType(k) |  | ||||||
| 	v, e := p.ReadByte(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	vType = TType(v) |  | ||||||
| 	size32, e := p.ReadI32(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if size32 < 0 { |  | ||||||
| 		err = invalidDataLength |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	size = int(size32) |  | ||||||
| 	return kType, vType, size, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadMapEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	b, e := p.ReadByte(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	elemType = TType(b) |  | ||||||
| 	size32, e := p.ReadI32(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if size32 < 0 { |  | ||||||
| 		err = invalidDataLength |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	size = int(size32) |  | ||||||
| 
 |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadListEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	b, e := p.ReadByte(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	elemType = TType(b) |  | ||||||
| 	size32, e := p.ReadI32(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if size32 < 0 { |  | ||||||
| 		err = invalidDataLength |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	size = int(size32) |  | ||||||
| 	return elemType, size, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadSetEnd(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadBool(ctx context.Context) (bool, error) { |  | ||||||
| 	b, e := p.ReadByte(ctx) |  | ||||||
| 	v := true |  | ||||||
| 	if b != 1 { |  | ||||||
| 		v = false |  | ||||||
| 	} |  | ||||||
| 	return v, e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadByte(ctx context.Context) (int8, error) { |  | ||||||
| 	v, err := p.trans.ReadByte() |  | ||||||
| 	return int8(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadI16(ctx context.Context) (value int16, err error) { |  | ||||||
| 	buf := p.buffer[0:2] |  | ||||||
| 	err = p.readAll(ctx, buf) |  | ||||||
| 	value = int16(binary.BigEndian.Uint16(buf)) |  | ||||||
| 	return value, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadI32(ctx context.Context) (value int32, err error) { |  | ||||||
| 	buf := p.buffer[0:4] |  | ||||||
| 	err = p.readAll(ctx, buf) |  | ||||||
| 	value = int32(binary.BigEndian.Uint32(buf)) |  | ||||||
| 	return value, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadI64(ctx context.Context) (value int64, err error) { |  | ||||||
| 	buf := p.buffer[0:8] |  | ||||||
| 	err = p.readAll(ctx, buf) |  | ||||||
| 	value = int64(binary.BigEndian.Uint64(buf)) |  | ||||||
| 	return value, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadDouble(ctx context.Context) (value float64, err error) { |  | ||||||
| 	buf := p.buffer[0:8] |  | ||||||
| 	err = p.readAll(ctx, buf) |  | ||||||
| 	value = math.Float64frombits(binary.BigEndian.Uint64(buf)) |  | ||||||
| 	return value, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadString(ctx context.Context) (value string, err error) { |  | ||||||
| 	size, e := p.ReadI32(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return "", e |  | ||||||
| 	} |  | ||||||
| 	err = checkSizeForProtocol(size, p.cfg) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if size < 0 { |  | ||||||
| 		err = invalidDataLength |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if size == 0 { |  | ||||||
| 		return "", nil |  | ||||||
| 	} |  | ||||||
| 	if size < int32(len(p.buffer)) { |  | ||||||
| 		// Avoid allocation on small reads |  | ||||||
| 		buf := p.buffer[:size] |  | ||||||
| 		read, e := io.ReadFull(p.trans, buf) |  | ||||||
| 		return string(buf[:read]), NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return p.readStringBody(size) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) ReadBinary(ctx context.Context) ([]byte, error) { |  | ||||||
| 	size, e := p.ReadI32(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return nil, e |  | ||||||
| 	} |  | ||||||
| 	if err := checkSizeForProtocol(size, p.cfg); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	buf, err := safeReadBytes(size, p.trans) |  | ||||||
| 	return buf, NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) Flush(ctx context.Context) (err error) { |  | ||||||
| 	return NewTProtocolException(p.trans.Flush(ctx)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) Skip(ctx context.Context, fieldType TType) (err error) { |  | ||||||
| 	return SkipDefaultDepth(ctx, p, fieldType) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) Transport() TTransport { |  | ||||||
| 	return p.origTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) readAll(ctx context.Context, buf []byte) (err error) { |  | ||||||
| 	var read int |  | ||||||
| 	_, deadlineSet := ctx.Deadline() |  | ||||||
| 	for { |  | ||||||
| 		read, err = io.ReadFull(p.trans, buf) |  | ||||||
| 		if deadlineSet && read == 0 && isTimeoutError(err) && ctx.Err() == nil { |  | ||||||
| 			// This is I/O timeout without anything read, |  | ||||||
| 			// and we still have time left, keep retrying. |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		// For anything else, don't retry |  | ||||||
| 		break |  | ||||||
| 	} |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) { |  | ||||||
| 	buf, err := safeReadBytes(size, p.trans) |  | ||||||
| 	return string(buf), NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBinaryProtocol) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.trans, conf) |  | ||||||
| 	PropagateTConfiguration(p.origTransport, conf) |  | ||||||
| 	p.cfg = conf |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	_ TConfigurationSetter = (*TBinaryProtocolFactory)(nil) |  | ||||||
| 	_ TConfigurationSetter = (*TBinaryProtocol)(nil) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // This function is shared between TBinaryProtocol and TCompactProtocol. |  | ||||||
| // |  | ||||||
| // It tries to read size bytes from trans, in a way that prevents large |  | ||||||
| // allocations when size is insanely large (mostly caused by malformed message). |  | ||||||
| func safeReadBytes(size int32, trans io.Reader) ([]byte, error) { |  | ||||||
| 	if size < 0 { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	buf := new(bytes.Buffer) |  | ||||||
| 	_, err := io.CopyN(buf, trans, int64(size)) |  | ||||||
| 	return buf.Bytes(), err |  | ||||||
| } |  | ||||||
|  | @ -1,99 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"context" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TBufferedTransportFactory struct { |  | ||||||
| 	size int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TBufferedTransport struct { |  | ||||||
| 	bufio.ReadWriter |  | ||||||
| 	tp TTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	return NewTBufferedTransport(trans, p.size), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTBufferedTransportFactory(bufferSize int) *TBufferedTransportFactory { |  | ||||||
| 	return &TBufferedTransportFactory{size: bufferSize} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTBufferedTransport(trans TTransport, bufferSize int) *TBufferedTransport { |  | ||||||
| 	return &TBufferedTransport{ |  | ||||||
| 		ReadWriter: bufio.ReadWriter{ |  | ||||||
| 			Reader: bufio.NewReaderSize(trans, bufferSize), |  | ||||||
| 			Writer: bufio.NewWriterSize(trans, bufferSize), |  | ||||||
| 		}, |  | ||||||
| 		tp: trans, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) IsOpen() bool { |  | ||||||
| 	return p.tp.IsOpen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) Open() (err error) { |  | ||||||
| 	return p.tp.Open() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) Close() (err error) { |  | ||||||
| 	return p.tp.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) Read(b []byte) (int, error) { |  | ||||||
| 	n, err := p.ReadWriter.Read(b) |  | ||||||
| 	if err != nil { |  | ||||||
| 		p.ReadWriter.Reader.Reset(p.tp) |  | ||||||
| 	} |  | ||||||
| 	return n, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) Write(b []byte) (int, error) { |  | ||||||
| 	n, err := p.ReadWriter.Write(b) |  | ||||||
| 	if err != nil { |  | ||||||
| 		p.ReadWriter.Writer.Reset(p.tp) |  | ||||||
| 	} |  | ||||||
| 	return n, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) Flush(ctx context.Context) error { |  | ||||||
| 	if err := p.ReadWriter.Flush(); err != nil { |  | ||||||
| 		p.ReadWriter.Writer.Reset(p.tp) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return p.tp.Flush(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	return p.tp.RemainingBytes() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter for propagation. |  | ||||||
| func (p *TBufferedTransport) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.tp, conf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*TBufferedTransport)(nil) |  | ||||||
|  | @ -1,109 +0,0 @@ | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // ResponseMeta represents the metadata attached to the response. |  | ||||||
| type ResponseMeta struct { |  | ||||||
| 	// The headers in the response, if any. |  | ||||||
| 	// If the underlying transport/protocol is not THeader, this will always be nil. |  | ||||||
| 	Headers THeaderMap |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TClient interface { |  | ||||||
| 	Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TStandardClient struct { |  | ||||||
| 	seqId        int32 |  | ||||||
| 	iprot, oprot TProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TStandardClient implements TClient, and uses the standard message format for Thrift. |  | ||||||
| // It is not safe for concurrent use. |  | ||||||
| func NewTStandardClient(inputProtocol, outputProtocol TProtocol) *TStandardClient { |  | ||||||
| 	return &TStandardClient{ |  | ||||||
| 		iprot: inputProtocol, |  | ||||||
| 		oprot: outputProtocol, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TStandardClient) Send(ctx context.Context, oprot TProtocol, seqId int32, method string, args TStruct) error { |  | ||||||
| 	// Set headers from context object on THeaderProtocol |  | ||||||
| 	if headerProt, ok := oprot.(*THeaderProtocol); ok { |  | ||||||
| 		headerProt.ClearWriteHeaders() |  | ||||||
| 		for _, key := range GetWriteHeaderList(ctx) { |  | ||||||
| 			if value, ok := GetHeader(ctx, key); ok { |  | ||||||
| 				headerProt.SetWriteHeader(key, value) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := oprot.WriteMessageBegin(ctx, method, CALL, seqId); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if err := args.Write(ctx, oprot); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if err := oprot.WriteMessageEnd(ctx); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return oprot.Flush(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TStandardClient) Recv(ctx context.Context, iprot TProtocol, seqId int32, method string, result TStruct) error { |  | ||||||
| 	rMethod, rTypeId, rSeqId, err := iprot.ReadMessageBegin(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if method != rMethod { |  | ||||||
| 		return NewTApplicationException(WRONG_METHOD_NAME, fmt.Sprintf("%s: wrong method name", method)) |  | ||||||
| 	} else if seqId != rSeqId { |  | ||||||
| 		return NewTApplicationException(BAD_SEQUENCE_ID, fmt.Sprintf("%s: out of order sequence response", method)) |  | ||||||
| 	} else if rTypeId == EXCEPTION { |  | ||||||
| 		var exception tApplicationException |  | ||||||
| 		if err := exception.Read(ctx, iprot); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if err := iprot.ReadMessageEnd(ctx); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return &exception |  | ||||||
| 	} else if rTypeId != REPLY { |  | ||||||
| 		return NewTApplicationException(INVALID_MESSAGE_TYPE_EXCEPTION, fmt.Sprintf("%s: invalid message type", method)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := result.Read(ctx, iprot); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return iprot.ReadMessageEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { |  | ||||||
| 	p.seqId++ |  | ||||||
| 	seqId := p.seqId |  | ||||||
| 
 |  | ||||||
| 	if err := p.Send(ctx, p.oprot, seqId, method, args); err != nil { |  | ||||||
| 		return ResponseMeta{}, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// method is oneway |  | ||||||
| 	if result == nil { |  | ||||||
| 		return ResponseMeta{}, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	err := p.Recv(ctx, p.iprot, seqId, method, result) |  | ||||||
| 	var headers THeaderMap |  | ||||||
| 	if hp, ok := p.iprot.(*THeaderProtocol); ok { |  | ||||||
| 		headers = hp.transport.readHeaders |  | ||||||
| 	} |  | ||||||
| 	return ResponseMeta{ |  | ||||||
| 		Headers: headers, |  | ||||||
| 	}, err |  | ||||||
| } |  | ||||||
|  | @ -1,865 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"math" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	COMPACT_PROTOCOL_ID       = 0x082 |  | ||||||
| 	COMPACT_VERSION           = 1 |  | ||||||
| 	COMPACT_VERSION_MASK      = 0x1f |  | ||||||
| 	COMPACT_TYPE_MASK         = 0x0E0 |  | ||||||
| 	COMPACT_TYPE_BITS         = 0x07 |  | ||||||
| 	COMPACT_TYPE_SHIFT_AMOUNT = 5 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type tCompactType byte |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	COMPACT_BOOLEAN_TRUE  = 0x01 |  | ||||||
| 	COMPACT_BOOLEAN_FALSE = 0x02 |  | ||||||
| 	COMPACT_BYTE          = 0x03 |  | ||||||
| 	COMPACT_I16           = 0x04 |  | ||||||
| 	COMPACT_I32           = 0x05 |  | ||||||
| 	COMPACT_I64           = 0x06 |  | ||||||
| 	COMPACT_DOUBLE        = 0x07 |  | ||||||
| 	COMPACT_BINARY        = 0x08 |  | ||||||
| 	COMPACT_LIST          = 0x09 |  | ||||||
| 	COMPACT_SET           = 0x0A |  | ||||||
| 	COMPACT_MAP           = 0x0B |  | ||||||
| 	COMPACT_STRUCT        = 0x0C |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	ttypeToCompactType map[TType]tCompactType |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| 	ttypeToCompactType = map[TType]tCompactType{ |  | ||||||
| 		STOP:   STOP, |  | ||||||
| 		BOOL:   COMPACT_BOOLEAN_TRUE, |  | ||||||
| 		BYTE:   COMPACT_BYTE, |  | ||||||
| 		I16:    COMPACT_I16, |  | ||||||
| 		I32:    COMPACT_I32, |  | ||||||
| 		I64:    COMPACT_I64, |  | ||||||
| 		DOUBLE: COMPACT_DOUBLE, |  | ||||||
| 		STRING: COMPACT_BINARY, |  | ||||||
| 		LIST:   COMPACT_LIST, |  | ||||||
| 		SET:    COMPACT_SET, |  | ||||||
| 		MAP:    COMPACT_MAP, |  | ||||||
| 		STRUCT: COMPACT_STRUCT, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TCompactProtocolFactory struct { |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTCompactProtocolFactoryConf instead. |  | ||||||
| func NewTCompactProtocolFactory() *TCompactProtocolFactory { |  | ||||||
| 	return NewTCompactProtocolFactoryConf(&TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTCompactProtocolFactoryConf(conf *TConfiguration) *TCompactProtocolFactory { |  | ||||||
| 	return &TCompactProtocolFactory{ |  | ||||||
| 		cfg: conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol { |  | ||||||
| 	return NewTCompactProtocolConf(trans, p.cfg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocolFactory) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	p.cfg = conf |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TCompactProtocol struct { |  | ||||||
| 	trans         TRichTransport |  | ||||||
| 	origTransport TTransport |  | ||||||
| 
 |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| 
 |  | ||||||
| 	// Used to keep track of the last field for the current and previous structs, |  | ||||||
| 	// so we can do the delta stuff. |  | ||||||
| 	lastField   []int |  | ||||||
| 	lastFieldId int |  | ||||||
| 
 |  | ||||||
| 	// If we encounter a boolean field begin, save the TField here so it can |  | ||||||
| 	// have the value incorporated. |  | ||||||
| 	booleanFieldName    string |  | ||||||
| 	booleanFieldId      int16 |  | ||||||
| 	booleanFieldPending bool |  | ||||||
| 
 |  | ||||||
| 	// If we read a field header, and it's a boolean field, save the boolean |  | ||||||
| 	// value here so that readBool can use it. |  | ||||||
| 	boolValue          bool |  | ||||||
| 	boolValueIsNotNull bool |  | ||||||
| 	buffer             [64]byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTCompactProtocolConf instead. |  | ||||||
| func NewTCompactProtocol(trans TTransport) *TCompactProtocol { |  | ||||||
| 	return NewTCompactProtocolConf(trans, &TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTCompactProtocolConf(trans TTransport, conf *TConfiguration) *TCompactProtocol { |  | ||||||
| 	PropagateTConfiguration(trans, conf) |  | ||||||
| 	p := &TCompactProtocol{ |  | ||||||
| 		origTransport: trans, |  | ||||||
| 		cfg:           conf, |  | ||||||
| 	} |  | ||||||
| 	if et, ok := trans.(TRichTransport); ok { |  | ||||||
| 		p.trans = et |  | ||||||
| 	} else { |  | ||||||
| 		p.trans = NewTRichTransport(trans) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return p |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // |  | ||||||
| // Public Writing methods. |  | ||||||
| // |  | ||||||
| 
 |  | ||||||
| // Write a message header to the wire. Compact Protocol messages contain the |  | ||||||
| // protocol version so we can migrate forwards in the future if need be. |  | ||||||
| func (p *TCompactProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { |  | ||||||
| 	err := p.writeByteDirect(COMPACT_PROTOCOL_ID) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	_, err = p.writeVarint32(seqid) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	e := p.WriteString(ctx, name) |  | ||||||
| 	return e |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteMessageEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Write a struct begin. This doesn't actually put anything on the wire. We |  | ||||||
| // use it as an opportunity to put special placeholder markers on the field |  | ||||||
| // stack so we can get the field id deltas correct. |  | ||||||
| func (p *TCompactProtocol) WriteStructBegin(ctx context.Context, name string) error { |  | ||||||
| 	p.lastField = append(p.lastField, p.lastFieldId) |  | ||||||
| 	p.lastFieldId = 0 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write a struct end. This doesn't actually put anything on the wire. We use |  | ||||||
| // this as an opportunity to pop the last field from the current struct off |  | ||||||
| // of the field stack. |  | ||||||
| func (p *TCompactProtocol) WriteStructEnd(ctx context.Context) error { |  | ||||||
| 	if len(p.lastField) <= 0 { |  | ||||||
| 		return NewTProtocolExceptionWithType(INVALID_DATA, errors.New("WriteStructEnd called without matching WriteStructBegin call before")) |  | ||||||
| 	} |  | ||||||
| 	p.lastFieldId = p.lastField[len(p.lastField)-1] |  | ||||||
| 	p.lastField = p.lastField[:len(p.lastField)-1] |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { |  | ||||||
| 	if typeId == BOOL { |  | ||||||
| 		// we want to possibly include the value, so we'll wait. |  | ||||||
| 		p.booleanFieldName, p.booleanFieldId, p.booleanFieldPending = name, id, true |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	_, err := p.writeFieldBeginInternal(ctx, name, typeId, id, 0xFF) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // The workhorse of writeFieldBegin. It has the option of doing a |  | ||||||
| // 'type override' of the type header. This is used specifically in the |  | ||||||
| // boolean field case. |  | ||||||
| func (p *TCompactProtocol) writeFieldBeginInternal(ctx context.Context, name string, typeId TType, id int16, typeOverride byte) (int, error) { |  | ||||||
| 	// short lastField = lastField_.pop(); |  | ||||||
| 
 |  | ||||||
| 	// if there's a type override, use that. |  | ||||||
| 	var typeToWrite byte |  | ||||||
| 	if typeOverride == 0xFF { |  | ||||||
| 		typeToWrite = byte(p.getCompactType(typeId)) |  | ||||||
| 	} else { |  | ||||||
| 		typeToWrite = typeOverride |  | ||||||
| 	} |  | ||||||
| 	// check if we can use delta encoding for the field id |  | ||||||
| 	fieldId := int(id) |  | ||||||
| 	written := 0 |  | ||||||
| 	if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 { |  | ||||||
| 		// write them together |  | ||||||
| 		err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		// write them separate |  | ||||||
| 		err := p.writeByteDirect(typeToWrite) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		err = p.WriteI16(ctx, id) |  | ||||||
| 		written = 1 + 2 |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	p.lastFieldId = fieldId |  | ||||||
| 	return written, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteFieldEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteFieldStop(ctx context.Context) error { |  | ||||||
| 	err := p.writeByteDirect(STOP) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { |  | ||||||
| 	if size == 0 { |  | ||||||
| 		err := p.writeByteDirect(0) |  | ||||||
| 		return NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	_, err := p.writeVarint32(int32(size)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType))) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteMapEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Write a list header. |  | ||||||
| func (p *TCompactProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	_, err := p.writeCollectionBegin(elemType, size) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteListEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Write a set header. |  | ||||||
| func (p *TCompactProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	_, err := p.writeCollectionBegin(elemType, size) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteSetEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) WriteBool(ctx context.Context, value bool) error { |  | ||||||
| 	v := byte(COMPACT_BOOLEAN_FALSE) |  | ||||||
| 	if value { |  | ||||||
| 		v = byte(COMPACT_BOOLEAN_TRUE) |  | ||||||
| 	} |  | ||||||
| 	if p.booleanFieldPending { |  | ||||||
| 		// we haven't written the field header yet |  | ||||||
| 		_, err := p.writeFieldBeginInternal(ctx, p.booleanFieldName, BOOL, p.booleanFieldId, v) |  | ||||||
| 		p.booleanFieldPending = false |  | ||||||
| 		return NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	// we're not part of a field, so just write the value. |  | ||||||
| 	err := p.writeByteDirect(v) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write a byte. Nothing to see here! |  | ||||||
| func (p *TCompactProtocol) WriteByte(ctx context.Context, value int8) error { |  | ||||||
| 	err := p.writeByteDirect(byte(value)) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write an I16 as a zigzag varint. |  | ||||||
| func (p *TCompactProtocol) WriteI16(ctx context.Context, value int16) error { |  | ||||||
| 	_, err := p.writeVarint32(p.int32ToZigzag(int32(value))) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write an i32 as a zigzag varint. |  | ||||||
| func (p *TCompactProtocol) WriteI32(ctx context.Context, value int32) error { |  | ||||||
| 	_, err := p.writeVarint32(p.int32ToZigzag(value)) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write an i64 as a zigzag varint. |  | ||||||
| func (p *TCompactProtocol) WriteI64(ctx context.Context, value int64) error { |  | ||||||
| 	_, err := p.writeVarint64(p.int64ToZigzag(value)) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write a double to the wire as 8 bytes. |  | ||||||
| func (p *TCompactProtocol) WriteDouble(ctx context.Context, value float64) error { |  | ||||||
| 	buf := p.buffer[0:8] |  | ||||||
| 	binary.LittleEndian.PutUint64(buf, math.Float64bits(value)) |  | ||||||
| 	_, err := p.trans.Write(buf) |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write a string to the wire with a varint size preceding. |  | ||||||
| func (p *TCompactProtocol) WriteString(ctx context.Context, value string) error { |  | ||||||
| 	_, e := p.writeVarint32(int32(len(value))) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	if len(value) > 0 { |  | ||||||
| 	} |  | ||||||
| 	_, e = p.trans.WriteString(value) |  | ||||||
| 	return e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write a byte array, using a varint for the size. |  | ||||||
| func (p *TCompactProtocol) WriteBinary(ctx context.Context, bin []byte) error { |  | ||||||
| 	_, e := p.writeVarint32(int32(len(bin))) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	if len(bin) > 0 { |  | ||||||
| 		_, e = p.trans.Write(bin) |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // |  | ||||||
| // Reading methods. |  | ||||||
| // |  | ||||||
| 
 |  | ||||||
| // Read a message header. |  | ||||||
| func (p *TCompactProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { |  | ||||||
| 	var protocolId byte |  | ||||||
| 
 |  | ||||||
| 	_, deadlineSet := ctx.Deadline() |  | ||||||
| 	for { |  | ||||||
| 		protocolId, err = p.readByteDirect() |  | ||||||
| 		if deadlineSet && isTimeoutError(err) && ctx.Err() == nil { |  | ||||||
| 			// keep retrying I/O timeout errors since we still have |  | ||||||
| 			// time left |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		// For anything else, don't retry |  | ||||||
| 		break |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if protocolId != COMPACT_PROTOCOL_ID { |  | ||||||
| 		e := fmt.Errorf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId) |  | ||||||
| 		return "", typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, e) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	versionAndType, err := p.readByteDirect() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	version := versionAndType & COMPACT_VERSION_MASK |  | ||||||
| 	typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS) |  | ||||||
| 	if version != COMPACT_VERSION { |  | ||||||
| 		e := fmt.Errorf("Expected version %02x but got %02x", COMPACT_VERSION, version) |  | ||||||
| 		err = NewTProtocolExceptionWithType(BAD_VERSION, e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	seqId, e := p.readVarint32() |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	name, err = p.ReadString(ctx) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) ReadMessageEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Read a struct begin. There's nothing on the wire for this, but it is our |  | ||||||
| // opportunity to push a new struct begin marker onto the field stack. |  | ||||||
| func (p *TCompactProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { |  | ||||||
| 	p.lastField = append(p.lastField, p.lastFieldId) |  | ||||||
| 	p.lastFieldId = 0 |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Doesn't actually consume any wire data, just removes the last field for |  | ||||||
| // this struct from the field stack. |  | ||||||
| func (p *TCompactProtocol) ReadStructEnd(ctx context.Context) error { |  | ||||||
| 	// consume the last field we read off the wire. |  | ||||||
| 	if len(p.lastField) <= 0 { |  | ||||||
| 		return NewTProtocolExceptionWithType(INVALID_DATA, errors.New("ReadStructEnd called without matching ReadStructBegin call before")) |  | ||||||
| 	} |  | ||||||
| 	p.lastFieldId = p.lastField[len(p.lastField)-1] |  | ||||||
| 	p.lastField = p.lastField[:len(p.lastField)-1] |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read a field header off the wire. |  | ||||||
| func (p *TCompactProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) { |  | ||||||
| 	t, err := p.readByteDirect() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// if it's a stop, then we can return immediately, as the struct is over. |  | ||||||
| 	if (t & 0x0f) == STOP { |  | ||||||
| 		return "", STOP, 0, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// mask off the 4 MSB of the type header. it could contain a field id delta. |  | ||||||
| 	modifier := int16((t & 0xf0) >> 4) |  | ||||||
| 	if modifier == 0 { |  | ||||||
| 		// not a delta. look ahead for the zigzag varint field id. |  | ||||||
| 		id, err = p.ReadI16(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		// has a delta. add the delta to the last read field id. |  | ||||||
| 		id = int16(p.lastFieldId) + modifier |  | ||||||
| 	} |  | ||||||
| 	typeId, e := p.getTType(tCompactType(t & 0x0f)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// if this happens to be a boolean field, the value is encoded in the type |  | ||||||
| 	if p.isBoolType(t) { |  | ||||||
| 		// save the boolean value in a special instance variable. |  | ||||||
| 		p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE) |  | ||||||
| 		p.boolValueIsNotNull = true |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// push the new field onto the field stack so we can keep the deltas going. |  | ||||||
| 	p.lastFieldId = int(id) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) ReadFieldEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Read a map header off the wire. If the size is zero, skip reading the key |  | ||||||
| // and value type. This means that 0-length maps will yield TMaps without the |  | ||||||
| // "correct" types. |  | ||||||
| func (p *TCompactProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { |  | ||||||
| 	size32, e := p.readVarint32() |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if size32 < 0 { |  | ||||||
| 		err = invalidDataLength |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	size = int(size32) |  | ||||||
| 
 |  | ||||||
| 	keyAndValueType := byte(STOP) |  | ||||||
| 	if size != 0 { |  | ||||||
| 		keyAndValueType, err = p.readByteDirect() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	keyType, _ = p.getTType(tCompactType(keyAndValueType >> 4)) |  | ||||||
| 	valueType, _ = p.getTType(tCompactType(keyAndValueType & 0xf)) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) ReadMapEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Read a list header off the wire. If the list size is 0-14, the size will |  | ||||||
| // be packed into the element type header. If it's a longer list, the 4 MSB |  | ||||||
| // of the element type header will be 0xF, and a varint will follow with the |  | ||||||
| // true size. |  | ||||||
| func (p *TCompactProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	size_and_type, err := p.readByteDirect() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	size = int((size_and_type >> 4) & 0x0f) |  | ||||||
| 	if size == 15 { |  | ||||||
| 		size2, e := p.readVarint32() |  | ||||||
| 		if e != nil { |  | ||||||
| 			err = NewTProtocolException(e) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		if size2 < 0 { |  | ||||||
| 			err = invalidDataLength |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		size = int(size2) |  | ||||||
| 	} |  | ||||||
| 	elemType, e := p.getTType(tCompactType(size_and_type)) |  | ||||||
| 	if e != nil { |  | ||||||
| 		err = NewTProtocolException(e) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) ReadListEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Read a set header off the wire. If the set size is 0-14, the size will |  | ||||||
| // be packed into the element type header. If it's a longer set, the 4 MSB |  | ||||||
| // of the element type header will be 0xF, and a varint will follow with the |  | ||||||
| // true size. |  | ||||||
| func (p *TCompactProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	return p.ReadListBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) ReadSetEnd(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| // Read a boolean off the wire. If this is a boolean field, the value should |  | ||||||
| // already have been read during readFieldBegin, so we'll just consume the |  | ||||||
| // pre-stored value. Otherwise, read a byte. |  | ||||||
| func (p *TCompactProtocol) ReadBool(ctx context.Context) (value bool, err error) { |  | ||||||
| 	if p.boolValueIsNotNull { |  | ||||||
| 		p.boolValueIsNotNull = false |  | ||||||
| 		return p.boolValue, nil |  | ||||||
| 	} |  | ||||||
| 	v, err := p.readByteDirect() |  | ||||||
| 	return v == COMPACT_BOOLEAN_TRUE, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read a single byte off the wire. Nothing interesting here. |  | ||||||
| func (p *TCompactProtocol) ReadByte(ctx context.Context) (int8, error) { |  | ||||||
| 	v, err := p.readByteDirect() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	return int8(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read an i16 from the wire as a zigzag varint. |  | ||||||
| func (p *TCompactProtocol) ReadI16(ctx context.Context) (value int16, err error) { |  | ||||||
| 	v, err := p.ReadI32(ctx) |  | ||||||
| 	return int16(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read an i32 from the wire as a zigzag varint. |  | ||||||
| func (p *TCompactProtocol) ReadI32(ctx context.Context) (value int32, err error) { |  | ||||||
| 	v, e := p.readVarint32() |  | ||||||
| 	if e != nil { |  | ||||||
| 		return 0, NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	value = p.zigzagToInt32(v) |  | ||||||
| 	return value, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read an i64 from the wire as a zigzag varint. |  | ||||||
| func (p *TCompactProtocol) ReadI64(ctx context.Context) (value int64, err error) { |  | ||||||
| 	v, e := p.readVarint64() |  | ||||||
| 	if e != nil { |  | ||||||
| 		return 0, NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	value = p.zigzagToInt64(v) |  | ||||||
| 	return value, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // No magic here - just read a double off the wire. |  | ||||||
| func (p *TCompactProtocol) ReadDouble(ctx context.Context) (value float64, err error) { |  | ||||||
| 	longBits := p.buffer[0:8] |  | ||||||
| 	_, e := io.ReadFull(p.trans, longBits) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return 0.0, NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	return math.Float64frombits(p.bytesToUint64(longBits)), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Reads a []byte (via readBinary), and then UTF-8 decodes it. |  | ||||||
| func (p *TCompactProtocol) ReadString(ctx context.Context) (value string, err error) { |  | ||||||
| 	length, e := p.readVarint32() |  | ||||||
| 	if e != nil { |  | ||||||
| 		return "", NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	err = checkSizeForProtocol(length, p.cfg) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if length == 0 { |  | ||||||
| 		return "", nil |  | ||||||
| 	} |  | ||||||
| 	if length < int32(len(p.buffer)) { |  | ||||||
| 		// Avoid allocation on small reads |  | ||||||
| 		buf := p.buffer[:length] |  | ||||||
| 		read, e := io.ReadFull(p.trans, buf) |  | ||||||
| 		return string(buf[:read]), NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	buf, e := safeReadBytes(length, p.trans) |  | ||||||
| 	return string(buf), NewTProtocolException(e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read a []byte from the wire. |  | ||||||
| func (p *TCompactProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { |  | ||||||
| 	length, e := p.readVarint32() |  | ||||||
| 	if e != nil { |  | ||||||
| 		return nil, NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	err = checkSizeForProtocol(length, p.cfg) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if length == 0 { |  | ||||||
| 		return []byte{}, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	buf, e := safeReadBytes(length, p.trans) |  | ||||||
| 	return buf, NewTProtocolException(e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) Flush(ctx context.Context) (err error) { |  | ||||||
| 	return NewTProtocolException(p.trans.Flush(ctx)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) Skip(ctx context.Context, fieldType TType) (err error) { |  | ||||||
| 	return SkipDefaultDepth(ctx, p, fieldType) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) Transport() TTransport { |  | ||||||
| 	return p.origTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // |  | ||||||
| // Internal writing methods |  | ||||||
| // |  | ||||||
| 
 |  | ||||||
| // Abstract method for writing the start of lists and sets. List and sets on |  | ||||||
| // the wire differ only by the type indicator. |  | ||||||
| func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, error) { |  | ||||||
| 	if size <= 14 { |  | ||||||
| 		return 1, p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType)))) |  | ||||||
| 	} |  | ||||||
| 	err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType))) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	m, err := p.writeVarint32(int32(size)) |  | ||||||
| 	return 1 + m, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write an i32 as a varint. Results in 1-5 bytes on the wire. |  | ||||||
| // TODO(pomack): make a permanent buffer like writeVarint64? |  | ||||||
| func (p *TCompactProtocol) writeVarint32(n int32) (int, error) { |  | ||||||
| 	i32buf := p.buffer[0:5] |  | ||||||
| 	idx := 0 |  | ||||||
| 	for { |  | ||||||
| 		if (n & ^0x7F) == 0 { |  | ||||||
| 			i32buf[idx] = byte(n) |  | ||||||
| 			idx++ |  | ||||||
| 			// p.writeByteDirect(byte(n)); |  | ||||||
| 			break |  | ||||||
| 			// return; |  | ||||||
| 		} else { |  | ||||||
| 			i32buf[idx] = byte((n & 0x7F) | 0x80) |  | ||||||
| 			idx++ |  | ||||||
| 			// p.writeByteDirect(byte(((n & 0x7F) | 0x80))); |  | ||||||
| 			u := uint32(n) |  | ||||||
| 			n = int32(u >> 7) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return p.trans.Write(i32buf[0:idx]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write an i64 as a varint. Results in 1-10 bytes on the wire. |  | ||||||
| func (p *TCompactProtocol) writeVarint64(n int64) (int, error) { |  | ||||||
| 	varint64out := p.buffer[0:10] |  | ||||||
| 	idx := 0 |  | ||||||
| 	for { |  | ||||||
| 		if (n & ^0x7F) == 0 { |  | ||||||
| 			varint64out[idx] = byte(n) |  | ||||||
| 			idx++ |  | ||||||
| 			break |  | ||||||
| 		} else { |  | ||||||
| 			varint64out[idx] = byte((n & 0x7F) | 0x80) |  | ||||||
| 			idx++ |  | ||||||
| 			u := uint64(n) |  | ||||||
| 			n = int64(u >> 7) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return p.trans.Write(varint64out[0:idx]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Convert l into a zigzag long. This allows negative numbers to be |  | ||||||
| // represented compactly as a varint. |  | ||||||
| func (p *TCompactProtocol) int64ToZigzag(l int64) int64 { |  | ||||||
| 	return (l << 1) ^ (l >> 63) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Convert l into a zigzag long. This allows negative numbers to be |  | ||||||
| // represented compactly as a varint. |  | ||||||
| func (p *TCompactProtocol) int32ToZigzag(n int32) int32 { |  | ||||||
| 	return (n << 1) ^ (n >> 31) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) { |  | ||||||
| 	binary.LittleEndian.PutUint64(buf, n) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) { |  | ||||||
| 	binary.LittleEndian.PutUint64(buf, uint64(n)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Writes a byte without any possibility of all that field header nonsense. |  | ||||||
| // Used internally by other writing methods that know they need to write a byte. |  | ||||||
| func (p *TCompactProtocol) writeByteDirect(b byte) error { |  | ||||||
| 	return p.trans.WriteByte(b) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Writes a byte without any possibility of all that field header nonsense. |  | ||||||
| func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, error) { |  | ||||||
| 	return 1, p.writeByteDirect(byte(n)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // |  | ||||||
| // Internal reading methods |  | ||||||
| // |  | ||||||
| 
 |  | ||||||
| // Read an i32 from the wire as a varint. The MSB of each byte is set |  | ||||||
| // if there is another byte to follow. This can read up to 5 bytes. |  | ||||||
| func (p *TCompactProtocol) readVarint32() (int32, error) { |  | ||||||
| 	// if the wire contains the right stuff, this will just truncate the i64 we |  | ||||||
| 	// read and get us the right sign. |  | ||||||
| 	v, err := p.readVarint64() |  | ||||||
| 	return int32(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read an i64 from the wire as a proper varint. The MSB of each byte is set |  | ||||||
| // if there is another byte to follow. This can read up to 10 bytes. |  | ||||||
| func (p *TCompactProtocol) readVarint64() (int64, error) { |  | ||||||
| 	shift := uint(0) |  | ||||||
| 	result := int64(0) |  | ||||||
| 	for { |  | ||||||
| 		b, err := p.readByteDirect() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		result |= int64(b&0x7f) << shift |  | ||||||
| 		if (b & 0x80) != 0x80 { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		shift += 7 |  | ||||||
| 	} |  | ||||||
| 	return result, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read a byte, unlike ReadByte that reads Thrift-byte that is i8. |  | ||||||
| func (p *TCompactProtocol) readByteDirect() (byte, error) { |  | ||||||
| 	return p.trans.ReadByte() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // |  | ||||||
| // encoding helpers |  | ||||||
| // |  | ||||||
| 
 |  | ||||||
| // Convert from zigzag int to int. |  | ||||||
| func (p *TCompactProtocol) zigzagToInt32(n int32) int32 { |  | ||||||
| 	u := uint32(n) |  | ||||||
| 	return int32(u>>1) ^ -(n & 1) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Convert from zigzag long to long. |  | ||||||
| func (p *TCompactProtocol) zigzagToInt64(n int64) int64 { |  | ||||||
| 	u := uint64(n) |  | ||||||
| 	return int64(u>>1) ^ -(n & 1) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Note that it's important that the mask bytes are long literals, |  | ||||||
| // otherwise they'll default to ints, and when you shift an int left 56 bits, |  | ||||||
| // you just get a messed up int. |  | ||||||
| func (p *TCompactProtocol) bytesToInt64(b []byte) int64 { |  | ||||||
| 	return int64(binary.LittleEndian.Uint64(b)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Note that it's important that the mask bytes are long literals, |  | ||||||
| // otherwise they'll default to ints, and when you shift an int left 56 bits, |  | ||||||
| // you just get a messed up int. |  | ||||||
| func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 { |  | ||||||
| 	return binary.LittleEndian.Uint64(b) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // |  | ||||||
| // type testing and converting |  | ||||||
| // |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) isBoolType(b byte) bool { |  | ||||||
| 	return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Given a tCompactType constant, convert it to its corresponding |  | ||||||
| // TType value. |  | ||||||
| func (p *TCompactProtocol) getTType(t tCompactType) (TType, error) { |  | ||||||
| 	switch byte(t) & 0x0f { |  | ||||||
| 	case STOP: |  | ||||||
| 		return STOP, nil |  | ||||||
| 	case COMPACT_BOOLEAN_FALSE, COMPACT_BOOLEAN_TRUE: |  | ||||||
| 		return BOOL, nil |  | ||||||
| 	case COMPACT_BYTE: |  | ||||||
| 		return BYTE, nil |  | ||||||
| 	case COMPACT_I16: |  | ||||||
| 		return I16, nil |  | ||||||
| 	case COMPACT_I32: |  | ||||||
| 		return I32, nil |  | ||||||
| 	case COMPACT_I64: |  | ||||||
| 		return I64, nil |  | ||||||
| 	case COMPACT_DOUBLE: |  | ||||||
| 		return DOUBLE, nil |  | ||||||
| 	case COMPACT_BINARY: |  | ||||||
| 		return STRING, nil |  | ||||||
| 	case COMPACT_LIST: |  | ||||||
| 		return LIST, nil |  | ||||||
| 	case COMPACT_SET: |  | ||||||
| 		return SET, nil |  | ||||||
| 	case COMPACT_MAP: |  | ||||||
| 		return MAP, nil |  | ||||||
| 	case COMPACT_STRUCT: |  | ||||||
| 		return STRUCT, nil |  | ||||||
| 	} |  | ||||||
| 	return STOP, NewTProtocolException(fmt.Errorf("don't know what type: %v", t&0x0f)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Given a TType value, find the appropriate TCompactProtocol.Types constant. |  | ||||||
| func (p *TCompactProtocol) getCompactType(t TType) tCompactType { |  | ||||||
| 	return ttypeToCompactType[t] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TCompactProtocol) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.trans, conf) |  | ||||||
| 	PropagateTConfiguration(p.origTransport, conf) |  | ||||||
| 	p.cfg = conf |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	_ TConfigurationSetter = (*TCompactProtocolFactory)(nil) |  | ||||||
| 	_ TConfigurationSetter = (*TCompactProtocol)(nil) |  | ||||||
| ) |  | ||||||
|  | @ -1,378 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/tls" |  | ||||||
| 	"fmt" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Default TConfiguration values. |  | ||||||
| const ( |  | ||||||
| 	DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024 |  | ||||||
| 	DEFAULT_MAX_FRAME_SIZE   = 16384000 |  | ||||||
| 
 |  | ||||||
| 	DEFAULT_TBINARY_STRICT_READ  = false |  | ||||||
| 	DEFAULT_TBINARY_STRICT_WRITE = true |  | ||||||
| 
 |  | ||||||
| 	DEFAULT_CONNECT_TIMEOUT = 0 |  | ||||||
| 	DEFAULT_SOCKET_TIMEOUT  = 0 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // TConfiguration defines some configurations shared between TTransport, |  | ||||||
| // TProtocol, TTransportFactory, TProtocolFactory, and other implementations. |  | ||||||
| // |  | ||||||
| // When constructing TConfiguration, you only need to specify the non-default |  | ||||||
| // fields. All zero values have sane default values. |  | ||||||
| // |  | ||||||
| // Not all configurations defined are applicable to all implementations. |  | ||||||
| // Implementations are free to ignore the configurations not applicable to them. |  | ||||||
| // |  | ||||||
| // All functions attached to this type are nil-safe. |  | ||||||
| // |  | ||||||
| // See [1] for spec. |  | ||||||
| // |  | ||||||
| // NOTE: When using TConfiguration, fill in all the configurations you want to |  | ||||||
| // set across the stack, not only the ones you want to set in the immediate |  | ||||||
| // TTransport/TProtocol. |  | ||||||
| // |  | ||||||
| // For example, say you want to migrate this old code into using TConfiguration: |  | ||||||
| // |  | ||||||
| //     sccket := thrift.NewTSocketTimeout("host:port", time.Second) |  | ||||||
| //     transFactory := thrift.NewTFramedTransportFactoryMaxLength( |  | ||||||
| //         thrift.NewTTransportFactory(), |  | ||||||
| //         1024 * 1024 * 256, |  | ||||||
| //     ) |  | ||||||
| //     protoFactory := thrift.NewTBinaryProtocolFactory(true, true) |  | ||||||
| // |  | ||||||
| // This is the wrong way to do it because in the end the TConfiguration used by |  | ||||||
| // socket and transFactory will be overwritten by the one used by protoFactory |  | ||||||
| // because of TConfiguration propagation: |  | ||||||
| // |  | ||||||
| //     // bad example, DO NOT USE |  | ||||||
| //     sccket := thrift.NewTSocketConf("host:port", &thrift.TConfiguration{ |  | ||||||
| //         ConnectTimeout: time.Second, |  | ||||||
| //         SocketTimeout:  time.Second, |  | ||||||
| //     }) |  | ||||||
| //     transFactory := thrift.NewTFramedTransportFactoryConf( |  | ||||||
| //         thrift.NewTTransportFactory(), |  | ||||||
| //         &thrift.TConfiguration{ |  | ||||||
| //             MaxFrameSize: 1024 * 1024 * 256, |  | ||||||
| //         }, |  | ||||||
| //     ) |  | ||||||
| //     protoFactory := thrift.NewTBinaryProtocolFactoryConf(&thrift.TConfiguration{ |  | ||||||
| //         TBinaryStrictRead:  thrift.BoolPtr(true), |  | ||||||
| //         TBinaryStrictWrite: thrift.BoolPtr(true), |  | ||||||
| //     }) |  | ||||||
| // |  | ||||||
| // This is the correct way to do it: |  | ||||||
| // |  | ||||||
| //     conf := &thrift.TConfiguration{ |  | ||||||
| //         ConnectTimeout: time.Second, |  | ||||||
| //         SocketTimeout:  time.Second, |  | ||||||
| // |  | ||||||
| //         MaxFrameSize: 1024 * 1024 * 256, |  | ||||||
| // |  | ||||||
| //         TBinaryStrictRead:  thrift.BoolPtr(true), |  | ||||||
| //         TBinaryStrictWrite: thrift.BoolPtr(true), |  | ||||||
| //     } |  | ||||||
| //     sccket := thrift.NewTSocketConf("host:port", conf) |  | ||||||
| //     transFactory := thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), conf) |  | ||||||
| //     protoFactory := thrift.NewTBinaryProtocolFactoryConf(conf) |  | ||||||
| // |  | ||||||
| // [1]: https://github.com/apache/thrift/blob/master/doc/specs/thrift-tconfiguration.md |  | ||||||
| type TConfiguration struct { |  | ||||||
| 	// If <= 0, DEFAULT_MAX_MESSAGE_SIZE will be used instead. |  | ||||||
| 	MaxMessageSize int32 |  | ||||||
| 
 |  | ||||||
| 	// If <= 0, DEFAULT_MAX_FRAME_SIZE will be used instead. |  | ||||||
| 	// |  | ||||||
| 	// Also if MaxMessageSize < MaxFrameSize, |  | ||||||
| 	// MaxMessageSize will be used instead. |  | ||||||
| 	MaxFrameSize int32 |  | ||||||
| 
 |  | ||||||
| 	// Connect and socket timeouts to be used by TSocket and TSSLSocket. |  | ||||||
| 	// |  | ||||||
| 	// 0 means no timeout. |  | ||||||
| 	// |  | ||||||
| 	// If <0, DEFAULT_CONNECT_TIMEOUT and DEFAULT_SOCKET_TIMEOUT will be |  | ||||||
| 	// used. |  | ||||||
| 	ConnectTimeout time.Duration |  | ||||||
| 	SocketTimeout  time.Duration |  | ||||||
| 
 |  | ||||||
| 	// TLS config to be used by TSSLSocket. |  | ||||||
| 	TLSConfig *tls.Config |  | ||||||
| 
 |  | ||||||
| 	// Strict read/write configurations for TBinaryProtocol. |  | ||||||
| 	// |  | ||||||
| 	// BoolPtr helper function is available to use literal values. |  | ||||||
| 	TBinaryStrictRead  *bool |  | ||||||
| 	TBinaryStrictWrite *bool |  | ||||||
| 
 |  | ||||||
| 	// The wrapped protocol id to be used in THeader transport/protocol. |  | ||||||
| 	// |  | ||||||
| 	// THeaderProtocolIDPtr and THeaderProtocolIDPtrMust helper functions |  | ||||||
| 	// are provided to help filling this value. |  | ||||||
| 	THeaderProtocolID *THeaderProtocolID |  | ||||||
| 
 |  | ||||||
| 	// Used internally by deprecated constructors, to avoid overriding |  | ||||||
| 	// underlying TTransport/TProtocol's cfg by accidental propagations. |  | ||||||
| 	// |  | ||||||
| 	// For external users this is always false. |  | ||||||
| 	noPropagation bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetMaxMessageSize returns the max message size an implementation should |  | ||||||
| // follow. |  | ||||||
| // |  | ||||||
| // It's nil-safe. DEFAULT_MAX_MESSAGE_SIZE will be returned if tc is nil. |  | ||||||
| func (tc *TConfiguration) GetMaxMessageSize() int32 { |  | ||||||
| 	if tc == nil || tc.MaxMessageSize <= 0 { |  | ||||||
| 		return DEFAULT_MAX_MESSAGE_SIZE |  | ||||||
| 	} |  | ||||||
| 	return tc.MaxMessageSize |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetMaxFrameSize returns the max frame size an implementation should follow. |  | ||||||
| // |  | ||||||
| // It's nil-safe. DEFAULT_MAX_FRAME_SIZE will be returned if tc is nil. |  | ||||||
| // |  | ||||||
| // If the configured max message size is smaller than the configured max frame |  | ||||||
| // size, the smaller one will be returned instead. |  | ||||||
| func (tc *TConfiguration) GetMaxFrameSize() int32 { |  | ||||||
| 	if tc == nil { |  | ||||||
| 		return DEFAULT_MAX_FRAME_SIZE |  | ||||||
| 	} |  | ||||||
| 	maxFrameSize := tc.MaxFrameSize |  | ||||||
| 	if maxFrameSize <= 0 { |  | ||||||
| 		maxFrameSize = DEFAULT_MAX_FRAME_SIZE |  | ||||||
| 	} |  | ||||||
| 	if maxMessageSize := tc.GetMaxMessageSize(); maxMessageSize < maxFrameSize { |  | ||||||
| 		return maxMessageSize |  | ||||||
| 	} |  | ||||||
| 	return maxFrameSize |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetConnectTimeout returns the connect timeout should be used by TSocket and |  | ||||||
| // TSSLSocket. |  | ||||||
| // |  | ||||||
| // It's nil-safe. If tc is nil, DEFAULT_CONNECT_TIMEOUT will be returned instead. |  | ||||||
| func (tc *TConfiguration) GetConnectTimeout() time.Duration { |  | ||||||
| 	if tc == nil || tc.ConnectTimeout < 0 { |  | ||||||
| 		return DEFAULT_CONNECT_TIMEOUT |  | ||||||
| 	} |  | ||||||
| 	return tc.ConnectTimeout |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetSocketTimeout returns the socket timeout should be used by TSocket and |  | ||||||
| // TSSLSocket. |  | ||||||
| // |  | ||||||
| // It's nil-safe. If tc is nil, DEFAULT_SOCKET_TIMEOUT will be returned instead. |  | ||||||
| func (tc *TConfiguration) GetSocketTimeout() time.Duration { |  | ||||||
| 	if tc == nil || tc.SocketTimeout < 0 { |  | ||||||
| 		return DEFAULT_SOCKET_TIMEOUT |  | ||||||
| 	} |  | ||||||
| 	return tc.SocketTimeout |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTLSConfig returns the tls config should be used by TSSLSocket. |  | ||||||
| // |  | ||||||
| // It's nil-safe. If tc is nil, nil will be returned instead. |  | ||||||
| func (tc *TConfiguration) GetTLSConfig() *tls.Config { |  | ||||||
| 	if tc == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return tc.TLSConfig |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTBinaryStrictRead returns the strict read configuration TBinaryProtocol |  | ||||||
| // should follow. |  | ||||||
| // |  | ||||||
| // It's nil-safe. DEFAULT_TBINARY_STRICT_READ will be returned if either tc or |  | ||||||
| // tc.TBinaryStrictRead is nil. |  | ||||||
| func (tc *TConfiguration) GetTBinaryStrictRead() bool { |  | ||||||
| 	if tc == nil || tc.TBinaryStrictRead == nil { |  | ||||||
| 		return DEFAULT_TBINARY_STRICT_READ |  | ||||||
| 	} |  | ||||||
| 	return *tc.TBinaryStrictRead |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTBinaryStrictWrite returns the strict read configuration TBinaryProtocol |  | ||||||
| // should follow. |  | ||||||
| // |  | ||||||
| // It's nil-safe. DEFAULT_TBINARY_STRICT_WRITE will be returned if either tc or |  | ||||||
| // tc.TBinaryStrictWrite is nil. |  | ||||||
| func (tc *TConfiguration) GetTBinaryStrictWrite() bool { |  | ||||||
| 	if tc == nil || tc.TBinaryStrictWrite == nil { |  | ||||||
| 		return DEFAULT_TBINARY_STRICT_WRITE |  | ||||||
| 	} |  | ||||||
| 	return *tc.TBinaryStrictWrite |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTHeaderProtocolID returns the THeaderProtocolID should be used by |  | ||||||
| // THeaderProtocol clients (for servers, they always use the same one as the |  | ||||||
| // client instead). |  | ||||||
| // |  | ||||||
| // It's nil-safe. If either tc or tc.THeaderProtocolID is nil, |  | ||||||
| // THeaderProtocolDefault will be returned instead. |  | ||||||
| // THeaderProtocolDefault will also be returned if configured value is invalid. |  | ||||||
| func (tc *TConfiguration) GetTHeaderProtocolID() THeaderProtocolID { |  | ||||||
| 	if tc == nil || tc.THeaderProtocolID == nil { |  | ||||||
| 		return THeaderProtocolDefault |  | ||||||
| 	} |  | ||||||
| 	protoID := *tc.THeaderProtocolID |  | ||||||
| 	if err := protoID.Validate(); err != nil { |  | ||||||
| 		return THeaderProtocolDefault |  | ||||||
| 	} |  | ||||||
| 	return protoID |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // THeaderProtocolIDPtr validates and returns the pointer to id. |  | ||||||
| // |  | ||||||
| // If id is not a valid THeaderProtocolID, a pointer to THeaderProtocolDefault |  | ||||||
| // and the validation error will be returned. |  | ||||||
| func THeaderProtocolIDPtr(id THeaderProtocolID) (*THeaderProtocolID, error) { |  | ||||||
| 	err := id.Validate() |  | ||||||
| 	if err != nil { |  | ||||||
| 		id = THeaderProtocolDefault |  | ||||||
| 	} |  | ||||||
| 	return &id, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // THeaderProtocolIDPtrMust validates and returns the pointer to id. |  | ||||||
| // |  | ||||||
| // It's similar to THeaderProtocolIDPtr, but it panics on validation errors |  | ||||||
| // instead of returning them. |  | ||||||
| func THeaderProtocolIDPtrMust(id THeaderProtocolID) *THeaderProtocolID { |  | ||||||
| 	ptr, err := THeaderProtocolIDPtr(id) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| 	return ptr |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TConfigurationSetter is an optional interface TProtocol, TTransport, |  | ||||||
| // TProtocolFactory, TTransportFactory, and other implementations can implement. |  | ||||||
| // |  | ||||||
| // It's intended to be called during intializations. |  | ||||||
| // The behavior of calling SetTConfiguration on a TTransport/TProtocol in the |  | ||||||
| // middle of a message is undefined: |  | ||||||
| // It may or may not change the behavior of the current processing message, |  | ||||||
| // and it may even cause the current message to fail. |  | ||||||
| // |  | ||||||
| // Note for implementations: SetTConfiguration might be called multiple times |  | ||||||
| // with the same value in quick successions due to the implementation of the |  | ||||||
| // propagation. Implementations should make SetTConfiguration as simple as |  | ||||||
| // possible (usually just overwrite the stored configuration and propagate it to |  | ||||||
| // the wrapped TTransports/TProtocols). |  | ||||||
| type TConfigurationSetter interface { |  | ||||||
| 	SetTConfiguration(*TConfiguration) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // PropagateTConfiguration propagates cfg to impl if impl implements |  | ||||||
| // TConfigurationSetter and cfg is non-nil, otherwise it does nothing. |  | ||||||
| // |  | ||||||
| // NOTE: nil cfg is not propagated. If you want to propagate a TConfiguration |  | ||||||
| // with everything being default value, use &TConfiguration{} explicitly instead. |  | ||||||
| func PropagateTConfiguration(impl interface{}, cfg *TConfiguration) { |  | ||||||
| 	if cfg == nil || cfg.noPropagation { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if setter, ok := impl.(TConfigurationSetter); ok { |  | ||||||
| 		setter.SetTConfiguration(cfg) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func checkSizeForProtocol(size int32, cfg *TConfiguration) error { |  | ||||||
| 	if size < 0 { |  | ||||||
| 		return NewTProtocolExceptionWithType( |  | ||||||
| 			NEGATIVE_SIZE, |  | ||||||
| 			fmt.Errorf("negative size: %d", size), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 	if size > cfg.GetMaxMessageSize() { |  | ||||||
| 		return NewTProtocolExceptionWithType( |  | ||||||
| 			SIZE_LIMIT, |  | ||||||
| 			fmt.Errorf("size exceeded max allowed: %d", size), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tTransportFactoryConf struct { |  | ||||||
| 	delegate TTransportFactory |  | ||||||
| 	cfg      *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (f *tTransportFactoryConf) GetTransport(orig TTransport) (TTransport, error) { |  | ||||||
| 	trans, err := f.delegate.GetTransport(orig) |  | ||||||
| 	if err == nil { |  | ||||||
| 		PropagateTConfiguration(orig, f.cfg) |  | ||||||
| 		PropagateTConfiguration(trans, f.cfg) |  | ||||||
| 	} |  | ||||||
| 	return trans, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (f *tTransportFactoryConf) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(f.delegate, f.cfg) |  | ||||||
| 	f.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TTransportFactoryConf wraps a TTransportFactory to propagate |  | ||||||
| // TConfiguration on the factory's GetTransport calls. |  | ||||||
| func TTransportFactoryConf(delegate TTransportFactory, conf *TConfiguration) TTransportFactory { |  | ||||||
| 	return &tTransportFactoryConf{ |  | ||||||
| 		delegate: delegate, |  | ||||||
| 		cfg:      conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tProtocolFactoryConf struct { |  | ||||||
| 	delegate TProtocolFactory |  | ||||||
| 	cfg      *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (f *tProtocolFactoryConf) GetProtocol(trans TTransport) TProtocol { |  | ||||||
| 	proto := f.delegate.GetProtocol(trans) |  | ||||||
| 	PropagateTConfiguration(trans, f.cfg) |  | ||||||
| 	PropagateTConfiguration(proto, f.cfg) |  | ||||||
| 	return proto |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (f *tProtocolFactoryConf) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(f.delegate, f.cfg) |  | ||||||
| 	f.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TProtocolFactoryConf wraps a TProtocolFactory to propagate |  | ||||||
| // TConfiguration on the factory's GetProtocol calls. |  | ||||||
| func TProtocolFactoryConf(delegate TProtocolFactory, conf *TConfiguration) TProtocolFactory { |  | ||||||
| 	return &tProtocolFactoryConf{ |  | ||||||
| 		delegate: delegate, |  | ||||||
| 		cfg:      conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	_ TConfigurationSetter = (*tTransportFactoryConf)(nil) |  | ||||||
| 	_ TConfigurationSetter = (*tProtocolFactoryConf)(nil) |  | ||||||
| ) |  | ||||||
|  | @ -1,24 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import "context" |  | ||||||
| 
 |  | ||||||
| var defaultCtx = context.Background() |  | ||||||
|  | @ -1,447 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TDebugProtocol struct { |  | ||||||
| 	// Required. The actual TProtocol to do the read/write. |  | ||||||
| 	Delegate TProtocol |  | ||||||
| 
 |  | ||||||
| 	// Optional. The logger and prefix to log all the args/return values |  | ||||||
| 	// from Delegate TProtocol calls. |  | ||||||
| 	// |  | ||||||
| 	// If Logger is nil, StdLogger using stdlib log package with os.Stderr |  | ||||||
| 	// will be used. If disable logging is desired, set Logger to NopLogger |  | ||||||
| 	// explicitly instead of leaving it as nil/unset. |  | ||||||
| 	Logger    Logger |  | ||||||
| 	LogPrefix string |  | ||||||
| 
 |  | ||||||
| 	// Optional. An TProtocol to duplicate everything read/written from Delegate. |  | ||||||
| 	// |  | ||||||
| 	// A typical use case of this is to use TSimpleJSONProtocol wrapping |  | ||||||
| 	// TMemoryBuffer in a middleware to json logging requests/responses. |  | ||||||
| 	// |  | ||||||
| 	// This feature is not available from TDebugProtocolFactory. In order to |  | ||||||
| 	// use it you have to construct TDebugProtocol directly, or set DuplicateTo |  | ||||||
| 	// field after getting a TDebugProtocol from the factory. |  | ||||||
| 	DuplicateTo TProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TDebugProtocolFactory struct { |  | ||||||
| 	Underlying TProtocolFactory |  | ||||||
| 	LogPrefix  string |  | ||||||
| 	Logger     Logger |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTDebugProtocolFactory creates a TDebugProtocolFactory. |  | ||||||
| // |  | ||||||
| // Deprecated: Please use NewTDebugProtocolFactoryWithLogger or the struct |  | ||||||
| // itself instead. This version will use the default logger from standard |  | ||||||
| // library. |  | ||||||
| func NewTDebugProtocolFactory(underlying TProtocolFactory, logPrefix string) *TDebugProtocolFactory { |  | ||||||
| 	return &TDebugProtocolFactory{ |  | ||||||
| 		Underlying: underlying, |  | ||||||
| 		LogPrefix:  logPrefix, |  | ||||||
| 		Logger:     StdLogger(nil), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTDebugProtocolFactoryWithLogger creates a TDebugProtocolFactory. |  | ||||||
| func NewTDebugProtocolFactoryWithLogger(underlying TProtocolFactory, logPrefix string, logger Logger) *TDebugProtocolFactory { |  | ||||||
| 	return &TDebugProtocolFactory{ |  | ||||||
| 		Underlying: underlying, |  | ||||||
| 		LogPrefix:  logPrefix, |  | ||||||
| 		Logger:     logger, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TDebugProtocolFactory) GetProtocol(trans TTransport) TProtocol { |  | ||||||
| 	return &TDebugProtocol{ |  | ||||||
| 		Delegate:  t.Underlying.GetProtocol(trans), |  | ||||||
| 		LogPrefix: t.LogPrefix, |  | ||||||
| 		Logger:    fallbackLogger(t.Logger), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (tdp *TDebugProtocol) logf(format string, v ...interface{}) { |  | ||||||
| 	fallbackLogger(tdp.Logger)(fmt.Sprintf(format, v...)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (tdp *TDebugProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { |  | ||||||
| 	err := tdp.Delegate.WriteMessageBegin(ctx, name, typeId, seqid) |  | ||||||
| 	tdp.logf("%sWriteMessageBegin(name=%#v, typeId=%#v, seqid=%#v) => %#v", tdp.LogPrefix, name, typeId, seqid, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteMessageEnd(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteMessageEnd(ctx) |  | ||||||
| 	tdp.logf("%sWriteMessageEnd() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMessageEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteStructBegin(ctx context.Context, name string) error { |  | ||||||
| 	err := tdp.Delegate.WriteStructBegin(ctx, name) |  | ||||||
| 	tdp.logf("%sWriteStructBegin(name=%#v) => %#v", tdp.LogPrefix, name, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteStructBegin(ctx, name) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteStructEnd(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteStructEnd(ctx) |  | ||||||
| 	tdp.logf("%sWriteStructEnd() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteStructEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { |  | ||||||
| 	err := tdp.Delegate.WriteFieldBegin(ctx, name, typeId, id) |  | ||||||
| 	tdp.logf("%sWriteFieldBegin(name=%#v, typeId=%#v, id%#v) => %#v", tdp.LogPrefix, name, typeId, id, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteFieldEnd(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteFieldEnd(ctx) |  | ||||||
| 	tdp.logf("%sWriteFieldEnd() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteFieldEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteFieldStop(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteFieldStop(ctx) |  | ||||||
| 	tdp.logf("%sWriteFieldStop() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteFieldStop(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { |  | ||||||
| 	err := tdp.Delegate.WriteMapBegin(ctx, keyType, valueType, size) |  | ||||||
| 	tdp.logf("%sWriteMapBegin(keyType=%#v, valueType=%#v, size=%#v) => %#v", tdp.LogPrefix, keyType, valueType, size, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteMapEnd(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteMapEnd(ctx) |  | ||||||
| 	tdp.logf("%sWriteMapEnd() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMapEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	err := tdp.Delegate.WriteListBegin(ctx, elemType, size) |  | ||||||
| 	tdp.logf("%sWriteListBegin(elemType=%#v, size=%#v) => %#v", tdp.LogPrefix, elemType, size, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteListBegin(ctx, elemType, size) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteListEnd(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteListEnd(ctx) |  | ||||||
| 	tdp.logf("%sWriteListEnd() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteListEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	err := tdp.Delegate.WriteSetBegin(ctx, elemType, size) |  | ||||||
| 	tdp.logf("%sWriteSetBegin(elemType=%#v, size=%#v) => %#v", tdp.LogPrefix, elemType, size, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteSetBegin(ctx, elemType, size) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteSetEnd(ctx context.Context) error { |  | ||||||
| 	err := tdp.Delegate.WriteSetEnd(ctx) |  | ||||||
| 	tdp.logf("%sWriteSetEnd() => %#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteSetEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteBool(ctx context.Context, value bool) error { |  | ||||||
| 	err := tdp.Delegate.WriteBool(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteBool(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteBool(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteByte(ctx context.Context, value int8) error { |  | ||||||
| 	err := tdp.Delegate.WriteByte(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteByte(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteByte(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteI16(ctx context.Context, value int16) error { |  | ||||||
| 	err := tdp.Delegate.WriteI16(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteI16(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteI16(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteI32(ctx context.Context, value int32) error { |  | ||||||
| 	err := tdp.Delegate.WriteI32(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteI32(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteI32(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteI64(ctx context.Context, value int64) error { |  | ||||||
| 	err := tdp.Delegate.WriteI64(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteI64(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteI64(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteDouble(ctx context.Context, value float64) error { |  | ||||||
| 	err := tdp.Delegate.WriteDouble(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteDouble(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteDouble(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteString(ctx context.Context, value string) error { |  | ||||||
| 	err := tdp.Delegate.WriteString(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteString(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteString(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) WriteBinary(ctx context.Context, value []byte) error { |  | ||||||
| 	err := tdp.Delegate.WriteBinary(ctx, value) |  | ||||||
| 	tdp.logf("%sWriteBinary(value=%#v) => %#v", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteBinary(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (tdp *TDebugProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) { |  | ||||||
| 	name, typeId, seqid, err = tdp.Delegate.ReadMessageBegin(ctx) |  | ||||||
| 	tdp.logf("%sReadMessageBegin() (name=%#v, typeId=%#v, seqid=%#v, err=%#v)", tdp.LogPrefix, name, typeId, seqid, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadMessageEnd(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.ReadMessageEnd(ctx) |  | ||||||
| 	tdp.logf("%sReadMessageEnd() err=%#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMessageEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { |  | ||||||
| 	name, err = tdp.Delegate.ReadStructBegin(ctx) |  | ||||||
| 	tdp.logf("%sReadStructBegin() (name%#v, err=%#v)", tdp.LogPrefix, name, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteStructBegin(ctx, name) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadStructEnd(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.ReadStructEnd(ctx) |  | ||||||
| 	tdp.logf("%sReadStructEnd() err=%#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteStructEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) { |  | ||||||
| 	name, typeId, id, err = tdp.Delegate.ReadFieldBegin(ctx) |  | ||||||
| 	tdp.logf("%sReadFieldBegin() (name=%#v, typeId=%#v, id=%#v, err=%#v)", tdp.LogPrefix, name, typeId, id, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadFieldEnd(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.ReadFieldEnd(ctx) |  | ||||||
| 	tdp.logf("%sReadFieldEnd() err=%#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteFieldEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { |  | ||||||
| 	keyType, valueType, size, err = tdp.Delegate.ReadMapBegin(ctx) |  | ||||||
| 	tdp.logf("%sReadMapBegin() (keyType=%#v, valueType=%#v, size=%#v, err=%#v)", tdp.LogPrefix, keyType, valueType, size, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadMapEnd(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.ReadMapEnd(ctx) |  | ||||||
| 	tdp.logf("%sReadMapEnd() err=%#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteMapEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	elemType, size, err = tdp.Delegate.ReadListBegin(ctx) |  | ||||||
| 	tdp.logf("%sReadListBegin() (elemType=%#v, size=%#v, err=%#v)", tdp.LogPrefix, elemType, size, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteListBegin(ctx, elemType, size) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadListEnd(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.ReadListEnd(ctx) |  | ||||||
| 	tdp.logf("%sReadListEnd() err=%#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteListEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	elemType, size, err = tdp.Delegate.ReadSetBegin(ctx) |  | ||||||
| 	tdp.logf("%sReadSetBegin() (elemType=%#v, size=%#v, err=%#v)", tdp.LogPrefix, elemType, size, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteSetBegin(ctx, elemType, size) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadSetEnd(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.ReadSetEnd(ctx) |  | ||||||
| 	tdp.logf("%sReadSetEnd() err=%#v", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteSetEnd(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadBool(ctx context.Context) (value bool, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadBool(ctx) |  | ||||||
| 	tdp.logf("%sReadBool() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteBool(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadByte(ctx context.Context) (value int8, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadByte(ctx) |  | ||||||
| 	tdp.logf("%sReadByte() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteByte(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadI16(ctx context.Context) (value int16, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadI16(ctx) |  | ||||||
| 	tdp.logf("%sReadI16() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteI16(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadI32(ctx context.Context) (value int32, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadI32(ctx) |  | ||||||
| 	tdp.logf("%sReadI32() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteI32(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadI64(ctx context.Context) (value int64, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadI64(ctx) |  | ||||||
| 	tdp.logf("%sReadI64() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteI64(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadDouble(ctx context.Context) (value float64, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadDouble(ctx) |  | ||||||
| 	tdp.logf("%sReadDouble() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteDouble(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadString(ctx context.Context) (value string, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadString(ctx) |  | ||||||
| 	tdp.logf("%sReadString() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteString(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { |  | ||||||
| 	value, err = tdp.Delegate.ReadBinary(ctx) |  | ||||||
| 	tdp.logf("%sReadBinary() (value=%#v, err=%#v)", tdp.LogPrefix, value, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.WriteBinary(ctx, value) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) Skip(ctx context.Context, fieldType TType) (err error) { |  | ||||||
| 	err = tdp.Delegate.Skip(ctx, fieldType) |  | ||||||
| 	tdp.logf("%sSkip(fieldType=%#v) (err=%#v)", tdp.LogPrefix, fieldType, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.Skip(ctx, fieldType) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (tdp *TDebugProtocol) Flush(ctx context.Context) (err error) { |  | ||||||
| 	err = tdp.Delegate.Flush(ctx) |  | ||||||
| 	tdp.logf("%sFlush() (err=%#v)", tdp.LogPrefix, err) |  | ||||||
| 	if tdp.DuplicateTo != nil { |  | ||||||
| 		tdp.DuplicateTo.Flush(ctx) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (tdp *TDebugProtocol) Transport() TTransport { |  | ||||||
| 	return tdp.Delegate.Transport() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter for propagation. |  | ||||||
| func (tdp *TDebugProtocol) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(tdp.Delegate, conf) |  | ||||||
| 	PropagateTConfiguration(tdp.DuplicateTo, conf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*TDebugProtocol)(nil) |  | ||||||
|  | @ -1,121 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"sync" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TDeserializer struct { |  | ||||||
| 	Transport *TMemoryBuffer |  | ||||||
| 	Protocol  TProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTDeserializer() *TDeserializer { |  | ||||||
| 	transport := NewTMemoryBufferLen(1024) |  | ||||||
| 	protocol := NewTBinaryProtocolTransport(transport) |  | ||||||
| 
 |  | ||||||
| 	return &TDeserializer{ |  | ||||||
| 		Transport: transport, |  | ||||||
| 		Protocol:  protocol, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TDeserializer) ReadString(ctx context.Context, msg TStruct, s string) (err error) { |  | ||||||
| 	t.Transport.Reset() |  | ||||||
| 
 |  | ||||||
| 	err = nil |  | ||||||
| 	if _, err = t.Transport.Write([]byte(s)); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if err = msg.Read(ctx, t.Protocol); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TDeserializer) Read(ctx context.Context, msg TStruct, b []byte) (err error) { |  | ||||||
| 	t.Transport.Reset() |  | ||||||
| 
 |  | ||||||
| 	err = nil |  | ||||||
| 	if _, err = t.Transport.Write(b); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if err = msg.Read(ctx, t.Protocol); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TDeserializerPool is the thread-safe version of TDeserializer, |  | ||||||
| // it uses resource pool of TDeserializer under the hood. |  | ||||||
| // |  | ||||||
| // It must be initialized with either NewTDeserializerPool or |  | ||||||
| // NewTDeserializerPoolSizeFactory. |  | ||||||
| type TDeserializerPool struct { |  | ||||||
| 	pool sync.Pool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTDeserializerPool creates a new TDeserializerPool. |  | ||||||
| // |  | ||||||
| // NewTDeserializer can be used as the arg here. |  | ||||||
| func NewTDeserializerPool(f func() *TDeserializer) *TDeserializerPool { |  | ||||||
| 	return &TDeserializerPool{ |  | ||||||
| 		pool: sync.Pool{ |  | ||||||
| 			New: func() interface{} { |  | ||||||
| 				return f() |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTDeserializerPoolSizeFactory creates a new TDeserializerPool with |  | ||||||
| // the given size and protocol factory. |  | ||||||
| // |  | ||||||
| // Note that the size is not the limit. The TMemoryBuffer underneath can grow |  | ||||||
| // larger than that. It just dictates the initial size. |  | ||||||
| func NewTDeserializerPoolSizeFactory(size int, factory TProtocolFactory) *TDeserializerPool { |  | ||||||
| 	return &TDeserializerPool{ |  | ||||||
| 		pool: sync.Pool{ |  | ||||||
| 			New: func() interface{} { |  | ||||||
| 				transport := NewTMemoryBufferLen(size) |  | ||||||
| 				protocol := factory.GetProtocol(transport) |  | ||||||
| 
 |  | ||||||
| 				return &TDeserializer{ |  | ||||||
| 					Transport: transport, |  | ||||||
| 					Protocol:  protocol, |  | ||||||
| 				} |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TDeserializerPool) ReadString(ctx context.Context, msg TStruct, s string) error { |  | ||||||
| 	d := t.pool.Get().(*TDeserializer) |  | ||||||
| 	defer t.pool.Put(d) |  | ||||||
| 	return d.ReadString(ctx, msg, s) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TDeserializerPool) Read(ctx context.Context, msg TStruct, b []byte) error { |  | ||||||
| 	d := t.pool.Get().(*TDeserializer) |  | ||||||
| 	defer t.pool.Put(d) |  | ||||||
| 	return d.Read(ctx, msg, b) |  | ||||||
| } |  | ||||||
|  | @ -1,116 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Generic Thrift exception |  | ||||||
| type TException interface { |  | ||||||
| 	error |  | ||||||
| 
 |  | ||||||
| 	TExceptionType() TExceptionType |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Prepends additional information to an error without losing the Thrift exception interface |  | ||||||
| func PrependError(prepend string, err error) error { |  | ||||||
| 	msg := prepend + err.Error() |  | ||||||
| 
 |  | ||||||
| 	var te TException |  | ||||||
| 	if errors.As(err, &te) { |  | ||||||
| 		switch te.TExceptionType() { |  | ||||||
| 		case TExceptionTypeTransport: |  | ||||||
| 			if t, ok := err.(TTransportException); ok { |  | ||||||
| 				return prependTTransportException(prepend, t) |  | ||||||
| 			} |  | ||||||
| 		case TExceptionTypeProtocol: |  | ||||||
| 			if t, ok := err.(TProtocolException); ok { |  | ||||||
| 				return prependTProtocolException(prepend, t) |  | ||||||
| 			} |  | ||||||
| 		case TExceptionTypeApplication: |  | ||||||
| 			var t TApplicationException |  | ||||||
| 			if errors.As(err, &t) { |  | ||||||
| 				return NewTApplicationException(t.TypeId(), msg) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return wrappedTException{ |  | ||||||
| 			err:            err, |  | ||||||
| 			msg:            msg, |  | ||||||
| 			tExceptionType: te.TExceptionType(), |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return errors.New(msg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TExceptionType is an enum type to categorize different "subclasses" of TExceptions. |  | ||||||
| type TExceptionType byte |  | ||||||
| 
 |  | ||||||
| // TExceptionType values |  | ||||||
| const ( |  | ||||||
| 	TExceptionTypeUnknown     TExceptionType = iota |  | ||||||
| 	TExceptionTypeCompiled                   // TExceptions defined in thrift files and generated by thrift compiler |  | ||||||
| 	TExceptionTypeApplication                // TApplicationExceptions |  | ||||||
| 	TExceptionTypeProtocol                   // TProtocolExceptions |  | ||||||
| 	TExceptionTypeTransport                  // TTransportExceptions |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // WrapTException wraps an error into TException. |  | ||||||
| // |  | ||||||
| // If err is nil or already TException, it's returned as-is. |  | ||||||
| // Otherwise it will be wrapped into TException with TExceptionType() returning |  | ||||||
| // TExceptionTypeUnknown, and Unwrap() returning the original error. |  | ||||||
| func WrapTException(err error) TException { |  | ||||||
| 	if err == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if te, ok := err.(TException); ok { |  | ||||||
| 		return te |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return wrappedTException{ |  | ||||||
| 		err:            err, |  | ||||||
| 		msg:            err.Error(), |  | ||||||
| 		tExceptionType: TExceptionTypeUnknown, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type wrappedTException struct { |  | ||||||
| 	err            error |  | ||||||
| 	msg            string |  | ||||||
| 	tExceptionType TExceptionType |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (w wrappedTException) Error() string { |  | ||||||
| 	return w.msg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (w wrappedTException) TExceptionType() TExceptionType { |  | ||||||
| 	return w.tExceptionType |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (w wrappedTException) Unwrap() error { |  | ||||||
| 	return w.err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TException = wrappedTException{} |  | ||||||
|  | @ -1,223 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use DEFAULT_MAX_FRAME_SIZE instead. |  | ||||||
| const DEFAULT_MAX_LENGTH = 16384000 |  | ||||||
| 
 |  | ||||||
| type TFramedTransport struct { |  | ||||||
| 	transport TTransport |  | ||||||
| 
 |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| 
 |  | ||||||
| 	writeBuf bytes.Buffer |  | ||||||
| 
 |  | ||||||
| 	reader  *bufio.Reader |  | ||||||
| 	readBuf bytes.Buffer |  | ||||||
| 
 |  | ||||||
| 	buffer [4]byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tFramedTransportFactory struct { |  | ||||||
| 	factory TTransportFactory |  | ||||||
| 	cfg     *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTFramedTransportFactoryConf instead. |  | ||||||
| func NewTFramedTransportFactory(factory TTransportFactory) TTransportFactory { |  | ||||||
| 	return NewTFramedTransportFactoryConf(factory, &TConfiguration{ |  | ||||||
| 		MaxFrameSize: DEFAULT_MAX_LENGTH, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTFramedTransportFactoryConf instead. |  | ||||||
| func NewTFramedTransportFactoryMaxLength(factory TTransportFactory, maxLength uint32) TTransportFactory { |  | ||||||
| 	return NewTFramedTransportFactoryConf(factory, &TConfiguration{ |  | ||||||
| 		MaxFrameSize: int32(maxLength), |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTFramedTransportFactoryConf(factory TTransportFactory, conf *TConfiguration) TTransportFactory { |  | ||||||
| 	PropagateTConfiguration(factory, conf) |  | ||||||
| 	return &tFramedTransportFactory{ |  | ||||||
| 		factory: factory, |  | ||||||
| 		cfg:     conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tFramedTransportFactory) GetTransport(base TTransport) (TTransport, error) { |  | ||||||
| 	PropagateTConfiguration(base, p.cfg) |  | ||||||
| 	tt, err := p.factory.GetTransport(base) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return NewTFramedTransportConf(tt, p.cfg), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tFramedTransportFactory) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.factory, cfg) |  | ||||||
| 	p.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTFramedTransportConf instead. |  | ||||||
| func NewTFramedTransport(transport TTransport) *TFramedTransport { |  | ||||||
| 	return NewTFramedTransportConf(transport, &TConfiguration{ |  | ||||||
| 		MaxFrameSize: DEFAULT_MAX_LENGTH, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTFramedTransportConf instead. |  | ||||||
| func NewTFramedTransportMaxLength(transport TTransport, maxLength uint32) *TFramedTransport { |  | ||||||
| 	return NewTFramedTransportConf(transport, &TConfiguration{ |  | ||||||
| 		MaxFrameSize: int32(maxLength), |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTFramedTransportConf(transport TTransport, conf *TConfiguration) *TFramedTransport { |  | ||||||
| 	PropagateTConfiguration(transport, conf) |  | ||||||
| 	return &TFramedTransport{ |  | ||||||
| 		transport: transport, |  | ||||||
| 		reader:    bufio.NewReader(transport), |  | ||||||
| 		cfg:       conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) Open() error { |  | ||||||
| 	return p.transport.Open() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) IsOpen() bool { |  | ||||||
| 	return p.transport.IsOpen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) Close() error { |  | ||||||
| 	return p.transport.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) Read(buf []byte) (read int, err error) { |  | ||||||
| 	read, err = p.readBuf.Read(buf) |  | ||||||
| 	if err != io.EOF { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// For bytes.Buffer.Read, EOF would only happen when read is zero, |  | ||||||
| 	// but still, do a sanity check, |  | ||||||
| 	// in case that behavior is changed in a future version of go stdlib. |  | ||||||
| 	// When that happens, just return nil error, |  | ||||||
| 	// and let the caller call Read again to read the next frame. |  | ||||||
| 	if read > 0 { |  | ||||||
| 		return read, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Reaching here means that the last Read finished the last frame, |  | ||||||
| 	// so we need to read the next frame into readBuf now. |  | ||||||
| 	if err = p.readFrame(); err != nil { |  | ||||||
| 		return read, err |  | ||||||
| 	} |  | ||||||
| 	newRead, err := p.Read(buf[read:]) |  | ||||||
| 	return read + newRead, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) ReadByte() (c byte, err error) { |  | ||||||
| 	buf := p.buffer[:1] |  | ||||||
| 	_, err = p.Read(buf) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	c = buf[0] |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) Write(buf []byte) (int, error) { |  | ||||||
| 	n, err := p.writeBuf.Write(buf) |  | ||||||
| 	return n, NewTTransportExceptionFromError(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) WriteByte(c byte) error { |  | ||||||
| 	return p.writeBuf.WriteByte(c) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) WriteString(s string) (n int, err error) { |  | ||||||
| 	return p.writeBuf.WriteString(s) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) Flush(ctx context.Context) error { |  | ||||||
| 	size := p.writeBuf.Len() |  | ||||||
| 	buf := p.buffer[:4] |  | ||||||
| 	binary.BigEndian.PutUint32(buf, uint32(size)) |  | ||||||
| 	_, err := p.transport.Write(buf) |  | ||||||
| 	if err != nil { |  | ||||||
| 		p.writeBuf.Reset() |  | ||||||
| 		return NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	if size > 0 { |  | ||||||
| 		if _, err := io.Copy(p.transport, &p.writeBuf); err != nil { |  | ||||||
| 			p.writeBuf.Reset() |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	err = p.transport.Flush(ctx) |  | ||||||
| 	return NewTTransportExceptionFromError(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) readFrame() error { |  | ||||||
| 	buf := p.buffer[:4] |  | ||||||
| 	if _, err := io.ReadFull(p.reader, buf); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	size := binary.BigEndian.Uint32(buf) |  | ||||||
| 	if size < 0 || size > uint32(p.cfg.GetMaxFrameSize()) { |  | ||||||
| 		return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, fmt.Sprintf("Incorrect frame size (%d)", size)) |  | ||||||
| 	} |  | ||||||
| 	_, err := io.CopyN(&p.readBuf, p.reader, int64(size)) |  | ||||||
| 	return NewTTransportExceptionFromError(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TFramedTransport) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	return uint64(p.readBuf.Len()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter. |  | ||||||
| func (p *TFramedTransport) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.transport, cfg) |  | ||||||
| 	p.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	_ TConfigurationSetter = (*tFramedTransportFactory)(nil) |  | ||||||
| 	_ TConfigurationSetter = (*TFramedTransport)(nil) |  | ||||||
| ) |  | ||||||
|  | @ -1,110 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // See https://godoc.org/context#WithValue on why do we need the unexported typedefs. |  | ||||||
| type ( |  | ||||||
| 	headerKey     string |  | ||||||
| 	headerKeyList int |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Values for headerKeyList. |  | ||||||
| const ( |  | ||||||
| 	headerKeyListRead headerKeyList = iota |  | ||||||
| 	headerKeyListWrite |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // SetHeader sets a header in the context. |  | ||||||
| func SetHeader(ctx context.Context, key, value string) context.Context { |  | ||||||
| 	return context.WithValue( |  | ||||||
| 		ctx, |  | ||||||
| 		headerKey(key), |  | ||||||
| 		value, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // UnsetHeader unsets a previously set header in the context. |  | ||||||
| func UnsetHeader(ctx context.Context, key string) context.Context { |  | ||||||
| 	return context.WithValue( |  | ||||||
| 		ctx, |  | ||||||
| 		headerKey(key), |  | ||||||
| 		nil, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetHeader returns a value of the given header from the context. |  | ||||||
| func GetHeader(ctx context.Context, key string) (value string, ok bool) { |  | ||||||
| 	if v := ctx.Value(headerKey(key)); v != nil { |  | ||||||
| 		value, ok = v.(string) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetReadHeaderList sets the key list of read THeaders in the context. |  | ||||||
| func SetReadHeaderList(ctx context.Context, keys []string) context.Context { |  | ||||||
| 	return context.WithValue( |  | ||||||
| 		ctx, |  | ||||||
| 		headerKeyListRead, |  | ||||||
| 		keys, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetReadHeaderList returns the key list of read THeaders from the context. |  | ||||||
| func GetReadHeaderList(ctx context.Context) []string { |  | ||||||
| 	if v := ctx.Value(headerKeyListRead); v != nil { |  | ||||||
| 		if value, ok := v.([]string); ok { |  | ||||||
| 			return value |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetWriteHeaderList sets the key list of THeaders to write in the context. |  | ||||||
| func SetWriteHeaderList(ctx context.Context, keys []string) context.Context { |  | ||||||
| 	return context.WithValue( |  | ||||||
| 		ctx, |  | ||||||
| 		headerKeyListWrite, |  | ||||||
| 		keys, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetWriteHeaderList returns the key list of THeaders to write from the context. |  | ||||||
| func GetWriteHeaderList(ctx context.Context) []string { |  | ||||||
| 	if v := ctx.Value(headerKeyListWrite); v != nil { |  | ||||||
| 		if value, ok := v.([]string); ok { |  | ||||||
| 			return value |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AddReadTHeaderToContext adds the whole THeader headers into context. |  | ||||||
| func AddReadTHeaderToContext(ctx context.Context, headers THeaderMap) context.Context { |  | ||||||
| 	keys := make([]string, 0, len(headers)) |  | ||||||
| 	for key, value := range headers { |  | ||||||
| 		ctx = SetHeader(ctx, key, value) |  | ||||||
| 		keys = append(keys, key) |  | ||||||
| 	} |  | ||||||
| 	return SetReadHeaderList(ctx, keys) |  | ||||||
| } |  | ||||||
|  | @ -1,351 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // THeaderProtocol is a thrift protocol that implements THeader: |  | ||||||
| // https://github.com/apache/thrift/blob/master/doc/specs/HeaderFormat.md |  | ||||||
| // |  | ||||||
| // It supports either binary or compact protocol as the wrapped protocol. |  | ||||||
| // |  | ||||||
| // Most of the THeader handlings are happening inside THeaderTransport. |  | ||||||
| type THeaderProtocol struct { |  | ||||||
| 	transport *THeaderTransport |  | ||||||
| 
 |  | ||||||
| 	// Will be initialized on first read/write. |  | ||||||
| 	protocol TProtocol |  | ||||||
| 
 |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHeaderProtocolConf instead. |  | ||||||
| func NewTHeaderProtocol(trans TTransport) *THeaderProtocol { |  | ||||||
| 	return newTHeaderProtocolConf(trans, &TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTHeaderProtocolConf creates a new THeaderProtocol from the underlying |  | ||||||
| // transport with given TConfiguration. |  | ||||||
| // |  | ||||||
| // The passed in transport will be wrapped with THeaderTransport. |  | ||||||
| // |  | ||||||
| // Note that THeaderTransport handles frame and zlib by itself, |  | ||||||
| // so the underlying transport should be a raw socket transports (TSocket or TSSLSocket), |  | ||||||
| // instead of rich transports like TZlibTransport or TFramedTransport. |  | ||||||
| func NewTHeaderProtocolConf(trans TTransport, conf *TConfiguration) *THeaderProtocol { |  | ||||||
| 	return newTHeaderProtocolConf(trans, conf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func newTHeaderProtocolConf(trans TTransport, cfg *TConfiguration) *THeaderProtocol { |  | ||||||
| 	t := NewTHeaderTransportConf(trans, cfg) |  | ||||||
| 	p, _ := t.cfg.GetTHeaderProtocolID().GetProtocol(t) |  | ||||||
| 	PropagateTConfiguration(p, cfg) |  | ||||||
| 	return &THeaderProtocol{ |  | ||||||
| 		transport: t, |  | ||||||
| 		protocol:  p, |  | ||||||
| 		cfg:       cfg, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tHeaderProtocolFactory struct { |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (f tHeaderProtocolFactory) GetProtocol(trans TTransport) TProtocol { |  | ||||||
| 	return newTHeaderProtocolConf(trans, f.cfg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (f *tHeaderProtocolFactory) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	f.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHeaderProtocolFactoryConf instead. |  | ||||||
| func NewTHeaderProtocolFactory() TProtocolFactory { |  | ||||||
| 	return NewTHeaderProtocolFactoryConf(&TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTHeaderProtocolFactoryConf creates a factory for THeader with given |  | ||||||
| // TConfiguration. |  | ||||||
| func NewTHeaderProtocolFactoryConf(conf *TConfiguration) TProtocolFactory { |  | ||||||
| 	return tHeaderProtocolFactory{ |  | ||||||
| 		cfg: conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Transport returns the underlying transport. |  | ||||||
| // |  | ||||||
| // It's guaranteed to be of type *THeaderTransport. |  | ||||||
| func (p *THeaderProtocol) Transport() TTransport { |  | ||||||
| 	return p.transport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetReadHeaders returns the THeaderMap read from transport. |  | ||||||
| func (p *THeaderProtocol) GetReadHeaders() THeaderMap { |  | ||||||
| 	return p.transport.GetReadHeaders() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetWriteHeader sets a header for write. |  | ||||||
| func (p *THeaderProtocol) SetWriteHeader(key, value string) { |  | ||||||
| 	p.transport.SetWriteHeader(key, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ClearWriteHeaders clears all write headers previously set. |  | ||||||
| func (p *THeaderProtocol) ClearWriteHeaders() { |  | ||||||
| 	p.transport.ClearWriteHeaders() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AddTransform add a transform for writing. |  | ||||||
| func (p *THeaderProtocol) AddTransform(transform THeaderTransformID) error { |  | ||||||
| 	return p.transport.AddTransform(transform) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) Flush(ctx context.Context) error { |  | ||||||
| 	return p.transport.Flush(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteMessageBegin(ctx context.Context, name string, typeID TMessageType, seqID int32) error { |  | ||||||
| 	newProto, err := p.transport.Protocol().GetProtocol(p.transport) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	PropagateTConfiguration(newProto, p.cfg) |  | ||||||
| 	p.protocol = newProto |  | ||||||
| 	p.transport.SequenceID = seqID |  | ||||||
| 	return p.protocol.WriteMessageBegin(ctx, name, typeID, seqID) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteMessageEnd(ctx context.Context) error { |  | ||||||
| 	if err := p.protocol.WriteMessageEnd(ctx); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return p.transport.Flush(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteStructBegin(ctx context.Context, name string) error { |  | ||||||
| 	return p.protocol.WriteStructBegin(ctx, name) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteStructEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.WriteStructEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteFieldBegin(ctx context.Context, name string, typeID TType, id int16) error { |  | ||||||
| 	return p.protocol.WriteFieldBegin(ctx, name, typeID, id) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteFieldEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.WriteFieldEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteFieldStop(ctx context.Context) error { |  | ||||||
| 	return p.protocol.WriteFieldStop(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { |  | ||||||
| 	return p.protocol.WriteMapBegin(ctx, keyType, valueType, size) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteMapEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.WriteMapEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	return p.protocol.WriteListBegin(ctx, elemType, size) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteListEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.WriteListEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	return p.protocol.WriteSetBegin(ctx, elemType, size) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteSetEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.WriteSetEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteBool(ctx context.Context, value bool) error { |  | ||||||
| 	return p.protocol.WriteBool(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteByte(ctx context.Context, value int8) error { |  | ||||||
| 	return p.protocol.WriteByte(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteI16(ctx context.Context, value int16) error { |  | ||||||
| 	return p.protocol.WriteI16(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteI32(ctx context.Context, value int32) error { |  | ||||||
| 	return p.protocol.WriteI32(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteI64(ctx context.Context, value int64) error { |  | ||||||
| 	return p.protocol.WriteI64(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteDouble(ctx context.Context, value float64) error { |  | ||||||
| 	return p.protocol.WriteDouble(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteString(ctx context.Context, value string) error { |  | ||||||
| 	return p.protocol.WriteString(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) WriteBinary(ctx context.Context, value []byte) error { |  | ||||||
| 	return p.protocol.WriteBinary(ctx, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ReadFrame calls underlying THeaderTransport's ReadFrame function. |  | ||||||
| func (p *THeaderProtocol) ReadFrame(ctx context.Context) error { |  | ||||||
| 	return p.transport.ReadFrame(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadMessageBegin(ctx context.Context) (name string, typeID TMessageType, seqID int32, err error) { |  | ||||||
| 	if err = p.transport.ReadFrame(ctx); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var newProto TProtocol |  | ||||||
| 	newProto, err = p.transport.Protocol().GetProtocol(p.transport) |  | ||||||
| 	if err != nil { |  | ||||||
| 		var tAppExc TApplicationException |  | ||||||
| 		if !errors.As(err, &tAppExc) { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		if e := p.protocol.WriteMessageBegin(ctx, "", EXCEPTION, seqID); e != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		if e := tAppExc.Write(ctx, p.protocol); e != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		if e := p.protocol.WriteMessageEnd(ctx); e != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		if e := p.transport.Flush(ctx); e != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	PropagateTConfiguration(newProto, p.cfg) |  | ||||||
| 	p.protocol = newProto |  | ||||||
| 
 |  | ||||||
| 	return p.protocol.ReadMessageBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadMessageEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.ReadMessageEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { |  | ||||||
| 	return p.protocol.ReadStructBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadStructEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.ReadStructEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadFieldBegin(ctx context.Context) (name string, typeID TType, id int16, err error) { |  | ||||||
| 	return p.protocol.ReadFieldBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadFieldEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.ReadFieldEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { |  | ||||||
| 	return p.protocol.ReadMapBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadMapEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.ReadMapEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	return p.protocol.ReadListBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadListEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.ReadListEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { |  | ||||||
| 	return p.protocol.ReadSetBegin(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadSetEnd(ctx context.Context) error { |  | ||||||
| 	return p.protocol.ReadSetEnd(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadBool(ctx context.Context) (value bool, err error) { |  | ||||||
| 	return p.protocol.ReadBool(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadByte(ctx context.Context) (value int8, err error) { |  | ||||||
| 	return p.protocol.ReadByte(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadI16(ctx context.Context) (value int16, err error) { |  | ||||||
| 	return p.protocol.ReadI16(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadI32(ctx context.Context) (value int32, err error) { |  | ||||||
| 	return p.protocol.ReadI32(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadI64(ctx context.Context) (value int64, err error) { |  | ||||||
| 	return p.protocol.ReadI64(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadDouble(ctx context.Context) (value float64, err error) { |  | ||||||
| 	return p.protocol.ReadDouble(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadString(ctx context.Context) (value string, err error) { |  | ||||||
| 	return p.protocol.ReadString(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { |  | ||||||
| 	return p.protocol.ReadBinary(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THeaderProtocol) Skip(ctx context.Context, fieldType TType) error { |  | ||||||
| 	return p.protocol.Skip(ctx, fieldType) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter. |  | ||||||
| func (p *THeaderProtocol) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.transport, cfg) |  | ||||||
| 	PropagateTConfiguration(p.protocol, cfg) |  | ||||||
| 	p.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	_ TConfigurationSetter = (*tHeaderProtocolFactory)(nil) |  | ||||||
| 	_ TConfigurationSetter = (*THeaderProtocol)(nil) |  | ||||||
| ) |  | ||||||
|  | @ -1,809 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"bytes" |  | ||||||
| 	"compress/zlib" |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Size in bytes for 32-bit ints. |  | ||||||
| const size32 = 4 |  | ||||||
| 
 |  | ||||||
| type headerMeta struct { |  | ||||||
| 	MagicFlags   uint32 |  | ||||||
| 	SequenceID   int32 |  | ||||||
| 	HeaderLength uint16 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const headerMetaSize = 10 |  | ||||||
| 
 |  | ||||||
| type clientType int |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	clientUnknown clientType = iota |  | ||||||
| 	clientHeaders |  | ||||||
| 	clientFramedBinary |  | ||||||
| 	clientUnframedBinary |  | ||||||
| 	clientFramedCompact |  | ||||||
| 	clientUnframedCompact |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Constants defined in THeader format: |  | ||||||
| // https://github.com/apache/thrift/blob/master/doc/specs/HeaderFormat.md |  | ||||||
| const ( |  | ||||||
| 	THeaderHeaderMagic  uint32 = 0x0fff0000 |  | ||||||
| 	THeaderHeaderMask   uint32 = 0xffff0000 |  | ||||||
| 	THeaderFlagsMask    uint32 = 0x0000ffff |  | ||||||
| 	THeaderMaxFrameSize uint32 = 0x3fffffff |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // THeaderMap is the type of the header map in THeader transport. |  | ||||||
| type THeaderMap map[string]string |  | ||||||
| 
 |  | ||||||
| // THeaderProtocolID is the wrapped protocol id used in THeader. |  | ||||||
| type THeaderProtocolID int32 |  | ||||||
| 
 |  | ||||||
| // Supported THeaderProtocolID values. |  | ||||||
| const ( |  | ||||||
| 	THeaderProtocolBinary  THeaderProtocolID = 0x00 |  | ||||||
| 	THeaderProtocolCompact THeaderProtocolID = 0x02 |  | ||||||
| 	THeaderProtocolDefault                   = THeaderProtocolBinary |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Declared globally to avoid repetitive allocations, not really used. |  | ||||||
| var globalMemoryBuffer = NewTMemoryBuffer() |  | ||||||
| 
 |  | ||||||
| // Validate checks whether the THeaderProtocolID is a valid/supported one. |  | ||||||
| func (id THeaderProtocolID) Validate() error { |  | ||||||
| 	_, err := id.GetProtocol(globalMemoryBuffer) |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetProtocol gets the corresponding TProtocol from the wrapped protocol id. |  | ||||||
| func (id THeaderProtocolID) GetProtocol(trans TTransport) (TProtocol, error) { |  | ||||||
| 	switch id { |  | ||||||
| 	default: |  | ||||||
| 		return nil, NewTApplicationException( |  | ||||||
| 			INVALID_PROTOCOL, |  | ||||||
| 			fmt.Sprintf("THeader protocol id %d not supported", id), |  | ||||||
| 		) |  | ||||||
| 	case THeaderProtocolBinary: |  | ||||||
| 		return NewTBinaryProtocolTransport(trans), nil |  | ||||||
| 	case THeaderProtocolCompact: |  | ||||||
| 		return NewTCompactProtocol(trans), nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // THeaderTransformID defines the numeric id of the transform used. |  | ||||||
| type THeaderTransformID int32 |  | ||||||
| 
 |  | ||||||
| // THeaderTransformID values. |  | ||||||
| // |  | ||||||
| // Values not defined here are not currently supported, namely HMAC and Snappy. |  | ||||||
| const ( |  | ||||||
| 	TransformNone THeaderTransformID = iota // 0, no special handling |  | ||||||
| 	TransformZlib                           // 1, zlib |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var supportedTransformIDs = map[THeaderTransformID]bool{ |  | ||||||
| 	TransformNone: true, |  | ||||||
| 	TransformZlib: true, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TransformReader is an io.ReadCloser that handles transforms reading. |  | ||||||
| type TransformReader struct { |  | ||||||
| 	io.Reader |  | ||||||
| 
 |  | ||||||
| 	closers []io.Closer |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ io.ReadCloser = (*TransformReader)(nil) |  | ||||||
| 
 |  | ||||||
| // NewTransformReaderWithCapacity initializes a TransformReader with expected |  | ||||||
| // closers capacity. |  | ||||||
| // |  | ||||||
| // If you don't know the closers capacity beforehand, just use |  | ||||||
| // |  | ||||||
| //     &TransformReader{Reader: baseReader} |  | ||||||
| // |  | ||||||
| // instead would be sufficient. |  | ||||||
| func NewTransformReaderWithCapacity(baseReader io.Reader, capacity int) *TransformReader { |  | ||||||
| 	return &TransformReader{ |  | ||||||
| 		Reader:  baseReader, |  | ||||||
| 		closers: make([]io.Closer, 0, capacity), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Close calls the underlying closers in appropriate order, |  | ||||||
| // stops at and returns the first error encountered. |  | ||||||
| func (tr *TransformReader) Close() error { |  | ||||||
| 	// Call closers in reversed order |  | ||||||
| 	for i := len(tr.closers) - 1; i >= 0; i-- { |  | ||||||
| 		if err := tr.closers[i].Close(); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AddTransform adds a transform. |  | ||||||
| func (tr *TransformReader) AddTransform(id THeaderTransformID) error { |  | ||||||
| 	switch id { |  | ||||||
| 	default: |  | ||||||
| 		return NewTApplicationException( |  | ||||||
| 			INVALID_TRANSFORM, |  | ||||||
| 			fmt.Sprintf("THeaderTransformID %d not supported", id), |  | ||||||
| 		) |  | ||||||
| 	case TransformNone: |  | ||||||
| 		// no-op |  | ||||||
| 	case TransformZlib: |  | ||||||
| 		readCloser, err := zlib.NewReader(tr.Reader) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		tr.Reader = readCloser |  | ||||||
| 		tr.closers = append(tr.closers, readCloser) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TransformWriter is an io.WriteCloser that handles transforms writing. |  | ||||||
| type TransformWriter struct { |  | ||||||
| 	io.Writer |  | ||||||
| 
 |  | ||||||
| 	closers []io.Closer |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ io.WriteCloser = (*TransformWriter)(nil) |  | ||||||
| 
 |  | ||||||
| // NewTransformWriter creates a new TransformWriter with base writer and transforms. |  | ||||||
| func NewTransformWriter(baseWriter io.Writer, transforms []THeaderTransformID) (io.WriteCloser, error) { |  | ||||||
| 	writer := &TransformWriter{ |  | ||||||
| 		Writer:  baseWriter, |  | ||||||
| 		closers: make([]io.Closer, 0, len(transforms)), |  | ||||||
| 	} |  | ||||||
| 	for _, id := range transforms { |  | ||||||
| 		if err := writer.AddTransform(id); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return writer, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Close calls the underlying closers in appropriate order, |  | ||||||
| // stops at and returns the first error encountered. |  | ||||||
| func (tw *TransformWriter) Close() error { |  | ||||||
| 	// Call closers in reversed order |  | ||||||
| 	for i := len(tw.closers) - 1; i >= 0; i-- { |  | ||||||
| 		if err := tw.closers[i].Close(); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AddTransform adds a transform. |  | ||||||
| func (tw *TransformWriter) AddTransform(id THeaderTransformID) error { |  | ||||||
| 	switch id { |  | ||||||
| 	default: |  | ||||||
| 		return NewTApplicationException( |  | ||||||
| 			INVALID_TRANSFORM, |  | ||||||
| 			fmt.Sprintf("THeaderTransformID %d not supported", id), |  | ||||||
| 		) |  | ||||||
| 	case TransformNone: |  | ||||||
| 		// no-op |  | ||||||
| 	case TransformZlib: |  | ||||||
| 		writeCloser := zlib.NewWriter(tw.Writer) |  | ||||||
| 		tw.Writer = writeCloser |  | ||||||
| 		tw.closers = append(tw.closers, writeCloser) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // THeaderInfoType is the type id of the info headers. |  | ||||||
| type THeaderInfoType int32 |  | ||||||
| 
 |  | ||||||
| // Supported THeaderInfoType values. |  | ||||||
| const ( |  | ||||||
| 	_            THeaderInfoType = iota // Skip 0 |  | ||||||
| 	InfoKeyValue                        // 1 |  | ||||||
| 	// Rest of the info types are not supported. |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // THeaderTransport is a Transport mode that implements THeader. |  | ||||||
| // |  | ||||||
| // Note that THeaderTransport handles frame and zlib by itself, |  | ||||||
| // so the underlying transport should be a raw socket transports (TSocket or TSSLSocket), |  | ||||||
| // instead of rich transports like TZlibTransport or TFramedTransport. |  | ||||||
| type THeaderTransport struct { |  | ||||||
| 	SequenceID int32 |  | ||||||
| 	Flags      uint32 |  | ||||||
| 
 |  | ||||||
| 	transport TTransport |  | ||||||
| 
 |  | ||||||
| 	// THeaderMap for read and write |  | ||||||
| 	readHeaders  THeaderMap |  | ||||||
| 	writeHeaders THeaderMap |  | ||||||
| 
 |  | ||||||
| 	// Reading related variables. |  | ||||||
| 	reader *bufio.Reader |  | ||||||
| 	// When frame is detected, we read the frame fully into frameBuffer. |  | ||||||
| 	frameBuffer bytes.Buffer |  | ||||||
| 	// When it's non-nil, Read should read from frameReader instead of |  | ||||||
| 	// reader, and EOF error indicates end of frame instead of end of all |  | ||||||
| 	// transport. |  | ||||||
| 	frameReader io.ReadCloser |  | ||||||
| 
 |  | ||||||
| 	// Writing related variables |  | ||||||
| 	writeBuffer     bytes.Buffer |  | ||||||
| 	writeTransforms []THeaderTransformID |  | ||||||
| 
 |  | ||||||
| 	clientType clientType |  | ||||||
| 	protocolID THeaderProtocolID |  | ||||||
| 	cfg        *TConfiguration |  | ||||||
| 
 |  | ||||||
| 	// buffer is used in the following scenarios to avoid repetitive |  | ||||||
| 	// allocations, while 4 is big enough for all those scenarios: |  | ||||||
| 	// |  | ||||||
| 	// * header padding (max size 4) |  | ||||||
| 	// * write the frame size (size 4) |  | ||||||
| 	buffer [4]byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TTransport = (*THeaderTransport)(nil) |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHeaderTransportConf instead. |  | ||||||
| func NewTHeaderTransport(trans TTransport) *THeaderTransport { |  | ||||||
| 	return NewTHeaderTransportConf(trans, &TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTHeaderTransportConf creates THeaderTransport from the |  | ||||||
| // underlying transport, with given TConfiguration attached. |  | ||||||
| // |  | ||||||
| // If trans is already a *THeaderTransport, it will be returned as is, |  | ||||||
| // but with TConfiguration overridden by the value passed in. |  | ||||||
| // |  | ||||||
| // The protocol ID in TConfiguration is only useful for client transports. |  | ||||||
| // For servers, |  | ||||||
| // the protocol ID will be overridden again to the one set by the client, |  | ||||||
| // to ensure that servers always speak the same dialect as the client. |  | ||||||
| func NewTHeaderTransportConf(trans TTransport, conf *TConfiguration) *THeaderTransport { |  | ||||||
| 	if ht, ok := trans.(*THeaderTransport); ok { |  | ||||||
| 		ht.SetTConfiguration(conf) |  | ||||||
| 		return ht |  | ||||||
| 	} |  | ||||||
| 	PropagateTConfiguration(trans, conf) |  | ||||||
| 	return &THeaderTransport{ |  | ||||||
| 		transport:    trans, |  | ||||||
| 		reader:       bufio.NewReader(trans), |  | ||||||
| 		writeHeaders: make(THeaderMap), |  | ||||||
| 		protocolID:   conf.GetTHeaderProtocolID(), |  | ||||||
| 		cfg:          conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Open calls the underlying transport's Open function. |  | ||||||
| func (t *THeaderTransport) Open() error { |  | ||||||
| 	return t.transport.Open() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // IsOpen calls the underlying transport's IsOpen function. |  | ||||||
| func (t *THeaderTransport) IsOpen() bool { |  | ||||||
| 	return t.transport.IsOpen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ReadFrame tries to read the frame header, guess the client type, and handle |  | ||||||
| // unframed clients. |  | ||||||
| func (t *THeaderTransport) ReadFrame(ctx context.Context) error { |  | ||||||
| 	if !t.needReadFrame() { |  | ||||||
| 		// No need to read frame, skipping. |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Peek and handle the first 32 bits. |  | ||||||
| 	// They could either be the length field of a framed message, |  | ||||||
| 	// or the first bytes of an unframed message. |  | ||||||
| 	var buf []byte |  | ||||||
| 	var err error |  | ||||||
| 	// This is also usually the first read from a connection, |  | ||||||
| 	// so handle retries around socket timeouts. |  | ||||||
| 	_, deadlineSet := ctx.Deadline() |  | ||||||
| 	for { |  | ||||||
| 		buf, err = t.reader.Peek(size32) |  | ||||||
| 		if deadlineSet && isTimeoutError(err) && ctx.Err() == nil { |  | ||||||
| 			// This is I/O timeout and we still have time, |  | ||||||
| 			// continue trying |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		// For anything else, do not retry |  | ||||||
| 		break |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	frameSize := binary.BigEndian.Uint32(buf) |  | ||||||
| 	if frameSize&VERSION_MASK == VERSION_1 { |  | ||||||
| 		t.clientType = clientUnframedBinary |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if buf[0] == COMPACT_PROTOCOL_ID && buf[1]&COMPACT_VERSION_MASK == COMPACT_VERSION { |  | ||||||
| 		t.clientType = clientUnframedCompact |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// At this point it should be a framed message, |  | ||||||
| 	// sanity check on frameSize then discard the peeked part. |  | ||||||
| 	if frameSize > THeaderMaxFrameSize || frameSize > uint32(t.cfg.GetMaxFrameSize()) { |  | ||||||
| 		return NewTProtocolExceptionWithType( |  | ||||||
| 			SIZE_LIMIT, |  | ||||||
| 			errors.New("frame too large"), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 	t.reader.Discard(size32) |  | ||||||
| 
 |  | ||||||
| 	// Read the frame fully into frameBuffer. |  | ||||||
| 	_, err = io.CopyN(&t.frameBuffer, t.reader, int64(frameSize)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	t.frameReader = io.NopCloser(&t.frameBuffer) |  | ||||||
| 
 |  | ||||||
| 	// Peek and handle the next 32 bits. |  | ||||||
| 	buf = t.frameBuffer.Bytes()[:size32] |  | ||||||
| 	version := binary.BigEndian.Uint32(buf) |  | ||||||
| 	if version&THeaderHeaderMask == THeaderHeaderMagic { |  | ||||||
| 		t.clientType = clientHeaders |  | ||||||
| 		return t.parseHeaders(ctx, frameSize) |  | ||||||
| 	} |  | ||||||
| 	if version&VERSION_MASK == VERSION_1 { |  | ||||||
| 		t.clientType = clientFramedBinary |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if buf[0] == COMPACT_PROTOCOL_ID && buf[1]&COMPACT_VERSION_MASK == COMPACT_VERSION { |  | ||||||
| 		t.clientType = clientFramedCompact |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if err := t.endOfFrame(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return NewTProtocolExceptionWithType( |  | ||||||
| 		NOT_IMPLEMENTED, |  | ||||||
| 		errors.New("unsupported client transport type"), |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // endOfFrame does end of frame handling. |  | ||||||
| // |  | ||||||
| // It closes frameReader, and also resets frame related states. |  | ||||||
| func (t *THeaderTransport) endOfFrame() error { |  | ||||||
| 	defer func() { |  | ||||||
| 		t.frameBuffer.Reset() |  | ||||||
| 		t.frameReader = nil |  | ||||||
| 	}() |  | ||||||
| 	return t.frameReader.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) error { |  | ||||||
| 	if t.clientType != clientHeaders { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var err error |  | ||||||
| 	var meta headerMeta |  | ||||||
| 	if err = binary.Read(&t.frameBuffer, binary.BigEndian, &meta); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	frameSize -= headerMetaSize |  | ||||||
| 	t.Flags = meta.MagicFlags & THeaderFlagsMask |  | ||||||
| 	t.SequenceID = meta.SequenceID |  | ||||||
| 	headerLength := int64(meta.HeaderLength) * 4 |  | ||||||
| 	if int64(frameSize) < headerLength { |  | ||||||
| 		return NewTProtocolExceptionWithType( |  | ||||||
| 			SIZE_LIMIT, |  | ||||||
| 			errors.New("header size is larger than the whole frame"), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 	headerBuf := NewTMemoryBuffer() |  | ||||||
| 	_, err = io.CopyN(headerBuf, &t.frameBuffer, headerLength) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	hp := NewTCompactProtocol(headerBuf) |  | ||||||
| 	hp.SetTConfiguration(t.cfg) |  | ||||||
| 
 |  | ||||||
| 	// At this point the header is already read into headerBuf, |  | ||||||
| 	// and t.frameBuffer starts from the actual payload. |  | ||||||
| 	protoID, err := hp.readVarint32() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	t.protocolID = THeaderProtocolID(protoID) |  | ||||||
| 
 |  | ||||||
| 	var transformCount int32 |  | ||||||
| 	transformCount, err = hp.readVarint32() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if transformCount > 0 { |  | ||||||
| 		reader := NewTransformReaderWithCapacity( |  | ||||||
| 			&t.frameBuffer, |  | ||||||
| 			int(transformCount), |  | ||||||
| 		) |  | ||||||
| 		t.frameReader = reader |  | ||||||
| 		transformIDs := make([]THeaderTransformID, transformCount) |  | ||||||
| 		for i := 0; i < int(transformCount); i++ { |  | ||||||
| 			id, err := hp.readVarint32() |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			transformIDs[i] = THeaderTransformID(id) |  | ||||||
| 		} |  | ||||||
| 		// The transform IDs on the wire was added based on the order of |  | ||||||
| 		// writing, so on the reading side we need to reverse the order. |  | ||||||
| 		for i := transformCount - 1; i >= 0; i-- { |  | ||||||
| 			id := transformIDs[i] |  | ||||||
| 			if err := reader.AddTransform(id); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// The info part does not use the transforms yet, so it's |  | ||||||
| 	// important to continue using headerBuf. |  | ||||||
| 	headers := make(THeaderMap) |  | ||||||
| 	for { |  | ||||||
| 		infoType, err := hp.readVarint32() |  | ||||||
| 		if errors.Is(err, io.EOF) { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		if THeaderInfoType(infoType) == InfoKeyValue { |  | ||||||
| 			count, err := hp.readVarint32() |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			for i := 0; i < int(count); i++ { |  | ||||||
| 				key, err := hp.ReadString(ctx) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 				value, err := hp.ReadString(ctx) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
| 				headers[key] = value |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			// Skip reading info section on the first |  | ||||||
| 			// unsupported info type. |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	t.readHeaders = headers |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *THeaderTransport) needReadFrame() bool { |  | ||||||
| 	if t.clientType == clientUnknown { |  | ||||||
| 		// This is a new connection that's never read before. |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	if t.isFramed() && t.frameReader == nil { |  | ||||||
| 		// We just finished the last frame. |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *THeaderTransport) Read(p []byte) (read int, err error) { |  | ||||||
| 	// Here using context.Background instead of a context passed in is safe. |  | ||||||
| 	// First is that there's no way to pass context into this function. |  | ||||||
| 	// Then, 99% of the case when calling this Read frame is already read |  | ||||||
| 	// into frameReader. ReadFrame here is more of preventing bugs that |  | ||||||
| 	// didn't call ReadFrame before calling Read. |  | ||||||
| 	err = t.ReadFrame(context.Background()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if t.frameReader != nil { |  | ||||||
| 		read, err = t.frameReader.Read(p) |  | ||||||
| 		if err == nil && t.frameBuffer.Len() <= 0 { |  | ||||||
| 			// the last Read finished the frame, do endOfFrame |  | ||||||
| 			// handling here. |  | ||||||
| 			err = t.endOfFrame() |  | ||||||
| 		} else if err == io.EOF { |  | ||||||
| 			err = t.endOfFrame() |  | ||||||
| 			if err != nil { |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			if read == 0 { |  | ||||||
| 				// Try to read the next frame when we hit EOF |  | ||||||
| 				// (end of frame) immediately. |  | ||||||
| 				// When we got here, it means the last read |  | ||||||
| 				// finished the previous frame, but didn't |  | ||||||
| 				// do endOfFrame handling yet. |  | ||||||
| 				// We have to read the next frame here, |  | ||||||
| 				// as otherwise we would return 0 and nil, |  | ||||||
| 				// which is a case not handled well by most |  | ||||||
| 				// protocol implementations. |  | ||||||
| 				return t.Read(p) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return t.reader.Read(p) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write writes data to the write buffer. |  | ||||||
| // |  | ||||||
| // You need to call Flush to actually write them to the transport. |  | ||||||
| func (t *THeaderTransport) Write(p []byte) (int, error) { |  | ||||||
| 	return t.writeBuffer.Write(p) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Flush writes the appropriate header and the write buffer to the underlying transport. |  | ||||||
| func (t *THeaderTransport) Flush(ctx context.Context) error { |  | ||||||
| 	if t.writeBuffer.Len() == 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	defer t.writeBuffer.Reset() |  | ||||||
| 
 |  | ||||||
| 	switch t.clientType { |  | ||||||
| 	default: |  | ||||||
| 		fallthrough |  | ||||||
| 	case clientUnknown: |  | ||||||
| 		t.clientType = clientHeaders |  | ||||||
| 		fallthrough |  | ||||||
| 	case clientHeaders: |  | ||||||
| 		headers := NewTMemoryBuffer() |  | ||||||
| 		hp := NewTCompactProtocol(headers) |  | ||||||
| 		hp.SetTConfiguration(t.cfg) |  | ||||||
| 		if _, err := hp.writeVarint32(int32(t.protocolID)); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		if _, err := hp.writeVarint32(int32(len(t.writeTransforms))); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		for _, transform := range t.writeTransforms { |  | ||||||
| 			if _, err := hp.writeVarint32(int32(transform)); err != nil { |  | ||||||
| 				return NewTTransportExceptionFromError(err) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if len(t.writeHeaders) > 0 { |  | ||||||
| 			if _, err := hp.writeVarint32(int32(InfoKeyValue)); err != nil { |  | ||||||
| 				return NewTTransportExceptionFromError(err) |  | ||||||
| 			} |  | ||||||
| 			if _, err := hp.writeVarint32(int32(len(t.writeHeaders))); err != nil { |  | ||||||
| 				return NewTTransportExceptionFromError(err) |  | ||||||
| 			} |  | ||||||
| 			for key, value := range t.writeHeaders { |  | ||||||
| 				if err := hp.WriteString(ctx, key); err != nil { |  | ||||||
| 					return NewTTransportExceptionFromError(err) |  | ||||||
| 				} |  | ||||||
| 				if err := hp.WriteString(ctx, value); err != nil { |  | ||||||
| 					return NewTTransportExceptionFromError(err) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		padding := 4 - headers.Len()%4 |  | ||||||
| 		if padding < 4 { |  | ||||||
| 			buf := t.buffer[:padding] |  | ||||||
| 			for i := range buf { |  | ||||||
| 				buf[i] = 0 |  | ||||||
| 			} |  | ||||||
| 			if _, err := headers.Write(buf); err != nil { |  | ||||||
| 				return NewTTransportExceptionFromError(err) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		var payload bytes.Buffer |  | ||||||
| 		meta := headerMeta{ |  | ||||||
| 			MagicFlags:   THeaderHeaderMagic + t.Flags&THeaderFlagsMask, |  | ||||||
| 			SequenceID:   t.SequenceID, |  | ||||||
| 			HeaderLength: uint16(headers.Len() / 4), |  | ||||||
| 		} |  | ||||||
| 		if err := binary.Write(&payload, binary.BigEndian, meta); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		if _, err := io.Copy(&payload, headers); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		writer, err := NewTransformWriter(&payload, t.writeTransforms) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		if _, err := io.Copy(writer, &t.writeBuffer); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		if err := writer.Close(); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// First write frame length |  | ||||||
| 		buf := t.buffer[:size32] |  | ||||||
| 		binary.BigEndian.PutUint32(buf, uint32(payload.Len())) |  | ||||||
| 		if _, err := t.transport.Write(buf); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		// Then write the payload |  | ||||||
| 		if _, err := io.Copy(t.transport, &payload); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	case clientFramedBinary, clientFramedCompact: |  | ||||||
| 		buf := t.buffer[:size32] |  | ||||||
| 		binary.BigEndian.PutUint32(buf, uint32(t.writeBuffer.Len())) |  | ||||||
| 		if _, err := t.transport.Write(buf); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		fallthrough |  | ||||||
| 	case clientUnframedBinary, clientUnframedCompact: |  | ||||||
| 		if _, err := io.Copy(t.transport, &t.writeBuffer); err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	select { |  | ||||||
| 	default: |  | ||||||
| 	case <-ctx.Done(): |  | ||||||
| 		return NewTTransportExceptionFromError(ctx.Err()) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return t.transport.Flush(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Close closes the transport, along with its underlying transport. |  | ||||||
| func (t *THeaderTransport) Close() error { |  | ||||||
| 	if err := t.Flush(context.Background()); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return t.transport.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // RemainingBytes calls underlying transport's RemainingBytes. |  | ||||||
| // |  | ||||||
| // Even in framed cases, because of all the possible compression transforms |  | ||||||
| // involved, the remaining frame size is likely to be different from the actual |  | ||||||
| // remaining readable bytes, so we don't bother to keep tracking the remaining |  | ||||||
| // frame size by ourselves and just use the underlying transport's |  | ||||||
| // RemainingBytes directly. |  | ||||||
| func (t *THeaderTransport) RemainingBytes() uint64 { |  | ||||||
| 	return t.transport.RemainingBytes() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetReadHeaders returns the THeaderMap read from transport. |  | ||||||
| func (t *THeaderTransport) GetReadHeaders() THeaderMap { |  | ||||||
| 	return t.readHeaders |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetWriteHeader sets a header for write. |  | ||||||
| func (t *THeaderTransport) SetWriteHeader(key, value string) { |  | ||||||
| 	t.writeHeaders[key] = value |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ClearWriteHeaders clears all write headers previously set. |  | ||||||
| func (t *THeaderTransport) ClearWriteHeaders() { |  | ||||||
| 	t.writeHeaders = make(THeaderMap) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AddTransform add a transform for writing. |  | ||||||
| func (t *THeaderTransport) AddTransform(transform THeaderTransformID) error { |  | ||||||
| 	if !supportedTransformIDs[transform] { |  | ||||||
| 		return NewTProtocolExceptionWithType( |  | ||||||
| 			NOT_IMPLEMENTED, |  | ||||||
| 			fmt.Errorf("THeaderTransformID %d not supported", transform), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 	t.writeTransforms = append(t.writeTransforms, transform) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Protocol returns the wrapped protocol id used in this THeaderTransport. |  | ||||||
| func (t *THeaderTransport) Protocol() THeaderProtocolID { |  | ||||||
| 	switch t.clientType { |  | ||||||
| 	default: |  | ||||||
| 		return t.protocolID |  | ||||||
| 	case clientFramedBinary, clientUnframedBinary: |  | ||||||
| 		return THeaderProtocolBinary |  | ||||||
| 	case clientFramedCompact, clientUnframedCompact: |  | ||||||
| 		return THeaderProtocolCompact |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *THeaderTransport) isFramed() bool { |  | ||||||
| 	switch t.clientType { |  | ||||||
| 	default: |  | ||||||
| 		return false |  | ||||||
| 	case clientHeaders, clientFramedBinary, clientFramedCompact: |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter. |  | ||||||
| func (t *THeaderTransport) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(t.transport, cfg) |  | ||||||
| 	t.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // THeaderTransportFactory is a TTransportFactory implementation to create |  | ||||||
| // THeaderTransport. |  | ||||||
| // |  | ||||||
| // It also implements TConfigurationSetter. |  | ||||||
| type THeaderTransportFactory struct { |  | ||||||
| 	// The underlying factory, could be nil. |  | ||||||
| 	Factory TTransportFactory |  | ||||||
| 
 |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHeaderTransportFactoryConf instead. |  | ||||||
| func NewTHeaderTransportFactory(factory TTransportFactory) TTransportFactory { |  | ||||||
| 	return NewTHeaderTransportFactoryConf(factory, &TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTHeaderTransportFactoryConf creates a new *THeaderTransportFactory with |  | ||||||
| // the given *TConfiguration. |  | ||||||
| func NewTHeaderTransportFactoryConf(factory TTransportFactory, conf *TConfiguration) TTransportFactory { |  | ||||||
| 	return &THeaderTransportFactory{ |  | ||||||
| 		Factory: factory, |  | ||||||
| 
 |  | ||||||
| 		cfg: conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTransport implements TTransportFactory. |  | ||||||
| func (f *THeaderTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	if f.Factory != nil { |  | ||||||
| 		t, err := f.Factory.GetTransport(trans) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		return NewTHeaderTransportConf(t, f.cfg), nil |  | ||||||
| 	} |  | ||||||
| 	return NewTHeaderTransportConf(trans, f.cfg), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter. |  | ||||||
| func (f *THeaderTransportFactory) SetTConfiguration(cfg *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(f.Factory, f.cfg) |  | ||||||
| 	f.cfg = cfg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	_ TConfigurationSetter = (*THeaderTransportFactory)(nil) |  | ||||||
| 	_ TConfigurationSetter = (*THeaderTransport)(nil) |  | ||||||
| ) |  | ||||||
|  | @ -1,257 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| 	"net/http" |  | ||||||
| 	"net/url" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Default to using the shared http client. Library users are |  | ||||||
| // free to change this global client or specify one through |  | ||||||
| // THttpClientOptions. |  | ||||||
| var DefaultHttpClient *http.Client = http.DefaultClient |  | ||||||
| 
 |  | ||||||
| type THttpClient struct { |  | ||||||
| 	client             *http.Client |  | ||||||
| 	response           *http.Response |  | ||||||
| 	url                *url.URL |  | ||||||
| 	requestBuffer      *bytes.Buffer |  | ||||||
| 	header             http.Header |  | ||||||
| 	nsecConnectTimeout int64 |  | ||||||
| 	nsecReadTimeout    int64 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type THttpClientTransportFactory struct { |  | ||||||
| 	options THttpClientOptions |  | ||||||
| 	url     string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClientTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	if trans != nil { |  | ||||||
| 		t, ok := trans.(*THttpClient) |  | ||||||
| 		if ok && t.url != nil { |  | ||||||
| 			return NewTHttpClientWithOptions(t.url.String(), p.options) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return NewTHttpClientWithOptions(p.url, p.options) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type THttpClientOptions struct { |  | ||||||
| 	// If nil, DefaultHttpClient is used |  | ||||||
| 	Client *http.Client |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory { |  | ||||||
| 	return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTHttpClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { |  | ||||||
| 	return &THttpClientTransportFactory{url: url, options: options} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTHttpClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { |  | ||||||
| 	parsedURL, err := url.Parse(urlstr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	buf := make([]byte, 0, 1024) |  | ||||||
| 	client := options.Client |  | ||||||
| 	if client == nil { |  | ||||||
| 		client = DefaultHttpClient |  | ||||||
| 	} |  | ||||||
| 	httpHeader := map[string][]string{"Content-Type": {"application/x-thrift"}} |  | ||||||
| 	return &THttpClient{client: client, url: parsedURL, requestBuffer: bytes.NewBuffer(buf), header: httpHeader}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTHttpClient(urlstr string) (TTransport, error) { |  | ||||||
| 	return NewTHttpClientWithOptions(urlstr, THttpClientOptions{}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Set the HTTP Header for this specific Thrift Transport |  | ||||||
| // It is important that you first assert the TTransport as a THttpClient type |  | ||||||
| // like so: |  | ||||||
| // |  | ||||||
| // httpTrans := trans.(THttpClient) |  | ||||||
| // httpTrans.SetHeader("User-Agent","Thrift Client 1.0") |  | ||||||
| func (p *THttpClient) SetHeader(key string, value string) { |  | ||||||
| 	p.header.Add(key, value) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Get the HTTP Header represented by the supplied Header Key for this specific Thrift Transport |  | ||||||
| // It is important that you first assert the TTransport as a THttpClient type |  | ||||||
| // like so: |  | ||||||
| // |  | ||||||
| // httpTrans := trans.(THttpClient) |  | ||||||
| // hdrValue := httpTrans.GetHeader("User-Agent") |  | ||||||
| func (p *THttpClient) GetHeader(key string) string { |  | ||||||
| 	return p.header.Get(key) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deletes the HTTP Header given a Header Key for this specific Thrift Transport |  | ||||||
| // It is important that you first assert the TTransport as a THttpClient type |  | ||||||
| // like so: |  | ||||||
| // |  | ||||||
| // httpTrans := trans.(THttpClient) |  | ||||||
| // httpTrans.DelHeader("User-Agent") |  | ||||||
| func (p *THttpClient) DelHeader(key string) { |  | ||||||
| 	p.header.Del(key) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) Open() error { |  | ||||||
| 	// do nothing |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) IsOpen() bool { |  | ||||||
| 	return p.response != nil || p.requestBuffer != nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) closeResponse() error { |  | ||||||
| 	var err error |  | ||||||
| 	if p.response != nil && p.response.Body != nil { |  | ||||||
| 		// The docs specify that if keepalive is enabled and the response body is not |  | ||||||
| 		// read to completion the connection will never be returned to the pool and |  | ||||||
| 		// reused. Errors are being ignored here because if the connection is invalid |  | ||||||
| 		// and this fails for some reason, the Close() method will do any remaining |  | ||||||
| 		// cleanup. |  | ||||||
| 		io.Copy(io.Discard, p.response.Body) |  | ||||||
| 
 |  | ||||||
| 		err = p.response.Body.Close() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	p.response = nil |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) Close() error { |  | ||||||
| 	if p.requestBuffer != nil { |  | ||||||
| 		p.requestBuffer.Reset() |  | ||||||
| 		p.requestBuffer = nil |  | ||||||
| 	} |  | ||||||
| 	return p.closeResponse() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) Read(buf []byte) (int, error) { |  | ||||||
| 	if p.response == nil { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.") |  | ||||||
| 	} |  | ||||||
| 	n, err := p.response.Body.Read(buf) |  | ||||||
| 	if n > 0 && (err == nil || errors.Is(err, io.EOF)) { |  | ||||||
| 		return n, nil |  | ||||||
| 	} |  | ||||||
| 	return n, NewTTransportExceptionFromError(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) ReadByte() (c byte, err error) { |  | ||||||
| 	if p.response == nil { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.") |  | ||||||
| 	} |  | ||||||
| 	return readByte(p.response.Body) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) Write(buf []byte) (int, error) { |  | ||||||
| 	if p.requestBuffer == nil { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Request buffer is nil, connection may have been closed.") |  | ||||||
| 	} |  | ||||||
| 	return p.requestBuffer.Write(buf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) WriteByte(c byte) error { |  | ||||||
| 	if p.requestBuffer == nil { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "Request buffer is nil, connection may have been closed.") |  | ||||||
| 	} |  | ||||||
| 	return p.requestBuffer.WriteByte(c) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) WriteString(s string) (n int, err error) { |  | ||||||
| 	if p.requestBuffer == nil { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Request buffer is nil, connection may have been closed.") |  | ||||||
| 	} |  | ||||||
| 	return p.requestBuffer.WriteString(s) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) Flush(ctx context.Context) error { |  | ||||||
| 	// Close any previous response body to avoid leaking connections. |  | ||||||
| 	p.closeResponse() |  | ||||||
| 
 |  | ||||||
| 	// Give up the ownership of the current request buffer to http request, |  | ||||||
| 	// and create a new buffer for the next request. |  | ||||||
| 	buf := p.requestBuffer |  | ||||||
| 	p.requestBuffer = new(bytes.Buffer) |  | ||||||
| 	req, err := http.NewRequest("POST", p.url.String(), buf) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	req.Header = p.header |  | ||||||
| 	if ctx != nil { |  | ||||||
| 		req = req.WithContext(ctx) |  | ||||||
| 	} |  | ||||||
| 	response, err := p.client.Do(req) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	if response.StatusCode != http.StatusOK { |  | ||||||
| 		// Close the response to avoid leaking file descriptors. closeResponse does |  | ||||||
| 		// more than just call Close(), so temporarily assign it and reuse the logic. |  | ||||||
| 		p.response = response |  | ||||||
| 		p.closeResponse() |  | ||||||
| 
 |  | ||||||
| 		// TODO(pomack) log bad response |  | ||||||
| 		return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+strconv.Itoa(response.StatusCode)) |  | ||||||
| 	} |  | ||||||
| 	p.response = response |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *THttpClient) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	len := p.response.ContentLength |  | ||||||
| 	if len >= 0 { |  | ||||||
| 		return uint64(len) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	const maxSize = ^uint64(0) |  | ||||||
| 	return maxSize // the truth is, we just don't know unless framed is used |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHttpClientTransportFactory instead. |  | ||||||
| func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory { |  | ||||||
| 	return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHttpClientTransportFactoryWithOptions instead. |  | ||||||
| func NewTHttpPostClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { |  | ||||||
| 	return NewTHttpClientTransportFactoryWithOptions(url, options) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHttpClientWithOptions instead. |  | ||||||
| func NewTHttpPostClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { |  | ||||||
| 	return NewTHttpClientWithOptions(urlstr, options) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTHttpClient instead. |  | ||||||
| func NewTHttpPostClient(urlstr string) (TTransport, error) { |  | ||||||
| 	return NewTHttpClientWithOptions(urlstr, THttpClientOptions{}) |  | ||||||
| } |  | ||||||
|  | @ -1,74 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"compress/gzip" |  | ||||||
| 	"io" |  | ||||||
| 	"net/http" |  | ||||||
| 	"strings" |  | ||||||
| 	"sync" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function |  | ||||||
| func NewThriftHandlerFunc(processor TProcessor, |  | ||||||
| 	inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { |  | ||||||
| 
 |  | ||||||
| 	return gz(func(w http.ResponseWriter, r *http.Request) { |  | ||||||
| 		w.Header().Add("Content-Type", "application/x-thrift") |  | ||||||
| 
 |  | ||||||
| 		transport := NewStreamTransport(r.Body, w) |  | ||||||
| 		processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // gz transparently compresses the HTTP response if the client supports it. |  | ||||||
| func gz(handler http.HandlerFunc) http.HandlerFunc { |  | ||||||
| 	sp := &sync.Pool{ |  | ||||||
| 		New: func() interface{} { |  | ||||||
| 			return gzip.NewWriter(nil) |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return func(w http.ResponseWriter, r *http.Request) { |  | ||||||
| 		if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { |  | ||||||
| 			handler(w, r) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		w.Header().Set("Content-Encoding", "gzip") |  | ||||||
| 		gz := sp.Get().(*gzip.Writer) |  | ||||||
| 		gz.Reset(w) |  | ||||||
| 		defer func() { |  | ||||||
| 			_ = gz.Close() |  | ||||||
| 			sp.Put(gz) |  | ||||||
| 		}() |  | ||||||
| 		gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w} |  | ||||||
| 		handler(gzw, r) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type gzipResponseWriter struct { |  | ||||||
| 	io.Writer |  | ||||||
| 	http.ResponseWriter |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (w gzipResponseWriter) Write(b []byte) (int, error) { |  | ||||||
| 	return w.Writer.Write(b) |  | ||||||
| } |  | ||||||
|  | @ -1,222 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"context" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // StreamTransport is a Transport made of an io.Reader and/or an io.Writer |  | ||||||
| type StreamTransport struct { |  | ||||||
| 	io.Reader |  | ||||||
| 	io.Writer |  | ||||||
| 	isReadWriter bool |  | ||||||
| 	closed       bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type StreamTransportFactory struct { |  | ||||||
| 	Reader       io.Reader |  | ||||||
| 	Writer       io.Writer |  | ||||||
| 	isReadWriter bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	if trans != nil { |  | ||||||
| 		t, ok := trans.(*StreamTransport) |  | ||||||
| 		if ok { |  | ||||||
| 			if t.isReadWriter { |  | ||||||
| 				return NewStreamTransportRW(t.Reader.(io.ReadWriter)), nil |  | ||||||
| 			} |  | ||||||
| 			if t.Reader != nil && t.Writer != nil { |  | ||||||
| 				return NewStreamTransport(t.Reader, t.Writer), nil |  | ||||||
| 			} |  | ||||||
| 			if t.Reader != nil && t.Writer == nil { |  | ||||||
| 				return NewStreamTransportR(t.Reader), nil |  | ||||||
| 			} |  | ||||||
| 			if t.Reader == nil && t.Writer != nil { |  | ||||||
| 				return NewStreamTransportW(t.Writer), nil |  | ||||||
| 			} |  | ||||||
| 			return &StreamTransport{}, nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if p.isReadWriter { |  | ||||||
| 		return NewStreamTransportRW(p.Reader.(io.ReadWriter)), nil |  | ||||||
| 	} |  | ||||||
| 	if p.Reader != nil && p.Writer != nil { |  | ||||||
| 		return NewStreamTransport(p.Reader, p.Writer), nil |  | ||||||
| 	} |  | ||||||
| 	if p.Reader != nil && p.Writer == nil { |  | ||||||
| 		return NewStreamTransportR(p.Reader), nil |  | ||||||
| 	} |  | ||||||
| 	if p.Reader == nil && p.Writer != nil { |  | ||||||
| 		return NewStreamTransportW(p.Writer), nil |  | ||||||
| 	} |  | ||||||
| 	return &StreamTransport{}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory { |  | ||||||
| 	return &StreamTransportFactory{Reader: reader, Writer: writer, isReadWriter: isReadWriter} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewStreamTransport(r io.Reader, w io.Writer) *StreamTransport { |  | ||||||
| 	return &StreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewStreamTransportR(r io.Reader) *StreamTransport { |  | ||||||
| 	return &StreamTransport{Reader: bufio.NewReader(r)} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewStreamTransportW(w io.Writer) *StreamTransport { |  | ||||||
| 	return &StreamTransport{Writer: bufio.NewWriter(w)} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewStreamTransportRW(rw io.ReadWriter) *StreamTransport { |  | ||||||
| 	bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw)) |  | ||||||
| 	return &StreamTransport{Reader: bufrw, Writer: bufrw, isReadWriter: true} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) IsOpen() bool { |  | ||||||
| 	return !p.closed |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // implicitly opened on creation, can't be reopened once closed |  | ||||||
| func (p *StreamTransport) Open() error { |  | ||||||
| 	if !p.closed { |  | ||||||
| 		return NewTTransportException(ALREADY_OPEN, "StreamTransport already open.") |  | ||||||
| 	} else { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "cannot reopen StreamTransport.") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Closes both the input and output streams. |  | ||||||
| func (p *StreamTransport) Close() error { |  | ||||||
| 	if p.closed { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "StreamTransport already closed.") |  | ||||||
| 	} |  | ||||||
| 	p.closed = true |  | ||||||
| 	closedReader := false |  | ||||||
| 	if p.Reader != nil { |  | ||||||
| 		c, ok := p.Reader.(io.Closer) |  | ||||||
| 		if ok { |  | ||||||
| 			e := c.Close() |  | ||||||
| 			closedReader = true |  | ||||||
| 			if e != nil { |  | ||||||
| 				return e |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		p.Reader = nil |  | ||||||
| 	} |  | ||||||
| 	if p.Writer != nil && (!closedReader || !p.isReadWriter) { |  | ||||||
| 		c, ok := p.Writer.(io.Closer) |  | ||||||
| 		if ok { |  | ||||||
| 			e := c.Close() |  | ||||||
| 			if e != nil { |  | ||||||
| 				return e |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		p.Writer = nil |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Flushes the underlying output stream if not null. |  | ||||||
| func (p *StreamTransport) Flush(ctx context.Context) error { |  | ||||||
| 	if p.Writer == nil { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") |  | ||||||
| 	} |  | ||||||
| 	f, ok := p.Writer.(Flusher) |  | ||||||
| 	if ok { |  | ||||||
| 		err := f.Flush() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) Read(c []byte) (n int, err error) { |  | ||||||
| 	n, err = p.Reader.Read(c) |  | ||||||
| 	if err != nil { |  | ||||||
| 		err = NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) ReadByte() (c byte, err error) { |  | ||||||
| 	f, ok := p.Reader.(io.ByteReader) |  | ||||||
| 	if ok { |  | ||||||
| 		c, err = f.ReadByte() |  | ||||||
| 	} else { |  | ||||||
| 		c, err = readByte(p.Reader) |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		err = NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) Write(c []byte) (n int, err error) { |  | ||||||
| 	n, err = p.Writer.Write(c) |  | ||||||
| 	if err != nil { |  | ||||||
| 		err = NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) WriteByte(c byte) (err error) { |  | ||||||
| 	f, ok := p.Writer.(io.ByteWriter) |  | ||||||
| 	if ok { |  | ||||||
| 		err = f.WriteByte(c) |  | ||||||
| 	} else { |  | ||||||
| 		err = writeByte(p.Writer, c) |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		err = NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) WriteString(s string) (n int, err error) { |  | ||||||
| 	f, ok := p.Writer.(stringWriter) |  | ||||||
| 	if ok { |  | ||||||
| 		n, err = f.WriteString(s) |  | ||||||
| 	} else { |  | ||||||
| 		n, err = p.Writer.Write([]byte(s)) |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		err = NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *StreamTransport) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	const maxSize = ^uint64(0) |  | ||||||
| 	return maxSize // the truth is, we just don't know unless framed is used |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter for propagation. |  | ||||||
| func (p *StreamTransport) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(p.Reader, conf) |  | ||||||
| 	PropagateTConfiguration(p.Writer, conf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*StreamTransport)(nil) |  | ||||||
|  | @ -1,591 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/base64" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	THRIFT_JSON_PROTOCOL_VERSION = 1 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // for references to _ParseContext see tsimplejson_protocol.go |  | ||||||
| 
 |  | ||||||
| // JSON protocol implementation for thrift. |  | ||||||
| // Utilizes Simple JSON protocol |  | ||||||
| // |  | ||||||
| type TJSONProtocol struct { |  | ||||||
| 	*TSimpleJSONProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Constructor |  | ||||||
| func NewTJSONProtocol(t TTransport) *TJSONProtocol { |  | ||||||
| 	v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)} |  | ||||||
| 	v.parseContextStack.push(_CONTEXT_IN_TOPLEVEL) |  | ||||||
| 	v.dumpContext.push(_CONTEXT_IN_TOPLEVEL) |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Factory |  | ||||||
| type TJSONProtocolFactory struct{} |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { |  | ||||||
| 	return NewTJSONProtocol(trans) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTJSONProtocolFactory() *TJSONProtocolFactory { |  | ||||||
| 	return &TJSONProtocolFactory{} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error { |  | ||||||
| 	p.resetContextStack() // THRIFT-3735 |  | ||||||
| 	if e := p.OutputListBegin(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteI32(ctx, THRIFT_JSON_PROTOCOL_VERSION); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteString(ctx, name); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteByte(ctx, int8(typeId)); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteI32(ctx, seqId); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteMessageEnd(ctx context.Context) error { |  | ||||||
| 	return p.OutputListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteStructBegin(ctx context.Context, name string) error { |  | ||||||
| 	if e := p.OutputObjectBegin(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteStructEnd(ctx context.Context) error { |  | ||||||
| 	return p.OutputObjectEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { |  | ||||||
| 	if e := p.WriteI16(ctx, id); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.OutputObjectBegin(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	s, e1 := p.TypeIdToString(typeId) |  | ||||||
| 	if e1 != nil { |  | ||||||
| 		return e1 |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteString(ctx, s); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteFieldEnd(ctx context.Context) error { |  | ||||||
| 	return p.OutputObjectEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteFieldStop(ctx context.Context) error { return nil } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { |  | ||||||
| 	if e := p.OutputListBegin(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	s, e1 := p.TypeIdToString(keyType) |  | ||||||
| 	if e1 != nil { |  | ||||||
| 		return e1 |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteString(ctx, s); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	s, e1 = p.TypeIdToString(valueType) |  | ||||||
| 	if e1 != nil { |  | ||||||
| 		return e1 |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteString(ctx, s); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.WriteI64(ctx, int64(size)); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return p.OutputObjectBegin() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteMapEnd(ctx context.Context) error { |  | ||||||
| 	if e := p.OutputObjectEnd(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return p.OutputListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	return p.OutputElemListBegin(elemType, size) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteListEnd(ctx context.Context) error { |  | ||||||
| 	return p.OutputListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { |  | ||||||
| 	return p.OutputElemListBegin(elemType, size) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteSetEnd(ctx context.Context) error { |  | ||||||
| 	return p.OutputListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteBool(ctx context.Context, b bool) error { |  | ||||||
| 	if b { |  | ||||||
| 		return p.WriteI32(ctx, 1) |  | ||||||
| 	} |  | ||||||
| 	return p.WriteI32(ctx, 0) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteByte(ctx context.Context, b int8) error { |  | ||||||
| 	return p.WriteI32(ctx, int32(b)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteI16(ctx context.Context, v int16) error { |  | ||||||
| 	return p.WriteI32(ctx, int32(v)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteI32(ctx context.Context, v int32) error { |  | ||||||
| 	return p.OutputI64(int64(v)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteI64(ctx context.Context, v int64) error { |  | ||||||
| 	return p.OutputI64(int64(v)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteDouble(ctx context.Context, v float64) error { |  | ||||||
| 	return p.OutputF64(v) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteString(ctx context.Context, v string) error { |  | ||||||
| 	return p.OutputString(v) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) WriteBinary(ctx context.Context, v []byte) error { |  | ||||||
| 	// JSON library only takes in a string, |  | ||||||
| 	// not an arbitrary byte array, to ensure bytes are transmitted |  | ||||||
| 	// efficiently we must convert this into a valid JSON string |  | ||||||
| 	// therefore we use base64 encoding to avoid excessive escaping/quoting |  | ||||||
| 	if e := p.OutputPreValue(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if _, e := p.write(JSON_QUOTE_BYTES); e != nil { |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	writer := base64.NewEncoder(base64.StdEncoding, p.writer) |  | ||||||
| 	if _, e := writer.Write(v); e != nil { |  | ||||||
| 		p.writer.Reset(p.trans) // THRIFT-3735 |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	if e := writer.Close(); e != nil { |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	if _, e := p.write(JSON_QUOTE_BYTES); e != nil { |  | ||||||
| 		return NewTProtocolException(e) |  | ||||||
| 	} |  | ||||||
| 	return p.OutputPostValue() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Reading methods. |  | ||||||
| func (p *TJSONProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { |  | ||||||
| 	p.resetContextStack() // THRIFT-3735 |  | ||||||
| 	if isNull, err := p.ParseListBegin(); isNull || err != nil { |  | ||||||
| 		return name, typeId, seqId, err |  | ||||||
| 	} |  | ||||||
| 	version, err := p.ReadI32(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return name, typeId, seqId, err |  | ||||||
| 	} |  | ||||||
| 	if version != THRIFT_JSON_PROTOCOL_VERSION { |  | ||||||
| 		e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION) |  | ||||||
| 		return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| 	if name, err = p.ReadString(ctx); err != nil { |  | ||||||
| 		return name, typeId, seqId, err |  | ||||||
| 	} |  | ||||||
| 	bTypeId, err := p.ReadByte(ctx) |  | ||||||
| 	typeId = TMessageType(bTypeId) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return name, typeId, seqId, err |  | ||||||
| 	} |  | ||||||
| 	if seqId, err = p.ReadI32(ctx); err != nil { |  | ||||||
| 		return name, typeId, seqId, err |  | ||||||
| 	} |  | ||||||
| 	return name, typeId, seqId, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadMessageEnd(ctx context.Context) error { |  | ||||||
| 	err := p.ParseListEnd() |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { |  | ||||||
| 	_, err = p.ParseObjectStart() |  | ||||||
| 	return "", err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadStructEnd(ctx context.Context) error { |  | ||||||
| 	return p.ParseObjectEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadFieldBegin(ctx context.Context) (string, TType, int16, error) { |  | ||||||
| 	b, _ := p.reader.Peek(1) |  | ||||||
| 	if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] { |  | ||||||
| 		return "", STOP, -1, nil |  | ||||||
| 	} |  | ||||||
| 	fieldId, err := p.ReadI16(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", STOP, fieldId, err |  | ||||||
| 	} |  | ||||||
| 	if _, err = p.ParseObjectStart(); err != nil { |  | ||||||
| 		return "", STOP, fieldId, err |  | ||||||
| 	} |  | ||||||
| 	sType, err := p.ReadString(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", STOP, fieldId, err |  | ||||||
| 	} |  | ||||||
| 	fType, err := p.StringToTypeId(sType) |  | ||||||
| 	return "", fType, fieldId, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadFieldEnd(ctx context.Context) error { |  | ||||||
| 	return p.ParseObjectEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, e error) { |  | ||||||
| 	if isNull, e := p.ParseListBegin(); isNull || e != nil { |  | ||||||
| 		return VOID, VOID, 0, e |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// read keyType |  | ||||||
| 	sKeyType, e := p.ReadString(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return keyType, valueType, size, e |  | ||||||
| 	} |  | ||||||
| 	keyType, e = p.StringToTypeId(sKeyType) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return keyType, valueType, size, e |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// read valueType |  | ||||||
| 	sValueType, e := p.ReadString(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return keyType, valueType, size, e |  | ||||||
| 	} |  | ||||||
| 	valueType, e = p.StringToTypeId(sValueType) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return keyType, valueType, size, e |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// read size |  | ||||||
| 	iSize, e := p.ReadI64(ctx) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return keyType, valueType, size, e |  | ||||||
| 	} |  | ||||||
| 	size = int(iSize) |  | ||||||
| 
 |  | ||||||
| 	_, e = p.ParseObjectStart() |  | ||||||
| 	return keyType, valueType, size, e |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadMapEnd(ctx context.Context) error { |  | ||||||
| 	e := p.ParseObjectEnd() |  | ||||||
| 	if e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return p.ParseListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, e error) { |  | ||||||
| 	return p.ParseElemListBegin() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadListEnd(ctx context.Context) error { |  | ||||||
| 	return p.ParseListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, e error) { |  | ||||||
| 	return p.ParseElemListBegin() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadSetEnd(ctx context.Context) error { |  | ||||||
| 	return p.ParseListEnd() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadBool(ctx context.Context) (bool, error) { |  | ||||||
| 	value, err := p.ReadI32(ctx) |  | ||||||
| 	return (value != 0), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadByte(ctx context.Context) (int8, error) { |  | ||||||
| 	v, err := p.ReadI64(ctx) |  | ||||||
| 	return int8(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadI16(ctx context.Context) (int16, error) { |  | ||||||
| 	v, err := p.ReadI64(ctx) |  | ||||||
| 	return int16(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadI32(ctx context.Context) (int32, error) { |  | ||||||
| 	v, err := p.ReadI64(ctx) |  | ||||||
| 	return int32(v), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadI64(ctx context.Context) (int64, error) { |  | ||||||
| 	v, _, err := p.ParseI64() |  | ||||||
| 	return v, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadDouble(ctx context.Context) (float64, error) { |  | ||||||
| 	v, _, err := p.ParseF64() |  | ||||||
| 	return v, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadString(ctx context.Context) (string, error) { |  | ||||||
| 	var v string |  | ||||||
| 	if err := p.ParsePreValue(); err != nil { |  | ||||||
| 		return v, err |  | ||||||
| 	} |  | ||||||
| 	f, _ := p.reader.Peek(1) |  | ||||||
| 	if len(f) > 0 && f[0] == JSON_QUOTE { |  | ||||||
| 		p.reader.ReadByte() |  | ||||||
| 		value, err := p.ParseStringBody() |  | ||||||
| 		v = value |  | ||||||
| 		if err != nil { |  | ||||||
| 			return v, err |  | ||||||
| 		} |  | ||||||
| 	} else if len(f) > 0 && f[0] == JSON_NULL[0] { |  | ||||||
| 		b := make([]byte, len(JSON_NULL)) |  | ||||||
| 		_, err := p.reader.Read(b) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return v, NewTProtocolException(err) |  | ||||||
| 		} |  | ||||||
| 		if string(b) != string(JSON_NULL) { |  | ||||||
| 			e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) |  | ||||||
| 			return v, NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) |  | ||||||
| 		return v, NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| 	} |  | ||||||
| 	return v, p.ParsePostValue() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ReadBinary(ctx context.Context) ([]byte, error) { |  | ||||||
| 	var v []byte |  | ||||||
| 	if err := p.ParsePreValue(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	f, _ := p.reader.Peek(1) |  | ||||||
| 	if len(f) > 0 && f[0] == JSON_QUOTE { |  | ||||||
| 		p.reader.ReadByte() |  | ||||||
| 		value, err := p.ParseBase64EncodedBody() |  | ||||||
| 		v = value |  | ||||||
| 		if err != nil { |  | ||||||
| 			return v, err |  | ||||||
| 		} |  | ||||||
| 	} else if len(f) > 0 && f[0] == JSON_NULL[0] { |  | ||||||
| 		b := make([]byte, len(JSON_NULL)) |  | ||||||
| 		_, err := p.reader.Read(b) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return v, NewTProtocolException(err) |  | ||||||
| 		} |  | ||||||
| 		if string(b) != string(JSON_NULL) { |  | ||||||
| 			e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) |  | ||||||
| 			return v, NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) |  | ||||||
| 		return v, NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return v, p.ParsePostValue() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) Flush(ctx context.Context) (err error) { |  | ||||||
| 	err = p.writer.Flush() |  | ||||||
| 	if err == nil { |  | ||||||
| 		err = p.trans.Flush(ctx) |  | ||||||
| 	} |  | ||||||
| 	return NewTProtocolException(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) Skip(ctx context.Context, fieldType TType) (err error) { |  | ||||||
| 	return SkipDefaultDepth(ctx, p, fieldType) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) Transport() TTransport { |  | ||||||
| 	return p.trans |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error { |  | ||||||
| 	if e := p.OutputListBegin(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	s, e1 := p.TypeIdToString(elemType) |  | ||||||
| 	if e1 != nil { |  | ||||||
| 		return e1 |  | ||||||
| 	} |  | ||||||
| 	if e := p.OutputString(s); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.OutputI64(int64(size)); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { |  | ||||||
| 	if isNull, e := p.ParseListBegin(); isNull || e != nil { |  | ||||||
| 		return VOID, 0, e |  | ||||||
| 	} |  | ||||||
| 	// We don't really use the ctx in ReadString implementation, |  | ||||||
| 	// so this is safe for now. |  | ||||||
| 	// We might want to add context to ParseElemListBegin if we start to use |  | ||||||
| 	// ctx in ReadString implementation in the future. |  | ||||||
| 	sElemType, err := p.ReadString(context.Background()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return VOID, size, err |  | ||||||
| 	} |  | ||||||
| 	elemType, err = p.StringToTypeId(sElemType) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return elemType, size, err |  | ||||||
| 	} |  | ||||||
| 	nSize, _, err2 := p.ParseI64() |  | ||||||
| 	size = int(nSize) |  | ||||||
| 	return elemType, size, err2 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) { |  | ||||||
| 	if isNull, e := p.ParseListBegin(); isNull || e != nil { |  | ||||||
| 		return VOID, 0, e |  | ||||||
| 	} |  | ||||||
| 	// We don't really use the ctx in ReadString implementation, |  | ||||||
| 	// so this is safe for now. |  | ||||||
| 	// We might want to add context to ParseElemListBegin if we start to use |  | ||||||
| 	// ctx in ReadString implementation in the future. |  | ||||||
| 	sElemType, err := p.ReadString(context.Background()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return VOID, size, err |  | ||||||
| 	} |  | ||||||
| 	elemType, err = p.StringToTypeId(sElemType) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return elemType, size, err |  | ||||||
| 	} |  | ||||||
| 	nSize, _, err2 := p.ParseI64() |  | ||||||
| 	size = int(nSize) |  | ||||||
| 	return elemType, size, err2 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error { |  | ||||||
| 	if e := p.OutputListBegin(); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	s, e1 := p.TypeIdToString(elemType) |  | ||||||
| 	if e1 != nil { |  | ||||||
| 		return e1 |  | ||||||
| 	} |  | ||||||
| 	if e := p.OutputString(s); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	if e := p.OutputI64(int64(size)); e != nil { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) TypeIdToString(fieldType TType) (string, error) { |  | ||||||
| 	switch byte(fieldType) { |  | ||||||
| 	case BOOL: |  | ||||||
| 		return "tf", nil |  | ||||||
| 	case BYTE: |  | ||||||
| 		return "i8", nil |  | ||||||
| 	case I16: |  | ||||||
| 		return "i16", nil |  | ||||||
| 	case I32: |  | ||||||
| 		return "i32", nil |  | ||||||
| 	case I64: |  | ||||||
| 		return "i64", nil |  | ||||||
| 	case DOUBLE: |  | ||||||
| 		return "dbl", nil |  | ||||||
| 	case STRING: |  | ||||||
| 		return "str", nil |  | ||||||
| 	case STRUCT: |  | ||||||
| 		return "rec", nil |  | ||||||
| 	case MAP: |  | ||||||
| 		return "map", nil |  | ||||||
| 	case SET: |  | ||||||
| 		return "set", nil |  | ||||||
| 	case LIST: |  | ||||||
| 		return "lst", nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	e := fmt.Errorf("Unknown fieldType: %d", int(fieldType)) |  | ||||||
| 	return "", NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) { |  | ||||||
| 	switch fieldType { |  | ||||||
| 	case "tf": |  | ||||||
| 		return TType(BOOL), nil |  | ||||||
| 	case "i8": |  | ||||||
| 		return TType(BYTE), nil |  | ||||||
| 	case "i16": |  | ||||||
| 		return TType(I16), nil |  | ||||||
| 	case "i32": |  | ||||||
| 		return TType(I32), nil |  | ||||||
| 	case "i64": |  | ||||||
| 		return TType(I64), nil |  | ||||||
| 	case "dbl": |  | ||||||
| 		return TType(DOUBLE), nil |  | ||||||
| 	case "str": |  | ||||||
| 		return TType(STRING), nil |  | ||||||
| 	case "rec": |  | ||||||
| 		return TType(STRUCT), nil |  | ||||||
| 	case "map": |  | ||||||
| 		return TType(MAP), nil |  | ||||||
| 	case "set": |  | ||||||
| 		return TType(SET), nil |  | ||||||
| 	case "lst": |  | ||||||
| 		return TType(LIST), nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	e := fmt.Errorf("Unknown type identifier: %s", fieldType) |  | ||||||
| 	return TType(STOP), NewTProtocolExceptionWithType(INVALID_DATA, e) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*TJSONProtocol)(nil) |  | ||||||
|  | @ -1,69 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"log" |  | ||||||
| 	"os" |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Logger is a simple wrapper of a logging function. |  | ||||||
| // |  | ||||||
| // In reality the users might actually use different logging libraries, and they |  | ||||||
| // are not always compatible with each other. |  | ||||||
| // |  | ||||||
| // Logger is meant to be a simple common ground that it's easy to wrap whatever |  | ||||||
| // logging library they use into. |  | ||||||
| // |  | ||||||
| // See https://issues.apache.org/jira/browse/THRIFT-4985 for the design |  | ||||||
| // discussion behind it. |  | ||||||
| type Logger func(msg string) |  | ||||||
| 
 |  | ||||||
| // NopLogger is a Logger implementation that does nothing. |  | ||||||
| func NopLogger(msg string) {} |  | ||||||
| 
 |  | ||||||
| // StdLogger wraps stdlib log package into a Logger. |  | ||||||
| // |  | ||||||
| // If logger passed in is nil, it will fallback to use stderr and default flags. |  | ||||||
| func StdLogger(logger *log.Logger) Logger { |  | ||||||
| 	if logger == nil { |  | ||||||
| 		logger = log.New(os.Stderr, "", log.LstdFlags) |  | ||||||
| 	} |  | ||||||
| 	return func(msg string) { |  | ||||||
| 		logger.Print(msg) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TestLogger is a Logger implementation can be used in test codes. |  | ||||||
| // |  | ||||||
| // It fails the test when being called. |  | ||||||
| func TestLogger(tb testing.TB) Logger { |  | ||||||
| 	return func(msg string) { |  | ||||||
| 		tb.Errorf("logger called with msg: %q", msg) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func fallbackLogger(logger Logger) Logger { |  | ||||||
| 	if logger == nil { |  | ||||||
| 		return StdLogger(nil) |  | ||||||
| 	} |  | ||||||
| 	return logger |  | ||||||
| } |  | ||||||
|  | @ -1,80 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Memory buffer-based implementation of the TTransport interface. |  | ||||||
| type TMemoryBuffer struct { |  | ||||||
| 	*bytes.Buffer |  | ||||||
| 	size int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TMemoryBufferTransportFactory struct { |  | ||||||
| 	size int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	if trans != nil { |  | ||||||
| 		t, ok := trans.(*TMemoryBuffer) |  | ||||||
| 		if ok && t.size > 0 { |  | ||||||
| 			return NewTMemoryBufferLen(t.size), nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return NewTMemoryBufferLen(p.size), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory { |  | ||||||
| 	return &TMemoryBufferTransportFactory{size: size} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTMemoryBuffer() *TMemoryBuffer { |  | ||||||
| 	return &TMemoryBuffer{Buffer: &bytes.Buffer{}, size: 0} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTMemoryBufferLen(size int) *TMemoryBuffer { |  | ||||||
| 	buf := make([]byte, 0, size) |  | ||||||
| 	return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TMemoryBuffer) IsOpen() bool { |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TMemoryBuffer) Open() error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TMemoryBuffer) Close() error { |  | ||||||
| 	p.Buffer.Reset() |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Flushing a memory buffer is a no-op |  | ||||||
| func (p *TMemoryBuffer) Flush(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TMemoryBuffer) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	return uint64(p.Buffer.Len()) |  | ||||||
| } |  | ||||||
|  | @ -1,31 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| // Message type constants in the Thrift protocol. |  | ||||||
| type TMessageType int32 |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	INVALID_TMESSAGE_TYPE TMessageType = 0 |  | ||||||
| 	CALL                  TMessageType = 1 |  | ||||||
| 	REPLY                 TMessageType = 2 |  | ||||||
| 	EXCEPTION             TMessageType = 3 |  | ||||||
| 	ONEWAY                TMessageType = 4 |  | ||||||
| ) |  | ||||||
|  | @ -1,109 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import "context" |  | ||||||
| 
 |  | ||||||
| // ProcessorMiddleware is a function that can be passed to WrapProcessor to wrap the |  | ||||||
| // TProcessorFunctions for that TProcessor. |  | ||||||
| // |  | ||||||
| // Middlewares are passed in the name of the function as set in the processor |  | ||||||
| // map of the TProcessor. |  | ||||||
| type ProcessorMiddleware func(name string, next TProcessorFunction) TProcessorFunction |  | ||||||
| 
 |  | ||||||
| // WrapProcessor takes an existing TProcessor and wraps each of its inner |  | ||||||
| // TProcessorFunctions with the middlewares passed in and returns it. |  | ||||||
| // |  | ||||||
| // Middlewares will be called in the order that they are defined: |  | ||||||
| // |  | ||||||
| //		1. Middlewares[0] |  | ||||||
| //		2. Middlewares[1] |  | ||||||
| //		... |  | ||||||
| //		N. Middlewares[n] |  | ||||||
| func WrapProcessor(processor TProcessor, middlewares ...ProcessorMiddleware) TProcessor { |  | ||||||
| 	for name, processorFunc := range processor.ProcessorMap() { |  | ||||||
| 		wrapped := processorFunc |  | ||||||
| 		// Add middlewares in reverse so the first in the list is the outermost. |  | ||||||
| 		for i := len(middlewares) - 1; i >= 0; i-- { |  | ||||||
| 			wrapped = middlewares[i](name, wrapped) |  | ||||||
| 		} |  | ||||||
| 		processor.AddToProcessorMap(name, wrapped) |  | ||||||
| 	} |  | ||||||
| 	return processor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WrappedTProcessorFunction is a convenience struct that implements the |  | ||||||
| // TProcessorFunction interface that can be used when implementing custom |  | ||||||
| // Middleware. |  | ||||||
| type WrappedTProcessorFunction struct { |  | ||||||
| 	// Wrapped is called by WrappedTProcessorFunction.Process and should be a |  | ||||||
| 	// "wrapped" call to a base TProcessorFunc.Process call. |  | ||||||
| 	Wrapped func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Process implements the TProcessorFunction interface using p.Wrapped. |  | ||||||
| func (p WrappedTProcessorFunction) Process(ctx context.Context, seqID int32, in, out TProtocol) (bool, TException) { |  | ||||||
| 	return p.Wrapped(ctx, seqID, in, out) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // verify that WrappedTProcessorFunction implements TProcessorFunction |  | ||||||
| var ( |  | ||||||
| 	_ TProcessorFunction = WrappedTProcessorFunction{} |  | ||||||
| 	_ TProcessorFunction = (*WrappedTProcessorFunction)(nil) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // ClientMiddleware can be passed to WrapClient in order to wrap TClient calls |  | ||||||
| // with custom middleware. |  | ||||||
| type ClientMiddleware func(TClient) TClient |  | ||||||
| 
 |  | ||||||
| // WrappedTClient is a convenience struct that implements the TClient interface |  | ||||||
| // using inner Wrapped function. |  | ||||||
| // |  | ||||||
| // This is provided to aid in developing ClientMiddleware. |  | ||||||
| type WrappedTClient struct { |  | ||||||
| 	Wrapped func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Call implements the TClient interface by calling and returning c.Wrapped. |  | ||||||
| func (c WrappedTClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { |  | ||||||
| 	return c.Wrapped(ctx, method, args, result) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // verify that WrappedTClient implements TClient |  | ||||||
| var ( |  | ||||||
| 	_ TClient = WrappedTClient{} |  | ||||||
| 	_ TClient = (*WrappedTClient)(nil) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // WrapClient wraps the given TClient in the given middlewares. |  | ||||||
| // |  | ||||||
| // Middlewares will be called in the order that they are defined: |  | ||||||
| // |  | ||||||
| //		1. Middlewares[0] |  | ||||||
| //		2. Middlewares[1] |  | ||||||
| //		... |  | ||||||
| //		N. Middlewares[n] |  | ||||||
| func WrapClient(client TClient, middlewares ...ClientMiddleware) TClient { |  | ||||||
| 	// Add middlewares in reverse so the first in the list is the outermost. |  | ||||||
| 	for i := len(middlewares) - 1; i >= 0; i-- { |  | ||||||
| 		client = middlewares[i](client) |  | ||||||
| 	} |  | ||||||
| 	return client |  | ||||||
| } |  | ||||||
|  | @ -1,235 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| TMultiplexedProtocol is a protocol-independent concrete decorator |  | ||||||
| that allows a Thrift client to communicate with a multiplexing Thrift server, |  | ||||||
| by prepending the service name to the function name during function calls. |  | ||||||
| 
 |  | ||||||
| NOTE: THIS IS NOT USED BY SERVERS.  On the server, use TMultiplexedProcessor to handle request |  | ||||||
| from a multiplexing client. |  | ||||||
| 
 |  | ||||||
| This example uses a single socket transport to invoke two services: |  | ||||||
| 
 |  | ||||||
| socket := thrift.NewTSocketFromAddrTimeout(addr, TIMEOUT) |  | ||||||
| transport := thrift.NewTFramedTransport(socket) |  | ||||||
| protocol := thrift.NewTBinaryProtocolTransport(transport) |  | ||||||
| 
 |  | ||||||
| mp := thrift.NewTMultiplexedProtocol(protocol, "Calculator") |  | ||||||
| service := Calculator.NewCalculatorClient(mp) |  | ||||||
| 
 |  | ||||||
| mp2 := thrift.NewTMultiplexedProtocol(protocol, "WeatherReport") |  | ||||||
| service2 := WeatherReport.NewWeatherReportClient(mp2) |  | ||||||
| 
 |  | ||||||
| err := transport.Open() |  | ||||||
| if err != nil { |  | ||||||
| 	t.Fatal("Unable to open client socket", err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fmt.Println(service.Add(2,2)) |  | ||||||
| fmt.Println(service2.GetTemperature()) |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| type TMultiplexedProtocol struct { |  | ||||||
| 	TProtocol |  | ||||||
| 	serviceName string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const MULTIPLEXED_SEPARATOR = ":" |  | ||||||
| 
 |  | ||||||
| func NewTMultiplexedProtocol(protocol TProtocol, serviceName string) *TMultiplexedProtocol { |  | ||||||
| 	return &TMultiplexedProtocol{ |  | ||||||
| 		TProtocol:   protocol, |  | ||||||
| 		serviceName: serviceName, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TMultiplexedProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { |  | ||||||
| 	if typeId == CALL || typeId == ONEWAY { |  | ||||||
| 		return t.TProtocol.WriteMessageBegin(ctx, t.serviceName+MULTIPLEXED_SEPARATOR+name, typeId, seqid) |  | ||||||
| 	} else { |  | ||||||
| 		return t.TProtocol.WriteMessageBegin(ctx, name, typeId, seqid) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| TMultiplexedProcessor is a TProcessor allowing |  | ||||||
| a single TServer to provide multiple services. |  | ||||||
| 
 |  | ||||||
| To do so, you instantiate the processor and then register additional |  | ||||||
| processors with it, as shown in the following example: |  | ||||||
| 
 |  | ||||||
| var processor = thrift.NewTMultiplexedProcessor() |  | ||||||
| 
 |  | ||||||
| firstProcessor := |  | ||||||
| processor.RegisterProcessor("FirstService", firstProcessor) |  | ||||||
| 
 |  | ||||||
| processor.registerProcessor( |  | ||||||
|   "Calculator", |  | ||||||
|   Calculator.NewCalculatorProcessor(&CalculatorHandler{}), |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| processor.registerProcessor( |  | ||||||
|   "WeatherReport", |  | ||||||
|   WeatherReport.NewWeatherReportProcessor(&WeatherReportHandler{}), |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| serverTransport, err := thrift.NewTServerSocketTimeout(addr, TIMEOUT) |  | ||||||
| if err != nil { |  | ||||||
|   t.Fatal("Unable to create server socket", err) |  | ||||||
| } |  | ||||||
| server := thrift.NewTSimpleServer2(processor, serverTransport) |  | ||||||
| server.Serve(); |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| type TMultiplexedProcessor struct { |  | ||||||
| 	serviceProcessorMap map[string]TProcessor |  | ||||||
| 	DefaultProcessor    TProcessor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTMultiplexedProcessor() *TMultiplexedProcessor { |  | ||||||
| 	return &TMultiplexedProcessor{ |  | ||||||
| 		serviceProcessorMap: make(map[string]TProcessor), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ProcessorMap returns a mapping of "{ProcessorName}{MULTIPLEXED_SEPARATOR}{FunctionName}" |  | ||||||
| // to TProcessorFunction for any registered processors.  If there is also a |  | ||||||
| // DefaultProcessor, the keys for the methods on that processor will simply be |  | ||||||
| // "{FunctionName}".  If the TMultiplexedProcessor has both a DefaultProcessor and |  | ||||||
| // other registered processors, then the keys will be a mix of both formats. |  | ||||||
| // |  | ||||||
| // The implementation differs with other TProcessors in that the map returned is |  | ||||||
| // a new map, while most TProcessors just return their internal mapping directly. |  | ||||||
| // This means that edits to the map returned by this implementation of ProcessorMap |  | ||||||
| // will not affect the underlying mapping within the TMultiplexedProcessor. |  | ||||||
| func (t *TMultiplexedProcessor) ProcessorMap() map[string]TProcessorFunction { |  | ||||||
| 	processorFuncMap := make(map[string]TProcessorFunction) |  | ||||||
| 	for name, processor := range t.serviceProcessorMap { |  | ||||||
| 		for method, processorFunc := range processor.ProcessorMap() { |  | ||||||
| 			processorFuncName := name + MULTIPLEXED_SEPARATOR + method |  | ||||||
| 			processorFuncMap[processorFuncName] = processorFunc |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if t.DefaultProcessor != nil { |  | ||||||
| 		for method, processorFunc := range t.DefaultProcessor.ProcessorMap() { |  | ||||||
| 			processorFuncMap[method] = processorFunc |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return processorFuncMap |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AddToProcessorMap updates the underlying TProcessor ProccessorMaps depending on |  | ||||||
| // the format of "name". |  | ||||||
| // |  | ||||||
| // If "name" is in the format "{ProcessorName}{MULTIPLEXED_SEPARATOR}{FunctionName}", |  | ||||||
| // then it sets the given TProcessorFunction on the inner TProcessor with the |  | ||||||
| // ProcessorName component using the FunctionName component. |  | ||||||
| // |  | ||||||
| // If "name" is just in the format "{FunctionName}", that is to say there is no |  | ||||||
| // MULTIPLEXED_SEPARATOR, and the TMultiplexedProcessor has a DefaultProcessor |  | ||||||
| // configured, then it will set the given TProcessorFunction on the DefaultProcessor |  | ||||||
| // using the given name. |  | ||||||
| // |  | ||||||
| // If there is not a TProcessor available for the given name, then this function |  | ||||||
| // does nothing.  This can happen when there is no TProcessor registered for |  | ||||||
| // the given ProcessorName or if all that is given is the FunctionName and there |  | ||||||
| // is no DefaultProcessor set. |  | ||||||
| func (t *TMultiplexedProcessor) AddToProcessorMap(name string, processorFunc TProcessorFunction) { |  | ||||||
| 	processorName, funcName, found := strings.Cut(name, MULTIPLEXED_SEPARATOR) |  | ||||||
| 	if !found { |  | ||||||
| 		if t.DefaultProcessor != nil { |  | ||||||
| 			t.DefaultProcessor.AddToProcessorMap(processorName, processorFunc) |  | ||||||
| 		} |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if processor, ok := t.serviceProcessorMap[processorName]; ok { |  | ||||||
| 		processor.AddToProcessorMap(funcName, processorFunc) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // verify that TMultiplexedProcessor implements TProcessor |  | ||||||
| var _ TProcessor = (*TMultiplexedProcessor)(nil) |  | ||||||
| 
 |  | ||||||
| func (t *TMultiplexedProcessor) RegisterDefault(processor TProcessor) { |  | ||||||
| 	t.DefaultProcessor = processor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TMultiplexedProcessor) RegisterProcessor(name string, processor TProcessor) { |  | ||||||
| 	if t.serviceProcessorMap == nil { |  | ||||||
| 		t.serviceProcessorMap = make(map[string]TProcessor) |  | ||||||
| 	} |  | ||||||
| 	t.serviceProcessorMap[name] = processor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TMultiplexedProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { |  | ||||||
| 	name, typeId, seqid, err := in.ReadMessageBegin(ctx) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return false, NewTProtocolException(err) |  | ||||||
| 	} |  | ||||||
| 	if typeId != CALL && typeId != ONEWAY { |  | ||||||
| 		return false, NewTProtocolException(fmt.Errorf("Unexpected message type %v", typeId)) |  | ||||||
| 	} |  | ||||||
| 	// extract the service name |  | ||||||
| 	processorName, funcName, found := strings.Cut(name, MULTIPLEXED_SEPARATOR) |  | ||||||
| 	if !found { |  | ||||||
| 		if t.DefaultProcessor != nil { |  | ||||||
| 			smb := NewStoredMessageProtocol(in, name, typeId, seqid) |  | ||||||
| 			return t.DefaultProcessor.Process(ctx, smb, out) |  | ||||||
| 		} |  | ||||||
| 		return false, NewTProtocolException(fmt.Errorf( |  | ||||||
| 			"Service name not found in message name: %s.  Did you forget to use a TMultiplexProtocol in your client?", |  | ||||||
| 			name, |  | ||||||
| 		)) |  | ||||||
| 	} |  | ||||||
| 	actualProcessor, ok := t.serviceProcessorMap[processorName] |  | ||||||
| 	if !ok { |  | ||||||
| 		return false, NewTProtocolException(fmt.Errorf( |  | ||||||
| 			"Service name not found: %s.  Did you forget to call registerProcessor()?", |  | ||||||
| 			processorName, |  | ||||||
| 		)) |  | ||||||
| 	} |  | ||||||
| 	smb := NewStoredMessageProtocol(in, funcName, typeId, seqid) |  | ||||||
| 	return actualProcessor.Process(ctx, smb, out) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Protocol that use stored message for ReadMessageBegin |  | ||||||
| type storedMessageProtocol struct { |  | ||||||
| 	TProtocol |  | ||||||
| 	name   string |  | ||||||
| 	typeId TMessageType |  | ||||||
| 	seqid  int32 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewStoredMessageProtocol(protocol TProtocol, name string, typeId TMessageType, seqid int32) *storedMessageProtocol { |  | ||||||
| 	return &storedMessageProtocol{protocol, name, typeId, seqid} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (s *storedMessageProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) { |  | ||||||
| 	return s.name, s.typeId, s.seqid, nil |  | ||||||
| } |  | ||||||
|  | @ -1,164 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"math" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type Numeric interface { |  | ||||||
| 	Int64() int64 |  | ||||||
| 	Int32() int32 |  | ||||||
| 	Int16() int16 |  | ||||||
| 	Byte() byte |  | ||||||
| 	Int() int |  | ||||||
| 	Float64() float64 |  | ||||||
| 	Float32() float32 |  | ||||||
| 	String() string |  | ||||||
| 	isNull() bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type numeric struct { |  | ||||||
| 	iValue int64 |  | ||||||
| 	dValue float64 |  | ||||||
| 	sValue string |  | ||||||
| 	isNil  bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	INFINITY          Numeric |  | ||||||
| 	NEGATIVE_INFINITY Numeric |  | ||||||
| 	NAN               Numeric |  | ||||||
| 	ZERO              Numeric |  | ||||||
| 	NUMERIC_NULL      Numeric |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func NewNumericFromDouble(dValue float64) Numeric { |  | ||||||
| 	if math.IsInf(dValue, 1) { |  | ||||||
| 		return INFINITY |  | ||||||
| 	} |  | ||||||
| 	if math.IsInf(dValue, -1) { |  | ||||||
| 		return NEGATIVE_INFINITY |  | ||||||
| 	} |  | ||||||
| 	if math.IsNaN(dValue) { |  | ||||||
| 		return NAN |  | ||||||
| 	} |  | ||||||
| 	iValue := int64(dValue) |  | ||||||
| 	sValue := strconv.FormatFloat(dValue, 'g', 10, 64) |  | ||||||
| 	isNil := false |  | ||||||
| 	return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewNumericFromI64(iValue int64) Numeric { |  | ||||||
| 	dValue := float64(iValue) |  | ||||||
| 	sValue := strconv.FormatInt(iValue, 10) |  | ||||||
| 	isNil := false |  | ||||||
| 	return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewNumericFromI32(iValue int32) Numeric { |  | ||||||
| 	dValue := float64(iValue) |  | ||||||
| 	sValue := strconv.FormatInt(int64(iValue), 10) |  | ||||||
| 	isNil := false |  | ||||||
| 	return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewNumericFromString(sValue string) Numeric { |  | ||||||
| 	if sValue == INFINITY.String() { |  | ||||||
| 		return INFINITY |  | ||||||
| 	} |  | ||||||
| 	if sValue == NEGATIVE_INFINITY.String() { |  | ||||||
| 		return NEGATIVE_INFINITY |  | ||||||
| 	} |  | ||||||
| 	if sValue == NAN.String() { |  | ||||||
| 		return NAN |  | ||||||
| 	} |  | ||||||
| 	iValue, _ := strconv.ParseInt(sValue, 10, 64) |  | ||||||
| 	dValue, _ := strconv.ParseFloat(sValue, 64) |  | ||||||
| 	isNil := len(sValue) == 0 |  | ||||||
| 	return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewNumericFromJSONString(sValue string, isNull bool) Numeric { |  | ||||||
| 	if isNull { |  | ||||||
| 		return NewNullNumeric() |  | ||||||
| 	} |  | ||||||
| 	if sValue == JSON_INFINITY { |  | ||||||
| 		return INFINITY |  | ||||||
| 	} |  | ||||||
| 	if sValue == JSON_NEGATIVE_INFINITY { |  | ||||||
| 		return NEGATIVE_INFINITY |  | ||||||
| 	} |  | ||||||
| 	if sValue == JSON_NAN { |  | ||||||
| 		return NAN |  | ||||||
| 	} |  | ||||||
| 	iValue, _ := strconv.ParseInt(sValue, 10, 64) |  | ||||||
| 	dValue, _ := strconv.ParseFloat(sValue, 64) |  | ||||||
| 	return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewNullNumeric() Numeric { |  | ||||||
| 	return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Int64() int64 { |  | ||||||
| 	return p.iValue |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Int32() int32 { |  | ||||||
| 	return int32(p.iValue) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Int16() int16 { |  | ||||||
| 	return int16(p.iValue) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Byte() byte { |  | ||||||
| 	return byte(p.iValue) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Int() int { |  | ||||||
| 	return int(p.iValue) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Float64() float64 { |  | ||||||
| 	return p.dValue |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) Float32() float32 { |  | ||||||
| 	return float32(p.dValue) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) String() string { |  | ||||||
| 	return p.sValue |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *numeric) isNull() bool { |  | ||||||
| 	return p.isNil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| 	INFINITY = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false} |  | ||||||
| 	NEGATIVE_INFINITY = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false} |  | ||||||
| 	NAN = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false} |  | ||||||
| 	ZERO = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false} |  | ||||||
| 	NUMERIC_NULL = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true} |  | ||||||
| } |  | ||||||
|  | @ -1,52 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| /////////////////////////////////////////////////////////////////////////////// |  | ||||||
| // This file is home to helpers that convert from various base types to |  | ||||||
| // respective pointer types. This is necessary because Go does not permit |  | ||||||
| // references to constants, nor can a pointer type to base type be allocated |  | ||||||
| // and initialized in a single expression. |  | ||||||
| // |  | ||||||
| // E.g., this is not allowed: |  | ||||||
| // |  | ||||||
| //    var ip *int = &5 |  | ||||||
| // |  | ||||||
| // But this *is* allowed: |  | ||||||
| // |  | ||||||
| //    func IntPtr(i int) *int { return &i } |  | ||||||
| //    var ip *int = IntPtr(5) |  | ||||||
| // |  | ||||||
| // Since pointers to base types are commonplace as [optional] fields in |  | ||||||
| // exported thrift structs, we factor such helpers here. |  | ||||||
| /////////////////////////////////////////////////////////////////////////////// |  | ||||||
| 
 |  | ||||||
| func Float32Ptr(v float32) *float32 { return &v } |  | ||||||
| func Float64Ptr(v float64) *float64 { return &v } |  | ||||||
| func IntPtr(v int) *int             { return &v } |  | ||||||
| func Int8Ptr(v int8) *int8          { return &v } |  | ||||||
| func Int16Ptr(v int16) *int16       { return &v } |  | ||||||
| func Int32Ptr(v int32) *int32       { return &v } |  | ||||||
| func Int64Ptr(v int64) *int64       { return &v } |  | ||||||
| func StringPtr(v string) *string    { return &v } |  | ||||||
| func Uint32Ptr(v uint32) *uint32    { return &v } |  | ||||||
| func Uint64Ptr(v uint64) *uint64    { return &v } |  | ||||||
| func BoolPtr(v bool) *bool          { return &v } |  | ||||||
| func ByteSlicePtr(v []byte) *[]byte { return &v } |  | ||||||
|  | @ -1,80 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import "context" |  | ||||||
| 
 |  | ||||||
| // A processor is a generic object which operates upon an input stream and |  | ||||||
| // writes to some output stream. |  | ||||||
| type TProcessor interface { |  | ||||||
| 	Process(ctx context.Context, in, out TProtocol) (bool, TException) |  | ||||||
| 
 |  | ||||||
| 	// ProcessorMap returns a map of thrift method names to TProcessorFunctions. |  | ||||||
| 	ProcessorMap() map[string]TProcessorFunction |  | ||||||
| 
 |  | ||||||
| 	// AddToProcessorMap adds the given TProcessorFunction to the internal |  | ||||||
| 	// processor map at the given key. |  | ||||||
| 	// |  | ||||||
| 	// If one is already set at the given key, it will be replaced with the new |  | ||||||
| 	// TProcessorFunction. |  | ||||||
| 	AddToProcessorMap(string, TProcessorFunction) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TProcessorFunction interface { |  | ||||||
| 	Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // The default processor factory just returns a singleton |  | ||||||
| // instance. |  | ||||||
| type TProcessorFactory interface { |  | ||||||
| 	GetProcessor(trans TTransport) TProcessor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tProcessorFactory struct { |  | ||||||
| 	processor TProcessor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTProcessorFactory(p TProcessor) TProcessorFactory { |  | ||||||
| 	return &tProcessorFactory{processor: p} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor { |  | ||||||
| 	return p.processor |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * The default processor factory just returns a singleton |  | ||||||
|  * instance. |  | ||||||
|  */ |  | ||||||
| type TProcessorFunctionFactory interface { |  | ||||||
| 	GetProcessorFunction(trans TTransport) TProcessorFunction |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tProcessorFunctionFactory struct { |  | ||||||
| 	processor TProcessorFunction |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory { |  | ||||||
| 	return &tProcessorFunctionFactory{processor: p} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction { |  | ||||||
| 	return p.processor |  | ||||||
| } |  | ||||||
|  | @ -1,177 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	VERSION_MASK = 0xffff0000 |  | ||||||
| 	VERSION_1    = 0x80010000 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TProtocol interface { |  | ||||||
| 	WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error |  | ||||||
| 	WriteMessageEnd(ctx context.Context) error |  | ||||||
| 	WriteStructBegin(ctx context.Context, name string) error |  | ||||||
| 	WriteStructEnd(ctx context.Context) error |  | ||||||
| 	WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error |  | ||||||
| 	WriteFieldEnd(ctx context.Context) error |  | ||||||
| 	WriteFieldStop(ctx context.Context) error |  | ||||||
| 	WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error |  | ||||||
| 	WriteMapEnd(ctx context.Context) error |  | ||||||
| 	WriteListBegin(ctx context.Context, elemType TType, size int) error |  | ||||||
| 	WriteListEnd(ctx context.Context) error |  | ||||||
| 	WriteSetBegin(ctx context.Context, elemType TType, size int) error |  | ||||||
| 	WriteSetEnd(ctx context.Context) error |  | ||||||
| 	WriteBool(ctx context.Context, value bool) error |  | ||||||
| 	WriteByte(ctx context.Context, value int8) error |  | ||||||
| 	WriteI16(ctx context.Context, value int16) error |  | ||||||
| 	WriteI32(ctx context.Context, value int32) error |  | ||||||
| 	WriteI64(ctx context.Context, value int64) error |  | ||||||
| 	WriteDouble(ctx context.Context, value float64) error |  | ||||||
| 	WriteString(ctx context.Context, value string) error |  | ||||||
| 	WriteBinary(ctx context.Context, value []byte) error |  | ||||||
| 
 |  | ||||||
| 	ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) |  | ||||||
| 	ReadMessageEnd(ctx context.Context) error |  | ||||||
| 	ReadStructBegin(ctx context.Context) (name string, err error) |  | ||||||
| 	ReadStructEnd(ctx context.Context) error |  | ||||||
| 	ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) |  | ||||||
| 	ReadFieldEnd(ctx context.Context) error |  | ||||||
| 	ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) |  | ||||||
| 	ReadMapEnd(ctx context.Context) error |  | ||||||
| 	ReadListBegin(ctx context.Context) (elemType TType, size int, err error) |  | ||||||
| 	ReadListEnd(ctx context.Context) error |  | ||||||
| 	ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) |  | ||||||
| 	ReadSetEnd(ctx context.Context) error |  | ||||||
| 	ReadBool(ctx context.Context) (value bool, err error) |  | ||||||
| 	ReadByte(ctx context.Context) (value int8, err error) |  | ||||||
| 	ReadI16(ctx context.Context) (value int16, err error) |  | ||||||
| 	ReadI32(ctx context.Context) (value int32, err error) |  | ||||||
| 	ReadI64(ctx context.Context) (value int64, err error) |  | ||||||
| 	ReadDouble(ctx context.Context) (value float64, err error) |  | ||||||
| 	ReadString(ctx context.Context) (value string, err error) |  | ||||||
| 	ReadBinary(ctx context.Context) (value []byte, err error) |  | ||||||
| 
 |  | ||||||
| 	Skip(ctx context.Context, fieldType TType) (err error) |  | ||||||
| 	Flush(ctx context.Context) (err error) |  | ||||||
| 
 |  | ||||||
| 	Transport() TTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // The maximum recursive depth the skip() function will traverse |  | ||||||
| const DEFAULT_RECURSION_DEPTH = 64 |  | ||||||
| 
 |  | ||||||
| // Skips over the next data element from the provided input TProtocol object. |  | ||||||
| func SkipDefaultDepth(ctx context.Context, prot TProtocol, typeId TType) (err error) { |  | ||||||
| 	return Skip(ctx, prot, typeId, DEFAULT_RECURSION_DEPTH) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Skips over the next data element from the provided input TProtocol object. |  | ||||||
| func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (err error) { |  | ||||||
| 
 |  | ||||||
| 	if maxDepth <= 0 { |  | ||||||
| 		return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded")) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	switch fieldType { |  | ||||||
| 	case BOOL: |  | ||||||
| 		_, err = self.ReadBool(ctx) |  | ||||||
| 		return |  | ||||||
| 	case BYTE: |  | ||||||
| 		_, err = self.ReadByte(ctx) |  | ||||||
| 		return |  | ||||||
| 	case I16: |  | ||||||
| 		_, err = self.ReadI16(ctx) |  | ||||||
| 		return |  | ||||||
| 	case I32: |  | ||||||
| 		_, err = self.ReadI32(ctx) |  | ||||||
| 		return |  | ||||||
| 	case I64: |  | ||||||
| 		_, err = self.ReadI64(ctx) |  | ||||||
| 		return |  | ||||||
| 	case DOUBLE: |  | ||||||
| 		_, err = self.ReadDouble(ctx) |  | ||||||
| 		return |  | ||||||
| 	case STRING: |  | ||||||
| 		_, err = self.ReadString(ctx) |  | ||||||
| 		return |  | ||||||
| 	case STRUCT: |  | ||||||
| 		if _, err = self.ReadStructBegin(ctx); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		for { |  | ||||||
| 			_, typeId, _, _ := self.ReadFieldBegin(ctx) |  | ||||||
| 			if typeId == STOP { |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 			err := Skip(ctx, self, typeId, maxDepth-1) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			self.ReadFieldEnd(ctx) |  | ||||||
| 		} |  | ||||||
| 		return self.ReadStructEnd(ctx) |  | ||||||
| 	case MAP: |  | ||||||
| 		keyType, valueType, size, err := self.ReadMapBegin(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		for i := 0; i < size; i++ { |  | ||||||
| 			err := Skip(ctx, self, keyType, maxDepth-1) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			self.Skip(ctx, valueType) |  | ||||||
| 		} |  | ||||||
| 		return self.ReadMapEnd(ctx) |  | ||||||
| 	case SET: |  | ||||||
| 		elemType, size, err := self.ReadSetBegin(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		for i := 0; i < size; i++ { |  | ||||||
| 			err := Skip(ctx, self, elemType, maxDepth-1) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return self.ReadSetEnd(ctx) |  | ||||||
| 	case LIST: |  | ||||||
| 		elemType, size, err := self.ReadListBegin(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		for i := 0; i < size; i++ { |  | ||||||
| 			err := Skip(ctx, self, elemType, maxDepth-1) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return self.ReadListEnd(ctx) |  | ||||||
| 	default: |  | ||||||
| 		return NewTProtocolExceptionWithType(INVALID_DATA, errors.New(fmt.Sprintf("Unknown data type %d", fieldType))) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  | @ -1,104 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"encoding/base64" |  | ||||||
| 	"errors" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Thrift Protocol exception |  | ||||||
| type TProtocolException interface { |  | ||||||
| 	TException |  | ||||||
| 	TypeId() int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	UNKNOWN_PROTOCOL_EXCEPTION = 0 |  | ||||||
| 	INVALID_DATA               = 1 |  | ||||||
| 	NEGATIVE_SIZE              = 2 |  | ||||||
| 	SIZE_LIMIT                 = 3 |  | ||||||
| 	BAD_VERSION                = 4 |  | ||||||
| 	NOT_IMPLEMENTED            = 5 |  | ||||||
| 	DEPTH_LIMIT                = 6 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type tProtocolException struct { |  | ||||||
| 	typeId int |  | ||||||
| 	err    error |  | ||||||
| 	msg    string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TProtocolException = (*tProtocolException)(nil) |  | ||||||
| 
 |  | ||||||
| func (tProtocolException) TExceptionType() TExceptionType { |  | ||||||
| 	return TExceptionTypeProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tProtocolException) TypeId() int { |  | ||||||
| 	return p.typeId |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tProtocolException) String() string { |  | ||||||
| 	return p.msg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tProtocolException) Error() string { |  | ||||||
| 	return p.msg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tProtocolException) Unwrap() error { |  | ||||||
| 	return p.err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTProtocolException(err error) TProtocolException { |  | ||||||
| 	if err == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if e, ok := err.(TProtocolException); ok { |  | ||||||
| 		return e |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if errors.As(err, new(base64.CorruptInputError)) { |  | ||||||
| 		return NewTProtocolExceptionWithType(INVALID_DATA, err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return NewTProtocolExceptionWithType(UNKNOWN_PROTOCOL_EXCEPTION, err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTProtocolExceptionWithType(errType int, err error) TProtocolException { |  | ||||||
| 	if err == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return &tProtocolException{ |  | ||||||
| 		typeId: errType, |  | ||||||
| 		err:    err, |  | ||||||
| 		msg:    err.Error(), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func prependTProtocolException(prepend string, err TProtocolException) TProtocolException { |  | ||||||
| 	return &tProtocolException{ |  | ||||||
| 		typeId: err.TypeId(), |  | ||||||
| 		err:    err, |  | ||||||
| 		msg:    prepend + err.Error(), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,25 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| // Factory interface for constructing protocol instances. |  | ||||||
| type TProtocolFactory interface { |  | ||||||
| 	GetProtocol(trans TTransport) TProtocol |  | ||||||
| } |  | ||||||
|  | @ -1,94 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // See https://godoc.org/context#WithValue on why do we need the unexported typedefs. |  | ||||||
| type responseHelperKey struct{} |  | ||||||
| 
 |  | ||||||
| // TResponseHelper defines a object with a set of helper functions that can be |  | ||||||
| // retrieved from the context object passed into server handler functions. |  | ||||||
| // |  | ||||||
| // Use GetResponseHelper to retrieve the injected TResponseHelper implementation |  | ||||||
| // from the context object. |  | ||||||
| // |  | ||||||
| // The zero value of TResponseHelper is valid with all helper functions being |  | ||||||
| // no-op. |  | ||||||
| type TResponseHelper struct { |  | ||||||
| 	// THeader related functions |  | ||||||
| 	*THeaderResponseHelper |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // THeaderResponseHelper defines THeader related TResponseHelper functions. |  | ||||||
| // |  | ||||||
| // The zero value of *THeaderResponseHelper is valid with all helper functions |  | ||||||
| // being no-op. |  | ||||||
| type THeaderResponseHelper struct { |  | ||||||
| 	proto *THeaderProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTHeaderResponseHelper creates a new THeaderResponseHelper from the |  | ||||||
| // underlying TProtocol. |  | ||||||
| func NewTHeaderResponseHelper(proto TProtocol) *THeaderResponseHelper { |  | ||||||
| 	if hp, ok := proto.(*THeaderProtocol); ok { |  | ||||||
| 		return &THeaderResponseHelper{ |  | ||||||
| 			proto: hp, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetHeader sets a response header. |  | ||||||
| // |  | ||||||
| // It's no-op if the underlying protocol/transport does not support THeader. |  | ||||||
| func (h *THeaderResponseHelper) SetHeader(key, value string) { |  | ||||||
| 	if h != nil && h.proto != nil { |  | ||||||
| 		h.proto.SetWriteHeader(key, value) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ClearHeaders clears all the response headers previously set. |  | ||||||
| // |  | ||||||
| // It's no-op if the underlying protocol/transport does not support THeader. |  | ||||||
| func (h *THeaderResponseHelper) ClearHeaders() { |  | ||||||
| 	if h != nil && h.proto != nil { |  | ||||||
| 		h.proto.ClearWriteHeaders() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetResponseHelper retrieves the TResponseHelper implementation injected into |  | ||||||
| // the context object. |  | ||||||
| // |  | ||||||
| // If no helper was found in the context object, a nop helper with ok == false |  | ||||||
| // will be returned. |  | ||||||
| func GetResponseHelper(ctx context.Context) (helper TResponseHelper, ok bool) { |  | ||||||
| 	if v := ctx.Value(responseHelperKey{}); v != nil { |  | ||||||
| 		helper, ok = v.(TResponseHelper) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetResponseHelper injects TResponseHelper into the context object. |  | ||||||
| func SetResponseHelper(ctx context.Context, helper TResponseHelper) context.Context { |  | ||||||
| 	return context.WithValue(ctx, responseHelperKey{}, helper) |  | ||||||
| } |  | ||||||
|  | @ -1,71 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type RichTransport struct { |  | ||||||
| 	TTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Wraps Transport to provide TRichTransport interface |  | ||||||
| func NewTRichTransport(trans TTransport) *RichTransport { |  | ||||||
| 	return &RichTransport{trans} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *RichTransport) ReadByte() (c byte, err error) { |  | ||||||
| 	return readByte(r.TTransport) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *RichTransport) WriteByte(c byte) error { |  | ||||||
| 	return writeByte(r.TTransport, c) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *RichTransport) WriteString(s string) (n int, err error) { |  | ||||||
| 	return r.Write([]byte(s)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *RichTransport) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	return r.TTransport.RemainingBytes() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func readByte(r io.Reader) (c byte, err error) { |  | ||||||
| 	v := [1]byte{0} |  | ||||||
| 	n, err := r.Read(v[0:1]) |  | ||||||
| 	if n > 0 && (err == nil || errors.Is(err, io.EOF)) { |  | ||||||
| 		return v[0], nil |  | ||||||
| 	} |  | ||||||
| 	if n > 0 && err != nil { |  | ||||||
| 		return v[0], err |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	return v[0], nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func writeByte(w io.Writer, c byte) error { |  | ||||||
| 	v := [1]byte{c} |  | ||||||
| 	_, err := w.Write(v[0:1]) |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
|  | @ -1,136 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"sync" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TSerializer struct { |  | ||||||
| 	Transport *TMemoryBuffer |  | ||||||
| 	Protocol  TProtocol |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type TStruct interface { |  | ||||||
| 	Write(ctx context.Context, p TProtocol) error |  | ||||||
| 	Read(ctx context.Context, p TProtocol) error |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSerializer() *TSerializer { |  | ||||||
| 	transport := NewTMemoryBufferLen(1024) |  | ||||||
| 	protocol := NewTBinaryProtocolTransport(transport) |  | ||||||
| 
 |  | ||||||
| 	return &TSerializer{ |  | ||||||
| 		Transport: transport, |  | ||||||
| 		Protocol:  protocol, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TSerializer) WriteString(ctx context.Context, msg TStruct) (s string, err error) { |  | ||||||
| 	t.Transport.Reset() |  | ||||||
| 
 |  | ||||||
| 	if err = msg.Write(ctx, t.Protocol); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err = t.Protocol.Flush(ctx); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if err = t.Transport.Flush(ctx); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return t.Transport.String(), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TSerializer) Write(ctx context.Context, msg TStruct) (b []byte, err error) { |  | ||||||
| 	t.Transport.Reset() |  | ||||||
| 
 |  | ||||||
| 	if err = msg.Write(ctx, t.Protocol); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err = t.Protocol.Flush(ctx); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err = t.Transport.Flush(ctx); err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	b = append(b, t.Transport.Bytes()...) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TSerializerPool is the thread-safe version of TSerializer, it uses resource |  | ||||||
| // pool of TSerializer under the hood. |  | ||||||
| // |  | ||||||
| // It must be initialized with either NewTSerializerPool or |  | ||||||
| // NewTSerializerPoolSizeFactory. |  | ||||||
| type TSerializerPool struct { |  | ||||||
| 	pool sync.Pool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSerializerPool creates a new TSerializerPool. |  | ||||||
| // |  | ||||||
| // NewTSerializer can be used as the arg here. |  | ||||||
| func NewTSerializerPool(f func() *TSerializer) *TSerializerPool { |  | ||||||
| 	return &TSerializerPool{ |  | ||||||
| 		pool: sync.Pool{ |  | ||||||
| 			New: func() interface{} { |  | ||||||
| 				return f() |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSerializerPoolSizeFactory creates a new TSerializerPool with the given |  | ||||||
| // size and protocol factory. |  | ||||||
| // |  | ||||||
| // Note that the size is not the limit. The TMemoryBuffer underneath can grow |  | ||||||
| // larger than that. It just dictates the initial size. |  | ||||||
| func NewTSerializerPoolSizeFactory(size int, factory TProtocolFactory) *TSerializerPool { |  | ||||||
| 	return &TSerializerPool{ |  | ||||||
| 		pool: sync.Pool{ |  | ||||||
| 			New: func() interface{} { |  | ||||||
| 				transport := NewTMemoryBufferLen(size) |  | ||||||
| 				protocol := factory.GetProtocol(transport) |  | ||||||
| 
 |  | ||||||
| 				return &TSerializer{ |  | ||||||
| 					Transport: transport, |  | ||||||
| 					Protocol:  protocol, |  | ||||||
| 				} |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TSerializerPool) WriteString(ctx context.Context, msg TStruct) (string, error) { |  | ||||||
| 	s := t.pool.Get().(*TSerializer) |  | ||||||
| 	defer t.pool.Put(s) |  | ||||||
| 	return s.WriteString(ctx, msg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *TSerializerPool) Write(ctx context.Context, msg TStruct) ([]byte, error) { |  | ||||||
| 	s := t.pool.Get().(*TSerializer) |  | ||||||
| 	defer t.pool.Put(s) |  | ||||||
| 	return s.Write(ctx, msg) |  | ||||||
| } |  | ||||||
|  | @ -1,35 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| type TServer interface { |  | ||||||
| 	ProcessorFactory() TProcessorFactory |  | ||||||
| 	ServerTransport() TServerTransport |  | ||||||
| 	InputTransportFactory() TTransportFactory |  | ||||||
| 	OutputTransportFactory() TTransportFactory |  | ||||||
| 	InputProtocolFactory() TProtocolFactory |  | ||||||
| 	OutputProtocolFactory() TProtocolFactory |  | ||||||
| 
 |  | ||||||
| 	// Starts the server |  | ||||||
| 	Serve() error |  | ||||||
| 	// Stops the server. This is optional on a per-implementation basis. Not |  | ||||||
| 	// all servers are required to be cleanly stoppable. |  | ||||||
| 	Stop() error |  | ||||||
| } |  | ||||||
|  | @ -1,137 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"net" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TServerSocket struct { |  | ||||||
| 	listener      net.Listener |  | ||||||
| 	addr          net.Addr |  | ||||||
| 	clientTimeout time.Duration |  | ||||||
| 
 |  | ||||||
| 	// Protects the interrupted value to make it thread safe. |  | ||||||
| 	mu          sync.RWMutex |  | ||||||
| 	interrupted bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTServerSocket(listenAddr string) (*TServerSocket, error) { |  | ||||||
| 	return NewTServerSocketTimeout(listenAddr, 0) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTServerSocketTimeout(listenAddr string, clientTimeout time.Duration) (*TServerSocket, error) { |  | ||||||
| 	addr, err := net.ResolveTCPAddr("tcp", listenAddr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Creates a TServerSocket from a net.Addr |  | ||||||
| func NewTServerSocketFromAddrTimeout(addr net.Addr, clientTimeout time.Duration) *TServerSocket { |  | ||||||
| 	return &TServerSocket{addr: addr, clientTimeout: clientTimeout} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TServerSocket) Listen() error { |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	defer p.mu.Unlock() |  | ||||||
| 	if p.IsListening() { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	l, err := net.Listen(p.addr.Network(), p.addr.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	p.listener = l |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TServerSocket) Accept() (TTransport, error) { |  | ||||||
| 	p.mu.RLock() |  | ||||||
| 	interrupted := p.interrupted |  | ||||||
| 	p.mu.RUnlock() |  | ||||||
| 
 |  | ||||||
| 	if interrupted { |  | ||||||
| 		return nil, errTransportInterrupted |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	listener := p.listener |  | ||||||
| 	p.mu.Unlock() |  | ||||||
| 	if listener == nil { |  | ||||||
| 		return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	conn, err := listener.Accept() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return NewTSocketFromConnTimeout(conn, p.clientTimeout), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Checks whether the socket is listening. |  | ||||||
| func (p *TServerSocket) IsListening() bool { |  | ||||||
| 	return p.listener != nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Connects the socket, creating a new socket object if necessary. |  | ||||||
| func (p *TServerSocket) Open() error { |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	defer p.mu.Unlock() |  | ||||||
| 	if p.IsListening() { |  | ||||||
| 		return NewTTransportException(ALREADY_OPEN, "Server socket already open") |  | ||||||
| 	} |  | ||||||
| 	if l, err := net.Listen(p.addr.Network(), p.addr.String()); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} else { |  | ||||||
| 		p.listener = l |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TServerSocket) Addr() net.Addr { |  | ||||||
| 	if p.listener != nil { |  | ||||||
| 		return p.listener.Addr() |  | ||||||
| 	} |  | ||||||
| 	return p.addr |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TServerSocket) Close() error { |  | ||||||
| 	var err error |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	if p.IsListening() { |  | ||||||
| 		err = p.listener.Close() |  | ||||||
| 		p.listener = nil |  | ||||||
| 	} |  | ||||||
| 	p.mu.Unlock() |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TServerSocket) Interrupt() error { |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	p.interrupted = true |  | ||||||
| 	p.mu.Unlock() |  | ||||||
| 	p.Close() |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  | @ -1,34 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| // Server transport. Object which provides client transports. |  | ||||||
| type TServerTransport interface { |  | ||||||
| 	Listen() error |  | ||||||
| 	Accept() (TTransport, error) |  | ||||||
| 	Close() error |  | ||||||
| 
 |  | ||||||
| 	// Optional method implementation. This signals to the server transport |  | ||||||
| 	// that it should break out of any accept() or listen() that it is currently |  | ||||||
| 	// blocked on. This method, if implemented, MUST be thread safe, as it may |  | ||||||
| 	// be called from a different thread context than the other TServerTransport |  | ||||||
| 	// methods. |  | ||||||
| 	Interrupt() error |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,332 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"sync" |  | ||||||
| 	"sync/atomic" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // ErrAbandonRequest is a special error server handler implementations can |  | ||||||
| // return to indicate that the request has been abandoned. |  | ||||||
| // |  | ||||||
| // TSimpleServer will check for this error, and close the client connection |  | ||||||
| // instead of writing the response/error back to the client. |  | ||||||
| // |  | ||||||
| // It shall only be used when the server handler implementation know that the |  | ||||||
| // client already abandoned the request (by checking that the passed in context |  | ||||||
| // is already canceled, for example). |  | ||||||
| var ErrAbandonRequest = errors.New("request abandoned") |  | ||||||
| 
 |  | ||||||
| // ServerConnectivityCheckInterval defines the ticker interval used by |  | ||||||
| // connectivity check in thrift compiled TProcessorFunc implementations. |  | ||||||
| // |  | ||||||
| // It's defined as a variable instead of constant, so that thrift server |  | ||||||
| // implementations can change its value to control the behavior. |  | ||||||
| // |  | ||||||
| // If it's changed to <=0, the feature will be disabled. |  | ||||||
| var ServerConnectivityCheckInterval = time.Millisecond * 5 |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * This is not a typical TSimpleServer as it is not blocked after accept a socket. |  | ||||||
|  * It is more like a TThreadedServer that can handle different connections in different goroutines. |  | ||||||
|  * This will work if golang user implements a conn-pool like thing in client side. |  | ||||||
|  */ |  | ||||||
| type TSimpleServer struct { |  | ||||||
| 	closed int32 |  | ||||||
| 	wg     sync.WaitGroup |  | ||||||
| 	mu     sync.Mutex |  | ||||||
| 
 |  | ||||||
| 	processorFactory       TProcessorFactory |  | ||||||
| 	serverTransport        TServerTransport |  | ||||||
| 	inputTransportFactory  TTransportFactory |  | ||||||
| 	outputTransportFactory TTransportFactory |  | ||||||
| 	inputProtocolFactory   TProtocolFactory |  | ||||||
| 	outputProtocolFactory  TProtocolFactory |  | ||||||
| 
 |  | ||||||
| 	// Headers to auto forward in THeaderProtocol |  | ||||||
| 	forwardHeaders []string |  | ||||||
| 
 |  | ||||||
| 	logger Logger |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSimpleServer2(processor TProcessor, serverTransport TServerTransport) *TSimpleServer { |  | ||||||
| 	return NewTSimpleServerFactory2(NewTProcessorFactory(processor), serverTransport) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSimpleServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer { |  | ||||||
| 	return NewTSimpleServerFactory4(NewTProcessorFactory(processor), |  | ||||||
| 		serverTransport, |  | ||||||
| 		transportFactory, |  | ||||||
| 		protocolFactory, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSimpleServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer { |  | ||||||
| 	return NewTSimpleServerFactory6(NewTProcessorFactory(processor), |  | ||||||
| 		serverTransport, |  | ||||||
| 		inputTransportFactory, |  | ||||||
| 		outputTransportFactory, |  | ||||||
| 		inputProtocolFactory, |  | ||||||
| 		outputProtocolFactory, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSimpleServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TSimpleServer { |  | ||||||
| 	return NewTSimpleServerFactory6(processorFactory, |  | ||||||
| 		serverTransport, |  | ||||||
| 		NewTTransportFactory(), |  | ||||||
| 		NewTTransportFactory(), |  | ||||||
| 		NewTBinaryProtocolFactoryDefault(), |  | ||||||
| 		NewTBinaryProtocolFactoryDefault(), |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSimpleServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer { |  | ||||||
| 	return NewTSimpleServerFactory6(processorFactory, |  | ||||||
| 		serverTransport, |  | ||||||
| 		transportFactory, |  | ||||||
| 		transportFactory, |  | ||||||
| 		protocolFactory, |  | ||||||
| 		protocolFactory, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer { |  | ||||||
| 	return &TSimpleServer{ |  | ||||||
| 		processorFactory:       processorFactory, |  | ||||||
| 		serverTransport:        serverTransport, |  | ||||||
| 		inputTransportFactory:  inputTransportFactory, |  | ||||||
| 		outputTransportFactory: outputTransportFactory, |  | ||||||
| 		inputProtocolFactory:   inputProtocolFactory, |  | ||||||
| 		outputProtocolFactory:  outputProtocolFactory, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) ProcessorFactory() TProcessorFactory { |  | ||||||
| 	return p.processorFactory |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) ServerTransport() TServerTransport { |  | ||||||
| 	return p.serverTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) InputTransportFactory() TTransportFactory { |  | ||||||
| 	return p.inputTransportFactory |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) OutputTransportFactory() TTransportFactory { |  | ||||||
| 	return p.outputTransportFactory |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) InputProtocolFactory() TProtocolFactory { |  | ||||||
| 	return p.inputProtocolFactory |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) OutputProtocolFactory() TProtocolFactory { |  | ||||||
| 	return p.outputProtocolFactory |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) Listen() error { |  | ||||||
| 	return p.serverTransport.Listen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetForwardHeaders sets the list of header keys that will be auto forwarded |  | ||||||
| // while using THeaderProtocol. |  | ||||||
| // |  | ||||||
| // "forward" means that when the server is also a client to other upstream |  | ||||||
| // thrift servers, the context object user gets in the processor functions will |  | ||||||
| // have both read and write headers set, with write headers being forwarded. |  | ||||||
| // Users can always override the write headers by calling SetWriteHeaderList |  | ||||||
| // before calling thrift client functions. |  | ||||||
| func (p *TSimpleServer) SetForwardHeaders(headers []string) { |  | ||||||
| 	size := len(headers) |  | ||||||
| 	if size == 0 { |  | ||||||
| 		p.forwardHeaders = nil |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	keys := make([]string, size) |  | ||||||
| 	copy(keys, headers) |  | ||||||
| 	p.forwardHeaders = keys |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetLogger sets the logger used by this TSimpleServer. |  | ||||||
| // |  | ||||||
| // If no logger was set before Serve is called, a default logger using standard |  | ||||||
| // log library will be used. |  | ||||||
| func (p *TSimpleServer) SetLogger(logger Logger) { |  | ||||||
| 	p.logger = logger |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) innerAccept() (int32, error) { |  | ||||||
| 	client, err := p.serverTransport.Accept() |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	defer p.mu.Unlock() |  | ||||||
| 	closed := atomic.LoadInt32(&p.closed) |  | ||||||
| 	if closed != 0 { |  | ||||||
| 		return closed, nil |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	if client != nil { |  | ||||||
| 		p.wg.Add(1) |  | ||||||
| 		go func() { |  | ||||||
| 			defer p.wg.Done() |  | ||||||
| 			if err := p.processRequests(client); err != nil { |  | ||||||
| 				p.logger(fmt.Sprintf("error processing request: %v", err)) |  | ||||||
| 			} |  | ||||||
| 		}() |  | ||||||
| 	} |  | ||||||
| 	return 0, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) AcceptLoop() error { |  | ||||||
| 	for { |  | ||||||
| 		closed, err := p.innerAccept() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		if closed != 0 { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) Serve() error { |  | ||||||
| 	p.logger = fallbackLogger(p.logger) |  | ||||||
| 
 |  | ||||||
| 	err := p.Listen() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	p.AcceptLoop() |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) Stop() error { |  | ||||||
| 	p.mu.Lock() |  | ||||||
| 	defer p.mu.Unlock() |  | ||||||
| 	if atomic.LoadInt32(&p.closed) != 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	atomic.StoreInt32(&p.closed, 1) |  | ||||||
| 	p.serverTransport.Interrupt() |  | ||||||
| 	p.wg.Wait() |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // If err is actually EOF, return nil, otherwise return err as-is. |  | ||||||
| func treatEOFErrorsAsNil(err error) error { |  | ||||||
| 	if err == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if errors.Is(err, io.EOF) { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	var te TTransportException |  | ||||||
| 	if errors.As(err, &te) && te.TypeId() == END_OF_FILE { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSimpleServer) processRequests(client TTransport) (err error) { |  | ||||||
| 	defer func() { |  | ||||||
| 		err = treatEOFErrorsAsNil(err) |  | ||||||
| 	}() |  | ||||||
| 
 |  | ||||||
| 	processor := p.processorFactory.GetProcessor(client) |  | ||||||
| 	inputTransport, err := p.inputTransportFactory.GetTransport(client) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport) |  | ||||||
| 	var outputTransport TTransport |  | ||||||
| 	var outputProtocol TProtocol |  | ||||||
| 
 |  | ||||||
| 	// for THeaderProtocol, we must use the same protocol instance for |  | ||||||
| 	// input and output so that the response is in the same dialect that |  | ||||||
| 	// the server detected the request was in. |  | ||||||
| 	headerProtocol, ok := inputProtocol.(*THeaderProtocol) |  | ||||||
| 	if ok { |  | ||||||
| 		outputProtocol = inputProtocol |  | ||||||
| 	} else { |  | ||||||
| 		oTrans, err := p.outputTransportFactory.GetTransport(client) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		outputTransport = oTrans |  | ||||||
| 		outputProtocol = p.outputProtocolFactory.GetProtocol(outputTransport) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if inputTransport != nil { |  | ||||||
| 		defer inputTransport.Close() |  | ||||||
| 	} |  | ||||||
| 	if outputTransport != nil { |  | ||||||
| 		defer outputTransport.Close() |  | ||||||
| 	} |  | ||||||
| 	for { |  | ||||||
| 		if atomic.LoadInt32(&p.closed) != 0 { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		ctx := SetResponseHelper( |  | ||||||
| 			defaultCtx, |  | ||||||
| 			TResponseHelper{ |  | ||||||
| 				THeaderResponseHelper: NewTHeaderResponseHelper(outputProtocol), |  | ||||||
| 			}, |  | ||||||
| 		) |  | ||||||
| 		if headerProtocol != nil { |  | ||||||
| 			// We need to call ReadFrame here, otherwise we won't |  | ||||||
| 			// get any headers on the AddReadTHeaderToContext call. |  | ||||||
| 			// |  | ||||||
| 			// ReadFrame is safe to be called multiple times so it |  | ||||||
| 			// won't break when it's called again later when we |  | ||||||
| 			// actually start to read the message. |  | ||||||
| 			if err := headerProtocol.ReadFrame(ctx); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			ctx = AddReadTHeaderToContext(ctx, headerProtocol.GetReadHeaders()) |  | ||||||
| 			ctx = SetWriteHeaderList(ctx, p.forwardHeaders) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		ok, err := processor.Process(ctx, inputProtocol, outputProtocol) |  | ||||||
| 		if errors.Is(err, ErrAbandonRequest) { |  | ||||||
| 			return client.Close() |  | ||||||
| 		} |  | ||||||
| 		if errors.As(err, new(TTransportException)) && err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		var tae TApplicationException |  | ||||||
| 		if errors.As(err, &tae) && tae.TypeId() == UNKNOWN_METHOD { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if !ok { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  | @ -1,238 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"net" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TSocket struct { |  | ||||||
| 	conn *socketConn |  | ||||||
| 	addr net.Addr |  | ||||||
| 	cfg  *TConfiguration |  | ||||||
| 
 |  | ||||||
| 	connectTimeout time.Duration |  | ||||||
| 	socketTimeout  time.Duration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSocketConf instead. |  | ||||||
| func NewTSocket(hostPort string) (*TSocket, error) { |  | ||||||
| 	return NewTSocketConf(hostPort, &TConfiguration{ |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSocketConf creates a net.Conn-backed TTransport, given a host and port. |  | ||||||
| // |  | ||||||
| // Example: |  | ||||||
| // |  | ||||||
| //     trans, err := thrift.NewTSocketConf("localhost:9090", &TConfiguration{ |  | ||||||
| //         ConnectTimeout: time.Second, // Use 0 for no timeout |  | ||||||
| //         SocketTimeout:  time.Second, // Use 0 for no timeout |  | ||||||
| //     }) |  | ||||||
| func NewTSocketConf(hostPort string, conf *TConfiguration) (*TSocket, error) { |  | ||||||
| 	addr, err := net.ResolveTCPAddr("tcp", hostPort) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return NewTSocketFromAddrConf(addr, conf), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSocketConf instead. |  | ||||||
| func NewTSocketTimeout(hostPort string, connTimeout time.Duration, soTimeout time.Duration) (*TSocket, error) { |  | ||||||
| 	return NewTSocketConf(hostPort, &TConfiguration{ |  | ||||||
| 		ConnectTimeout: connTimeout, |  | ||||||
| 		SocketTimeout:  soTimeout, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSocketFromAddrConf creates a TSocket from a net.Addr |  | ||||||
| func NewTSocketFromAddrConf(addr net.Addr, conf *TConfiguration) *TSocket { |  | ||||||
| 	return &TSocket{ |  | ||||||
| 		addr: addr, |  | ||||||
| 		cfg:  conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSocketFromAddrConf instead. |  | ||||||
| func NewTSocketFromAddrTimeout(addr net.Addr, connTimeout time.Duration, soTimeout time.Duration) *TSocket { |  | ||||||
| 	return NewTSocketFromAddrConf(addr, &TConfiguration{ |  | ||||||
| 		ConnectTimeout: connTimeout, |  | ||||||
| 		SocketTimeout:  soTimeout, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSocketFromConnConf creates a TSocket from an existing net.Conn. |  | ||||||
| func NewTSocketFromConnConf(conn net.Conn, conf *TConfiguration) *TSocket { |  | ||||||
| 	return &TSocket{ |  | ||||||
| 		conn: wrapSocketConn(conn), |  | ||||||
| 		addr: conn.RemoteAddr(), |  | ||||||
| 		cfg:  conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSocketFromConnConf instead. |  | ||||||
| func NewTSocketFromConnTimeout(conn net.Conn, socketTimeout time.Duration) *TSocket { |  | ||||||
| 	return NewTSocketFromConnConf(conn, &TConfiguration{ |  | ||||||
| 		SocketTimeout: socketTimeout, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter. |  | ||||||
| // |  | ||||||
| // It can be used to set connect and socket timeouts. |  | ||||||
| func (p *TSocket) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	p.cfg = conf |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Sets the connect timeout |  | ||||||
| func (p *TSocket) SetConnTimeout(timeout time.Duration) error { |  | ||||||
| 	if p.cfg == nil { |  | ||||||
| 		p.cfg = &TConfiguration{ |  | ||||||
| 			noPropagation: true, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	p.cfg.ConnectTimeout = timeout |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Sets the socket timeout |  | ||||||
| func (p *TSocket) SetSocketTimeout(timeout time.Duration) error { |  | ||||||
| 	if p.cfg == nil { |  | ||||||
| 		p.cfg = &TConfiguration{ |  | ||||||
| 			noPropagation: true, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	p.cfg.SocketTimeout = timeout |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSocket) pushDeadline(read, write bool) { |  | ||||||
| 	var t time.Time |  | ||||||
| 	if timeout := p.cfg.GetSocketTimeout(); timeout > 0 { |  | ||||||
| 		t = time.Now().Add(time.Duration(timeout)) |  | ||||||
| 	} |  | ||||||
| 	if read && write { |  | ||||||
| 		p.conn.SetDeadline(t) |  | ||||||
| 	} else if read { |  | ||||||
| 		p.conn.SetReadDeadline(t) |  | ||||||
| 	} else if write { |  | ||||||
| 		p.conn.SetWriteDeadline(t) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Connects the socket, creating a new socket object if necessary. |  | ||||||
| func (p *TSocket) Open() error { |  | ||||||
| 	if p.conn.isValid() { |  | ||||||
| 		return NewTTransportException(ALREADY_OPEN, "Socket already connected.") |  | ||||||
| 	} |  | ||||||
| 	if p.addr == nil { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "Cannot open nil address.") |  | ||||||
| 	} |  | ||||||
| 	if len(p.addr.Network()) == 0 { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "Cannot open bad network name.") |  | ||||||
| 	} |  | ||||||
| 	if len(p.addr.String()) == 0 { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, "Cannot open bad address.") |  | ||||||
| 	} |  | ||||||
| 	var err error |  | ||||||
| 	if p.conn, err = createSocketConnFromReturn(net.DialTimeout( |  | ||||||
| 		p.addr.Network(), |  | ||||||
| 		p.addr.String(), |  | ||||||
| 		p.cfg.GetConnectTimeout(), |  | ||||||
| 	)); err != nil { |  | ||||||
| 		return NewTTransportException(NOT_OPEN, err.Error()) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Retrieve the underlying net.Conn |  | ||||||
| func (p *TSocket) Conn() net.Conn { |  | ||||||
| 	return p.conn |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Returns true if the connection is open |  | ||||||
| func (p *TSocket) IsOpen() bool { |  | ||||||
| 	return p.conn.IsOpen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Closes the socket. |  | ||||||
| func (p *TSocket) Close() error { |  | ||||||
| 	// Close the socket |  | ||||||
| 	if p.conn != nil { |  | ||||||
| 		err := p.conn.Close() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		p.conn = nil |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //Returns the remote address of the socket. |  | ||||||
| func (p *TSocket) Addr() net.Addr { |  | ||||||
| 	return p.addr |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSocket) Read(buf []byte) (int, error) { |  | ||||||
| 	if !p.conn.isValid() { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Connection not open") |  | ||||||
| 	} |  | ||||||
| 	p.pushDeadline(true, false) |  | ||||||
| 	// NOTE: Calling any of p.IsOpen, p.conn.read0, or p.conn.IsOpen between |  | ||||||
| 	// p.pushDeadline and p.conn.Read could cause the deadline set inside |  | ||||||
| 	// p.pushDeadline being reset, thus need to be avoided. |  | ||||||
| 	n, err := p.conn.Read(buf) |  | ||||||
| 	return n, NewTTransportExceptionFromError(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSocket) Write(buf []byte) (int, error) { |  | ||||||
| 	if !p.conn.isValid() { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Connection not open") |  | ||||||
| 	} |  | ||||||
| 	p.pushDeadline(false, true) |  | ||||||
| 	return p.conn.Write(buf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSocket) Flush(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSocket) Interrupt() error { |  | ||||||
| 	if !p.conn.isValid() { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return p.conn.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSocket) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	const maxSize = ^uint64(0) |  | ||||||
| 	return maxSize // the truth is, we just don't know unless framed is used |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*TSocket)(nil) |  | ||||||
|  | @ -1,102 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"net" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // socketConn is a wrapped net.Conn that tries to do connectivity check. |  | ||||||
| type socketConn struct { |  | ||||||
| 	net.Conn |  | ||||||
| 
 |  | ||||||
| 	buffer [1]byte |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ net.Conn = (*socketConn)(nil) |  | ||||||
| 
 |  | ||||||
| // createSocketConnFromReturn is a language sugar to help create socketConn from |  | ||||||
| // return values of functions like net.Dial, tls.Dial, net.Listener.Accept, etc. |  | ||||||
| func createSocketConnFromReturn(conn net.Conn, err error) (*socketConn, error) { |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return &socketConn{ |  | ||||||
| 		Conn: conn, |  | ||||||
| 	}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // wrapSocketConn wraps an existing net.Conn into *socketConn. |  | ||||||
| func wrapSocketConn(conn net.Conn) *socketConn { |  | ||||||
| 	// In case conn is already wrapped, |  | ||||||
| 	// return it as-is and avoid double wrapping. |  | ||||||
| 	if sc, ok := conn.(*socketConn); ok { |  | ||||||
| 		return sc |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return &socketConn{ |  | ||||||
| 		Conn: conn, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // isValid checks whether there's a valid connection. |  | ||||||
| // |  | ||||||
| // It's nil safe, and returns false if sc itself is nil, or if the underlying |  | ||||||
| // connection is nil. |  | ||||||
| // |  | ||||||
| // It's the same as the previous implementation of TSocket.IsOpen and |  | ||||||
| // TSSLSocket.IsOpen before we added connectivity check. |  | ||||||
| func (sc *socketConn) isValid() bool { |  | ||||||
| 	return sc != nil && sc.Conn != nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // IsOpen checks whether the connection is open. |  | ||||||
| // |  | ||||||
| // It's nil safe, and returns false if sc itself is nil, or if the underlying |  | ||||||
| // connection is nil. |  | ||||||
| // |  | ||||||
| // Otherwise, it tries to do a connectivity check and returns the result. |  | ||||||
| // |  | ||||||
| // It also has the side effect of resetting the previously set read deadline on |  | ||||||
| // the socket. As a result, it shouldn't be called between setting read deadline |  | ||||||
| // and doing actual read. |  | ||||||
| func (sc *socketConn) IsOpen() bool { |  | ||||||
| 	if !sc.isValid() { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return sc.checkConn() == nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Read implements io.Reader. |  | ||||||
| // |  | ||||||
| // On Windows, it behaves the same as the underlying net.Conn.Read. |  | ||||||
| // |  | ||||||
| // On non-Windows, it treats len(p) == 0 as a connectivity check instead of |  | ||||||
| // readability check, which means instead of blocking until there's something to |  | ||||||
| // read (readability check), or always return (0, nil) (the default behavior of |  | ||||||
| // go's stdlib implementation on non-Windows), it never blocks, and will return |  | ||||||
| // an error if the connection is lost. |  | ||||||
| func (sc *socketConn) Read(p []byte) (n int, err error) { |  | ||||||
| 	if len(p) == 0 { |  | ||||||
| 		return 0, sc.read0() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return sc.Conn.Read(p) |  | ||||||
| } |  | ||||||
|  | @ -1,83 +0,0 @@ | ||||||
| // +build !windows |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| 	"syscall" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // We rely on this variable to be the zero time, |  | ||||||
| // but define it as global variable to avoid repetitive allocations. |  | ||||||
| // Please DO NOT mutate this variable in any way. |  | ||||||
| var zeroTime time.Time |  | ||||||
| 
 |  | ||||||
| func (sc *socketConn) read0() error { |  | ||||||
| 	return sc.checkConn() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (sc *socketConn) checkConn() error { |  | ||||||
| 	syscallConn, ok := sc.Conn.(syscall.Conn) |  | ||||||
| 	if !ok { |  | ||||||
| 		// No way to check, return nil |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// The reading about to be done here is non-blocking so we don't really |  | ||||||
| 	// need a read deadline. We just need to clear the previously set read |  | ||||||
| 	// deadline, if any. |  | ||||||
| 	sc.Conn.SetReadDeadline(zeroTime) |  | ||||||
| 
 |  | ||||||
| 	rc, err := syscallConn.SyscallConn() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var n int |  | ||||||
| 
 |  | ||||||
| 	if readErr := rc.Read(func(fd uintptr) bool { |  | ||||||
| 		n, _, err = syscall.Recvfrom(int(fd), sc.buffer[:], syscall.MSG_PEEK|syscall.MSG_DONTWAIT) |  | ||||||
| 		return true |  | ||||||
| 	}); readErr != nil { |  | ||||||
| 		return readErr |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if n > 0 { |  | ||||||
| 		// We got something, which means we are good |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if errors.Is(err, syscall.EAGAIN) || errors.Is(err, syscall.EWOULDBLOCK) { |  | ||||||
| 		// This means the connection is still open but we don't have |  | ||||||
| 		// anything to read right now. |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// At this point, it means the other side already closed the connection. |  | ||||||
| 	return io.EOF |  | ||||||
| } |  | ||||||
|  | @ -1,34 +0,0 @@ | ||||||
| // +build windows |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| func (sc *socketConn) read0() error { |  | ||||||
| 	// On windows, we fallback to the default behavior of reading 0 bytes. |  | ||||||
| 	var p []byte |  | ||||||
| 	_, err := sc.Conn.Read(p) |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (sc *socketConn) checkConn() error { |  | ||||||
| 	// On windows, we always return nil for this check. |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  | @ -1,112 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/tls" |  | ||||||
| 	"net" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TSSLServerSocket struct { |  | ||||||
| 	listener      net.Listener |  | ||||||
| 	addr          net.Addr |  | ||||||
| 	clientTimeout time.Duration |  | ||||||
| 	interrupted   bool |  | ||||||
| 	cfg           *tls.Config |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSSLServerSocket(listenAddr string, cfg *tls.Config) (*TSSLServerSocket, error) { |  | ||||||
| 	return NewTSSLServerSocketTimeout(listenAddr, cfg, 0) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTSSLServerSocketTimeout(listenAddr string, cfg *tls.Config, clientTimeout time.Duration) (*TSSLServerSocket, error) { |  | ||||||
| 	if cfg.MinVersion == 0 { |  | ||||||
| 		cfg.MinVersion = tls.VersionTLS10 |  | ||||||
| 	} |  | ||||||
| 	addr, err := net.ResolveTCPAddr("tcp", listenAddr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return &TSSLServerSocket{addr: addr, clientTimeout: clientTimeout, cfg: cfg}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLServerSocket) Listen() error { |  | ||||||
| 	if p.IsListening() { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	p.listener = l |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLServerSocket) Accept() (TTransport, error) { |  | ||||||
| 	if p.interrupted { |  | ||||||
| 		return nil, errTransportInterrupted |  | ||||||
| 	} |  | ||||||
| 	if p.listener == nil { |  | ||||||
| 		return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") |  | ||||||
| 	} |  | ||||||
| 	conn, err := p.listener.Accept() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, NewTTransportExceptionFromError(err) |  | ||||||
| 	} |  | ||||||
| 	return NewTSSLSocketFromConnTimeout(conn, p.cfg, p.clientTimeout), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Checks whether the socket is listening. |  | ||||||
| func (p *TSSLServerSocket) IsListening() bool { |  | ||||||
| 	return p.listener != nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Connects the socket, creating a new socket object if necessary. |  | ||||||
| func (p *TSSLServerSocket) Open() error { |  | ||||||
| 	if p.IsListening() { |  | ||||||
| 		return NewTTransportException(ALREADY_OPEN, "Server socket already open") |  | ||||||
| 	} |  | ||||||
| 	if l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} else { |  | ||||||
| 		p.listener = l |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLServerSocket) Addr() net.Addr { |  | ||||||
| 	return p.addr |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLServerSocket) Close() error { |  | ||||||
| 	defer func() { |  | ||||||
| 		p.listener = nil |  | ||||||
| 	}() |  | ||||||
| 	if p.IsListening() { |  | ||||||
| 		return p.listener.Close() |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLServerSocket) Interrupt() error { |  | ||||||
| 	p.interrupted = true |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  | @ -1,258 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"crypto/tls" |  | ||||||
| 	"net" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TSSLSocket struct { |  | ||||||
| 	conn *socketConn |  | ||||||
| 	// hostPort contains host:port (e.g. "asdf.com:12345"). The field is |  | ||||||
| 	// only valid if addr is nil. |  | ||||||
| 	hostPort string |  | ||||||
| 	// addr is nil when hostPort is not "", and is only used when the |  | ||||||
| 	// TSSLSocket is constructed from a net.Addr. |  | ||||||
| 	addr net.Addr |  | ||||||
| 
 |  | ||||||
| 	cfg *TConfiguration |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSSLSocketConf creates a net.Conn-backed TTransport, given a host and port. |  | ||||||
| // |  | ||||||
| // Example: |  | ||||||
| // |  | ||||||
| //     trans, err := thrift.NewTSSLSocketConf("localhost:9090", nil, &TConfiguration{ |  | ||||||
| //         ConnectTimeout: time.Second, // Use 0 for no timeout |  | ||||||
| //         SocketTimeout:  time.Second, // Use 0 for no timeout |  | ||||||
| //     }) |  | ||||||
| func NewTSSLSocketConf(hostPort string, conf *TConfiguration) (*TSSLSocket, error) { |  | ||||||
| 	if cfg := conf.GetTLSConfig(); cfg != nil && cfg.MinVersion == 0 { |  | ||||||
| 		cfg.MinVersion = tls.VersionTLS10 |  | ||||||
| 	} |  | ||||||
| 	return &TSSLSocket{ |  | ||||||
| 		hostPort: hostPort, |  | ||||||
| 		cfg:      conf, |  | ||||||
| 	}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSSLSocketConf instead. |  | ||||||
| func NewTSSLSocket(hostPort string, cfg *tls.Config) (*TSSLSocket, error) { |  | ||||||
| 	return NewTSSLSocketConf(hostPort, &TConfiguration{ |  | ||||||
| 		TLSConfig: cfg, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSSLSocketConf instead. |  | ||||||
| func NewTSSLSocketTimeout(hostPort string, cfg *tls.Config, connectTimeout, socketTimeout time.Duration) (*TSSLSocket, error) { |  | ||||||
| 	return NewTSSLSocketConf(hostPort, &TConfiguration{ |  | ||||||
| 		ConnectTimeout: connectTimeout, |  | ||||||
| 		SocketTimeout:  socketTimeout, |  | ||||||
| 		TLSConfig:      cfg, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSSLSocketFromAddrConf creates a TSSLSocket from a net.Addr. |  | ||||||
| func NewTSSLSocketFromAddrConf(addr net.Addr, conf *TConfiguration) *TSSLSocket { |  | ||||||
| 	return &TSSLSocket{ |  | ||||||
| 		addr: addr, |  | ||||||
| 		cfg:  conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSSLSocketFromAddrConf instead. |  | ||||||
| func NewTSSLSocketFromAddrTimeout(addr net.Addr, cfg *tls.Config, connectTimeout, socketTimeout time.Duration) *TSSLSocket { |  | ||||||
| 	return NewTSSLSocketFromAddrConf(addr, &TConfiguration{ |  | ||||||
| 		ConnectTimeout: connectTimeout, |  | ||||||
| 		SocketTimeout:  socketTimeout, |  | ||||||
| 		TLSConfig:      cfg, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTSSLSocketFromConnConf creates a TSSLSocket from an existing net.Conn. |  | ||||||
| func NewTSSLSocketFromConnConf(conn net.Conn, conf *TConfiguration) *TSSLSocket { |  | ||||||
| 	return &TSSLSocket{ |  | ||||||
| 		conn: wrapSocketConn(conn), |  | ||||||
| 		addr: conn.RemoteAddr(), |  | ||||||
| 		cfg:  conf, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Deprecated: Use NewTSSLSocketFromConnConf instead. |  | ||||||
| func NewTSSLSocketFromConnTimeout(conn net.Conn, cfg *tls.Config, socketTimeout time.Duration) *TSSLSocket { |  | ||||||
| 	return NewTSSLSocketFromConnConf(conn, &TConfiguration{ |  | ||||||
| 		SocketTimeout: socketTimeout, |  | ||||||
| 		TLSConfig:     cfg, |  | ||||||
| 
 |  | ||||||
| 		noPropagation: true, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter. |  | ||||||
| // |  | ||||||
| // It can be used to change connect and socket timeouts. |  | ||||||
| func (p *TSSLSocket) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	p.cfg = conf |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Sets the connect timeout |  | ||||||
| func (p *TSSLSocket) SetConnTimeout(timeout time.Duration) error { |  | ||||||
| 	if p.cfg == nil { |  | ||||||
| 		p.cfg = &TConfiguration{} |  | ||||||
| 	} |  | ||||||
| 	p.cfg.ConnectTimeout = timeout |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Sets the socket timeout |  | ||||||
| func (p *TSSLSocket) SetSocketTimeout(timeout time.Duration) error { |  | ||||||
| 	if p.cfg == nil { |  | ||||||
| 		p.cfg = &TConfiguration{} |  | ||||||
| 	} |  | ||||||
| 	p.cfg.SocketTimeout = timeout |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLSocket) pushDeadline(read, write bool) { |  | ||||||
| 	var t time.Time |  | ||||||
| 	if timeout := p.cfg.GetSocketTimeout(); timeout > 0 { |  | ||||||
| 		t = time.Now().Add(time.Duration(timeout)) |  | ||||||
| 	} |  | ||||||
| 	if read && write { |  | ||||||
| 		p.conn.SetDeadline(t) |  | ||||||
| 	} else if read { |  | ||||||
| 		p.conn.SetReadDeadline(t) |  | ||||||
| 	} else if write { |  | ||||||
| 		p.conn.SetWriteDeadline(t) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Connects the socket, creating a new socket object if necessary. |  | ||||||
| func (p *TSSLSocket) Open() error { |  | ||||||
| 	var err error |  | ||||||
| 	// If we have a hostname, we need to pass the hostname to tls.Dial for |  | ||||||
| 	// certificate hostname checks. |  | ||||||
| 	if p.hostPort != "" { |  | ||||||
| 		if p.conn, err = createSocketConnFromReturn(tls.DialWithDialer( |  | ||||||
| 			&net.Dialer{ |  | ||||||
| 				Timeout: p.cfg.GetConnectTimeout(), |  | ||||||
| 			}, |  | ||||||
| 			"tcp", |  | ||||||
| 			p.hostPort, |  | ||||||
| 			p.cfg.GetTLSConfig(), |  | ||||||
| 		)); err != nil { |  | ||||||
| 			return NewTTransportException(NOT_OPEN, err.Error()) |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		if p.conn.isValid() { |  | ||||||
| 			return NewTTransportException(ALREADY_OPEN, "Socket already connected.") |  | ||||||
| 		} |  | ||||||
| 		if p.addr == nil { |  | ||||||
| 			return NewTTransportException(NOT_OPEN, "Cannot open nil address.") |  | ||||||
| 		} |  | ||||||
| 		if len(p.addr.Network()) == 0 { |  | ||||||
| 			return NewTTransportException(NOT_OPEN, "Cannot open bad network name.") |  | ||||||
| 		} |  | ||||||
| 		if len(p.addr.String()) == 0 { |  | ||||||
| 			return NewTTransportException(NOT_OPEN, "Cannot open bad address.") |  | ||||||
| 		} |  | ||||||
| 		if p.conn, err = createSocketConnFromReturn(tls.DialWithDialer( |  | ||||||
| 			&net.Dialer{ |  | ||||||
| 				Timeout: p.cfg.GetConnectTimeout(), |  | ||||||
| 			}, |  | ||||||
| 			p.addr.Network(), |  | ||||||
| 			p.addr.String(), |  | ||||||
| 			p.cfg.GetTLSConfig(), |  | ||||||
| 		)); err != nil { |  | ||||||
| 			return NewTTransportException(NOT_OPEN, err.Error()) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Retrieve the underlying net.Conn |  | ||||||
| func (p *TSSLSocket) Conn() net.Conn { |  | ||||||
| 	return p.conn |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Returns true if the connection is open |  | ||||||
| func (p *TSSLSocket) IsOpen() bool { |  | ||||||
| 	return p.conn.IsOpen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Closes the socket. |  | ||||||
| func (p *TSSLSocket) Close() error { |  | ||||||
| 	// Close the socket |  | ||||||
| 	if p.conn != nil { |  | ||||||
| 		err := p.conn.Close() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		p.conn = nil |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLSocket) Read(buf []byte) (int, error) { |  | ||||||
| 	if !p.conn.isValid() { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Connection not open") |  | ||||||
| 	} |  | ||||||
| 	p.pushDeadline(true, false) |  | ||||||
| 	// NOTE: Calling any of p.IsOpen, p.conn.read0, or p.conn.IsOpen between |  | ||||||
| 	// p.pushDeadline and p.conn.Read could cause the deadline set inside |  | ||||||
| 	// p.pushDeadline being reset, thus need to be avoided. |  | ||||||
| 	n, err := p.conn.Read(buf) |  | ||||||
| 	return n, NewTTransportExceptionFromError(err) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLSocket) Write(buf []byte) (int, error) { |  | ||||||
| 	if !p.conn.isValid() { |  | ||||||
| 		return 0, NewTTransportException(NOT_OPEN, "Connection not open") |  | ||||||
| 	} |  | ||||||
| 	p.pushDeadline(false, true) |  | ||||||
| 	return p.conn.Write(buf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLSocket) Flush(ctx context.Context) error { |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLSocket) Interrupt() error { |  | ||||||
| 	if !p.conn.isValid() { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return p.conn.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *TSSLSocket) RemainingBytes() (num_bytes uint64) { |  | ||||||
| 	const maxSize = ^uint64(0) |  | ||||||
| 	return maxSize // the truth is, we just don't know unless framed is used |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*TSSLSocket)(nil) |  | ||||||
|  | @ -1,70 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var errTransportInterrupted = errors.New("Transport Interrupted") |  | ||||||
| 
 |  | ||||||
| type Flusher interface { |  | ||||||
| 	Flush() (err error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type ContextFlusher interface { |  | ||||||
| 	Flush(ctx context.Context) (err error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type ReadSizeProvider interface { |  | ||||||
| 	RemainingBytes() (num_bytes uint64) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Encapsulates the I/O layer |  | ||||||
| type TTransport interface { |  | ||||||
| 	io.ReadWriteCloser |  | ||||||
| 	ContextFlusher |  | ||||||
| 	ReadSizeProvider |  | ||||||
| 
 |  | ||||||
| 	// Opens the transport for communication |  | ||||||
| 	Open() error |  | ||||||
| 
 |  | ||||||
| 	// Returns true if the transport is open |  | ||||||
| 	IsOpen() bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type stringWriter interface { |  | ||||||
| 	WriteString(s string) (n int, err error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // This is "enhanced" transport with extra capabilities. You need to use one of these |  | ||||||
| // to construct protocol. |  | ||||||
| // Notably, TSocket does not implement this interface, and it is always a mistake to use |  | ||||||
| // TSocket directly in protocol. |  | ||||||
| type TRichTransport interface { |  | ||||||
| 	io.ReadWriter |  | ||||||
| 	io.ByteReader |  | ||||||
| 	io.ByteWriter |  | ||||||
| 	stringWriter |  | ||||||
| 	ContextFlusher |  | ||||||
| 	ReadSizeProvider |  | ||||||
| } |  | ||||||
|  | @ -1,131 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type timeoutable interface { |  | ||||||
| 	Timeout() bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Thrift Transport exception |  | ||||||
| type TTransportException interface { |  | ||||||
| 	TException |  | ||||||
| 	TypeId() int |  | ||||||
| 	Err() error |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	UNKNOWN_TRANSPORT_EXCEPTION = 0 |  | ||||||
| 	NOT_OPEN                    = 1 |  | ||||||
| 	ALREADY_OPEN                = 2 |  | ||||||
| 	TIMED_OUT                   = 3 |  | ||||||
| 	END_OF_FILE                 = 4 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type tTransportException struct { |  | ||||||
| 	typeId int |  | ||||||
| 	err    error |  | ||||||
| 	msg    string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TTransportException = (*tTransportException)(nil) |  | ||||||
| 
 |  | ||||||
| func (tTransportException) TExceptionType() TExceptionType { |  | ||||||
| 	return TExceptionTypeTransport |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tTransportException) TypeId() int { |  | ||||||
| 	return p.typeId |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tTransportException) Error() string { |  | ||||||
| 	return p.msg |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tTransportException) Err() error { |  | ||||||
| 	return p.err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tTransportException) Unwrap() error { |  | ||||||
| 	return p.err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p *tTransportException) Timeout() bool { |  | ||||||
| 	return p.typeId == TIMED_OUT |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTTransportException(t int, e string) TTransportException { |  | ||||||
| 	return &tTransportException{ |  | ||||||
| 		typeId: t, |  | ||||||
| 		err:    errors.New(e), |  | ||||||
| 		msg:    e, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTTransportExceptionFromError(e error) TTransportException { |  | ||||||
| 	if e == nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if t, ok := e.(TTransportException); ok { |  | ||||||
| 		return t |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	te := &tTransportException{ |  | ||||||
| 		typeId: UNKNOWN_TRANSPORT_EXCEPTION, |  | ||||||
| 		err:    e, |  | ||||||
| 		msg:    e.Error(), |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if isTimeoutError(e) { |  | ||||||
| 		te.typeId = TIMED_OUT |  | ||||||
| 		return te |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if errors.Is(e, io.EOF) { |  | ||||||
| 		te.typeId = END_OF_FILE |  | ||||||
| 		return te |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return te |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func prependTTransportException(prepend string, e TTransportException) TTransportException { |  | ||||||
| 	return &tTransportException{ |  | ||||||
| 		typeId: e.TypeId(), |  | ||||||
| 		err:    e, |  | ||||||
| 		msg:    prepend + e.Error(), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // isTimeoutError returns true when err is an error caused by timeout. |  | ||||||
| // |  | ||||||
| // Note that this also includes TTransportException wrapped timeout errors. |  | ||||||
| func isTimeoutError(err error) bool { |  | ||||||
| 	var t timeoutable |  | ||||||
| 	if errors.As(err, &t) { |  | ||||||
| 		return t.Timeout() |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  | @ -1,39 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| // Factory class used to create wrapped instance of Transports. |  | ||||||
| // This is used primarily in servers, which get Transports from |  | ||||||
| // a ServerTransport and then may want to mutate them (i.e. create |  | ||||||
| // a BufferedTransport from the underlying base transport) |  | ||||||
| type TTransportFactory interface { |  | ||||||
| 	GetTransport(trans TTransport) (TTransport, error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type tTransportFactory struct{} |  | ||||||
| 
 |  | ||||||
| // Return a wrapped instance of the base Transport. |  | ||||||
| func (p *tTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	return trans, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTTransportFactory() TTransportFactory { |  | ||||||
| 	return &tTransportFactory{} |  | ||||||
| } |  | ||||||
|  | @ -1,69 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
|  * or more contributor license agreements. See the NOTICE file |  | ||||||
|  * distributed with this work for additional information |  | ||||||
|  * regarding copyright ownership. The ASF licenses this file |  | ||||||
|  * to you under the Apache License, Version 2.0 (the |  | ||||||
|  * "License"); you may not use this file except in compliance |  | ||||||
|  * with the License. You may obtain a copy of the License at |  | ||||||
|  * |  | ||||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  * |  | ||||||
|  * Unless required by applicable law or agreed to in writing, |  | ||||||
|  * software distributed under the License is distributed on an |  | ||||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
|  * KIND, either express or implied. See the License for the |  | ||||||
|  * specific language governing permissions and limitations |  | ||||||
|  * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| // Type constants in the Thrift protocol |  | ||||||
| type TType byte |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	STOP   = 0 |  | ||||||
| 	VOID   = 1 |  | ||||||
| 	BOOL   = 2 |  | ||||||
| 	BYTE   = 3 |  | ||||||
| 	I08    = 3 |  | ||||||
| 	DOUBLE = 4 |  | ||||||
| 	I16    = 6 |  | ||||||
| 	I32    = 8 |  | ||||||
| 	I64    = 10 |  | ||||||
| 	STRING = 11 |  | ||||||
| 	UTF7   = 11 |  | ||||||
| 	STRUCT = 12 |  | ||||||
| 	MAP    = 13 |  | ||||||
| 	SET    = 14 |  | ||||||
| 	LIST   = 15 |  | ||||||
| 	UTF8   = 16 |  | ||||||
| 	UTF16  = 17 |  | ||||||
| 	//BINARY = 18   wrong and unused |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var typeNames = map[int]string{ |  | ||||||
| 	STOP:   "STOP", |  | ||||||
| 	VOID:   "VOID", |  | ||||||
| 	BOOL:   "BOOL", |  | ||||||
| 	BYTE:   "BYTE", |  | ||||||
| 	DOUBLE: "DOUBLE", |  | ||||||
| 	I16:    "I16", |  | ||||||
| 	I32:    "I32", |  | ||||||
| 	I64:    "I64", |  | ||||||
| 	STRING: "STRING", |  | ||||||
| 	STRUCT: "STRUCT", |  | ||||||
| 	MAP:    "MAP", |  | ||||||
| 	SET:    "SET", |  | ||||||
| 	LIST:   "LIST", |  | ||||||
| 	UTF8:   "UTF8", |  | ||||||
| 	UTF16:  "UTF16", |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (p TType) String() string { |  | ||||||
| 	if s, ok := typeNames[int(p)]; ok { |  | ||||||
| 		return s |  | ||||||
| 	} |  | ||||||
| 	return "Unknown" |  | ||||||
| } |  | ||||||
|  | @ -1,137 +0,0 @@ | ||||||
| /* |  | ||||||
| * Licensed to the Apache Software Foundation (ASF) under one |  | ||||||
| * or more contributor license agreements. See the NOTICE file |  | ||||||
| * distributed with this work for additional information |  | ||||||
| * regarding copyright ownership. The ASF licenses this file |  | ||||||
| * to you under the Apache License, Version 2.0 (the |  | ||||||
| * "License"); you may not use this file except in compliance |  | ||||||
| * with the License. You may obtain a copy of the License at |  | ||||||
| * |  | ||||||
| *   http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| * |  | ||||||
| * Unless required by applicable law or agreed to in writing, |  | ||||||
| * software distributed under the License is distributed on an |  | ||||||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |  | ||||||
| * KIND, either express or implied. See the License for the |  | ||||||
| * specific language governing permissions and limitations |  | ||||||
| * under the License. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| package thrift |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"compress/zlib" |  | ||||||
| 	"context" |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // TZlibTransportFactory is a factory for TZlibTransport instances |  | ||||||
| type TZlibTransportFactory struct { |  | ||||||
| 	level   int |  | ||||||
| 	factory TTransportFactory |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TZlibTransport is a TTransport implementation that makes use of zlib compression. |  | ||||||
| type TZlibTransport struct { |  | ||||||
| 	reader    io.ReadCloser |  | ||||||
| 	transport TTransport |  | ||||||
| 	writer    *zlib.Writer |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTransport constructs a new instance of NewTZlibTransport |  | ||||||
| func (p *TZlibTransportFactory) GetTransport(trans TTransport) (TTransport, error) { |  | ||||||
| 	if p.factory != nil { |  | ||||||
| 		// wrap other factory |  | ||||||
| 		var err error |  | ||||||
| 		trans, err = p.factory.GetTransport(trans) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return NewTZlibTransport(trans, p.level) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTZlibTransportFactory constructs a new instance of NewTZlibTransportFactory |  | ||||||
| func NewTZlibTransportFactory(level int) *TZlibTransportFactory { |  | ||||||
| 	return &TZlibTransportFactory{level: level, factory: nil} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTZlibTransportFactory constructs a new instance of TZlibTransportFactory |  | ||||||
| // as a wrapper over existing transport factory |  | ||||||
| func NewTZlibTransportFactoryWithFactory(level int, factory TTransportFactory) *TZlibTransportFactory { |  | ||||||
| 	return &TZlibTransportFactory{level: level, factory: factory} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewTZlibTransport constructs a new instance of TZlibTransport |  | ||||||
| func NewTZlibTransport(trans TTransport, level int) (*TZlibTransport, error) { |  | ||||||
| 	w, err := zlib.NewWriterLevel(trans, level) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return &TZlibTransport{ |  | ||||||
| 		writer:    w, |  | ||||||
| 		transport: trans, |  | ||||||
| 	}, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Close closes the reader and writer (flushing any unwritten data) and closes |  | ||||||
| // the underlying transport. |  | ||||||
| func (z *TZlibTransport) Close() error { |  | ||||||
| 	if z.reader != nil { |  | ||||||
| 		if err := z.reader.Close(); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if err := z.writer.Close(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return z.transport.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Flush flushes the writer and its underlying transport. |  | ||||||
| func (z *TZlibTransport) Flush(ctx context.Context) error { |  | ||||||
| 	if err := z.writer.Flush(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return z.transport.Flush(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // IsOpen returns true if the transport is open |  | ||||||
| func (z *TZlibTransport) IsOpen() bool { |  | ||||||
| 	return z.transport.IsOpen() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Open opens the transport for communication |  | ||||||
| func (z *TZlibTransport) Open() error { |  | ||||||
| 	return z.transport.Open() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (z *TZlibTransport) Read(p []byte) (int, error) { |  | ||||||
| 	if z.reader == nil { |  | ||||||
| 		r, err := zlib.NewReader(z.transport) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, NewTTransportExceptionFromError(err) |  | ||||||
| 		} |  | ||||||
| 		z.reader = r |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return z.reader.Read(p) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // RemainingBytes returns the size in bytes of the data that is still to be |  | ||||||
| // read. |  | ||||||
| func (z *TZlibTransport) RemainingBytes() uint64 { |  | ||||||
| 	return z.transport.RemainingBytes() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (z *TZlibTransport) Write(p []byte) (int, error) { |  | ||||||
| 	return z.writer.Write(p) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTConfiguration implements TConfigurationSetter for propagation. |  | ||||||
| func (z *TZlibTransport) SetTConfiguration(conf *TConfiguration) { |  | ||||||
| 	PropagateTConfiguration(z.transport, conf) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ TConfigurationSetter = (*TZlibTransport)(nil) |  | ||||||
							
								
								
									
										360
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/jaeger.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										360
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/jaeger.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,360 +0,0 @@ | ||||||
| // Copyright The OpenTelemetry Authors |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
| 
 |  | ||||||
| package jaeger // import "go.opentelemetry.io/otel/exporters/jaeger" |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"fmt" |  | ||||||
| 	"sync" |  | ||||||
| 
 |  | ||||||
| 	"go.opentelemetry.io/otel/attribute" |  | ||||||
| 	"go.opentelemetry.io/otel/codes" |  | ||||||
| 	gen "go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger" |  | ||||||
| 	"go.opentelemetry.io/otel/sdk/resource" |  | ||||||
| 	sdktrace "go.opentelemetry.io/otel/sdk/trace" |  | ||||||
| 	semconv "go.opentelemetry.io/otel/semconv/v1.17.0" |  | ||||||
| 	"go.opentelemetry.io/otel/trace" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	keyInstrumentationLibraryName    = "otel.library.name" |  | ||||||
| 	keyInstrumentationLibraryVersion = "otel.library.version" |  | ||||||
| 	keyError                         = "error" |  | ||||||
| 	keySpanKind                      = "span.kind" |  | ||||||
| 	keyStatusCode                    = "otel.status_code" |  | ||||||
| 	keyStatusMessage                 = "otel.status_description" |  | ||||||
| 	keyDroppedAttributeCount         = "otel.event.dropped_attributes_count" |  | ||||||
| 	keyEventName                     = "event" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // New returns an OTel Exporter implementation that exports the collected |  | ||||||
| // spans to Jaeger. |  | ||||||
| func New(endpointOption EndpointOption) (*Exporter, error) { |  | ||||||
| 	uploader, err := endpointOption.newBatchUploader() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Fetch default service.name from default resource for backup |  | ||||||
| 	var defaultServiceName string |  | ||||||
| 	defaultResource := resource.Default() |  | ||||||
| 	if value, exists := defaultResource.Set().Value(semconv.ServiceNameKey); exists { |  | ||||||
| 		defaultServiceName = value.AsString() |  | ||||||
| 	} |  | ||||||
| 	if defaultServiceName == "" { |  | ||||||
| 		return nil, fmt.Errorf("failed to get service name from default resource") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	stopCh := make(chan struct{}) |  | ||||||
| 	e := &Exporter{ |  | ||||||
| 		uploader:           uploader, |  | ||||||
| 		stopCh:             stopCh, |  | ||||||
| 		defaultServiceName: defaultServiceName, |  | ||||||
| 	} |  | ||||||
| 	return e, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Exporter exports OpenTelemetry spans to a Jaeger agent or collector. |  | ||||||
| type Exporter struct { |  | ||||||
| 	uploader           batchUploader |  | ||||||
| 	stopOnce           sync.Once |  | ||||||
| 	stopCh             chan struct{} |  | ||||||
| 	defaultServiceName string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ sdktrace.SpanExporter = (*Exporter)(nil) |  | ||||||
| 
 |  | ||||||
| // ExportSpans transforms and exports OpenTelemetry spans to Jaeger. |  | ||||||
| func (e *Exporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error { |  | ||||||
| 	// Return fast if context is already canceled or Exporter shutdown. |  | ||||||
| 	select { |  | ||||||
| 	case <-ctx.Done(): |  | ||||||
| 		return ctx.Err() |  | ||||||
| 	case <-e.stopCh: |  | ||||||
| 		return nil |  | ||||||
| 	default: |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Cancel export if Exporter is shutdown. |  | ||||||
| 	var cancel context.CancelFunc |  | ||||||
| 	ctx, cancel = context.WithCancel(ctx) |  | ||||||
| 	defer cancel() |  | ||||||
| 	go func(ctx context.Context, cancel context.CancelFunc) { |  | ||||||
| 		select { |  | ||||||
| 		case <-ctx.Done(): |  | ||||||
| 		case <-e.stopCh: |  | ||||||
| 			cancel() |  | ||||||
| 		} |  | ||||||
| 	}(ctx, cancel) |  | ||||||
| 
 |  | ||||||
| 	for _, batch := range jaegerBatchList(spans, e.defaultServiceName) { |  | ||||||
| 		if err := e.uploader.upload(ctx, batch); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Shutdown stops the Exporter. This will close all connections and release |  | ||||||
| // all resources held by the Exporter. |  | ||||||
| func (e *Exporter) Shutdown(ctx context.Context) error { |  | ||||||
| 	// Stop any active and subsequent exports. |  | ||||||
| 	e.stopOnce.Do(func() { close(e.stopCh) }) |  | ||||||
| 	select { |  | ||||||
| 	case <-ctx.Done(): |  | ||||||
| 		return ctx.Err() |  | ||||||
| 	default: |  | ||||||
| 	} |  | ||||||
| 	return e.uploader.shutdown(ctx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // MarshalLog is the marshaling function used by the logging system to represent this exporter. |  | ||||||
| func (e *Exporter) MarshalLog() interface{} { |  | ||||||
| 	return struct { |  | ||||||
| 		Type string |  | ||||||
| 	}{ |  | ||||||
| 		Type: "jaeger", |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func spanToThrift(ss sdktrace.ReadOnlySpan) *gen.Span { |  | ||||||
| 	attr := ss.Attributes() |  | ||||||
| 	tags := make([]*gen.Tag, 0, len(attr)) |  | ||||||
| 	for _, kv := range attr { |  | ||||||
| 		tag := keyValueToTag(kv) |  | ||||||
| 		if tag != nil { |  | ||||||
| 			tags = append(tags, tag) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if is := ss.InstrumentationScope(); is.Name != "" { |  | ||||||
| 		tags = append(tags, getStringTag(keyInstrumentationLibraryName, is.Name)) |  | ||||||
| 		if is.Version != "" { |  | ||||||
| 			tags = append(tags, getStringTag(keyInstrumentationLibraryVersion, is.Version)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if ss.SpanKind() != trace.SpanKindInternal { |  | ||||||
| 		tags = append(tags, |  | ||||||
| 			getStringTag(keySpanKind, ss.SpanKind().String()), |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if ss.Status().Code != codes.Unset { |  | ||||||
| 		switch ss.Status().Code { |  | ||||||
| 		case codes.Ok: |  | ||||||
| 			tags = append(tags, getStringTag(keyStatusCode, "OK")) |  | ||||||
| 		case codes.Error: |  | ||||||
| 			tags = append(tags, getBoolTag(keyError, true)) |  | ||||||
| 			tags = append(tags, getStringTag(keyStatusCode, "ERROR")) |  | ||||||
| 		} |  | ||||||
| 		if ss.Status().Description != "" { |  | ||||||
| 			tags = append(tags, getStringTag(keyStatusMessage, ss.Status().Description)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var logs []*gen.Log |  | ||||||
| 	for _, a := range ss.Events() { |  | ||||||
| 		nTags := len(a.Attributes) |  | ||||||
| 		if a.Name != "" { |  | ||||||
| 			nTags++ |  | ||||||
| 		} |  | ||||||
| 		if a.DroppedAttributeCount != 0 { |  | ||||||
| 			nTags++ |  | ||||||
| 		} |  | ||||||
| 		fields := make([]*gen.Tag, 0, nTags) |  | ||||||
| 		if a.Name != "" { |  | ||||||
| 			// If an event contains an attribute with the same key, it needs |  | ||||||
| 			// to be given precedence and overwrite this. |  | ||||||
| 			fields = append(fields, getStringTag(keyEventName, a.Name)) |  | ||||||
| 		} |  | ||||||
| 		for _, kv := range a.Attributes { |  | ||||||
| 			tag := keyValueToTag(kv) |  | ||||||
| 			if tag != nil { |  | ||||||
| 				fields = append(fields, tag) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if a.DroppedAttributeCount != 0 { |  | ||||||
| 			fields = append(fields, getInt64Tag(keyDroppedAttributeCount, int64(a.DroppedAttributeCount))) |  | ||||||
| 		} |  | ||||||
| 		logs = append(logs, &gen.Log{ |  | ||||||
| 			Timestamp: a.Time.UnixNano() / 1000, |  | ||||||
| 			Fields:    fields, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var refs []*gen.SpanRef |  | ||||||
| 	for _, link := range ss.Links() { |  | ||||||
| 		tid := link.SpanContext.TraceID() |  | ||||||
| 		sid := link.SpanContext.SpanID() |  | ||||||
| 		refs = append(refs, &gen.SpanRef{ |  | ||||||
| 			TraceIdHigh: int64(binary.BigEndian.Uint64(tid[0:8])), |  | ||||||
| 			TraceIdLow:  int64(binary.BigEndian.Uint64(tid[8:16])), |  | ||||||
| 			SpanId:      int64(binary.BigEndian.Uint64(sid[:])), |  | ||||||
| 			RefType:     gen.SpanRefType_FOLLOWS_FROM, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	tid := ss.SpanContext().TraceID() |  | ||||||
| 	sid := ss.SpanContext().SpanID() |  | ||||||
| 	psid := ss.Parent().SpanID() |  | ||||||
| 	return &gen.Span{ |  | ||||||
| 		TraceIdHigh:   int64(binary.BigEndian.Uint64(tid[0:8])), |  | ||||||
| 		TraceIdLow:    int64(binary.BigEndian.Uint64(tid[8:16])), |  | ||||||
| 		SpanId:        int64(binary.BigEndian.Uint64(sid[:])), |  | ||||||
| 		ParentSpanId:  int64(binary.BigEndian.Uint64(psid[:])), |  | ||||||
| 		OperationName: ss.Name(), // TODO: if span kind is added then add prefix "Sent"/"Recv" |  | ||||||
| 		Flags:         int32(ss.SpanContext().TraceFlags()), |  | ||||||
| 		StartTime:     ss.StartTime().UnixNano() / 1000, |  | ||||||
| 		Duration:      ss.EndTime().Sub(ss.StartTime()).Nanoseconds() / 1000, |  | ||||||
| 		Tags:          tags, |  | ||||||
| 		Logs:          logs, |  | ||||||
| 		References:    refs, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func keyValueToTag(keyValue attribute.KeyValue) *gen.Tag { |  | ||||||
| 	var tag *gen.Tag |  | ||||||
| 	switch keyValue.Value.Type() { |  | ||||||
| 	case attribute.STRING: |  | ||||||
| 		s := keyValue.Value.AsString() |  | ||||||
| 		tag = &gen.Tag{ |  | ||||||
| 			Key:   string(keyValue.Key), |  | ||||||
| 			VStr:  &s, |  | ||||||
| 			VType: gen.TagType_STRING, |  | ||||||
| 		} |  | ||||||
| 	case attribute.BOOL: |  | ||||||
| 		b := keyValue.Value.AsBool() |  | ||||||
| 		tag = &gen.Tag{ |  | ||||||
| 			Key:   string(keyValue.Key), |  | ||||||
| 			VBool: &b, |  | ||||||
| 			VType: gen.TagType_BOOL, |  | ||||||
| 		} |  | ||||||
| 	case attribute.INT64: |  | ||||||
| 		i := keyValue.Value.AsInt64() |  | ||||||
| 		tag = &gen.Tag{ |  | ||||||
| 			Key:   string(keyValue.Key), |  | ||||||
| 			VLong: &i, |  | ||||||
| 			VType: gen.TagType_LONG, |  | ||||||
| 		} |  | ||||||
| 	case attribute.FLOAT64: |  | ||||||
| 		f := keyValue.Value.AsFloat64() |  | ||||||
| 		tag = &gen.Tag{ |  | ||||||
| 			Key:     string(keyValue.Key), |  | ||||||
| 			VDouble: &f, |  | ||||||
| 			VType:   gen.TagType_DOUBLE, |  | ||||||
| 		} |  | ||||||
| 	case attribute.BOOLSLICE, |  | ||||||
| 		attribute.INT64SLICE, |  | ||||||
| 		attribute.FLOAT64SLICE, |  | ||||||
| 		attribute.STRINGSLICE: |  | ||||||
| 		data, _ := json.Marshal(keyValue.Value.AsInterface()) |  | ||||||
| 		a := (string)(data) |  | ||||||
| 		tag = &gen.Tag{ |  | ||||||
| 			Key:   string(keyValue.Key), |  | ||||||
| 			VStr:  &a, |  | ||||||
| 			VType: gen.TagType_STRING, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return tag |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func getInt64Tag(k string, i int64) *gen.Tag { |  | ||||||
| 	return &gen.Tag{ |  | ||||||
| 		Key:   k, |  | ||||||
| 		VLong: &i, |  | ||||||
| 		VType: gen.TagType_LONG, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func getStringTag(k, s string) *gen.Tag { |  | ||||||
| 	return &gen.Tag{ |  | ||||||
| 		Key:   k, |  | ||||||
| 		VStr:  &s, |  | ||||||
| 		VType: gen.TagType_STRING, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func getBoolTag(k string, b bool) *gen.Tag { |  | ||||||
| 	return &gen.Tag{ |  | ||||||
| 		Key:   k, |  | ||||||
| 		VBool: &b, |  | ||||||
| 		VType: gen.TagType_BOOL, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // jaegerBatchList transforms a slice of spans into a slice of jaeger Batch. |  | ||||||
| func jaegerBatchList(ssl []sdktrace.ReadOnlySpan, defaultServiceName string) []*gen.Batch { |  | ||||||
| 	if len(ssl) == 0 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	batchDict := make(map[attribute.Distinct]*gen.Batch) |  | ||||||
| 
 |  | ||||||
| 	for _, ss := range ssl { |  | ||||||
| 		if ss == nil { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		resourceKey := ss.Resource().Equivalent() |  | ||||||
| 		batch, bOK := batchDict[resourceKey] |  | ||||||
| 		if !bOK { |  | ||||||
| 			batch = &gen.Batch{ |  | ||||||
| 				Process: process(ss.Resource(), defaultServiceName), |  | ||||||
| 				Spans:   []*gen.Span{}, |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		batch.Spans = append(batch.Spans, spanToThrift(ss)) |  | ||||||
| 		batchDict[resourceKey] = batch |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Transform the categorized map into a slice |  | ||||||
| 	batchList := make([]*gen.Batch, 0, len(batchDict)) |  | ||||||
| 	for _, batch := range batchDict { |  | ||||||
| 		batchList = append(batchList, batch) |  | ||||||
| 	} |  | ||||||
| 	return batchList |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // process transforms an OTel Resource into a jaeger Process. |  | ||||||
| func process(res *resource.Resource, defaultServiceName string) *gen.Process { |  | ||||||
| 	var process gen.Process |  | ||||||
| 
 |  | ||||||
| 	var serviceName attribute.KeyValue |  | ||||||
| 	if res != nil { |  | ||||||
| 		for iter := res.Iter(); iter.Next(); { |  | ||||||
| 			if iter.Attribute().Key == semconv.ServiceNameKey { |  | ||||||
| 				serviceName = iter.Attribute() |  | ||||||
| 				// Don't convert service.name into tag. |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			if tag := keyValueToTag(iter.Attribute()); tag != nil { |  | ||||||
| 				process.Tags = append(process.Tags, tag) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// If no service.name is contained in a Span's Resource, |  | ||||||
| 	// that field MUST be populated from the default Resource. |  | ||||||
| 	if serviceName.Value.AsString() == "" { |  | ||||||
| 		serviceName = semconv.ServiceName(defaultServiceName) |  | ||||||
| 	} |  | ||||||
| 	process.ServiceName = serviceName.Value.AsString() |  | ||||||
| 
 |  | ||||||
| 	return &process |  | ||||||
| } |  | ||||||
							
								
								
									
										204
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/reconnecting_udp_client.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										204
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/reconnecting_udp_client.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,204 +0,0 @@ | ||||||
| // Copyright The OpenTelemetry Authors |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
| 
 |  | ||||||
| package jaeger // import "go.opentelemetry.io/otel/exporters/jaeger" |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"net" |  | ||||||
| 	"sync" |  | ||||||
| 	"sync/atomic" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"github.com/go-logr/logr" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // reconnectingUDPConn is an implementation of udpConn that resolves hostPort every resolveTimeout, if the resolved address is |  | ||||||
| // different than the current conn then the new address is dialed and the conn is swapped. |  | ||||||
| type reconnectingUDPConn struct { |  | ||||||
| 	// `sync/atomic` expects the first word in an allocated struct to be 64-bit |  | ||||||
| 	// aligned on both ARM and x86-32. See https://goo.gl/zW7dgq for more details. |  | ||||||
| 	bufferBytes int64 |  | ||||||
| 	hostPort    string |  | ||||||
| 	resolveFunc resolveFunc |  | ||||||
| 	dialFunc    dialFunc |  | ||||||
| 	logger      logr.Logger |  | ||||||
| 
 |  | ||||||
| 	connMtx   sync.RWMutex |  | ||||||
| 	conn      *net.UDPConn |  | ||||||
| 	destAddr  *net.UDPAddr |  | ||||||
| 	closeChan chan struct{} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type resolveFunc func(network string, hostPort string) (*net.UDPAddr, error) |  | ||||||
| type dialFunc func(network string, laddr, raddr *net.UDPAddr) (*net.UDPConn, error) |  | ||||||
| 
 |  | ||||||
| // newReconnectingUDPConn returns a new udpConn that resolves hostPort every resolveTimeout, if the resolved address is |  | ||||||
| // different than the current conn then the new address is dialed and the conn is swapped. |  | ||||||
| func newReconnectingUDPConn(hostPort string, bufferBytes int, resolveTimeout time.Duration, resolveFunc resolveFunc, dialFunc dialFunc, logger logr.Logger) (*reconnectingUDPConn, error) { |  | ||||||
| 	conn := &reconnectingUDPConn{ |  | ||||||
| 		hostPort:    hostPort, |  | ||||||
| 		resolveFunc: resolveFunc, |  | ||||||
| 		dialFunc:    dialFunc, |  | ||||||
| 		logger:      logger, |  | ||||||
| 		closeChan:   make(chan struct{}), |  | ||||||
| 		bufferBytes: int64(bufferBytes), |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := conn.attemptResolveAndDial(); err != nil { |  | ||||||
| 		conn.logf("failed resolving destination address on connection startup, with err: %q. retrying in %s", err.Error(), resolveTimeout) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	go conn.reconnectLoop(resolveTimeout) |  | ||||||
| 
 |  | ||||||
| 	return conn, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *reconnectingUDPConn) logf(format string, args ...interface{}) { |  | ||||||
| 	if c.logger != emptyLogger { |  | ||||||
| 		c.logger.Info(format, args...) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *reconnectingUDPConn) reconnectLoop(resolveTimeout time.Duration) { |  | ||||||
| 	ticker := time.NewTicker(resolveTimeout) |  | ||||||
| 	defer ticker.Stop() |  | ||||||
| 
 |  | ||||||
| 	for { |  | ||||||
| 		select { |  | ||||||
| 		case <-c.closeChan: |  | ||||||
| 			return |  | ||||||
| 		case <-ticker.C: |  | ||||||
| 			if err := c.attemptResolveAndDial(); err != nil { |  | ||||||
| 				c.logf("%s", err.Error()) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *reconnectingUDPConn) attemptResolveAndDial() error { |  | ||||||
| 	newAddr, err := c.resolveFunc("udp", c.hostPort) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("failed to resolve new addr for host %q, with err: %w", c.hostPort, err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	c.connMtx.RLock() |  | ||||||
| 	curAddr := c.destAddr |  | ||||||
| 	c.connMtx.RUnlock() |  | ||||||
| 
 |  | ||||||
| 	// dont attempt dial if an addr was successfully dialed previously and, resolved addr is the same as current conn |  | ||||||
| 	if curAddr != nil && newAddr.String() == curAddr.String() { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := c.attemptDialNewAddr(newAddr); err != nil { |  | ||||||
| 		return fmt.Errorf("failed to dial newly resolved addr '%s', with err: %w", newAddr, err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *reconnectingUDPConn) attemptDialNewAddr(newAddr *net.UDPAddr) error { |  | ||||||
| 	connUDP, err := c.dialFunc(newAddr.Network(), nil, newAddr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if bufferBytes := int(atomic.LoadInt64(&c.bufferBytes)); bufferBytes != 0 { |  | ||||||
| 		if err = connUDP.SetWriteBuffer(bufferBytes); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	c.connMtx.Lock() |  | ||||||
| 	c.destAddr = newAddr |  | ||||||
| 	// store prev to close later |  | ||||||
| 	prevConn := c.conn |  | ||||||
| 	c.conn = connUDP |  | ||||||
| 	c.connMtx.Unlock() |  | ||||||
| 
 |  | ||||||
| 	if prevConn != nil { |  | ||||||
| 		return prevConn.Close() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Write calls net.udpConn.Write, if it fails an attempt is made to connect to a new addr, if that succeeds the write is retried before returning. |  | ||||||
| func (c *reconnectingUDPConn) Write(b []byte) (int, error) { |  | ||||||
| 	var bytesWritten int |  | ||||||
| 	var err error |  | ||||||
| 
 |  | ||||||
| 	c.connMtx.RLock() |  | ||||||
| 	conn := c.conn |  | ||||||
| 	c.connMtx.RUnlock() |  | ||||||
| 
 |  | ||||||
| 	if conn == nil { |  | ||||||
| 		// if connection is not initialized indicate this with err in order to hook into retry logic |  | ||||||
| 		err = fmt.Errorf("UDP connection not yet initialized, an address has not been resolved") |  | ||||||
| 	} else { |  | ||||||
| 		bytesWritten, err = conn.Write(b) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err == nil { |  | ||||||
| 		return bytesWritten, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// attempt to resolve and dial new address in case that's the problem, if resolve and dial succeeds, try write again |  | ||||||
| 	if reconnErr := c.attemptResolveAndDial(); reconnErr == nil { |  | ||||||
| 		c.connMtx.RLock() |  | ||||||
| 		conn := c.conn |  | ||||||
| 		c.connMtx.RUnlock() |  | ||||||
| 
 |  | ||||||
| 		return conn.Write(b) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// return original error if reconn fails |  | ||||||
| 	return bytesWritten, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Close stops the reconnectLoop, then closes the connection via net.udpConn 's implementation. |  | ||||||
| func (c *reconnectingUDPConn) Close() error { |  | ||||||
| 	close(c.closeChan) |  | ||||||
| 
 |  | ||||||
| 	// acquire rw lock before closing conn to ensure calls to Write drain |  | ||||||
| 	c.connMtx.Lock() |  | ||||||
| 	defer c.connMtx.Unlock() |  | ||||||
| 
 |  | ||||||
| 	if c.conn != nil { |  | ||||||
| 		return c.conn.Close() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetWriteBuffer defers to the net.udpConn SetWriteBuffer implementation wrapped with a RLock. if no conn is currently held |  | ||||||
| // and SetWriteBuffer is called store bufferBytes to be set for new conns. |  | ||||||
| func (c *reconnectingUDPConn) SetWriteBuffer(bytes int) error { |  | ||||||
| 	var err error |  | ||||||
| 
 |  | ||||||
| 	c.connMtx.RLock() |  | ||||||
| 	conn := c.conn |  | ||||||
| 	c.connMtx.RUnlock() |  | ||||||
| 
 |  | ||||||
| 	if conn != nil { |  | ||||||
| 		err = c.conn.SetWriteBuffer(bytes) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err == nil { |  | ||||||
| 		atomic.StoreInt64(&c.bufferBytes, int64(bytes)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
							
								
								
									
										339
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/uploader.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										339
									
								
								vendor/go.opentelemetry.io/otel/exporters/jaeger/uploader.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,339 +0,0 @@ | ||||||
| // Copyright The OpenTelemetry Authors |  | ||||||
| // |  | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
| // you may not use this file except in compliance with the License. |  | ||||||
| // You may obtain a copy of the License at |  | ||||||
| // |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
| 
 |  | ||||||
| package jaeger // import "go.opentelemetry.io/otel/exporters/jaeger" |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"context" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"log" |  | ||||||
| 	"net/http" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"github.com/go-logr/logr" |  | ||||||
| 	"github.com/go-logr/stdr" |  | ||||||
| 
 |  | ||||||
| 	gen "go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger" |  | ||||||
| 	"go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // batchUploader send a batch of spans to Jaeger. |  | ||||||
| type batchUploader interface { |  | ||||||
| 	upload(context.Context, *gen.Batch) error |  | ||||||
| 	shutdown(context.Context) error |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // EndpointOption configures a Jaeger endpoint. |  | ||||||
| type EndpointOption interface { |  | ||||||
| 	newBatchUploader() (batchUploader, error) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type endpointOptionFunc func() (batchUploader, error) |  | ||||||
| 
 |  | ||||||
| func (fn endpointOptionFunc) newBatchUploader() (batchUploader, error) { |  | ||||||
| 	return fn() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithAgentEndpoint configures the Jaeger exporter to send spans to a Jaeger agent |  | ||||||
| // over compact thrift protocol. This will use the following environment variables for |  | ||||||
| // configuration if no explicit option is provided: |  | ||||||
| // |  | ||||||
| // - OTEL_EXPORTER_JAEGER_AGENT_HOST is used for the agent address host |  | ||||||
| // - OTEL_EXPORTER_JAEGER_AGENT_PORT is used for the agent address port |  | ||||||
| // |  | ||||||
| // The passed options will take precedence over any environment variables and default values |  | ||||||
| // will be used if neither are provided. |  | ||||||
| func WithAgentEndpoint(options ...AgentEndpointOption) EndpointOption { |  | ||||||
| 	return endpointOptionFunc(func() (batchUploader, error) { |  | ||||||
| 		cfg := agentEndpointConfig{ |  | ||||||
| 			agentClientUDPParams{ |  | ||||||
| 				AttemptReconnecting: true, |  | ||||||
| 				Host:                envOr(envAgentHost, "localhost"), |  | ||||||
| 				Port:                envOr(envAgentPort, "6831"), |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 		for _, opt := range options { |  | ||||||
| 			cfg = opt.apply(cfg) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		client, err := newAgentClientUDP(cfg.agentClientUDPParams) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return &agentUploader{client: client}, nil |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // AgentEndpointOption configures a Jaeger agent endpoint. |  | ||||||
| type AgentEndpointOption interface { |  | ||||||
| 	apply(agentEndpointConfig) agentEndpointConfig |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type agentEndpointConfig struct { |  | ||||||
| 	agentClientUDPParams |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type agentEndpointOptionFunc func(agentEndpointConfig) agentEndpointConfig |  | ||||||
| 
 |  | ||||||
| func (fn agentEndpointOptionFunc) apply(cfg agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 	return fn(cfg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithAgentHost sets a host to be used in the agent client endpoint. |  | ||||||
| // This option overrides any value set for the |  | ||||||
| // OTEL_EXPORTER_JAEGER_AGENT_HOST environment variable. |  | ||||||
| // If this option is not passed and the env var is not set, "localhost" will be used by default. |  | ||||||
| func WithAgentHost(host string) AgentEndpointOption { |  | ||||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 		o.Host = host |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithAgentPort sets a port to be used in the agent client endpoint. |  | ||||||
| // This option overrides any value set for the |  | ||||||
| // OTEL_EXPORTER_JAEGER_AGENT_PORT environment variable. |  | ||||||
| // If this option is not passed and the env var is not set, "6831" will be used by default. |  | ||||||
| func WithAgentPort(port string) AgentEndpointOption { |  | ||||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 		o.Port = port |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var emptyLogger = logr.Logger{} |  | ||||||
| 
 |  | ||||||
| // WithLogger sets a logger to be used by agent client. |  | ||||||
| // WithLogger and WithLogr will overwrite each other. |  | ||||||
| func WithLogger(logger *log.Logger) AgentEndpointOption { |  | ||||||
| 	return WithLogr(stdr.New(logger)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithLogr sets a logr.Logger to be used by agent client. |  | ||||||
| // WithLogr and WithLogger will overwrite each other. |  | ||||||
| func WithLogr(logger logr.Logger) AgentEndpointOption { |  | ||||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 		o.Logger = logger |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithDisableAttemptReconnecting sets option to disable reconnecting udp client. |  | ||||||
| func WithDisableAttemptReconnecting() AgentEndpointOption { |  | ||||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 		o.AttemptReconnecting = false |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithAttemptReconnectingInterval sets the interval between attempts to re resolve agent endpoint. |  | ||||||
| func WithAttemptReconnectingInterval(interval time.Duration) AgentEndpointOption { |  | ||||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 		o.AttemptReconnectInterval = interval |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithMaxPacketSize sets the maximum UDP packet size for transport to the Jaeger agent. |  | ||||||
| func WithMaxPacketSize(size int) AgentEndpointOption { |  | ||||||
| 	return agentEndpointOptionFunc(func(o agentEndpointConfig) agentEndpointConfig { |  | ||||||
| 		o.MaxPacketSize = size |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithCollectorEndpoint defines the full URL to the Jaeger HTTP Thrift collector. This will |  | ||||||
| // use the following environment variables for configuration if no explicit option is provided: |  | ||||||
| // |  | ||||||
| // - OTEL_EXPORTER_JAEGER_ENDPOINT is the HTTP endpoint for sending spans directly to a collector. |  | ||||||
| // - OTEL_EXPORTER_JAEGER_USER is the username to be sent as authentication to the collector endpoint. |  | ||||||
| // - OTEL_EXPORTER_JAEGER_PASSWORD is the password to be sent as authentication to the collector endpoint. |  | ||||||
| // |  | ||||||
| // The passed options will take precedence over any environment variables. |  | ||||||
| // If neither values are provided for the endpoint, the default value of "http://localhost:14268/api/traces" will be used. |  | ||||||
| // If neither values are provided for the username or the password, they will not be set since there is no default. |  | ||||||
| func WithCollectorEndpoint(options ...CollectorEndpointOption) EndpointOption { |  | ||||||
| 	return endpointOptionFunc(func() (batchUploader, error) { |  | ||||||
| 		cfg := collectorEndpointConfig{ |  | ||||||
| 			endpoint:   envOr(envEndpoint, "http://localhost:14268/api/traces"), |  | ||||||
| 			username:   envOr(envUser, ""), |  | ||||||
| 			password:   envOr(envPassword, ""), |  | ||||||
| 			httpClient: http.DefaultClient, |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for _, opt := range options { |  | ||||||
| 			cfg = opt.apply(cfg) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return &collectorUploader{ |  | ||||||
| 			endpoint:   cfg.endpoint, |  | ||||||
| 			username:   cfg.username, |  | ||||||
| 			password:   cfg.password, |  | ||||||
| 			httpClient: cfg.httpClient, |  | ||||||
| 		}, nil |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // CollectorEndpointOption configures a Jaeger collector endpoint. |  | ||||||
| type CollectorEndpointOption interface { |  | ||||||
| 	apply(collectorEndpointConfig) collectorEndpointConfig |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type collectorEndpointConfig struct { |  | ||||||
| 	// endpoint for sending spans directly to a collector. |  | ||||||
| 	endpoint string |  | ||||||
| 
 |  | ||||||
| 	// username to be used for authentication with the collector endpoint. |  | ||||||
| 	username string |  | ||||||
| 
 |  | ||||||
| 	// password to be used for authentication with the collector endpoint. |  | ||||||
| 	password string |  | ||||||
| 
 |  | ||||||
| 	// httpClient to be used to make requests to the collector endpoint. |  | ||||||
| 	httpClient *http.Client |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type collectorEndpointOptionFunc func(collectorEndpointConfig) collectorEndpointConfig |  | ||||||
| 
 |  | ||||||
| func (fn collectorEndpointOptionFunc) apply(cfg collectorEndpointConfig) collectorEndpointConfig { |  | ||||||
| 	return fn(cfg) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithEndpoint is the URL for the Jaeger collector that spans are sent to. |  | ||||||
| // This option overrides any value set for the |  | ||||||
| // OTEL_EXPORTER_JAEGER_ENDPOINT environment variable. |  | ||||||
| // If this option is not passed and the environment variable is not set, |  | ||||||
| // "http://localhost:14268/api/traces" will be used by default. |  | ||||||
| func WithEndpoint(endpoint string) CollectorEndpointOption { |  | ||||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { |  | ||||||
| 		o.endpoint = endpoint |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithUsername sets the username to be used in the authorization header sent for all requests to the collector. |  | ||||||
| // This option overrides any value set for the |  | ||||||
| // OTEL_EXPORTER_JAEGER_USER environment variable. |  | ||||||
| // If this option is not passed and the environment variable is not set, no username will be set. |  | ||||||
| func WithUsername(username string) CollectorEndpointOption { |  | ||||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { |  | ||||||
| 		o.username = username |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithPassword sets the password to be used in the authorization header sent for all requests to the collector. |  | ||||||
| // This option overrides any value set for the |  | ||||||
| // OTEL_EXPORTER_JAEGER_PASSWORD environment variable. |  | ||||||
| // If this option is not passed and the environment variable is not set, no password will be set. |  | ||||||
| func WithPassword(password string) CollectorEndpointOption { |  | ||||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { |  | ||||||
| 		o.password = password |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WithHTTPClient sets the http client to be used to make request to the collector endpoint. |  | ||||||
| func WithHTTPClient(client *http.Client) CollectorEndpointOption { |  | ||||||
| 	return collectorEndpointOptionFunc(func(o collectorEndpointConfig) collectorEndpointConfig { |  | ||||||
| 		o.httpClient = client |  | ||||||
| 		return o |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // agentUploader implements batchUploader interface sending batches to |  | ||||||
| // Jaeger through the UDP agent. |  | ||||||
| type agentUploader struct { |  | ||||||
| 	client *agentClientUDP |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ batchUploader = (*agentUploader)(nil) |  | ||||||
| 
 |  | ||||||
| func (a *agentUploader) shutdown(ctx context.Context) error { |  | ||||||
| 	done := make(chan error, 1) |  | ||||||
| 	go func() { |  | ||||||
| 		done <- a.client.Close() |  | ||||||
| 	}() |  | ||||||
| 
 |  | ||||||
| 	select { |  | ||||||
| 	case <-ctx.Done(): |  | ||||||
| 		// Prioritize not blocking the calling thread and just leak the |  | ||||||
| 		// spawned goroutine to close the client. |  | ||||||
| 		return ctx.Err() |  | ||||||
| 	case err := <-done: |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (a *agentUploader) upload(ctx context.Context, batch *gen.Batch) error { |  | ||||||
| 	return a.client.EmitBatch(ctx, batch) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // collectorUploader implements batchUploader interface sending batches to |  | ||||||
| // Jaeger through the collector http endpoint. |  | ||||||
| type collectorUploader struct { |  | ||||||
| 	endpoint   string |  | ||||||
| 	username   string |  | ||||||
| 	password   string |  | ||||||
| 	httpClient *http.Client |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var _ batchUploader = (*collectorUploader)(nil) |  | ||||||
| 
 |  | ||||||
| func (c *collectorUploader) shutdown(ctx context.Context) error { |  | ||||||
| 	// The Exporter will cancel any active exports and will prevent all |  | ||||||
| 	// subsequent exports, so nothing to do here. |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *collectorUploader) upload(ctx context.Context, batch *gen.Batch) error { |  | ||||||
| 	body, err := serialize(batch) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	req, err := http.NewRequestWithContext(ctx, "POST", c.endpoint, body) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if c.username != "" && c.password != "" { |  | ||||||
| 		req.SetBasicAuth(c.username, c.password) |  | ||||||
| 	} |  | ||||||
| 	req.Header.Set("Content-Type", "application/x-thrift") |  | ||||||
| 
 |  | ||||||
| 	resp, err := c.httpClient.Do(req) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, _ = io.Copy(io.Discard, resp.Body) |  | ||||||
| 	if err = resp.Body.Close(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if resp.StatusCode < 200 || resp.StatusCode >= 300 { |  | ||||||
| 		return fmt.Errorf("failed to upload traces; HTTP status code: %d", resp.StatusCode) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func serialize(obj thrift.TStruct) (*bytes.Buffer, error) { |  | ||||||
| 	buf := thrift.NewTMemoryBuffer() |  | ||||||
| 	if err := obj.Write(context.Background(), thrift.NewTBinaryProtocolConf(buf, &thrift.TConfiguration{})); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return buf.Buffer, nil |  | ||||||
| } |  | ||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue