diff --git a/.azure-pipelines/pipelines.yml b/.azure-pipelines/pipelines.yml index 5afb77b97b20..ffa38e11198d 100644 --- a/.azure-pipelines/pipelines.yml +++ b/.azure-pipelines/pipelines.yml @@ -393,6 +393,12 @@ stages: BAZEL_REMOTE_CACHE: grpcs://remotebuildexecution.googleapis.com BAZEL_REMOTE_INSTANCE: projects/envoy-ci/instances/default_instance GCP_SERVICE_ACCOUNT_KEY: $(GcpServiceAccountKey) + - task: PublishTestResults@2 + inputs: + testResultsFiles: "**/bazel-out/**/testlogs/**/test.xml" + testRunTitle: "windows" + searchFolder: $(Build.StagingDirectory)/tmp + condition: always() - task: PublishBuildArtifacts@1 inputs: pathtoPublish: "$(Build.StagingDirectory)/envoy" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 97c37be6a676..b6ee2969559f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -12,6 +12,9 @@ // Uncomment next line if you have devcontainer.env // "--env-file=.devcontainer/devcontainer.env" ], + "containerEnv": { + "ENVOY_SRCDIR": "${containerWorkspaceFolder}", + }, "settings": { "terminal.integrated.shell.linux": "/bin/bash", "bazel.buildifierFixOnFormat": true, diff --git a/.github/workflows/codeql-push.yml b/.github/workflows/codeql-push.yml index d6110bbddca2..fbe091a90ec0 100644 --- a/.github/workflows/codeql-push.yml +++ b/.github/workflows/codeql-push.yml @@ -24,7 +24,9 @@ jobs: - name: Get build targets run: | . .github/workflows/get_build_targets.sh - echo ::set-env name=BUILD_TARGETS::$(echo $BUILD_TARGETS_LOCAL) + echo 'BUILD_TARGETS<> $GITHUB_ENV + echo $BUILD_TARGETS_LOCAL >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 diff --git a/CODEOWNERS b/CODEOWNERS index ab8af77e3401..c72b2900ec38 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -92,6 +92,8 @@ extensions/filters/common/original_src @snowp @klarose /*/extensions/filters/network/wasm @PiotrSikora @lizan # webassembly common extension /*/extensions/common/wasm @PiotrSikora @lizan +# webassembly runtimes +/*/extensions/wasm_runtime/ @PiotrSikora @lizan # common matcher /*/extensions/common/matcher @mattklein123 @yangminzhu # common crypto extension diff --git a/REPO_LAYOUT.md b/REPO_LAYOUT.md index e4f2452a1417..3eae104c8c35 100644 --- a/REPO_LAYOUT.md +++ b/REPO_LAYOUT.md @@ -63,9 +63,8 @@ Not every directory within test is described below, but a few highlights: ## [source/extensions](source/extensions/) layout We maintain a very specific code and namespace layout for extensions. This aids in discovering -code/extensions, and also will allow us in the future to more easily scale out our extension -maintainers by having OWNERS files specific to certain extensions. (As of this writing, this is not -currently implemented but that is the plan moving forward.) +code/extensions, and allows us specify extension owners in [CODEOWNERS](CODEOWNERS). + * All extensions are either registered in [all_extensions.bzl](source/extensions/all_extensions.bzl) or [extensions_build_config.bzl](source/extensions/extensions_build_config.bzl). The former is @@ -76,6 +75,14 @@ currently implemented but that is the plan moving forward.) * These are the top level extension directories and associated namespaces: * [access_loggers/](/source/extensions/access_loggers): Access log implementations which use the `Envoy::Extensions::AccessLoggers` namespace. + * [bootstrap](/source/extensions/bootstrap): Bootstrap extensions which use + the `Envoy::Extensions::Bootstrap` namespace. + * [clusters](/source/extensions/clusters): Cluster extensions which use the + `Envoy::Extensions::Clusters` namespace. + * [compression](/source/extensions/compression): Compression extensions + which use `Envoy::Extensions::Compression` namespace. + * [fatal_actions](/source/extensions/fatal_actions): Fatal Action extensions + which use the `Envoy::Extensions::FatalActions` namespace. * [filters/http/](/source/extensions/filters/http): HTTP L7 filters which use the `Envoy::Extensions::HttpFilters` namespace. * [filters/listener/](/source/extensions/filters/listener): Listener filters which use the @@ -86,14 +93,24 @@ currently implemented but that is the plan moving forward.) `Envoy::Extensions::GrpcCredentials` namespace. * [health_checker/](/source/extensions/health_checker): Custom health checkers which use the `Envoy::Extensions::HealthCheckers` namespace. - * [resolvers/](/source/extensions/resolvers): Network address resolvers which use the - `Envoy::Extensions::Resolvers` namespace. + * [internal_redirect](/source/extensions/internal_redirect): Internal Redirect + extensions which use the `Envoy::Extensions::InternalRedirect` namespace. + * [quic_listeners](/source/extensions/quic_listeners): QUIC extensions which + use the `Envoy::Quic` namespace. + * [resource_monitors](/source/extensions/resource_monitors): Resource monitor + extensions which use the `Envoy::Extensions::ResourceMonitors` namespace. + * [retry](/source/extensions/retry): Retry extensions which use the + `Envoy::Extensions::Retry` namespace. * [stat_sinks/](/source/extensions/stat_sinks): Stat sink implementations which use the `Envoy::Extensions::StatSinks` namespace. * [tracers/](/source/extensions/tracers): Tracers which use the `Envoy::Extensions::Tracers` namespace. * [transport_sockets/](/source/extensions/transport_sockets): Transport socket implementations which use the `Envoy::Extensions::TransportSockets` namespace. + * [upstreams](/source/extensions/upstreams): Upstream extensions use the + `Envoy::Extensions::Upstreams` namespace. + * [watchdog](/source/extensions/watchdog): Watchdog extensions use the + `Envoy::Extensions::Watchdog` namespace. * Each extension is contained wholly in its own namespace. E.g., `Envoy::Extensions::NetworkFilters::Echo`. * Common code that is used by multiple extensions should be in a `common/` directory as close to diff --git a/api/envoy/config/bootstrap/v3/bootstrap.proto b/api/envoy/config/bootstrap/v3/bootstrap.proto index a9a0290b297c..9581fd6ca772 100644 --- a/api/envoy/config/bootstrap/v3/bootstrap.proto +++ b/api/envoy/config/bootstrap/v3/bootstrap.proto @@ -40,7 +40,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 28] +// [#next-free-field: 29] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Bootstrap"; @@ -243,6 +243,10 @@ message Bootstrap { // Each item contains extension specific configuration. repeated core.v3.TypedExtensionConfig bootstrap_extensions = 21; + // Specifies optional extensions instantiated at startup time and + // invoked during crash time on the request that caused the crash. + repeated FatalAction fatal_actions = 28; + // Configuration sources that will participate in // *udpa.core.v1.ResourceLocator* authority resolution. The algorithm is as // follows: @@ -420,6 +424,20 @@ message Watchdog { type.v3.Percent multikill_threshold = 5; } +// Fatal actions to run while crashing. Actions can be safe (meaning they are +// async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. +// If using an unsafe action that could get stuck or deadlock, it important to +// have an out of band system to terminate the process. +// +// The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. +// *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API +// namespace. +message FatalAction { + // Extension specific configuration for the action. It's expected to conform + // to the ``Envoy::Server::Configuration::FatalAction`` interface. + core.v3.TypedExtensionConfig config = 1; +} + // Runtime :ref:`configuration overview ` (deprecated). message Runtime { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Runtime"; diff --git a/api/envoy/config/bootstrap/v4alpha/bootstrap.proto b/api/envoy/config/bootstrap/v4alpha/bootstrap.proto index ef10dead9706..1fe40d6b9607 100644 --- a/api/envoy/config/bootstrap/v4alpha/bootstrap.proto +++ b/api/envoy/config/bootstrap/v4alpha/bootstrap.proto @@ -38,7 +38,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 28] +// [#next-free-field: 29] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v3.Bootstrap"; @@ -229,6 +229,10 @@ message Bootstrap { // Each item contains extension specific configuration. repeated core.v4alpha.TypedExtensionConfig bootstrap_extensions = 21; + // Specifies optional extensions instantiated at startup time and + // invoked during crash time on the request that caused the crash. + repeated FatalAction fatal_actions = 28; + // Configuration sources that will participate in // *udpa.core.v1.ResourceLocator* authority resolution. The algorithm is as // follows: @@ -412,6 +416,23 @@ message Watchdog { type.v3.Percent multikill_threshold = 5; } +// Fatal actions to run while crashing. Actions can be safe (meaning they are +// async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. +// If using an unsafe action that could get stuck or deadlock, it important to +// have an out of band system to terminate the process. +// +// The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. +// *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API +// namespace. +message FatalAction { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.bootstrap.v3.FatalAction"; + + // Extension specific configuration for the action. It's expected to conform + // to the ``Envoy::Server::Configuration::FatalAction`` interface. + core.v4alpha.TypedExtensionConfig config = 1; +} + // Runtime :ref:`configuration overview ` (deprecated). message Runtime { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v3.Runtime"; diff --git a/api/envoy/config/common/matcher/v3/matcher.proto b/api/envoy/config/common/matcher/v3/matcher.proto index 8a1cb4839c4a..24ed5dafbdc5 100644 --- a/api/envoy/config/common/matcher/v3/matcher.proto +++ b/api/envoy/config/common/matcher/v3/matcher.proto @@ -4,7 +4,7 @@ package envoy.config.common.matcher.v3; import "envoy/config/core/v3/extension.proto"; import "envoy/config/route/v3/route_components.proto"; -import "envoy/type/matcher/v3/value.proto"; +import "envoy/type/matcher/v3/string.proto"; import "udpa/annotations/migrate.proto"; import "udpa/annotations/status.proto"; @@ -58,9 +58,8 @@ message Matcher { oneof matcher { option (validate.required) = true; - // Use existing infrastructure for actually matching the - // value. - type.matcher.v3.ValueMatcher value_match = 2; + // Built-in string matcher. + type.matcher.v3.StringMatcher value_match = 2; // Extension for custom matching logic. core.v3.TypedExtensionConfig custom_match = 3; diff --git a/api/envoy/config/common/matcher/v4alpha/matcher.proto b/api/envoy/config/common/matcher/v4alpha/matcher.proto index 15859474e6e1..ab1f4de6cccc 100644 --- a/api/envoy/config/common/matcher/v4alpha/matcher.proto +++ b/api/envoy/config/common/matcher/v4alpha/matcher.proto @@ -4,7 +4,7 @@ package envoy.config.common.matcher.v4alpha; import "envoy/config/core/v4alpha/extension.proto"; import "envoy/config/route/v4alpha/route_components.proto"; -import "envoy/type/matcher/v4alpha/value.proto"; +import "envoy/type/matcher/v4alpha/string.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -72,9 +72,8 @@ message Matcher { oneof matcher { option (validate.required) = true; - // Use existing infrastructure for actually matching the - // value. - type.matcher.v4alpha.ValueMatcher value_match = 2; + // Built-in string matcher. + type.matcher.v4alpha.StringMatcher value_match = 2; // Extension for custom matching logic. core.v4alpha.TypedExtensionConfig custom_match = 3; diff --git a/api/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto b/api/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto index 3082089202ee..007ccabc3e47 100644 --- a/api/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto +++ b/api/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto @@ -15,11 +15,27 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // gRPC-JSON transcoder :ref:`configuration overview `. // [#extension: envoy.filters.http.grpc_json_transcoder] -// [#next-free-field: 10] +// [#next-free-field: 11] message GrpcJsonTranscoder { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder"; + enum UrlUnescapeSpec { + // URL path parameters will not decode RFC 6570 reserved characters. + // For example, segment `%2f%23/%20%2523` is unescaped to `%2f%23/ %23`. + ALL_CHARACTERS_EXCEPT_RESERVED = 0; + + // URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // For example, segment `%2f%23/%20%2523` is unescaped to `%2f#/ %23`. + ALL_CHARACTERS_EXCEPT_SLASH = 1; + + // URL path parameters will be fully URI-decoded. + // For example, segment `%2f%23/%20%2523` is unescaped to `/#/ %23`. + ALL_CHARACTERS = 2; + } + message PrintOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder.PrintOptions"; @@ -160,4 +176,11 @@ message GrpcJsonTranscoder { // the ``google/rpc/error_details.proto`` should be included in the configured // :ref:`proto descriptor set `. bool convert_grpc_status = 9; + + // URL unescaping policy. + // This spec is only applied when extracting variable with multiple segments. + // For example, in case of `/foo/{x=*}/bar/{y=prefix/*}/{z=**}` `x` variable is single segment and `y` and `z` are multiple segments. + // For a path with `/foo/first/bar/prefix/second/third/fourth`, `x=first`, `y=prefix/second`, `z=third/fourth`. + // If this setting is not specified, the value defaults to :ref:`ALL_CHARACTERS_EXCEPT_RESERVED`. + UrlUnescapeSpec url_unescape_spec = 10 [(validate.rules).enum = {defined_only: true}]; } diff --git a/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto index 0e4294608384..a10fa68f3043 100644 --- a/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -51,7 +51,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // cache_duration: // seconds: 300 // -// [#next-free-field: 10] +// [#next-free-field: 11] message JwtProvider { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.jwt_authn.v2alpha.JwtProvider"; @@ -191,6 +191,10 @@ message JwtProvider { // exp: 1501281058 // string payload_in_metadata = 9; + + // Specify the clock skew in seconds when verifying JWT time constraint, + // such as `exp`, and `nbf`. If not specified, default is 60 seconds. + uint32 clock_skew_seconds = 10; } // This message specifies how to fetch JWKS from remote and how to cache it. diff --git a/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto b/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto index 53ee84fd65ea..2746640fa738 100644 --- a/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto +++ b/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto @@ -51,7 +51,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // cache_duration: // seconds: 300 // -// [#next-free-field: 10] +// [#next-free-field: 11] message JwtProvider { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.http.jwt_authn.v3.JwtProvider"; @@ -191,6 +191,10 @@ message JwtProvider { // exp: 1501281058 // string payload_in_metadata = 9; + + // Specify the clock skew in seconds when verifying JWT time constraint, + // such as `exp`, and `nbf`. If not specified, default is 60 seconds. + uint32 clock_skew_seconds = 10; } // This message specifies how to fetch JWKS from remote and how to cache it. diff --git a/api/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto b/api/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto index e4be64167ed2..11fe12695865 100644 --- a/api/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto +++ b/api/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto @@ -44,7 +44,7 @@ message OAuth2Credentials { // OAuth config // -// [#next-free-field: 9] +// [#next-free-field: 10] message OAuth2Config { // Endpoint on the authorization server to retrieve the access token from. config.core.v3.HttpUri token_endpoint = 1; @@ -74,6 +74,11 @@ message OAuth2Config { // Any request that matches any of the provided matchers will be passed through without OAuth validation. repeated config.route.v3.HeaderMatcher pass_through_matcher = 8; + + // Optional list of OAuth scopes to be claimed in the authorization request. If not specified, + // defaults to "user" scope. + // OAuth RFC https://tools.ietf.org/html/rfc6749#section-3.3 + repeated string auth_scopes = 9; } // Filter config. diff --git a/api/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto b/api/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto index ee51e1f96099..af1f0944ed34 100644 --- a/api/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto +++ b/api/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto @@ -47,7 +47,7 @@ message OAuth2Credentials { // OAuth config // -// [#next-free-field: 9] +// [#next-free-field: 10] message OAuth2Config { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.http.oauth2.v3alpha.OAuth2Config"; @@ -80,6 +80,11 @@ message OAuth2Config { // Any request that matches any of the provided matchers will be passed through without OAuth validation. repeated config.route.v4alpha.HeaderMatcher pass_through_matcher = 8; + + // Optional list of OAuth scopes to be claimed in the authorization request. If not specified, + // defaults to "user" scope. + // OAuth RFC https://tools.ietf.org/html/rfc6749#section-3.3 + repeated string auth_scopes = 9; } // Filter config. diff --git a/api/envoy/extensions/transport_sockets/tls/v3/common.proto b/api/envoy/extensions/transport_sockets/tls/v3/common.proto index 587e3271836b..2b545b35ee12 100644 --- a/api/envoy/extensions/transport_sockets/tls/v3/common.proto +++ b/api/envoy/extensions/transport_sockets/tls/v3/common.proto @@ -155,7 +155,8 @@ message TlsCertificate { // default the parent directories of the filesystem paths in // *certificate_chain* and *private_key* are watched if this field is not // specified. This only applies when a *TlsCertificate* is delivered by SDS - // with references to filesystem paths. + // with references to filesystem paths. See the :ref:`SDS key rotation + // ` documentation for further details. config.core.v3.WatchedDirectory watched_directory = 7; // BoringSSL private key method provider. This is an alternative to :ref:`private_key @@ -265,7 +266,8 @@ message CertificateValidationContext { // default the parent directory of the filesystem path in *trusted_ca* is // watched if this field is not specified. This only applies when a // *CertificateValidationContext* is delivered by SDS with references to - // filesystem paths. + // filesystem paths. See the :ref:`SDS key rotation ` + // documentation for further details. config.core.v3.WatchedDirectory watched_directory = 11; // An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the diff --git a/api/envoy/extensions/transport_sockets/tls/v4alpha/common.proto b/api/envoy/extensions/transport_sockets/tls/v4alpha/common.proto index b2fa6f672628..30859bc2a3eb 100644 --- a/api/envoy/extensions/transport_sockets/tls/v4alpha/common.proto +++ b/api/envoy/extensions/transport_sockets/tls/v4alpha/common.proto @@ -157,7 +157,8 @@ message TlsCertificate { // default the parent directories of the filesystem paths in // *certificate_chain* and *private_key* are watched if this field is not // specified. This only applies when a *TlsCertificate* is delivered by SDS - // with references to filesystem paths. + // with references to filesystem paths. See the :ref:`SDS key rotation + // ` documentation for further details. config.core.v4alpha.WatchedDirectory watched_directory = 7; // BoringSSL private key method provider. This is an alternative to :ref:`private_key @@ -267,7 +268,8 @@ message CertificateValidationContext { // default the parent directory of the filesystem path in *trusted_ca* is // watched if this field is not specified. This only applies when a // *CertificateValidationContext* is delivered by SDS with references to - // filesystem paths. + // filesystem paths. See the :ref:`SDS key rotation ` + // documentation for further details. config.core.v4alpha.WatchedDirectory watched_directory = 11; // An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the diff --git a/api/envoy/extensions/wasm/v3/wasm.proto b/api/envoy/extensions/wasm/v3/wasm.proto index b42fb75a0bf7..c6affb810611 100644 --- a/api/envoy/extensions/wasm/v3/wasm.proto +++ b/api/envoy/extensions/wasm/v3/wasm.proto @@ -28,7 +28,29 @@ message VmConfig { // See ref: "TODO: add ref" for details. string vm_id = 1; - // The Wasm runtime type (either "v8" or "null" for code compiled into Envoy). + // The Wasm runtime type. + // Available Wasm runtime types are registered as extensions. The following runtimes are included + // in Envoy code base: + // + // .. _extension_envoy.wasm.runtime.null: + // + // **envoy.wasm.runtime.null**: Null sandbox, the Wasm module must be compiled and linked into the + // Envoy binary. The registered name is given in the *code* field as *inline_string*. + // + // .. _extension_envoy.wasm.runtime.v8: + // + // **envoy.wasm.runtime.v8**: `V8 `_-based WebAssembly runtime. + // + // .. _extension_envoy.wasm.runtime.wavm: + // + // **envoy.wasm.runtime.wavm**: `WAVM `_-based WebAssembly runtime. + // This runtime is not enabled in the official build. + // + // .. _extension_envoy.wasm.runtime.wasmtime: + // + // **envoy.wasm.runtime.wasmtime**: `Wasmtime `_-based WebAssembly runtime. + // This runtime is not enabled in the official build. + // string runtime = 2 [(validate.rules).string = {min_len: 1}]; // The Wasm code that Envoy will execute. diff --git a/bazel/README.md b/bazel/README.md index f2b79eab5c00..50379a6efd0a 100644 --- a/bazel/README.md +++ b/bazel/README.md @@ -126,14 +126,19 @@ for how to update or override dependencies. Install bazelisk in the PATH using the `bazel.exe` executable name as described above in the first section. When building Envoy, Bazel creates very long path names. One way to work around these excessive path - lengths is to change the output base directory for bazel to a very short root path. The CI pipeline - for Windows uses `C:\_eb` as the bazel base path. This and other preferences should be set up by placing + lengths is to change the output base directory for bazel to a very short root path. An example Bazel configuration + to help with this is to use `C:\_eb` as the bazel base path. This and other preferences should be set up by placing the following bazelrc configuration line in a system `%ProgramData%\bazel.bazelrc` file or the individual user's `%USERPROFILE%\.bazelrc` file (rather than including it on every bazel command line): + ``` startup --output_base=C:/_eb ``` + Another option to shorten the the output root for Bazel is to set the `USERNAME` environment variable in your shell + session to a short value. Bazel uses this value when constructing its output root path if no explicit `--output_base` + is set. + Bazel also creates file symlinks when building Envoy. It's strongly recommended to enable file symlink support using [Bazel's instructions](https://docs.bazel.build/versions/master/windows.html#enable-symlink-support). For other common issues, see the @@ -721,13 +726,18 @@ https://github.com/bazelbuild/bazel/issues/2805. # Coverage builds -To generate coverage results, make sure you are using a clang toolchain and have `llvm-cov` and +To generate coverage results, make sure you are using a Clang toolchain and have `llvm-cov` and `llvm-profdata` in your `PATH`. Then run: ``` test/run_envoy_bazel_coverage.sh ``` +**Note** that it is important to ensure that the versions of `clang`, `llvm-cov` and `llvm-profdata` +are consistent and that they match the most recent Clang/LLVM toolchain version in use by Envoy (see +the [build container +toolchain](https://github.com/envoyproxy/envoy-build-tools/blob/master/build_container/build_container_ubuntu.sh) for reference). + The summary results are printed to the standard output and the full coverage report is available in `generated/coverage/coverage.html`. diff --git a/bazel/envoy_internal.bzl b/bazel/envoy_internal.bzl index 91d7ac2abee8..c122e36cd9c7 100644 --- a/bazel/envoy_internal.bzl +++ b/bazel/envoy_internal.bzl @@ -63,6 +63,8 @@ def envoy_copts(repository, test = False): }) + select({ repository + "//bazel:clang_build": ["-fno-limit-debug-info", "-Wgnu-conditional-omitted-operand", "-Wc++2a-extensions", "-Wrange-loop-analysis"], repository + "//bazel:gcc_build": ["-Wno-maybe-uninitialized"], + # TODO: Replace with /Zc:preprocessor for cl.exe versions >= 16.5 + repository + "//bazel:windows_x86_64": ["-experimental:preprocessor", "-Wv:19.4"], "//conditions:default": [], }) + select({ repository + "//bazel:no_debug_info": ["-g0"], diff --git a/bazel/envoy_library.bzl b/bazel/envoy_library.bzl index adcee0750790..a2f7c6b0ae02 100644 --- a/bazel/envoy_library.bzl +++ b/bazel/envoy_library.bzl @@ -144,7 +144,7 @@ def envoy_cc_library( hdrs = hdrs, copts = envoy_copts(repository) + copts, visibility = visibility, - tags = ["nocompdb"], + tags = ["nocompdb"] + tags, deps = [":" + name], strip_include_prefix = strip_include_prefix, ) diff --git a/bazel/external/proxy_wasm_cpp_host.BUILD b/bazel/external/proxy_wasm_cpp_host.BUILD index 6157654ed5ea..148635bc099d 100644 --- a/bazel/external/proxy_wasm_cpp_host.BUILD +++ b/bazel/external/proxy_wasm_cpp_host.BUILD @@ -1,10 +1,4 @@ load("@rules_cc//cc:defs.bzl", "cc_library") -load( - "@envoy//bazel:envoy_build_system.bzl", - "envoy_select_wasm_v8", - "envoy_select_wasm_wasmtime", - "envoy_select_wasm_wavm", -) licenses(["notice"]) # Apache 2 @@ -19,29 +13,14 @@ cc_library( ) cc_library( - name = "lib", - # Note that the select cannot appear in the glob. - srcs = glob( - [ - "src/**/*.h", - "src/**/*.cc", - ], - exclude = [ - "src/v8/*.cc", - "src/wavm/*.cc", - "src/wasmtime/*.cc", - ], - ) + envoy_select_wasm_v8(glob([ - "src/v8/*.cc", - ])) + envoy_select_wasm_wavm(glob([ - "src/wavm/*.cc", - ])) + envoy_select_wasm_wasmtime(glob([ - "src/wasmtime/*.cc", - ])), - copts = envoy_select_wasm_wavm([ - '-DWAVM_API=""', - "-Wno-non-virtual-dtor", - "-Wno-old-style-cast", + name = "common_lib", + srcs = glob([ + "src/*.h", + "src/*.cc", + "src/common/*.h", + "src/common/*.cc", + "src/third_party/*.h", + "src/third_party/*.cc", ]), deps = [ ":include", @@ -53,11 +32,54 @@ cc_library( "//external:zlib", "@proxy_wasm_cpp_sdk//:api_lib", "@proxy_wasm_cpp_sdk//:common_lib", - ] + envoy_select_wasm_v8([ + ], +) + +cc_library( + name = "null_lib", + srcs = glob([ + "src/null/*.cc", + ]), + deps = [ + ":common_lib", + ], +) + +cc_library( + name = "v8_lib", + srcs = glob([ + "src/v8/*.cc", + ]), + deps = [ + ":common_lib", "//external:wee8", - ]) + envoy_select_wasm_wavm([ + ], +) + +cc_library( + name = "wavm_lib", + srcs = glob([ + "src/wavm/*.cc", + ]), + copts = [ + '-DWAVM_API=""', + "-Wno-non-virtual-dtor", + "-Wno-old-style-cast", + ], + deps = [ + ":common_lib", "@envoy//bazel/foreign_cc:wavm", - ]) + envoy_select_wasm_wasmtime([ - "@com_github_wasm_c_api//:wasmtime_lib", + ], +) + +cc_library( + name = "wasmtime_lib", + srcs = glob([ + "src/wasmtime/*.h", + "src/wasmtime/*.cc", ]), + deps = [ + ":common_lib", + "@com_github_wasm_c_api//:wasmtime_lib", + ], ) diff --git a/bazel/external/quiche.BUILD b/bazel/external/quiche.BUILD index 7541909aa191..a3c430cf9fa4 100644 --- a/bazel/external/quiche.BUILD +++ b/bazel/external/quiche.BUILD @@ -57,16 +57,12 @@ quiche_common_copts = [ "-Wno-unused-function", # quic_inlined_frame.h uses offsetof() to optimize memory usage in frames. "-Wno-invalid-offsetof", - "-Wno-range-loop-analysis", ] quiche_copts = select({ # Ignore unguarded #pragma GCC statements in QUICHE sources "@envoy//bazel:windows_x86_64": ["-wd4068"], # Remove these after upstream fix. - "@envoy//bazel:gcc_build": [ - "-Wno-sign-compare", - ] + quiche_common_copts, "//conditions:default": quiche_common_copts, }) @@ -737,7 +733,6 @@ envoy_cc_library( hdrs = [ "quiche/spdy/platform/api/spdy_bug_tracker.h", "quiche/spdy/platform/api/spdy_containers.h", - "quiche/spdy/platform/api/spdy_endianness_util.h", "quiche/spdy/platform/api/spdy_estimate_memory_usage.h", "quiche/spdy/platform/api/spdy_flags.h", "quiche/spdy/platform/api/spdy_logging.h", @@ -935,6 +930,7 @@ envoy_cc_library( copts = quiche_copts, repository = "@envoy", deps = [ + ":http2_hpack_huffman_hpack_huffman_encoder_lib", ":spdy_core_protocol_lib", ":spdy_platform", ], @@ -1049,19 +1045,16 @@ envoy_cc_library( envoy_cc_library( name = "quic_platform_base", hdrs = [ - "quiche/quic/platform/api/quic_aligned.h", "quiche/quic/platform/api/quic_bug_tracker.h", "quiche/quic/platform/api/quic_client_stats.h", "quiche/quic/platform/api/quic_containers.h", "quiche/quic/platform/api/quic_error_code_wrappers.h", "quiche/quic/platform/api/quic_estimate_memory_usage.h", "quiche/quic/platform/api/quic_exported_stats.h", - "quiche/quic/platform/api/quic_fallthrough.h", "quiche/quic/platform/api/quic_flag_utils.h", "quiche/quic/platform/api/quic_flags.h", "quiche/quic/platform/api/quic_iovec.h", "quiche/quic/platform/api/quic_logging.h", - "quiche/quic/platform/api/quic_macros.h", "quiche/quic/platform/api/quic_map_util.h", "quiche/quic/platform/api/quic_mem_slice.h", "quiche/quic/platform/api/quic_prefetch.h", @@ -1072,6 +1065,7 @@ envoy_cc_library( "quiche/quic/platform/api/quic_stream_buffer_allocator.h", "quiche/quic/platform/api/quic_string_utils.h", "quiche/quic/platform/api/quic_uint128.h", + "quiche/quic/platform/api/quic_testvalue.h", # TODO: uncomment the following files as implementations are added. # "quiche/quic/platform/api/quic_fuzzed_data_provider.h", # "quiche/quic/platform/api/quic_test_loopback.h", @@ -1147,7 +1141,6 @@ envoy_cc_test_library( hdrs = ["quiche/quic/platform/api/quic_port_utils.h"], repository = "@envoy", tags = ["nofips"], - deps = ["@envoy//test/extensions/quic_listeners/quiche/platform:quic_platform_port_utils_impl_lib"], ) envoy_cc_library( @@ -1216,15 +1209,14 @@ envoy_cc_test_library( ) envoy_cc_library( - name = "quiche_common_platform_endian", - hdrs = ["quiche/common/platform/api/quiche_endian.h"], + name = "quiche_common_endian_lib", + hdrs = ["quiche/common/quiche_endian.h"], repository = "@envoy", tags = ["nofips"], visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", - "@envoy//source/extensions/quic_listeners/quiche/platform:quiche_common_platform_endian_impl_lib", ], ) @@ -1932,6 +1924,7 @@ envoy_cc_library( visibility = ["//visibility:public"], deps = [ ":quic_core_clock_lib", + ":quic_core_crypto_certificate_view_lib", ":quic_core_crypto_encryption_lib", ":quic_core_crypto_hkdf_lib", ":quic_core_crypto_proof_source_interface_lib", @@ -2167,6 +2160,15 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "quic_core_flags_list_lib", + hdrs = ["quiche/quic/core/quic_flags_list.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + visibility = ["//visibility:public"], +) + envoy_cc_library( name = "quic_core_framer_lib", srcs = ["quiche/quic/core/quic_framer.cc"], @@ -2339,6 +2341,7 @@ envoy_cc_library( repository = "@envoy", tags = ["nofips"], deps = [ + ":http2_constants_lib", ":quic_core_data_lib", ":quic_core_error_codes_lib", ":quic_core_http_http_frames_lib", @@ -2723,6 +2726,27 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "quic_core_path_validator_lib", + srcs = ["quiche/quic/core/quic_path_validator.cc"], + hdrs = ["quiche/quic/core/quic_path_validator.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quic_core_alarm_factory_interface_lib", + ":quic_core_alarm_interface_lib", + ":quic_core_arena_scoped_ptr_lib", + ":quic_core_clock_lib", + ":quic_core_constants_lib", + ":quic_core_crypto_random_lib", + ":quic_core_one_block_arena_lib", + ":quic_core_packet_writer_interface_lib", + ":quic_core_types_lib", + ":quic_platform", + ], +) + envoy_cc_library( name = "quic_core_process_packet_interface_lib", hdrs = ["quiche/quic/core/quic_process_packet_interface.h"], @@ -2735,6 +2759,15 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "quic_core_protocol_flags_list_lib", + hdrs = ["quiche/quic/core/quic_protocol_flags_list.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + visibility = ["//visibility:public"], +) + envoy_cc_library( name = "quic_core_qpack_blocking_manager_lib", srcs = ["quiche/quic/core/qpack/qpack_blocking_manager.cc"], @@ -2896,6 +2929,7 @@ envoy_cc_library( deps = [ ":http2_decoder_decode_buffer_lib", ":http2_decoder_decode_status_lib", + ":quic_core_error_codes_lib", ":quic_core_qpack_qpack_instruction_decoder_lib", ":quic_core_qpack_qpack_instructions_lib", ":quic_core_qpack_qpack_stream_receiver_lib", @@ -3368,7 +3402,7 @@ envoy_cc_library( ":quic_core_error_codes_lib", ":quic_core_time_lib", ":quic_platform_base", - ":quiche_common_platform_endian", + ":quiche_common_endian_lib", ], ) @@ -3420,6 +3454,7 @@ envoy_cc_library( repository = "@envoy", tags = ["nofips"], deps = [ + ":quic_core_circular_deque_lib", ":quic_core_connection_stats_lib", ":quic_core_packets_lib", ":quic_core_session_notifier_interface_lib", @@ -3459,6 +3494,7 @@ envoy_cc_library( deps = [ ":quic_core_versions_lib", ":quic_platform_base", + ":quiche_common_endian_lib", ], ) @@ -3475,7 +3511,6 @@ envoy_cc_library( ":quic_core_tag_lib", ":quic_core_types_lib", ":quic_platform_base", - ":quiche_common_platform_endian", ], ) @@ -3619,6 +3654,35 @@ envoy_cc_test_library( ], ) +envoy_cc_test_library( + name = "quic_test_tools_qpack_qpack_encoder_test_utils_lib", + srcs = ["quiche/quic/test_tools/qpack/qpack_encoder_test_utils.cc"], + hdrs = ["quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quic_core_qpack_qpack_encoder_lib", + ":quic_platform_test", + ":quic_test_tools_qpack_qpack_test_utils_lib", + ":spdy_core_header_block_lib", + ":spdy_core_hpack_hpack_lib", + ], +) + +envoy_cc_test_library( + name = "quic_test_tools_qpack_qpack_test_utils_lib", + srcs = ["quiche/quic/test_tools/qpack/qpack_test_utils.cc"], + hdrs = ["quiche/quic/test_tools/qpack/qpack_test_utils.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quic_core_qpack_qpack_stream_sender_delegate_lib", + ":quic_platform_test", + ], +) + envoy_cc_test_library( name = "quic_test_tools_sent_packet_manager_peer_lib", srcs = ["quiche/quic/test_tools/quic_sent_packet_manager_peer.cc"], @@ -3746,6 +3810,7 @@ envoy_cc_test_library( ":quic_core_packet_creator_lib", ":quic_core_packet_writer_interface_lib", ":quic_core_packets_lib", + ":quic_core_path_validator_lib", ":quic_core_received_packet_manager_lib", ":quic_core_sent_packet_manager_lib", ":quic_core_server_id_lib", @@ -3836,25 +3901,10 @@ envoy_cc_test_library( deps = [":epoll_server_platform"], ) -envoy_cc_library( - name = "quiche_common_platform_optional", - hdrs = ["quiche/common/platform/api/quiche_optional.h"], - repository = "@envoy", - tags = ["nofips"], - visibility = ["//visibility:public"], - deps = [ - ":quiche_common_platform_export", - "@envoy//source/extensions/quic_listeners/quiche/platform:quiche_common_platform_optional_impl_lib", - ], -) - envoy_cc_library( name = "quiche_common_platform", hdrs = [ - "quiche/common/platform/api/quiche_arraysize.h", "quiche/common/platform/api/quiche_logging.h", - "quiche/common/platform/api/quiche_optional.h", - "quiche/common/platform/api/quiche_ptr_util.h", "quiche/common/platform/api/quiche_str_cat.h", "quiche/common/platform/api/quiche_string_piece.h", "quiche/common/platform/api/quiche_text_utils.h", @@ -3866,7 +3916,6 @@ envoy_cc_library( visibility = ["//visibility:public"], deps = [ ":quiche_common_platform_export", - ":quiche_common_platform_optional", "@envoy//source/extensions/quic_listeners/quiche/platform:quiche_common_platform_impl_lib", ], ) @@ -3874,7 +3923,6 @@ envoy_cc_library( envoy_cc_test_library( name = "quiche_common_platform_test", srcs = [ - "quiche/common/platform/api/quiche_endian_test.cc", "quiche/common/platform/api/quiche_str_cat_test.cc", "quiche/common/platform/api/quiche_text_utils_test.cc", "quiche/common/platform/api/quiche_time_utils_test.cc", @@ -3884,7 +3932,6 @@ envoy_cc_test_library( tags = ["nofips"], deps = [ ":quiche_common_platform", - ":quiche_common_platform_endian", "@envoy//test/extensions/quic_listeners/quiche/platform:quiche_common_platform_test_impl_lib", ], ) @@ -3904,8 +3951,8 @@ envoy_cc_library( tags = ["nofips"], visibility = ["//visibility:public"], deps = [ + ":quiche_common_endian_lib", ":quiche_common_platform", - ":quiche_common_platform_endian", ], ) @@ -3944,6 +3991,7 @@ envoy_cc_test( deps = [ ":http2_platform", ":http2_test_tools_random", + ":quiche_common_test_tools_test_utils_lib", ], ) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index a91db6898b9c..77a28e659613 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -60,18 +60,18 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "BoringSSL", project_desc = "Minimal OpenSSL fork", project_url = "https://github.com/google/boringssl", - version = "2192bbc878822cf6ab5977d4257a1339453d9d39", - sha256 = "bb55b0ed2f0cb548b5dce6a6b8307ce37f7f748eb9f1be6bfe2d266ff2b4d52b", + version = "1ce6682c7f6cfe0426ed54a37c10775bea9d3502", + sha256 = "b878d84f90b9a95fa1e53f46f1b69a5116621e117a6d4dbf602d884311ee6aa7", strip_prefix = "boringssl-{version}", # To update BoringSSL, which tracks Chromium releases: # 1. Open https://omahaproxy.appspot.com/ and note of linux/stable release. # 2. Open https://chromium.googlesource.com/chromium/src/+/refs/tags//DEPS and note . # 3. Find a commit in BoringSSL's "master-with-bazel" branch that merges . # - # chromium-86.0.4240.80 + # chromium-87.0.4280.66 urls = ["https://github.com/google/boringssl/archive/{version}.tar.gz"], use_category = ["controlplane", "dataplane_core"], - release_date = "2020-07-30", + release_date = "2020-09-21", cpe = "cpe:2.3:a:google:boringssl:*", ), boringssl_fips = dict( @@ -408,13 +408,13 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "jwt_verify_lib", project_desc = "JWT verification library for C++", project_url = "https://github.com/google/jwt_verify_lib", - version = "7276a339af8426724b744216f619c99152f8c141", - sha256 = "f1fde4f3ebb3b2d841332c7a02a4b50e0529a19709934c63bc6208d1bbe28fb1", + version = "28efec2e4df1072db0ed03597591360ec9f80aac", + sha256 = "7a5c35b7cbf633398503ae12cad8c2833e92b3a796eed68b6256d22d51ace5e1", strip_prefix = "jwt_verify_lib-{version}", urls = ["https://github.com/google/jwt_verify_lib/archive/{version}.tar.gz"], use_category = ["dataplane_ext"], extensions = ["envoy.filters.http.jwt_authn"], - release_date = "2020-07-10", + release_date = "2020-11-04", cpe = "N/A", ), com_github_nodejs_http_parser = dict( @@ -507,13 +507,13 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "grpc-httpjson-transcoding", project_desc = "Library that supports transcoding so that HTTP/JSON can be converted to gRPC", project_url = "https://github.com/grpc-ecosystem/grpc-httpjson-transcoding", - version = "b48d8aa15b3825e146168146755475ab918e95b7", - sha256 = "4147e992ec239fb78c435fdd9f68e8d93d89106f67278bf2995f3672dddba52b", + version = "4d095f048889d4fc3b8d4579aa80ca4290319802", + sha256 = "7af66e0674340932683ab4f04ea6f03e2550849a54741738d94310b84d396a2c", strip_prefix = "grpc-httpjson-transcoding-{version}", urls = ["https://github.com/grpc-ecosystem/grpc-httpjson-transcoding/archive/{version}.tar.gz"], use_category = ["dataplane_ext"], extensions = ["envoy.filters.http.grpc_json_transcoder"], - release_date = "2020-11-05", + release_date = "2020-11-12", cpe = "N/A", ), io_bazel_rules_go = dict( @@ -587,13 +587,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/llvm/llvm-project/releases/download/llvmorg-{version}/llvm-{version}.src.tar.xz"], release_date = "2020-03-23", use_category = ["dataplane_ext"], - extensions = [ - "envoy.access_loggers.wasm", - "envoy.bootstrap.wasm", - "envoy.filters.http.wasm", - "envoy.filters.network.wasm", - "envoy.stat_sinks.wasm", - ], + extensions = ["envoy.wasm.runtime.wavm"], cpe = "cpe:2.3:a:llvm:*:*", ), com_github_wavm_wavm = dict( @@ -606,13 +600,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/WAVM/WAVM/archive/{version}.tar.gz"], release_date = "2020-09-17", use_category = ["dataplane_ext"], - extensions = [ - "envoy.access_loggers.wasm", - "envoy.bootstrap.wasm", - "envoy.filters.http.wasm", - "envoy.filters.network.wasm", - "envoy.stat_sinks.wasm", - ], + extensions = ["envoy.wasm.runtime.wavm"], cpe = "cpe:2.3:a:webassembly_virtual_machine_project:webassembly_virtual_machine:*", ), com_github_wasmtime = dict( @@ -625,13 +613,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/bytecodealliance/wasmtime/archive/v{version}.tar.gz"], release_date = "2020-11-05", use_category = ["dataplane_ext"], - extensions = [ - "envoy.access_loggers.wasm", - "envoy.bootstrap.wasm", - "envoy.filters.http.wasm", - "envoy.filters.network.wasm", - "envoy.stat_sinks.wasm", - ], + extensions = ["envoy.wasm.runtime.wasmtime"], cpe = "N/A", ), com_github_wasm_c_api = dict( @@ -646,13 +628,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/WebAssembly/wasm-c-api/archive/{version}.tar.gz"], release_date = "2019-11-14", use_category = ["dataplane_ext"], - extensions = [ - "envoy.access_loggers.wasm", - "envoy.bootstrap.wasm", - "envoy.filters.http.wasm", - "envoy.filters.network.wasm", - "envoy.stat_sinks.wasm", - ], + extensions = ["envoy.wasm.runtime.wasmtime"], cpe = "N/A", ), io_opencensus_cpp = dict( @@ -697,13 +673,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( sha256 = "f22734640e0515bc34d1ca3772513aef24374fafa44d0489d3a9a57cadec69fb", urls = ["https://storage.googleapis.com/envoyproxy-wee8/wee8-{version}.tar.gz"], use_category = ["dataplane_ext"], - extensions = [ - "envoy.access_loggers.wasm", - "envoy.bootstrap.wasm", - "envoy.filters.http.wasm", - "envoy.filters.network.wasm", - "envoy.stat_sinks.wasm", - ], + extensions = ["envoy.wasm.runtime.v8"], release_date = "2020-10-27", cpe = "cpe:2.3:a:google:v8:*", ), @@ -711,13 +681,13 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "QUICHE", project_desc = "QUICHE (QUIC, HTTP/2, Etc) is Google‘s implementation of QUIC and related protocols", project_url = "https://quiche.googlesource.com/quiche", - # Static snapshot of https://quiche.googlesource.com/quiche/+archive/f555d99a084cdd086a349548c70fb558ac5847cf.tar.gz - version = "f555d99a084cdd086a349548c70fb558ac5847cf", - sha256 = "1833f08e7b0f18b49d7498b029b7f3e6559a82113ec82a98a9e945553756e351", + # Static snapshot of https://quiche.googlesource.com/quiche/+archive/ecc28c0d7428f3323ea26eb1ddb98a5e06b23dea.tar.gz + version = "ecc28c0d7428f3323ea26eb1ddb98a5e06b23dea", + sha256 = "52680dea984dbe899c27176155578b97276e1f1516b7c3a63fb16ba593061859", urls = ["https://storage.googleapis.com/quiche-envoy-integration/{version}.tar.gz"], use_category = ["dataplane_ext"], extensions = ["envoy.transport_sockets.quic"], - release_date = "2020-09-17", + release_date = "2020-11-10", cpe = "N/A", ), com_googlesource_googleurl = dict( @@ -862,6 +832,10 @@ REPOSITORY_LOCATIONS_SPEC = dict( "envoy.filters.http.wasm", "envoy.filters.network.wasm", "envoy.stat_sinks.wasm", + "envoy.wasm.runtime.null", + "envoy.wasm.runtime.v8", + "envoy.wasm.runtime.wavm", + "envoy.wasm.runtime.wasmtime", ], release_date = "2020-10-22", cpe = "N/A", @@ -881,6 +855,10 @@ REPOSITORY_LOCATIONS_SPEC = dict( "envoy.filters.http.wasm", "envoy.filters.network.wasm", "envoy.stat_sinks.wasm", + "envoy.wasm.runtime.null", + "envoy.wasm.runtime.v8", + "envoy.wasm.runtime.wavm", + "envoy.wasm.runtime.wasmtime", ], release_date = "2020-11-12", cpe = "N/A", @@ -905,13 +883,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( strip_prefix = "rules_rust-{version}", urls = ["https://github.com/bazelbuild/rules_rust/archive/{version}.tar.gz"], use_category = ["dataplane_ext"], - extensions = [ - "envoy.access_loggers.wasm", - "envoy.bootstrap.wasm", - "envoy.filters.http.wasm", - "envoy.filters.network.wasm", - "envoy.stat_sinks.wasm", - ], + extensions = ["envoy.wasm.runtime.wasmtime"], release_date = "2020-10-21", cpe = "N/A", ), diff --git a/ci/Dockerfile-envoy-google-vrp b/ci/Dockerfile-envoy-google-vrp index 802e148851e0..abc84f1269ab 100644 --- a/ci/Dockerfile-envoy-google-vrp +++ b/ci/Dockerfile-envoy-google-vrp @@ -16,6 +16,9 @@ ADD configs/google-vrp/supervisor.conf /etc/supervisor.conf ADD test/config/integration/certs/serverkey.pem /etc/envoy/certs/serverkey.pem ADD test/config/integration/certs/servercert.pem /etc/envoy/certs/servercert.pem # ADD %local envoy bin% /usr/local/bin/envoy +RUN chmod 777 /var/log/supervisor +RUN chmod a+r /etc/supervisor.conf /etc/envoy/* /etc/envoy/certs/* +RUN chmod a+rx /usr/local/bin/launch_envoy.sh EXPOSE 10000 EXPOSE 10001 diff --git a/ci/run_clang_tidy.sh b/ci/run_clang_tidy.sh index fe5d5fdd2047..b29a624c3f45 100755 --- a/ci/run_clang_tidy.sh +++ b/ci/run_clang_tidy.sh @@ -113,9 +113,7 @@ elif [[ "${RUN_FULL_CLANG_TIDY}" == 1 ]]; then run_clang_tidy else if [[ -z "${DIFF_REF}" ]]; then - if [[ "${BUILD_REASON}" == "PullRequest" ]]; then - DIFF_REF="remotes/origin/${SYSTEM_PULLREQUEST_TARGETBRANCH}" - elif [[ "${BUILD_REASON}" == *CI ]]; then + if [[ "${BUILD_REASON}" == *CI ]]; then DIFF_REF="HEAD^" else DIFF_REF=$("${ENVOY_SRCDIR}"/tools/git/last_github_commit.sh) diff --git a/ci/run_envoy_docker.sh b/ci/run_envoy_docker.sh index e0f204e67fcf..da5115db5274 100755 --- a/ci/run_envoy_docker.sh +++ b/ci/run_envoy_docker.sh @@ -83,7 +83,6 @@ docker run --rm \ -e ENVOY_BUILD_IMAGE \ -e ENVOY_SRCDIR \ -e ENVOY_BUILD_TARGET \ - -e SYSTEM_PULLREQUEST_TARGETBRANCH \ -e SYSTEM_PULLREQUEST_PULLREQUESTNUMBER \ -e GCS_ARTIFACT_BUCKET \ -e GITHUB_TOKEN \ diff --git a/ci/windows_ci_steps.sh b/ci/windows_ci_steps.sh index ff77a9ea1465..91e5cf39cfa3 100755 --- a/ci/windows_ci_steps.sh +++ b/ci/windows_ci_steps.sh @@ -42,7 +42,7 @@ export TEST_TMPDIR=${BUILD_DIR}/tmp [[ "${BUILD_REASON}" != "PullRequest" ]] && BAZEL_EXTRA_TEST_OPTIONS+=(--nocache_test_results) -BAZEL_STARTUP_OPTIONS+=("--output_base=c:/_eb") +BAZEL_STARTUP_OPTIONS+=("--output_base=${TEST_TMPDIR/\/c/c:}") BAZEL_BUILD_OPTIONS=( -c opt --show_task_finish diff --git a/configs/google-vrp/supervisor.conf b/configs/google-vrp/supervisor.conf index e019581d079c..1e1d09f33660 100644 --- a/configs/google-vrp/supervisor.conf +++ b/configs/google-vrp/supervisor.conf @@ -1,5 +1,6 @@ [supervisord] nodaemon=true +logfile=/var/log/supervisor/supervisord.log [program:envoy-edge] command=launch_envoy.sh -c /etc/envoy/envoy-edge.yaml %(ENV_ENVOY_EDGE_EXTRA_ARGS)s diff --git a/docs/root/configuration/http/http_filters/oauth2_filter.rst b/docs/root/configuration/http/http_filters/oauth2_filter.rst index 6b8b9789a5c7..ebd2f9cdff5f 100644 --- a/docs/root/configuration/http/http_filters/oauth2_filter.rst +++ b/docs/root/configuration/http/http_filters/oauth2_filter.rst @@ -71,6 +71,11 @@ The following is an example configuring the filter. name: hmac sds_config: path: "/etc/envoy/hmac.yaml" + # (Optional): defaults to 'user' scope if not provided + auth_scopes: + - user + - openid + - email Below is a complete code example of how we employ the filter as one of :ref:`HttpConnectionManager HTTP filters @@ -114,6 +119,11 @@ Below is a complete code example of how we employ the filter as one of name: hmac sds_config: path: "/etc/envoy/hmac.yaml" + # (Optional): defaults to 'user' scope if not provided + auth_scopes: + - user + - openid + - email - name: envoy.router tracing: {} codec_type: "AUTO" diff --git a/docs/root/configuration/observability/access_log/usage.rst b/docs/root/configuration/observability/access_log/usage.rst index 75c0630285fa..73ca330f7333 100644 --- a/docs/root/configuration/observability/access_log/usage.rst +++ b/docs/root/configuration/observability/access_log/usage.rst @@ -187,6 +187,10 @@ The following command operators are supported: HTTP response code. Note that a response code of '0' means that the server never sent the beginning of a response. This generally means that the (downstream) client disconnected. + Note that in the case of 100-continue responses, only the response code of the final headers + will be logged. If a 100-continue is followed by a 200, the logged response will be 200. + If a 100-continue results in a disconnect, the 100 will be logged. + TCP Not implemented ("-"). diff --git a/docs/root/configuration/security/secret.rst b/docs/root/configuration/security/secret.rst index fdbc88242d02..5ad3650cc19e 100644 --- a/docs/root/configuration/security/secret.rst +++ b/docs/root/configuration/security/secret.rst @@ -45,11 +45,15 @@ refer to filesystem paths. This currently is supported for the following secret * :ref:`TlsCertificate ` * :ref:`CertificateValidationContext ` -By default, directories containing secrets are watched for filesystem move events. Explicit control over -the watched directory is possible by specifying a *watched_directory* path in :ref:`TlsCertificate +By default, directories containing secrets are watched for filesystem move events. For example, a +key or trusted CA certificates at ``/foo/bar/baz/cert.pem`` will be watched at `/foo/bar/baz`. +Explicit control over the watched directory is possible by specifying a *watched_directory* path in +:ref:`TlsCertificate ` and :ref:`CertificateValidationContext `. +This allows watches to be established at path predecessors, e.g. ``/foo/bar``; this capability is +useful when implementing common key rotation schemes. An example of key rotation is provided :ref:`below `. diff --git a/docs/root/extending/extending.rst b/docs/root/extending/extending.rst index cd36ddb2188d..7f2e676e20eb 100644 --- a/docs/root/extending/extending.rst +++ b/docs/root/extending/extending.rst @@ -24,6 +24,8 @@ types including: * :ref:`Watchdog action ` * :ref:`Internal redirect policy ` * :ref:`Compression libraries ` +* :ref:`Bootstrap extensions ` +* :ref:`Fatal actions ` As of this writing there is no high level extension developer documentation. The :repo:`existing extensions ` are a good way to learn what is possible. diff --git a/docs/root/operations/cli.rst b/docs/root/operations/cli.rst index d4f6f2808213..4f7129a1b4df 100644 --- a/docs/root/operations/cli.rst +++ b/docs/root/operations/cli.rst @@ -332,7 +332,7 @@ following are the command line options that Envoy supports. extensions cannot be used by static or dynamic configuration, though they are still linked into Envoy and may run start-up code or have other runtime effects. Extension names are created by joining the extension category and name with a forward slash, - e.g. ``grpc_credentials/envoy.grpc_credentials.file_based_metadata``. + e.g. ``envoy.grpc_credentials/envoy.grpc_credentials.file_based_metadata``. .. option:: --version diff --git a/docs/root/start/sandboxes/dynamic-configuration-filesystem.rst b/docs/root/start/sandboxes/dynamic-configuration-filesystem.rst index 9364e98f40aa..ade85340a492 100644 --- a/docs/root/start/sandboxes/dynamic-configuration-filesystem.rst +++ b/docs/root/start/sandboxes/dynamic-configuration-filesystem.rst @@ -115,7 +115,7 @@ the ``example_proxy_cluster`` should now be configured to proxy to ``service2``: .. code-block:: console - $ curl -s http://localhost:19000/config_dump jq -r '.configs[1].dynamic_active_clusters' + $ curl -s http://localhost:19000/config_dump | jq -r '.configs[1].dynamic_active_clusters' .. literalinclude:: _include/dynamic-config-fs/response-config-active-clusters-updated.json :language: json diff --git a/docs/root/start/sandboxes/load_reporting_service.rst b/docs/root/start/sandboxes/load_reporting_service.rst index 59d1bdfd19f8..a3e2bb7977de 100644 --- a/docs/root/start/sandboxes/load_reporting_service.rst +++ b/docs/root/start/sandboxes/load_reporting_service.rst @@ -28,7 +28,7 @@ Change to the ``examples/load-reporting-service`` directory. Terminal 1 :: $ pwd - envoy/examples/load_reporting_service + envoy/examples/load-reporting-service $ docker-compose pull $ docker-compose up --scale http_service=2 diff --git a/docs/root/start/sandboxes/mysql.rst b/docs/root/start/sandboxes/mysql.rst index ca588f94faa0..065198a7a876 100644 --- a/docs/root/start/sandboxes/mysql.rst +++ b/docs/root/start/sandboxes/mysql.rst @@ -49,7 +49,7 @@ Terminal 1 .. code-block:: console - $ docker run --rm -it --network envoymesh mysql:5.5 mysql -h envoy -P 1999 -u root + $ docker run --rm -it --network envoymesh mysql:5.5 mysql -h proxy -P 1999 -u root ... snip ... mysql> CREATE DATABASE test; diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index f72b7f9842d0..eb0befa192ec 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -17,7 +17,11 @@ Minor Behavior Changes * ext_authz filter: disable `envoy.reloadable_features.ext_authz_measure_timeout_on_check_created` by default. * ext_authz filter: the deprecated field :ref:`use_alpha ` is no longer supported and cannot be set anymore. * grpc_web filter: if a `grpc-accept-encoding` header is present it's passed as-is to the upstream and if it isn't `grpc-accept-encoding:identity` is sent instead. The header was always overwriten with `grpc-accept-encoding:identity,deflate,gzip` before. +* jwt_authn filter: added support of Jwt time constraint verification with a clock skew (default to 60 seconds) and added a filter config field :ref:`clock_skew_seconds ` to configure it. * memory: enable new tcmalloc with restartable sequences for aarch64 builds. +* oauth filter: added the optional parameter :ref:`auth_scopes ` with default value of 'user' if not provided. Enables for this value to be overridden in the Authorization request to the OAuth provider. +* mongo proxy metrics: swapped network connection remote and local closed counters previously set reversed (`cx_destroy_local_with_active_rq` and `cx_destroy_remote_with_active_rq`). +* oauth filter: added the optional parameter :ref:`auth_scopes ` with default value of 'user' if not provided. Enables this value to be overridden in the Authorization request to the OAuth provider. * tls: removed RSA key transport and SHA-1 cipher suites from the client-side defaults. * watchdog: the watchdog action :ref:`abort_action ` is now the default action to terminate the process if watchdog kill / multikill is enabled. * xds: to support TTLs, heartbeating has been added to xDS. As a result, responses that contain empty resources without updating the version will no longer be propagated to the @@ -34,14 +38,17 @@ Bug Fixes * http: reject requests with missing required headers after filter chain processing. * http: sending CONNECT_ERROR for HTTP/2 where appropriate during CONNECT requests. * proxy_proto: fixed a bug where the wrong downstream address got sent to upstream connections. +* proxy_proto: fixed a bug where network filters would not have the correct downstreamRemoteAddress() when accessed from the StreamInfo. This could result in incorrect enforcement of RBAC rules in the RBAC network filter (but not in the RBAC HTTP filter), or incorrect access log addresses from tcp_proxy. * tls: fix detection of the upstream connection close event. * tls: fix read resumption after triggering buffer high-watermark and all remaining request/response bytes are stored in the SSL connection's internal buffers. +* udp: fixed issue in which receiving truncated UDP datagrams would cause Envoy to crash. * watchdog: touch the watchdog before most event loop operations to avoid misses when handling bursts of callbacks. Removed Config or Runtime ------------------------- *Normally occurs at the end of the* :ref:`deprecation period ` +* dispatcher: removed legacy socket read/write resumption code path and runtime guard `envoy.reloadable_features.activate_fds_next_event_loop`. * ext_authz: removed auto ignore case in HTTP-based `ext_authz` header matching and the runtime guard `envoy.reloadable_features.ext_authz_http_service_enable_case_sensitive_string_matcher`. To ignore case, set the :ref:`ignore_case ` field to true. * http: flip default HTTP/1 and HTTP/2 server codec implementations to new codecs that remove the use of exceptions for control flow. To revert to old codec behavior, set the runtime feature `envoy.reloadable_features.new_codec_behavior` to false. * http: removed `envoy.reloadable_features.http1_flood_protection` and legacy code path for turning flood protection off. @@ -50,6 +57,7 @@ New Features ------------ * config: added new runtime feature `envoy.features.enable_all_deprecated_features` that allows the use of all deprecated features. * grpc: implemented header value syntax support when defining :ref:`initial metadata ` for gRPC-based `ext_authz` :ref:`HTTP ` and :ref:`network ` filters, and :ref:`ratelimit ` filters. +* grpc-json: added support for configuring :ref:`unescaping behavior ` for path components. * hds: added support for delta updates in the :ref:`HealthCheckSpecifier `, making only the Endpoints and Health Checkers that changed be reconstructed on receiving a new message, rather than the entire HDS. * health_check: added option to use :ref:`no_traffic_healthy_interval ` which allows a different no traffic interval when the host is healthy. * http: added HCM :ref:`timeout config field ` to control how long a downstream has to finish sending headers before the stream is cancelled. @@ -66,6 +74,7 @@ New Features * sds: improved support for atomic :ref:`key rotations ` and added configurable rotation triggers for :ref:`TlsCertificate ` and :ref:`CertificateValidationContext `. +* signal: added an extension point for custom actions to run on the thread that has encountered a fatal error. Actions are configurable via :ref:`fatal_actions `. * tcp: added a new :ref:`envoy.overload_actions.reject_incoming_connections ` action to reject incoming TCP connections. * tls: added support for RSA certificates with 4096-bit keys in FIPS mode. * tracing: added SkyWalking tracer. diff --git a/examples/skywalking-tracing/docker-compose.yaml b/examples/skywalking-tracing/docker-compose.yaml index 5ac0e647a7fe..359f7be74dca 100644 --- a/examples/skywalking-tracing/docker-compose.yaml +++ b/examples/skywalking-tracing/docker-compose.yaml @@ -56,7 +56,7 @@ services: soft: -1 hard: -1 skywalking-oap: - image: apache/skywalking-oap-server:8.1.0-es7 + image: apache/skywalking-oap-server:8.2.0-es7 networks: - envoymesh depends_on: @@ -72,7 +72,7 @@ services: start_period: 40s restart: on-failure skywalking-ui: - image: apache/skywalking-ui:8.1.0 + image: apache/skywalking-ui:8.2.0 networks: - envoymesh depends_on: diff --git a/examples/vrp-litmus/Dockerfile-vrp b/examples/vrp-litmus/Dockerfile-vrp new file mode 100644 index 000000000000..f0e6704d6d21 --- /dev/null +++ b/examples/vrp-litmus/Dockerfile-vrp @@ -0,0 +1 @@ +FROM envoyproxy/envoy-google-vrp-dev:latest diff --git a/examples/vrp-litmus/README.md b/examples/vrp-litmus/README.md new file mode 100644 index 000000000000..58c14b3fd8cb --- /dev/null +++ b/examples/vrp-litmus/README.md @@ -0,0 +1,3 @@ +Simple litmus test to verify the VRP image in CI. For more details on VRP, +please see +https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/google_vrp. diff --git a/examples/vrp-litmus/docker-compose.yaml b/examples/vrp-litmus/docker-compose.yaml new file mode 100644 index 000000000000..46eefcafb9aa --- /dev/null +++ b/examples/vrp-litmus/docker-compose.yaml @@ -0,0 +1,17 @@ +version: "3.7" +services: + + vrp: + build: + context: . + dockerfile: Dockerfile-vrp + environment: + ENVOY_EDGE_EXTRA_ARGS: "" + ENVOY_ORIGIN_EXTRA_ARGS: "" + networks: + - envoymesh + ports: + - "10000:10000" + +networks: + envoymesh: {} diff --git a/examples/vrp-litmus/verify.sh b/examples/vrp-litmus/verify.sh new file mode 100755 index 000000000000..02791785c628 --- /dev/null +++ b/examples/vrp-litmus/verify.sh @@ -0,0 +1,14 @@ +#!/bin/bash -e + +export NAME=vrp-litmus +export DELAY=10 + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test proxy" +responds_with \ + normal \ + https://localhost:10000/content \ + -k diff --git a/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto b/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto index cce2dceb72d8..52b9a88365d0 100644 --- a/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto +++ b/generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto @@ -40,7 +40,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 28] +// [#next-free-field: 29] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Bootstrap"; @@ -241,6 +241,10 @@ message Bootstrap { // Each item contains extension specific configuration. repeated core.v3.TypedExtensionConfig bootstrap_extensions = 21; + // Specifies optional extensions instantiated at startup time and + // invoked during crash time on the request that caused the crash. + repeated FatalAction fatal_actions = 28; + // Configuration sources that will participate in // *udpa.core.v1.ResourceLocator* authority resolution. The algorithm is as // follows: @@ -421,6 +425,20 @@ message Watchdog { type.v3.Percent multikill_threshold = 5; } +// Fatal actions to run while crashing. Actions can be safe (meaning they are +// async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. +// If using an unsafe action that could get stuck or deadlock, it important to +// have an out of band system to terminate the process. +// +// The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. +// *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API +// namespace. +message FatalAction { + // Extension specific configuration for the action. It's expected to conform + // to the ``Envoy::Server::Configuration::FatalAction`` interface. + core.v3.TypedExtensionConfig config = 1; +} + // Runtime :ref:`configuration overview ` (deprecated). message Runtime { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Runtime"; diff --git a/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto b/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto index 57f37e5ff6ee..074936c7226e 100644 --- a/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto +++ b/generated_api_shadow/envoy/config/bootstrap/v4alpha/bootstrap.proto @@ -39,7 +39,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 28] +// [#next-free-field: 29] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v3.Bootstrap"; @@ -242,6 +242,10 @@ message Bootstrap { // Each item contains extension specific configuration. repeated core.v4alpha.TypedExtensionConfig bootstrap_extensions = 21; + // Specifies optional extensions instantiated at startup time and + // invoked during crash time on the request that caused the crash. + repeated FatalAction fatal_actions = 28; + // Configuration sources that will participate in // *udpa.core.v1.ResourceLocator* authority resolution. The algorithm is as // follows: @@ -425,6 +429,23 @@ message Watchdog { type.v3.Percent multikill_threshold = 5; } +// Fatal actions to run while crashing. Actions can be safe (meaning they are +// async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. +// If using an unsafe action that could get stuck or deadlock, it important to +// have an out of band system to terminate the process. +// +// The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. +// *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API +// namespace. +message FatalAction { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.bootstrap.v3.FatalAction"; + + // Extension specific configuration for the action. It's expected to conform + // to the ``Envoy::Server::Configuration::FatalAction`` interface. + core.v4alpha.TypedExtensionConfig config = 1; +} + // Runtime :ref:`configuration overview ` (deprecated). message Runtime { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v3.Runtime"; diff --git a/generated_api_shadow/envoy/config/common/matcher/v3/matcher.proto b/generated_api_shadow/envoy/config/common/matcher/v3/matcher.proto index 8a1cb4839c4a..24ed5dafbdc5 100644 --- a/generated_api_shadow/envoy/config/common/matcher/v3/matcher.proto +++ b/generated_api_shadow/envoy/config/common/matcher/v3/matcher.proto @@ -4,7 +4,7 @@ package envoy.config.common.matcher.v3; import "envoy/config/core/v3/extension.proto"; import "envoy/config/route/v3/route_components.proto"; -import "envoy/type/matcher/v3/value.proto"; +import "envoy/type/matcher/v3/string.proto"; import "udpa/annotations/migrate.proto"; import "udpa/annotations/status.proto"; @@ -58,9 +58,8 @@ message Matcher { oneof matcher { option (validate.required) = true; - // Use existing infrastructure for actually matching the - // value. - type.matcher.v3.ValueMatcher value_match = 2; + // Built-in string matcher. + type.matcher.v3.StringMatcher value_match = 2; // Extension for custom matching logic. core.v3.TypedExtensionConfig custom_match = 3; diff --git a/generated_api_shadow/envoy/config/common/matcher/v4alpha/matcher.proto b/generated_api_shadow/envoy/config/common/matcher/v4alpha/matcher.proto index 15859474e6e1..ab1f4de6cccc 100644 --- a/generated_api_shadow/envoy/config/common/matcher/v4alpha/matcher.proto +++ b/generated_api_shadow/envoy/config/common/matcher/v4alpha/matcher.proto @@ -4,7 +4,7 @@ package envoy.config.common.matcher.v4alpha; import "envoy/config/core/v4alpha/extension.proto"; import "envoy/config/route/v4alpha/route_components.proto"; -import "envoy/type/matcher/v4alpha/value.proto"; +import "envoy/type/matcher/v4alpha/string.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -72,9 +72,8 @@ message Matcher { oneof matcher { option (validate.required) = true; - // Use existing infrastructure for actually matching the - // value. - type.matcher.v4alpha.ValueMatcher value_match = 2; + // Built-in string matcher. + type.matcher.v4alpha.StringMatcher value_match = 2; // Extension for custom matching logic. core.v4alpha.TypedExtensionConfig custom_match = 3; diff --git a/generated_api_shadow/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto b/generated_api_shadow/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto index 3082089202ee..007ccabc3e47 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/grpc_json_transcoder/v3/transcoder.proto @@ -15,11 +15,27 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // gRPC-JSON transcoder :ref:`configuration overview `. // [#extension: envoy.filters.http.grpc_json_transcoder] -// [#next-free-field: 10] +// [#next-free-field: 11] message GrpcJsonTranscoder { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder"; + enum UrlUnescapeSpec { + // URL path parameters will not decode RFC 6570 reserved characters. + // For example, segment `%2f%23/%20%2523` is unescaped to `%2f%23/ %23`. + ALL_CHARACTERS_EXCEPT_RESERVED = 0; + + // URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // For example, segment `%2f%23/%20%2523` is unescaped to `%2f#/ %23`. + ALL_CHARACTERS_EXCEPT_SLASH = 1; + + // URL path parameters will be fully URI-decoded. + // For example, segment `%2f%23/%20%2523` is unescaped to `/#/ %23`. + ALL_CHARACTERS = 2; + } + message PrintOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder.PrintOptions"; @@ -160,4 +176,11 @@ message GrpcJsonTranscoder { // the ``google/rpc/error_details.proto`` should be included in the configured // :ref:`proto descriptor set `. bool convert_grpc_status = 9; + + // URL unescaping policy. + // This spec is only applied when extracting variable with multiple segments. + // For example, in case of `/foo/{x=*}/bar/{y=prefix/*}/{z=**}` `x` variable is single segment and `y` and `z` are multiple segments. + // For a path with `/foo/first/bar/prefix/second/third/fourth`, `x=first`, `y=prefix/second`, `z=third/fourth`. + // If this setting is not specified, the value defaults to :ref:`ALL_CHARACTERS_EXCEPT_RESERVED`. + UrlUnescapeSpec url_unescape_spec = 10 [(validate.rules).enum = {defined_only: true}]; } diff --git a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto index 0e4294608384..a10fa68f3043 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -51,7 +51,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // cache_duration: // seconds: 300 // -// [#next-free-field: 10] +// [#next-free-field: 11] message JwtProvider { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.jwt_authn.v2alpha.JwtProvider"; @@ -191,6 +191,10 @@ message JwtProvider { // exp: 1501281058 // string payload_in_metadata = 9; + + // Specify the clock skew in seconds when verifying JWT time constraint, + // such as `exp`, and `nbf`. If not specified, default is 60 seconds. + uint32 clock_skew_seconds = 10; } // This message specifies how to fetch JWKS from remote and how to cache it. diff --git a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto index 53ee84fd65ea..2746640fa738 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto @@ -51,7 +51,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // cache_duration: // seconds: 300 // -// [#next-free-field: 10] +// [#next-free-field: 11] message JwtProvider { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.http.jwt_authn.v3.JwtProvider"; @@ -191,6 +191,10 @@ message JwtProvider { // exp: 1501281058 // string payload_in_metadata = 9; + + // Specify the clock skew in seconds when verifying JWT time constraint, + // such as `exp`, and `nbf`. If not specified, default is 60 seconds. + uint32 clock_skew_seconds = 10; } // This message specifies how to fetch JWKS from remote and how to cache it. diff --git a/generated_api_shadow/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto b/generated_api_shadow/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto index e4be64167ed2..11fe12695865 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/oauth2/v3alpha/oauth.proto @@ -44,7 +44,7 @@ message OAuth2Credentials { // OAuth config // -// [#next-free-field: 9] +// [#next-free-field: 10] message OAuth2Config { // Endpoint on the authorization server to retrieve the access token from. config.core.v3.HttpUri token_endpoint = 1; @@ -74,6 +74,11 @@ message OAuth2Config { // Any request that matches any of the provided matchers will be passed through without OAuth validation. repeated config.route.v3.HeaderMatcher pass_through_matcher = 8; + + // Optional list of OAuth scopes to be claimed in the authorization request. If not specified, + // defaults to "user" scope. + // OAuth RFC https://tools.ietf.org/html/rfc6749#section-3.3 + repeated string auth_scopes = 9; } // Filter config. diff --git a/generated_api_shadow/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto b/generated_api_shadow/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto index ee51e1f96099..af1f0944ed34 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/oauth2/v4alpha/oauth.proto @@ -47,7 +47,7 @@ message OAuth2Credentials { // OAuth config // -// [#next-free-field: 9] +// [#next-free-field: 10] message OAuth2Config { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.http.oauth2.v3alpha.OAuth2Config"; @@ -80,6 +80,11 @@ message OAuth2Config { // Any request that matches any of the provided matchers will be passed through without OAuth validation. repeated config.route.v4alpha.HeaderMatcher pass_through_matcher = 8; + + // Optional list of OAuth scopes to be claimed in the authorization request. If not specified, + // defaults to "user" scope. + // OAuth RFC https://tools.ietf.org/html/rfc6749#section-3.3 + repeated string auth_scopes = 9; } // Filter config. diff --git a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/common.proto b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/common.proto index c5452fced643..2ddca5720fc8 100644 --- a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/common.proto +++ b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/common.proto @@ -154,7 +154,8 @@ message TlsCertificate { // default the parent directories of the filesystem paths in // *certificate_chain* and *private_key* are watched if this field is not // specified. This only applies when a *TlsCertificate* is delivered by SDS - // with references to filesystem paths. + // with references to filesystem paths. See the :ref:`SDS key rotation + // ` documentation for further details. config.core.v3.WatchedDirectory watched_directory = 7; // BoringSSL private key method provider. This is an alternative to :ref:`private_key @@ -262,7 +263,8 @@ message CertificateValidationContext { // default the parent directory of the filesystem path in *trusted_ca* is // watched if this field is not specified. This only applies when a // *CertificateValidationContext* is delivered by SDS with references to - // filesystem paths. + // filesystem paths. See the :ref:`SDS key rotation ` + // documentation for further details. config.core.v3.WatchedDirectory watched_directory = 11; // An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the diff --git a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v4alpha/common.proto b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v4alpha/common.proto index b2fa6f672628..30859bc2a3eb 100644 --- a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v4alpha/common.proto +++ b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v4alpha/common.proto @@ -157,7 +157,8 @@ message TlsCertificate { // default the parent directories of the filesystem paths in // *certificate_chain* and *private_key* are watched if this field is not // specified. This only applies when a *TlsCertificate* is delivered by SDS - // with references to filesystem paths. + // with references to filesystem paths. See the :ref:`SDS key rotation + // ` documentation for further details. config.core.v4alpha.WatchedDirectory watched_directory = 7; // BoringSSL private key method provider. This is an alternative to :ref:`private_key @@ -267,7 +268,8 @@ message CertificateValidationContext { // default the parent directory of the filesystem path in *trusted_ca* is // watched if this field is not specified. This only applies when a // *CertificateValidationContext* is delivered by SDS with references to - // filesystem paths. + // filesystem paths. See the :ref:`SDS key rotation ` + // documentation for further details. config.core.v4alpha.WatchedDirectory watched_directory = 11; // An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the diff --git a/generated_api_shadow/envoy/extensions/wasm/v3/wasm.proto b/generated_api_shadow/envoy/extensions/wasm/v3/wasm.proto index b42fb75a0bf7..c6affb810611 100644 --- a/generated_api_shadow/envoy/extensions/wasm/v3/wasm.proto +++ b/generated_api_shadow/envoy/extensions/wasm/v3/wasm.proto @@ -28,7 +28,29 @@ message VmConfig { // See ref: "TODO: add ref" for details. string vm_id = 1; - // The Wasm runtime type (either "v8" or "null" for code compiled into Envoy). + // The Wasm runtime type. + // Available Wasm runtime types are registered as extensions. The following runtimes are included + // in Envoy code base: + // + // .. _extension_envoy.wasm.runtime.null: + // + // **envoy.wasm.runtime.null**: Null sandbox, the Wasm module must be compiled and linked into the + // Envoy binary. The registered name is given in the *code* field as *inline_string*. + // + // .. _extension_envoy.wasm.runtime.v8: + // + // **envoy.wasm.runtime.v8**: `V8 `_-based WebAssembly runtime. + // + // .. _extension_envoy.wasm.runtime.wavm: + // + // **envoy.wasm.runtime.wavm**: `WAVM `_-based WebAssembly runtime. + // This runtime is not enabled in the official build. + // + // .. _extension_envoy.wasm.runtime.wasmtime: + // + // **envoy.wasm.runtime.wasmtime**: `Wasmtime `_-based WebAssembly runtime. + // This runtime is not enabled in the official build. + // string runtime = 2 [(validate.rules).string = {min_len: 1}]; // The Wasm code that Envoy will execute. diff --git a/include/envoy/api/io_error.h b/include/envoy/api/io_error.h index 247e102a49d5..d671dea790e1 100644 --- a/include/envoy/api/io_error.h +++ b/include/envoy/api/io_error.h @@ -71,6 +71,12 @@ template struct IoCallResult { */ bool ok() const { return err_ == nullptr; } + /** + * This return code is frequent enough that we have a separate function to check. + * @return true if the system call failed because the socket would block. + */ + bool wouldBlock() const { return !ok() && err_->getErrorCode() == IoError::IoErrorCode::Again; } + // TODO(danzh): rename it to be more meaningful, i.e. return_value_. ReturnValue rc_; IoErrorPtr err_; diff --git a/include/envoy/buffer/buffer.h b/include/envoy/buffer/buffer.h index 3ab150504ccd..42b414c665f6 100644 --- a/include/envoy/buffer/buffer.h +++ b/include/envoy/buffer/buffer.h @@ -160,6 +160,14 @@ class Instance { virtual RawSliceVector getRawSlices(absl::optional max_slices = absl::nullopt) const PURE; + /** + * Fetch the valid data pointer and valid data length of the first non-zero-length + * slice in the buffer. + * @return RawSlice the first non-empty slice in the buffer, or {nullptr, 0} if the buffer + * is empty. + */ + virtual RawSlice frontSlice() const PURE; + /** * Transfer ownership of the front slice to the caller. Must only be called if the * buffer is not empty otherwise the implementation will have undefined behavior. diff --git a/include/envoy/event/file_event.h b/include/envoy/event/file_event.h index e66289cdb4f0..cfcb298b3080 100644 --- a/include/envoy/event/file_event.h +++ b/include/envoy/event/file_event.h @@ -18,15 +18,38 @@ struct FileReadyType { static const uint32_t Closed = 0x4; }; -enum class FileTriggerType { Level, Edge }; +enum class FileTriggerType { + // See @man 7 epoll(7) + // They are used on all platforms for DNS and TCP listeners. + Level, + // See @man 7 epoll(7) + // They are used on all platforms that support Edge triggering as the default trigger type. + Edge, + // These are synthetic edge events managed by Envoy. They are based on level events and when they + // are activated they are immediately disabled. This makes them behave like Edge events. Then it + // is is the responsibility of the consumer of the event to reactivate the event + // when the socket operation would block. + // + // Their main application in Envoy is for Win32 which does not support edge-triggered events. They + // should be used in Win32 instead of level events. They can only be used in platforms where + // `PlatformDefaultTriggerType` is `FileTriggerType::EmulatedEdge`. + EmulatedEdge +}; -static constexpr FileTriggerType PlatformDefaultTriggerType -#ifdef WIN32 - // Libevent only supports Level trigger on Windows. - {FileTriggerType::Level}; +// For POSIX developers to get the Windows behavior of file events +// you need to add the following definition: +// `FORCE_LEVEL_EVENTS` +// You can do this with bazel if you add the following build/test options +// `--copt="-DFORCE_LEVEL_EVENTS"` +constexpr FileTriggerType determinePlatformPreferredEventType() { +#if defined(WIN32) || defined(FORCE_LEVEL_EVENTS) + return FileTriggerType::EmulatedEdge; #else - {FileTriggerType::Edge}; + return FileTriggerType::Edge; #endif +} + +static constexpr FileTriggerType PlatformDefaultTriggerType = determinePlatformPreferredEventType(); /** * Callback invoked when a FileEvent is ready for reading or writing. @@ -53,6 +76,16 @@ class FileEvent { * registered events and fire callbacks when they are active. */ virtual void setEnabled(uint32_t events) PURE; + + /** + * Add a single event from the event registration mark. + */ + virtual void registerEventIfEmulatedEdge(uint32_t event) PURE; + + /** + * Remove a single event from the event registration mark. + */ + virtual void unregisterEventIfEmulatedEdge(uint32_t event) PURE; }; using FileEventPtr = std::unique_ptr; diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 03c1b654f1bf..de530474592a 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -86,11 +86,12 @@ class IoHandle { virtual Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) PURE; /** - * Write the buffer out to a file descriptor. - * @param buffer supplies the buffer to write to. - * @return a IoCallUint64Result with err_ = nullptr and rc_ = the number of bytes - * written if successful, or err_ = some IoError for failure. If call failed, rc_ shouldn't be - * used. + * Write the contents of the buffer out to a file descriptor. Bytes that were successfully written + * are drained from the buffer. + * @param buffer supplies the buffer to write from. + * @return a IoCallUint64Result with err_ = nullptr and rc_ = if successful, the number of bytes + * written and drained from the buffer, or err_ = some IoError for failure. If call failed, rc_ + * shouldn't be used. */ virtual Api::IoCallUint64Result write(Buffer::Instance& buffer) PURE; @@ -117,6 +118,9 @@ class IoHandle { unsigned int msg_len_{0}; // The gso_size, if specified in the transport header unsigned int gso_size_{0}; + // If true indicates a successful syscall, but the packet was dropped due to truncation. We do + // not support receiving truncated packets. + bool truncated_and_dropped_{false}; }; /** diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 4401df6cc20c..d708d02ce7e0 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -378,9 +378,6 @@ class UdpListener : public virtual Listener { /** * Make this listener readable at the beginning of the next event loop. - * - * @note: it may become readable during the current loop if feature - * ``envoy.reloadable_features.activate_fds_next_event_loop`` is disabled. */ virtual void activateRead() PURE; }; diff --git a/include/envoy/server/BUILD b/include/envoy/server/BUILD index a9f7854ba1c2..0fbd876f0a94 100644 --- a/include/envoy/server/BUILD +++ b/include/envoy/server/BUILD @@ -329,3 +329,15 @@ envoy_cc_library( "//include/envoy/config:typed_config_interface", ], ) + +envoy_cc_library( + name = "fatal_action_interface", + hdrs = ["fatal_action_config.h"], + deps = [ + "//include/envoy/config:typed_config_interface", + "//include/envoy/event:dispatcher_interface", + "//include/envoy/protobuf:message_validator_interface", + "//include/envoy/server:instance_interface", + "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", + ], +) diff --git a/include/envoy/server/fatal_action_config.h b/include/envoy/server/fatal_action_config.h new file mode 100644 index 000000000000..c8768dced40a --- /dev/null +++ b/include/envoy/server/fatal_action_config.h @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include "envoy/common/pure.h" +#include "envoy/config/bootstrap/v3/bootstrap.pb.h" +#include "envoy/config/typed_config.h" +#include "envoy/event/dispatcher.h" +#include "envoy/protobuf/message_validator.h" +#include "envoy/server/instance.h" + +namespace Envoy { +namespace Server { +namespace Configuration { + +class FatalAction { +public: + virtual ~FatalAction() = default; + /** + * Callback function to run when we are crashing. + * @param current_object the object we were working on when we started + * crashing. + */ + virtual void run(const ScopeTrackedObject* current_object) PURE; + + /** + * @return whether the action is async-signal-safe. + * See man 7 signal-safety for the definition of async-signal-safe. + */ + virtual bool isAsyncSignalSafe() const PURE; +}; + +using FatalActionPtr = std::unique_ptr; + +/** + * Implemented by each custom FatalAction and registered via Registry::registerFactory() + * or the convenience class RegisterFactory. + */ +class FatalActionFactory : public Config::TypedFactory { +public: + ~FatalActionFactory() override = default; + + /** + * Creates a particular FatalAction implementation. + * + * @param config supplies the configuration for the action. + * @param context supplies the GuardDog Action's context. + * @return FatalActionsPtr the FatalActions object. + */ + virtual FatalActionPtr + createFatalActionFromProto(const envoy::config::bootstrap::v3::FatalAction& config, + Instance* server) PURE; + + std::string category() const override { return "envoy.fatal_action"; } +}; + +} // namespace Configuration +} // namespace Server +} // namespace Envoy diff --git a/include/envoy/upstream/cluster_manager.h b/include/envoy/upstream/cluster_manager.h index beb88299da28..aff096838adc 100644 --- a/include/envoy/upstream/cluster_manager.h +++ b/include/envoy/upstream/cluster_manager.h @@ -73,6 +73,47 @@ using ClusterUpdateCallbacksHandlePtr = std::unique_ptr void checkAndDecrement(T& value, uint32_t delta) { + ASSERT(delta <= value); + value -= delta; + } + + template void checkAndIncrement(T& value, uint32_t delta) { + ASSERT(std::numeric_limits::max() - value > delta); + value += delta; + } + + void incrPendingStreams(uint32_t delta) { checkAndIncrement(pending_streams_, delta); } + void decrPendingStreams(uint32_t delta) { checkAndDecrement(pending_streams_, delta); } + void incrConnectingStreamCapacity(uint32_t delta) { + checkAndIncrement(connecting_stream_capacity_, delta); + } + void decrConnectingStreamCapacity(uint32_t delta) { + checkAndDecrement(connecting_stream_capacity_, delta); + } + void incrActiveStreams(uint32_t delta) { checkAndIncrement(active_streams_, delta); } + void decrActiveStreams(uint32_t delta) { checkAndDecrement(active_streams_, delta); } + + // Tracks the number of pending streams for this ClusterManager. + uint32_t pending_streams_{}; + // Tracks the number of active streams for this ClusterManager. + uint32_t active_streams_{}; + // Tracks the available stream capacity if all connecting connections were connected. + // + // For example, if an H2 connection is started with concurrent stream limit of 100, this + // goes up by 100. If the connection is established and 2 streams are in use, it + // would be reduced to 98 (as 2 of the 100 are not available). + uint64_t connecting_stream_capacity_{}; +}; + /** * Manages connection pools and load balancing for upstream clusters. The cluster manager is * persistent and shared among multiple ongoing requests/connections. @@ -321,7 +362,8 @@ class ClusterManagerFactory { allocateConnPool(Event::Dispatcher& dispatcher, HostConstSharedPtr host, ResourcePriority priority, Http::Protocol protocol, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) PURE; + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + ClusterConnectivityState& state) PURE; /** * Allocate a TCP connection pool for the host. Pools are separated by 'priority' and @@ -331,7 +373,8 @@ class ClusterManagerFactory { allocateTcpConnPool(Event::Dispatcher& dispatcher, HostConstSharedPtr host, ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - Network::TransportSocketOptionsSharedPtr transport_socket_options) PURE; + Network::TransportSocketOptionsSharedPtr transport_socket_options, + ClusterConnectivityState& state) PURE; /** * Allocate a cluster from configuration proto. diff --git a/source/common/api/win32/os_sys_calls_impl.cc b/source/common/api/win32/os_sys_calls_impl.cc index 5169f6855b50..f0f9768dc0c1 100644 --- a/source/common/api/win32/os_sys_calls_impl.cc +++ b/source/common/api/win32/os_sys_calls_impl.cc @@ -144,14 +144,22 @@ SysCallSizeResult OsSysCallsImpl::recv(os_fd_t socket, void* buffer, size_t leng } SysCallSizeResult OsSysCallsImpl::recvmsg(os_fd_t sockfd, msghdr* msg, int flags) { - DWORD bytes_received; + DWORD bytes_received = 0; LPFN_WSARECVMSG recvmsg_fn_ptr = getFnPtrWSARecvMsg(); wsamsgResult wsamsg = msghdrToWSAMSG(msg); // Windows supports only a single flag on input to WSARecvMsg wsamsg.wsamsg_->dwFlags = flags & MSG_PEEK; const int rc = recvmsg_fn_ptr(sockfd, wsamsg.wsamsg_.get(), &bytes_received, nullptr, nullptr); if (rc == SOCKET_ERROR) { - return {-1, ::WSAGetLastError()}; + // We try to match the UNIX behavior for truncated packages. In that case the return code is + // the length of the allocated buffer and we get the value from `dwFlags`. + auto last_error = ::WSAGetLastError(); + if (last_error == WSAEMSGSIZE) { + msg->msg_flags = wsamsg.wsamsg_->dwFlags; + return {bytes_received, 0}; + } + + return {rc, last_error}; } msg->msg_namelen = wsamsg.wsamsg_->namelen; msg->msg_flags = wsamsg.wsamsg_->dwFlags; diff --git a/source/common/buffer/buffer_impl.cc b/source/common/buffer/buffer_impl.cc index 556faf73d638..f43507ac9530 100644 --- a/source/common/buffer/buffer_impl.cc +++ b/source/common/buffer/buffer_impl.cc @@ -201,6 +201,17 @@ RawSliceVector OwnedImpl::getRawSlices(absl::optional max_slices) cons return raw_slices; } +RawSlice OwnedImpl::frontSlice() const { + // Ignore zero-size slices and return the first slice with data. + for (const auto& slice : slices_) { + if (slice->dataSize() > 0) { + return RawSlice{slice->data(), slice->dataSize()}; + } + } + + return {nullptr, 0}; +} + SliceDataPtr OwnedImpl::extractMutableFrontSlice() { RELEASE_ASSERT(length_ > 0, "Extract called on empty buffer"); // Remove zero byte fragments from the front of the queue to ensure diff --git a/source/common/buffer/buffer_impl.h b/source/common/buffer/buffer_impl.h index cfbaadd82323..180106886732 100644 --- a/source/common/buffer/buffer_impl.h +++ b/source/common/buffer/buffer_impl.h @@ -564,6 +564,7 @@ class OwnedImpl : public LibEventInstance { void copyOut(size_t start, uint64_t size, void* data) const override; void drain(uint64_t size) override; RawSliceVector getRawSlices(absl::optional max_slices = absl::nullopt) const override; + RawSlice frontSlice() const override; SliceDataPtr extractMutableFrontSlice() override; uint64_t length() const override; void* linearize(uint32_t size) override; diff --git a/source/common/buffer/zero_copy_input_stream_impl.cc b/source/common/buffer/zero_copy_input_stream_impl.cc index 6b805eaf01a0..bfd0e4794c0a 100644 --- a/source/common/buffer/zero_copy_input_stream_impl.cc +++ b/source/common/buffer/zero_copy_input_stream_impl.cc @@ -29,10 +29,9 @@ void ZeroCopyInputStreamImpl::drainLastSlice() { bool ZeroCopyInputStreamImpl::Next(const void** data, int* size) { drainLastSlice(); - Buffer::RawSliceVector slices = buffer_->getRawSlices(1); + Buffer::RawSlice slice = buffer_->frontSlice(); - if (!slices.empty() && slices[0].len_ > 0) { - auto& slice = slices[0]; + if (slice.len_ > 0) { *data = slice.mem_; *size = slice.len_; position_ = slice.len_; diff --git a/source/common/common/regex.h b/source/common/common/regex.h index 68cb7ff8074d..2fdcd52ebc1c 100644 --- a/source/common/common/regex.h +++ b/source/common/common/regex.h @@ -9,6 +9,8 @@ namespace Envoy { namespace Regex { +enum class Type { Re2, StdRegex }; + /** * Utilities for constructing regular expressions. */ diff --git a/source/common/config/BUILD b/source/common/config/BUILD index 7c5460df96bb..baf4f851e998 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -461,6 +461,7 @@ envoy_cc_library( hdrs = ["well_known_names.h"], deps = [ "//source/common/common:assert_lib", + "//source/common/common:regex_lib", "//source/common/singleton:const_singleton", ], ) diff --git a/source/common/config/version_converter.cc b/source/common/config/version_converter.cc index db2bd1cfc216..0477c29bcf86 100644 --- a/source/common/config/version_converter.cc +++ b/source/common/config/version_converter.cc @@ -78,20 +78,28 @@ void VersionConverter::annotateWithOriginalType(const Protobuf::Descriptor& prev void onMessage(Protobuf::Message& message, const void* ctxt) override { const Protobuf::Descriptor* descriptor = message.GetDescriptor(); const Protobuf::Reflection* reflection = message.GetReflection(); - const Protobuf::Descriptor& prev_descriptor = *static_cast(ctxt); + const Protobuf::Descriptor* prev_descriptor = static_cast(ctxt); + // If there is no previous descriptor for this message, we don't need to annotate anything. + if (prev_descriptor == nullptr) { + return; + } // If they are the same type, there's no possibility of any different type // further down, so we're done. - if (descriptor->full_name() == prev_descriptor.full_name()) { + if (descriptor->full_name() == prev_descriptor->full_name()) { return; } auto* unknown_field_set = reflection->MutableUnknownFields(&message); unknown_field_set->AddLengthDelimited(ProtobufWellKnown::OriginalTypeFieldNumber, - prev_descriptor.full_name()); + prev_descriptor->full_name()); } const void* onField(Protobuf::Message&, const Protobuf::FieldDescriptor& field, const void* ctxt) override { - const Protobuf::Descriptor& prev_descriptor = *static_cast(ctxt); + const Protobuf::Descriptor* prev_descriptor = static_cast(ctxt); + // If there is no previous descriptor for this field, we don't need to annotate anything. + if (prev_descriptor == nullptr) { + return nullptr; + } // TODO(htuch): This is a terrible hack, there should be no per-resource // business logic in this file. The reason this is required is that // endpoints, when captured in configuration such as inlined hosts in @@ -101,13 +109,13 @@ void VersionConverter::annotateWithOriginalType(const Protobuf::Descriptor& prev // In theory, we should be able to just clean up these annotations in // ClusterManagerImpl with type erasure, but protobuf doesn't free up memory // as expected, we probably need some arena level trick to address this. - if (prev_descriptor.full_name() == "envoy.api.v2.Cluster" && + if (prev_descriptor->full_name() == "envoy.api.v2.Cluster" && (field.name() == "hidden_envoy_deprecated_hosts" || field.name() == "load_assignment")) { // This will cause the sub-message visit to abort early. return field.message_type(); } const Protobuf::FieldDescriptor* prev_field = - prev_descriptor.FindFieldByNumber(field.number()); + prev_descriptor->FindFieldByNumber(field.number()); return prev_field != nullptr ? prev_field->message_type() : nullptr; } }; diff --git a/source/common/config/well_known_names.cc b/source/common/config/well_known_names.cc index e2677cb742a4..e8fc767c41a3 100644 --- a/source/common/config/well_known_names.cc +++ b/source/common/config/well_known_names.cc @@ -92,7 +92,7 @@ TagNameValues::TagNameValues() { addRegex(RATELIMIT_PREFIX, R"(^ratelimit\.((.*?)\.)\w+?$)"); // cluster.(.)* - addRegex(CLUSTER_NAME, "^cluster\\.((.*?)\\.)"); + addRe2(CLUSTER_NAME, "^cluster\\.(([^\\.]+)\\.).*"); // listener.[
.]http.(.)* addRegex(HTTP_CONN_MANAGER_PREFIX, R"(^listener(?=\.).*?\.http\.((.*?)\.))", ".http."); @@ -119,7 +119,12 @@ TagNameValues::TagNameValues() { void TagNameValues::addRegex(const std::string& name, const std::string& regex, const std::string& substr) { - descriptor_vec_.emplace_back(Descriptor(name, regex, substr)); + descriptor_vec_.emplace_back(Descriptor{name, regex, substr, Regex::Type::StdRegex}); +} + +void TagNameValues::addRe2(const std::string& name, const std::string& regex, + const std::string& substr) { + descriptor_vec_.emplace_back(Descriptor{name, regex, substr, Regex::Type::Re2}); } } // namespace Config diff --git a/source/common/config/well_known_names.h b/source/common/config/well_known_names.h index 1d3cd09c51d8..97ce58fd7265 100644 --- a/source/common/config/well_known_names.h +++ b/source/common/config/well_known_names.h @@ -6,6 +6,7 @@ #include "envoy/common/exception.h" #include "common/common/assert.h" +#include "common/common/regex.h" #include "common/singleton/const_singleton.h" namespace Envoy { @@ -62,11 +63,10 @@ class TagNameValues { * tags, such as "_rq_(\\d)xx$", will probably stay as regexes. */ struct Descriptor { - Descriptor(const std::string& name, const std::string& regex, const std::string& substr = "") - : name_(name), regex_(regex), substr_(substr) {} const std::string name_; const std::string regex_; const std::string substr_; + const Regex::Type re_type_; }; // Cluster name tag @@ -130,6 +130,7 @@ class TagNameValues { private: void addRegex(const std::string& name, const std::string& regex, const std::string& substr = ""); + void addRe2(const std::string& name, const std::string& regex, const std::string& substr = ""); // Collection of tag descriptors. std::vector descriptor_vec_; diff --git a/source/common/conn_pool/conn_pool_base.cc b/source/common/conn_pool/conn_pool_base.cc index bc5293e99318..daec20bc40fc 100644 --- a/source/common/conn_pool/conn_pool_base.cc +++ b/source/common/conn_pool/conn_pool_base.cc @@ -12,9 +12,10 @@ namespace ConnectionPool { ConnPoolImplBase::ConnPoolImplBase( Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, Event::Dispatcher& dispatcher, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) - : host_(host), priority_(priority), dispatcher_(dispatcher), socket_options_(options), - transport_socket_options_(transport_socket_options) {} + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Upstream::ClusterConnectivityState& state) + : state_(state), host_(host), priority_(priority), dispatcher_(dispatcher), + socket_options_(options), transport_socket_options_(transport_socket_options) {} ConnPoolImplBase::~ConnPoolImplBase() { ASSERT(ready_clients_.empty()); @@ -107,6 +108,8 @@ bool ConnPoolImplBase::tryCreateNewConnection(float global_prefetch_ratio) { ASSERT(std::numeric_limits::max() - connecting_stream_capacity_ >= client->effectiveConcurrentStreamLimit()); ASSERT(client->real_host_description_); + // Increase the connecting capacity to reflect the streams this connection can serve. + state_.incrConnectingStreamCapacity(client->effectiveConcurrentStreamLimit()); connecting_stream_capacity_ += client->effectiveConcurrentStreamLimit(); LinkedList::moveIntoList(std::move(client), owningList(client->state_)); } @@ -135,6 +138,10 @@ void ConnPoolImplBase::attachStreamToClient(Envoy::ConnectionPool::ActiveClient& transitionActiveClientState(client, Envoy::ConnectionPool::ActiveClient::State::BUSY); } + // Decrement the capacity, as there's one less stream available for serving. + state_.decrConnectingStreamCapacity(1); + // Track the new active stream. + state_.incrActiveStreams(1); num_active_streams_++; host_->stats().rq_total_.inc(); host_->stats().rq_active_.inc(); @@ -150,10 +157,18 @@ void ConnPoolImplBase::onStreamClosed(Envoy::ConnectionPool::ActiveClient& clien bool delay_attaching_stream) { ENVOY_CONN_LOG(debug, "destroying stream: {} remaining", client, client.numActiveStreams()); ASSERT(num_active_streams_ > 0); + // Reflect there's one less stream in flight. + state_.decrActiveStreams(1); num_active_streams_--; host_->stats().rq_active_.dec(); host_->cluster().stats().upstream_rq_active_.dec(); host_->cluster().resourceManager(priority_).requests().dec(); + // If the effective client capacity was limited by concurrency, increase connecting capacity. + // If the effective client capacity was limited by max total streams, this will not result in an + // increment as no capacity is freed up. + if (client.remaining_streams_ > client.concurrent_stream_limit_ - client.numActiveStreams() - 1) { + state_.incrConnectingStreamCapacity(1); + } if (client.state_ == ActiveClient::State::DRAINING && client.numActiveStreams() == 0) { // Close out the draining client if we no longer have active streams. client.close(); @@ -205,6 +220,7 @@ void ConnPoolImplBase::onUpstreamReady() { ENVOY_CONN_LOG(debug, "attaching to next stream", *client); // Pending streams are pushed onto the front, so pull from the back. attachStreamToClient(*client, pending_streams_.back()->context()); + state_.decrPendingStreams(1); pending_streams_.pop_back(); } } @@ -310,6 +326,9 @@ void ConnPoolImplBase::onConnectionEvent(ActiveClient& client, absl::string_view if (event == Network::ConnectionEvent::RemoteClose || event == Network::ConnectionEvent::LocalClose) { + state_.decrConnectingStreamCapacity(client.currentUnusedCapacity()); + // Make sure that onStreamClosed won't double count. + client.remaining_streams_ = 0; // The client died. ENVOY_CONN_LOG(debug, "client disconnected, failure reason: {}", client, failure_reason); @@ -397,6 +416,7 @@ void ConnPoolImplBase::purgePendingStreams( absl::string_view failure_reason, ConnectionPool::PoolFailureReason reason) { // NOTE: We move the existing pending streams to a temporary list. This is done so that // if retry logic submits a new stream to the pool, we don't fail it inline. + state_.decrPendingStreams(pending_streams_.size()); pending_streams_to_purge_ = std::move(pending_streams_); while (!pending_streams_to_purge_.empty()) { PendingStreamPtr stream = @@ -431,6 +451,7 @@ void ConnPoolImplBase::onPendingStreamCancel(PendingStream& stream, // and there is no need to call its onPoolFailure callback. stream.removeFromList(pending_streams_to_purge_); } else { + state_.decrPendingStreams(1); stream.removeFromList(pending_streams_); } if (policy == Envoy::ConnectionPool::CancelPolicy::CloseExcess && !connecting_clients_.empty() && @@ -447,13 +468,13 @@ void ConnPoolImplBase::onPendingStreamCancel(PendingStream& stream, namespace { // Translate zero to UINT64_MAX so that the zero/unlimited case doesn't // have to be handled specially. -uint64_t translateZeroToUnlimited(uint64_t limit) { - return (limit != 0) ? limit : std::numeric_limits::max(); +uint32_t translateZeroToUnlimited(uint32_t limit) { + return (limit != 0) ? limit : std::numeric_limits::max(); } } // namespace -ActiveClient::ActiveClient(ConnPoolImplBase& parent, uint64_t lifetime_stream_limit, - uint64_t concurrent_stream_limit) +ActiveClient::ActiveClient(ConnPoolImplBase& parent, uint32_t lifetime_stream_limit, + uint32_t concurrent_stream_limit) : parent_(parent), remaining_streams_(translateZeroToUnlimited(lifetime_stream_limit)), concurrent_stream_limit_(translateZeroToUnlimited(concurrent_stream_limit)), connect_timer_(parent_.dispatcher().createTimer([this]() -> void { onConnectTimeout(); })) { diff --git a/source/common/conn_pool/conn_pool_base.h b/source/common/conn_pool/conn_pool_base.h index 83265bd23ced..3cc2c2d08953 100644 --- a/source/common/conn_pool/conn_pool_base.h +++ b/source/common/conn_pool/conn_pool_base.h @@ -4,6 +4,7 @@ #include "envoy/event/dispatcher.h" #include "envoy/network/connection.h" #include "envoy/stats/timespan.h" +#include "envoy/upstream/cluster_manager.h" #include "common/common/linked_object.h" @@ -28,8 +29,8 @@ class ActiveClient : public LinkedObject, public Event::DeferredDeletable, protected Logger::Loggable { public: - ActiveClient(ConnPoolImplBase& parent, uint64_t lifetime_stream_limit, - uint64_t concurrent_stream_limit); + ActiveClient(ConnPoolImplBase& parent, uint32_t lifetime_stream_limit, + uint32_t concurrent_stream_limit); ~ActiveClient() override; void releaseResources(); @@ -44,10 +45,14 @@ class ActiveClient : public LinkedObject, // Returns the concurrent stream limit, accounting for if the total stream limit // is less than the concurrent stream limit. - uint64_t effectiveConcurrentStreamLimit() const { + uint32_t effectiveConcurrentStreamLimit() const { return std::min(remaining_streams_, concurrent_stream_limit_); } + uint32_t currentUnusedCapacity() const { + return std::min(remaining_streams_, concurrent_stream_limit_ - numActiveStreams()); + } + // Closes the underlying connection. virtual void close() PURE; // Returns the ID of the underlying connection. @@ -55,7 +60,7 @@ class ActiveClient : public LinkedObject, // Returns true if this closed with an incomplete stream, for stats tracking/ purposes. virtual bool closingWithIncompleteStream() const PURE; // Returns the number of active streams on this connection. - virtual size_t numActiveStreams() const PURE; + virtual uint32_t numActiveStreams() const PURE; enum class State { CONNECTING, // Connection is not yet established. @@ -67,8 +72,8 @@ class ActiveClient : public LinkedObject, }; ConnPoolImplBase& parent_; - uint64_t remaining_streams_; - const uint64_t concurrent_stream_limit_; + uint32_t remaining_streams_; + const uint32_t concurrent_stream_limit_; State state_{State::CONNECTING}; Upstream::HostDescriptionConstSharedPtr real_host_description_; Stats::TimespanPtr conn_connect_ms_; @@ -105,7 +110,8 @@ class ConnPoolImplBase : protected Logger::Loggable { ConnPoolImplBase(Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, Event::Dispatcher& dispatcher, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options); + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Upstream::ClusterConnectivityState& state); virtual ~ConnPoolImplBase(); // A helper function to get the specific context type from the base class context. @@ -196,6 +202,22 @@ class ConnPoolImplBase : protected Logger::Loggable { float perUpstreamPrefetchRatio() const; + ConnectionPool::Cancellable* + addPendingStream(Envoy::ConnectionPool::PendingStreamPtr&& pending_stream) { + LinkedList::moveIntoList(std::move(pending_stream), pending_streams_); + state_.incrPendingStreams(1); + return pending_streams_.front().get(); + } + + bool hasActiveStreams() const { return num_active_streams_ > 0; } + + void decrConnectingStreamCapacity(int32_t delta) { + state_.decrConnectingStreamCapacity(delta); + connecting_stream_capacity_ -= delta; + } + + Upstream::ClusterConnectivityState& state_; + const Upstream::HostConstSharedPtr host_; const Upstream::ResourcePriority priority_; @@ -204,7 +226,6 @@ class ConnPoolImplBase : protected Logger::Loggable { const Network::TransportSocketOptionsSharedPtr transport_socket_options_; std::list drained_callbacks_; - std::list pending_streams_; // When calling purgePendingStreams, this list will be used to hold the streams we are about // to purge. We need this if one cancelled streams cancels a different pending stream @@ -220,12 +241,15 @@ class ConnPoolImplBase : protected Logger::Loggable { // Clients that are not ready to handle additional streams because they are CONNECTING. std::list connecting_clients_; +private: + std::list pending_streams_; + // The number of streams currently attached to clients. - uint64_t num_active_streams_{0}; + uint32_t num_active_streams_{0}; // The number of streams that can be immediately dispatched // if all CONNECTING connections become connected. - uint64_t connecting_stream_capacity_{0}; + uint32_t connecting_stream_capacity_{0}; }; } // namespace ConnectionPool diff --git a/source/common/event/BUILD b/source/common/event/BUILD index 5e538bc52cf6..99c30f683fc6 100644 --- a/source/common/event/BUILD +++ b/source/common/event/BUILD @@ -33,7 +33,6 @@ envoy_cc_library( "//source/common/network:dns_lib", "//source/common/network:connection_lib", "//source/common/network:listener_lib", - "//source/common/runtime:runtime_features_lib", ] + select({ "//bazel:apple": ["//source/common/network:apple_dns_lib"], "//conditions:default": [], diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index d615e5986f5d..382ea30f1d66 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -278,6 +278,19 @@ void DispatcherImpl::runPostCallbacks() { } } +void DispatcherImpl::runFatalActionsOnTrackedObject( + const FatalAction::FatalActionPtrList& actions) const { + // Only run if this is the dispatcher of the current thread and + // DispatcherImpl::Run has been called. + if (run_tid_.isEmpty() || (run_tid_ != api_.threadFactory().currentThreadId())) { + return; + } + + for (const auto& action : actions) { + action->run(current_object_); + } +} + void DispatcherImpl::touchWatchdog() { if (watchdog_registration_) { watchdog_registration_->touchWatchdog(); diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 62c10920d7fe..46de3a8b50f7 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -94,6 +94,9 @@ class DispatcherImpl : Logger::Loggable, } } + void + runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const override; + private: // Holds a reference to the watchdog registered with this dispatcher and the timer used to ensure // that the dog is touched periodically. diff --git a/source/common/event/file_event_impl.cc b/source/common/event/file_event_impl.cc index 028bd18cfdf0..ac99c7ad47e7 100644 --- a/source/common/event/file_event_impl.cc +++ b/source/common/event/file_event_impl.cc @@ -4,7 +4,6 @@ #include "common/common/assert.h" #include "common/event/dispatcher_impl.h" -#include "common/runtime/runtime_features.h" #include "event2/event.h" @@ -13,32 +12,24 @@ namespace Event { FileEventImpl::FileEventImpl(DispatcherImpl& dispatcher, os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) - : cb_(cb), fd_(fd), trigger_(trigger), - activate_fd_events_next_event_loop_( - // Only read the runtime feature if the runtime loader singleton has already been created. - // Attempts to access runtime features too early in the initialization sequence triggers - // some spurious, scary-looking logs about not being able to read runtime feature config - // from the singleton. These warnings are caused by creation of filesystem watchers as - // part of the process of loading the runtime configuration from disk. - Runtime::LoaderSingleton::getExisting() - ? Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.activate_fds_next_event_loop") - : true) { + : cb_(cb), fd_(fd), trigger_(trigger), enabled_events_(events), + activation_cb_(dispatcher.createSchedulableCallback([this]() { + ASSERT(injected_activation_events_ != 0); + mergeInjectedEventsAndRunCb(0); + })) { // Treat the lack of a valid fd (which in practice should only happen if we run out of FDs) as // an OOM condition and just crash. RELEASE_ASSERT(SOCKET_VALID(fd), ""); #ifdef WIN32 - RELEASE_ASSERT(trigger_ == FileTriggerType::Level, - "libevent does not support edge triggers on Windows"); + ASSERT(trigger_ != FileTriggerType::Edge, "libevent does not support edge triggers on Windows"); #endif + if constexpr (PlatformDefaultTriggerType != FileTriggerType::EmulatedEdge) { + ASSERT(trigger_ != FileTriggerType::EmulatedEdge, + "Cannot use EmulatedEdge events if they are not the default platform type"); + } + assignEvents(events, &dispatcher.base()); event_add(&raw_event_, nullptr); - if (activate_fd_events_next_event_loop_) { - activation_cb_ = dispatcher.createSchedulableCallback([this]() { - ASSERT(injected_activation_events_ != 0); - mergeInjectedEventsAndRunCb(0); - }); - } } void FileEventImpl::activate(uint32_t events) { @@ -47,26 +38,6 @@ void FileEventImpl::activate(uint32_t events) { // Only supported event types are set. ASSERT((events & (FileReadyType::Read | FileReadyType::Write | FileReadyType::Closed)) == events); - if (!activate_fd_events_next_event_loop_) { - // Legacy implementation - int libevent_events = 0; - if (events & FileReadyType::Read) { - libevent_events |= EV_READ; - } - - if (events & FileReadyType::Write) { - libevent_events |= EV_WRITE; - } - - if (events & FileReadyType::Closed) { - libevent_events |= EV_CLOSED; - } - - ASSERT(libevent_events); - event_active(&raw_event_, libevent_events, 0); - return; - } - // Schedule the activation callback so it runs as part of the next loop iteration if it is not // already scheduled. if (injected_activation_events_ == 0) { @@ -81,9 +52,10 @@ void FileEventImpl::activate(uint32_t events) { void FileEventImpl::assignEvents(uint32_t events, event_base* base) { ASSERT(base != nullptr); + enabled_events_ = events; event_assign( &raw_event_, base, fd_, - EV_PERSIST | (trigger_ == FileTriggerType::Level ? 0 : EV_ET) | + EV_PERSIST | (trigger_ == FileTriggerType::Edge ? EV_ET : 0) | (events & FileReadyType::Read ? EV_READ : 0) | (events & FileReadyType::Write ? EV_WRITE : 0) | (events & FileReadyType::Closed ? EV_CLOSED : 0), @@ -108,8 +80,18 @@ void FileEventImpl::assignEvents(uint32_t events, event_base* base) { this); } +void FileEventImpl::updateEvents(uint32_t events) { + if (events == enabled_events_) { + return; + } + auto* base = event_get_base(&raw_event_); + event_del(&raw_event_); + assignEvents(events, base); + event_add(&raw_event_, nullptr); +} + void FileEventImpl::setEnabled(uint32_t events) { - if (activate_fd_events_next_event_loop_ && injected_activation_events_ != 0) { + if (injected_activation_events_ != 0) { // Clear pending events on updates to the fd event mask to avoid delivering events that are no // longer relevant. Updating the event mask will reset the fd edge trigger state so the proxy // will be able to determine the fd read/write state without need for the injected activation @@ -117,19 +99,62 @@ void FileEventImpl::setEnabled(uint32_t events) { injected_activation_events_ = 0; activation_cb_->cancel(); } + updateEvents(events); +} - auto* base = event_get_base(&raw_event_); - event_del(&raw_event_); - assignEvents(events, base); - event_add(&raw_event_, nullptr); +void FileEventImpl::unregisterEventIfEmulatedEdge(uint32_t event) { + // This constexpr if allows the compiler to optimize away the function on POSIX + if constexpr (PlatformDefaultTriggerType == FileTriggerType::EmulatedEdge) { + ASSERT((event & (FileReadyType::Read | FileReadyType::Write)) == event); + if (trigger_ == FileTriggerType::EmulatedEdge) { + auto new_event_mask = enabled_events_ & ~event; + updateEvents(new_event_mask); + } + } +} + +void FileEventImpl::registerEventIfEmulatedEdge(uint32_t event) { + // This constexpr if allows the compiler to optimize away the function on POSIX + if constexpr (PlatformDefaultTriggerType == FileTriggerType::EmulatedEdge) { + ASSERT((event & (FileReadyType::Read | FileReadyType::Write)) == event); + if (trigger_ == FileTriggerType::EmulatedEdge) { + auto new_event_mask = enabled_events_ | event; + if (event & FileReadyType::Read && (enabled_events_ & FileReadyType::Closed)) { + // We never ask for both early close and read at the same time. + new_event_mask = new_event_mask & ~FileReadyType::Read; + } + updateEvents(new_event_mask); + } + } } void FileEventImpl::mergeInjectedEventsAndRunCb(uint32_t events) { - if (activate_fd_events_next_event_loop_ && injected_activation_events_ != 0) { + if (injected_activation_events_ != 0) { + // TODO(antoniovicente) remove this adjustment to activation events once ConnectionImpl can + // handle Read and Close events delivered together. + if constexpr (PlatformDefaultTriggerType == FileTriggerType::EmulatedEdge) { + if (events & FileReadyType::Closed && injected_activation_events_ & FileReadyType::Read) { + // We never ask for both early close and read at the same time. If close is requested + // keep that instead. + injected_activation_events_ = injected_activation_events_ & ~FileReadyType::Read; + } + } + events |= injected_activation_events_; injected_activation_events_ = 0; activation_cb_->cancel(); } + + // TODO(davinci26): This can be optimized further in (w)epoll backends using the `EPOLLONESHOT` + // flag. With this flag `EPOLLIN`/`EPOLLOUT` are automatically disabled when the event is + // activated. + if constexpr (PlatformDefaultTriggerType == FileTriggerType::EmulatedEdge) { + if (trigger_ == FileTriggerType::EmulatedEdge) { + unregisterEventIfEmulatedEdge(events & + (Event::FileReadyType::Write | Event::FileReadyType::Read)); + } + } + cb_(events); } diff --git a/source/common/event/file_event_impl.h b/source/common/event/file_event_impl.h index cc3e505d788b..dabfadd1b691 100644 --- a/source/common/event/file_event_impl.h +++ b/source/common/event/file_event_impl.h @@ -22,24 +22,25 @@ class FileEventImpl : public FileEvent, ImplBase { // Event::FileEvent void activate(uint32_t events) override; void setEnabled(uint32_t events) override; + void unregisterEventIfEmulatedEdge(uint32_t event) override; + void registerEventIfEmulatedEdge(uint32_t event) override; private: void assignEvents(uint32_t events, event_base* base); void mergeInjectedEventsAndRunCb(uint32_t events); + void updateEvents(uint32_t events); FileReadyCb cb_; os_fd_t fd_; FileTriggerType trigger_; + // Enabled events for this fd. + uint32_t enabled_events_; // Injected FileReadyType events that were scheduled by recent calls to activate() and are pending // delivery. uint32_t injected_activation_events_{}; // Used to schedule delayed event activation. Armed iff pending_activation_events_ != 0. SchedulableCallbackPtr activation_cb_; - // Latched "envoy.reloadable_features.activate_fds_next_event_loop" runtime feature. If true, fd - // events scheduled via activate are evaluated in the next iteration of the event loop after - // polling and activating new fd events. - const bool activate_fd_events_next_event_loop_; }; } // namespace Event } // namespace Envoy diff --git a/source/common/event/libevent_scheduler.h b/source/common/event/libevent_scheduler.h index ab076cbabd88..d9aeecd387ad 100644 --- a/source/common/event/libevent_scheduler.h +++ b/source/common/event/libevent_scheduler.h @@ -43,8 +43,6 @@ namespace Event { // The same mechanism implements both of these operations, so they are invoked as a group. // - Event::SchedulableCallback::scheduleCallbackCurrentIteration(). Each of these callbacks is // scheduled and invoked independently. -// - Event::FileEvent::activate() if "envoy.reloadable_features.activate_fds_next_event_loop" -// runtime feature is disabled. // - Event::Timer::enableTimer(0) if "envoy.reloadable_features.activate_timers_next_event_loop" // runtime feature is disabled. // @@ -110,10 +108,9 @@ class LibeventScheduler : public Scheduler, public CallbackScheduler { static constexpr int flagsBasedOnEventType() { if constexpr (Event::PlatformDefaultTriggerType == FileTriggerType::Level) { - // On Windows, EVLOOP_NONBLOCK will cause the libevent event_base_loop to run forever. - // This is because libevent only supports level triggering on Windows, and so the write - // event callbacks will trigger every time through the loop. Adding EVLOOP_ONCE ensures the - // loop will run at most once + // With level events, EVLOOP_NONBLOCK will cause the libevent event_base_loop to run + // forever. This is because the write event callbacks will trigger every time through the + // loop. Adding EVLOOP_ONCE ensures the loop will run at most once return EVLOOP_NONBLOCK | EVLOOP_ONCE; } return EVLOOP_NONBLOCK; diff --git a/source/common/http/codec_client.cc b/source/common/http/codec_client.cc index 0da14ae6992a..3c5c16aed654 100644 --- a/source/common/http/codec_client.cc +++ b/source/common/http/codec_client.cc @@ -105,8 +105,11 @@ void CodecClient::onEvent(Network::ConnectionEvent event) { } } -void CodecClient::responseDecodeComplete(ActiveRequest& request) { +void CodecClient::responsePreDecodeComplete(ActiveRequest& request) { ENVOY_CONN_LOG(debug, "response complete", *connection_); + if (codec_client_callbacks_) { + codec_client_callbacks_->onStreamPreDecodeComplete(); + } deleteRequest(request); // HTTP/2 can send us a reset after a complete response if the request was not complete. Users @@ -138,6 +141,10 @@ void CodecClient::onData(Buffer::Instance& data) { host_->cluster().stats().upstream_cx_protocol_error_.inc(); } } + + // All data should be consumed at this point if the connection remains open. + ASSERT(data.length() == 0 || connection_->state() != Network::Connection::State::Open, + absl::StrCat("extraneous bytes after response complete: ", data.length())); } CodecClientProd::CodecClientProd(Type type, Network::ClientConnectionPtr&& connection, diff --git a/source/common/http/codec_client.h b/source/common/http/codec_client.h index 5d74eb114ec8..ca6232bd9d9c 100644 --- a/source/common/http/codec_client.h +++ b/source/common/http/codec_client.h @@ -28,6 +28,9 @@ class CodecClientCallbacks { public: virtual ~CodecClientCallbacks() = default; + // Called in onPreDecodeComplete + virtual void onStreamPreDecodeComplete() {} + /** * Called every time an owned stream is destroyed, whether complete or not. */ @@ -201,7 +204,7 @@ class CodecClient : Logger::Loggable, void onBelowWriteBufferLowWatermark() override {} // StreamDecoderWrapper - void onPreDecodeComplete() override { parent_.responseDecodeComplete(*this); } + void onPreDecodeComplete() override { parent_.responsePreDecodeComplete(*this); } void onDecodeComplete() override {} RequestEncoder* encoder_{}; @@ -214,7 +217,7 @@ class CodecClient : Logger::Loggable, * Called when a response finishes decoding. This is called *before* forwarding on to the * wrapped decoder. */ - void responseDecodeComplete(ActiveRequest& request); + void responsePreDecodeComplete(ActiveRequest& request); void deleteRequest(ActiveRequest& request); void onReset(ActiveRequest& request, StreamResetReason reason); diff --git a/source/common/http/conn_pool_base.cc b/source/common/http/conn_pool_base.cc index 4fbd6cbd588b..ff577eff4901 100644 --- a/source/common/http/conn_pool_base.cc +++ b/source/common/http/conn_pool_base.cc @@ -50,10 +50,11 @@ HttpConnPoolImplBase::HttpConnPoolImplBase( Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, Event::Dispatcher& dispatcher, const Network::ConnectionSocket::OptionsSharedPtr& options, const Network::TransportSocketOptionsSharedPtr& transport_socket_options, - Random::RandomGenerator& random_generator, std::vector protocols) + Random::RandomGenerator& random_generator, Upstream::ClusterConnectivityState& state, + std::vector protocols) : Envoy::ConnectionPool::ConnPoolImplBase( host, priority, dispatcher, options, - wrapTransportSocketOptions(transport_socket_options, protocols)), + wrapTransportSocketOptions(transport_socket_options, protocols), state), random_generator_(random_generator) { ASSERT(!protocols.empty()); // TODO(alyssawilk) the protocol function should probably be an optional and @@ -73,7 +74,7 @@ HttpConnPoolImplBase::newStream(Http::ResponseDecoder& response_decoder, } bool HttpConnPoolImplBase::hasActiveConnections() const { - return (!pending_streams_.empty() || (num_active_streams_ > 0)); + return (hasPendingStreams() || (hasActiveStreams())); } ConnectionPool::Cancellable* @@ -83,8 +84,7 @@ HttpConnPoolImplBase::newPendingStream(Envoy::ConnectionPool::AttachContext& con ENVOY_LOG(debug, "queueing stream due to no available connections"); Envoy::ConnectionPool::PendingStreamPtr pending_stream( new HttpPendingStream(*this, decoder, callbacks)); - LinkedList::moveIntoList(std::move(pending_stream), pending_streams_); - return pending_streams_.front().get(); + return addPendingStream(std::move(pending_stream)); } void HttpConnPoolImplBase::onPoolReady(Envoy::ConnectionPool::ActiveClient& client, diff --git a/source/common/http/conn_pool_base.h b/source/common/http/conn_pool_base.h index aad2d57ee3f1..29c48af1127d 100644 --- a/source/common/http/conn_pool_base.h +++ b/source/common/http/conn_pool_base.h @@ -51,6 +51,7 @@ class HttpConnPoolImplBase : public Envoy::ConnectionPool::ConnPoolImplBase, const Network::ConnectionSocket::OptionsSharedPtr& options, const Network::TransportSocketOptionsSharedPtr& transport_socket_options, Random::RandomGenerator& random_generator, + Upstream::ClusterConnectivityState& state, std::vector protocol); ~HttpConnPoolImplBase() override; @@ -90,8 +91,8 @@ class HttpConnPoolImplBase : public Envoy::ConnectionPool::ConnPoolImplBase, // An implementation of Envoy::ConnectionPool::ActiveClient for HTTP/1.1 and HTTP/2 class ActiveClient : public Envoy::ConnectionPool::ActiveClient { public: - ActiveClient(HttpConnPoolImplBase& parent, uint64_t lifetime_stream_limit, - uint64_t concurrent_stream_limit) + ActiveClient(HttpConnPoolImplBase& parent, uint32_t lifetime_stream_limit, + uint32_t concurrent_stream_limit) : Envoy::ConnectionPool::ActiveClient(parent, lifetime_stream_limit, concurrent_stream_limit) { // The static cast makes sure we call the base class host() and not @@ -119,7 +120,7 @@ class ActiveClient : public Envoy::ConnectionPool::ActiveClient { void onEvent(Network::ConnectionEvent event) override { parent_.onConnectionEvent(*this, codec_client_->connectionFailureReason(), event); } - size_t numActiveStreams() const override { return codec_client_->numActiveRequests(); } + uint32_t numActiveStreams() const override { return codec_client_->numActiveRequests(); } uint64_t id() const override { return codec_client_->id(); } HttpConnPoolImplBase& parent() { return *static_cast(&parent_); } @@ -139,10 +140,11 @@ class FixedHttpConnPoolImpl : public HttpConnPoolImplBase { Event::Dispatcher& dispatcher, const Network::ConnectionSocket::OptionsSharedPtr& options, const Network::TransportSocketOptionsSharedPtr& transport_socket_options, - Random::RandomGenerator& random_generator, CreateClientFn client_fn, + Random::RandomGenerator& random_generator, + Upstream::ClusterConnectivityState& state, CreateClientFn client_fn, CreateCodecFn codec_fn, std::vector protocol) : HttpConnPoolImplBase(host, priority, dispatcher, options, transport_socket_options, - random_generator, protocol), + random_generator, state, protocol), codec_fn_(codec_fn), client_fn_(client_fn) {} CodecClientPtr createCodecClient(Upstream::Host::CreateConnectionData& data) override { diff --git a/source/common/http/http1/codec_impl.cc b/source/common/http/http1/codec_impl.cc index 6a803cca1e6c..f8c530cbcf48 100644 --- a/source/common/http/http1/codec_impl.cc +++ b/source/common/http/http1/codec_impl.cc @@ -552,6 +552,16 @@ Http::Status ConnectionImpl::dispatch(Buffer::Instance& data) { [&](Buffer::Instance& data) -> Http::Status { return innerDispatch(data); }, data); } +Http::Status ClientConnectionImpl::dispatch(Buffer::Instance& data) { + Http::Status status = ConnectionImpl::dispatch(data); + if (status.ok() && data.length() > 0) { + // The HTTP/1.1 codec pauses dispatch after a single response is complete. Extraneous data + // after a response is complete indicates an error. + return codecProtocolError("http/1.1 protocol error: extraneous data after response complete"); + } + return status; +} + Http::Status ConnectionImpl::innerDispatch(Buffer::Instance& data) { ENVOY_CONN_LOG(trace, "parsing {} bytes", connection_, data.length()); // Make sure that dispatching_ is set to false after dispatching, even when @@ -1285,6 +1295,9 @@ void ClientConnectionImpl::onMessageComplete() { pending_response_.reset(); headers_or_trailers_.emplace(nullptr); } + + // Pause the parser after a response is complete. Any remaining data indicates an error. + http_parser_pause(&parser_, 1); } void ClientConnectionImpl::onResetStream(StreamResetReason reason) { diff --git a/source/common/http/http1/codec_impl.h b/source/common/http/http1/codec_impl.h index 867cd603f57a..f63b777c6a44 100644 --- a/source/common/http/http1/codec_impl.h +++ b/source/common/http/http1/codec_impl.h @@ -580,6 +580,7 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { bool cannotHaveBody(); // ConnectionImpl + Http::Status dispatch(Buffer::Instance& data) override; void onEncodeComplete() override {} Status onMessageBegin() override { return okStatus(); } Status onUrl(const char*, size_t) override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } diff --git a/source/common/http/http1/codec_impl_legacy.cc b/source/common/http/http1/codec_impl_legacy.cc index 474fd7ce1b0c..d82a6ae15b2f 100644 --- a/source/common/http/http1/codec_impl_legacy.cc +++ b/source/common/http/http1/codec_impl_legacy.cc @@ -526,6 +526,16 @@ Http::Status ConnectionImpl::dispatch(Buffer::Instance& data) { [&](Buffer::Instance& data) -> Http::Status { return innerDispatch(data); }, data); } +Http::Status ClientConnectionImpl::dispatch(Buffer::Instance& data) { + Http::Status status = ConnectionImpl::dispatch(data); + if (status.ok() && data.length() > 0) { + // The HTTP/1.1 codec pauses dispatch after a single response is complete. Extraneous data + // after a response is complete indicates an error. + return codecProtocolError("http/1.1 protocol error: extraneous data after response complete"); + } + return status; +} + Http::Status ConnectionImpl::innerDispatch(Buffer::Instance& data) { ENVOY_CONN_LOG(trace, "parsing {} bytes", connection_, data.length()); ASSERT(buffered_body_.length() == 0); diff --git a/source/common/http/http1/codec_impl_legacy.h b/source/common/http/http1/codec_impl_legacy.h index 48382473f0bd..6510116d7a36 100644 --- a/source/common/http/http1/codec_impl_legacy.h +++ b/source/common/http/http1/codec_impl_legacy.h @@ -555,6 +555,7 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { bool cannotHaveBody(); // ConnectionImpl + Http::Status dispatch(Buffer::Instance& data) override; void onEncodeComplete() override {} void onMessageBegin() override {} void onUrl(const char*, size_t) override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } diff --git a/source/common/http/http1/conn_pool.cc b/source/common/http/http1/conn_pool.cc index c37e2f8e8635..cc69ab976c0e 100644 --- a/source/common/http/http1/conn_pool.cc +++ b/source/common/http/http1/conn_pool.cc @@ -66,7 +66,6 @@ void ActiveClient::StreamWrapper::decodeHeaders(ResponseHeaderMapPtr&& headers, void ActiveClient::StreamWrapper::onDecodeComplete() { ASSERT(!decode_complete_); decode_complete_ = encode_complete_; - ENVOY_CONN_LOG(debug, "response complete", *parent_.codec_client_); if (!parent_.stream_wrapper_->encode_complete_) { @@ -110,10 +109,11 @@ ConnectionPool::InstancePtr allocateConnPool(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) { + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Upstream::ClusterConnectivityState& state) { return std::make_unique( std::move(host), std::move(priority), dispatcher, options, transport_socket_options, - random_generator, + random_generator, state, [](HttpConnPoolImplBase* pool) { return std::make_unique(*pool); }, [](Upstream::Host::CreateConnectionData& data, HttpConnPoolImplBase* pool) { CodecClientPtr codec{new CodecClientProd( diff --git a/source/common/http/http1/conn_pool.h b/source/common/http/http1/conn_pool.h index 5b37d855e52f..e8c5b0705587 100644 --- a/source/common/http/http1/conn_pool.h +++ b/source/common/http/http1/conn_pool.h @@ -22,6 +22,14 @@ class ActiveClient : public Envoy::Http::ActiveClient { bool closingWithIncompleteStream() const override; RequestEncoder& newStreamEncoder(ResponseDecoder& response_decoder) override; + uint32_t numActiveStreams() const override { + // Override the parent class using the codec for numActiveStreams. + // Unfortunately for the HTTP/1 codec, the stream is destroyed before decode + // is complete, and we must make sure the connection pool does not observe available + // capacity and assign a new stream before decode is complete. + return stream_wrapper_.get() ? 1 : 0; + } + struct StreamWrapper : public RequestEncoderWrapper, public ResponseDecoderWrapper, public StreamCallbacks, @@ -42,10 +50,13 @@ class ActiveClient : public Envoy::Http::ActiveClient { void onAboveWriteBufferHighWatermark() override {} void onBelowWriteBufferLowWatermark() override {} + void onStreamDestroy(); + ActiveClient& parent_; + bool stream_incomplete_{}; bool encode_complete_{}; - bool close_connection_{}; bool decode_complete_{}; + bool close_connection_{}; }; using StreamWrapperPtr = std::unique_ptr; @@ -56,7 +67,8 @@ ConnectionPool::InstancePtr allocateConnPool(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options); + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Upstream::ClusterConnectivityState& state); } // namespace Http1 } // namespace Http diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index fc5cc2349171..74a565b27916 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -1007,7 +1007,7 @@ int ConnectionImpl::onMetadataReceived(int32_t stream_id, const uint8_t* data, s ENVOY_CONN_LOG(trace, "recv {} bytes METADATA", connection_, len); StreamImpl* stream = getStream(stream_id); - if (!stream) { + if (!stream || stream->remote_end_stream_) { return 0; } @@ -1020,7 +1020,7 @@ int ConnectionImpl::onMetadataFrameComplete(int32_t stream_id, bool end_metadata stream_id, end_metadata); StreamImpl* stream = getStream(stream_id); - if (stream == nullptr) { + if (!stream || stream->remote_end_stream_) { return 0; } diff --git a/source/common/http/http2/codec_impl_legacy.cc b/source/common/http/http2/codec_impl_legacy.cc index 75719d625e01..794885e47526 100644 --- a/source/common/http/http2/codec_impl_legacy.cc +++ b/source/common/http/http2/codec_impl_legacy.cc @@ -993,7 +993,7 @@ int ConnectionImpl::onMetadataReceived(int32_t stream_id, const uint8_t* data, s ENVOY_CONN_LOG(trace, "recv {} bytes METADATA", connection_, len); StreamImpl* stream = getStream(stream_id); - if (!stream) { + if (!stream || stream->remote_end_stream_) { return 0; } @@ -1006,7 +1006,7 @@ int ConnectionImpl::onMetadataFrameComplete(int32_t stream_id, bool end_metadata stream_id, end_metadata); StreamImpl* stream = getStream(stream_id); - if (stream == nullptr) { + if (!stream || stream->remote_end_stream_) { return 0; } diff --git a/source/common/http/http2/conn_pool.cc b/source/common/http/http2/conn_pool.cc index c9c901f466d3..492ebb62e4f6 100644 --- a/source/common/http/http2/conn_pool.cc +++ b/source/common/http/http2/conn_pool.cc @@ -74,9 +74,10 @@ ConnectionPool::InstancePtr allocateConnPool(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) { + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Upstream::ClusterConnectivityState& state) { return std::make_unique( - host, priority, dispatcher, options, transport_socket_options, random_generator, + host, priority, dispatcher, options, transport_socket_options, random_generator, state, [](HttpConnPoolImplBase* pool) { return std::make_unique(*pool); }, [](Upstream::Host::CreateConnectionData& data, HttpConnPoolImplBase* pool) { CodecClientPtr codec{new CodecClientProd( diff --git a/source/common/http/http2/conn_pool.h b/source/common/http/http2/conn_pool.h index cc5c335e38be..2a277a55ea6c 100644 --- a/source/common/http/http2/conn_pool.h +++ b/source/common/http/http2/conn_pool.h @@ -39,7 +39,8 @@ ConnectionPool::InstancePtr allocateConnPool(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options); + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Upstream::ClusterConnectivityState& state); } // namespace Http2 } // namespace Http diff --git a/source/common/network/io_socket_handle_impl.cc b/source/common/network/io_socket_handle_impl.cc index fb1c2e120ec5..508ce6400aac 100644 --- a/source/common/network/io_socket_handle_impl.cc +++ b/source/common/network/io_socket_handle_impl.cc @@ -48,6 +48,16 @@ in_addr addressFromMessage(const cmsghdr& cmsg) { #endif } +constexpr int messageTruncatedOption() { +#if defined(__APPLE__) + // OSX does not support passing `MSG_TRUNC` to recvmsg and recvmmsg. This does not effect + // functionality and it primarily used for logging. + return 0; +#else + return MSG_TRUNC; +#endif +} + } // namespace namespace Network { @@ -84,8 +94,18 @@ Api::IoCallUint64Result IoSocketHandleImpl::readv(uint64_t max_length, Buffer::R num_bytes_to_read += slice_length; } ASSERT(num_bytes_to_read <= max_length); - return sysCallResultToIoCallResult(Api::OsSysCallsSingleton::get().readv( + auto result = sysCallResultToIoCallResult(Api::OsSysCallsSingleton::get().readv( fd_, iov.begin(), static_cast(num_slices_to_read))); + + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + // Some tests try to read without initializing the file_event. + if (result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Read); + } + } + return result; } Api::IoCallUint64Result IoSocketHandleImpl::read(Buffer::Instance& buffer, uint64_t max_length) { @@ -103,6 +123,15 @@ Api::IoCallUint64Result IoSocketHandleImpl::read(Buffer::Instance& buffer, uint6 bytes_to_commit -= slices[i].len_; } buffer.commit(slices, num_slices); + + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + // Some tests try to read without initializing the file_event. + if (result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Read); + } + } return result; } @@ -120,8 +149,18 @@ Api::IoCallUint64Result IoSocketHandleImpl::writev(const Buffer::RawSlice* slice if (num_slices_to_write == 0) { return Api::ioCallUint64ResultNoError(); } - return sysCallResultToIoCallResult( + auto result = sysCallResultToIoCallResult( Api::OsSysCallsSingleton::get().writev(fd_, iov.begin(), num_slices_to_write)); + + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + // Some tests try to write without initializing the file_event. + if (result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Write); + } + } + return result; } Api::IoCallUint64Result IoSocketHandleImpl::write(Buffer::Instance& buffer) { @@ -131,6 +170,15 @@ Api::IoCallUint64Result IoSocketHandleImpl::write(Buffer::Instance& buffer) { if (result.ok() && result.rc_ > 0) { buffer.drain(static_cast(result.rc_)); } + + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + // Some tests try to read without initializing the file_event. + if (result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Write); + } + } return result; } @@ -168,7 +216,15 @@ Api::IoCallUint64Result IoSocketHandleImpl::sendmsg(const Buffer::RawSlice* slic message.msg_control = nullptr; message.msg_controllen = 0; const Api::SysCallSizeResult result = os_syscalls.sendmsg(fd_, &message, flags); - return sysCallResultToIoCallResult(result); + auto io_result = sysCallResultToIoCallResult(result); + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + if (io_result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Write); + } + } + return io_result; } else { const size_t space_v6 = CMSG_SPACE(sizeof(in6_pktinfo)); const size_t space_v4 = CMSG_SPACE(sizeof(in_pktinfo)); @@ -210,7 +266,15 @@ Api::IoCallUint64Result IoSocketHandleImpl::sendmsg(const Buffer::RawSlice* slic *(reinterpret_cast(pktinfo->ipi6_addr.s6_addr)) = self_ip->ipv6()->address(); } const Api::SysCallSizeResult result = os_syscalls.sendmsg(fd_, &message, flags); - return sysCallResultToIoCallResult(result); + auto io_result = sysCallResultToIoCallResult(result); + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + if (io_result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Write); + } + } + return io_result; } } @@ -296,8 +360,24 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmsg(Buffer::RawSlice* slices, hdr.msg_flags = 0; hdr.msg_control = cbuf.begin(); hdr.msg_controllen = cmsg_space_; - const Api::SysCallSizeResult result = Api::OsSysCallsSingleton::get().recvmsg(fd_, &hdr, 0); + Api::SysCallSizeResult result = + Api::OsSysCallsSingleton::get().recvmsg(fd_, &hdr, messageTruncatedOption()); if (result.rc_ < 0) { + auto io_result = sysCallResultToIoCallResult(result); + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + if (io_result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Read); + } + } + return io_result; + } + if ((hdr.msg_flags & MSG_TRUNC) != 0) { + ENVOY_LOG_MISC(debug, "Dropping truncated UDP packet with size: {}.", result.rc_); + result.rc_ = 0; + (*output.dropped_packets_)++; + output.msg_[0].truncated_and_dropped_ = true; return sysCallResultToIoCallResult(result); } @@ -324,7 +404,7 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmsg(Buffer::RawSlice* slices, if (output.dropped_packets_ != nullptr) { absl::optional maybe_dropped = maybeGetPacketsDroppedFromHeader(*cmsg); if (maybe_dropped) { - *output.dropped_packets_ = *maybe_dropped; + *output.dropped_packets_ += *maybe_dropped; continue; } } @@ -377,28 +457,37 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmmsg(RawSliceArrays& slices, uin // Set MSG_WAITFORONE so that recvmmsg will not waiting for // |num_packets_per_mmsg_call| packets to arrive before returning when the // socket is a blocking socket. - const Api::SysCallIntResult result = Api::OsSysCallsSingleton::get().recvmmsg( - fd_, mmsg_hdr.data(), num_packets_per_mmsg_call, MSG_TRUNC | MSG_WAITFORONE, nullptr); + const Api::SysCallIntResult result = + Api::OsSysCallsSingleton::get().recvmmsg(fd_, mmsg_hdr.data(), num_packets_per_mmsg_call, + messageTruncatedOption() | MSG_WAITFORONE, nullptr); if (result.rc_ <= 0) { - return sysCallResultToIoCallResult(result); + auto io_result = sysCallResultToIoCallResult(result); + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + if (io_result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Read); + } + } + return io_result; } int num_packets_read = result.rc_; for (int i = 0; i < num_packets_read; ++i) { - if (mmsg_hdr[i].msg_len == 0) { + msghdr& hdr = mmsg_hdr[i].msg_hdr; + if ((hdr.msg_flags & MSG_TRUNC) != 0) { + ENVOY_LOG_MISC(debug, "Dropping truncated UDP packet with size: {}.", mmsg_hdr[i].msg_len); + (*output.dropped_packets_)++; + output.msg_[i].truncated_and_dropped_ = true; continue; } - msghdr& hdr = mmsg_hdr[i].msg_hdr; + RELEASE_ASSERT((hdr.msg_flags & MSG_CTRUNC) == 0, fmt::format("Incorrectly set control message length: {}", hdr.msg_controllen)); RELEASE_ASSERT(hdr.msg_namelen > 0, fmt::format("Unable to get remote address from recvmmsg() for fd: {}", fd_)); - if ((hdr.msg_flags & MSG_TRUNC) != 0) { - ENVOY_LOG_MISC(warn, "Dropping truncated UDP packet with size: {}.", mmsg_hdr[i].msg_len); - continue; - } output.msg_[i].msg_len_ = mmsg_hdr[i].msg_len; // Get local and peer addresses for each packet. @@ -424,7 +513,7 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmmsg(RawSliceArrays& slices, uin for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr; cmsg = CMSG_NXTHDR(&hdr, cmsg)) { absl::optional maybe_dropped = maybeGetPacketsDroppedFromHeader(*cmsg); if (maybe_dropped) { - *output.dropped_packets_ = *maybe_dropped; + *output.dropped_packets_ += *maybe_dropped; } } } @@ -435,7 +524,15 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmmsg(RawSliceArrays& slices, uin Api::IoCallUint64Result IoSocketHandleImpl::recv(void* buffer, size_t length, int flags) { const Api::SysCallSizeResult result = Api::OsSysCallsSingleton::get().recv(fd_, buffer, length, flags); - return sysCallResultToIoCallResult(result); + auto io_result = sysCallResultToIoCallResult(result); + // Emulated edge events need to registered if the socket operation did not complete + // because the socket would block. + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + if (io_result.wouldBlock() && file_event_) { + file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Read); + } + } + return io_result; } bool IoSocketHandleImpl::supportsMmsg() const { diff --git a/source/common/network/udp_listener_impl.h b/source/common/network/udp_listener_impl.h index 99db6dca4ac0..a6b2852b3990 100644 --- a/source/common/network/udp_listener_impl.h +++ b/source/common/network/udp_listener_impl.h @@ -24,8 +24,8 @@ class UdpListenerImpl : public BaseListenerImpl, public: UdpListenerImpl(Event::DispatcherImpl& dispatcher, SocketSharedPtr socket, UdpListenerCallbacks& cb, TimeSource& time_source); - ~UdpListenerImpl() override; + uint32_t packetsDropped() { return packets_dropped_; } // Network::Listener Interface void disable() override; diff --git a/source/common/network/utility.cc b/source/common/network/utility.cc index 426598ace956..0574c040a1d1 100644 --- a/source/common/network/utility.cc +++ b/source/common/network/utility.cc @@ -629,6 +629,10 @@ Api::IoCallUint64Result Utility::readFromSocket(IoHandle& handle, uint64_t packets_read = result.rc_; ENVOY_LOG_MISC(trace, "recvmmsg read {} packets", packets_read); for (uint64_t i = 0; i < packets_read; ++i) { + if (output.msg_[i].truncated_and_dropped_) { + continue; + } + Buffer::RawSlice* slice = slices[i].data(); const uint64_t msg_len = output.msg_[i].msg_len_; ASSERT(msg_len <= slice->len_); @@ -651,7 +655,7 @@ Api::IoCallUint64Result Utility::readFromSocket(IoHandle& handle, Api::IoCallUint64Result result = receiveMessage(udp_packet_processor.maxPacketSize(), buffer, output, handle, local_address); - if (!result.ok()) { + if (!result.ok() || output.msg_[0].truncated_and_dropped_) { return result; } @@ -678,12 +682,6 @@ Api::IoErrorPtr Utility::readPacketsFromSocket(IoHandle& handle, return std::move(result.err_); } - if (result.rc_ == 0) { - // TODO(conqerAtapple): Is zero length packet interesting? If so add stats - // for it. Otherwise remove the warning log below. - ENVOY_LOG_MISC(trace, "received 0-length packet"); - } - if (packets_dropped != old_packets_dropped) { // The kernel tracks SO_RXQ_OVFL as a uint32 which can overflow to a smaller // value. So as long as this count differs from previously recorded value, diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index a961c25eaebb..fd9907cbef75 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -57,7 +57,6 @@ constexpr const char* runtime_features[] = { // Begin alphabetically sorted section. "envoy.deprecated_features.allow_deprecated_extension_names", "envoy.reloadable_features.always_apply_route_header_rules", - "envoy.reloadable_features.activate_fds_next_event_loop", "envoy.reloadable_features.activate_timers_next_event_loop", "envoy.reloadable_features.allow_500_after_100", "envoy.reloadable_features.allow_prefetch", diff --git a/source/common/signal/BUILD b/source/common/signal/BUILD index 2a18144c87db..893f2fa78454 100644 --- a/source/common/signal/BUILD +++ b/source/common/signal/BUILD @@ -13,6 +13,8 @@ envoy_cc_library( srcs = ["fatal_error_handler.cc"], hdrs = ["fatal_error_handler.h"], deps = [ + ":fatal_action_lib", + "//include/envoy/event:dispatcher_interface", "//source/common/common:macros", ], ) @@ -30,3 +32,12 @@ envoy_cc_library( "//source/server:backtrace_lib", ], ) + +envoy_cc_library( + name = "fatal_action_lib", + hdrs = ["fatal_action.h"], + deps = [ + "//include/envoy/server:fatal_action_interface", + "//include/envoy/thread:thread_interface", + ], +) diff --git a/source/common/signal/fatal_action.h b/source/common/signal/fatal_action.h new file mode 100644 index 000000000000..4ecaf1461635 --- /dev/null +++ b/source/common/signal/fatal_action.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#include "envoy/common/pure.h" +#include "envoy/server/fatal_action_config.h" +#include "envoy/thread/thread.h" + +namespace Envoy { +namespace FatalAction { + +using FatalActionPtrList = std::list; + +// Status when trying to run the Fatal Actions. +enum class Status { + Success, + + // We either haven't set up the Fatal Action manager, or we unregistered it + // as the server terminated. + ActionManangerUnset, + + // Another thread beat us to running the Fatal Actions. + RunningOnAnotherThread, + + // We have already ran those actions on this thread. + AlreadyRanOnThisThread, +}; + +// A simple class which manages the Fatal Actions registered via the +// extension point. +class FatalActionManager { +public: + FatalActionManager(FatalActionPtrList safe_actions, FatalActionPtrList unsafe_actions, + Thread::ThreadFactory& thread_factory) + : safe_actions_(std::move(safe_actions)), unsafe_actions_(std::move(unsafe_actions)), + thread_factory_(thread_factory) {} + + const FatalActionPtrList& getSafeActions() const { return safe_actions_; } + const FatalActionPtrList& getUnsafeActions() const { return unsafe_actions_; } + Thread::ThreadFactory& getThreadFactory() const { return thread_factory_; } + +private: + FatalActionPtrList safe_actions_; + FatalActionPtrList unsafe_actions_; + Thread::ThreadFactory& thread_factory_; +}; + +} // namespace FatalAction +} // namespace Envoy diff --git a/source/common/signal/fatal_error_handler.cc b/source/common/signal/fatal_error_handler.cc index 125093e3c589..e7099e6f0254 100644 --- a/source/common/signal/fatal_error_handler.cc +++ b/source/common/signal/fatal_error_handler.cc @@ -1,8 +1,13 @@ #include "common/signal/fatal_error_handler.h" +#include #include +#include "envoy/event/dispatcher.h" + +#include "common/common/assert.h" #include "common/common/macros.h" +#include "common/signal/fatal_action.h" #include "absl/base/attributes.h" #include "absl/synchronization/mutex.h" @@ -12,6 +17,12 @@ namespace FatalErrorHandler { namespace { +// The type of Fatal Actions. +enum class FatalActionType { + Safe, + Unsafe, +}; + ABSL_CONST_INIT static absl::Mutex failure_mutex(absl::kConstInit); // Since we can't grab the failure mutex on fatal error (snagging locks under // fatal crash causing potential deadlocks) access the handler list as an atomic @@ -22,17 +33,84 @@ ABSL_CONST_INIT static absl::Mutex failure_mutex(absl::kConstInit); using FailureFunctionList = std::list; ABSL_CONST_INIT std::atomic fatal_error_handlers{nullptr}; +// Use an atomic operation since on fatal error we'll consume the +// fatal_action_manager and don't want to have any locks as they aren't +// async-signal-safe. +ABSL_CONST_INIT std::atomic fatal_action_manager{nullptr}; +ABSL_CONST_INIT std::atomic failure_tid{-1}; + +// Executes the Fatal Actions provided. +void runFatalActionsInternal(const FatalAction::FatalActionPtrList& actions) { + // Exchange the fatal_error_handlers pointer so other functions cannot + // concurrently access the list. + FailureFunctionList* list = fatal_error_handlers.exchange(nullptr); + if (list == nullptr) { + return; + } + + // Get the dispatcher and its tracked object. + for (auto* handler : *list) { + handler->runFatalActionsOnTrackedObject(actions); + } + + // Restore the fatal_error_handlers pointer so subsequent calls using the list + // can succeed. + fatal_error_handlers.store(list); +} + +// Helper function to run exclusively either safe or unsafe actions depending on +// the provided action_type. +// Returns a FatalAction status corresponding to our attempt to run the +// action_type. +FatalAction::Status runFatalActions(FatalActionType action_type) { + // Check that registerFatalActions has already been called. + FatalAction::FatalActionManager* action_manager = fatal_action_manager.load(); + + if (action_manager == nullptr) { + return FatalAction::Status::ActionManangerUnset; + } + + int64_t my_tid = action_manager->getThreadFactory().currentThreadId().getId(); + + if (action_type == FatalActionType::Safe) { + // Try to run safe actions + int64_t expected_tid = -1; + + if (failure_tid.compare_exchange_strong(expected_tid, my_tid)) { + // Run the actions + runFatalActionsInternal(action_manager->getSafeActions()); + return FatalAction::Status::Success; + } else if (expected_tid == my_tid) { + return FatalAction::Status::AlreadyRanOnThisThread; + } + + } else { + // Try to run unsafe actions + int64_t failing_tid = failure_tid.load(); + + ASSERT(failing_tid != -1); + + if (my_tid == failing_tid) { + runFatalActionsInternal(action_manager->getUnsafeActions()); + return FatalAction::Status::Success; + } + } + + return FatalAction::Status::RunningOnAnotherThread; +} + } // namespace void registerFatalErrorHandler(const FatalErrorHandlerInterface& handler) { #ifdef ENVOY_OBJECT_TRACE_ON_DUMP absl::MutexLock l(&failure_mutex); - FailureFunctionList* list = fatal_error_handlers.exchange(nullptr, std::memory_order_relaxed); + FailureFunctionList* list = fatal_error_handlers.exchange(nullptr); if (list == nullptr) { list = new FailureFunctionList; } list->push_back(&handler); - fatal_error_handlers.store(list, std::memory_order_release); + // Store the fatal_error_handlers pointer now that the list is updated. + fatal_error_handlers.store(list); #else UNREFERENCED_PARAMETER(handler); #endif @@ -41,7 +119,7 @@ void registerFatalErrorHandler(const FatalErrorHandlerInterface& handler) { void removeFatalErrorHandler(const FatalErrorHandlerInterface& handler) { #ifdef ENVOY_OBJECT_TRACE_ON_DUMP absl::MutexLock l(&failure_mutex); - FailureFunctionList* list = fatal_error_handlers.exchange(nullptr, std::memory_order_relaxed); + FailureFunctionList* list = fatal_error_handlers.exchange(nullptr); if (list == nullptr) { // removeFatalErrorHandler() may see an empty list of fatal error handlers // if it's called at the same time as callFatalErrorHandlers(). In that case @@ -53,7 +131,7 @@ void removeFatalErrorHandler(const FatalErrorHandlerInterface& handler) { if (list->empty()) { delete list; } else { - fatal_error_handlers.store(list, std::memory_order_release); + fatal_error_handlers.store(list); } #else UNREFERENCED_PARAMETER(handler); @@ -61,13 +139,50 @@ void removeFatalErrorHandler(const FatalErrorHandlerInterface& handler) { } void callFatalErrorHandlers(std::ostream& os) { - FailureFunctionList* list = fatal_error_handlers.exchange(nullptr, std::memory_order_relaxed); + FailureFunctionList* list = fatal_error_handlers.exchange(nullptr); if (list != nullptr) { for (const auto* handler : *list) { handler->onFatalError(os); } - delete list; + + fatal_error_handlers.store(list); + } +} + +void registerFatalActions(FatalAction::FatalActionPtrList safe_actions, + FatalAction::FatalActionPtrList unsafe_actions, + Thread::ThreadFactory& thread_factory) { + // Create a FatalActionManager and store it. + FatalAction::FatalActionManager* previous_manager = + fatal_action_manager.exchange(new FatalAction::FatalActionManager( + std::move(safe_actions), std::move(unsafe_actions), thread_factory)); + + // Previous manager should be NULL. + ASSERT(!previous_manager); +} + +FatalAction::Status runSafeActions() { return runFatalActions(FatalActionType::Safe); } + +FatalAction::Status runUnsafeActions() { return runFatalActions(FatalActionType::Unsafe); } + +void clearFatalActionsOnTerminate() { + auto* raw_ptr = fatal_action_manager.exchange(nullptr); + if (raw_ptr != nullptr) { + delete raw_ptr; + } +} + +// This resets the internal state of Fatal Action for the module. +// This is necessary as it allows us to have multiple test cases invoke the +// fatal actions without state from other tests leaking in. +void resetFatalActionStateForTest() { + // Free the memory of the Fatal Action, since it's not managed by a smart + // pointer. This prevents memory leaks in tests. + auto* raw_ptr = fatal_action_manager.exchange(nullptr); + if (raw_ptr != nullptr) { + delete raw_ptr; } + failure_tid.store(-1); } } // namespace FatalErrorHandler diff --git a/source/common/signal/fatal_error_handler.h b/source/common/signal/fatal_error_handler.h index b06997af7e81..d7d25013432d 100644 --- a/source/common/signal/fatal_error_handler.h +++ b/source/common/signal/fatal_error_handler.h @@ -4,6 +4,8 @@ #include "envoy/common/pure.h" +#include "common/signal/fatal_action.h" + namespace Envoy { // A simple class which allows registering functions to be called when Envoy @@ -14,6 +16,9 @@ class FatalErrorHandlerInterface { // Called when Envoy receives a fatal signal. Must be async-signal-safe: in // particular, it can't allocate memory. virtual void onFatalError(std::ostream& os) const PURE; + + virtual void + runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const PURE; }; namespace FatalErrorHandler { @@ -35,5 +40,37 @@ void removeFatalErrorHandler(const FatalErrorHandlerInterface& handler); * called from a fatal signal handler. */ void callFatalErrorHandlers(std::ostream& os); + +/** + * Creates the singleton FatalActionManager if not already created and + * registers the specified actions to run on failure. + */ +void registerFatalActions(FatalAction::FatalActionPtrList safe_actions, + FatalAction::FatalActionPtrList unsafe_actions, + Thread::ThreadFactory& thread_factory); + +/** + * Tries to run all of the safe fatal actions. Only one thread will + * be allowed to run the fatal functions. + * + * Returns a FatalAction::Status which the caller should use to + * determine how to proceed. + */ +FatalAction::Status runSafeActions(); + +/** + * Tries to run all of the unsafe fatal actions. Call this only + * after calling runSafeActions. + * + * Returns a FatalAction::Status which the caller should use to determine + * how to proceed. + */ +FatalAction::Status runUnsafeActions(); + +/** + * Clear the Fatal Actions at the end of the server's call to terminate(). + * We should clean up the Fatal Action to prevent the memory from leaking. + */ +void clearFatalActionsOnTerminate(); } // namespace FatalErrorHandler } // namespace Envoy diff --git a/source/common/signal/signal_action.cc b/source/common/signal/signal_action.cc index c3a53c19da70..143b95a81f6c 100644 --- a/source/common/signal/signal_action.cc +++ b/source/common/signal/signal_action.cc @@ -5,6 +5,7 @@ #include #include "common/common/assert.h" +#include "common/signal/fatal_action.h" #include "common/version/version.h" namespace Envoy { @@ -22,8 +23,31 @@ void SignalAction::sigHandler(int sig, siginfo_t* info, void* context) { } tracer.logTrace(); - // Finally after logging the stack trace, call any registered crash handlers. - FatalErrorHandler::callFatalErrorHandlers(std::cerr); + // Finally after logging the stack trace, call the crash handlers + // in order from safe to unsafe. + auto status = FatalErrorHandler::runSafeActions(); + + switch (status) { + case FatalAction::Status::Success: + FatalErrorHandler::callFatalErrorHandlers(std::cerr); + FatalErrorHandler::runUnsafeActions(); + break; + case FatalAction::Status::ActionManangerUnset: + FatalErrorHandler::callFatalErrorHandlers(std::cerr); + break; + case FatalAction::Status::RunningOnAnotherThread: { + // We should wait for some duration for the other thread to finish + // running. We should add support for this scenario, even though the + // probability of it occurring is low. + // TODO(kbaichoo): Implement a configurable call to sleep + NOT_IMPLEMENTED_GCOVR_EXCL_LINE; + break; + } + case FatalAction::Status::AlreadyRanOnThisThread: + // We caused another fatal signal to be raised. + std::cerr << "Our FatalActions triggered a fatal signal.\n"; + break; + } signal(sig, SIG_DFL); raise(sig); diff --git a/source/common/stats/BUILD b/source/common/stats/BUILD index fb8528063934..edc68f4774e7 100644 --- a/source/common/stats/BUILD +++ b/source/common/stats/BUILD @@ -195,6 +195,7 @@ envoy_cc_library( hdrs = ["tag_extractor_impl.h"], deps = [ "//include/envoy/stats:stats_interface", + "//source/common/common:assert_lib", "//source/common/common:perf_annotation_lib", "//source/common/common:regex_lib", ], diff --git a/source/common/stats/tag_extractor_impl.cc b/source/common/stats/tag_extractor_impl.cc index 3c666a13e105..6aefbdf6cd25 100644 --- a/source/common/stats/tag_extractor_impl.cc +++ b/source/common/stats/tag_extractor_impl.cc @@ -5,6 +5,7 @@ #include "envoy/common/exception.h" +#include "common/common/assert.h" #include "common/common/fmt.h" #include "common/common/perf_annotation.h" #include "common/common/regex.h" @@ -23,12 +24,11 @@ bool regexStartsWithDot(absl::string_view regex) { } // namespace -TagExtractorImpl::TagExtractorImpl(const std::string& name, const std::string& regex, - const std::string& substr) - : name_(name), prefix_(std::string(extractRegexPrefix(regex))), substr_(substr), - regex_(Regex::Utility::parseStdRegex(regex)) {} +TagExtractorImplBase::TagExtractorImplBase(absl::string_view name, absl::string_view regex, + absl::string_view substr) + : name_(name), prefix_(std::string(extractRegexPrefix(regex))), substr_(substr) {} -std::string TagExtractorImpl::extractRegexPrefix(absl::string_view regex) { +std::string TagExtractorImplBase::extractRegexPrefix(absl::string_view regex) { std::string prefix; if (absl::StartsWith(regex, "^")) { for (absl::string_view::size_type i = 1; i < regex.size(); ++i) { @@ -47,10 +47,10 @@ std::string TagExtractorImpl::extractRegexPrefix(absl::string_view regex) { return prefix; } -TagExtractorPtr TagExtractorImpl::createTagExtractor(const std::string& name, - const std::string& regex, - const std::string& substr) { - +TagExtractorPtr TagExtractorImplBase::createTagExtractor(absl::string_view name, + absl::string_view regex, + absl::string_view substr, + Regex::Type re_type) { if (name.empty()) { throw EnvoyException("tag_name cannot be empty"); } @@ -59,19 +59,37 @@ TagExtractorPtr TagExtractorImpl::createTagExtractor(const std::string& name, throw EnvoyException(fmt::format( "No regex specified for tag specifier and no default regex for name: '{}'", name)); } - return TagExtractorPtr{new TagExtractorImpl(name, regex, substr)}; + switch (re_type) { + case Regex::Type::Re2: + return std::make_unique(name, regex, substr); + case Regex::Type::StdRegex: + return std::make_unique(name, regex, substr); + } + NOT_REACHED_GCOVR_EXCL_LINE; } -bool TagExtractorImpl::substrMismatch(absl::string_view stat_name) const { +bool TagExtractorImplBase::substrMismatch(absl::string_view stat_name) const { return !substr_.empty() && stat_name.find(substr_) == absl::string_view::npos; } -bool TagExtractorImpl::extractTag(absl::string_view stat_name, TagVector& tags, - IntervalSet& remove_characters) const { +TagExtractorStdRegexImpl::TagExtractorStdRegexImpl(absl::string_view name, absl::string_view regex, + absl::string_view substr) + : TagExtractorImplBase(name, regex, substr), + regex_(Regex::Utility::parseStdRegex(std::string(regex))) {} + +std::string& TagExtractorImplBase::addTag(std::vector& tags) const { + tags.emplace_back(); + Tag& tag = tags.back(); + tag.name_ = name_; + return tag.value_; +} + +bool TagExtractorStdRegexImpl::extractTag(absl::string_view stat_name, std::vector& tags, + IntervalSet& remove_characters) const { PERF_OPERATION(perf); if (substrMismatch(stat_name)) { - PERF_RECORD(perf, "re-skip-substr", name_); + PERF_RECORD(perf, "re-skip", name_); return false; } @@ -88,11 +106,7 @@ bool TagExtractorImpl::extractTag(absl::string_view stat_name, TagVector& tags, // from the string but also not necessary in the tag value ("." for example). If there is no // second submatch, then the value_subexpr is the same as the remove_subexpr. const auto& value_subexpr = match.size() > 2 ? match[2] : remove_subexpr; - - tags.emplace_back(); - Tag& tag = tags.back(); - tag.name_ = name_; - tag.value_ = value_subexpr.str(); + addTag(tags) = value_subexpr.str(); // Determines which characters to remove from stat_name to elide remove_subexpr. std::string::size_type start = remove_subexpr.first - stat_name.begin(); @@ -105,5 +119,47 @@ bool TagExtractorImpl::extractTag(absl::string_view stat_name, TagVector& tags, return false; } +TagExtractorRe2Impl::TagExtractorRe2Impl(absl::string_view name, absl::string_view regex, + absl::string_view substr) + : TagExtractorImplBase(name, regex, substr), regex_(regex) {} + +bool TagExtractorRe2Impl::extractTag(absl::string_view stat_name, std::vector& tags, + IntervalSet& remove_characters) const { + PERF_OPERATION(perf); + + if (substrMismatch(stat_name)) { + PERF_RECORD(perf, "re2-skip", name_); + return false; + } + + // remove_subexpr is the first submatch. It represents the portion of the string to be removed. + re2::StringPiece remove_subexpr, value_subexpr; + + // The regex must match and contain one or more subexpressions (all after the first are ignored). + if (re2::RE2::FullMatch(re2::StringPiece(stat_name.data(), stat_name.size()), regex_, + &remove_subexpr, &value_subexpr) && + !remove_subexpr.empty()) { + + // value_subexpr is the optional second submatch. It is usually inside the first submatch + // (remove_subexpr) to allow the expression to strip off extra characters that should be removed + // from the string but also not necessary in the tag value ("." for example). If there is no + // second submatch, then the value_subexpr is the same as the remove_subexpr. + if (value_subexpr.empty()) { + value_subexpr = remove_subexpr; + } + addTag(tags) = std::string(value_subexpr); + + // Determines which characters to remove from stat_name to elide remove_subexpr. + std::string::size_type start = remove_subexpr.data() - stat_name.data(); + std::string::size_type end = remove_subexpr.data() + remove_subexpr.size() - stat_name.data(); + remove_characters.insert(start, end); + + PERF_RECORD(perf, "re2-match", name_); + return true; + } + PERF_RECORD(perf, "re2-miss", name_); + return false; +} + } // namespace Stats } // namespace Envoy diff --git a/source/common/stats/tag_extractor_impl.h b/source/common/stats/tag_extractor_impl.h index a63c7e1e4626..f909868eb236 100644 --- a/source/common/stats/tag_extractor_impl.h +++ b/source/common/stats/tag_extractor_impl.h @@ -6,12 +6,15 @@ #include "envoy/stats/tag_extractor.h" +#include "common/common/regex.h" + #include "absl/strings/string_view.h" +#include "re2/re2.h" namespace Envoy { namespace Stats { -class TagExtractorImpl : public TagExtractor { +class TagExtractorImplBase : public TagExtractor { public: /** * Creates a tag extractor from the regex provided. name and regex must be non-empty. @@ -20,16 +23,16 @@ class TagExtractorImpl : public TagExtractor { * @param substr a substring that -- if provided -- must be present in a stat name * in order to match the regex. This is an optional performance tweak * to avoid large numbers of failed regex lookups. + * @param re_type the regular expression syntax used (Regex::Type::StdRegex or Regex::Type::Re2). * @return TagExtractorPtr newly constructed TagExtractor. */ - static TagExtractorPtr createTagExtractor(const std::string& name, const std::string& regex, - const std::string& substr = ""); + static TagExtractorPtr createTagExtractor(absl::string_view name, absl::string_view regex, + absl::string_view substr = "", + Regex::Type re_type = Regex::Type::StdRegex); - TagExtractorImpl(const std::string& name, const std::string& regex, - const std::string& substr = ""); + TagExtractorImplBase(absl::string_view name, absl::string_view regex, + absl::string_view substr = ""); std::string name() const override { return name_; } - bool extractTag(absl::string_view tag_extracted_name, TagVector& tags, - IntervalSet& remove_characters) const override; absl::string_view prefixToken() const override { return prefix_; } /** @@ -39,7 +42,7 @@ class TagExtractorImpl : public TagExtractor { */ bool substrMismatch(absl::string_view stat_name) const; -private: +protected: /** * Examines a regex string, looking for the pattern: ^alphanumerics_with_underscores\. * Returns "alphanumerics_with_underscores" if that pattern is found, empty-string otherwise. @@ -47,11 +50,43 @@ class TagExtractorImpl : public TagExtractor { * @return std::string the prefix, or "" if no prefix found. */ static std::string extractRegexPrefix(absl::string_view regex); + + /** + * Adds a new tag for the current name, returning a reference to the tag value. + * + * @param tags the list of tags + * @return a reference to the value of the tag that was added. + */ + std::string& addTag(std::vector& tags) const; + const std::string name_; const std::string prefix_; const std::string substr_; +}; + +class TagExtractorStdRegexImpl : public TagExtractorImplBase { +public: + TagExtractorStdRegexImpl(absl::string_view name, absl::string_view regex, + absl::string_view substr = ""); + + bool extractTag(absl::string_view tag_extracted_name, std::vector& tags, + IntervalSet& remove_characters) const override; + +private: const std::regex regex_; }; +class TagExtractorRe2Impl : public TagExtractorImplBase { +public: + TagExtractorRe2Impl(absl::string_view name, absl::string_view regex, + absl::string_view substr = ""); + + bool extractTag(absl::string_view tag_extracted_name, std::vector& tags, + IntervalSet& remove_characters) const override; + +private: + const re2::RE2 regex_; +}; + } // namespace Stats } // namespace Envoy diff --git a/source/common/stats/tag_producer_impl.cc b/source/common/stats/tag_producer_impl.cc index 255dfcaeed39..bfc35b52e40a 100644 --- a/source/common/stats/tag_producer_impl.cc +++ b/source/common/stats/tag_producer_impl.cc @@ -34,11 +34,11 @@ TagProducerImpl::TagProducerImpl(const envoy::config::metrics::v3::StatsConfig& "No regex specified for tag specifier and no default regex for name: '{}'", name)); } } else { - addExtractor(Stats::TagExtractorImpl::createTagExtractor(name, tag_specifier.regex())); + addExtractor(TagExtractorImplBase::createTagExtractor(name, tag_specifier.regex())); } } else if (tag_specifier.tag_value_case() == envoy::config::metrics::v3::TagSpecifier::TagValueCase::kFixedValue) { - default_tags_.emplace_back(Stats::Tag{name, tag_specifier.fixed_value()}); + default_tags_.emplace_back(Tag{name, tag_specifier.fixed_value()}); } } } @@ -47,8 +47,8 @@ int TagProducerImpl::addExtractorsMatching(absl::string_view name) { int num_found = 0; for (const auto& desc : Config::TagNames::get().descriptorVec()) { if (desc.name_ == name) { - addExtractor( - Stats::TagExtractorImpl::createTagExtractor(desc.name_, desc.regex_, desc.substr_)); + addExtractor(TagExtractorImplBase::createTagExtractor(desc.name_, desc.regex_, desc.substr_, + desc.re_type_)); ++num_found; } } @@ -103,8 +103,8 @@ TagProducerImpl::addDefaultExtractors(const envoy::config::metrics::v3::StatsCon if (!config.has_use_all_default_tags() || config.use_all_default_tags().value()) { for (const auto& desc : Config::TagNames::get().descriptorVec()) { names.emplace(desc.name_); - addExtractor( - Stats::TagExtractorImpl::createTagExtractor(desc.name_, desc.regex_, desc.substr_)); + addExtractor(TagExtractorImplBase::createTagExtractor(desc.name_, desc.regex_, desc.substr_, + desc.re_type_)); } } return names; diff --git a/source/common/tcp/conn_pool.h b/source/common/tcp/conn_pool.h index a3637b8a43cd..15fa4bd9aca4 100644 --- a/source/common/tcp/conn_pool.h +++ b/source/common/tcp/conn_pool.h @@ -95,7 +95,7 @@ class ActiveTcpClient : public Envoy::ConnectionPool::ActiveClient { void onBelowWriteBufferLowWatermark() override { callbacks_->onBelowWriteBufferLowWatermark(); } void close() override { connection_->close(Network::ConnectionCloseType::NoFlush); } - size_t numActiveStreams() const override { return callbacks_ ? 1 : 0; } + uint32_t numActiveStreams() const override { return callbacks_ ? 1 : 0; } bool closingWithIncompleteStream() const override { return false; } uint64_t id() const override { return connection_->id(); } @@ -121,9 +121,10 @@ class ConnPoolImpl : public Envoy::ConnectionPool::ConnPoolImplBase, ConnPoolImpl(Event::Dispatcher& dispatcher, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - Network::TransportSocketOptionsSharedPtr transport_socket_options) + Network::TransportSocketOptionsSharedPtr transport_socket_options, + Upstream::ClusterConnectivityState& state) : Envoy::ConnectionPool::ConnPoolImplBase(host, priority, dispatcher, options, - transport_socket_options) {} + transport_socket_options, state) {} ~ConnPoolImpl() override { destructAllConnections(); } void addDrainedCallback(DrainedCb cb) override { addDrainedCallbackImpl(cb); } @@ -136,8 +137,8 @@ class ConnPoolImpl : public Envoy::ConnectionPool::ConnPoolImplBase, uint64_t old_limit = connecting_client->effectiveConcurrentStreamLimit(); connecting_client->remaining_streams_ = 1; if (connecting_client->effectiveConcurrentStreamLimit() < old_limit) { - connecting_stream_capacity_ -= - (old_limit - connecting_client->effectiveConcurrentStreamLimit()); + decrConnectingStreamCapacity(old_limit - + connecting_client->effectiveConcurrentStreamLimit()); } } } @@ -162,8 +163,7 @@ class ConnPoolImpl : public Envoy::ConnectionPool::ConnPoolImplBase, newPendingStream(Envoy::ConnectionPool::AttachContext& context) override { Envoy::ConnectionPool::PendingStreamPtr pending_stream = std::make_unique(*this, typedContext(context)); - LinkedList::moveIntoList(std::move(pending_stream), pending_streams_); - return pending_streams_.front().get(); + return addPendingStream(std::move(pending_stream)); } Upstream::HostDescriptionConstSharedPtr host() const override { diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index 3e816fc6e160..a4d53e9d6bab 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -1450,7 +1450,8 @@ ClusterManagerImpl::ThreadLocalClusterManagerImpl::ClusterEntry::connPool( return parent_.parent_.factory_.allocateConnPool( parent_.thread_local_dispatcher_, host, priority, upstream_protocol, !upstream_options->empty() ? upstream_options : nullptr, - have_transport_socket_options ? context->upstreamTransportSocketOptions() : nullptr); + have_transport_socket_options ? context->upstreamTransportSocketOptions() : nullptr, + parent_.cluster_manager_state_); }); if (pool.has_value()) { @@ -1499,7 +1500,8 @@ ClusterManagerImpl::ThreadLocalClusterManagerImpl::ClusterEntry::tcpConnPool( container.pools_[hash_key] = parent_.parent_.factory_.allocateTcpConnPool( parent_.thread_local_dispatcher_, host, priority, have_options ? context->downstreamConnection()->socketOptions() : nullptr, - have_transport_socket_options ? context->upstreamTransportSocketOptions() : nullptr); + have_transport_socket_options ? context->upstreamTransportSocketOptions() : nullptr, + parent_.cluster_manager_state_); } return container.pools_[hash_key].get(); @@ -1515,27 +1517,29 @@ ClusterManagerPtr ProdClusterManagerFactory::clusterManagerFromProto( Http::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateConnPool( Event::Dispatcher& dispatcher, HostConstSharedPtr host, ResourcePriority priority, Http::Protocol protocol, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) { + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + ClusterConnectivityState& state) { if (protocol == Http::Protocol::Http2 && runtime_.snapshot().featureEnabled("upstream.use_http2", 100)) { return Http::Http2::allocateConnPool(dispatcher, api_.randomGenerator(), host, priority, - options, transport_socket_options); + options, transport_socket_options, state); } else if (protocol == Http::Protocol::Http3) { // Quic connection pool is not implemented. NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } else { return Http::Http1::allocateConnPool(dispatcher, api_.randomGenerator(), host, priority, - options, transport_socket_options); + options, transport_socket_options, state); } } Tcp::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateTcpConnPool( Event::Dispatcher& dispatcher, HostConstSharedPtr host, ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - Network::TransportSocketOptionsSharedPtr transport_socket_options) { + Network::TransportSocketOptionsSharedPtr transport_socket_options, + ClusterConnectivityState& state) { if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.new_tcp_connection_pool")) { return std::make_unique(dispatcher, host, priority, options, - transport_socket_options); + transport_socket_options, state); } else { return Tcp::ConnectionPool::InstancePtr{new Tcp::OriginalConnPoolImpl( dispatcher, host, priority, options, transport_socket_options)}; diff --git a/source/common/upstream/cluster_manager_impl.h b/source/common/upstream/cluster_manager_impl.h index 837afe731a4e..0efef83108f7 100644 --- a/source/common/upstream/cluster_manager_impl.h +++ b/source/common/upstream/cluster_manager_impl.h @@ -60,15 +60,18 @@ class ProdClusterManagerFactory : public ClusterManagerFactory { // Upstream::ClusterManagerFactory ClusterManagerPtr clusterManagerFromProto(const envoy::config::bootstrap::v3::Bootstrap& bootstrap) override; - Http::ConnectionPool::InstancePtr allocateConnPool( - Event::Dispatcher& dispatcher, HostConstSharedPtr host, ResourcePriority priority, - Http::Protocol protocol, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) override; + Http::ConnectionPool::InstancePtr + allocateConnPool(Event::Dispatcher& dispatcher, HostConstSharedPtr host, + ResourcePriority priority, Http::Protocol protocol, + const Network::ConnectionSocket::OptionsSharedPtr& options, + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + ClusterConnectivityState& state) override; Tcp::ConnectionPool::InstancePtr allocateTcpConnPool(Event::Dispatcher& dispatcher, HostConstSharedPtr host, ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - Network::TransportSocketOptionsSharedPtr transport_socket_options) override; + Network::TransportSocketOptionsSharedPtr transport_socket_options, + ClusterConnectivityState& state) override; std::pair clusterFromProto(const envoy::config::cluster::v3::Cluster& cluster, ClusterManager& cm, Outlier::EventLoggerSharedPtr outlier_event_logger, bool added_via_api) override; @@ -431,6 +434,8 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggable thread_local_clusters_; + ClusterConnectivityState cluster_manager_state_; + // These maps are owned by the ThreadLocalClusterManagerImpl instead of the ClusterEntry // to prevent lifetime/ownership issues when a cluster is dynamically removed. absl::node_hash_map host_http_conn_pool_map_; @@ -545,8 +550,8 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggable prefetch_pool); + static void maybePrefetch(ThreadLocalClusterManagerImpl::ClusterEntryPtr& cluster_entry, + std::function prefetch_pool); ClusterManagerFactory& factory_; Runtime::Loader& runtime_; diff --git a/source/common/upstream/load_balancer_impl.cc b/source/common/upstream/load_balancer_impl.cc index f12085eea88d..da89730843f9 100644 --- a/source/common/upstream/load_balancer_impl.cc +++ b/source/common/upstream/load_balancer_impl.cc @@ -778,6 +778,7 @@ HostConstSharedPtr EdfLoadBalancerBase::peekAnotherHost(LoadBalancerContext* con if (!hosts_source) { return nullptr; } + auto scheduler_it = scheduler_.find(*hosts_source); // We should always have a scheduler for any return value from // hostSourceToUse() via the construction in refresh(); diff --git a/source/extensions/common/wasm/BUILD b/source/extensions/common/wasm/BUILD index e2a03e72fc0f..0f351b56b5bd 100644 --- a/source/extensions/common/wasm/BUILD +++ b/source/extensions/common/wasm/BUILD @@ -16,6 +16,16 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "wasm_runtime_factory_interface", + hdrs = [ + "wasm_runtime_factory.h", + ], + deps = [ + "@proxy_wasm_cpp_host//:include", + ], +) + # NB: Used to break the circular dependency between wasm_lib and null_plugin_lib. envoy_cc_library( name = "wasm_hdr", @@ -86,6 +96,7 @@ envoy_cc_library( deps = [ ":wasm_hdr", ":wasm_interoperation_lib", + ":wasm_runtime_factory_interface", "//external:abseil_base", "//external:abseil_node_hash_map", "//include/envoy/server:lifecycle_notifier_interface", @@ -107,7 +118,8 @@ envoy_cc_library( "@com_google_cel_cpp//eval/public:cel_value", "@com_google_cel_cpp//eval/public:value_export_util", "@envoy_api//envoy/extensions/wasm/v3:pkg_cc_proto", - "@proxy_wasm_cpp_host//:lib", + "@proxy_wasm_cpp_host//:common_lib", + "@proxy_wasm_cpp_host//:null_lib", ] + select( { "//bazel:windows_x86_64": [], diff --git a/source/extensions/common/wasm/context.cc b/source/extensions/common/wasm/context.cc index 006e7648c0e6..250d523cc78c 100644 --- a/source/extensions/common/wasm/context.cc +++ b/source/extensions/common/wasm/context.cc @@ -858,11 +858,7 @@ BufferInterface* Context::getBuffer(WasmBufferType type) { void Context::onDownstreamConnectionClose(CloseType close_type) { ContextBase::onDownstreamConnectionClose(close_type); downstream_closed_ = true; - // Call close on TCP connection, if upstream connection closed or there was a failure seen in - // this connection. - if (upstream_closed_ || getRequestStreamInfo()->hasAnyResponseFlag()) { - onCloseTCP(); - } + onCloseTCP(); } void Context::onUpstreamConnectionClose(CloseType close_type) { diff --git a/source/extensions/common/wasm/wasm_runtime_factory.h b/source/extensions/common/wasm/wasm_runtime_factory.h new file mode 100644 index 000000000000..d0d589705f91 --- /dev/null +++ b/source/extensions/common/wasm/wasm_runtime_factory.h @@ -0,0 +1,29 @@ +#pragma once + +#include "envoy/common/pure.h" + +#include "absl/strings/string_view.h" +#include "include/proxy-wasm/wasm_vm.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +using WasmVmPtr = std::unique_ptr; + +class WasmRuntimeFactory { +public: + virtual ~WasmRuntimeFactory() = default; + virtual WasmVmPtr createWasmVm() PURE; + + virtual absl::string_view name() PURE; + virtual absl::string_view shortName() PURE; + + std::string category() { return "envoy.wasm.runtime"; } +}; + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/common/wasm/wasm_vm.cc b/source/extensions/common/wasm/wasm_vm.cc index 5b482e6bb847..b7b8ec0c6734 100644 --- a/source/extensions/common/wasm/wasm_vm.cc +++ b/source/extensions/common/wasm/wasm_vm.cc @@ -6,21 +6,11 @@ #include "extensions/common/wasm/context.h" #include "extensions/common/wasm/ext/envoy_null_vm_wasm_api.h" #include "extensions/common/wasm/wasm_extension.h" +#include "extensions/common/wasm/wasm_runtime_factory.h" #include "extensions/common/wasm/well_known_names.h" -#include "include/proxy-wasm/null.h" #include "include/proxy-wasm/null_plugin.h" -#if defined(ENVOY_WASM_V8) -#include "include/proxy-wasm/v8.h" -#endif -#if defined(ENVOY_WASM_WAVM) -#include "include/proxy-wasm/wavm.h" -#endif -#if defined(ENVOY_WASM_WASMTIME) -#include "include/proxy-wasm/wasmtime.h" -#endif - using ContextBase = proxy_wasm::ContextBase; using Word = proxy_wasm::Word; @@ -70,36 +60,21 @@ WasmVmPtr createWasmVm(absl::string_view runtime, const Stats::ScopeSharedPtr& s ENVOY_LOG_TO_LOGGER(Envoy::Logger::Registry::getLog(Envoy::Logger::Id::wasm), warn, "Failed to create Wasm VM with unspecified runtime"); return nullptr; - } else if (runtime == WasmRuntimeNames::get().Null) { - auto wasm = proxy_wasm::createNullVm(); - wasm->integration() = getWasmExtension()->createEnvoyWasmVmIntegration(scope, runtime, "null"); - return wasm; -#if defined(ENVOY_WASM_V8) - } else if (runtime == WasmRuntimeNames::get().V8) { - auto wasm = proxy_wasm::createV8Vm(); - wasm->integration() = getWasmExtension()->createEnvoyWasmVmIntegration(scope, runtime, "v8"); - return wasm; -#endif -#if defined(ENVOY_WASM_WAVM) - } else if (runtime == WasmRuntimeNames::get().Wavm) { - auto wasm = proxy_wasm::createWavmVm(); - wasm->integration() = getWasmExtension()->createEnvoyWasmVmIntegration(scope, runtime, "wavm"); - return wasm; -#endif -#if defined(ENVOY_WASM_WASMTIME) - } else if (runtime == WasmRuntimeNames::get().Wasmtime) { - auto wasm = proxy_wasm::createWasmtimeVm(); - wasm->integration() = - getWasmExtension()->createEnvoyWasmVmIntegration(scope, runtime, "wasmtime"); - return wasm; -#endif - } else { + } + + auto runtime_factory = Registry::FactoryRegistry::getFactory(runtime); + if (runtime_factory == nullptr) { ENVOY_LOG_TO_LOGGER( Envoy::Logger::Registry::getLog(Envoy::Logger::Id::wasm), warn, "Failed to create Wasm VM using {} runtime. Envoy was compiled without support for it", runtime); return nullptr; } + + auto wasm = runtime_factory->createWasmVm(); + wasm->integration() = getWasmExtension()->createEnvoyWasmVmIntegration( + scope, runtime_factory->name(), runtime_factory->shortName()); + return wasm; } } // namespace Wasm diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 664b561fb0d2..8a48fb678264 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -214,8 +214,17 @@ EXTENSIONS = { # # Watchdog actions # + "envoy.watchdog.profile_action": "//source/extensions/watchdog/profile_action:config", + # + # WebAssembly runtimes + # + + "envoy.wasm.runtime.null": "//source/extensions/wasm_runtime/null:config", + "envoy.wasm.runtime.v8": "//source/extensions/wasm_runtime/v8:config", + "envoy.wasm.runtime.wavm": "//source/extensions/wasm_runtime/wavm:config", + "envoy.wasm.runtime.wasmtime": "//source/extensions/wasm_runtime/wasmtime:config", } # These can be changed to ["//visibility:public"], for downstream builds which diff --git a/source/extensions/fatal_actions/README.md b/source/extensions/fatal_actions/README.md new file mode 100644 index 000000000000..d4ab098a4071 --- /dev/null +++ b/source/extensions/fatal_actions/README.md @@ -0,0 +1 @@ +Currently there are no fatal action extensions. diff --git a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc index e2998a3f5866..d770b9feb51a 100644 --- a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc +++ b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc @@ -188,6 +188,24 @@ JsonTranscoderConfig::JsonTranscoderConfig( } } + switch (proto_config.url_unescape_spec()) { + case envoy::extensions::filters::http::grpc_json_transcoder::v3::GrpcJsonTranscoder:: + ALL_CHARACTERS_EXCEPT_RESERVED: + pmb.SetUrlUnescapeSpec( + google::grpc::transcoding::UrlUnescapeSpec::kAllCharactersExceptReserved); + break; + case envoy::extensions::filters::http::grpc_json_transcoder::v3::GrpcJsonTranscoder:: + ALL_CHARACTERS_EXCEPT_SLASH: + pmb.SetUrlUnescapeSpec(google::grpc::transcoding::UrlUnescapeSpec::kAllCharactersExceptSlash); + break; + case envoy::extensions::filters::http::grpc_json_transcoder::v3::GrpcJsonTranscoder:: + ALL_CHARACTERS: + pmb.SetUrlUnescapeSpec(google::grpc::transcoding::UrlUnescapeSpec::kAllCharacters); + break; + default: + NOT_REACHED_GCOVR_EXCL_LINE; + } + path_matcher_ = pmb.Build(); const auto& print_config = proto_config.print_options(); diff --git a/source/extensions/filters/http/jwt_authn/authenticator.cc b/source/extensions/filters/http/jwt_authn/authenticator.cc index 1b73eeaf08b2..cf447f68bdaa 100644 --- a/source/extensions/filters/http/jwt_authn/authenticator.cc +++ b/source/extensions/filters/http/jwt_authn/authenticator.cc @@ -141,7 +141,7 @@ void AuthenticatorImpl::startVerify() { jwt_ = std::make_unique<::google::jwt_verify::Jwt>(); ENVOY_LOG(debug, "{}: Parse Jwt {}", name(), curr_token_->token()); - const Status status = jwt_->parseFromString(curr_token_->token()); + Status status = jwt_->parseFromString(curr_token_->token()); if (status != Status::Ok) { doneWithStatus(status); return; @@ -163,33 +163,23 @@ void AuthenticatorImpl::startVerify() { } } - // TODO(qiwzhang): Cross-platform-wise the below unix_timestamp code is wrong as the - // epoch is not guaranteed to be defined as the unix epoch. We should use - // the abseil time functionality instead or use the jwt_verify_lib to check - // the validity of a JWT. - // Check "exp" claim. - const uint64_t unix_timestamp = - std::chrono::duration_cast(timeSource().systemTime().time_since_epoch()) - .count(); - // If the nbf claim does *not* appear in the JWT, then the nbf field is defaulted - // to 0. - if (jwt_->nbf_ > unix_timestamp) { - doneWithStatus(Status::JwtNotYetValid); - return; - } - // If the exp claim does *not* appear in the JWT then the exp field is defaulted - // to 0. - if (jwt_->exp_ > 0 && jwt_->exp_ < unix_timestamp) { - doneWithStatus(Status::JwtExpired); - return; - } - // Check the issuer is configured or not. jwks_data_ = provider_ ? jwks_cache_.findByProvider(provider_.value()) : jwks_cache_.findByIssuer(jwt_->iss_); // isIssuerSpecified() check already make sure the issuer is in the cache. ASSERT(jwks_data_ != nullptr); + // Default is 60 seconds + uint64_t clock_skew_seconds = ::google::jwt_verify::kClockSkewInSecond; + if (jwks_data_->getJwtProvider().clock_skew_seconds() > 0) { + clock_skew_seconds = jwks_data_->getJwtProvider().clock_skew_seconds(); + } + status = jwt_->verifyTimeConstraint(absl::ToUnixSeconds(absl::Now()), clock_skew_seconds); + if (status != Status::Ok) { + doneWithStatus(status); + return; + } + // Check if audience is allowed bool is_allowed = check_audience_ ? check_audience_->areAudiencesAllowed(jwt_->audiences_) : jwks_data_->areAudiencesAllowed(jwt_->audiences_); @@ -247,7 +237,8 @@ void AuthenticatorImpl::onDestroy() { // Verify with a specific public key. void AuthenticatorImpl::verifyKey() { - const Status status = ::google::jwt_verify::verifyJwt(*jwt_, *jwks_data_->getJwksObj()); + const Status status = + ::google::jwt_verify::verifyJwtWithoutTimeChecking(*jwt_, *jwks_data_->getJwksObj()); if (status != Status::Ok) { doneWithStatus(status); return; diff --git a/source/extensions/filters/http/lua/wrappers.h b/source/extensions/filters/http/lua/wrappers.h index bf19843dd8d1..ba4170dbfaaa 100644 --- a/source/extensions/filters/http/lua/wrappers.h +++ b/source/extensions/filters/http/lua/wrappers.h @@ -222,7 +222,10 @@ class StreamInfoWrapper : public Filters::Common::Lua::BaseLuaObject dynamic_metadata_wrapper_; diff --git a/source/extensions/filters/http/oauth2/config.cc b/source/extensions/filters/http/oauth2/config.cc index d51d798874e5..8dac7db7d3de 100644 --- a/source/extensions/filters/http/oauth2/config.cc +++ b/source/extensions/filters/http/oauth2/config.cc @@ -36,6 +36,7 @@ secretsProvider(const envoy::extensions::transport_sockets::tls::v3::SdsSecretCo return secret_manager.findStaticGenericSecretProvider(config.name()); } } + } // namespace Http::FilterFactoryCb OAuth2Config::createFilterFactoryFromProtoTyped( diff --git a/source/extensions/filters/http/oauth2/filter.cc b/source/extensions/filters/http/oauth2/filter.cc index cfd341828b29..92ec0dc030fa 100644 --- a/source/extensions/filters/http/oauth2/filter.cc +++ b/source/extensions/filters/http/oauth2/filter.cc @@ -48,7 +48,7 @@ constexpr const char* CookieTailHttpOnlyFormatString = ";version=1;path=/;Max-Age={};secure;HttpOnly"; const char* AuthorizationEndpointFormat = - "{}?client_id={}&scope=user&response_type=code&redirect_uri={}&state={}"; + "{}?client_id={}&scope={}&response_type=code&redirect_uri={}&state={}"; constexpr absl::string_view UnauthorizedBodyMessage = "OAuth flow failed."; @@ -60,6 +60,7 @@ constexpr absl::string_view REDIRECT_RACE = "oauth.race_redirect"; constexpr absl::string_view REDIRECT_LOGGED_IN = "oauth.logged_in"; constexpr absl::string_view REDIRECT_FOR_CREDENTIALS = "oauth.missing_credentials"; constexpr absl::string_view SIGN_OUT = "oauth.sign_out"; +constexpr absl::string_view DEFAULT_AUTH_SCOPE = "user"; template std::vector headerMatchers(const T& matcher_protos) { @@ -73,6 +74,27 @@ std::vector headerMatchers(const T& matcher_pro return matchers; } +// Transforms the proto list of 'auth_scopes' into a vector of std::string, also +// handling the default value logic +template +std::vector authScopesList(const T& auth_scopes_protos) { + std::vector scopes; + + // if 'auth_scopes_protos' is zero sized, it means the list is empty in the yaml, + // then it should default to a list of single value + if (auth_scopes_protos.size() == 0) { + scopes.reserve(1); + scopes.emplace_back(DEFAULT_AUTH_SCOPE); + } else { + scopes.reserve(auth_scopes_protos.size()); + + for (const auto& scope : auth_scopes_protos) { + scopes.emplace_back(scope); + } + } + return scopes; +} + // Sets the auth token as the Bearer token in the authorization header. void setBearerToken(Http::RequestHeaderMap& headers, const std::string& token) { headers.setInline(authorization_handle.handle(), absl::StrCat("Bearer ", token)); @@ -90,6 +112,7 @@ FilterConfig::FilterConfig( redirect_matcher_(proto_config.redirect_path_matcher()), signout_path_(proto_config.signout_path()), secret_reader_(secret_reader), stats_(FilterConfig::generateStats(stats_prefix, scope)), + auth_scopes_(authScopesList(proto_config.auth_scopes())), forward_bearer_token_(proto_config.forward_bearer_token()), pass_through_header_matchers_(headerMatchers(proto_config.pass_through_matcher())) { if (!cluster_manager.get(oauth_token_endpoint_.cluster())) { @@ -275,9 +298,11 @@ Http::FilterHeadersStatus OAuth2Filter::decodeHeaders(Http::RequestHeaderMap& he const std::string escaped_redirect_uri = Http::Utility::PercentEncoding::encode(redirect_uri, ":/=&?"); + const std::string escaped_auth_scopes = absl::StrJoin(config_->authScopes(), "%20"); + const std::string new_url = fmt::format(AuthorizationEndpointFormat, config_->authorizationEndpoint(), - config_->clientId(), escaped_redirect_uri, escaped_state); + config_->clientId(), escaped_auth_scopes, escaped_redirect_uri, escaped_state); response_headers->setLocation(new_url); decoder_callbacks_->encodeHeaders(std::move(response_headers), true, REDIRECT_FOR_CREDENTIALS); diff --git a/source/extensions/filters/http/oauth2/filter.h b/source/extensions/filters/http/oauth2/filter.h index eae64214ee09..c3496db6df5f 100644 --- a/source/extensions/filters/http/oauth2/filter.h +++ b/source/extensions/filters/http/oauth2/filter.h @@ -123,6 +123,7 @@ class FilterConfig { std::string clientSecret() const { return secret_reader_->clientSecret(); } std::string tokenSecret() const { return secret_reader_->tokenSecret(); } FilterStats& stats() { return stats_; } + const std::vector& authScopes() const { return auth_scopes_; } private: static FilterStats generateStats(const std::string& prefix, Stats::Scope& scope); @@ -135,6 +136,7 @@ class FilterConfig { const Matchers::PathMatcher signout_path_; std::shared_ptr secret_reader_; FilterStats stats_; + const std::vector auth_scopes_; const bool forward_bearer_token_ : 1; const std::vector pass_through_header_matchers_; }; diff --git a/source/extensions/filters/http/oauth2/oauth_client.cc b/source/extensions/filters/http/oauth2/oauth_client.cc index 71db1ce74020..9e7f4021b3b9 100644 --- a/source/extensions/filters/http/oauth2/oauth_client.cc +++ b/source/extensions/filters/http/oauth2/oauth_client.cc @@ -66,6 +66,7 @@ void OAuth2ClientImpl::onSuccess(const Http::AsyncClient::Request&, const auto response_code = message->headers().Status()->value().getStringView(); if (response_code != "200") { ENVOY_LOG(debug, "Oauth response code: {}", response_code); + ENVOY_LOG(debug, "Oauth response body: {}", message->bodyAsString()); parent_->sendUnauthorizedResponse(); return; } diff --git a/source/extensions/filters/network/mongo_proxy/proxy.cc b/source/extensions/filters/network/mongo_proxy/proxy.cc index b8ee760c910b..789d6e8df91d 100644 --- a/source/extensions/filters/network/mongo_proxy/proxy.cc +++ b/source/extensions/filters/network/mongo_proxy/proxy.cc @@ -366,11 +366,11 @@ void ProxyFilter::onEvent(Network::ConnectionEvent event) { } if (event == Network::ConnectionEvent::RemoteClose && !active_query_list_.empty()) { - stats_.cx_destroy_local_with_active_rq_.inc(); + stats_.cx_destroy_remote_with_active_rq_.inc(); } if (event == Network::ConnectionEvent::LocalClose && !active_query_list_.empty()) { - stats_.cx_destroy_remote_with_active_rq_.inc(); + stats_.cx_destroy_local_with_active_rq_.inc(); } } diff --git a/source/extensions/quic_listeners/quiche/BUILD b/source/extensions/quic_listeners/quiche/BUILD index 29eb78d155e1..a90cfde6ddc6 100644 --- a/source/extensions/quic_listeners/quiche/BUILD +++ b/source/extensions/quic_listeners/quiche/BUILD @@ -212,6 +212,7 @@ envoy_cc_library( "//source/common/buffer:buffer_lib", "//source/common/common:assert_lib", "//source/common/http:header_map_lib", + "//source/common/http:header_utility_lib", "//source/extensions/quic_listeners/quiche/platform:quic_platform_mem_slice_storage_impl_lib", "@com_googlesource_quiche//:quic_core_http_client_lib", ], diff --git a/source/extensions/quic_listeners/quiche/active_quic_listener.cc b/source/extensions/quic_listeners/quiche/active_quic_listener.cc index f4808adc52b0..86bb75a2ed51 100644 --- a/source/extensions/quic_listeners/quiche/active_quic_listener.cc +++ b/source/extensions/quic_listeners/quiche/active_quic_listener.cc @@ -55,7 +55,7 @@ ActiveQuicListener::ActiveQuicListener( quic::QuicRandom* const random = quic::QuicRandom::GetInstance(); random->RandBytes(random_seed_, sizeof(random_seed_)); crypto_config_ = std::make_unique( - quiche::QuicheStringPiece(reinterpret_cast(random_seed_), sizeof(random_seed_)), + absl::string_view(reinterpret_cast(random_seed_), sizeof(random_seed_)), quic::QuicRandom::GetInstance(), std::make_unique(listen_socket_, listener_config.filterChainManager(), stats_), @@ -110,11 +110,11 @@ void ActiveQuicListener::onDataWorker(Network::UdpRecvData&& data) { quic::QuicTime::Delta::FromMicroseconds(std::chrono::duration_cast( data.receive_time_.time_since_epoch()) .count()); - ASSERT(data.buffer_->getRawSlices().size() == 1); - Buffer::RawSliceVector slices = data.buffer_->getRawSlices(/*max_slices=*/1); + Buffer::RawSlice slice = data.buffer_->frontSlice(); + ASSERT(data.buffer_->length() == slice.len_); // TODO(danzh): pass in TTL and UDP header. - quic::QuicReceivedPacket packet(reinterpret_cast(slices[0].mem_), slices[0].len_, - timestamp, /*owns_buffer=*/false, /*ttl=*/0, /*ttl_valid=*/false, + quic::QuicReceivedPacket packet(reinterpret_cast(slice.mem_), slice.len_, timestamp, + /*owns_buffer=*/false, /*ttl=*/0, /*ttl_valid=*/false, /*packet_headers=*/nullptr, /*headers_length=*/0, /*owns_header_buffer*/ false); quic_dispatcher_->ProcessPacket(self_address, peer_address, packet); diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc index b92a77147e91..63783ee08e35 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc @@ -43,7 +43,7 @@ EnvoyQuicClientConnection::EnvoyQuicClientConnection( const quic::ParsedQuicVersionVector& supported_versions, Event::Dispatcher& dispatcher, Network::ConnectionSocketPtr&& connection_socket) : EnvoyQuicConnection( - server_connection_id, + server_connection_id, quic::QuicSocketAddress(), envoyIpAddressToQuicSocketAddress(connection_socket->remoteAddress()->ip()), helper, alarm_factory, writer, owns_writer, quic::Perspective::IS_CLIENT, supported_versions, std::move(connection_socket)), @@ -62,9 +62,9 @@ void EnvoyQuicClientConnection::processPacket( std::chrono::duration_cast(receive_time.time_since_epoch()) .count()); ASSERT(buffer->getRawSlices().size() == 1); - Buffer::RawSliceVector slices = buffer->getRawSlices(/*max_slices=*/1); - quic::QuicReceivedPacket packet(reinterpret_cast(slices[0].mem_), slices[0].len_, - timestamp, /*owns_buffer=*/false, /*ttl=*/0, /*ttl_valid=*/false, + Buffer::RawSlice slice = buffer->frontSlice(); + quic::QuicReceivedPacket packet(reinterpret_cast(slice.mem_), slice.len_, timestamp, + /*owns_buffer=*/false, /*ttl=*/0, /*ttl_valid=*/false, /*packet_headers=*/nullptr, /*headers_length=*/0, /*owns_header_buffer*/ false); ProcessUdpPacket(envoyIpAddressToQuicSocketAddress(local_address->ip()), diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc index b52b411df7e7..79e442ea8628 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc @@ -20,6 +20,7 @@ #include "common/buffer/buffer_impl.h" #include "common/http/header_map_impl.h" +#include "common/http/header_utility.h" #include "common/common/assert.h" namespace Envoy { @@ -48,6 +49,10 @@ EnvoyQuicClientStream::EnvoyQuicClientStream(quic::PendingStream* pending, Http::Status EnvoyQuicClientStream::encodeHeaders(const Http::RequestHeaderMap& headers, bool end_stream) { + // Required headers must be present. This can only happen by some erroneous processing after the + // downstream codecs decode. + RETURN_IF_ERROR(Http::HeaderUtility::checkRequiredHeaders(headers)); + ENVOY_STREAM_LOG(debug, "encodeHeaders: (end_stream={}) {}.", *this, end_stream, headers); quic::QuicStream* writing_stream = quic::VersionUsesHttp3(transport_version()) @@ -67,6 +72,10 @@ Http::Status EnvoyQuicClientStream::encodeHeaders(const Http::RequestHeaderMap& void EnvoyQuicClientStream::encodeData(Buffer::Instance& data, bool end_stream) { ENVOY_STREAM_LOG(debug, "encodeData (end_stream={}) of {} bytes.", *this, end_stream, data.length()); + if (data.length() == 0 && !end_stream) { + return; + } + ASSERT(!local_end_stream_); local_end_stream_ = end_stream; // This is counting not serialized bytes in the send buffer. const uint64_t bytes_to_send_old = BufferedDataBytes(); @@ -107,8 +116,6 @@ void EnvoyQuicClientStream::encodeMetadata(const Http::MetadataMapVector& /*meta } void EnvoyQuicClientStream::resetStream(Http::StreamResetReason reason) { - // Higher layers expect calling resetStream() to immediately raise reset callbacks. - runResetCallbacks(reason); Reset(envoyResetReasonToQuicRstError(reason)); } @@ -125,13 +132,15 @@ void EnvoyQuicClientStream::switchStreamBlockState(bool should_block) { void EnvoyQuicClientStream::OnInitialHeadersComplete(bool fin, size_t frame_len, const quic::QuicHeaderList& header_list) { - quic::QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list); if (rst_sent()) { return; } - ASSERT(headers_decompressed()); + quic::QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list); + ASSERT(headers_decompressed() && !header_list.empty()); + response_decoder_->decodeHeaders( - quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); + quicHeadersToEnvoyHeaders(header_list), + /*end_stream=*/fin); if (fin) { end_stream_decoded_ = true; } @@ -160,18 +169,17 @@ void EnvoyQuicClientStream::OnBodyAvailable() { buffer->commit(&slice, 1); MarkConsumed(bytes_read); } + ASSERT(buffer->length() == 0 || !end_stream_decoded_); - // True if no trailer and FIN read. - bool finished_reading = IsDoneReading(); - bool empty_payload_with_fin = buffer->length() == 0 && fin_received(); + bool fin_read_and_no_trailers = IsDoneReading(); // If this call is triggered by an empty frame with FIN which is not from peer // but synthesized by stream itself upon receiving HEADERS with FIN or // TRAILERS, do not deliver end of stream here. Because either decodeHeaders // already delivered it or decodeTrailers will be called. - bool skip_decoding = empty_payload_with_fin && (end_stream_decoded_ || !finished_reading); + bool skip_decoding = (buffer->length() == 0 && !fin_read_and_no_trailers) || end_stream_decoded_; if (!skip_decoding) { - response_decoder_->decodeData(*buffer, finished_reading); - if (finished_reading) { + response_decoder_->decodeData(*buffer, fin_read_and_no_trailers); + if (fin_read_and_no_trailers) { end_stream_decoded_ = true; } } @@ -186,14 +194,10 @@ void EnvoyQuicClientStream::OnBodyAvailable() { return; } - if (!quic::VersionUsesHttp3(transport_version()) && !FinishedReadingTrailers()) { - // For Google QUIC implementation, trailers may arrived earlier and wait to - // be consumed after reading all the body. Consume it here. - // IETF QUIC shouldn't reach here because trailers are sent on same stream. - response_decoder_->decodeTrailers( - spdyHeaderBlockToEnvoyHeaders(received_trailers())); - MarkTrailersConsumed(); - } + // Trailers may arrived earlier and wait to be consumed after reading all the body. Consume it + // here. + maybeDecodeTrailers(); + OnFinRead(); in_decode_data_callstack_ = false; } @@ -202,20 +206,31 @@ void EnvoyQuicClientStream::OnTrailingHeadersComplete(bool fin, size_t frame_len const quic::QuicHeaderList& header_list) { quic::QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list); ASSERT(trailers_decompressed()); - if (session()->connection()->connected() && - (quic::VersionUsesHttp3(transport_version()) || sequencer()->IsClosed()) && - !FinishedReadingTrailers()) { - // Before QPack, trailers can arrive before body. Only decode trailers after finishing decoding - // body. + if (session()->connection()->connected() && !rst_sent()) { + maybeDecodeTrailers(); + } +} + +void EnvoyQuicClientStream::maybeDecodeTrailers() { + if (sequencer()->IsClosed() && !FinishedReadingTrailers()) { + ASSERT(!received_trailers().empty()); + // Only decode trailers after finishing decoding body. response_decoder_->decodeTrailers( spdyHeaderBlockToEnvoyHeaders(received_trailers())); + end_stream_decoded_ = true; MarkTrailersConsumed(); } } void EnvoyQuicClientStream::OnStreamReset(const quic::QuicRstStreamFrame& frame) { quic::QuicSpdyClientStream::OnStreamReset(frame); - runResetCallbacks(quicRstErrorToEnvoyResetReason(frame.error_code)); + runResetCallbacks(quicRstErrorToEnvoyRemoteResetReason(frame.error_code)); +} + +void EnvoyQuicClientStream::Reset(quic::QuicRstStreamErrorCode error) { + // Upper layers expect calling resetStream() to immediately raise reset callbacks. + runResetCallbacks(quicRstErrorToEnvoyLocalResetReason(error)); + quic::QuicSpdyClientStream::Reset(error); } void EnvoyQuicClientStream::OnConnectionClosed(quic::QuicErrorCode error, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h index 2446fbb0c3e9..2702b5f8fe79 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h @@ -46,6 +46,7 @@ class EnvoyQuicClientStream : public quic::QuicSpdyClientStream, // quic::QuicSpdyStream void OnBodyAvailable() override; void OnStreamReset(const quic::QuicRstStreamFrame& frame) override; + void Reset(quic::QuicRstStreamErrorCode error) override; void OnClose() override; void OnCanWrite() override; // quic::Stream @@ -67,6 +68,9 @@ class EnvoyQuicClientStream : public quic::QuicSpdyClientStream, private: QuicFilterManagerConnectionImpl* filterManagerConnection(); + // Deliver awaiting trailers if body has been delivered. + void maybeDecodeTrailers(); + Http::ResponseDecoder* response_decoder_{nullptr}; }; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_connection.cc b/source/extensions/quic_listeners/quiche/envoy_quic_connection.cc index dcc311a6eaac..d813dfe4badb 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_connection.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_connection.cc @@ -6,6 +6,7 @@ namespace Envoy { namespace Quic { EnvoyQuicConnection::EnvoyQuicConnection(const quic::QuicConnectionId& server_connection_id, + quic::QuicSocketAddress initial_self_address, quic::QuicSocketAddress initial_peer_address, quic::QuicConnectionHelperInterface& helper, quic::QuicAlarmFactory& alarm_factory, @@ -13,8 +14,9 @@ EnvoyQuicConnection::EnvoyQuicConnection(const quic::QuicConnectionId& server_co quic::Perspective perspective, const quic::ParsedQuicVersionVector& supported_versions, Network::ConnectionSocketPtr&& connection_socket) - : quic::QuicConnection(server_connection_id, initial_peer_address, &helper, &alarm_factory, - writer, owns_writer, perspective, supported_versions), + : quic::QuicConnection(server_connection_id, initial_self_address, initial_peer_address, + &helper, &alarm_factory, writer, owns_writer, perspective, + supported_versions), connection_socket_(std::move(connection_socket)) {} EnvoyQuicConnection::~EnvoyQuicConnection() { connection_socket_->close(); } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_connection.h b/source/extensions/quic_listeners/quiche/envoy_quic_connection.h index f4c8589d7118..f8543bc938d7 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_connection.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_connection.h @@ -26,6 +26,7 @@ class EnvoyQuicConnection : public quic::QuicConnection, protected Logger::Loggable { public: EnvoyQuicConnection(const quic::QuicConnectionId& server_connection_id, + quic::QuicSocketAddress initial_self_address, quic::QuicSocketAddress initial_peer_address, quic::QuicConnectionHelperInterface& helper, quic::QuicAlarmFactory& alarm_factory, quic::QuicPacketWriter* writer, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc index ba8f7f3a8239..e6351f643653 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc @@ -48,11 +48,11 @@ void EnvoyQuicDispatcher::OnConnectionClosed(quic::QuicConnectionId connection_i } std::unique_ptr EnvoyQuicDispatcher::CreateQuicSession( - quic::QuicConnectionId server_connection_id, const quic::QuicSocketAddress& /*self_address*/, - const quic::QuicSocketAddress& peer_address, quiche::QuicheStringPiece /*alpn*/, + quic::QuicConnectionId server_connection_id, const quic::QuicSocketAddress& self_address, + const quic::QuicSocketAddress& peer_address, absl::string_view /*alpn*/, const quic::ParsedQuicVersion& version) { auto quic_connection = std::make_unique( - server_connection_id, peer_address, *helper(), *alarm_factory(), writer(), + server_connection_id, self_address, peer_address, *helper(), *alarm_factory(), writer(), /*owns_writer=*/false, quic::ParsedQuicVersionVector{version}, listen_socket_); auto quic_session = std::make_unique( config(), quic::ParsedQuicVersionVector{version}, std::move(quic_connection), this, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h index 589ff5327706..d59307f415ec 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h @@ -62,7 +62,7 @@ class EnvoyQuicDispatcher : public quic::QuicDispatcher { std::unique_ptr CreateQuicSession(quic::QuicConnectionId server_connection_id, const quic::QuicSocketAddress& self_address, - const quic::QuicSocketAddress& peer_address, quiche::QuicheStringPiece alpn, + const quic::QuicSocketAddress& peer_address, absl::string_view alpn, const quic::ParsedQuicVersion& version) override; private: diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.cc b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.cc index 1f65e4e7e6a0..967765829a28 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.cc @@ -36,7 +36,7 @@ EnvoyQuicProofSource::GetCertChain(const quic::QuicSocketAddress& server_address void EnvoyQuicProofSource::signPayload( const quic::QuicSocketAddress& server_address, const quic::QuicSocketAddress& client_address, - const std::string& hostname, uint16_t signature_algorithm, quiche::QuicheStringPiece in, + const std::string& hostname, uint16_t signature_algorithm, absl::string_view in, std::unique_ptr callback) { CertConfigWithFilterChain res = getTlsCertConfigAndFilterChain(server_address, client_address, hostname); diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.h b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.h index 6e1c74c9234c..e22bf3465f49 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source.h @@ -28,7 +28,7 @@ class EnvoyQuicProofSource : public EnvoyQuicProofSourceBase { // quic::ProofSource void signPayload(const quic::QuicSocketAddress& server_address, const quic::QuicSocketAddress& client_address, const std::string& hostname, - uint16_t signature_algorithm, quiche::QuicheStringPiece in, + uint16_t signature_algorithm, absl::string_view in, std::unique_ptr callback) override; private: diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.cc b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.cc index 2c82c04d901d..9ad3cb07f428 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.cc @@ -21,7 +21,7 @@ void EnvoyQuicProofSourceBase::GetProof(const quic::QuicSocketAddress& server_ad const std::string& hostname, const std::string& server_config, quic::QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr callback) { quic::QuicReferenceCountedPointer chain = GetCertChain(server_address, client_address, hostname); @@ -68,13 +68,12 @@ void EnvoyQuicProofSourceBase::GetProof(const quic::QuicSocketAddress& server_ad auto signature_callback = std::make_unique(std::move(callback), chain); signPayload(server_address, client_address, hostname, sign_alg, - quiche::QuicheStringPiece(payload.get(), payload_size), - std::move(signature_callback)); + absl::string_view(payload.get(), payload_size), std::move(signature_callback)); } void EnvoyQuicProofSourceBase::ComputeTlsSignature( const quic::QuicSocketAddress& server_address, const quic::QuicSocketAddress& client_address, - const std::string& hostname, uint16_t signature_algorithm, quiche::QuicheStringPiece in, + const std::string& hostname, uint16_t signature_algorithm, absl::string_view in, std::unique_ptr callback) { signPayload(server_address, client_address, hostname, signature_algorithm, in, std::move(callback)); diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.h b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.h index b7d76981e519..a9e7e8c3f094 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_proof_source_base.h @@ -57,7 +57,7 @@ class EnvoyQuicProofSourceBase : public quic::ProofSource, void GetProof(const quic::QuicSocketAddress& server_address, const quic::QuicSocketAddress& client_address, const std::string& hostname, const std::string& server_config, quic::QuicTransportVersion /*transport_version*/, - quiche::QuicheStringPiece chlo_hash, + absl::string_view chlo_hash, std::unique_ptr callback) override; TicketCrypter* GetTicketCrypter() override { return nullptr; } @@ -65,14 +65,14 @@ class EnvoyQuicProofSourceBase : public quic::ProofSource, void ComputeTlsSignature(const quic::QuicSocketAddress& server_address, const quic::QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr callback) override; protected: virtual void signPayload(const quic::QuicSocketAddress& server_address, const quic::QuicSocketAddress& client_address, const std::string& hostname, uint16_t signature_algorithm, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr callback) PURE; private: diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_base.cc b/source/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_base.cc index 229b3ab36628..e375905295a3 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_base.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_base.cc @@ -58,8 +58,8 @@ bool EnvoyQuicProofVerifierBase::verifySignature(const std::string& server_confi *error_details = "QuicPacketWriter error."; return false; } - bool valid = cert_view->VerifySignature(quiche::QuicheStringPiece(payload.get(), payload_size), - signature, sign_alg); + bool valid = cert_view->VerifySignature(absl::string_view(payload.get(), payload_size), signature, + sign_alg); if (!valid) { *error_details = "Signature is not valid."; } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.cc index b8fa94221f05..974c6c8ebc8c 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.cc @@ -11,11 +11,13 @@ namespace Quic { EnvoyQuicServerConnection::EnvoyQuicServerConnection( const quic::QuicConnectionId& server_connection_id, - quic::QuicSocketAddress initial_peer_address, quic::QuicConnectionHelperInterface& helper, - quic::QuicAlarmFactory& alarm_factory, quic::QuicPacketWriter* writer, bool owns_writer, + quic::QuicSocketAddress initial_self_address, quic::QuicSocketAddress initial_peer_address, + quic::QuicConnectionHelperInterface& helper, quic::QuicAlarmFactory& alarm_factory, + quic::QuicPacketWriter* writer, bool owns_writer, const quic::ParsedQuicVersionVector& supported_versions, Network::Socket& listen_socket) - : EnvoyQuicConnection(server_connection_id, initial_peer_address, helper, alarm_factory, writer, - owns_writer, quic::Perspective::IS_SERVER, supported_versions, + : EnvoyQuicConnection(server_connection_id, initial_self_address, initial_peer_address, helper, + alarm_factory, writer, owns_writer, quic::Perspective::IS_SERVER, + supported_versions, std::make_unique( // Wraps the real IoHandle instance so that if the connection socket // gets closed, the real IoHandle won't be affected. diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.h b/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.h index 7b7fac05e925..7625fad02d0b 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_connection.h @@ -10,6 +10,7 @@ namespace Quic { class EnvoyQuicServerConnection : public EnvoyQuicConnection { public: EnvoyQuicServerConnection(const quic::QuicConnectionId& server_connection_id, + quic::QuicSocketAddress initial_self_address, quic::QuicSocketAddress initial_peer_address, quic::QuicConnectionHelperInterface& helper, quic::QuicAlarmFactory& alarm_factory, quic::QuicPacketWriter* writer, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc index d5e5726bf369..c7d25b8d47da 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc @@ -84,6 +84,10 @@ void EnvoyQuicServerStream::encodeHeaders(const Http::ResponseHeaderMap& headers void EnvoyQuicServerStream::encodeData(Buffer::Instance& data, bool end_stream) { ENVOY_STREAM_LOG(debug, "encodeData (end_stream={}) of {} bytes.", *this, end_stream, data.length()); + if (data.length() == 0 && !end_stream) { + return; + } + ASSERT(!local_end_stream_); local_end_stream_ = end_stream; // This is counting not serialized bytes in the send buffer. const uint64_t bytes_to_send_old = BufferedDataBytes(); @@ -121,8 +125,6 @@ void EnvoyQuicServerStream::encodeMetadata(const Http::MetadataMapVector& /*meta } void EnvoyQuicServerStream::resetStream(Http::StreamResetReason reason) { - // Upper layers expect calling resetStream() to immediately raise reset callbacks. - runResetCallbacks(reason); if (local_end_stream_ && !reading_stopped()) { // This is after 200 early response. Reset with QUIC_STREAM_NO_ERROR instead // of propagating original reset reason. In QUICHE if a stream stops reading @@ -146,10 +148,17 @@ void EnvoyQuicServerStream::switchStreamBlockState(bool should_block) { void EnvoyQuicServerStream::OnInitialHeadersComplete(bool fin, size_t frame_len, const quic::QuicHeaderList& header_list) { + // TODO(danzh) Fix in QUICHE. If the stream has been reset in the call stack, + // OnInitialHeadersComplete() shouldn't be called. + if (rst_sent()) { + return; + } quic::QuicSpdyServerStreamBase::OnInitialHeadersComplete(fin, frame_len, header_list); - ASSERT(headers_decompressed()); + ASSERT(headers_decompressed() && !header_list.empty()); + request_decoder_->decodeHeaders( - quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); + quicHeadersToEnvoyHeaders(header_list), + /*end_stream=*/fin); if (fin) { end_stream_decoded_ = true; } @@ -179,17 +188,15 @@ void EnvoyQuicServerStream::OnBodyAvailable() { MarkConsumed(bytes_read); } - // True if no trailer and FIN read. - bool finished_reading = IsDoneReading(); - bool empty_payload_with_fin = buffer->length() == 0 && fin_received(); + bool fin_read_and_no_trailers = IsDoneReading(); // If this call is triggered by an empty frame with FIN which is not from peer // but synthesized by stream itself upon receiving HEADERS with FIN or // TRAILERS, do not deliver end of stream here. Because either decodeHeaders // already delivered it or decodeTrailers will be called. - bool skip_decoding = empty_payload_with_fin && (end_stream_decoded_ || !finished_reading); + bool skip_decoding = (buffer->length() == 0 && !fin_read_and_no_trailers) || end_stream_decoded_; if (!skip_decoding) { - request_decoder_->decodeData(*buffer, finished_reading); - if (finished_reading) { + request_decoder_->decodeData(*buffer, fin_read_and_no_trailers); + if (fin_read_and_no_trailers) { end_stream_decoded_ = true; } } @@ -204,14 +211,10 @@ void EnvoyQuicServerStream::OnBodyAvailable() { return; } - if (!quic::VersionUsesHttp3(transport_version()) && !FinishedReadingTrailers()) { - // For Google QUIC implementation, trailers may arrived earlier and wait to - // be consumed after reading all the body. Consume it here. - // IETF QUIC shouldn't reach here because trailers are sent on same stream. - request_decoder_->decodeTrailers( - spdyHeaderBlockToEnvoyHeaders(received_trailers())); - MarkTrailersConsumed(); - } + // Trailers may arrived earlier and wait to be consumed after reading all the body. Consume it + // here. + maybeDecodeTrailers(); + OnFinRead(); in_decode_data_callstack_ = false; } @@ -219,20 +222,32 @@ void EnvoyQuicServerStream::OnBodyAvailable() { void EnvoyQuicServerStream::OnTrailingHeadersComplete(bool fin, size_t frame_len, const quic::QuicHeaderList& header_list) { quic::QuicSpdyServerStreamBase::OnTrailingHeadersComplete(fin, frame_len, header_list); - if (session()->connection()->connected() && - (quic::VersionUsesHttp3(transport_version()) || sequencer()->IsClosed()) && - !FinishedReadingTrailers()) { - // Before QPack trailers can arrive before body. Only decode trailers after finishing decoding - // body. + ASSERT(trailers_decompressed()); + if (session()->connection()->connected() && !rst_sent()) { + maybeDecodeTrailers(); + } +} + +void EnvoyQuicServerStream::maybeDecodeTrailers() { + if (sequencer()->IsClosed() && !FinishedReadingTrailers()) { + ASSERT(!received_trailers().empty()); + // Only decode trailers after finishing decoding body. request_decoder_->decodeTrailers( spdyHeaderBlockToEnvoyHeaders(received_trailers())); + end_stream_decoded_ = true; MarkTrailersConsumed(); } } void EnvoyQuicServerStream::OnStreamReset(const quic::QuicRstStreamFrame& frame) { quic::QuicSpdyServerStreamBase::OnStreamReset(frame); - runResetCallbacks(quicRstErrorToEnvoyResetReason(frame.error_code)); + runResetCallbacks(quicRstErrorToEnvoyRemoteResetReason(frame.error_code)); +} + +void EnvoyQuicServerStream::Reset(quic::QuicRstStreamErrorCode error) { + // Upper layers expect calling resetStream() to immediately raise reset callbacks. + runResetCallbacks(quicRstErrorToEnvoyLocalResetReason(error)); + quic::QuicSpdyServerStreamBase::Reset(error); } void EnvoyQuicServerStream::OnConnectionClosed(quic::QuicErrorCode error, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h index b05a707751ff..acd4138db398 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h @@ -49,9 +49,10 @@ class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, // quic::QuicSpdyStream void OnBodyAvailable() override; void OnStreamReset(const quic::QuicRstStreamFrame& frame) override; + void Reset(quic::QuicRstStreamErrorCode error) override; void OnClose() override; void OnCanWrite() override; - // quic::QuicServerSessionBase + // quic::QuicSpdyServerStreamBase void OnConnectionClosed(quic::QuicErrorCode error, quic::ConnectionCloseSource source) override; protected: @@ -69,6 +70,9 @@ class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, private: QuicFilterManagerConnectionImpl* filterManagerConnection(); + // Deliver awaiting trailers if body has been delivered. + void maybeDecodeTrailers(); + Http::RequestDecoder* request_decoder_{nullptr}; }; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc b/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc index 473c01e617d6..bd0a8a657ccd 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc @@ -65,20 +65,32 @@ quic::QuicRstStreamErrorCode envoyResetReasonToQuicRstError(Http::StreamResetRea case Http::StreamResetReason::LocalRefusedStreamReset: return quic::QUIC_REFUSED_STREAM; case Http::StreamResetReason::ConnectionFailure: + case Http::StreamResetReason::ConnectionTermination: return quic::QUIC_STREAM_CONNECTION_ERROR; case Http::StreamResetReason::LocalReset: return quic::QUIC_STREAM_CANCELLED; - case Http::StreamResetReason::ConnectionTermination: - return quic::QUIC_STREAM_NO_ERROR; default: return quic::QUIC_BAD_APPLICATION_PAYLOAD; } } -Http::StreamResetReason quicRstErrorToEnvoyResetReason(quic::QuicRstStreamErrorCode rst_err) { +Http::StreamResetReason quicRstErrorToEnvoyLocalResetReason(quic::QuicRstStreamErrorCode rst_err) { + switch (rst_err) { + case quic::QUIC_REFUSED_STREAM: + return Http::StreamResetReason::LocalRefusedStreamReset; + case quic::QUIC_STREAM_CONNECTION_ERROR: + return Http::StreamResetReason::ConnectionFailure; + default: + return Http::StreamResetReason::LocalReset; + } +} + +Http::StreamResetReason quicRstErrorToEnvoyRemoteResetReason(quic::QuicRstStreamErrorCode rst_err) { switch (rst_err) { case quic::QUIC_REFUSED_STREAM: return Http::StreamResetReason::RemoteRefusedStreamReset; + case quic::QUIC_STREAM_CONNECTION_ERROR: + return Http::StreamResetReason::ConnectError; default: return Http::StreamResetReason::RemoteReset; } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_utils.h b/source/extensions/quic_listeners/quiche/envoy_quic_utils.h index 563e0960cbd9..3c29b28ef21f 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_utils.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_utils.h @@ -66,7 +66,10 @@ spdy::SpdyHeaderBlock envoyHeadersToSpdyHeaderBlock(const Http::HeaderMap& heade quic::QuicRstStreamErrorCode envoyResetReasonToQuicRstError(Http::StreamResetReason reason); // Called when a RST_STREAM frame is received. -Http::StreamResetReason quicRstErrorToEnvoyResetReason(quic::QuicRstStreamErrorCode rst_err); +Http::StreamResetReason quicRstErrorToEnvoyLocalResetReason(quic::QuicRstStreamErrorCode rst_err); + +// Called when a QUIC stack reset the stream. +Http::StreamResetReason quicRstErrorToEnvoyRemoteResetReason(quic::QuicRstStreamErrorCode rst_err); // Called when underlying QUIC connection is closed either locally or by peer. Http::StreamResetReason quicErrorCodeToEnvoyResetReason(quic::QuicErrorCode error); diff --git a/source/extensions/quic_listeners/quiche/platform/BUILD b/source/extensions/quic_listeners/quiche/platform/BUILD index f53e07b58a33..839664d52f97 100644 --- a/source/extensions/quic_listeners/quiche/platform/BUILD +++ b/source/extensions/quic_listeners/quiche/platform/BUILD @@ -36,15 +36,16 @@ envoy_extension_package() envoy_cc_library( name = "flags_impl_lib", srcs = ["flags_impl.cc"], - hdrs = [ - "flags_impl.h", - "flags_list.h", - ], + hdrs = ["flags_impl.h"], external_deps = [ "abseil_base", "abseil_synchronization", ], visibility = ["//visibility:public"], + deps = [ + "@com_googlesource_quiche//:quic_core_flags_list_lib", + "@com_googlesource_quiche//:quic_core_protocol_flags_list_lib", + ], ) envoy_cc_library( @@ -62,7 +63,6 @@ envoy_cc_library( envoy_cc_library( name = "http2_platform_impl_lib", hdrs = [ - "http2_arraysize_impl.h", "http2_bug_tracker_impl.h", "http2_containers_impl.h", "http2_estimate_memory_usage_impl.h", @@ -74,7 +74,6 @@ envoy_cc_library( ], external_deps = [ "abseil_base", - "abseil_optional", "abseil_str_format", ], visibility = ["//visibility:public"], @@ -114,16 +113,13 @@ envoy_cc_library( "quic_mem_slice_impl.cc", ], hdrs = [ - "quic_aligned_impl.h", "quic_client_stats_impl.h", "quic_containers_impl.h", "quic_error_code_wrappers_impl.h", "quic_estimate_memory_usage_impl.h", - "quic_fallthrough_impl.h", "quic_flag_utils_impl.h", "quic_flags_impl.h", "quic_iovec_impl.h", - "quic_macros_impl.h", "quic_map_util_impl.h", "quic_mem_slice_impl.h", "quic_prefetch_impl.h", @@ -132,6 +128,7 @@ envoy_cc_library( "quic_server_stats_impl.h", "quic_stack_trace_impl.h", "quic_stream_buffer_allocator_impl.h", + "quic_testvalue_impl.h", "quic_uint128_impl.h", ], external_deps = [ @@ -141,7 +138,6 @@ envoy_cc_library( "abseil_memory", "abseil_node_hash_map", "abseil_node_hash_set", - "abseil_optional", ], tags = ["nofips"], visibility = ["//visibility:public"], @@ -236,6 +232,7 @@ envoy_cc_library( }), repository = "@envoy", tags = ["nofips"], + visibility = ["//visibility:public"], ) envoy_cc_library( @@ -250,23 +247,12 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "quiche_common_platform_optional_impl_lib", - hdrs = ["quiche_optional_impl.h"], - external_deps = [ - "abseil_node_hash_map", - ], - visibility = ["//visibility:public"], -) - envoy_cc_library( name = "quiche_common_platform_impl_lib", srcs = ["quiche_time_utils_impl.cc"], hdrs = [ - "quiche_arraysize_impl.h", "quiche_logging_impl.h", "quiche_map_util_impl.h", - "quiche_ptr_util_impl.h", "quiche_str_cat_impl.h", "quiche_string_piece_impl.h", "quiche_text_utils_impl.h", @@ -281,17 +267,14 @@ envoy_cc_library( deps = [ ":quic_platform_logging_impl_lib", ":string_utils_lib", - "@com_googlesource_quiche//:quiche_common_platform_optional", ], ) envoy_cc_library( name = "spdy_platform_impl_lib", hdrs = [ - "spdy_arraysize_impl.h", "spdy_bug_tracker_impl.h", "spdy_containers_impl.h", - "spdy_endianness_util_impl.h", "spdy_estimate_memory_usage_impl.h", "spdy_flags_impl.h", "spdy_logging_impl.h", @@ -331,14 +314,3 @@ envoy_cc_library( tags = ["nofips"], visibility = ["//visibility:public"], ) - -envoy_cc_library( - name = "quiche_common_platform_endian_impl_lib", - hdrs = ["quiche_endian_impl.h"], - tags = ["nofips"], - visibility = ["//visibility:public"], - deps = [ - "quiche_common_platform_export_impl_lib", - "//source/common/common:byte_order_lib", - ], -) diff --git a/source/extensions/quic_listeners/quiche/platform/flags_impl.cc b/source/extensions/quic_listeners/quiche/platform/flags_impl.cc index 70fb182d673d..9d4ea89ce3a6 100644 --- a/source/extensions/quic_listeners/quiche/platform/flags_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/flags_impl.cc @@ -15,12 +15,24 @@ namespace quiche { namespace { -absl::flat_hash_map MakeFlagMap() { +absl::flat_hash_map makeFlagMap() { absl::flat_hash_map flags; -#define QUICHE_FLAG(type, flag, value, help) flags.emplace(FLAGS_##flag->name(), FLAGS_##flag); -#include "extensions/quic_listeners/quiche/platform/flags_list.h" -#undef QUICHE_FLAG +#define QUIC_FLAG(flag, ...) flags.emplace(flag->name(), flag); +#include "quiche/quic/core/quic_flags_list.h" + QUIC_FLAG(FLAGS_quic_reloadable_flag_spdy_testonly_default_false, false) + QUIC_FLAG(FLAGS_quic_reloadable_flag_spdy_testonly_default_true, true) + QUIC_FLAG(FLAGS_quic_restart_flag_spdy_testonly_default_false, false) + QUIC_FLAG(FLAGS_quic_restart_flag_spdy_testonly_default_true, true) + QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_testonly_default_false, false) + QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_testonly_default_true, true) + QUIC_FLAG(FLAGS_quic_restart_flag_http2_testonly_default_false, false) + QUIC_FLAG(FLAGS_quic_restart_flag_http2_testonly_default_true, true) +#undef QUIC_FLAG + +#define QUIC_PROTOCOL_FLAG(type, flag, ...) flags.emplace(FLAGS_##flag->name(), FLAGS_##flag); +#include "quiche/quic/core/quic_protocol_flags_list.h" +#undef QUIC_PROTOCOL_FLAG return flags; } @@ -28,75 +40,123 @@ absl::flat_hash_map MakeFlagMap() { } // namespace // static -FlagRegistry& FlagRegistry::GetInstance() { +FlagRegistry& FlagRegistry::getInstance() { static auto* instance = new FlagRegistry(); return *instance; } -FlagRegistry::FlagRegistry() : flags_(MakeFlagMap()) {} +FlagRegistry::FlagRegistry() : flags_(makeFlagMap()) {} -void FlagRegistry::ResetFlags() const { +void FlagRegistry::resetFlags() const { for (auto& kv : flags_) { - kv.second->ResetValue(); + kv.second->resetValue(); } } -Flag* FlagRegistry::FindFlag(const std::string& name) const { +Flag* FlagRegistry::findFlag(const std::string& name) const { auto it = flags_.find(name); return (it != flags_.end()) ? it->second : nullptr; } -template <> bool TypedFlag::SetValueFromString(const std::string& value_str) { +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { static const auto* kTrueValues = new std::set({"1", "t", "true", "y", "yes"}); static const auto* kFalseValues = new std::set({"0", "f", "false", "n", "no"}); auto lower = absl::AsciiStrToLower(value_str); if (kTrueValues->find(lower) != kTrueValues->end()) { - SetValue(true); + setValue(true); return true; } if (kFalseValues->find(lower) != kFalseValues->end()) { - SetValue(false); + setValue(false); return true; } return false; } -template <> bool TypedFlag::SetValueFromString(const std::string& value_str) { +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { int32_t value; if (absl::SimpleAtoi(value_str, &value)) { - SetValue(value); + setValue(value); return true; } return false; } -template <> bool TypedFlag::SetValueFromString(const std::string& value_str) { +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { int64_t value; if (absl::SimpleAtoi(value_str, &value)) { - SetValue(value); + setValue(value); return true; } return false; } -template <> bool TypedFlag::SetValueFromString(const std::string& value_str) { +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { double value; if (absl::SimpleAtod(value_str, &value)) { - SetValue(value); + setValue(value); return true; } return false; } -template <> bool TypedFlag::SetValueFromString(const std::string& value_str) { - SetValue(value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { + setValue(value_str); return true; } +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { + unsigned long value; + if (absl::SimpleAtoi(value_str, &value)) { + setValue(value); + return true; + } + return false; +} + +template <> bool TypedFlag::setValueFromString(const std::string& value_str) { + unsigned long long value; + if (absl::SimpleAtoi(value_str, &value)) { + setValue(value); + return true; + } + return false; +} + // Flag definitions -#define QUICHE_FLAG(type, flag, value, help) \ - TypedFlag* FLAGS_##flag = new TypedFlag(#flag, value, help); -#include "extensions/quic_listeners/quiche/platform/flags_list.h" -#undef QUICHE_FLAG +#define QUIC_FLAG(flag, value) TypedFlag* flag = new TypedFlag(#flag, value, ""); +#include "quiche/quic/core/quic_flags_list.h" +QUIC_FLAG(FLAGS_quic_reloadable_flag_spdy_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_spdy_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_restart_flag_spdy_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_restart_flag_spdy_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_restart_flag_http2_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_restart_flag_http2_testonly_default_true, true) + +#undef QUIC_FLAG + +#define STRINGIFY(X) #X + +#define DEFINE_QUIC_PROTOCOL_FLAG_IMPL(type, flag, value, help) \ + TypedFlag* FLAGS_##flag = new TypedFlag(STRINGIFY(FLAGS_##flag), value, help); + +#define DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE(type, flag, value, doc) \ + DEFINE_QUIC_PROTOCOL_FLAG_IMPL(type, flag, value, doc) + +#define DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES(type, flag, internal_value, external_value, doc) \ + DEFINE_QUIC_PROTOCOL_FLAG_IMPL(type, flag, external_value, doc) + +// Select the right macro based on the number of arguments. +#define GET_6TH_ARG(arg1, arg2, arg3, arg4, arg5, arg6, ...) arg6 + +#define QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(...) \ + GET_6TH_ARG(__VA_ARGS__, DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES, \ + DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE) + +#define QUIC_PROTOCOL_FLAG(...) QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) +#include "quiche/quic/core/quic_protocol_flags_list.h" +#undef QUIC_PROTOCOL_FLAG } // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/flags_impl.h b/source/extensions/quic_listeners/quiche/platform/flags_impl.h index 5db939925510..83ed8430c07d 100644 --- a/source/extensions/quic_listeners/quiche/platform/flags_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/flags_impl.h @@ -26,13 +26,13 @@ class FlagRegistry { ~FlagRegistry() = default; // Return singleton instance. - static FlagRegistry& GetInstance(); + static FlagRegistry& getInstance(); // Reset all registered flags to their default values. - void ResetFlags() const; + void resetFlags() const; // Look up a flag by name. - Flag* FindFlag(const std::string& name) const; + Flag* findFlag(const std::string& name) const; private: FlagRegistry(); @@ -48,10 +48,10 @@ class Flag { virtual ~Flag() = default; // Set flag value from given string, returning true iff successful. - virtual bool SetValueFromString(const std::string& value_str) = 0; + virtual bool setValueFromString(const std::string& value_str) = 0; // Reset flag to default value. - virtual void ResetValue() = 0; + virtual void resetValue() = 0; // Return flag name. std::string name() const { return name_; } @@ -70,15 +70,15 @@ template class TypedFlag : public Flag { TypedFlag(const char* name, T default_value, const char* help) : Flag(name, help), value_(default_value), default_value_(default_value) {} - bool SetValueFromString(const std::string& value_str) override; + bool setValueFromString(const std::string& value_str) override; - void ResetValue() override { + void resetValue() override { absl::MutexLock lock(&mutex_); value_ = default_value_; } // Set flag value. - void SetValue(T value) { + void setValue(T value) { absl::MutexLock lock(&mutex_); value_ = value; } @@ -96,15 +96,29 @@ template class TypedFlag : public Flag { }; // SetValueFromString specializations -template <> bool TypedFlag::SetValueFromString(const std::string& value_str); -template <> bool TypedFlag::SetValueFromString(const std::string& value_str); -template <> bool TypedFlag::SetValueFromString(const std::string& value_str); -template <> bool TypedFlag::SetValueFromString(const std::string& value_str); -template <> bool TypedFlag::SetValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); +template <> bool TypedFlag::setValueFromString(const std::string& value_str); // Flag declarations -#define QUICHE_FLAG(type, flag, value, help) extern TypedFlag* FLAGS_##flag; -#include "extensions/quic_listeners/quiche/platform/flags_list.h" -#undef QUICHE_FLAG +#define QUIC_FLAG(flag, ...) extern TypedFlag* flag; +#include "quiche/quic/core/quic_flags_list.h" +QUIC_FLAG(FLAGS_quic_reloadable_flag_spdy_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_spdy_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_restart_flag_spdy_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_restart_flag_spdy_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_http2_testonly_default_true, true) +QUIC_FLAG(FLAGS_quic_restart_flag_http2_testonly_default_false, false) +QUIC_FLAG(FLAGS_quic_restart_flag_http2_testonly_default_true, true) +#undef QUIC_FLAG + +#define QUIC_PROTOCOL_FLAG(type, flag, ...) extern TypedFlag* FLAGS_##flag; +#include "quiche/quic/core/quic_protocol_flags_list.h" +#undef QUIC_PROTOCOL_FLAG } // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/flags_list.h b/source/extensions/quic_listeners/quiche/platform/flags_list.h deleted file mode 100644 index 52454caec0a2..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/flags_list.h +++ /dev/null @@ -1,502 +0,0 @@ -// This file intentionally does not have header guards. It is intended to be -// included multiple times, each time with a different definition of -// QUICHE_FLAG. - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -// This file is generated by //third_party/quic/tools:quic_flags_list in -// Google3. - -#if defined(QUICHE_FLAG) - -QUICHE_FLAG( - bool, http2_reloadable_flag_http2_backend_alpn_failure_error_code, false, - "If true, the GFE will return a new ResponseCodeDetails error when ALPN to the backend fails.") - -QUICHE_FLAG(bool, http2_reloadable_flag_http2_ip_based_cwnd_exp, true, - "If true, enable IP address based CWND bootstrapping experiment with different " - "bandwidth models and priorities in HTTP2.") - -QUICHE_FLAG( - bool, http2_reloadable_flag_http2_load_based_goaway_warning, false, - "If true, load-based connection closures will send a warning GOAWAY before the actual GOAWAY.") - -QUICHE_FLAG(bool, http2_reloadable_flag_http2_security_requirement_for_client3, false, - "If true, check whether client meets security requirements during SSL handshake. If " - "flag is true and client does not meet security requirements, do not negotiate HTTP/2 " - "with client or terminate the session with SPDY_INADEQUATE_SECURITY if HTTP/2 is " - "already negotiated. The spec contains both cipher and TLS version requirements.") - -QUICHE_FLAG(bool, http2_reloadable_flag_http2_websocket_detection, false, - "If true, uses a HTTP/2-specific method of detecting websocket upgrade requests.") - -QUICHE_FLAG(bool, http2_reloadable_flag_permissive_http2_switch, false, - "If true, the GFE allows both HTTP/1.0 and HTTP/1.1 versions in HTTP/2 upgrade " - "requests/responses.") - -QUICHE_FLAG(bool, quic_reloadable_flag_advertise_quic_for_https_for_debugips, false, "") - -QUICHE_FLAG(bool, quic_reloadable_flag_advertise_quic_for_https_for_external_users, false, "") - -QUICHE_FLAG(bool, quic_reloadable_flag_gclb_quic_allow_alia, true, - "If gfe2_reloadable_flag_gclb_use_alia is also true, use Alia for GCLB QUIC " - "handshakes. To be used as a big red button if there's a problem with Alia/QUIC.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_abort_qpack_on_stream_close, false, - "If true, abort async QPACK header decompression in QuicSpdyStream::OnClose().") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_ack_delay_alarm_granularity, false, - "When true, ensure the ACK delay is never less than the alarm granularity when ACK " - "decimation is enabled.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_add_missing_connected_checks, false, - "If true, add missing connected checks.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_add_silent_idle_timeout, true, - "If true, when server is silently closing connections due to idle timeout, serialize " - "the connection close packets which will be added to time wait list.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, false, - "If true, include stream information in idle timeout connection close detail.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_allow_backend_set_stream_ttl, false, - "If true, check backend response header for X-Response-Ttl. If it is provided, the " - "stream TTL is set. A QUIC stream will be immediately canceled when tries to write " - "data if this TTL expired.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true, - "If true, allow client to enable BBRv2 on server via connection option 'B2ON'.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_alpn_dispatch, false, - "Support different QUIC sessions, as indicated by ALPN. Used for QBONE.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_avoid_too_low_probe_bw_cwnd, false, - "If true, QUIC BBRv2's PROBE_BW mode will not reduce cwnd below BDP+ack_height.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_fewer_startup_round_trips, false, - "When true, the 1RTT and 2RTT connection options decrease the number of round trips in " - "BBRv2 STARTUP without a 25% bandwidth increase to 1 or 2 round trips respectively.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_bbr2_limit_inflight_hi, false, - "When true, the B2HI connection option limits reduction of inflight_hi to (1-Beta)*CWND.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_use_post_inflight_to_detect_queuing, false, - "If true, QUIC BBRv2 will use inflight byte after congestion event to detect queuing " - "during PROBE_UP.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_no_bytes_acked_in_startup_recovery, false, - "When in STARTUP and recovery, do not add bytes_acked to QUIC BBR's CWND in " - "CalculateCongestionWindow()") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bootstrap_cwnd_by_spdy_priority, true, - "If true, bootstrap initial QUIC cwnd by SPDY priorities.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_cap_large_client_initial_rtt, true, - "If true, cap client suggested initial RTT to 1s if it is longer than 1s.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_clean_up_spdy_session_destructor, false, - "If true, QuicSpdySession's destructor won't need to do cleanup.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_close_connection_in_on_can_write_with_blocked_writer, - false, - "If true, close connection if writer is still blocked while OnCanWrite is called.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_close_connection_on_serialization_failure, false, - "If true, close connection on packet serialization failures.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_conservative_bursts, false, - "If true, set burst token to 2 in cwnd bootstrapping experiment.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false, - "If true, uses conservative cwnd gain and pacing gain when cwnd gets bootstrapped.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_copy_bbr_cwnd_to_bbr2, false, - "If true, when switching from BBR to BBRv2, BBRv2 will use BBR's cwnd as its initial cwnd.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true, - "If true, default-enable 5RTO blachole detection.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_default_on_pto, false, - "If true, default on PTO which unifies TLP + RTO loss recovery.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_default_to_bbr, true, - "When true, defaults to BBR congestion control instead of Cubic.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_default_to_bbr_v2, false, - "If true, use BBRv2 as the default congestion controller. Takes precedence over " - "--quic_default_to_bbr.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_server_blackhole_detection, false, - "If true, disable blackhole detection on server side.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_draft_27, false, - "If true, disable QUIC version h3-27.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_draft_29, false, - "If true, disable QUIC version h3-29.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_q043, false, - "If true, disable QUIC version Q043.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_q046, false, - "If true, disable QUIC version Q046.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_q050, false, - "If true, disable QUIC version Q050.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_t050, false, - "If true, disable QUIC version h3-T050.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_t051, false, - "If true, disable QUIC version h3-T051.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, false, - "If true, discard INITIAL packet if the key has been dropped.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_do_not_accept_stop_waiting, false, - "In v44 and above, where STOP_WAITING is never sent, close the connection if it's received.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false, - "If true, stop resetting ideal_next_packet_send_time_ in pacing sender.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_loss_detection_experiment_at_gfe, false, - "If ture, enable GFE-picked loss detection experiment.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_loss_detection_tuner, false, - "If true, allow QUIC loss detection tuning to be enabled by connection option ELDT.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false, - "If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enabled, false, "") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_fix_arm_pto_for_application_data, false, - "If true, do not arm PTO for application data until handshake confirmed.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_fix_bytes_left_for_batch_write, false, - "If true, convert bytes_left_for_batch_write_ to unsigned int.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_fix_http3_goaway_stream_id, false, - "If true, send the lowest stream ID that can be retried by the client in a GOAWAY frame. If " - "false, send the highest received stream ID, which actually should not be retried.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_fix_out_of_order_sending, false, - "If true, fix a potential out of order sending caused by handshake gets confirmed " - "while the coalescer is not empty.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_fix_pto_pending_timer_count, false, - "If true, make sure there is pending timer credit when trying to PTO retransmit any packets.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_fix_undecryptable_packets2, false, - "If true, remove processed undecryptable packets.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_get_stream_information_from_stream_map, true, - "If true, gQUIC will only consult stream_map in QuicSession::GetNumActiveStreams().") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_give_sent_packet_to_debug_visitor_after_sent, false, - "If true, QUIC connection will pass sent packet information to the debug visitor after " - "a packet is recorded as sent in sent packet manager.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_http3_new_default_urgency_value, false, - "If true, QuicStream::kDefaultUrgency is 3, otherwise 1.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_ip_based_cwnd_exp, true, - "If true, enable IP address based CWND bootstrapping experiment with different " - "bandwidth models and priorities. ") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_listener_never_fake_epollout, false, - "If true, QuicListener::OnSocketIsWritable will always return false, which means there " - "will never be a fake `EPOLLOUT` event in the next epoll iteration.") - -QUICHE_FLAG(bool, - quic_reloadable_flag_quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded, - false, "If true, neuter initial packet in the coalescer when discarding initial keys.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_no_dup_experiment_id_2, false, - "If true, transport connection stats doesn't report duplicated experiments for same " - "connection.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_no_silent_close_for_idle_timeout, true, - "If true, always send connection close for idle timeout if NSLC is received.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_only_set_uaid_in_tcs_visitor, false, - "If true, QuicTransportConnectionStatsVisitor::PopulateTransportConnectionStats will " - "be the only place where TCS's uaid field is set.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_only_truncate_long_cids, true, - "In IETF QUIC, only truncate long CIDs from the client's Initial, don't modify them.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_preferred_altsvc_version, false, - "When true, we will send a preferred QUIC version at the start of our Alt-Svc list.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_proxy_write_packed_strings, false, - "If true, QuicProxyDispatcher will write packed_client_address and packed_server_vip " - "in TcpProxyHeaderProto.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_record_frontend_service_vip_mapping, true, - "If true, for L1 GFE, as requests come in, record frontend service to VIP mapping " - "which is used to announce VIP in SHLO for proxied sessions. ") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_record_received_min_ack_delay, false, - "If true, record the received min_ack_delay in transport parameters to QUIC config.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_reject_all_traffic, false, "") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_remove_zombie_streams, true, - "If true, QuicSession doesn't keep a separate zombie_streams. Instead, all streams are " - "stored in stream_map_.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_require_handshake_confirmation, false, - "If true, require handshake confirmation for QUIC connections, functionally disabling " - "0-rtt handshakes.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_send_key_update_not_yet_supported, false, - "When true, QUIC+TLS versions will send the key_update_not_yet_supported transport parameter.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_send_path_response, false, - "If true, send PATH_RESPONSE upon receiving PATH_CHALLENGE regardless of perspective. " - "--gfe2_reloadable_flag_quic_start_peer_migration_earlier has to be true before turn " - "on this flag.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_send_timestamps, false, - "When the STMP connection option is sent by the client, timestamps in the QUIC ACK " - "frame are sent and processed.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_server_push, false, - "If true, enable server push feature on QUIC.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_set_resumed_ssl_session_early, false, - "If true, set resumed_ssl_session if this is a 0-RTT connection.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_start_peer_migration_earlier, false, - "If true, while reading an IETF quic packet, start peer migration immediately when " - "detecting the existence of any non-probing frame instead of at the end of the packet.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_stop_sending_uses_ietf_error_code, false, - "If true, use IETF QUIC application error codes in STOP_SENDING frames. If false, use " - "QuicRstStreamErrorCodes.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_testonly_default_false, false, - "A testonly reloadable flag that will always default to false.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_testonly_default_true, true, - "A testonly reloadable flag that will always default to true.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_unified_iw_options, false, - "When true, set the initial congestion control window from connection options in " - "QuicSentPacketManager rather than TcpCubicSenderBytes.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_header_stage_idle_list2, false, - "If true, use header stage idle list for QUIC connections in GFE.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_leto_key_exchange, false, - "If true, QUIC will attempt to use the Leto key exchange service and only fall back to " - "local key exchange if that fails.") - -QUICHE_FLAG(bool, quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, false, - "If true and using Leto for QUIC shared-key calculations, GFE will react to a failure " - "to contact Leto by sending a REJ containing a fallback ServerConfig, allowing the " - "client to continue the handshake.") - -QUICHE_FLAG( - bool, quic_restart_flag_dont_fetch_quic_private_keys_from_leto, false, - "If true, GFE will not request private keys when fetching QUIC ServerConfigs from Leto.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_adjust_initial_cwnd_by_gws, true, - "If true, GFE informs backend that a client request is the first one on the connection " - "via frontline header \"first_request=1\". Also, adjust initial cwnd based on " - "X-Google-Gws-Initial-Cwnd-Mode sent by GWS.") - -QUICHE_FLAG( - bool, quic_restart_flag_quic_allow_loas_multipacket_chlo, false, - "If true, inspects QUIC CHLOs for kLOAS and early creates sessions to allow multi-packet CHLOs") - -QUICHE_FLAG( - bool, quic_restart_flag_quic_disable_gws_cwnd_experiment, false, - "If true, X-Google-Gws-Initial-Cwnd-Mode related header sent by GWS becomes no-op for QUIC.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_enable_tls_resumption_v4, true, - "If true, enables support for TLS resumption in QUIC.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_enable_zero_rtt_for_tls_v2, true, - "If true, support for IETF QUIC 0-rtt is enabled.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_offload_pacing_to_usps2, false, - "If true, QUIC offload pacing when using USPS as egress method.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_rx_ring_use_tpacket_v3, false, - "If true, use TPACKET_V3 for QuicRxRing instead of TPACKET_V2.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_should_accept_new_connection, false, - "If true, reject QUIC CHLO packets when dispatcher is asked to do so.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_support_release_time_for_gso, false, - "If true, QuicGsoBatchWriter will support release time if it is available and the " - "process has the permission to do so.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_testonly_default_false, false, - "A testonly restart flag that will always default to false.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_testonly_default_true, true, - "A testonly restart flag that will always default to true.") - -QUICHE_FLAG( - bool, quic_restart_flag_quic_use_leto_for_quic_configs, false, - "If true, use Leto to fetch QUIC server configs instead of using the seeds from Memento.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_use_pigeon_socket_to_backend, false, - "If true, create a shared pigeon socket for all quic to backend connections and switch " - "to use it after successful handshake.") - -QUICHE_FLAG(bool, spdy_reloadable_flag_quic_bootstrap_cwnd_by_spdy_priority, true, - "If true, bootstrap initial QUIC cwnd by SPDY priorities.") - -QUICHE_FLAG(bool, spdy_reloadable_flag_quic_clean_up_spdy_session_destructor, false, - "If true, QuicSpdySession's destructor won't need to do cleanup.") - -QUICHE_FLAG( - bool, spdy_reloadable_flag_spdy_discard_response_body_if_disallowed, false, - "If true, SPDY will discard all response body bytes when response code indicates no response " - "body should exist. Previously, we only discard partial bytes on the first response processing " - "and the rest of the response bytes would still be delivered even though the response code " - "said there should not be any body associated with the response code.") - -QUICHE_FLAG(bool, quic_allow_chlo_buffering, true, - "If true, allows packets to be buffered in anticipation of a " - "future CHLO, and allow CHLO packets to be buffered until next " - "iteration of the event loop.") - -QUICHE_FLAG(bool, quic_disable_pacing_for_perf_tests, false, "If true, disable pacing in QUIC") - -QUICHE_FLAG(bool, quic_enforce_single_packet_chlo, true, - "If true, enforce that QUIC CHLOs fit in one packet") - -QUICHE_FLAG(int64_t, quic_time_wait_list_max_connections, 600000, - "Maximum number of connections on the time-wait list. " - "A negative value implies no configured limit.") - -QUICHE_FLAG(int64_t, quic_time_wait_list_seconds, 200, - "Time period for which a given connection_id should live in " - "the time-wait state.") - -QUICHE_FLAG(double, quic_bbr_cwnd_gain, 2.0f, - "Congestion window gain for QUIC BBR during PROBE_BW phase.") - -QUICHE_FLAG(int32_t, quic_buffered_data_threshold, 8 * 1024, - "If buffered data in QUIC stream is less than this " - "threshold, buffers all provided data or asks upper layer for more data") - -QUICHE_FLAG(int32_t, quic_send_buffer_max_data_slice_size, 4 * 1024, - "Max size of data slice in bytes for QUIC stream send buffer.") - -QUICHE_FLAG(int32_t, quic_lumpy_pacing_size, 2, - "Number of packets that the pacing sender allows in bursts during " - "pacing. This flag is ignored if a flow's estimated bandwidth is " - "lower than 1200 kbps.") - -QUICHE_FLAG(double, quic_lumpy_pacing_cwnd_fraction, 0.25f, - "Congestion window fraction that the pacing sender allows in bursts " - "during pacing.") - -QUICHE_FLAG(int32_t, quic_max_pace_time_into_future_ms, 10, - "Max time that QUIC can pace packets into the future in ms.") - -QUICHE_FLAG(double, quic_pace_time_into_future_srtt_fraction, 0.125f, - "Smoothed RTT fraction that a connection can pace packets into the future.") - -QUICHE_FLAG(bool, quic_export_server_num_packets_per_write_histogram, false, - "If true, export number of packets written per write operation histogram.") - -QUICHE_FLAG(bool, quic_disable_version_negotiation_grease_randomness, false, - "If true, use predictable version negotiation versions.") - -QUICHE_FLAG(bool, quic_enable_http3_grease_randomness, true, - "If true, use random greased settings and frames.") - -QUICHE_FLAG(int64_t, quic_max_tracked_packet_count, 10000, "Maximum number of tracked packets.") - -QUICHE_FLAG(bool, quic_prober_uses_length_prefixed_connection_ids, false, - "If true, QuicFramer::WriteClientVersionNegotiationProbePacket uses " - "length-prefixed connection IDs.") - -QUICHE_FLAG(bool, quic_client_convert_http_header_name_to_lowercase, true, - "If true, HTTP request header names sent from QuicSpdyClientBase(and " - "descendents) will be automatically converted to lower case.") - -QUICHE_FLAG(bool, quic_enable_http3_server_push, false, - "If true, server push will be allowed in QUIC versions that use HTTP/3.") - -QUICHE_FLAG(int32_t, quic_bbr2_default_probe_bw_base_duration_ms, 2000, - "The default minimum duration for BBRv2-native probes, in milliseconds.") - -QUICHE_FLAG(int32_t, quic_bbr2_default_probe_bw_max_rand_duration_ms, 1000, - "The default upper bound of the random amount of BBRv2-native " - "probes, in milliseconds.") - -QUICHE_FLAG(int32_t, quic_bbr2_default_probe_rtt_period_ms, 10000, - "The default period for entering PROBE_RTT, in milliseconds.") - -QUICHE_FLAG(double, quic_bbr2_default_loss_threshold, 0.02, - "The default loss threshold for QUIC BBRv2, should be a value " - "between 0 and 1.") - -QUICHE_FLAG(int32_t, quic_bbr2_default_startup_full_loss_count, 8, - "The default minimum number of loss marking events to exit STARTUP.") - -QUICHE_FLAG(int32_t, quic_bbr2_default_probe_bw_full_loss_count, 2, - "The default minimum number of loss marking events to exit PROBE_UP phase.") - -QUICHE_FLAG(double, quic_bbr2_default_inflight_hi_headroom, 0.01, - "The default fraction of unutilized headroom to try to leave in path " - "upon high loss.") - -QUICHE_FLAG(int32_t, quic_bbr2_default_initial_ack_height_filter_window, 10, - "The default initial value of the max ack height filter's window length.") - -QUICHE_FLAG(double, quic_ack_aggregation_bandwidth_threshold, 1.0, - "If the bandwidth during ack aggregation is smaller than (estimated " - "bandwidth * this flag), consider the current aggregation completed " - "and starts a new one.") - -QUICHE_FLAG(int32_t, quic_anti_amplification_factor, 5, - "Anti-amplification factor. Before address validation, server will " - "send no more than factor times bytes received.") - -QUICHE_FLAG(int32_t, quic_max_buffered_crypto_bytes, 16 * 1024, - "The maximum amount of CRYPTO frame data that can be buffered.") - -QUICHE_FLAG(int32_t, quic_max_aggressive_retransmittable_on_wire_ping_count, 0, - "If set to non-zero, the maximum number of consecutive pings that " - "can be sent with aggressive initial retransmittable on wire timeout " - "if there is no new data received. After which, the timeout will be " - "exponentially back off until exceeds the default ping timeout.") - -QUICHE_FLAG(int32_t, quic_max_congestion_window, 2000, "The maximum congestion window in packets.") - -QUICHE_FLAG(int32_t, quic_max_streams_window_divisor, 2, - "The divisor that controls how often MAX_STREAMS frame is sent.") - -QUICHE_FLAG(bool, http2_reloadable_flag_http2_testonly_default_false, false, - "A testonly reloadable flag that will always default to false.") - -QUICHE_FLAG(bool, http2_restart_flag_http2_testonly_default_false, false, - "A testonly restart flag that will always default to false.") - -QUICHE_FLAG(bool, spdy_reloadable_flag_spdy_testonly_default_false, false, - "A testonly reloadable flag that will always default to false.") - -QUICHE_FLAG(bool, spdy_restart_flag_spdy_testonly_default_false, false, - "A testonly restart flag that will always default to false.") - -#endif diff --git a/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h b/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h index 7d2561469780..dc6fe5429bde 100644 --- a/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h @@ -8,10 +8,10 @@ #include "extensions/quic_listeners/quiche/platform/flags_impl.h" -#define GetHttp2ReloadableFlagImpl(flag) quiche::FLAGS_http2_reloadable_flag_##flag->value() +#define GetHttp2ReloadableFlagImpl(flag) quiche::FLAGS_quic_reloadable_flag_##flag->value() #define SetHttp2ReloadableFlagImpl(flag, value) \ - quiche::FLAGS_http2_reloadable_flag_##flag->SetValue(value) + quiche::FLAGS_quic_reloadable_flag_##flag->setValue(value) #define HTTP2_CODE_COUNT_N_IMPL(flag, instance, total) \ do { \ diff --git a/source/extensions/quic_listeners/quiche/platform/quic_aligned_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_aligned_impl.h deleted file mode 100644 index 3f595380b720..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/quic_aligned_impl.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "absl/base/optimization.h" - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#define QUIC_ALIGN_OF_IMPL alignof -#ifdef _MSC_VER -#define QUIC_ALIGNED_IMPL(X) __declspec(align(X)) -#else -#define QUIC_ALIGNED_IMPL(X) __attribute__((aligned(X))) -#endif -#define QUIC_CACHELINE_ALIGNED_IMPL ABSL_CACHELINE_ALIGNED -#define QUIC_CACHELINE_SIZE_IMPL ABSL_CACHELINE_SIZE diff --git a/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.cc index 2a886a12caa1..27b977908d95 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.cc @@ -10,25 +10,7 @@ namespace quic { -// static -bool QuicCertUtilsImpl::ExtractSubjectNameFromDERCert(quiche::QuicheStringPiece cert, - quiche::QuicheStringPiece* subject_out) { - CBS tbs_certificate; - if (!SeekToSubject(cert, &tbs_certificate)) { - return false; - } - - CBS subject; - if (!CBS_get_asn1_element(&tbs_certificate, &subject, CBS_ASN1_SEQUENCE)) { - return false; - } - *subject_out = - absl::string_view(reinterpret_cast(CBS_data(&subject)), CBS_len(&subject)); - return true; -} - -// static -bool QuicCertUtilsImpl::SeekToSubject(quiche::QuicheStringPiece cert, CBS* tbs_certificate) { +bool seekToSubject(absl::string_view cert, CBS* tbs_certificate) { CBS der; CBS_init(&der, reinterpret_cast(cert.data()), cert.size()); CBS certificate; @@ -65,4 +47,22 @@ bool QuicCertUtilsImpl::SeekToSubject(quiche::QuicheStringPiece cert, CBS* tbs_c return true; } +// static +// NOLINTNEXTLINE(readability-identifier-naming) +bool QuicCertUtilsImpl::ExtractSubjectNameFromDERCert(absl::string_view cert, + absl::string_view* subject_out) { + CBS tbs_certificate; + if (!seekToSubject(cert, &tbs_certificate)) { + return false; + } + + CBS subject; + if (!CBS_get_asn1_element(&tbs_certificate, &subject, CBS_ASN1_SEQUENCE)) { + return false; + } + *subject_out = + absl::string_view(reinterpret_cast(CBS_data(&subject)), CBS_len(&subject)); + return true; +} + } // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.h index 0c41b9dbcf21..29b882b7d75d 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_cert_utils_impl.h @@ -6,18 +6,15 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. +#include "absl/strings/string_view.h" #include "openssl/base.h" -#include "quiche/common/platform/api/quiche_string_piece.h" namespace quic { class QuicCertUtilsImpl { public: - static bool ExtractSubjectNameFromDERCert(quiche::QuicheStringPiece cert, - quiche::QuicheStringPiece* subject_out); - -private: - static bool SeekToSubject(quiche::QuicheStringPiece cert, CBS* tbs_certificate); + // NOLINTNEXTLINE(readability-identifier-naming) + static bool ExtractSubjectNameFromDERCert(absl::string_view cert, absl::string_view* subject_out); }; } // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_fallthrough_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_fallthrough_impl.h deleted file mode 100644 index aa9d6bc36a18..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/quic_fallthrough_impl.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "absl/base/macros.h" - -#define QUIC_FALLTHROUGH_INTENDED_IMPL ABSL_FALLTHROUGH_INTENDED diff --git a/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.cc index 91d52c44abbc..b2e396fab4be 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.cc @@ -36,6 +36,7 @@ void depthFirstTraverseDirectory(const std::string& dirname, std::vector ReadFileContentsImpl(const std::string& dirname) { std::vector files; depthFirstTraverseDirectory(dirname, files); @@ -43,7 +44,8 @@ std::vector ReadFileContentsImpl(const std::string& dirname) { } // Reads the contents of |filename| as a string into |contents|. -void ReadFileContentsImpl(quiche::QuicheStringPiece filename, std::string* contents) { +// NOLINTNEXTLINE(readability-identifier-naming) +void ReadFileContentsImpl(absl::string_view filename, std::string* contents) { #ifdef WIN32 Envoy::Filesystem::InstanceImplWin32 fs; #else diff --git a/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.h index 654c1ad1826b..25c31e9deca2 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_file_utils_impl.h @@ -8,7 +8,7 @@ #include -#include "quiche/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { @@ -16,6 +16,7 @@ namespace quic { * Traverses the directory |dirname| and returns all of the files it contains. * @param dirname full path without trailing '/'. */ +// NOLINTNEXTLINE(readability-identifier-naming)` std::vector ReadFileContentsImpl(const std::string& dirname); /** @@ -23,6 +24,7 @@ std::vector ReadFileContentsImpl(const std::string& dirname); * @param filename the full path to the file. * @param contents output location of the file content. */ -void ReadFileContentsImpl(quiche::QuicheStringPiece filename, std::string* contents); +// NOLINTNEXTLINE(readability-identifier-naming) +void ReadFileContentsImpl(absl::string_view filename, std::string* contents); } // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_flags_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_flags_impl.h index 872495f2db8e..d562bb1a4813 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_flags_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_flags_impl.h @@ -15,16 +15,16 @@ #define GetQuicFlagImpl(flag) (quiche::flag)->value() // |flag| is the global flag variable, which is a pointer to TypedFlag. -#define SetQuicFlagImpl(flag, value) (quiche::flag)->SetValue(value) +#define SetQuicFlagImpl(flag, value) (quiche::flag)->setValue(value) #define GetQuicReloadableFlagImpl(flag) quiche::FLAGS_quic_reloadable_flag_##flag->value() #define SetQuicReloadableFlagImpl(flag, value) \ - quiche::FLAGS_quic_reloadable_flag_##flag->SetValue(value) + quiche::FLAGS_quic_reloadable_flag_##flag->setValue(value) #define GetQuicRestartFlagImpl(flag) quiche::FLAGS_quic_restart_flag_##flag->value() -#define SetQuicRestartFlagImpl(flag, value) quiche::FLAGS_quic_restart_flag_##flag->SetValue(value) +#define SetQuicRestartFlagImpl(flag, value) quiche::FLAGS_quic_restart_flag_##flag->setValue(value) // Not wired into command-line parsing. #define DEFINE_QUIC_COMMAND_LINE_FLAG_IMPL(type, flag, value, help) \ diff --git a/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.cc index bcbafb56639e..75849611d6a2 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.cc @@ -19,7 +19,8 @@ namespace quic { // static -bool QuicHostnameUtilsImpl::IsValidSNI(quiche::QuicheStringPiece sni) { +// NOLINTNEXTLINE(readability-identifier-naming) +bool QuicHostnameUtilsImpl::IsValidSNI(absl::string_view sni) { // TODO(wub): Implement it on top of GoogleUrl, once it is available. return sni.find_last_of('.') != std::string::npos && @@ -27,7 +28,8 @@ bool QuicHostnameUtilsImpl::IsValidSNI(quiche::QuicheStringPiece sni) { } // static -std::string QuicHostnameUtilsImpl::NormalizeHostname(quiche::QuicheStringPiece hostname) { +// NOLINTNEXTLINE(readability-identifier-naming) +std::string QuicHostnameUtilsImpl::NormalizeHostname(absl::string_view hostname) { // TODO(wub): Implement it on top of GoogleUrl, once it is available. std::string host = absl::AsciiStrToLower(hostname); diff --git a/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.h index 2b7ed43571b4..67cd787d03c2 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_hostname_utils_impl.h @@ -6,7 +6,7 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -#include "quiche/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "quiche/quic/platform/api/quic_export.h" namespace quic { @@ -18,7 +18,8 @@ class QUIC_EXPORT_PRIVATE QuicHostnameUtilsImpl { // (2) check that the hostname contains valid characters only; and // (3) contains at least one dot. // NOTE(wub): Only (3) is implemented for now. - static bool IsValidSNI(quiche::QuicheStringPiece sni); + // NOLINTNEXTLINE(readability-identifier-naming) + static bool IsValidSNI(absl::string_view sni); // Normalize a hostname: // (1) Canonicalize it, similar to what Chromium does in @@ -27,7 +28,8 @@ class QUIC_EXPORT_PRIVATE QuicHostnameUtilsImpl { // (3) Remove the trailing '.'. // WARNING: May mutate |hostname| in place. // NOTE(wub): Only (2) and (3) are implemented for now. - static std::string NormalizeHostname(quiche::QuicheStringPiece hostname); + // NOLINTNEXTLINE(readability-identifier-naming) + static std::string NormalizeHostname(absl::string_view hostname); private: QuicHostnameUtilsImpl() = delete; diff --git a/source/extensions/quic_listeners/quiche/platform/quic_macros_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_macros_impl.h deleted file mode 100644 index b8b70a0426b4..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/quic_macros_impl.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "absl/base/attributes.h" - -#define QUIC_MUST_USE_RESULT_IMPL ABSL_MUST_USE_RESULT -#define QUIC_UNUSED_IMPL ABSL_ATTRIBUTE_UNUSED -#define QUIC_CONST_INIT_IMPL ABSL_CONST_INIT diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc index 903ee1332d04..f1c21d0509f7 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc @@ -29,15 +29,11 @@ QuicMemSliceImpl::QuicMemSliceImpl(Envoy::Buffer::Instance& buffer, size_t lengt } const char* QuicMemSliceImpl::data() const { - Envoy::Buffer::RawSliceVector slices = single_slice_buffer_.getRawSlices(/*max_slices=*/1); - ASSERT(slices.size() <= 1); - return !slices.empty() ? static_cast(slices[0].mem_) : nullptr; + return reinterpret_cast(single_slice_buffer_.frontSlice().mem_); } size_t QuicMemSliceImpl::firstSliceLength(Envoy::Buffer::Instance& buffer) { - Envoy::Buffer::RawSliceVector slices = buffer.getRawSlices(/*max_slices=*/1); - ASSERT(slices.size() == 1); - return slices[0].len_; + return buffer.frontSlice().len_; } } // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.cc index c2eb527d6584..9e46c37df344 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.cc @@ -10,7 +10,8 @@ namespace quic { -quiche::QuicheStringPiece QuicMemSliceSpanImpl::GetData(size_t index) { +// NOLINTNEXTLINE(readability-identifier-naming) +absl::string_view QuicMemSliceSpanImpl::GetData(size_t index) { Envoy::Buffer::RawSliceVector slices = buffer_->getRawSlices(/*max_slices=*/index + 1); ASSERT(slices.size() > index); return {reinterpret_cast(slices[index].mem_), slices[index].len_}; diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.h index 1824fb8d1fa5..ef40e6387057 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_span_impl.h @@ -9,7 +9,7 @@ #include "envoy/buffer/buffer.h" #include "absl/container/fixed_array.h" -#include "quiche/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" #include "quiche/quic/core/quic_types.h" #include "quiche/quic/platform/api/quic_mem_slice.h" @@ -43,9 +43,13 @@ class QuicMemSliceSpanImpl { } // QuicMemSliceSpan - quiche::QuicheStringPiece GetData(size_t index); + // NOLINTNEXTLINE(readability-identifier-naming) + absl::string_view GetData(size_t index); + // NOLINTNEXTLINE(readability-identifier-naming) QuicByteCount total_length() { return buffer_->length(); }; + // NOLINTNEXTLINE(readability-identifier-naming) size_t NumSlices() { return buffer_->getRawSlices().size(); } + // NOLINTNEXTLINE(readability-identifier-naming) template QuicByteCount ConsumeAll(ConsumeFunction consume); bool empty() const { return buffer_->length() == 0; } @@ -54,6 +58,7 @@ class QuicMemSliceSpanImpl { }; template +// NOLINTNEXTLINE(readability-identifier-naming) QuicByteCount QuicMemSliceSpanImpl::ConsumeAll(ConsumeFunction consume) { size_t saved_length = 0; for (auto& slice : buffer_->getRawSlices()) { diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_ptr_util_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_testvalue_impl.h similarity index 52% rename from source/extensions/quic_listeners/quiche/platform/quiche_ptr_util_impl.h rename to source/extensions/quic_listeners/quiche/platform/quic_testvalue_impl.h index aaebe5d5c352..4b0201c35af6 100644 --- a/source/extensions/quic_listeners/quiche/platform/quiche_ptr_util_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_testvalue_impl.h @@ -6,12 +6,11 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -#include "absl/memory/memory.h" +#include "absl/strings/string_view.h" -namespace quiche { +namespace quic { -template std::unique_ptr QuicheWrapUniqueImpl(T* ptr) { - return absl::WrapUnique(ptr); -} +// NOLINTNEXTLINE(readability-identifier-naming) +template void AdjustTestValueImpl(absl::string_view /*label*/, T* /*var*/) {} -} // namespace quiche +} // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_udp_socket_platform_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_udp_socket_platform_impl.h index 248cfc193e02..1e88abe466cc 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_udp_socket_platform_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_udp_socket_platform_impl.h @@ -19,4 +19,7 @@ inline bool GetGooglePacketHeadersFromControlMessageImpl(struct ::cmsghdr* /*cms return false; } +// NOLINTNEXTLINE(readability-identifier-naming) +inline void SetGoogleSocketOptionsImpl(int /*fd*/) {} + } // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_arraysize_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_arraysize_impl.h deleted file mode 100644 index 7a23b53da85d..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/quiche_arraysize_impl.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "absl/base/macros.h" - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#define QUICHE_ARRAYSIZE_IMPL(array) ABSL_ARRAYSIZE(array) diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_optional_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_optional_impl.h deleted file mode 100644 index f8b2b6c0800d..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/quiche_optional_impl.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "absl/types/optional.h" - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -namespace quiche { - -template using QuicheOptionalImpl = absl::optional; - -#define QUICHE_NULLOPT_IMPL absl::nullopt - -} // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_text_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_text_utils_impl.h index 3a6d1a393a8b..7b87c1cd61e8 100644 --- a/source/extensions/quic_listeners/quiche/platform/quiche_text_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_text_utils_impl.h @@ -2,7 +2,6 @@ #include "common/common/base64.h" -#include "extensions/quic_listeners/quiche/platform/quiche_optional_impl.h" #include "extensions/quic_listeners/quiche/platform/quiche_string_piece_impl.h" #include "extensions/quic_listeners/quiche/platform/string_utils.h" @@ -13,6 +12,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_split.h" +#include "absl/types/optional.h" // NOLINT(namespace-envoy) @@ -25,58 +25,16 @@ namespace quiche { class QuicheTextUtilsImpl { public: // NOLINTNEXTLINE(readability-identifier-naming) - static bool StartsWith(QuicheStringPieceImpl data, QuicheStringPieceImpl prefix) { - return absl::StartsWith(data, prefix); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - static bool EndsWith(QuicheStringPieceImpl data, QuicheStringPieceImpl suffix) { - return absl::EndsWith(data, suffix); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - static bool EndsWithIgnoreCase(QuicheStringPieceImpl data, QuicheStringPieceImpl suffix) { - return absl::EndsWithIgnoreCase(data, suffix); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - static std::string ToLower(QuicheStringPieceImpl data) { return absl::AsciiStrToLower(data); } + static std::string ToLower(absl::string_view data) { return absl::AsciiStrToLower(data); } // NOLINTNEXTLINE(readability-identifier-naming) - static void RemoveLeadingAndTrailingWhitespace(QuicheStringPieceImpl* data) { + static void RemoveLeadingAndTrailingWhitespace(absl::string_view* data) { *data = absl::StripAsciiWhitespace(*data); } - // NOLINTNEXTLINE(readability-identifier-naming) - static bool StringToUint64(QuicheStringPieceImpl in, uint64_t* out) { - return absl::SimpleAtoi(in, out); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - static bool StringToInt(QuicheStringPieceImpl in, int* out) { return absl::SimpleAtoi(in, out); } - - // NOLINTNEXTLINE(readability-identifier-naming) - static bool StringToUint32(QuicheStringPieceImpl in, uint32_t* out) { - return absl::SimpleAtoi(in, out); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - static bool StringToSizeT(QuicheStringPieceImpl in, size_t* out) { - return absl::SimpleAtoi(in, out); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - static std::string Uint64ToString(uint64_t in) { return absl::StrCat(in); } - - // NOLINTNEXTLINE(readability-identifier-naming) - static std::string HexEncode(QuicheStringPieceImpl data) { return absl::BytesToHexString(data); } - // NOLINTNEXTLINE(readability-identifier-naming) static std::string Hex(uint32_t v) { return absl::StrCat(absl::Hex(v)); } - // NOLINTNEXTLINE(readability-identifier-naming) - static std::string HexDecode(QuicheStringPieceImpl data) { return absl::HexStringToBytes(data); } - // NOLINTNEXTLINE(readability-identifier-naming) static void Base64Encode(const uint8_t* data, size_t data_len, std::string* output) { *output = @@ -84,27 +42,28 @@ class QuicheTextUtilsImpl { } // NOLINTNEXTLINE(readability-identifier-naming) - static QuicheOptionalImpl Base64Decode(QuicheStringPieceImpl input) { + static absl::optional Base64Decode(absl::string_view input) { return Envoy::Base64::decodeWithoutPadding(input); } // NOLINTNEXTLINE(readability-identifier-naming) - static std::string HexDump(QuicheStringPieceImpl binary_data) { - return quiche::HexDump(binary_data); - } + static std::string Uint64ToString(uint64_t in) { return absl::StrCat(in); } + + // NOLINTNEXTLINE(readability-identifier-naming) + static std::string HexDump(absl::string_view binary_data) { return quiche::HexDump(binary_data); } // NOLINTNEXTLINE(readability-identifier-naming) - static bool ContainsUpperCase(QuicheStringPieceImpl data) { + static bool ContainsUpperCase(absl::string_view data) { return std::any_of(data.begin(), data.end(), absl::ascii_isupper); } // NOLINTNEXTLINE(readability-identifier-naming) - static bool IsAllDigits(QuicheStringPieceImpl data) { + static bool IsAllDigits(absl::string_view data) { return std::all_of(data.begin(), data.end(), absl::ascii_isdigit); } // NOLINTNEXTLINE(readability-identifier-naming) - static std::vector Split(QuicheStringPieceImpl data, char delim) { + static std::vector Split(absl::string_view data, char delim) { return absl::StrSplit(data, delim); } }; diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.cc b/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.cc index 3260eafee4da..5387e059876a 100644 --- a/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.cc @@ -9,7 +9,7 @@ namespace quiche { namespace { -QuicheOptional quicheUtcDateTimeToUnixSecondsInner(int year, int month, int day, int hour, +absl::optional quicheUtcDateTimeToUnixSecondsInner(int year, int month, int day, int hour, int minute, int second) { const absl::CivilSecond civil_time(year, month, day, hour, minute, second); if (second != 60 && (civil_time.year() != year || civil_time.month() != month || @@ -24,7 +24,7 @@ QuicheOptional quicheUtcDateTimeToUnixSecondsInner(int year, int month, } // namespace // NOLINTNEXTLINE(readability-identifier-naming) -QuicheOptional QuicheUtcDateTimeToUnixSecondsImpl(int year, int month, int day, int hour, +absl::optional QuicheUtcDateTimeToUnixSecondsImpl(int year, int month, int day, int hour, int minute, int second) { // Handle leap seconds without letting any other irregularities happen. if (second == 60) { diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.h index a1b70b70a51e..5e2ef79567f5 100644 --- a/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_time_utils_impl.h @@ -10,12 +10,12 @@ #include "absl/time/civil_time.h" #include "absl/time/time.h" -#include "quiche/common/platform/api/quiche_optional.h" +#include "absl/types/optional.h" namespace quiche { // NOLINTNEXTLINE(readability-identifier-naming) -QuicheOptional QuicheUtcDateTimeToUnixSecondsImpl(int year, int month, int day, int hour, +absl::optional QuicheUtcDateTimeToUnixSecondsImpl(int year, int month, int day, int hour, int minute, int second); } // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_endianness_util_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_endianness_util_impl.h deleted file mode 100644 index 737b81ee2914..000000000000 --- a/source/extensions/quic_listeners/quiche/platform/spdy_endianness_util_impl.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include "envoy/common/platform.h" - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -namespace spdy { - -inline uint16_t SpdyNetToHost16Impl(uint16_t x) { return ntohs(x); } - -inline uint32_t SpdyNetToHost32Impl(uint32_t x) { return ntohl(x); } - -// TODO: implement -inline uint64_t SpdyNetToHost64Impl(uint64_t /*x*/) { return 0; } - -inline uint16_t SpdyHostToNet16Impl(uint16_t x) { return htons(x); } - -inline uint32_t SpdyHostToNet32Impl(uint32_t x) { return htonl(x); } - -// TODO: implement -inline uint64_t SpdyHostToNet64Impl(uint64_t /*x*/) { return 0; } - -} // namespace spdy diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h index a3cbd680ffc5..833562fab5b9 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h @@ -8,9 +8,9 @@ #include "extensions/quic_listeners/quiche/platform/flags_impl.h" -#define GetSpdyReloadableFlagImpl(flag) quiche::FLAGS_spdy_reloadable_flag_##flag->value() +#define GetSpdyReloadableFlagImpl(flag) quiche::FLAGS_quic_reloadable_flag_##flag->value() -#define GetSpdyRestartFlagImpl(flag) quiche::FLAGS_spdy_restart_flag_##flag->value() +#define GetSpdyRestartFlagImpl(flag) quiche::FLAGS_quic_restart_flag_##flag->value() #define SPDY_CODE_COUNT_N_IMPL(flag, instance, total) \ do { \ diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h index 41fa3cad815f..4b01b2dbddb3 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h @@ -50,7 +50,7 @@ inline std::string SpdyHexEncodeUInt32AndTrimImpl(uint32_t data) { inline std::string SpdyHexDumpImpl(absl::string_view data) { return quiche::HexDump(data); } struct SpdyStringPieceCaseHashImpl { - size_t operator()(quiche::QuicheStringPiece data) const { + size_t operator()(absl::string_view data) const { std::string lower = absl::AsciiStrToLower(data); return absl::Hash()(lower); } diff --git a/source/extensions/quic_listeners/quiche/spdy_server_push_utils_for_envoy.cc b/source/extensions/quic_listeners/quiche/spdy_server_push_utils_for_envoy.cc index 3bd0bc2950b2..5ac5738c4bfe 100644 --- a/source/extensions/quic_listeners/quiche/spdy_server_push_utils_for_envoy.cc +++ b/source/extensions/quic_listeners/quiche/spdy_server_push_utils_for_envoy.cc @@ -12,25 +12,29 @@ using spdy::SpdyHeaderBlock; namespace quic { // static +// NOLINTNEXTLINE(readability-identifier-naming) std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders(const SpdyHeaderBlock& /*headers*/) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } // static std::string +// NOLINTNEXTLINE(readability-identifier-naming) SpdyServerPushUtils::GetPromisedHostNameFromHeaders(const SpdyHeaderBlock& /*headers*/) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } // static +// NOLINTNEXTLINE(readability-identifier-naming) bool SpdyServerPushUtils::PromisedUrlIsValid(const SpdyHeaderBlock& /*headers*/) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } // static -std::string SpdyServerPushUtils::GetPushPromiseUrl(quiche::QuicheStringPiece /*scheme*/, - quiche::QuicheStringPiece /*authority*/, - quiche::QuicheStringPiece /*path*/) { +// NOLINTNEXTLINE(readability-identifier-naming) +std::string SpdyServerPushUtils::GetPushPromiseUrl(absl::string_view /*scheme*/, + absl::string_view /*authority*/, + absl::string_view /*path*/) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } diff --git a/source/extensions/transport_sockets/tls/context_impl.cc b/source/extensions/transport_sockets/tls/context_impl.cc index e163eddfc8b4..e79a1aeadb6d 100644 --- a/source/extensions/transport_sockets/tls/context_impl.cc +++ b/source/extensions/transport_sockets/tls/context_impl.cc @@ -417,9 +417,11 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c !tls_certificate.password().empty() ? const_cast(tls_certificate.password().c_str()) : nullptr)); + if (pkey == nullptr || !SSL_CTX_use_PrivateKey(ctx.ssl_ctx_.get(), pkey.get())) { - throw EnvoyException( - absl::StrCat("Failed to load private key from ", tls_certificate.privateKeyPath())); + throw EnvoyException(fmt::format("Failed to load private key from {}, Cause: {}", + tls_certificate.privateKeyPath(), + Utility::getLastCryptoError().value_or("unknown"))); } #ifdef BORINGSSL_FIPS diff --git a/source/extensions/transport_sockets/tls/ssl_socket.cc b/source/extensions/transport_sockets/tls/ssl_socket.cc index 50b2d27926e2..37a1f8547952 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.cc +++ b/source/extensions/transport_sockets/tls/ssl_socket.cc @@ -293,6 +293,17 @@ void SslSocket::shutdownSsl() { if (info_->state() != Ssl::SocketState::ShutdownSent && callbacks_->connection().state() != Network::Connection::State::Closed) { int rc = SSL_shutdown(rawSsl()); + if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) { + // Windows operate under `EmulatedEdge`. These are level events that are artificially + // made to behave like edge events. And if the rc is 0 then in that case we want read + // activation resumption. This code is protected with an `constexpr` if, to minimize the tax + // on POSIX systems that operate in Edge events. + if (rc == 0) { + // See https://www.openssl.org/docs/manmaster/man3/SSL_shutdown.html + // if return value is 0, Call SSL_read() to do a bidirectional shutdown. + callbacks_->setReadBufferReady(); + } + } ENVOY_CONN_LOG(debug, "SSL shutdown: rc={}", callbacks_->connection(), rc); drainErrorQueue(); info_->setState(Ssl::SocketState::ShutdownSent); diff --git a/source/extensions/transport_sockets/tls/ssl_socket.h b/source/extensions/transport_sockets/tls/ssl_socket.h index 4c5f38e0fb14..81b4712979fd 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.h +++ b/source/extensions/transport_sockets/tls/ssl_socket.h @@ -70,8 +70,6 @@ class SslSocket : public Network::TransportSocket, void onFailure() override; Network::TransportSocketCallbacks* transportSocketCallbacks() override { return callbacks_; } - SSL* rawSslForTest() const { return rawSsl(); } - protected: SSL* rawSsl() const { return info_->ssl_.get(); } diff --git a/source/extensions/wasm_runtime/null/BUILD b/source/extensions/wasm_runtime/null/BUILD new file mode 100644 index 000000000000..63969c889c25 --- /dev/null +++ b/source/extensions/wasm_runtime/null/BUILD @@ -0,0 +1,21 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_extension_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_extension( + name = "config", + srcs = ["config.cc"], + security_posture = "unknown", + status = "alpha", + deps = [ + "//include/envoy/registry", + "//source/extensions/common/wasm:wasm_runtime_factory_interface", + "@proxy_wasm_cpp_host//:null_lib", + ], +) diff --git a/source/extensions/wasm_runtime/null/config.cc b/source/extensions/wasm_runtime/null/config.cc new file mode 100644 index 000000000000..3515c9462ce1 --- /dev/null +++ b/source/extensions/wasm_runtime/null/config.cc @@ -0,0 +1,25 @@ +#include "envoy/registry/registry.h" + +#include "extensions/common/wasm/wasm_runtime_factory.h" + +#include "include/proxy-wasm/null.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +class NullRuntimeFactory : public WasmRuntimeFactory { +public: + WasmVmPtr createWasmVm() override { return proxy_wasm::createNullVm(); } + + absl::string_view name() override { return "envoy.wasm.runtime.null"; } + absl::string_view shortName() override { return "null"; } +}; + +REGISTER_FACTORY(NullRuntimeFactory, WasmRuntimeFactory); + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/wasm_runtime/v8/BUILD b/source/extensions/wasm_runtime/v8/BUILD new file mode 100644 index 000000000000..8785616044d7 --- /dev/null +++ b/source/extensions/wasm_runtime/v8/BUILD @@ -0,0 +1,23 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_extension_package", +) +load("//bazel:envoy_select.bzl", "envoy_select_wasm_v8") + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_extension( + name = "config", + srcs = ["config.cc"], + security_posture = "unknown", + status = "alpha", + deps = [ + "//include/envoy/registry", + "//source/extensions/common/wasm:wasm_runtime_factory_interface", + ] + envoy_select_wasm_v8([ + "@proxy_wasm_cpp_host//:v8_lib", + ]), +) diff --git a/source/extensions/wasm_runtime/v8/config.cc b/source/extensions/wasm_runtime/v8/config.cc new file mode 100644 index 000000000000..1061b17b2b9d --- /dev/null +++ b/source/extensions/wasm_runtime/v8/config.cc @@ -0,0 +1,27 @@ +#include "envoy/registry/registry.h" + +#include "extensions/common/wasm/wasm_runtime_factory.h" + +#include "include/proxy-wasm/v8.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +class V8RuntimeFactory : public WasmRuntimeFactory { +public: + WasmVmPtr createWasmVm() override { return proxy_wasm::createV8Vm(); } + + absl::string_view name() override { return "envoy.wasm.runtime.v8"; } + absl::string_view shortName() override { return "v8"; } +}; + +#if defined(ENVOY_WASM_V8) +REGISTER_FACTORY(V8RuntimeFactory, WasmRuntimeFactory); +#endif + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/wasm_runtime/wasmtime/BUILD b/source/extensions/wasm_runtime/wasmtime/BUILD new file mode 100644 index 000000000000..d0adea5660c6 --- /dev/null +++ b/source/extensions/wasm_runtime/wasmtime/BUILD @@ -0,0 +1,23 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_extension_package", +) +load("//bazel:envoy_select.bzl", "envoy_select_wasm_wasmtime") + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_extension( + name = "config", + srcs = ["config.cc"], + security_posture = "unknown", + status = "alpha", + deps = [ + "//include/envoy/registry", + "//source/extensions/common/wasm:wasm_runtime_factory_interface", + ] + envoy_select_wasm_wasmtime([ + "@proxy_wasm_cpp_host//:wasmtime_lib", + ]), +) diff --git a/source/extensions/wasm_runtime/wasmtime/config.cc b/source/extensions/wasm_runtime/wasmtime/config.cc new file mode 100644 index 000000000000..a407d847bdfd --- /dev/null +++ b/source/extensions/wasm_runtime/wasmtime/config.cc @@ -0,0 +1,27 @@ +#include "envoy/registry/registry.h" + +#include "extensions/common/wasm/wasm_runtime_factory.h" + +#include "include/proxy-wasm/wasmtime.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +class WasmtimeRuntimeFactory : public WasmRuntimeFactory { +public: + WasmVmPtr createWasmVm() override { return proxy_wasm::createWasmtimeVm(); } + + absl::string_view name() override { return "envoy.wasm.runtime.wasmtime"; } + absl::string_view shortName() override { return "wasmtime"; } +}; + +#if defined(ENVOY_WASM_WASMTIME) +REGISTER_FACTORY(WasmtimeRuntimeFactory, WasmRuntimeFactory); +#endif + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/wasm_runtime/wavm/BUILD b/source/extensions/wasm_runtime/wavm/BUILD new file mode 100644 index 000000000000..c9a5153efe31 --- /dev/null +++ b/source/extensions/wasm_runtime/wavm/BUILD @@ -0,0 +1,23 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_extension_package", +) +load("//bazel:envoy_select.bzl", "envoy_select_wasm_wavm") + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_extension( + name = "config", + srcs = ["config.cc"], + security_posture = "unknown", + status = "alpha", + deps = [ + "//include/envoy/registry", + "//source/extensions/common/wasm:wasm_runtime_factory_interface", + ] + envoy_select_wasm_wavm([ + "@proxy_wasm_cpp_host//:wavm_lib", + ]), +) diff --git a/source/extensions/wasm_runtime/wavm/config.cc b/source/extensions/wasm_runtime/wavm/config.cc new file mode 100644 index 000000000000..d50119cf784d --- /dev/null +++ b/source/extensions/wasm_runtime/wavm/config.cc @@ -0,0 +1,27 @@ +#include "envoy/registry/registry.h" + +#include "extensions/common/wasm/wasm_runtime_factory.h" + +#include "include/proxy-wasm/wavm.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +class WavmRuntimeFactory : public WasmRuntimeFactory { +public: + WasmVmPtr createWasmVm() override { return proxy_wasm::createWavmVm(); } + + absl::string_view name() override { return "envoy.wasm.runtime.wavm"; } + absl::string_view shortName() override { return "wavm"; } +}; + +#if defined(ENVOY_WASM_WAVM) +REGISTER_FACTORY(WavmRuntimeFactory, WasmRuntimeFactory); +#endif + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/source/server/BUILD b/source/server/BUILD index c3404818a217..cc21ce681f28 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -418,6 +418,7 @@ envoy_cc_library( "//include/envoy/network:dns_interface", "//include/envoy/server:bootstrap_extension_config_interface", "//include/envoy/server:drain_manager_interface", + "//include/envoy/server:fatal_action_interface", "//include/envoy/server:instance_interface", "//include/envoy/server:listener_manager_interface", "//include/envoy/server:options_interface", @@ -444,6 +445,7 @@ envoy_cc_library( "//source/common/router:rds_lib", "//source/common/runtime:runtime_lib", "//source/common/secret:secret_manager_impl_lib", + "//source/common/signal:fatal_error_handler_lib", "//source/common/singleton:manager_impl_lib", "//source/common/stats:thread_local_store_lib", "//source/common/upstream:cluster_manager_lib", diff --git a/source/server/connection_handler_impl.cc b/source/server/connection_handler_impl.cc index beba66b72f0b..91b92f763ffc 100644 --- a/source/server/connection_handler_impl.cc +++ b/source/server/connection_handler_impl.cc @@ -460,9 +460,10 @@ void ConnectionHandlerImpl::ActiveTcpListener::resumeListening() { void ConnectionHandlerImpl::ActiveTcpListener::newConnection( Network::ConnectionSocketPtr&& socket, std::unique_ptr stream_info) { - // Refresh local address in case it was restored by a listener filter like the original_dst - // filter. + // Refresh addresses in case they are modified by listener filters, such as proxy protocol or + // original_dst. stream_info->setDownstreamLocalAddress(socket->localAddress()); + stream_info->setDownstreamRemoteAddress(socket->remoteAddress()); // Find matching filter chain. const auto filter_chain = config_->filterChainManager().findFilterChain(*socket); diff --git a/source/server/hot_restarting_parent.cc b/source/server/hot_restarting_parent.cc index 874c19b11a5a..6898c0db9999 100644 --- a/source/server/hot_restarting_parent.cc +++ b/source/server/hot_restarting_parent.cc @@ -29,7 +29,7 @@ void HotRestartingParent::initialize(Event::Dispatcher& dispatcher, Server::Inst ASSERT(events == Event::FileReadyType::Read); onSocketEvent(); }, - Event::PlatformDefaultTriggerType, Event::FileReadyType::Read); + Event::FileTriggerType::Edge, Event::FileReadyType::Read); internal_ = std::make_unique(&server); } diff --git a/source/server/listener_impl.cc b/source/server/listener_impl.cc index b62d36dd071b..517f6263565e 100644 --- a/source/server/listener_impl.cc +++ b/source/server/listener_impl.cc @@ -38,15 +38,22 @@ namespace Envoy { namespace Server { namespace { +bool anyFilterChain( + const envoy::config::listener::v3::Listener& config, + std::function predicate) { + return (config.has_default_filter_chain() && predicate(config.default_filter_chain())) || + std::any_of(config.filter_chains().begin(), config.filter_chains().end(), predicate); +} + bool needTlsInspector(const envoy::config::listener::v3::Listener& config) { - return std::any_of(config.filter_chains().begin(), config.filter_chains().end(), - [](const auto& filter_chain) { - const auto& matcher = filter_chain.filter_chain_match(); - return matcher.transport_protocol() == "tls" || - (matcher.transport_protocol().empty() && - (!matcher.server_names().empty() || - !matcher.application_protocols().empty())); - }) && + return anyFilterChain(config, + [](const auto& filter_chain) { + const auto& matcher = filter_chain.filter_chain_match(); + return matcher.transport_protocol() == "tls" || + (matcher.transport_protocol().empty() && + (!matcher.server_names().empty() || + !matcher.application_protocols().empty())); + }) && !std::any_of( config.listener_filters().begin(), config.listener_filters().end(), [](const auto& filter) { @@ -55,6 +62,14 @@ bool needTlsInspector(const envoy::config::listener::v3::Listener& config) { filter.name() == "envoy.listener.tls_inspector"; }); } + +bool usesProxyProto(const envoy::config::listener::v3::Listener& config) { + // TODO(#14085): `use_proxy_proto` should be deprecated. + // Checking only the first or default filter chain is done for backwards compatibility. + return PROTOBUF_GET_WRAPPED_OR_DEFAULT( + config.filter_chains().empty() ? config.default_filter_chain() : config.filter_chains()[0], + use_proxy_proto, false); +} } // namespace ListenSocketFactoryImpl::ListenSocketFactoryImpl(ListenerComponentFactory& factory, @@ -458,21 +473,22 @@ void ListenerImpl::createListenerFilterFactories(Network::Socket::Type socket_ty } void ListenerImpl::validateFilterChains(Network::Socket::Type socket_type) { - if (config_.filter_chains().empty() && (socket_type == Network::Socket::Type::Stream || - !udp_listener_factory_->isTransportConnectionless())) { + if (config_.filter_chains().empty() && !config_.has_default_filter_chain() && + (socket_type == Network::Socket::Type::Stream || + !udp_listener_factory_->isTransportConnectionless())) { // If we got here, this is a tcp listener or connection-oriented udp listener, so ensure there // is a filter chain specified throw EnvoyException(fmt::format("error adding listener '{}': no filter chains specified", address_->asString())); } else if (udp_listener_factory_ != nullptr && !udp_listener_factory_->isTransportConnectionless()) { - for (auto& filter_chain : config_.filter_chains()) { - // Early fail if any filter chain doesn't have transport socket configured. - if (!filter_chain.has_transport_socket()) { - throw EnvoyException(fmt::format("error adding listener '{}': no transport socket " - "specified for connection oriented UDP listener", - address_->asString())); - } + // Early fail if any filter chain doesn't have transport socket configured. + if (anyFilterChain(config_, [](const auto& filter_chain) { + return !filter_chain.has_transport_socket(); + })) { + throw EnvoyException(fmt::format("error adding listener '{}': no transport socket " + "specified for connection oriented UDP listener", + address_->asString())); } } } @@ -528,7 +544,7 @@ void ListenerImpl::buildProxyProtocolListenerFilter() { // TODO(jrajahalme): This is the last listener filter on purpose. When filter chain matching // is implemented, this needs to be run after the filter chain has been // selected. - if (PROTOBUF_GET_WRAPPED_OR_DEFAULT(config_.filter_chains()[0], use_proxy_proto, false)) { + if (usesProxyProto(config_)) { auto& factory = Config::Utility::getAndCheckFactoryByName( Extensions::ListenerFilters::ListenerFilterNames::get().ProxyProtocol); @@ -712,10 +728,8 @@ bool ListenerImpl::supportUpdateFilterChain(const envoy::config::listener::v3::L return false; } - // See buildProxyProtocolListenerFilter(). Full listener update guarantees at least 1 filter chain - // at tcp listener. - if (PROTOBUF_GET_WRAPPED_OR_DEFAULT(config_.filter_chains()[0], use_proxy_proto, false) ^ - PROTOBUF_GET_WRAPPED_OR_DEFAULT(config.filter_chains()[0], use_proxy_proto, false)) { + // See buildProxyProtocolListenerFilter(). + if (usesProxyProto(config_) ^ usesProxyProto(config)) { return false; } diff --git a/source/server/server.cc b/source/server/server.cc index ee7792c719c7..214f9d045938 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -20,6 +20,7 @@ #include "envoy/network/dns.h" #include "envoy/registry/registry.h" #include "envoy/server/bootstrap_extension_config.h" +#include "envoy/server/instance.h" #include "envoy/server/options.h" #include "envoy/upstream/cluster_manager.h" @@ -40,6 +41,7 @@ #include "common/protobuf/utility.h" #include "common/router/rds_impl.h" #include "common/runtime/runtime_impl.h" +#include "common/signal/fatal_error_handler.h" #include "common/singleton/manager_impl.h" #include "common/stats/thread_local_store.h" #include "common/stats/timespan_impl.h" @@ -420,6 +422,26 @@ void InstanceImpl::initialize(const Options& options, factory.createBootstrapExtension(*config, serverFactoryContext())); } + // Register the fatal actions. + { + FatalAction::FatalActionPtrList safe_actions; + FatalAction::FatalActionPtrList unsafe_actions; + for (const auto& action_config : bootstrap_.fatal_actions()) { + auto& factory = + Config::Utility::getAndCheckFactory( + action_config.config()); + auto action = factory.createFatalActionFromProto(action_config, this); + + if (action->isAsyncSignalSafe()) { + safe_actions.push_back(std::move(action)); + } else { + unsafe_actions.push_back(std::move(action)); + } + } + Envoy::FatalErrorHandler::registerFatalActions( + std::move(safe_actions), std::move(unsafe_actions), api_->threadFactory()); + } + if (!bootstrap_.default_socket_interface().empty()) { auto& sock_name = bootstrap_.default_socket_interface(); auto sock = const_cast(Network::socketInterface(sock_name)); @@ -733,6 +755,7 @@ void InstanceImpl::terminate() { restarter_.shutdown(); ENVOY_LOG(info, "exiting"); ENVOY_FLUSH_LOG(); + FatalErrorHandler::clearFatalActionsOnTerminate(); } Runtime::Loader& InstanceImpl::runtime() { return Runtime::LoaderSingleton::get(); } diff --git a/test/common/buffer/buffer_fuzz.cc b/test/common/buffer/buffer_fuzz.cc index 4128ceea866d..7dc34ca3e58f 100644 --- a/test/common/buffer/buffer_fuzz.cc +++ b/test/common/buffer/buffer_fuzz.cc @@ -126,6 +126,8 @@ class StringBuffer : public Buffer::Instance { return {{const_cast(start()), size_}}; } + Buffer::RawSlice frontSlice() const override { return {const_cast(start()), size_}; } + uint64_t length() const override { return size_; } void* linearize(uint32_t /*size*/) override { diff --git a/test/common/buffer/owned_impl_test.cc b/test/common/buffer/owned_impl_test.cc index dc15d80b4b5d..e7249e2b6522 100644 --- a/test/common/buffer/owned_impl_test.cc +++ b/test/common/buffer/owned_impl_test.cc @@ -1256,6 +1256,13 @@ TEST_F(OwnedImplTest, MoveSmallSliceIntoNotEnoughFreeSpace) { TestBufferMove(4096 - 127, 128, 2); } +TEST_F(OwnedImplTest, FrontSlice) { + Buffer::OwnedImpl buffer; + EXPECT_EQ(0, buffer.frontSlice().len_); + buffer.add("a"); + EXPECT_EQ(1, buffer.frontSlice().len_); +} + } // namespace } // namespace Buffer } // namespace Envoy diff --git a/test/common/common/BUILD b/test/common/common/BUILD index 8f9ec5324dc8..c002da716b0a 100644 --- a/test/common/common/BUILD +++ b/test/common/common/BUILD @@ -269,6 +269,17 @@ envoy_cc_test( deps = ["//source/common/common:callback_impl_lib"], ) +envoy_cc_benchmark_binary( + name = "re_speed_test", + srcs = ["re_speed_test.cc"], + external_deps = ["benchmark"], + deps = [ + "//source/common/common:assert_lib", + "//source/common/common:utility_lib", + "@com_googlesource_code_re2//:re2", + ], +) + envoy_cc_benchmark_binary( name = "utility_speed_test", srcs = ["utility_speed_test.cc"], diff --git a/test/common/common/re_speed_test.cc b/test/common/common/re_speed_test.cc new file mode 100644 index 000000000000..0db62906e281 --- /dev/null +++ b/test/common/common/re_speed_test.cc @@ -0,0 +1,128 @@ +// Note: this should be run with --compilation_mode=opt, and would benefit from +// a quiescent system with disabled cstate power management. + +#include + +#include "common/common/assert.h" + +#include "absl/strings/string_view.h" +#include "benchmark/benchmark.h" +#include "re2/re2.h" + +// NOLINT(namespace-envoy) + +static const char* ClusterInputs[] = { + "cluster.no_trailing_dot", + "cluster.match.", + "cluster.match.normal", + "cluster.match.and.a.whole.lot.of.things.coming.after.the.matches.really.too.much.stuff", +}; + +static const char ClusterRePattern[] = "^cluster\\.((.*?)\\.)"; +static const char ClusterReAltPattern[] = "^cluster\\.(([^\\.]+)\\.).*"; + +// NOLINTNEXTLINE(readability-identifier-naming) +static void BM_StdRegex(benchmark::State& state) { + std::regex re(ClusterRePattern); + uint32_t passes = 0; + std::vector inputs; + for (const char* cluster_input : ClusterInputs) { + inputs.push_back(cluster_input); + } + + for (auto _ : state) { // NOLINT + for (const std::string& cluster_input : inputs) { + std::smatch match; + if (std::regex_search(cluster_input, match, re)) { + ASSERT(match.size() >= 3); + ASSERT(match[1] == "match."); + ASSERT(match[2] == "match"); + ++passes; + } + } + } + RELEASE_ASSERT(passes > 0, ""); +} +BENCHMARK(BM_StdRegex); + +// NOLINTNEXTLINE(readability-identifier-naming) +static void BM_StdRegexStringView(benchmark::State& state) { + std::regex re(ClusterRePattern); + std::vector inputs; + for (const char* cluster_input : ClusterInputs) { + inputs.push_back(cluster_input); + } + uint32_t passes = 0; + for (auto _ : state) { // NOLINT + for (absl::string_view cluster_input : inputs) { + std::match_results smatch; + if (std::regex_search(cluster_input.begin(), cluster_input.end(), smatch, re)) { + ASSERT(smatch.size() >= 3); + ASSERT(smatch[1] == "match."); + ASSERT(smatch[2] == "match"); + ++passes; + } + } + } + RELEASE_ASSERT(passes > 0, ""); +} +BENCHMARK(BM_StdRegexStringView); + +// NOLINTNEXTLINE(readability-identifier-naming) +static void BM_StdRegexStringViewAltPattern(benchmark::State& state) { + std::regex re(ClusterReAltPattern); + std::vector inputs; + for (const char* cluster_input : ClusterInputs) { + inputs.push_back(cluster_input); + } + uint32_t passes = 0; + for (auto _ : state) { // NOLINT + for (absl::string_view cluster_input : inputs) { + std::match_results smatch; + if (std::regex_search(cluster_input.begin(), cluster_input.end(), smatch, re)) { + ASSERT(smatch.size() >= 3); + ASSERT(smatch[1] == "match."); + ASSERT(smatch[2] == "match"); + ++passes; + } + } + } + RELEASE_ASSERT(passes > 0, ""); +} +BENCHMARK(BM_StdRegexStringViewAltPattern); + +// NOLINTNEXTLINE(readability-identifier-naming) +static void BM_RE2(benchmark::State& state) { + re2::RE2 re(ClusterRePattern); + uint32_t passes = 0; + for (auto _ : state) { // NOLINT + for (const char* cluster_input : ClusterInputs) { + re2::StringPiece match1, match2; + if (re2::RE2::PartialMatch(cluster_input, re, &match1, &match2)) { + ASSERT(match1 == "match."); + ASSERT(match2 == "match"); + ++passes; + } + } + } + RELEASE_ASSERT(passes > 0, ""); +} +BENCHMARK(BM_RE2); + +// NOLINTNEXTLINE(readability-identifier-naming) +static void BM_RE2_AltPattern(benchmark::State& state) { + re2::RE2 re(ClusterReAltPattern); + uint32_t passes = 0; + for (auto _ : state) { // NOLINT + for (const char* cluster_input : ClusterInputs) { + re2::StringPiece match1, match2; + if (re2::RE2::PartialMatch(cluster_input, re, &match1, &match2)) { + ASSERT(match1 == "match."); + ASSERT(match2 == "match"); + ++passes; + } + } + } + RELEASE_ASSERT(passes > 0, ""); +} +BENCHMARK(BM_RE2_AltPattern); diff --git a/test/common/config/version_converter_test.cc b/test/common/config/version_converter_test.cc index 65bb66145fc7..1c7e949fb625 100644 --- a/test/common/config/version_converter_test.cc +++ b/test/common/config/version_converter_test.cc @@ -71,6 +71,18 @@ TEST(VersionConverterProto, UpgradeNextVersion) { VersionConverter::upgrade(source, dst); } +// Validate that even if we pass in a newer proto version that is being passed off as an older +// version (e.g. via a type URL mistake), we don't crash. This is a regression test for +// https://github.com/envoyproxy/envoy/issues/13681. +TEST(VersionConverterProto, UpgradeWithConfusedTypes) { + test::common::config::NextVersion source_next; + source_next.mutable_new_message_in_this_version(); + test::common::config::PreviousVersion source; + ASSERT_TRUE(source.ParseFromString(source_next.SerializeAsString())); + test::common::config::NextVersion dst; + VersionConverter::upgrade(source, dst); +} + // Bad UTF-8 can fail wire cast during upgrade. TEST(VersionConverterTest, UpgradeException) { API_NO_BOOST(envoy::api::v2::Cluster) source; diff --git a/test/common/conn_pool/conn_pool_base_test.cc b/test/common/conn_pool/conn_pool_base_test.cc index bf2b1946967c..0096c95f46e2 100644 --- a/test/common/conn_pool/conn_pool_base_test.cc +++ b/test/common/conn_pool/conn_pool_base_test.cc @@ -12,6 +12,7 @@ namespace Envoy { namespace ConnectionPool { using testing::AnyNumber; +using testing::Invoke; using testing::InvokeWithoutArgs; using testing::Return; @@ -21,7 +22,9 @@ class TestActiveClient : public ActiveClient { void close() override { onEvent(Network::ConnectionEvent::LocalClose); } uint64_t id() const override { return 1; } bool closingWithIncompleteStream() const override { return false; } - size_t numActiveStreams() const override { return 1; } + uint32_t numActiveStreams() const override { return active_streams_; } + + uint32_t active_streams_{}; }; class TestPendingStream : public PendingStream { @@ -37,8 +40,7 @@ class TestConnPoolImplBase : public ConnPoolImplBase { using ConnPoolImplBase::ConnPoolImplBase; ConnectionPool::Cancellable* newPendingStream(AttachContext& context) override { auto entry = std::make_unique(*this, context); - LinkedList::moveIntoList(std::move(entry), pending_streams_); - return pending_streams_.front().get(); + return addPendingStream(std::move(entry)); } MOCK_METHOD(ActiveClientPtr, instantiateActiveClient, ()); MOCK_METHOD(void, onPoolFailure, @@ -50,7 +52,7 @@ class TestConnPoolImplBase : public ConnPoolImplBase { class ConnPoolImplBaseTest : public testing::Test { public: ConnPoolImplBaseTest() - : pool_(host_, Upstream::ResourcePriority::Default, dispatcher_, nullptr, nullptr) { + : pool_(host_, Upstream::ResourcePriority::Default, dispatcher_, nullptr, nullptr, state_) { // Default connections to 1024 because the tests shouldn't be relying on the // connection resource limit for most tests. cluster_->resetResourceManager(1024, 1024, 1024, 1, 1); @@ -60,10 +62,20 @@ class ConnPoolImplBaseTest : public testing::Test { ret->real_host_description_ = descr_; return ret; })); + ON_CALL(pool_, onPoolReady(_, _)) + .WillByDefault(Invoke([](ActiveClient& client, AttachContext&) -> void { + ++(reinterpret_cast(&client)->active_streams_); + })); } +#define CHECK_STATE(active, pending, capacity) \ + EXPECT_EQ(state_.pending_streams_, pending); \ + EXPECT_EQ(state_.active_streams_, active); \ + EXPECT_EQ(state_.connecting_stream_capacity_, capacity) + uint32_t stream_limit_ = 100; uint32_t concurrent_streams_ = 1; + Upstream::ClusterConnectivityState state_; std::shared_ptr> descr_{ new NiceMock()}; std::shared_ptr cluster_{new NiceMock()}; @@ -79,10 +91,13 @@ TEST_F(ConnPoolImplBaseTest, BasicPrefetch) { ON_CALL(*cluster_, perUpstreamPrefetchRatio).WillByDefault(Return(1.5)); // On new stream, create 2 connections. + CHECK_STATE(0 /*active*/, 0 /*pending*/, 0 /*connecting capacity*/); EXPECT_CALL(pool_, instantiateActiveClient).Times(2); auto cancelable = pool_.newStream(context_); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 2 /*connecting capacity*/); cancelable->cancel(ConnectionPool::CancelPolicy::CloseExcess); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 1 /*connecting capacity*/); pool_.destructAllConnections(); } @@ -95,6 +110,7 @@ TEST_F(ConnPoolImplBaseTest, PrefetchOnDisconnect) { // On new stream, create 2 connections. EXPECT_CALL(pool_, instantiateActiveClient).Times(2); pool_.newStream(context_); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 2 /*connecting capacity*/); // If a connection fails, existing connections are purged. If a retry causes // a new stream, make sure we create the correct number of connections. @@ -103,6 +119,7 @@ TEST_F(ConnPoolImplBaseTest, PrefetchOnDisconnect) { })); EXPECT_CALL(pool_, instantiateActiveClient).Times(1); clients_[0]->close(); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 2 /*connecting capacity*/); EXPECT_CALL(pool_, onPoolFailure); pool_.destructAllConnections(); @@ -118,6 +135,7 @@ TEST_F(ConnPoolImplBaseTest, NoPrefetchIfUnhealthy) { // On new stream, create 1 connection. EXPECT_CALL(pool_, instantiateActiveClient).Times(1); auto cancelable = pool_.newStream(context_); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 1 /*connecting capacity*/); cancelable->cancel(ConnectionPool::CancelPolicy::CloseExcess); pool_.destructAllConnections(); @@ -146,11 +164,13 @@ TEST_F(ConnPoolImplBaseTest, ExplicitPrefetch) { // With global prefetch off, we won't prefetch. EXPECT_FALSE(pool_.maybePrefetch(0)); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 0 /*connecting capacity*/); // With prefetch ratio of 1.1, we'll prefetch two connections. // Currently, no number of subsequent calls to prefetch will increase that. EXPECT_TRUE(pool_.maybePrefetch(1.1)); EXPECT_TRUE(pool_.maybePrefetch(1.1)); EXPECT_FALSE(pool_.maybePrefetch(1.1)); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 2 /*connecting capacity*/); // With a higher prefetch ratio, more connections may be prefetched. EXPECT_TRUE(pool_.maybePrefetch(3)); diff --git a/test/common/event/BUILD b/test/common/event/BUILD index 2eaba5a4f461..d5448366b593 100644 --- a/test/common/event/BUILD +++ b/test/common/event/BUILD @@ -11,7 +11,6 @@ envoy_package() envoy_cc_test( name = "dispatcher_impl_test", srcs = ["dispatcher_impl_test.cc"], - tags = ["fails_on_windows"], deps = [ "//source/common/api:api_lib", "//source/common/event:deferred_task", @@ -30,7 +29,6 @@ envoy_cc_test( envoy_cc_test( name = "file_event_impl_test", srcs = ["file_event_impl_test.cc"], - tags = ["fails_on_windows"], deps = [ "//include/envoy/event:file_event_interface", "//source/common/event:dispatcher_includes", diff --git a/test/common/event/dispatcher_impl_test.cc b/test/common/event/dispatcher_impl_test.cc index cbb0119f0ff2..468c79bb62b7 100644 --- a/test/common/event/dispatcher_impl_test.cc +++ b/test/common/event/dispatcher_impl_test.cc @@ -458,6 +458,51 @@ TEST_F(DispatcherImplTest, IsThreadSafe) { EXPECT_FALSE(dispatcher_->isThreadSafe()); } +class TestFatalAction : public Server::Configuration::FatalAction { +public: + void run(const ScopeTrackedObject* /*current_object*/) override { ++times_ran_; } + bool isAsyncSignalSafe() const override { return true; } + int getNumTimesRan() { return times_ran_; } + +private: + int times_ran_ = 0; +}; + +TEST_F(DispatcherImplTest, OnlyRunsFatalActionsIfRunningOnSameThread) { + FatalAction::FatalActionPtrList actions; + actions.emplace_back(std::make_unique()); + auto* action = dynamic_cast(actions.front().get()); + + ASSERT_EQ(action->getNumTimesRan(), 0); + + // Should not run as dispatcher isn't running yet + auto non_running_dispatcher = api_->allocateDispatcher("non_running_thread"); + static_cast(non_running_dispatcher.get()) + ->runFatalActionsOnTrackedObject(actions); + ASSERT_EQ(action->getNumTimesRan(), 0); + + // Should not run when not on same thread + static_cast(dispatcher_.get())->runFatalActionsOnTrackedObject(actions); + ASSERT_EQ(action->getNumTimesRan(), 0); + + // Should run since on same thread as dispatcher + dispatcher_->post([this, &actions]() { + { + Thread::LockGuard lock(mu_); + static_cast(dispatcher_.get())->runFatalActionsOnTrackedObject(actions); + work_finished_ = true; + } + cv_.notifyOne(); + }); + + Thread::LockGuard lock(mu_); + while (!work_finished_) { + cv_.wait(mu_); + } + + EXPECT_EQ(action->getNumTimesRan(), 1); +} + class NotStartedDispatcherImplTest : public testing::Test { protected: NotStartedDispatcherImplTest() @@ -1202,7 +1247,7 @@ TEST_F(DispatcherWithWatchdogTest, TouchBeforeTimer) { } TEST_F(DispatcherWithWatchdogTest, TouchBeforeFdEvent) { - os_fd_t fd = os_sys_calls_.socket(AF_INET6, SOCK_STREAM, 0).rc_; + os_fd_t fd = os_sys_calls_.socket(AF_INET6, SOCK_DGRAM, 0).rc_; ASSERT_TRUE(SOCKET_VALID(fd)); ReadyWatcher watcher; @@ -1213,7 +1258,7 @@ TEST_F(DispatcherWithWatchdogTest, TouchBeforeFdEvent) { file_event->activate(FileReadyType::Read); InSequence s; - EXPECT_CALL(*watchdog_, touch()); + EXPECT_CALL(*watchdog_, touch()).Times(2); EXPECT_CALL(watcher, ready()); dispatcher_->run(Dispatcher::RunType::NonBlock); } diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index 7116fd8bc5f7..974c498dc905 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -47,14 +47,9 @@ class FileEventImplTest : public testing::Test { Api::OsSysCalls& os_sys_calls_; }; -class FileEventImplActivateTest - : public testing::TestWithParam> { +class FileEventImplActivateTest : public testing::TestWithParam { public: - FileEventImplActivateTest() : os_sys_calls_(Api::OsSysCallsSingleton::get()) { - Runtime::LoaderSingleton::getExisting()->mergeValues( - {{"envoy.reloadable_features.activate_fds_next_event_loop", - activateFdsNextEventLoop() ? "true" : "false"}}); - } + FileEventImplActivateTest() : os_sys_calls_(Api::OsSysCallsSingleton::get()) {} static void onWatcherReady(evwatch*, const evwatch_prepare_cb_info*, void* arg) { // `arg` contains the ReadyWatcher passed in from evwatch_prepare_new. @@ -62,19 +57,15 @@ class FileEventImplActivateTest watcher->ready(); } - int domain() { - return std::get<0>(GetParam()) == Network::Address::IpVersion::v4 ? AF_INET : AF_INET6; - } - bool activateFdsNextEventLoop() { return std::get<1>(GetParam()); } + int domain() { return GetParam() == Network::Address::IpVersion::v4 ? AF_INET : AF_INET6; } protected: Api::OsSysCalls& os_sys_calls_; TestScopedRuntime scoped_runtime_; }; -INSTANTIATE_TEST_SUITE_P( - IpVersions, FileEventImplActivateTest, - testing::Combine(testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), testing::Bool())); +INSTANTIATE_TEST_SUITE_P(IpVersions, FileEventImplActivateTest, + testing::ValuesIn(TestEnvironment::getIpVersionsForTest())); TEST_P(FileEventImplActivateTest, Activate) { os_fd_t fd = os_sys_calls_.socket(domain(), SOCK_STREAM, 0).rc_; @@ -115,7 +106,7 @@ TEST_P(FileEventImplActivateTest, Activate) { } TEST_P(FileEventImplActivateTest, ActivateChaining) { - os_fd_t fd = os_sys_calls_.socket(domain(), SOCK_STREAM, 0).rc_; + os_fd_t fd = os_sys_calls_.socket(domain(), SOCK_DGRAM, 0).rc_; ASSERT_TRUE(SOCKET_VALID(fd)); Api::ApiPtr api = Api::createApiForTest(); @@ -160,29 +151,17 @@ TEST_P(FileEventImplActivateTest, ActivateChaining) { EXPECT_CALL(fd_event, ready()); EXPECT_CALL(read_event, ready()); EXPECT_CALL(write_event, ready()); - if (activateFdsNextEventLoop()) { - // Second loop iteration: handle write and close events scheduled while handling read. - EXPECT_CALL(prepare_watcher, ready()); - EXPECT_CALL(fd_event, ready()); - EXPECT_CALL(write_event, ready()); - EXPECT_CALL(closed_event, ready()); - // Third loop iteration: handle close event scheduled while handling write. - EXPECT_CALL(prepare_watcher, ready()); - EXPECT_CALL(fd_event, ready()); - EXPECT_CALL(closed_event, ready()); - // Fourth loop iteration: poll returned no new real events. - EXPECT_CALL(prepare_watcher, ready()); - } else { - // Same loop iteration activation: handle write and close events scheduled while handling read. - EXPECT_CALL(fd_event, ready()); - EXPECT_CALL(write_event, ready()); - EXPECT_CALL(closed_event, ready()); - // Second same loop iteration activation: handle close event scheduled while handling write. - EXPECT_CALL(fd_event, ready()); - EXPECT_CALL(closed_event, ready()); - // Second loop iteration: poll returned no new real events. - EXPECT_CALL(prepare_watcher, ready()); - } + // Second loop iteration: handle write and close events scheduled while handling read. + EXPECT_CALL(prepare_watcher, ready()); + EXPECT_CALL(fd_event, ready()); + EXPECT_CALL(write_event, ready()); + EXPECT_CALL(closed_event, ready()); + // Third loop iteration: handle close event scheduled while handling write. + EXPECT_CALL(prepare_watcher, ready()); + EXPECT_CALL(fd_event, ready()); + EXPECT_CALL(closed_event, ready()); + // Fourth loop iteration: poll returned no new real events. + EXPECT_CALL(prepare_watcher, ready()); file_event->activate(FileReadyType::Read); dispatcher->run(Event::Dispatcher::RunType::NonBlock); @@ -191,7 +170,7 @@ TEST_P(FileEventImplActivateTest, ActivateChaining) { } TEST_P(FileEventImplActivateTest, SetEnableCancelsActivate) { - os_fd_t fd = os_sys_calls_.socket(domain(), SOCK_STREAM, 0).rc_; + os_fd_t fd = os_sys_calls_.socket(domain(), SOCK_DGRAM, 0).rc_; ASSERT_TRUE(SOCKET_VALID(fd)); Api::ApiPtr api = Api::createApiForTest(); diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index be23d01b2791..2e728d1d2c8d 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -298,8 +298,9 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { EXPECT_CALL(*mock_host_, createConnection_(_, _)).WillRepeatedly(Return(connection_data)); EXPECT_CALL(*mock_host_, cluster()).WillRepeatedly(ReturnRef(*cluster_info_ptr_)); EXPECT_CALL(*mock_host_description_, locality()).WillRepeatedly(ReturnRef(host_locality_)); - http_conn_pool_ = Http::Http2::allocateConnPool( - *dispatcher_, random_, host_ptr_, Upstream::ResourcePriority::Default, nullptr, nullptr); + http_conn_pool_ = Http::Http2::allocateConnPool(*dispatcher_, random_, host_ptr_, + Upstream::ResourcePriority::Default, nullptr, + nullptr, state_); EXPECT_CALL(cm_, httpConnPoolForCluster(_, _, _, _)) .WillRepeatedly(Return(http_conn_pool_.get())); http_async_client_ = std::make_unique( @@ -456,6 +457,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { const TestMetadata empty_metadata_; // Fake/mock infrastructure for Grpc::AsyncClientImpl upstream. + Upstream::ClusterConnectivityState state_; Network::TransportSocketPtr async_client_transport_socket_{new Network::RawBufferSocket()}; const std::string fake_cluster_name_{"fake_cluster"}; Upstream::MockClusterManager cm_; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 48a1dad0da8e..25ba456a87fe 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -374,6 +374,7 @@ TEST_P(CodecNetworkTest, SendData) { upstream_connection_->write(data, false); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> Http::Status { EXPECT_EQ(full_data, data.toString()); + data.drain(data.length()); dispatcher_->exit(); return Http::okStatus(); })); @@ -397,10 +398,12 @@ TEST_P(CodecNetworkTest, SendHeadersAndClose) { .Times(2) .WillOnce(Invoke([&](Buffer::Instance& data) -> Http::Status { EXPECT_EQ(full_data, data.toString()); + data.drain(data.length()); return Http::okStatus(); })) .WillOnce(Invoke([&](Buffer::Instance& data) -> Http::Status { EXPECT_EQ("", data.toString()); + data.drain(data.length()); return Http::okStatus(); })); // Because the headers are not complete, the disconnect will reset the stream. @@ -435,6 +438,7 @@ TEST_P(CodecNetworkTest, SendHeadersAndCloseUnderReadDisable) { .Times(2) .WillOnce(Invoke([&](Buffer::Instance& data) -> Http::Status { EXPECT_EQ(full_data, data.toString()); + data.drain(data.length()); return Http::okStatus(); })) .WillOnce(Invoke([&](Buffer::Instance& data) -> Http::Status { diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index 3803add0f724..0e6e2a54cc29 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -56,6 +56,7 @@ class ConnPoolImplForTest : public FixedHttpConnPoolImpl { : FixedHttpConnPoolImpl( Upstream::makeTestHost(cluster, "tcp://127.0.0.1:9000"), Upstream::ResourcePriority::Default, dispatcher, nullptr, nullptr, random_generator, + state_, [](HttpConnPoolImplBase* pool) { return std::make_unique(*pool); }, [](Upstream::Host::CreateConnectionData&, HttpConnPoolImplBase*) { return nullptr; // Not used: createCodecClient overloaded. @@ -66,7 +67,7 @@ class ConnPoolImplForTest : public FixedHttpConnPoolImpl { ~ConnPoolImplForTest() override { EXPECT_EQ(0U, ready_clients_.size()); EXPECT_EQ(0U, busy_clients_.size()); - EXPECT_EQ(0U, pending_streams_.size()); + EXPECT_FALSE(hasPendingStreams()); } struct TestCodecClient { @@ -121,6 +122,7 @@ class ConnPoolImplForTest : public FixedHttpConnPoolImpl { void expectAndRunUpstreamReady() { post_cb_(); } + Upstream::ClusterConnectivityState state_; Api::ApiPtr api_; Event::MockDispatcher& mock_dispatcher_; Event::PostCb post_cb_; diff --git a/test/common/http/http2/codec_impl_test.cc b/test/common/http/http2/codec_impl_test.cc index e2c749c55940..5430db5f61d3 100644 --- a/test/common/http/http2/codec_impl_test.cc +++ b/test/common/http/http2/codec_impl_test.cc @@ -782,8 +782,8 @@ TEST_P(Http2CodecImplTest, SmallMetadataVecTest) { // Generates a valid stream_id by sending a request header. TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); - EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); - EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, true).ok()); + EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); + EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, false).ok()); MetadataMapVector metadata_map_vector; const int size = 10; @@ -812,8 +812,8 @@ TEST_P(Http2CodecImplTest, LargeMetadataVecTest) { // Generates a valid stream_id by sending a request header. TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); - EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); - EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, true).ok()); + EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); + EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, false).ok()); MetadataMapVector metadata_map_vector; const int size = 10; @@ -839,8 +839,8 @@ TEST_P(Http2CodecImplTest, BadMetadataVecReceivedTest) { // Generates a valid stream_id by sending a request header. TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); - EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); - EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, true).ok()); + EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); + EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, false).ok()); MetadataMap metadata_map = { {"header_key1", "header_value1"}, @@ -886,6 +886,27 @@ TEST_P(Http2CodecImplTest, EncodeMetadataWhileDispatchingTest) { EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, true).ok()); } +// Verifies that metadata is not decoded after the stream ended. +TEST_P(Http2CodecImplTest, NoMetadataEndStreamTest) { + allow_metadata_ = true; + initialize(); + + // Generates a valid stream_id by sending a request header, and end stream. + TestRequestHeaderMapImpl request_headers; + HttpTestUtility::addDefaultHeaders(request_headers); + EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); + EXPECT_TRUE(request_encoder_->encodeHeaders(request_headers, true).ok()); + + const MetadataMap metadata_map = {{"header_key1", "header_value1"}}; + MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); + MetadataMapVector metadata_map_vector; + metadata_map_vector.push_back(std::move(metadata_map_ptr)); + + // The metadata decoding will not be called after the stream has ended. + EXPECT_CALL(request_decoder_, decodeMetadata_(_)).Times(0); + request_encoder_->encodeMetadata(metadata_map_vector); +} + // Validate the keepalive PINGs are sent and received correctly. TEST_P(Http2CodecImplTest, ConnectionKeepalive) { constexpr uint32_t interval_ms = 100; diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 90b7a48350bf..47d6799a4c8d 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -41,10 +41,11 @@ class TestConnPoolImpl : public FixedHttpConnPoolImpl { TestConnPoolImpl(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + Envoy::Upstream::ClusterConnectivityState& state) : FixedHttpConnPoolImpl( std::move(host), std::move(priority), dispatcher, options, transport_socket_options, - random_generator, + random_generator, state, [](HttpConnPoolImplBase* pool) { return std::make_unique(*pool); }, [](Upstream::Host::CreateConnectionData&, HttpConnPoolImplBase*) { return nullptr; }, std::vector{Protocol::Http2}) {} @@ -73,8 +74,9 @@ class Http2ConnPoolImplTest : public testing::Test { Http2ConnPoolImplTest() : api_(Api::createApiForTest(stats_store_)), - pool_(std::make_unique( - dispatcher_, random_, host_, Upstream::ResourcePriority::Default, nullptr, nullptr)) { + pool_(std::make_unique(dispatcher_, random_, host_, + Upstream::ResourcePriority::Default, nullptr, + nullptr, state_)) { // Default connections to 1024 because the tests shouldn't be relying on the // connection resource limit for most tests. cluster_->resetResourceManager(1024, 1024, 1024, 1, 1); @@ -172,6 +174,12 @@ class Http2ConnPoolImplTest : public testing::Test { // Asserts that the provided requests receives onPoolFailure. void expectStreamReset(ActiveTestRequest& r); +// Use a macro to avoid tons of cut and paste, but to retain line numbers on error. +#define CHECK_STATE(active, pending, capacity) \ + EXPECT_EQ(state_.pending_streams_, pending); \ + EXPECT_EQ(state_.active_streams_, active); \ + EXPECT_EQ(state_.connecting_stream_capacity_, capacity); + /** * Closes a test client. */ @@ -195,6 +203,7 @@ class Http2ConnPoolImplTest : public testing::Test { MOCK_METHOD(void, onClientDestroy, ()); + Upstream::ClusterConnectivityState state_; int timer_index_{}; int connection_index_{}; Stats::IsolatedStoreImpl stats_store_; @@ -327,8 +336,8 @@ TEST_F(Http2ConnPoolImplTest, VerifyAlpnFallback) { // Recreate the conn pool so that the host re-evaluates the transport socket match, arriving at // our test transport socket factory. host_ = Upstream::makeTestHost(cluster_, "tcp://127.0.0.1:80"); - pool_ = std::make_unique(dispatcher_, random_, host_, - Upstream::ResourcePriority::Default, nullptr, nullptr); + pool_ = std::make_unique( + dispatcher_, random_, host_, Upstream::ResourcePriority::Default, nullptr, nullptr, state_); // This requires some careful set up of expectations ordering: the call to createTransportSocket // happens before all the connection set up but after the test client is created (due to some) @@ -960,8 +969,12 @@ TEST_F(Http2ConnPoolImplTest, VerifyBufferLimits) { InSequence s; expectClientCreate(8192); ActiveTestRequest r1(*this, 0, false); + // 1 stream. HTTP/2 defaults to 536870912 streams/connection. + CHECK_STATE(0 /*active*/, 1 /*pending*/, 536870912 /*capacity*/); expectClientConnect(0, r1); + // capacity goes down by one as one stream is used. + CHECK_STATE(1 /*active*/, 0 /*pending*/, 536870911 /*capacity*/); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); EXPECT_TRUE( r1.callbacks_.outer_encoder_ @@ -974,6 +987,7 @@ TEST_F(Http2ConnPoolImplTest, VerifyBufferLimits) { test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 0 /*capacity*/); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_destroy_.value()); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_destroy_remote_.value()); @@ -1391,16 +1405,19 @@ TEST_F(Http2ConnPoolImplTest, PrefetchWithoutMultiplexing) { // kick off 2 connections. expectClientsCreate(2); ActiveTestRequest r1(*this, 0, false); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 2 /*capacity*/); // With another incoming request, we'll have 2 in flight and want 1.5*2 so // create one connection. expectClientsCreate(1); ActiveTestRequest r2(*this, 0, false); + CHECK_STATE(0 /*active*/, 2 /*pending*/, 3 /*capacity*/); // With a third request we'll have 3 in flight and want 1.5*3 -> 5 so kick off // two again. expectClientsCreate(2); ActiveTestRequest r3(*this, 0, false); + CHECK_STATE(0 /*active*/, 3 /*pending*/, 5 /*capacity*/); r1.handle_->cancel(Envoy::ConnectionPool::CancelPolicy::CloseExcess); r2.handle_->cancel(Envoy::ConnectionPool::CancelPolicy::CloseExcess); @@ -1436,11 +1453,13 @@ TEST_F(Http2ConnPoolImplTest, PrefetchWithMultiplexing) { // only kick off 1 connection. expectClientsCreate(1); ActiveTestRequest r1(*this, 0, false); + CHECK_STATE(0 /*active*/, 1 /*pending*/, 2 /*capacity*/); // With another incoming request, we'll have capacity(2) in flight and want 1.5*2 so // create an additional connection. expectClientsCreate(1); ActiveTestRequest r2(*this, 0, false); + CHECK_STATE(0 /*active*/, 2 /*pending*/, 4 /*capacity*/); // Clean up. r1.handle_->cancel(Envoy::ConnectionPool::CancelPolicy::CloseExcess); @@ -1534,6 +1553,44 @@ TEST_F(Http2ConnPoolImplTest, MaybePrefetch) { closeAllClients(); } +TEST_F(Http2ConnPoolImplTest, TestStateWithMultiplexing) { + cluster_->http2_options_.mutable_max_concurrent_streams()->set_value(2); + cluster_->max_requests_per_connection_ = 4; + + expectClientsCreate(1); + ActiveTestRequest r1(*this, 0, false); + // Initially, capacity is based on concurrency and capped at 2. + CHECK_STATE(0 /*active*/, 1 /*pending*/, 2 /*capacity*/); + expectClientConnect(0, r1); + // Now the stream is active, remaining concurrency capacity is 1 + CHECK_STATE(1 /*active*/, 0 /*pending*/, 1 /*capacity*/); + + // With one more stream, remaining concurrency capacity is 0. + ActiveTestRequest r2(*this, 0, true); + CHECK_STATE(2 /*active*/, 0 /*pending*/, 0 /*capacity*/); + + // If one stream closes, concurrency capacity goes to 1 (2 remaining streams) + completeRequest(r1); + CHECK_STATE(1 /*active*/, 0 /*pending*/, 1 /*capacity*/); + + // Assigning a new stream, concurrency capacity returns to 0 (1 remaining stream); + ActiveTestRequest r3(*this, 0, true); + CHECK_STATE(2 /*active*/, 0 /*pending*/, 0 /*capacity*/); + + // Closing a stream, capacity returns to 1 (both concurrency and remaining streams) + completeRequest(r2); + CHECK_STATE(1 /*active*/, 0 /*pending*/, 1 /*capacity*/); + + // Closing another, capacity remains at 1, as there is only 1 remaining stream. + completeRequest(r3); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 1 /*capacity*/); + + // Clean up with an outstanding stream. + pool_->drainConnections(); + closeAllClients(); + CHECK_STATE(0 /*active*/, 0 /*pending*/, 0 /*capacity*/); +} + } // namespace Http2 } // namespace Http } // namespace Envoy diff --git a/test/common/http/http2/http2_frame.cc b/test/common/http/http2/http2_frame.cc index 34decb609a46..f7eda300935d 100644 --- a/test/common/http/http2/http2_frame.cc +++ b/test/common/http/http2/http2_frame.cc @@ -323,6 +323,16 @@ Http2Frame Http2Frame::makeMalformedRequestWithZerolenHeader(uint32_t stream_ind return frame; } +Http2Frame Http2Frame::makeMalformedResponseWithZerolenHeader(uint32_t stream_index) { + Http2Frame frame; + frame.buildHeader(Type::Headers, 0, orFlags(HeadersFlags::EndStream, HeadersFlags::EndHeaders), + makeNetworkOrderStreamId(stream_index)); + frame.appendStaticHeader(StaticHeaderIndex::Status200); + frame.appendEmptyHeader(); + frame.adjustPayloadSize(); + return frame; +} + Http2Frame Http2Frame::makeRequest(uint32_t stream_index, absl::string_view host, absl::string_view path) { Http2Frame frame; diff --git a/test/common/http/http2/http2_frame.h b/test/common/http/http2/http2_frame.h index b2592891ccee..a077e2601bf2 100644 --- a/test/common/http/http2/http2_frame.h +++ b/test/common/http/http2/http2_frame.h @@ -142,6 +142,7 @@ class Http2Frame { static Http2Frame makeMalformedRequestWithZerolenHeader(uint32_t stream_index, absl::string_view host, absl::string_view path); + static Http2Frame makeMalformedResponseWithZerolenHeader(uint32_t stream_index); static Http2Frame makeRequest(uint32_t stream_index, absl::string_view host, absl::string_view path); static Http2Frame makeRequest(uint32_t stream_index, absl::string_view host, diff --git a/test/common/http/mixed_conn_pool_test.cc b/test/common/http/mixed_conn_pool_test.cc index f48b37afdcf7..578070cf9bec 100644 --- a/test/common/http/mixed_conn_pool_test.cc +++ b/test/common/http/mixed_conn_pool_test.cc @@ -21,11 +21,11 @@ namespace { // TODO(alyssawilk) replace this with the MixedConnectionPool once it lands. class ConnPoolImplForTest : public HttpConnPoolImplBase { public: - ConnPoolImplForTest(Event::MockDispatcher& dispatcher, Random::RandomGenerator& random, - Upstream::ClusterInfoConstSharedPtr cluster) + ConnPoolImplForTest(Event::MockDispatcher& dispatcher, Upstream::ClusterConnectivityState& state, + Random::RandomGenerator& random, Upstream::ClusterInfoConstSharedPtr cluster) : HttpConnPoolImplBase(Upstream::makeTestHost(cluster, "tcp://127.0.0.1:9000"), Upstream::ResourcePriority::Default, dispatcher, nullptr, nullptr, - random, {Http::Protocol::Http2, Http::Protocol::Http11}) {} + random, state, {Http::Protocol::Http2, Http::Protocol::Http11}) {} Envoy::ConnectionPool::ActiveClientPtr instantiateActiveClient() override { return nullptr; } Http::Protocol protocol() const override { return Http::Protocol::Http2; } @@ -40,12 +40,13 @@ class ConnPoolImplForTest : public HttpConnPoolImplBase { class MixedConnPoolImplTest : public testing::Test { public: MixedConnPoolImplTest() - : conn_pool_(std::make_unique(dispatcher_, random_, cluster_)) {} + : conn_pool_(std::make_unique(dispatcher_, state_, random_, cluster_)) {} ~MixedConnPoolImplTest() override { EXPECT_EQ("", TestUtility::nonZeroedGauges(cluster_->stats_store_.gauges())); } + Upstream::ClusterConnectivityState state_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; std::unique_ptr conn_pool_; diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index aab097ee10b8..deadc876a03c 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -1098,6 +1098,12 @@ TEST_P(ConnectionImplTest, WriteWithWatermarks) { Invoke(client_write_buffer_, &MockWatermarkBuffer::baseMove))); NiceMock os_sys_calls; TestThreadsafeSingletonInjector os_calls(&os_sys_calls); + + EXPECT_CALL(os_sys_calls, readv(_, _, _)) + .WillRepeatedly(Invoke([&](os_fd_t, const iovec*, int) -> Api::SysCallSizeResult { + return {-1, SOCKET_ERROR_AGAIN}; + })); + EXPECT_CALL(os_sys_calls, writev(_, _, _)) .WillOnce(Invoke([&](os_fd_t, const iovec*, int) -> Api::SysCallSizeResult { dispatcher_->exit(); @@ -1188,6 +1194,7 @@ TEST_P(ConnectionImplTest, WatermarkFuzzing) { EXPECT_CALL(os_sys_calls, writev(_, _, _)) .WillOnce(Invoke([&](os_fd_t, const iovec*, int) -> Api::SysCallSizeResult { client_write_buffer_->drain(bytes_to_flush); + dispatcher_->exit(); return {-1, SOCKET_ERROR_AGAIN}; })) .WillRepeatedly(Invoke([&](os_fd_t, const iovec*, int) -> Api::SysCallSizeResult { @@ -1195,7 +1202,7 @@ TEST_P(ConnectionImplTest, WatermarkFuzzing) { })); client_connection_->write(buffer_to_write, false); - dispatcher_->run(Event::Dispatcher::RunType::NonBlock); + dispatcher_->run(Event::Dispatcher::RunType::Block); } EXPECT_CALL(client_callbacks_, onBelowWriteBufferLowWatermark()).Times(AnyNumber()); @@ -1832,7 +1839,7 @@ class MockTransportConnectionImplTest : public testing::Test { return new Buffer::WatermarkBuffer(below_low, above_high, above_overflow); })); - file_event_ = new Event::MockFileEvent; + file_event_ = new NiceMock; EXPECT_CALL(dispatcher_, createFileEvent_(0, _, _, _)) .WillOnce(DoAll(SaveArg<1>(&file_ready_cb_), Return(file_event_))); transport_socket_ = new NiceMock; diff --git a/test/common/network/udp_listener_impl_test.cc b/test/common/network/udp_listener_impl_test.cc index 1ee20f8e93a9..b6e4bd670510 100644 --- a/test/common/network/udp_listener_impl_test.cc +++ b/test/common/network/udp_listener_impl_test.cc @@ -40,17 +40,21 @@ namespace { // packets are sent from a network namespace different to that of // the client. Currently, the testing framework does not support // this behavior. -// This helper allows to intercept the supportsUdpGro syscall and -// toggle the gro behavior as per individual test requirements. -class MockSupportsUdpGro : public Api::OsSysCallsImpl { +// This helper allows to intercept syscalls and +// toggle the behavior as per individual test requirements. +class OverrideOsSysCallsImpl : public Api::OsSysCallsImpl { public: MOCK_METHOD(bool, supportsUdpGro, (), (const)); + MOCK_METHOD(bool, supportsMmsg, (), (const)); }; class UdpListenerImplTest : public UdpListenerImplTestBase { public: void SetUp() override { - ON_CALL(udp_gro_syscall_, supportsUdpGro()).WillByDefault(Return(false)); + ON_CALL(override_syscall_, supportsUdpGro()).WillByDefault(Return(false)); + // Return the real version by default. + ON_CALL(override_syscall_, supportsMmsg()) + .WillByDefault(Return(os_calls.latched().supportsMmsg())); // Set listening socket options. server_socket_->addOptions(SocketOptionFactory::buildIpPacketInfoOptions()); @@ -64,8 +68,8 @@ class UdpListenerImplTest : public UdpListenerImplTestBase { ON_CALL(listener_callbacks_, udpPacketWriter()).WillByDefault(ReturnRef(*udp_packet_writer_)); } - NiceMock udp_gro_syscall_; - TestThreadsafeSingletonInjector os_calls{&udp_gro_syscall_}; + NiceMock override_syscall_; + TestThreadsafeSingletonInjector os_calls{&override_syscall_}; }; INSTANTIATE_TEST_SUITE_P(IpVersions, UdpListenerImplTest, @@ -126,6 +130,54 @@ TEST_P(UdpListenerImplTest, UseActualDstUdp) { dispatcher_->run(Event::Dispatcher::RunType::Block); } +// Test a large datagram that gets dropped using recvmmsg if supported. +TEST_P(UdpListenerImplTest, LargeDatagramRecvmmsg) { + // This will get dropped. + const std::string first(4096, 'a'); + client_.write(first, *send_to_addr_); + const std::string second("second"); + client_.write(second, *send_to_addr_); + // This will get dropped. + const std::string third(4096, 'b'); + client_.write(third, *send_to_addr_); + + EXPECT_CALL(listener_callbacks_, onReadReady()); + EXPECT_CALL(listener_callbacks_, onData(_)).WillOnce(Invoke([&](const UdpRecvData& data) -> void { + validateRecvCallbackParams(data, Api::OsSysCallsSingleton::get().supportsMmsg() ? 16u : 1u); + EXPECT_EQ(data.buffer_->toString(), second); + + dispatcher_->exit(); + })); + + dispatcher_->run(Event::Dispatcher::RunType::Block); + EXPECT_EQ(2, listener_->packetsDropped()); +} + +// Test a large datagram that gets dropped using recvmsg. +TEST_P(UdpListenerImplTest, LargeDatagramRecvmsg) { + ON_CALL(override_syscall_, supportsMmsg()).WillByDefault(Return(false)); + + // This will get dropped. + const std::string first(4096, 'a'); + client_.write(first, *send_to_addr_); + const std::string second("second"); + client_.write(second, *send_to_addr_); + // This will get dropped. + const std::string third(4096, 'b'); + client_.write(third, *send_to_addr_); + + EXPECT_CALL(listener_callbacks_, onReadReady()); + EXPECT_CALL(listener_callbacks_, onData(_)).WillOnce(Invoke([&](const UdpRecvData& data) -> void { + validateRecvCallbackParams(data, Api::OsSysCallsSingleton::get().supportsMmsg() ? 16u : 1u); + EXPECT_EQ(data.buffer_->toString(), second); + + dispatcher_->exit(); + })); + + dispatcher_->run(Event::Dispatcher::RunType::Block); + EXPECT_EQ(2, listener_->packetsDropped()); +} + /** * Tests UDP listener for read and write callbacks with actual data. */ diff --git a/test/common/signal/BUILD b/test/common/signal/BUILD index c3f9cf5df843..00b5d183480f 100644 --- a/test/common/signal/BUILD +++ b/test/common/signal/BUILD @@ -23,3 +23,13 @@ envoy_cc_test( "//test/test_common:utility_lib", ], ) + +envoy_cc_test( + name = "fatal_action_test", + srcs = ["fatal_action_test.cc"], + deps = [ + "//source/common/signal:fatal_error_handler_lib", + "//test/mocks/server:instance_mocks", + "//test/test_common:utility_lib", + ], +) diff --git a/test/common/signal/fatal_action_test.cc b/test/common/signal/fatal_action_test.cc new file mode 100644 index 000000000000..5105e8f49ffd --- /dev/null +++ b/test/common/signal/fatal_action_test.cc @@ -0,0 +1,126 @@ +#include "envoy/server/fatal_action_config.h" + +#include "common/signal/fatal_action.h" +#include "common/signal/fatal_error_handler.h" + +#include "test/mocks/server/instance.h" +#include "test/test_common/utility.h" + +#include "absl/synchronization/notification.h" +#include "gtest/gtest.h" + +namespace Envoy { +namespace FatalErrorHandler { + +extern void resetFatalActionStateForTest(); + +} // namespace FatalErrorHandler +namespace FatalAction { + +// Use this test handler instead of a mock, because fatal error handlers must be +// signal-safe and a mock might allocate memory. +class TestFatalErrorHandler : public FatalErrorHandlerInterface { + void onFatalError(std::ostream& /*os*/) const override {} + void + runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const override { + // Call the Fatal Actions with nullptr + for (const Server::Configuration::FatalActionPtr& action : actions) { + action->run(nullptr); + } + } +}; + +class TestFatalAction : public Server::Configuration::FatalAction { +public: + TestFatalAction(bool is_safe, int* const counter) : is_safe_(is_safe), counter_(counter) {} + void run(const ScopeTrackedObject* /*current_object*/) override { ++(*counter_); } + bool isAsyncSignalSafe() const override { return is_safe_; } + +private: + const bool is_safe_; + int* const counter_; +}; + +class FatalActionTest : public ::testing::Test { +public: + FatalActionTest() : handler_(std::make_unique()) { + FatalErrorHandler::registerFatalErrorHandler(*handler_); + } + +protected: + void TearDown() override { + // Reset module state + FatalErrorHandler::resetFatalActionStateForTest(); + FatalErrorHandler::removeFatalErrorHandler(*handler_); + } + + std::unique_ptr handler_; + FatalAction::FatalActionPtrList safe_actions_; + FatalAction::FatalActionPtrList unsafe_actions_; + int counter_ = 0; +}; + +TEST_F(FatalActionTest, ShouldNotBeAbleToRunActionsBeforeRegistration) { + // Call the actions + EXPECT_EQ(FatalErrorHandler::runSafeActions(), Status::ActionManangerUnset); + EXPECT_EQ(FatalErrorHandler::runUnsafeActions(), Status::ActionManangerUnset); +} + +TEST_F(FatalActionTest, ShouldOnlyBeAbleToRegisterFatalActionsOnce) { + // Register empty list of actions + FatalErrorHandler::registerFatalActions({}, {}, Thread::threadFactoryForTest()); + EXPECT_DEBUG_DEATH( + { FatalErrorHandler::registerFatalActions({}, {}, Thread::threadFactoryForTest()); }, ""); +} + +TEST_F(FatalActionTest, CanCallRegisteredActions) { + // Set up Fatal Actions + safe_actions_.emplace_back(std::make_unique(true, &counter_)); + unsafe_actions_.emplace_back(std::make_unique(false, &counter_)); + FatalErrorHandler::registerFatalActions(std::move(safe_actions_), std::move(unsafe_actions_), + Thread::threadFactoryForTest()); + + // Call the actions and check they increment the counter. + EXPECT_EQ(FatalErrorHandler::runSafeActions(), Status::Success); + EXPECT_EQ(counter_, 1); + + EXPECT_EQ(FatalErrorHandler::runUnsafeActions(), Status::Success); + EXPECT_EQ(counter_, 2); +} + +TEST_F(FatalActionTest, CanOnlyRunSafeActionsOnce) { + FatalErrorHandler::registerFatalActions(std::move(safe_actions_), std::move(unsafe_actions_), + Thread::threadFactoryForTest()); + ASSERT_EQ(FatalErrorHandler::runSafeActions(), Status::Success); + + EXPECT_EQ(FatalErrorHandler::runSafeActions(), Status::AlreadyRanOnThisThread); +} + +TEST_F(FatalActionTest, ShouldOnlyBeAbleToRunUnsafeActionsFromThreadThatRanSafeActions) { + FatalErrorHandler::registerFatalActions(std::move(safe_actions_), std::move(unsafe_actions_), + Thread::threadFactoryForTest()); + + absl::Notification run_unsafe_actions; + absl::Notification ran_safe_actions; + auto fatal_action_thread = + Thread::threadFactoryForTest().createThread([&run_unsafe_actions, &ran_safe_actions]() { + // Run Safe Actions and notify + EXPECT_EQ(FatalErrorHandler::runSafeActions(), Status::Success); + ran_safe_actions.Notify(); + + run_unsafe_actions.WaitForNotification(); + EXPECT_EQ(FatalErrorHandler::runUnsafeActions(), Status::Success); + }); + + // Wait for other thread to run safe actions, then try to run safe and + // unsafe actions, they should both not run for this thread. + ran_safe_actions.WaitForNotification(); + ASSERT_EQ(FatalErrorHandler::runSafeActions(), Status::RunningOnAnotherThread); + ASSERT_EQ(FatalErrorHandler::runUnsafeActions(), Status::RunningOnAnotherThread); + run_unsafe_actions.Notify(); + + fatal_action_thread->join(); +} + +} // namespace FatalAction +} // namespace Envoy diff --git a/test/common/signal/signals_test.cc b/test/common/signal/signals_test.cc index cc66d32d81d0..3ecf49f6695b 100644 --- a/test/common/signal/signals_test.cc +++ b/test/common/signal/signals_test.cc @@ -8,8 +8,6 @@ #include "test/common/stats/stat_test_utility.h" #include "test/test_common/utility.h" -#include "gtest/gtest.h" - namespace Envoy { #if defined(__has_feature) #if __has_feature(address_sanitizer) @@ -21,10 +19,41 @@ namespace Envoy { #define ASANITIZED /* Sanitized by GCC */ #endif +namespace FatalErrorHandler { + +extern void resetFatalActionStateForTest(); + +} // namespace FatalErrorHandler + // Use this test handler instead of a mock, because fatal error handlers must be // signal-safe and a mock might allocate memory. class TestFatalErrorHandler : public FatalErrorHandlerInterface { void onFatalError(std::ostream& os) const override { os << "HERE!"; } + void + runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const override { + // Run the actions + for (const auto& action : actions) { + action->run(nullptr); + } + } +}; + +// Use this to test fatal actions get called, as well as the order they run. +class EchoFatalAction : public Server::Configuration::FatalAction { +public: + EchoFatalAction(absl::string_view echo_msg) : echo_msg_(echo_msg) {} + void run(const ScopeTrackedObject* /*current_object*/) override { std::cerr << echo_msg_; } + bool isAsyncSignalSafe() const override { return true; } + +private: + const std::string echo_msg_; +}; + +// Use this to test failing while in a signal handler. +class SegfaultFatalAction : public Server::Configuration::FatalAction { +public: + void run(const ScopeTrackedObject* /*current_object*/) override { raise(SIGSEGV); } + bool isAsyncSignalSafe() const override { return false; } }; // Death tests that expect a particular output are disabled under address sanitizer. @@ -46,6 +75,7 @@ TEST(SignalsDeathTest, InvalidAddressDeathTest) { TEST(SignalsDeathTest, RegisteredHandlerTest) { TestFatalErrorHandler handler; FatalErrorHandler::registerFatalErrorHandler(handler); + SignalAction actions; // Make sure the fatal error log "HERE" registered above is logged on fatal error. EXPECT_DEATH( @@ -115,6 +145,39 @@ TEST(SignalsDeathTest, RestoredPreviousHandlerDeathTest) { EXPECT_DEATH([]() -> void { abort(); }(), "backtrace.*Abort(ed)?"); } +TEST(SignalsDeathTest, CanRunAllFatalActions) { + SignalAction actions; + TestFatalErrorHandler handler; + FatalErrorHandler::registerFatalErrorHandler(handler); + + FatalAction::FatalActionPtrList safe_actions; + FatalAction::FatalActionPtrList unsafe_actions; + + safe_actions.emplace_back(std::make_unique("Safe Action!")); + unsafe_actions.emplace_back(std::make_unique("Unsafe Action!")); + FatalErrorHandler::registerFatalActions(std::move(safe_actions), std::move(unsafe_actions), + Thread::threadFactoryForTest()); + EXPECT_DEATH([]() -> void { raise(SIGSEGV); }(), "Safe Action!.*HERE.*Unsafe Action!"); + FatalErrorHandler::removeFatalErrorHandler(handler); + FatalErrorHandler::resetFatalActionStateForTest(); +} + +TEST(SignalsDeathTest, ShouldJustExitIfFatalActionsRaiseAnotherSignal) { + SignalAction actions; + TestFatalErrorHandler handler; + FatalErrorHandler::registerFatalErrorHandler(handler); + + FatalAction::FatalActionPtrList safe_actions; + FatalAction::FatalActionPtrList unsafe_actions; + + unsafe_actions.emplace_back(std::make_unique()); + FatalErrorHandler::registerFatalActions(std::move(safe_actions), std::move(unsafe_actions), + Thread::threadFactoryForTest()); + + EXPECT_DEATH([]() -> void { raise(SIGABRT); }(), "Our FatalActions triggered a fatal signal."); + FatalErrorHandler::removeFatalErrorHandler(handler); + FatalErrorHandler::resetFatalActionStateForTest(); +} #endif TEST(SignalsDeathTest, IllegalStackAccessDeathTest) { @@ -179,6 +242,9 @@ class MemoryCheckingFatalErrorHandler : public FatalErrorHandlerInterface { allocated_after_call_ = memory_test_.consumedBytes(); } + void runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& + /*actions*/) const override {} + private: const Stats::TestUtil::MemoryTest& memory_test_; uint64_t& allocated_after_call_; diff --git a/test/common/stats/tag_extractor_impl_test.cc b/test/common/stats/tag_extractor_impl_test.cc index 18ff4d6ec88c..13fd4de172c9 100644 --- a/test/common/stats/tag_extractor_impl_test.cc +++ b/test/common/stats/tag_extractor_impl_test.cc @@ -15,7 +15,21 @@ namespace Envoy { namespace Stats { TEST(TagExtractorTest, TwoSubexpressions) { - TagExtractorImpl tag_extractor("cluster_name", "^cluster\\.((.+?)\\.)"); + TagExtractorStdRegexImpl tag_extractor("cluster_name", "^cluster\\.((.+?)\\.)"); + EXPECT_EQ("cluster_name", tag_extractor.name()); + std::string name = "cluster.test_cluster.upstream_cx_total"; + TagVector tags; + IntervalSetImpl remove_characters; + ASSERT_TRUE(tag_extractor.extractTag(name, tags, remove_characters)); + std::string tag_extracted_name = StringUtil::removeCharacters(name, remove_characters); + EXPECT_EQ("cluster.upstream_cx_total", tag_extracted_name); + ASSERT_EQ(1, tags.size()); + EXPECT_EQ("test_cluster", tags.at(0).value_); + EXPECT_EQ("cluster_name", tags.at(0).name_); +} + +TEST(TagExtractorTest, RE2Variants) { + TagExtractorRe2Impl tag_extractor("cluster_name", "^cluster\\.(([^\\.]+)\\.).*"); EXPECT_EQ("cluster_name", tag_extractor.name()); std::string name = "cluster.test_cluster.upstream_cx_total"; TagVector tags; @@ -29,7 +43,7 @@ TEST(TagExtractorTest, TwoSubexpressions) { } TEST(TagExtractorTest, SingleSubexpression) { - TagExtractorImpl tag_extractor("listner_port", "^listener\\.(\\d+?\\.)"); + TagExtractorStdRegexImpl tag_extractor("listner_port", "^listener\\.(\\d+?\\.)"); std::string name = "listener.80.downstream_cx_total"; TagVector tags; IntervalSetImpl remove_characters; @@ -42,24 +56,26 @@ TEST(TagExtractorTest, SingleSubexpression) { } TEST(TagExtractorTest, substrMismatch) { - TagExtractorImpl tag_extractor("listner_port", "^listener\\.(\\d+?\\.)\\.foo\\.", ".foo."); + TagExtractorStdRegexImpl tag_extractor("listner_port", "^listener\\.(\\d+?\\.)\\.foo\\.", + ".foo."); EXPECT_TRUE(tag_extractor.substrMismatch("listener.80.downstream_cx_total")); EXPECT_FALSE(tag_extractor.substrMismatch("listener.80.downstream_cx_total.foo.bar")); } TEST(TagExtractorTest, noSubstrMismatch) { - TagExtractorImpl tag_extractor("listner_port", "^listener\\.(\\d+?\\.)\\.foo\\."); + TagExtractorStdRegexImpl tag_extractor("listner_port", "^listener\\.(\\d+?\\.)\\.foo\\."); EXPECT_FALSE(tag_extractor.substrMismatch("listener.80.downstream_cx_total")); EXPECT_FALSE(tag_extractor.substrMismatch("listener.80.downstream_cx_total.foo.bar")); } TEST(TagExtractorTest, EmptyName) { - EXPECT_THROW_WITH_MESSAGE(TagExtractorImpl::createTagExtractor("", "^listener\\.(\\d+?\\.)"), - EnvoyException, "tag_name cannot be empty"); + EXPECT_THROW_WITH_MESSAGE( + TagExtractorStdRegexImpl::createTagExtractor("", "^listener\\.(\\d+?\\.)"), EnvoyException, + "tag_name cannot be empty"); } TEST(TagExtractorTest, BadRegex) { - EXPECT_THROW_WITH_REGEX(TagExtractorImpl::createTagExtractor("cluster_name", "+invalid"), + EXPECT_THROW_WITH_REGEX(TagExtractorStdRegexImpl::createTagExtractor("cluster_name", "+invalid"), EnvoyException, "Invalid regex '\\+invalid':"); } @@ -361,7 +377,7 @@ TEST(TagExtractorTest, DefaultTagExtractors) { TEST(TagExtractorTest, ExtractRegexPrefix) { TagExtractorPtr tag_extractor; // Keep tag_extractor in this scope to prolong prefix lifetime. auto extractRegexPrefix = [&tag_extractor](const std::string& regex) -> absl::string_view { - tag_extractor = TagExtractorImpl::createTagExtractor("foo", regex); + tag_extractor = TagExtractorStdRegexImpl::createTagExtractor("foo", regex); return tag_extractor->prefixToken(); }; @@ -376,7 +392,7 @@ TEST(TagExtractorTest, ExtractRegexPrefix) { } TEST(TagExtractorTest, CreateTagExtractorNoRegex) { - EXPECT_THROW_WITH_REGEX(TagExtractorImpl::createTagExtractor("no such default tag", ""), + EXPECT_THROW_WITH_REGEX(TagExtractorStdRegexImpl::createTagExtractor("no such default tag", ""), EnvoyException, "^No regex specified for tag specifier and no default"); } diff --git a/test/common/stats/thread_local_store_speed_test.cc b/test/common/stats/thread_local_store_speed_test.cc index 3eff52a78d97..5208fdaed9f5 100644 --- a/test/common/stats/thread_local_store_speed_test.cc +++ b/test/common/stats/thread_local_store_speed_test.cc @@ -79,6 +79,7 @@ class ThreadLocalStorePerf { // Tests the single-threaded performance of the thread-local-store stats caches // without having initialized tls. +// NOLINTNEXTLINE(readability-identifier-naming) static void BM_StatsNoTls(benchmark::State& state) { Envoy::ThreadLocalStorePerf context; @@ -91,6 +92,7 @@ BENCHMARK(BM_StatsNoTls); // Tests the single-threaded performance of the thread-local-store stats caches // with tls. Note that this test is still single-threaded, and so there's only // one replica of the tls cache. +// NOLINTNEXTLINE(readability-identifier-naming) static void BM_StatsWithTls(benchmark::State& state) { Envoy::ThreadLocalStorePerf context; context.initThreading(); diff --git a/test/common/tcp/conn_pool_test.cc b/test/common/tcp/conn_pool_test.cc index f81d9ffcd334..726edfed05b0 100644 --- a/test/common/tcp/conn_pool_test.cc +++ b/test/common/tcp/conn_pool_test.cc @@ -49,6 +49,7 @@ struct ConnPoolCallbacks : public Tcp::ConnectionPool::Callbacks { void onPoolReady(ConnectionPool::ConnectionDataPtr&& conn, Upstream::HostDescriptionConstSharedPtr host) override { conn_data_ = std::move(conn); + conn_data_->addUpstreamCallbacks(callbacks_); host_ = host; pool_ready_.ready(); } @@ -60,6 +61,7 @@ struct ConnPoolCallbacks : public Tcp::ConnectionPool::Callbacks { pool_failure_.ready(); } + NiceMock callbacks_; ReadyWatcher pool_failure_; ReadyWatcher pool_ready_; ConnectionPool::ConnectionDataPtr conn_data_{}; @@ -151,7 +153,8 @@ class ConnPoolBase : public Tcp::ConnectionPool::Instance { public: ConnPoolImplForTest(Event::MockDispatcher& dispatcher, Upstream::HostSharedPtr host, ConnPoolBase& parent) - : ConnPoolImpl(dispatcher, host, Upstream::ResourcePriority::Default, nullptr, nullptr), + : ConnPoolImpl(dispatcher, host, Upstream::ResourcePriority::Default, nullptr, nullptr, + state_), parent_(parent) {} void onConnReleased(Envoy::ConnectionPool::ActiveClient& client) override { @@ -165,6 +168,8 @@ class ConnPoolBase : public Tcp::ConnectionPool::Instance { } void onConnDestroyed() override { parent_.onConnDestroyedForTest(); } + + Upstream::ClusterConnectivityState state_; Event::PostCb post_cb_; ConnPoolBase& parent_; }; @@ -273,7 +278,7 @@ class TcpConnPoolImplDestructorTest : public testing::TestWithParam { host_ = Upstream::makeTestHost(cluster_, "tcp://127.0.0.1:9000"); if (test_new_connection_pool_) { conn_pool_ = std::make_unique( - dispatcher_, host_, Upstream::ResourcePriority::Default, nullptr, nullptr); + dispatcher_, host_, Upstream::ResourcePriority::Default, nullptr, nullptr, state_); } else { conn_pool_ = std::make_unique( dispatcher_, host_, Upstream::ResourcePriority::Default, nullptr, nullptr); @@ -297,6 +302,7 @@ class TcpConnPoolImplDestructorTest : public testing::TestWithParam { } bool test_new_connection_pool_; + Upstream::ClusterConnectivityState state_; Upstream::HostConstSharedPtr host_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; @@ -452,23 +458,20 @@ TEST_P(TcpConnPoolImplTest, VerifyBufferLimits) { TEST_P(TcpConnPoolImplTest, UpstreamCallbacks) { Buffer::OwnedImpl buffer; - ConnectionPool::MockUpstreamCallbacks callbacks; - - // Create connection, set UpstreamCallbacks + // Create connection, UpstreamCallbacks set automatically ActiveTestConn c1(*this, 0, ActiveTestConn::Type::CreateConnection); - c1.callbacks_.conn_data_->addUpstreamCallbacks(callbacks); // Expect invocation when connection's ReadFilter::onData is invoked - EXPECT_CALL(callbacks, onUpstreamData(_, _)); + EXPECT_CALL(c1.callbacks_.callbacks_, onUpstreamData(_, _)); EXPECT_EQ(Network::FilterStatus::StopIteration, conn_pool_.test_conns_[0].filter_->onData(buffer, false)); - EXPECT_CALL(callbacks, onAboveWriteBufferHighWatermark()); + EXPECT_CALL(c1.callbacks_.callbacks_, onAboveWriteBufferHighWatermark()); for (auto* cb : conn_pool_.test_conns_[0].connection_->callbacks_) { cb->onAboveWriteBufferHighWatermark(); } - EXPECT_CALL(callbacks, onBelowWriteBufferLowWatermark()); + EXPECT_CALL(c1.callbacks_.callbacks_, onBelowWriteBufferLowWatermark()); for (auto* cb : conn_pool_.test_conns_[0].connection_->callbacks_) { cb->onBelowWriteBufferLowWatermark(); } @@ -482,41 +485,6 @@ TEST_P(TcpConnPoolImplTest, UpstreamCallbacks) { dispatcher_.clearDeferredDeleteList(); } -/** - * Test that upstream callback close event fires for assigned connections. - */ -TEST_P(TcpConnPoolImplTest, UpstreamCallbacksCloseEvent) { - Buffer::OwnedImpl buffer; - - ConnectionPool::MockUpstreamCallbacks callbacks; - - // Create connection, set UpstreamCallbacks - ActiveTestConn c1(*this, 0, ActiveTestConn::Type::CreateConnection); - c1.callbacks_.conn_data_->addUpstreamCallbacks(callbacks); - - EXPECT_CALL(callbacks, onEvent(Network::ConnectionEvent::RemoteClose)); - - EXPECT_CALL(conn_pool_, onConnDestroyedForTest()); - conn_pool_.test_conns_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); - dispatcher_.clearDeferredDeleteList(); -} - -/** - * Test that a connection pool functions without upstream callbacks. - */ -TEST_P(TcpConnPoolImplTest, NoUpstreamCallbacks) { - Buffer::OwnedImpl buffer; - - // Create connection. - ActiveTestConn c1(*this, 0, ActiveTestConn::Type::CreateConnection); - - // Trigger connection's ReadFilter::onData -- connection pool closes connection. - EXPECT_CALL(conn_pool_, onConnDestroyedForTest()); - EXPECT_EQ(Network::FilterStatus::StopIteration, - conn_pool_.test_conns_[0].filter_->onData(buffer, false)); - dispatcher_.clearDeferredDeleteList(); -} - /** * Tests a request that generates a new connection, completes, and then a second request that uses * the same connection. @@ -990,11 +958,8 @@ TEST_P(TcpConnPoolImplTest, DrainOnClose) { ActiveTestConn c1(*this, 0, ActiveTestConn::Type::CreateConnection); - ConnectionPool::MockUpstreamCallbacks callbacks; - c1.callbacks_.conn_data_->addUpstreamCallbacks(callbacks); - EXPECT_CALL(drained, ready()); - EXPECT_CALL(callbacks, onEvent(Network::ConnectionEvent::RemoteClose)) + EXPECT_CALL(c1.callbacks_.callbacks_, onEvent(Network::ConnectionEvent::RemoteClose)) .WillOnce(Invoke([&](Network::ConnectionEvent event) -> void { EXPECT_EQ(Network::ConnectionEvent::RemoteClose, event); c1.releaseConn(); diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index 1e3217285dea..21217a421752 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -1492,7 +1492,7 @@ TEST_F(ClusterManagerImplTest, DynamicAddRemove) { EXPECT_EQ(cluster2->info_, cluster_manager_->get("fake_cluster")->info()); EXPECT_EQ(1UL, cluster_manager_->clusters().active_clusters_.size()); Http::ConnectionPool::MockInstance* cp = new Http::ConnectionPool::MockInstance(); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(cp)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(cp)); EXPECT_EQ(cp, cluster_manager_->httpConnPoolForCluster("fake_cluster", ResourcePriority::Default, Http::Protocol::Http11, nullptr)); @@ -1649,7 +1649,7 @@ TEST_F(ClusterManagerImplTest, CloseHttpConnectionsOnHealthFailure) { })); create(parseBootstrapFromV3Json(json)); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(cp1)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(cp1)); cluster_manager_->httpConnPoolForCluster("some_cluster", ResourcePriority::Default, Http::Protocol::Http11, nullptr); @@ -1660,7 +1660,7 @@ TEST_F(ClusterManagerImplTest, CloseHttpConnectionsOnHealthFailure) { test_host->healthFlagSet(Host::HealthFlag::FAILED_OUTLIER_CHECK); outlier_detector.runCallbacks(test_host); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(cp2)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(cp2)); cluster_manager_->httpConnPoolForCluster("some_cluster", ResourcePriority::High, Http::Protocol::Http11, nullptr); } @@ -1925,7 +1925,7 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemove) { EXPECT_CALL(initialized, ready()); cluster_manager_->setInitializedCb([&]() -> void { initialized.ready(); }); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .Times(4) .WillRepeatedly(ReturnNew()); @@ -2098,7 +2098,7 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { EXPECT_CALL(initialized, ready()); cluster_manager_->setInitializedCb([&]() -> void { initialized.ready(); }); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .Times(4) .WillRepeatedly(ReturnNew()); @@ -2380,7 +2380,7 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveDefaultPriority) { dns_callback(Network::DnsResolver::ResolutionStatus::Success, TestUtility::makeDnsResponse({"127.0.0.2"})); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .WillOnce(ReturnNew()); EXPECT_CALL(factory_, allocateTcpConnPool_(_)) @@ -2462,7 +2462,7 @@ TEST_F(ClusterManagerImplTest, ConnPoolDestroyWithDraining) { TestUtility::makeDnsResponse({"127.0.0.2"})); MockConnPoolWithDestroy* mock_cp = new MockConnPoolWithDestroy(); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(mock_cp)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(mock_cp)); MockTcpConnPoolWithDestroy* mock_tcp = new MockTcpConnPoolWithDestroy(); EXPECT_CALL(factory_, allocateTcpConnPool_(_)).WillOnce(Return(mock_tcp)); @@ -2911,7 +2911,7 @@ TEST_F(ClusterManagerImplTest, UpstreamSocketOptionsPassedToConnPool) { Network::SocketOptionFactory::buildIpTransparentOptions(); EXPECT_CALL(context, upstreamSocketOptions()).WillOnce(Return(options_to_return)); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(to_create)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(to_create)); Http::ConnectionPool::Instance* cp = cluster_manager_->httpConnPoolForCluster( "cluster_1", ResourcePriority::Default, Http::Protocol::Http11, &context); @@ -2933,12 +2933,12 @@ TEST_F(ClusterManagerImplTest, UpstreamSocketOptionsUsedInConnPoolHash) { EXPECT_CALL(context1, upstreamSocketOptions()).WillRepeatedly(Return(options1)); EXPECT_CALL(context2, upstreamSocketOptions()).WillRepeatedly(Return(options2)); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(to_create1)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(to_create1)); Http::ConnectionPool::Instance* cp1 = cluster_manager_->httpConnPoolForCluster( "cluster_1", ResourcePriority::Default, Http::Protocol::Http11, &context1); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(to_create2)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(to_create2)); Http::ConnectionPool::Instance* cp2 = cluster_manager_->httpConnPoolForCluster( "cluster_1", ResourcePriority::Default, Http::Protocol::Http11, &context2); @@ -2963,7 +2963,7 @@ TEST_F(ClusterManagerImplTest, UpstreamSocketOptionsNullIsOkay) { Network::Socket::OptionsSharedPtr options_to_return = nullptr; EXPECT_CALL(context, upstreamSocketOptions()).WillOnce(Return(options_to_return)); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(to_create)); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(to_create)); Http::ConnectionPool::Instance* cp = cluster_manager_->httpConnPoolForCluster( "cluster_1", ResourcePriority::Default, Http::Protocol::Http11, &context); @@ -3863,7 +3863,7 @@ TEST_F(ClusterManagerImplTest, ConnPoolsDrainedOnHostSetChange) { EXPECT_EQ(0, factory_.stats_.counter("cluster_manager.cluster_updated_via_merge").value()); EXPECT_EQ(0, factory_.stats_.counter("cluster_manager.update_merge_cancelled").value()); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .Times(3) .WillRepeatedly(ReturnNew()); @@ -3967,7 +3967,7 @@ TEST_F(ClusterManagerImplTest, ConnPoolsNotDrainedOnHostSetChange) { 0, HostSetImpl::partitionHosts(hosts_ptr, HostsPerLocalityImpl::empty()), nullptr, hosts, {}, 100); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .Times(1) .WillRepeatedly(ReturnNew()); @@ -4104,7 +4104,7 @@ TEST_F(ClusterManagerImplTest, ConnectionPoolPerDownstreamConnection) { std::vector conn_pool_vector; for (size_t i = 0; i < 3; ++i) { conn_pool_vector.push_back(new Http::ConnectionPool::MockInstance()); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)).WillOnce(Return(conn_pool_vector.back())); + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)).WillOnce(Return(conn_pool_vector.back())); EXPECT_CALL(downstream_connection, hashKey) .WillOnce(Invoke([i](std::vector& hash_key) { hash_key.push_back(i); })); EXPECT_EQ(conn_pool_vector.back(), @@ -4177,7 +4177,7 @@ TEST_F(PrefetchTest, PrefetchOff) { // With prefetch set to 0, each request for a connection pool will only // allocate that conn pool. initialize(0); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .Times(1) .WillRepeatedly(ReturnNew()); cluster_manager_->httpConnPoolForCluster("cluster_1", ResourcePriority::Default, @@ -4194,7 +4194,7 @@ TEST_F(PrefetchTest, PrefetchOn) { // prefetching, so create the pool for both the current connection and the // anticipated one. initialize(1.1); - EXPECT_CALL(factory_, allocateConnPool_(_, _, _)) + EXPECT_CALL(factory_, allocateConnPool_(_, _, _, _)) .Times(2) .WillRepeatedly(ReturnNew>()); cluster_manager_->httpConnPoolForCluster("cluster_1", ResourcePriority::Default, diff --git a/test/common/upstream/test_cluster_manager.h b/test/common/upstream/test_cluster_manager.h index 3cce3f09182d..0c221529cb45 100644 --- a/test/common/upstream/test_cluster_manager.h +++ b/test/common/upstream/test_cluster_manager.h @@ -77,18 +77,20 @@ class TestClusterManagerFactory : public ClusterManagerFactory { })); } - Http::ConnectionPool::InstancePtr allocateConnPool( - Event::Dispatcher&, HostConstSharedPtr host, ResourcePriority, Http::Protocol, - const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options) override { + Http::ConnectionPool::InstancePtr + allocateConnPool(Event::Dispatcher&, HostConstSharedPtr host, ResourcePriority, Http::Protocol, + const Network::ConnectionSocket::OptionsSharedPtr& options, + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + ClusterConnectivityState& state) override { return Http::ConnectionPool::InstancePtr{ - allocateConnPool_(host, options, transport_socket_options)}; + allocateConnPool_(host, options, transport_socket_options, state)}; } Tcp::ConnectionPool::InstancePtr allocateTcpConnPool(Event::Dispatcher&, HostConstSharedPtr host, ResourcePriority, const Network::ConnectionSocket::OptionsSharedPtr&, - Network::TransportSocketOptionsSharedPtr) override { + Network::TransportSocketOptionsSharedPtr, + Upstream::ClusterConnectivityState&) override { return Tcp::ConnectionPool::InstancePtr{allocateTcpConnPool_(host)}; } @@ -115,7 +117,7 @@ class TestClusterManagerFactory : public ClusterManagerFactory { (const envoy::config::bootstrap::v3::Bootstrap& bootstrap)); MOCK_METHOD(Http::ConnectionPool::Instance*, allocateConnPool_, (HostConstSharedPtr host, Network::ConnectionSocket::OptionsSharedPtr, - Network::TransportSocketOptionsSharedPtr)); + Network::TransportSocketOptionsSharedPtr, ClusterConnectivityState&)); MOCK_METHOD(Tcp::ConnectionPool::Instance*, allocateTcpConnPool_, (HostConstSharedPtr host)); MOCK_METHOD((std::pair), clusterFromProto_, (const envoy::config::cluster::v3::Cluster& cluster, ClusterManager& cm, diff --git a/test/common/upstream/utility.h b/test/common/upstream/utility.h index ef3dd210adf3..cd92eb9d37a3 100644 --- a/test/common/upstream/utility.h +++ b/test/common/upstream/utility.h @@ -79,48 +79,48 @@ inline envoy::config::cluster::v3::Cluster defaultStaticCluster(const std::strin inline HostSharedPtr makeTestHost(ClusterInfoConstSharedPtr cluster, const std::string& hostname, const std::string& url, uint32_t weight = 1) { - return HostSharedPtr{ - new HostImpl(cluster, hostname, Network::Utility::resolveUrl(url), nullptr, weight, - envoy::config::core::v3::Locality(), - envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), 0, - envoy::config::core::v3::UNKNOWN)}; + return std::make_shared( + cluster, hostname, Network::Utility::resolveUrl(url), nullptr, weight, + envoy::config::core::v3::Locality(), + envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), 0, + envoy::config::core::v3::UNKNOWN); } inline HostSharedPtr makeTestHost(ClusterInfoConstSharedPtr cluster, const std::string& url, uint32_t weight = 1, uint32_t priority = 0) { - return HostSharedPtr{ - new HostImpl(cluster, "", Network::Utility::resolveUrl(url), nullptr, weight, - envoy::config::core::v3::Locality(), - envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), - priority, envoy::config::core::v3::UNKNOWN)}; + return std::make_shared( + cluster, "", Network::Utility::resolveUrl(url), nullptr, weight, + envoy::config::core::v3::Locality(), + envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), priority, + envoy::config::core::v3::UNKNOWN); } inline HostSharedPtr makeTestHost(ClusterInfoConstSharedPtr cluster, const std::string& url, const envoy::config::core::v3::Metadata& metadata, uint32_t weight = 1) { - return HostSharedPtr{ - new HostImpl(cluster, "", Network::Utility::resolveUrl(url), - std::make_shared(metadata), weight, - envoy::config::core::v3::Locality(), - envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), 0, - envoy::config::core::v3::UNKNOWN)}; + return std::make_shared( + cluster, "", Network::Utility::resolveUrl(url), + std::make_shared(metadata), weight, + envoy::config::core::v3::Locality(), + envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), 0, + envoy::config::core::v3::UNKNOWN); } inline HostSharedPtr makeTestHost(ClusterInfoConstSharedPtr cluster, const std::string& url, const envoy::config::endpoint::v3::Endpoint::HealthCheckConfig& health_check_config, uint32_t weight = 1) { - return HostSharedPtr{new HostImpl(cluster, "", Network::Utility::resolveUrl(url), nullptr, weight, + return std::make_shared(cluster, "", Network::Utility::resolveUrl(url), nullptr, weight, envoy::config::core::v3::Locality(), health_check_config, 0, - envoy::config::core::v3::UNKNOWN)}; + envoy::config::core::v3::UNKNOWN); } inline HostDescriptionConstSharedPtr makeTestHostDescription(ClusterInfoConstSharedPtr cluster, const std::string& url) { - return HostDescriptionConstSharedPtr{new HostDescriptionImpl( + return std::make_shared( cluster, "", Network::Utility::resolveUrl(url), nullptr, envoy::config::core::v3::Locality().default_instance(), - envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), 0)}; + envoy::config::endpoint::v3::Endpoint::HealthCheckConfig::default_instance(), 0); } inline HostsPerLocalitySharedPtr makeHostsPerLocality(std::vector&& locality_hosts, diff --git a/test/extensions/access_loggers/wasm/BUILD b/test/extensions/access_loggers/wasm/BUILD index 54ab90482a91..fc56bc9b7c39 100644 --- a/test/extensions/access_loggers/wasm/BUILD +++ b/test/extensions/access_loggers/wasm/BUILD @@ -25,6 +25,7 @@ envoy_extension_cc_test( deps = [ "//source/extensions/access_loggers/wasm:config", "//test/extensions/access_loggers/wasm/test_data:test_cpp_plugin", + "//test/extensions/common/wasm:wasm_runtime", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", "//test/test_common:utility_lib", diff --git a/test/extensions/access_loggers/wasm/config_test.cc b/test/extensions/access_loggers/wasm/config_test.cc index 744f074fdb8c..fb570453db30 100644 --- a/test/extensions/access_loggers/wasm/config_test.cc +++ b/test/extensions/access_loggers/wasm/config_test.cc @@ -9,6 +9,7 @@ #include "extensions/access_loggers/well_known_names.h" #include "extensions/common/wasm/wasm.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/server/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/printers.h" @@ -39,20 +40,8 @@ class TestFactoryContext : public NiceMock {}; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8", -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm", -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime", -#endif - "null"); -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmAccessLogConfigTest, testing_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmAccessLogConfigTest, + Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmAccessLogConfigTest, CreateWasmFromEmpty) { auto factory = diff --git a/test/extensions/bootstrap/wasm/BUILD b/test/extensions/bootstrap/wasm/BUILD index 6a6488e2b63b..b9c8282420c3 100644 --- a/test/extensions/bootstrap/wasm/BUILD +++ b/test/extensions/bootstrap/wasm/BUILD @@ -37,6 +37,7 @@ envoy_extension_cc_test( "//source/extensions/bootstrap/wasm:config", "//source/extensions/common/wasm:wasm_lib", "//test/extensions/bootstrap/wasm/test_data:stats_cpp_plugin", + "//test/extensions/common/wasm:wasm_runtime", "//test/mocks/server:server_mocks", "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", @@ -58,6 +59,7 @@ envoy_extension_cc_test( "//source/extensions/bootstrap/wasm:config", "//source/extensions/common/wasm:wasm_lib", "//test/extensions/bootstrap/wasm/test_data:start_cpp_plugin", + "//test/extensions/common/wasm:wasm_runtime", "//test/mocks/event:event_mocks", "//test/mocks/server:server_mocks", "//test/mocks/thread_local:thread_local_mocks", @@ -85,6 +87,7 @@ envoy_extension_cc_test_binary( "//source/extensions/bootstrap/wasm:config", "//source/extensions/common/wasm:wasm_lib", "//test/extensions/bootstrap/wasm/test_data:speed_cpp_plugin", + "//test/extensions/common/wasm:wasm_runtime", "//test/mocks/server:server_mocks", "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", diff --git a/test/extensions/bootstrap/wasm/config_test.cc b/test/extensions/bootstrap/wasm/config_test.cc index bd5d4b947166..a0b7274e53fd 100644 --- a/test/extensions/bootstrap/wasm/config_test.cc +++ b/test/extensions/bootstrap/wasm/config_test.cc @@ -6,6 +6,7 @@ #include "extensions/bootstrap/wasm/config.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/event/mocks.h" #include "test/mocks/server/mocks.h" #include "test/mocks/thread_local/mocks.h" @@ -67,20 +68,8 @@ class WasmFactoryTest : public testing::TestWithParam { Server::BootstrapExtensionPtr extension_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8", -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm", -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime", -#endif - "null"); -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmFactoryTest, testing_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmFactoryTest, + Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmFactoryTest, CreateWasmFromWasm) { auto factory = std::make_unique(); diff --git a/test/extensions/bootstrap/wasm/wasm_test.cc b/test/extensions/bootstrap/wasm/wasm_test.cc index 5384c66dcae8..757b086770b6 100644 --- a/test/extensions/bootstrap/wasm/wasm_test.cc +++ b/test/extensions/bootstrap/wasm/wasm_test.cc @@ -3,6 +3,7 @@ #include "extensions/common/wasm/wasm.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/server/mocks.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/environment.h" @@ -73,34 +74,14 @@ class WasmTestBase { std::shared_ptr wasm_; }; -#if defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME) class WasmTest : public WasmTestBase, public testing::TestWithParam { public: void createWasm() { WasmTestBase::createWasm(GetParam()); } }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8" -#endif -#if defined(ENVOY_WASM_V8) && (defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME)) - , -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm" -#endif -#if (defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM)) && defined(ENVOY_WASM_WASMTIME) - , -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime" -#endif -); - -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmTest, testing_values); -#endif +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmTest, + Envoy::Extensions::Common::Wasm::sandbox_runtime_values); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WasmTest); class WasmNullTest : public WasmTestBase, public testing::TestWithParam { public: @@ -116,22 +97,8 @@ class WasmNullTest : public WasmTestBase, public testing::TestWithParam> { public: @@ -151,24 +118,9 @@ class WasmTestMatrix : public WasmTestBase, }; INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, WasmTestMatrix, - testing::Combine(testing::Values( -#if defined(ENVOY_WASM_V8) - "v8" -#endif -#if defined(ENVOY_WASM_V8) && (defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME)) - , -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm" -#endif -#if (defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM)) && defined(ENVOY_WASM_WASMTIME) - , -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime" -#endif - ), + testing::Combine(Envoy::Extensions::Common::Wasm::sandbox_runtime_values, testing::Values("cpp", "rust"))); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WasmTestMatrix); TEST_P(WasmTestMatrix, Logging) { plugin_configuration_ = "configure-test"; @@ -202,9 +154,7 @@ TEST_P(WasmTestMatrix, Logging) { dispatcher_->run(Event::Dispatcher::RunType::NonBlock); dispatcher_->clearDeferredDeleteList(); } -#endif -#if defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME) TEST_P(WasmTest, BadSignature) { createWasm(); const auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( @@ -266,7 +216,6 @@ TEST_P(WasmTest, Asm2Wasm) { EXPECT_CALL(*context, log_(spdlog::level::info, Eq("out 0 0 0"))); EXPECT_TRUE(wasm_->configure(context, plugin_)); } -#endif TEST_P(WasmNullTest, Stats) { createWasm(); diff --git a/test/extensions/common/wasm/BUILD b/test/extensions/common/wasm/BUILD index 4e586cb7902f..b26be4cdb7e5 100644 --- a/test/extensions/common/wasm/BUILD +++ b/test/extensions/common/wasm/BUILD @@ -2,6 +2,7 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_test", "envoy_cc_test_binary", + "envoy_cc_test_library", "envoy_package", ) load( @@ -21,6 +22,7 @@ envoy_cc_test( ]), deps = [ "//source/extensions/common/wasm:wasm_lib", + "//test/extensions/common/wasm:wasm_runtime", "//test/test_common:environment_lib", "//test/test_common:registry_lib", "//test/test_common:utility_lib", @@ -44,6 +46,7 @@ envoy_cc_test( "//source/common/stats:stats_lib", "//source/extensions/common/crypto:utility_lib", "//source/extensions/common/wasm:wasm_lib", + "//test/extensions/common/wasm:wasm_runtime", "//test/extensions/common/wasm/test_data:test_context_cpp_plugin", "//test/extensions/common/wasm/test_data:test_cpp_plugin", "//test/mocks/server:server_mocks", @@ -63,8 +66,21 @@ envoy_cc_test_binary( deps = [ "//source/common/event:dispatcher_lib", "//source/extensions/common/wasm:wasm_lib", + "//test/extensions/common/wasm:wasm_runtime", "//test/mocks/server:server_mocks", "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", ], ) + +envoy_cc_test_library( + name = "wasm_runtime", + srcs = ["wasm_runtime.cc"], + hdrs = ["wasm_runtime.h"], + deps = [ + "//source/extensions/wasm_runtime/null:config", + "//source/extensions/wasm_runtime/v8:config", + "//source/extensions/wasm_runtime/wasmtime:config", + "//source/extensions/wasm_runtime/wavm:config", + ], +) diff --git a/test/extensions/common/wasm/wasm_runtime.cc b/test/extensions/common/wasm/wasm_runtime.cc new file mode 100644 index 000000000000..a8451c70df64 --- /dev/null +++ b/test/extensions/common/wasm/wasm_runtime.cc @@ -0,0 +1,41 @@ +#include "test/extensions/common/wasm/wasm_runtime.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +std::vector runtimes() { + std::vector runtimes = sandboxRuntimes(); + runtimes.push_back("null"); + return runtimes; +} + +std::vector sandboxRuntimes() { + std::vector runtimes; +#if defined(ENVOY_WASM_V8) + runtimes.push_back("v8"); +#endif +#if defined(ENVOY_WASM_WAVM) + runtimes.push_back("wavm"); +#endif +#if defined(ENVOY_WASM_WASMTIME) + runtimes.push_back("wasmtime"); +#endif + return runtimes; +} + +std::vector> runtimesAndLanguages() { + std::vector> values; + for (const auto& runtime : sandboxRuntimes()) { + values.push_back(std::make_tuple(runtime, "cpp")); + values.push_back(std::make_tuple(runtime, "rust")); + } + values.push_back(std::make_tuple("null", "cpp")); + return values; +} + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/common/wasm/wasm_runtime.h b/test/extensions/common/wasm/wasm_runtime.h new file mode 100644 index 000000000000..ef248d85310b --- /dev/null +++ b/test/extensions/common/wasm/wasm_runtime.h @@ -0,0 +1,26 @@ +#pragma once + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace Common { +namespace Wasm { + +// All WASM runtimes. +std::vector runtimes(); + +// All sandboxed WASM runtimes. +std::vector sandboxRuntimes(); + +// Testable runtime and language combinations +std::vector> runtimesAndLanguages(); + +inline auto runtime_values = testing::ValuesIn(runtimes()); +inline auto sandbox_runtime_values = testing::ValuesIn(sandboxRuntimes()); +inline auto runtime_and_language_values = testing::ValuesIn(runtimesAndLanguages()); + +} // namespace Wasm +} // namespace Common +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/common/wasm/wasm_test.cc b/test/extensions/common/wasm/wasm_test.cc index 6d903abdbec2..cd56089daf5f 100644 --- a/test/extensions/common/wasm/wasm_test.cc +++ b/test/extensions/common/wasm/wasm_test.cc @@ -6,6 +6,7 @@ #include "extensions/common/wasm/wasm.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/server/mocks.h" #include "test/mocks/stats/mocks.h" #include "test/mocks/upstream/mocks.h" @@ -89,20 +90,7 @@ class WasmCommonTest : public testing::TestWithParam { } }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto test_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8", -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm", -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime", -#endif - "null"); -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmCommonTest, test_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmCommonTest, Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmCommonTest, EnvoyWasm) { auto envoy_wasm = std::make_unique(); @@ -969,7 +957,8 @@ class WasmCommonContextTest std::unique_ptr context_; }; -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmCommonContextTest, test_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmCommonContextTest, + Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmCommonContextTest, OnDnsResolve) { std::string code; diff --git a/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc b/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc index 1ec37be541b4..8082a846db89 100644 --- a/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc +++ b/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc @@ -1270,6 +1270,78 @@ INSTANTIATE_TEST_SUITE_P( })", R"({"id":"101","gender":"MALE","last_name":"Shakespeare"})"})); +struct GrpcJsonTranscoderFilterUnescapeTestParam { + std::string config_json_; + std::string expected_arg_; +}; + +class GrpcJsonTranscoderFilterUnescapeTest + : public testing::TestWithParam, + public GrpcJsonTranscoderFilterTestBase { +protected: + GrpcJsonTranscoderFilterUnescapeTest() { + envoy::extensions::filters::http::grpc_json_transcoder::v3::GrpcJsonTranscoder proto_config; + TestUtility::loadFromJson(TestEnvironment::substitute(GetParam().config_json_), proto_config); + config_ = std::make_unique(proto_config, *api_); + filter_ = std::make_unique(*config_); + filter_->setDecoderFilterCallbacks(decoder_callbacks_); + filter_->setEncoderFilterCallbacks(encoder_callbacks_); + } + + std::unique_ptr config_; + std::unique_ptr filter_; + NiceMock decoder_callbacks_; + NiceMock encoder_callbacks_; +}; + +TEST_P(GrpcJsonTranscoderFilterUnescapeTest, UnescapeSpec) { + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "text/plain"}, {":method", "POST"}, {":path", "/wildcard/%2f%23/%20%2523"}}; + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); + + Buffer::OwnedImpl request_data{"{}"}; + EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(request_data, true)); + + Grpc::Decoder decoder; + std::vector frames; + decoder.decode(request_data, frames); + + EXPECT_EQ(1, frames.size()); + + bookstore::EchoBodyRequest expected_request; + expected_request.set_arg(GetParam().expected_arg_); + + bookstore::EchoBodyRequest request; + request.ParseFromString(frames[0].data_->toString()); + + EXPECT_EQ(expected_request.ByteSize(), frames[0].length_); + EXPECT_TRUE(MessageDifferencer::Equals(expected_request, request)); +} + +INSTANTIATE_TEST_SUITE_P(GrpcJsonTranscoderFilterUnescapeOptions, + GrpcJsonTranscoderFilterUnescapeTest, + ::testing::Values( + GrpcJsonTranscoderFilterUnescapeTestParam{ + R"({ + "proto_descriptor": "{{ test_rundir }}/test/proto/bookstore.descriptor", + "services": ["bookstore.Bookstore"] + })", + "%2f%23/ %23"}, + GrpcJsonTranscoderFilterUnescapeTestParam{ + R"({ + "proto_descriptor": "{{ test_rundir }}/test/proto/bookstore.descriptor", + "services": ["bookstore.Bookstore"], + "url_unescape_spec": "ALL_CHARACTERS_EXCEPT_SLASH" + })", + "%2f#/ %23"}, + GrpcJsonTranscoderFilterUnescapeTestParam{ + R"({ + "proto_descriptor": "{{ test_rundir }}/test/proto/bookstore.descriptor", + "services": ["bookstore.Bookstore"], + "url_unescape_spec": "ALL_CHARACTERS" + })", + "/#/ %23"})); + } // namespace } // namespace GrpcJsonTranscoder } // namespace HttpFilters diff --git a/test/extensions/filters/http/jwt_authn/authenticator_test.cc b/test/extensions/filters/http/jwt_authn/authenticator_test.cc index e9ceb23cbbbd..fbb732a63298 100644 --- a/test/extensions/filters/http/jwt_authn/authenticator_test.cc +++ b/test/extensions/filters/http/jwt_authn/authenticator_test.cc @@ -303,6 +303,23 @@ TEST_F(AuthenticatorTest, TestExpiredJWT) { expectVerifyStatus(Status::JwtExpired, headers); } +// This test verifies when a JWT is expired but with a big clock skew. +TEST_F(AuthenticatorTest, TestExpiredJWTWithABigClockSkew) { + auto& provider = (*proto_config_.mutable_providers())[std::string(ProviderName)]; + // Token is expired at 1205005587, but add clock skew at another 1205005587. + provider.set_clock_skew_seconds(1205005587); + createAuthenticator(); + + EXPECT_CALL(*raw_fetcher_, fetch(_, _, _)) + .WillOnce(Invoke([this](const envoy::config::core::v3::HttpUri&, Tracing::Span&, + JwksFetcher::JwksReceiver& receiver) { + receiver.onJwksSuccess(std::move(jwks_)); + })); + + Http::TestRequestHeaderMapImpl headers{{"Authorization", "Bearer " + std::string(ExpiredToken)}}; + expectVerifyStatus(Status::Ok, headers); +} + // This test verifies when a JWT is not yet valid, JwtNotYetValid status is returned. TEST_F(AuthenticatorTest, TestNotYetValidJWT) { EXPECT_CALL(*raw_fetcher_, fetch(_, _, _)).Times(0); diff --git a/test/extensions/filters/http/lua/lua_filter_test.cc b/test/extensions/filters/http/lua/lua_filter_test.cc index 310bafc36b39..d07420f4d8e4 100644 --- a/test/extensions/filters/http/lua/lua_filter_test.cc +++ b/test/extensions/filters/http/lua/lua_filter_test.cc @@ -1884,7 +1884,7 @@ TEST_F(LuaHttpFilterTest, InspectStreamInfoDowstreamSslConnection) { Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; - auto connection_info = std::make_shared(); + const auto connection_info = std::make_shared(); EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(stream_info_)); EXPECT_CALL(stream_info_, downstreamSslConnection()).WillRepeatedly(Return(connection_info)); @@ -1992,6 +1992,35 @@ TEST_F(LuaHttpFilterTest, InspectStreamInfoDowstreamSslConnectionOnPlainConnecti EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } +// Should survive from multiple streamInfo():downstreamSslConnection() calls. +// This is a regression test for #14091. +TEST_F(LuaHttpFilterTest, SurviveMultipleDownstreamSslConnectionCalls) { + const std::string SCRIPT{R"EOF( + function envoy_on_request(request_handle) + if request_handle:streamInfo():downstreamSslConnection() ~= nil then + request_handle:logTrace("downstreamSslConnection is present") + end + end + )EOF"}; + + setup(SCRIPT); + + const auto connection_info = std::make_shared(); + EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(stream_info_)); + EXPECT_CALL(stream_info_, downstreamSslConnection()).WillRepeatedly(Return(connection_info)); + + for (uint64_t i = 0; i < 200; i++) { + EXPECT_CALL(*filter_, + scriptLog(spdlog::level::trace, StrEq("downstreamSslConnection is present"))); + + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); + + filter_->onDestroy(); + setupFilter(); + } +} + TEST_F(LuaHttpFilterTest, ImportPublicKey) { const std::string SCRIPT{R"EOF( function string.fromhex(str) diff --git a/test/extensions/filters/http/oauth2/config_test.cc b/test/extensions/filters/http/oauth2/config_test.cc index 4be857a21d0a..b9f0571bc61b 100644 --- a/test/extensions/filters/http/oauth2/config_test.cc +++ b/test/extensions/filters/http/oauth2/config_test.cc @@ -47,6 +47,10 @@ void expectInvalidSecretConfig(const std::string& failed_secret_name, signout_path: path: exact: /signout + auth_scopes: + - user + - openid + - email )EOF"; OAuth2Config factory; @@ -87,6 +91,10 @@ TEST(ConfigTest, CreateFilter) { signout_path: path: exact: /signout + auth_scopes: + - user + - openid + - email )EOF"; OAuth2Config factory; diff --git a/test/extensions/filters/http/oauth2/filter_test.cc b/test/extensions/filters/http/oauth2/filter_test.cc index 83f5e7f08833..8fb1d2f3448e 100644 --- a/test/extensions/filters/http/oauth2/filter_test.cc +++ b/test/extensions/filters/http/oauth2/filter_test.cc @@ -35,6 +35,7 @@ static const std::string TEST_CALLBACK = "/_oauth"; static const std::string TEST_CLIENT_ID = "1"; static const std::string TEST_CLIENT_SECRET_ID = "MyClientSecretKnoxID"; static const std::string TEST_TOKEN_SECRET_ID = "MyTokenSecretKnoxID"; +static const std::string TEST_ENCODED_AUTH_SCOPES = "user%20openid%20email"; namespace { Http::RegisterCustomInlineHeader @@ -91,6 +92,9 @@ class OAuth2Test : public testing::Test { p.set_authorization_endpoint("https://auth.example.com/oauth/authorize/"); p.mutable_signout_path()->mutable_path()->set_exact("/_signout"); p.set_forward_bearer_token(true); + p.add_auth_scopes("user"); + p.add_auth_scopes("openid"); + p.add_auth_scopes("email"); auto* matcher = p.add_pass_through_matcher(); matcher->set_name(":method"); matcher->set_exact_match("OPTIONS"); @@ -147,6 +151,43 @@ TEST_F(OAuth2Test, InvalidCluster) { "specify which cluster to direct OAuth requests to."); } +// Verifies that the OAuth config is created with a default value for auth_scopes field when it is +// not set in proto/yaml. +TEST_F(OAuth2Test, DefaultAuthScope) { + + // Set up proto fields + envoy::extensions::filters::http::oauth2::v3alpha::OAuth2Config p; + auto* endpoint = p.mutable_token_endpoint(); + endpoint->set_cluster("auth.example.com"); + endpoint->set_uri("auth.example.com/_oauth"); + endpoint->mutable_timeout()->set_seconds(1); + p.set_redirect_uri("%REQ(x-forwarded-proto)%://%REQ(:authority)%" + TEST_CALLBACK); + p.mutable_redirect_path_matcher()->mutable_path()->set_exact(TEST_CALLBACK); + p.set_authorization_endpoint("https://auth.example.com/oauth/authorize/"); + p.mutable_signout_path()->mutable_path()->set_exact("/_signout"); + p.set_forward_bearer_token(true); + auto* matcher = p.add_pass_through_matcher(); + matcher->set_name(":method"); + matcher->set_exact_match("OPTIONS"); + + auto credentials = p.mutable_credentials(); + credentials->set_client_id(TEST_CLIENT_ID); + credentials->mutable_token_secret()->set_name("secret"); + credentials->mutable_hmac_secret()->set_name("hmac"); + + MessageUtil::validate(p, ProtobufMessage::getStrictValidationVisitor()); + + // Create the OAuth config. + auto secret_reader = std::make_shared(); + FilterConfigSharedPtr test_config_; + test_config_ = std::make_shared(p, factory_context_.cluster_manager_, secret_reader, + scope_, "test."); + + // auth_scopes was not set, should return default value + std::vector default_scope = {"user"}; + EXPECT_EQ(test_config_->authScopes(), default_scope); +} + /** * Scenario: The OAuth filter receives a sign out request. * @@ -239,8 +280,8 @@ TEST_F(OAuth2Test, OAuthErrorNonOAuthHttpCallback) { {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + - TEST_CLIENT_ID + - "&scope=user&response_type=code&" + TEST_CLIENT_ID + "&scope=" + TEST_ENCODED_AUTH_SCOPES + + "&response_type=code&" "redirect_uri=http%3A%2F%2Ftraffic.example.com%2F" "_oauth&state=http%3A%2F%2Ftraffic.example.com%2Fnot%2F_oauth"}, }; @@ -392,8 +433,8 @@ TEST_F(OAuth2Test, OAuthTestInvalidUrlInStateQueryParam) { Http::TestRequestHeaderMapImpl request_headers{ {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=user&" - "state=blah"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=abcdefxyz123&scope=" + TEST_ENCODED_AUTH_SCOPES + "&state=blah"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123;version=test"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token;version=test"}, {Http::Headers::get().Cookie.get(), @@ -426,8 +467,9 @@ TEST_F(OAuth2Test, OAuthTestCallbackUrlInStateQueryParam) { Http::TestRequestHeaderMapImpl request_headers{ {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=user&" - "state=https%3A%2F%2Ftraffic.example.com%2F_oauth"}, + {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=" + + TEST_ENCODED_AUTH_SCOPES + + "&state=https%3A%2F%2Ftraffic.example.com%2F_oauth"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123;version=test"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token;version=test"}, {Http::Headers::get().Cookie.get(), @@ -457,8 +499,9 @@ TEST_F(OAuth2Test, OAuthTestCallbackUrlInStateQueryParam) { Http::TestRequestHeaderMapImpl final_request_headers{ {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=user&" - "state=https%3A%2F%2Ftraffic.example.com%2F_oauth"}, + {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=" + + TEST_ENCODED_AUTH_SCOPES + + "&state=https%3A%2F%2Ftraffic.example.com%2F_oauth"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123;version=test"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token;version=test"}, {Http::Headers::get().Cookie.get(), @@ -482,8 +525,9 @@ TEST_F(OAuth2Test, OAuthTestUpdatePathAfterSuccess) { Http::TestRequestHeaderMapImpl request_headers{ {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=user&" - "state=https%3A%2F%2Ftraffic.example.com%2Foriginal_path"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=abcdefxyz123&scope=" + TEST_ENCODED_AUTH_SCOPES + + "&state=https%3A%2F%2Ftraffic.example.com%2Foriginal_path"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123;version=test"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token;version=test"}, {Http::Headers::get().Cookie.get(), @@ -511,8 +555,9 @@ TEST_F(OAuth2Test, OAuthTestUpdatePathAfterSuccess) { Http::TestRequestHeaderMapImpl final_request_headers{ {Http::Headers::get().Host.get(), "traffic.example.com"}, {Http::Headers::get().Method.get(), Http::Headers::get().MethodValues.Get}, - {Http::Headers::get().Path.get(), "/_oauth?code=abcdefxyz123&scope=user&" - "state=https%3A%2F%2Ftraffic.example.com%2Foriginal_path"}, + {Http::Headers::get().Path.get(), + "/_oauth?code=abcdefxyz123&scope=" + TEST_ENCODED_AUTH_SCOPES + + "&state=https%3A%2F%2Ftraffic.example.com%2Foriginal_path"}, {Http::Headers::get().Cookie.get(), "OauthExpires=123;version=test"}, {Http::Headers::get().Cookie.get(), "BearerToken=legit_token;version=test"}, {Http::Headers::get().Cookie.get(), @@ -545,8 +590,8 @@ TEST_F(OAuth2Test, OAuthTestFullFlowPostWithParameters) { {Http::Headers::get().Location.get(), "https://auth.example.com/oauth/" "authorize/?client_id=" + - TEST_CLIENT_ID + - "&scope=user&response_type=code&" + TEST_CLIENT_ID + "&scope=" + TEST_ENCODED_AUTH_SCOPES + + "&response_type=code&" "redirect_uri=https%3A%2F%2Ftraffic.example.com%2F" "_oauth&state=https%3A%2F%2Ftraffic.example.com%2Ftest%" "3Fname%3Dadmin%26level%3Dtrace"}, diff --git a/test/extensions/filters/http/oauth2/oauth_integration_test.cc b/test/extensions/filters/http/oauth2/oauth_integration_test.cc index 0788c5d2b3b9..750e370fd197 100644 --- a/test/extensions/filters/http/oauth2/oauth_integration_test.cc +++ b/test/extensions/filters/http/oauth2/oauth_integration_test.cc @@ -58,6 +58,10 @@ name: oauth name: token hmac_secret: name: hmac + auth_scopes: + - user + - openid + - email )EOF"); // Add the OAuth cluster. @@ -91,8 +95,6 @@ TEST_F(OauthIntegrationTest, UnauthenticatedFlow) { {":authority", "authority"}}; auto encoder_decoder = codec_client_->startRequest(headers); - Buffer::OwnedImpl buffer; - encoder_decoder.first.encodeData(buffer, true); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -144,4 +146,4 @@ TEST_F(OauthIntegrationTest, AuthenticationFlow) { } // namespace Oauth } // namespace HttpFilters } // namespace Extensions -} // namespace Envoy \ No newline at end of file +} // namespace Envoy diff --git a/test/extensions/filters/http/wasm/BUILD b/test/extensions/filters/http/wasm/BUILD index f8392be38a7a..055529c224ce 100644 --- a/test/extensions/filters/http/wasm/BUILD +++ b/test/extensions/filters/http/wasm/BUILD @@ -34,6 +34,7 @@ envoy_extension_cc_test( deps = [ "//source/common/http:message_lib", "//source/extensions/filters/http/wasm:wasm_filter_lib", + "//test/extensions/common/wasm:wasm_runtime", "//test/extensions/filters/http/wasm/test_data:test_cpp_plugin", "//test/mocks/network:connection_mocks", "//test/mocks/router:router_mocks", @@ -58,6 +59,7 @@ envoy_extension_cc_test( "//source/extensions/common/crypto:utility_lib", "//source/extensions/common/wasm:wasm_lib", "//source/extensions/filters/http/wasm:config", + "//test/extensions/common/wasm:wasm_runtime", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", "@envoy_api//envoy/extensions/filters/http/wasm/v3:pkg_cc_proto", diff --git a/test/extensions/filters/http/wasm/config_test.cc b/test/extensions/filters/http/wasm/config_test.cc index 552aa61a9387..5d5d92afb6b5 100644 --- a/test/extensions/filters/http/wasm/config_test.cc +++ b/test/extensions/filters/http/wasm/config_test.cc @@ -11,6 +11,7 @@ #include "extensions/common/wasm/wasm.h" #include "extensions/filters/http/wasm/config.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/http/mocks.h" #include "test/mocks/server/mocks.h" #include "test/test_common/environment.h" @@ -29,7 +30,6 @@ using Common::Wasm::WasmException; namespace HttpFilters { namespace Wasm { -#if defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME) class WasmFilterConfigTest : public Event::TestUsingSimulatedTime, public testing::TestWithParam { protected: @@ -65,27 +65,9 @@ class WasmFilterConfigTest : public Event::TestUsingSimulatedTime, Event::TimerCb retry_timer_cb_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8" -#endif -#if defined(ENVOY_WASM_V8) && (defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME)) - , -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm" -#endif -#if (defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM)) && defined(ENVOY_WASM_WASMTIME) - , -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime" -#endif -); - -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmFilterConfigTest, testing_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmFilterConfigTest, + Envoy::Extensions::Common::Wasm::sandbox_runtime_values); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WasmFilterConfigTest); TEST_P(WasmFilterConfigTest, JsonLoadFromFileWasm) { const std::string json = TestEnvironment::substitute(absl::StrCat(R"EOF( @@ -832,7 +814,6 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteSuccessBadcodeFailOpen) { // The filter is not registered. cb(filter_callback); } -#endif } // namespace Wasm } // namespace HttpFilters diff --git a/test/extensions/filters/http/wasm/wasm_filter_test.cc b/test/extensions/filters/http/wasm/wasm_filter_test.cc index 9999d453c75f..fddde58db40b 100644 --- a/test/extensions/filters/http/wasm/wasm_filter_test.cc +++ b/test/extensions/filters/http/wasm/wasm_filter_test.cc @@ -2,6 +2,7 @@ #include "extensions/filters/http/wasm/wasm_filter.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/network/connection.h" #include "test/mocks/router/mocks.h" #include "test/test_common/wasm_base.h" @@ -95,20 +96,8 @@ class WasmHttpFilterTest : public Common::Wasm::WasmHttpFilterTestBase< Grpc::MockAsyncClientManager async_client_manager_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - std::make_tuple("v8", "cpp"), std::make_tuple("v8", "rust"), -#endif -#if defined(ENVOY_WASM_WAVM) - std::make_tuple("wavm", "cpp"), std::make_tuple("wavm", "rust"), -#endif -#if defined(ENVOY_WASM_WASMTIME) - std::make_tuple("wasmtime", "cpp"), std::make_tuple("wasmtime", "rust"), -#endif - std::make_tuple("null", "cpp")); -INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, WasmHttpFilterTest, testing_values); +INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, WasmHttpFilterTest, + Envoy::Extensions::Common::Wasm::runtime_and_language_values); // Bad code in initial config. TEST_P(WasmHttpFilterTest, BadCode) { @@ -1263,9 +1252,11 @@ TEST_P(WasmHttpFilterTest, GrpcStreamOpenAtShutdown) { } // Test metadata access including CEL expressions. -// TODO: re-enable this on Windows if and when the CEL `Antlr` parser compiles on Windows. -#if defined(ENVOY_WASM_V8) || defined(ENVOY_WASM_WAVM) || defined(ENVOY_WASM_WASMTIME) TEST_P(WasmHttpFilterTest, Metadata) { +#ifdef WIN32 + // TODO: re-enable this on Windows if and when the CEL `Antlr` parser compiles on Windows. + GTEST_SKIP() << "Skipping on Windows"; +#endif setupTest("", "metadata"); setupFilter(); envoy::config::core::v3::Node node_data; @@ -1319,7 +1310,6 @@ TEST_P(WasmHttpFilterTest, Metadata) { filter().onDestroy(); filter().onDestroy(); // Does nothing. } -#endif TEST_P(WasmHttpFilterTest, Property) { if (std::get<1>(GetParam()) == "rust") { diff --git a/test/extensions/filters/listener/tls_inspector/tls_inspector_benchmark.cc b/test/extensions/filters/listener/tls_inspector/tls_inspector_benchmark.cc index 5bed094fc34c..00f1e37aa50c 100644 --- a/test/extensions/filters/listener/tls_inspector/tls_inspector_benchmark.cc +++ b/test/extensions/filters/listener/tls_inspector/tls_inspector_benchmark.cc @@ -41,6 +41,8 @@ class FastMockListenerFilterCallbacks : public Network::MockListenerFilterCallba class FastMockFileEvent : public Event::FileEvent { void activate(uint32_t) override {} void setEnabled(uint32_t) override {} + void unregisterEventIfEmulatedEdge(uint32_t) override {} + void registerEventIfEmulatedEdge(uint32_t) override {} }; class FastMockDispatcher : public Event::MockDispatcher { diff --git a/test/extensions/filters/network/mongo_proxy/proxy_test.cc b/test/extensions/filters/network/mongo_proxy/proxy_test.cc index 5b20f6cd5106..c43ebe8ca897 100644 --- a/test/extensions/filters/network/mongo_proxy/proxy_test.cc +++ b/test/extensions/filters/network/mongo_proxy/proxy_test.cc @@ -626,8 +626,8 @@ TEST_F(MongoProxyFilterTest, ConnectionDestroyLocal) { EXPECT_CALL(*delay_timer, disableTimer()); read_filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); - EXPECT_EQ(1U, store_.counter("test.cx_destroy_local_with_active_rq").value()); - EXPECT_EQ(0U, store_.counter("test.cx_destroy_remote_with_active_rq").value()); + EXPECT_EQ(0U, store_.counter("test.cx_destroy_local_with_active_rq").value()); + EXPECT_EQ(1U, store_.counter("test.cx_destroy_remote_with_active_rq").value()); } TEST_F(MongoProxyFilterTest, ConnectionDestroyRemote) { @@ -650,8 +650,8 @@ TEST_F(MongoProxyFilterTest, ConnectionDestroyRemote) { EXPECT_CALL(*delay_timer, disableTimer()); read_filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::LocalClose); - EXPECT_EQ(1U, store_.counter("test.cx_destroy_remote_with_active_rq").value()); - EXPECT_EQ(0U, store_.counter("test.cx_destroy_local_with_active_rq").value()); + EXPECT_EQ(0U, store_.counter("test.cx_destroy_remote_with_active_rq").value()); + EXPECT_EQ(1U, store_.counter("test.cx_destroy_local_with_active_rq").value()); } } // namespace MongoProxy diff --git a/test/extensions/filters/network/postgres_proxy/postgres_decoder_test.cc b/test/extensions/filters/network/postgres_proxy/postgres_decoder_test.cc index e787a18f2d5b..1643cc83d2fa 100644 --- a/test/extensions/filters/network/postgres_proxy/postgres_decoder_test.cc +++ b/test/extensions/filters/network/postgres_proxy/postgres_decoder_test.cc @@ -523,6 +523,7 @@ class FakeBuffer : public Buffer::Instance { MOCK_METHOD(void, copyOut, (size_t, uint64_t, void*), (const, override)); MOCK_METHOD(void, drain, (uint64_t), (override)); MOCK_METHOD(Buffer::RawSliceVector, getRawSlices, (absl::optional), (const, override)); + MOCK_METHOD(Buffer::RawSlice, frontSlice, (), (const, override)); MOCK_METHOD(Buffer::SliceDataPtr, extractMutableFrontSlice, (), (override)); MOCK_METHOD(uint64_t, length, (), (const, override)); MOCK_METHOD(void*, linearize, (uint32_t), (override)); diff --git a/test/extensions/filters/network/wasm/BUILD b/test/extensions/filters/network/wasm/BUILD index d21eba6c0853..bfbd34124d5f 100644 --- a/test/extensions/filters/network/wasm/BUILD +++ b/test/extensions/filters/network/wasm/BUILD @@ -29,6 +29,7 @@ envoy_extension_cc_test( "//source/extensions/common/crypto:utility_lib", "//source/extensions/common/wasm:wasm_lib", "//source/extensions/filters/network/wasm:config", + "//test/extensions/common/wasm:wasm_runtime", "//test/extensions/filters/network/wasm/test_data:test_cpp_plugin", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", @@ -46,6 +47,7 @@ envoy_extension_cc_test( extension_name = "envoy.filters.network.wasm", deps = [ "//source/extensions/filters/network/wasm:wasm_filter_lib", + "//test/extensions/common/wasm:wasm_runtime", "//test/extensions/filters/network/wasm/test_data:test_cpp_plugin", "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", diff --git a/test/extensions/filters/network/wasm/config_test.cc b/test/extensions/filters/network/wasm/config_test.cc index 68541490a82c..6d93a167f674 100644 --- a/test/extensions/filters/network/wasm/config_test.cc +++ b/test/extensions/filters/network/wasm/config_test.cc @@ -8,6 +8,7 @@ #include "extensions/filters/network/wasm/config.h" #include "extensions/filters/network/wasm/wasm_filter.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/server/mocks.h" #include "test/test_common/environment.h" @@ -56,20 +57,8 @@ class WasmNetworkFilterConfigTest : public testing::TestWithParam { Event::TimerCb retry_timer_cb_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8", -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm", -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime", -#endif - "null"); -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmNetworkFilterConfigTest, testing_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmNetworkFilterConfigTest, + Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmNetworkFilterConfigTest, YamlLoadFromFileWasm) { if (GetParam() == "null") { diff --git a/test/extensions/filters/network/wasm/wasm_filter_test.cc b/test/extensions/filters/network/wasm/wasm_filter_test.cc index 517d37cee3b5..c9bd6e7f8348 100644 --- a/test/extensions/filters/network/wasm/wasm_filter_test.cc +++ b/test/extensions/filters/network/wasm/wasm_filter_test.cc @@ -3,6 +3,7 @@ #include "extensions/common/wasm/wasm.h" #include "extensions/filters/network/wasm/wasm_filter.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/network/mocks.h" #include "test/mocks/server/mocks.h" #include "test/test_common/wasm_base.h" @@ -82,20 +83,8 @@ class WasmNetworkFilterTest : public Common::Wasm::WasmNetworkFilterTestBase< std::string code_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - std::make_tuple("v8", "cpp"), std::make_tuple("v8", "rust"), -#endif -#if defined(ENVOY_WASM_WAVM) - std::make_tuple("wavm", "cpp"), std::make_tuple("wavm", "rust"), -#endif -#if defined(ENVOY_WASM_WASMTIME) - std::make_tuple("wasmtime", "cpp"), std::make_tuple("wasmtime", "rust"), -#endif - std::make_tuple("null", "cpp")); -INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, WasmNetworkFilterTest, testing_values); +INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, WasmNetworkFilterTest, + Envoy::Extensions::Common::Wasm::runtime_and_language_values); // Bad code in initial config. TEST_P(WasmNetworkFilterTest, BadCode) { @@ -174,15 +163,11 @@ TEST_P(WasmNetworkFilterTest, CloseStream) { // Create context. EXPECT_CALL(filter(), log_(spdlog::level::trace, Eq(absl::string_view("onNewConnection 2")))); EXPECT_EQ(Network::FilterStatus::Continue, filter().onNewConnection()); - EXPECT_CALL(filter(), - log_(spdlog::level::trace, Eq(absl::string_view("onDownstreamConnectionClose 2 1")))); EXPECT_CALL(filter(), log_(spdlog::level::trace, Eq(absl::string_view("onDownstreamConnectionClose 2 2")))); filter().onEvent(static_cast(9999)); // Does nothing. filter().onEvent(Network::ConnectionEvent::RemoteClose); - filter().closeStream(proxy_wasm::WasmStreamType::Downstream); - filter().closeStream(proxy_wasm::WasmStreamType::Upstream); } TEST_P(WasmNetworkFilterTest, SegvFailOpen) { diff --git a/test/extensions/quic_listeners/quiche/BUILD b/test/extensions/quic_listeners/quiche/BUILD index 92aad3fe9a2e..4375b705ca7d 100644 --- a/test/extensions/quic_listeners/quiche/BUILD +++ b/test/extensions/quic_listeners/quiche/BUILD @@ -84,6 +84,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/test_common:utility_lib", "@com_googlesource_quiche//:quic_core_http_spdy_session_lib", + "@com_googlesource_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", "@com_googlesource_quiche//:quic_test_tools_session_peer_lib", ], ) @@ -105,6 +106,7 @@ envoy_cc_test( "//test/mocks/network:network_mocks", "//test/test_common:utility_lib", "@com_googlesource_quiche//:quic_core_http_spdy_session_lib", + "@com_googlesource_quiche//:quic_test_tools_qpack_qpack_test_utils_lib", ], ) @@ -290,5 +292,6 @@ envoy_cc_test_library( "//test/test_common:environment_lib", "@com_googlesource_quiche//:quic_core_http_spdy_session_lib", "@com_googlesource_quiche//:quic_test_tools_first_flight_lib", + "@com_googlesource_quiche//:quic_test_tools_qpack_qpack_encoder_test_utils_lib", ], ) diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc index c95a61e5ace8..e03c6ab3ba64 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc @@ -49,9 +49,9 @@ class TestEnvoyQuicClientConnection : public EnvoyQuicClientConnection { Network::ConnectionSocketPtr&& connection_socket) : EnvoyQuicClientConnection(server_connection_id, helper, alarm_factory, &writer, false, supported_versions, dispatcher, std::move(connection_socket)) { - SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); SetEncrypter(quic::ENCRYPTION_FORWARD_SECURE, std::make_unique(quic::Perspective::IS_CLIENT)); + SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); } MOCK_METHOD(void, SendConnectionClosePacket, (quic::QuicErrorCode, const std::string&)); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc index 7711b7c88bf0..01871dcfff99 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc @@ -48,11 +48,11 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { quic_session_.ActivateStream(std::unique_ptr(quic_stream_)); EXPECT_CALL(quic_session_, ShouldYield(_)).WillRepeatedly(testing::Return(false)); EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillRepeatedly(Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; - })); + .WillRepeatedly( + Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; + })); EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) .WillRepeatedly(Invoke([](const char*, size_t buf_len, const quic::QuicIpAddress&, const quic::QuicSocketAddress&, quic::PerPacketOptions*) { @@ -69,6 +69,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { response_headers_.OnHeader(":status", "200"); response_headers_.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); + spdy_response_headers_[":status"] = "200"; trailers_.OnHeaderBlockStart(); trailers_.OnHeader("key1", "value1"); @@ -77,6 +78,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { trailers_.OnHeader(":final-offset", absl::StrCat("", response_body_.length())); } trailers_.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); + spdy_trailers_["key1"] = "value1"; } void TearDown() override { @@ -87,6 +89,41 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { } } + std::string bodyToStreamPayload(const std::string& body) { + if (!quic::VersionUsesHttp3(quic_version_.transport_version)) { + return body; + } + return bodyToHttp3StreamPayload(body); + } + + size_t receiveResponse(const std::string& payload, bool fin) { + EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) + .WillOnce(Invoke([](const Http::ResponseHeaderMapPtr& headers, bool) { + EXPECT_EQ("200", headers->getStatusValue()); + })); + + EXPECT_CALL(stream_decoder_, decodeData(_, _)) + .WillOnce(Invoke([&](Buffer::Instance& buffer, bool finished_reading) { + EXPECT_EQ(payload, buffer.toString()); + EXPECT_EQ(fin, finished_reading); + })); + if (quic::VersionUsesHttp3(quic_version_.transport_version)) { + std::string data = absl::StrCat(spdyHeaderToHttp3StreamPayload(spdy_response_headers_), + bodyToStreamPayload(payload)); + quic::QuicStreamFrame frame(stream_id_, fin, 0, data); + quic_stream_->OnStreamFrame(frame); + EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); + return data.length(); + } + quic_stream_->OnStreamHeaderList(/*fin=*/false, response_headers_.uncompressed_header_bytes(), + response_headers_); + + quic::QuicStreamFrame frame(stream_id_, fin, 0, payload); + quic_stream_->OnStreamFrame(frame); + EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); + return payload.length(); + } + protected: Api::ApiPtr api_; Event::DispatcherPtr dispatcher_; @@ -107,7 +144,9 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { Http::TestRequestHeaderMapImpl request_headers_; Http::TestRequestTrailerMapImpl request_trailers_; quic::QuicHeaderList response_headers_; + spdy::SpdyHeaderBlock spdy_response_headers_; quic::QuicHeaderList trailers_; + spdy::SpdyHeaderBlock spdy_trailers_; Buffer::OwnedImpl request_body_{"Hello world"}; std::string response_body_{"OK\n"}; }; @@ -115,44 +154,35 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { INSTANTIATE_TEST_SUITE_P(EnvoyQuicClientStreamTests, EnvoyQuicClientStreamTest, testing::ValuesIn({true, false})); -TEST_P(EnvoyQuicClientStreamTest, PostRequestAndResponse) { - EXPECT_EQ(absl::nullopt, quic_stream_->http1StreamEncoderOptions()); - const auto result = quic_stream_->encodeHeaders(request_headers_, false); +TEST_P(EnvoyQuicClientStreamTest, GetRequestAndHeaderOnlyResponse) { + const auto result = quic_stream_->encodeHeaders(request_headers_, /*end_stream=*/true); EXPECT_TRUE(result.ok()); - quic_stream_->encodeData(request_body_, false); - quic_stream_->encodeTrailers(request_trailers_); - EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) + EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/!quic::VersionUsesHttp3( + quic_version_.transport_version))) .WillOnce(Invoke([](const Http::ResponseHeaderMapPtr& headers, bool) { EXPECT_EQ("200", headers->getStatusValue()); })); - quic_stream_->OnStreamHeaderList(/*fin=*/false, response_headers_.uncompressed_header_bytes(), - response_headers_); - EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); - - EXPECT_CALL(stream_decoder_, decodeData(_, _)) - .Times(testing::AtMost(2)) - .WillOnce(Invoke([&](Buffer::Instance& buffer, bool finished_reading) { - EXPECT_EQ(response_body_, buffer.toString()); - EXPECT_FALSE(finished_reading); - })) - // Depends on QUIC version, there may be an empty STREAM_FRAME with FIN. But - // since there is trailers, finished_reading should always be false. - .WillOnce(Invoke([](Buffer::Instance& buffer, bool finished_reading) { - EXPECT_FALSE(finished_reading); - EXPECT_EQ(0, buffer.length()); - })); - std::string data = response_body_; if (quic::VersionUsesHttp3(quic_version_.transport_version)) { - std::unique_ptr data_buffer; - quic::QuicByteCount data_frame_header_length = - quic::HttpEncoder::SerializeDataFrameHeader(response_body_.length(), &data_buffer); - quiche::QuicheStringPiece data_frame_header(data_buffer.get(), data_frame_header_length); - data = absl::StrCat(data_frame_header, response_body_); + EXPECT_CALL(stream_decoder_, decodeData(BufferStringEqual(""), /*end_stream=*/true)); + std::string payload = spdyHeaderToHttp3StreamPayload(spdy_response_headers_); + quic::QuicStreamFrame frame(stream_id_, true, 0, payload); + quic_stream_->OnStreamFrame(frame); + } else { + quic_stream_->OnStreamHeaderList(/*fin=*/true, response_headers_.uncompressed_header_bytes(), + response_headers_); } - quic::QuicStreamFrame frame(stream_id_, false, 0, data); - quic_stream_->OnStreamFrame(frame); + EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); +} + +TEST_P(EnvoyQuicClientStreamTest, PostRequestAndResponse) { + EXPECT_EQ(absl::nullopt, quic_stream_->http1StreamEncoderOptions()); + const auto result = quic_stream_->encodeHeaders(request_headers_, false); + EXPECT_TRUE(result.ok()); + quic_stream_->encodeData(request_body_, false); + quic_stream_->encodeTrailers(request_trailers_); + size_t offset = receiveResponse(response_body_, false); EXPECT_CALL(stream_decoder_, decodeTrailers_(_)) .WillOnce(Invoke([](const Http::ResponseTrailerMapPtr& headers) { Http::LowerCaseString key1("key1"); @@ -160,7 +190,22 @@ TEST_P(EnvoyQuicClientStreamTest, PostRequestAndResponse) { EXPECT_EQ("value1", headers->get(key1)[0]->value().getStringView()); EXPECT_TRUE(headers->get(key2).empty()); })); - quic_stream_->OnStreamHeaderList(/*fin=*/true, trailers_.uncompressed_header_bytes(), trailers_); + if (quic::VersionUsesHttp3(quic_version_.transport_version)) { + std::string more_response_body{"bbb"}; + EXPECT_CALL(stream_decoder_, decodeData(_, _)) + .WillOnce(Invoke([&](Buffer::Instance& buffer, bool finished_reading) { + EXPECT_EQ(more_response_body, buffer.toString()); + EXPECT_EQ(false, finished_reading); + })); + std::string payload = absl::StrCat(bodyToStreamPayload(more_response_body), + spdyHeaderToHttp3StreamPayload(spdy_trailers_)); + quic::QuicStreamFrame frame(stream_id_, true, offset, payload); + quic_stream_->OnStreamFrame(frame); + } else { + quic_stream_->OnStreamHeaderList( + /*fin=*/!quic::VersionUsesHttp3(quic_version_.transport_version), + trailers_.uncompressed_header_bytes(), trailers_); + } } TEST_P(EnvoyQuicClientStreamTest, OutOfOrderTrailers) { @@ -186,7 +231,7 @@ TEST_P(EnvoyQuicClientStreamTest, OutOfOrderTrailers) { std::unique_ptr data_buffer; quic::QuicByteCount data_frame_header_length = quic::HttpEncoder::SerializeDataFrameHeader(response_body_.length(), &data_buffer); - quiche::QuicheStringPiece data_frame_header(data_buffer.get(), data_frame_header_length); + absl::string_view data_frame_header(data_buffer.get(), data_frame_header_length); data = absl::StrCat(data_frame_header, response_body_); } quic::QuicStreamFrame frame(stream_id_, false, 0, data); @@ -286,11 +331,11 @@ TEST_P(EnvoyQuicClientStreamTest, HeadersContributeToWatermarkIquic) { // Make the stream blocked by congestion control. EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t /*write_length*/, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{0u, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t /*write_length*/, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{0u, state != quic::NO_FIN}; + })); const auto result = quic_stream_->encodeHeaders(request_headers_, /*end_stream=*/false); EXPECT_TRUE(result.ok()); @@ -305,11 +350,11 @@ TEST_P(EnvoyQuicClientStreamTest, HeadersContributeToWatermarkIquic) { // Unblock writing now, and this will write out 16kB data and cause stream to // be blocked by the flow control limit. EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; + })); EXPECT_CALL(stream_callbacks_, onBelowWriteBufferLowWatermark()); quic_session_.OnCanWrite(); EXPECT_TRUE(quic_stream_->IsFlowControlBlocked()); @@ -319,20 +364,20 @@ TEST_P(EnvoyQuicClientStreamTest, HeadersContributeToWatermarkIquic) { 32 * 1024); quic_stream_->OnWindowUpdateFrame(window_update1); EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; + })); quic_session_.OnCanWrite(); // No data should be buffered at this point. EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{0u, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{0u, state != quic::NO_FIN}; + })); // Send more data. If watermark bytes counting were not cleared in previous // OnCanWrite, this write would have caused the stream to exceed its high watermark. std::string request1(16 * 1024 - 3, 'a'); @@ -345,5 +390,18 @@ TEST_P(EnvoyQuicClientStreamTest, HeadersContributeToWatermarkIquic) { EXPECT_CALL(stream_callbacks_, onResetStream(_, _)); } +TEST_P(EnvoyQuicClientStreamTest, ResetStream) { + EXPECT_CALL(stream_callbacks_, onResetStream(Http::StreamResetReason::LocalReset, _)); + quic_stream_->resetStream(Http::StreamResetReason::LocalReset); + EXPECT_TRUE(quic_stream_->rst_sent()); +} + +TEST_P(EnvoyQuicClientStreamTest, ReceiveResetStream) { + EXPECT_CALL(stream_callbacks_, onResetStream(Http::StreamResetReason::RemoteReset, _)); + quic_stream_->OnStreamReset(quic::QuicRstStreamFrame( + quic::kInvalidControlFrameId, quic_stream_->id(), quic::QUIC_STREAM_NO_ERROR, 0)); + EXPECT_TRUE(quic_stream_->rst_received()); +} + } // namespace Quic } // namespace Envoy diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_proof_source_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_proof_source_test.cc index cbf66f511f50..8a493a8e8954 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_proof_source_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_proof_source_test.cc @@ -25,7 +25,7 @@ namespace Quic { class TestGetProofCallback : public quic::ProofSource::Callback { public: TestGetProofCallback(bool& called, bool should_succeed, const std::string& server_config, - quic::QuicTransportVersion& version, quiche::QuicheStringPiece chlo_hash, + quic::QuicTransportVersion& version, absl::string_view chlo_hash, Network::FilterChain& filter_chain) : called_(called), should_succeed_(should_succeed), server_config_(server_config), version_(version), chlo_hash_(chlo_hash), expected_filter_chain_(filter_chain) { @@ -100,7 +100,7 @@ class TestGetProofCallback : public quic::ProofSource::Callback { bool should_succeed_; const std::string& server_config_; const quic::QuicTransportVersion& version_; - quiche::QuicheStringPiece chlo_hash_; + absl::string_view chlo_hash_; Network::FilterChain& expected_filter_chain_; NiceMock store_; Event::GlobalTimeSystem time_system_; @@ -178,7 +178,7 @@ class EnvoyQuicProofSourceTest : public ::testing::Test { quic::QuicSocketAddress server_address_; quic::QuicSocketAddress client_address_; quic::QuicTransportVersion version_{quic::QUIC_VERSION_UNSUPPORTED}; - quiche::QuicheStringPiece chlo_hash_{"aaaaa"}; + absl::string_view chlo_hash_{"aaaaa"}; std::string server_config_{"Server Config"}; std::string expected_certs_{quic::test::kTestCertificateChainPem}; std::string pkey_{quic::test::kTestCertificatePrivateKeyPem}; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_test.cc index 4a1dfe144dd3..9cdc169cd6f5 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_proof_verifier_test.cc @@ -163,7 +163,7 @@ TEST_F(EnvoyQuicProofVerifierTest, VerifyProofFailureEmptyCertChain) { std::unique_ptr cert_view = quic::CertificateView::ParseSingleCertificate(leaf_cert_); quic::QuicTransportVersion version{quic::QUIC_VERSION_UNSUPPORTED}; - quiche::QuicheStringPiece chlo_hash{"aaaaa"}; + absl::string_view chlo_hash{"aaaaa"}; std::string server_config{"Server Config"}; const std::string ocsp_response; const std::string cert_sct; @@ -181,7 +181,7 @@ TEST_F(EnvoyQuicProofVerifierTest, VerifyProofFailureInvalidLeafCert) { std::unique_ptr cert_view = quic::CertificateView::ParseSingleCertificate(leaf_cert_); quic::QuicTransportVersion version{quic::QUIC_VERSION_UNSUPPORTED}; - quiche::QuicheStringPiece chlo_hash{"aaaaa"}; + absl::string_view chlo_hash{"aaaaa"}; std::string server_config{"Server Config"}; const std::string ocsp_response; const std::string cert_sct; @@ -197,7 +197,7 @@ TEST_F(EnvoyQuicProofVerifierTest, VerifyProofFailureInvalidLeafCert) { TEST_F(EnvoyQuicProofVerifierTest, VerifyProofFailureUnsupportedECKey) { configCertVerificationDetails(true); quic::QuicTransportVersion version{quic::QUIC_VERSION_UNSUPPORTED}; - quiche::QuicheStringPiece chlo_hash{"aaaaa"}; + absl::string_view chlo_hash{"aaaaa"}; std::string server_config{"Server Config"}; const std::string ocsp_response; const std::string cert_sct; @@ -236,7 +236,7 @@ TEST_F(EnvoyQuicProofVerifierTest, VerifyProofFailureInvalidSignature) { std::unique_ptr cert_view = quic::CertificateView::ParseSingleCertificate(leaf_cert_); quic::QuicTransportVersion version{quic::QUIC_VERSION_UNSUPPORTED}; - quiche::QuicheStringPiece chlo_hash{"aaaaa"}; + absl::string_view chlo_hash{"aaaaa"}; std::string server_config{"Server Config"}; const std::string ocsp_response; const std::string cert_sct; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc index 05307c6b9b7c..4fc37685788a 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc @@ -61,6 +61,7 @@ class TestEnvoyQuicServerConnection : public EnvoyQuicServerConnection { const quic::ParsedQuicVersionVector& supported_versions, Network::Socket& listen_socket) : EnvoyQuicServerConnection(quic::test::TestConnectionId(), + quic::QuicSocketAddress(quic::QuicIpAddress::Any4(), 12345), quic::QuicSocketAddress(quic::QuicIpAddress::Loopback4(), 12345), helper, alarm_factory, &writer, /*owns_writer=*/false, supported_versions, listen_socket) {} @@ -201,10 +202,10 @@ class EnvoyQuicServerSessionTest : public testing::TestWithParam { crypto_stream_ = test_crypto_stream; } quic::test::QuicServerSessionBasePeer::SetCryptoStream(&envoy_quic_session_, crypto_stream); - quic_connection_->SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); quic_connection_->SetEncrypter( quic::ENCRYPTION_FORWARD_SECURE, std::make_unique(quic::Perspective::IS_SERVER)); + quic_connection_->SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); } bool installReadFilter() { diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc index 42ba39344f4b..3e37ba3e1d39 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc @@ -51,6 +51,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { POOL_GAUGE(listener_config_.listenerScope()), POOL_HISTOGRAM(listener_config_.listenerScope()))}), quic_connection_(quic::test::TestConnectionId(), + quic::QuicSocketAddress(quic::QuicIpAddress::Any6(), 123), quic::QuicSocketAddress(quic::QuicIpAddress::Any6(), 12345), connection_helper_, alarm_factory_, &writer_, /*owns_writer=*/false, {quic_version_}, *listener_config_.socket_), @@ -66,11 +67,11 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { quic_session_.ActivateStream(std::unique_ptr(quic_stream_)); EXPECT_CALL(quic_session_, ShouldYield(_)).WillRepeatedly(testing::Return(false)); EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillRepeatedly(Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; - })); + .WillRepeatedly( + Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; + })); EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) .WillRepeatedly(Invoke([](const char*, size_t buf_len, const quic::QuicIpAddress&, const quic::QuicSocketAddress&, quic::PerPacketOptions*) { @@ -88,14 +89,16 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { request_headers_.OnHeader(":path", "/"); request_headers_.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); + spdy_request_headers_[":authority"] = host_; + spdy_request_headers_[":method"] = "POST"; + spdy_request_headers_[":path"] = "/"; trailers_.OnHeaderBlockStart(); trailers_.OnHeader("key1", "value1"); - if (!quic::VersionUsesHttp3(quic_version_.transport_version)) { - // ":final-offset" is required and stripped off by quic. - trailers_.OnHeader(":final-offset", absl::StrCat("", request_body_.length())); - } + // ":final-offset" is required and stripped off by quic. + trailers_.OnHeader(":final-offset", absl::StrCat("", request_body_.length())); trailers_.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); + spdy_trailers_["key1"] = "value1"; } void TearDown() override { @@ -105,27 +108,20 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { } std::string bodyToStreamPayload(const std::string& body) { - std::string data = body; - if (quic::VersionUsesHttp3(quic_version_.transport_version)) { - std::unique_ptr data_buffer; - quic::QuicByteCount data_frame_header_length = - quic::HttpEncoder::SerializeDataFrameHeader(body.length(), &data_buffer); - quiche::QuicheStringPiece data_frame_header(data_buffer.get(), data_frame_header_length); - data = absl::StrCat(data_frame_header, body); + if (!quic::VersionUsesHttp3(quic_version_.transport_version)) { + return body; } - return data; + return bodyToHttp3StreamPayload(body); } - size_t sendRequest(const std::string& payload, bool fin, size_t decoder_buffer_high_watermark) { + size_t receiveRequest(const std::string& payload, bool fin, + size_t decoder_buffer_high_watermark) { EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) .WillOnce(Invoke([this](const Http::RequestHeaderMapPtr& headers, bool) { EXPECT_EQ(host_, headers->getHostValue()); EXPECT_EQ("/", headers->getPathValue()); EXPECT_EQ(Http::Headers::get().MethodValues.Post, headers->getMethodValue()); })); - quic_stream_->OnStreamHeaderList(/*fin=*/false, request_headers_.uncompressed_header_bytes(), - request_headers_); - EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); EXPECT_CALL(stream_decoder_, decodeData(_, _)) .WillOnce(Invoke([&](Buffer::Instance& buffer, bool finished_reading) { @@ -135,10 +131,21 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { quic_stream_->readDisable(true); } })); - std::string data = bodyToStreamPayload(payload); - quic::QuicStreamFrame frame(stream_id_, fin, 0, data); + if (quic::VersionUsesHttp3(quic_version_.transport_version)) { + std::string data = absl::StrCat(spdyHeaderToHttp3StreamPayload(spdy_request_headers_), + bodyToStreamPayload(payload)); + quic::QuicStreamFrame frame(stream_id_, fin, 0, data); + quic_stream_->OnStreamFrame(frame); + EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); + return data.length(); + } + quic_stream_->OnStreamHeaderList(/*fin=*/false, request_headers_.uncompressed_header_bytes(), + request_headers_); + + quic::QuicStreamFrame frame(stream_id_, fin, 0, payload); quic_stream_->OnStreamFrame(frame); - return data.length(); + EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); + return payload.length(); } protected: @@ -158,9 +165,11 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { Http::MockRequestDecoder stream_decoder_; Http::MockStreamCallbacks stream_callbacks_; quic::QuicHeaderList request_headers_; + spdy::SpdyHeaderBlock spdy_request_headers_; Http::TestResponseHeaderMapImpl response_headers_; Http::TestResponseTrailerMapImpl response_trailers_; quic::QuicHeaderList trailers_; + spdy::SpdyHeaderBlock spdy_trailers_; std::string host_{"www.abc.com"}; std::string request_body_{"Hello world"}; }; @@ -177,27 +186,40 @@ TEST_P(EnvoyQuicServerStreamTest, GetRequestAndResponse) { request_headers.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); - EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/true)) + EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/!quic::VersionUsesHttp3( + quic_version_.transport_version))) .WillOnce(Invoke([this](const Http::RequestHeaderMapPtr& headers, bool) { EXPECT_EQ(host_, headers->getHostValue()); EXPECT_EQ("/", headers->getPathValue()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, headers->getMethodValue()); })); - quic_stream_->OnStreamHeaderList(/*fin=*/true, request_headers.uncompressed_header_bytes(), - request_headers); + if (quic::VersionUsesHttp3(quic_version_.transport_version)) { + EXPECT_CALL(stream_decoder_, decodeData(BufferStringEqual(""), /*end_stream=*/true)); + spdy::SpdyHeaderBlock spdy_headers; + spdy_headers[":authority"] = host_; + spdy_headers[":method"] = "GET"; + spdy_headers[":path"] = "/"; + std::string payload = spdyHeaderToHttp3StreamPayload(spdy_headers); + quic::QuicStreamFrame frame(stream_id_, true, 0, payload); + quic_stream_->OnStreamFrame(frame); + } else { + quic_stream_->OnStreamHeaderList(/*fin=*/true, request_headers.uncompressed_header_bytes(), + request_headers); + } EXPECT_TRUE(quic_stream_->FinishedReadingHeaders()); quic_stream_->encodeHeaders(response_headers_, /*end_stream=*/true); } TEST_P(EnvoyQuicServerStreamTest, PostRequestAndResponse) { EXPECT_EQ(absl::nullopt, quic_stream_->http1StreamEncoderOptions()); - sendRequest(request_body_, true, request_body_.size() * 2); + receiveRequest(request_body_, true, request_body_.size() * 2); quic_stream_->encodeHeaders(response_headers_, /*end_stream=*/false); quic_stream_->encodeTrailers(response_trailers_); } TEST_P(EnvoyQuicServerStreamTest, DecodeHeadersBodyAndTrailers) { - sendRequest(request_body_, false, request_body_.size() * 2); + size_t offset = receiveRequest(request_body_, false, request_body_.size() * 2); + EXPECT_CALL(stream_decoder_, decodeTrailers_(_)) .WillOnce(Invoke([](const Http::RequestTrailerMapPtr& headers) { Http::LowerCaseString key1("key1"); @@ -205,7 +227,14 @@ TEST_P(EnvoyQuicServerStreamTest, DecodeHeadersBodyAndTrailers) { EXPECT_EQ("value1", headers->get(key1)[0]->value().getStringView()); EXPECT_TRUE(headers->get(key2).empty()); })); - quic_stream_->OnStreamHeaderList(/*fin=*/true, trailers_.uncompressed_header_bytes(), trailers_); + if (quic::VersionUsesHttp3(quic_version_.transport_version)) { + std::string payload = spdyHeaderToHttp3StreamPayload(spdy_trailers_); + quic::QuicStreamFrame frame(stream_id_, true, offset, payload); + quic_stream_->OnStreamFrame(frame); + } else { + quic_stream_->OnStreamHeaderList(/*fin=*/true, trailers_.uncompressed_header_bytes(), + trailers_); + } EXPECT_CALL(stream_callbacks_, onResetStream(_, _)); } @@ -227,8 +256,7 @@ TEST_P(EnvoyQuicServerStreamTest, OutOfOrderTrailers) { // Trailer should be delivered to HCM later after body arrives. quic_stream_->OnStreamHeaderList(/*fin=*/true, trailers_.uncompressed_header_bytes(), trailers_); - std::string data = bodyToStreamPayload(request_body_); - quic::QuicStreamFrame frame(stream_id_, false, 0, data); + quic::QuicStreamFrame frame(stream_id_, false, 0, request_body_); EXPECT_CALL(stream_decoder_, decodeData(_, _)) .WillOnce(Invoke([this](Buffer::Instance& buffer, bool finished_reading) { EXPECT_EQ(request_body_, buffer.toString()); @@ -245,10 +273,29 @@ TEST_P(EnvoyQuicServerStreamTest, OutOfOrderTrailers) { quic_stream_->OnStreamFrame(frame); } +TEST_P(EnvoyQuicServerStreamTest, ResetStreamByHCM) { + receiveRequest(request_body_, false, request_body_.size() * 2); + EXPECT_CALL(stream_callbacks_, onResetStream(_, _)); + quic_stream_->resetStream(Http::StreamResetReason::LocalReset); + EXPECT_TRUE(quic_stream_->rst_sent()); +} + +TEST_P(EnvoyQuicServerStreamTest, EarlyResponseWithReset) { + receiveRequest(request_body_, false, request_body_.size() * 2); + // Write response headers with FIN before finish receiving request. + quic_stream_->encodeHeaders(response_headers_, true); + // Resetting the stream now means stop reading and sending QUIC_STREAM_NO_ERROR. + EXPECT_CALL(stream_callbacks_, onResetStream(_, _)); + quic_stream_->resetStream(Http::StreamResetReason::LocalReset); + EXPECT_TRUE(quic_stream_->rst_sent()); + EXPECT_TRUE(quic_stream_->reading_stopped()); + EXPECT_EQ(quic::QUIC_STREAM_NO_ERROR, quic_stream_->stream_error()); +} + TEST_P(EnvoyQuicServerStreamTest, ReadDisableUponLargePost) { std::string large_request(1024, 'a'); // Sending such large request will cause read to be disabled. - size_t payload_offset = sendRequest(large_request, false, 512); + size_t payload_offset = receiveRequest(large_request, false, 512); EXPECT_FALSE(quic_stream_->HasBytesToRead()); // Disable reading one more time. quic_stream_->readDisable(true); @@ -324,7 +371,7 @@ TEST_P(EnvoyQuicServerStreamTest, ReadDisableAndReEnableImmediately) { // Tests that the stream with a send buffer whose high limit is 16k and low // limit is 8k sends over 32kB response. TEST_P(EnvoyQuicServerStreamTest, WatermarkSendBuffer) { - sendRequest(request_body_, true, request_body_.size() * 2); + receiveRequest(request_body_, true, request_body_.size() * 2); // Bump connection flow control window large enough not to cause connection // level flow control blocked. @@ -386,7 +433,7 @@ TEST_P(EnvoyQuicServerStreamTest, HeadersContributeToWatermarkIquic) { return; } - sendRequest(request_body_, true, request_body_.size() * 2); + receiveRequest(request_body_, true, request_body_.size() * 2); // Bump connection flow control window large enough not to cause connection level flow control // blocked @@ -397,11 +444,11 @@ TEST_P(EnvoyQuicServerStreamTest, HeadersContributeToWatermarkIquic) { // Make the stream blocked by congestion control. EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t /*write_length*/, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{0u, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t /*write_length*/, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{0u, state != quic::NO_FIN}; + })); quic_stream_->encodeHeaders(response_headers_, /*end_stream=*/false); // Encode 16kB -10 bytes request body. Because the high watermark is 16KB, with previously @@ -415,11 +462,11 @@ TEST_P(EnvoyQuicServerStreamTest, HeadersContributeToWatermarkIquic) { // Unblock writing now, and this will write out 16kB data and cause stream to // be blocked by the flow control limit. EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; + })); EXPECT_CALL(stream_callbacks_, onBelowWriteBufferLowWatermark()); quic_session_.OnCanWrite(); EXPECT_TRUE(quic_stream_->IsFlowControlBlocked()); @@ -429,20 +476,20 @@ TEST_P(EnvoyQuicServerStreamTest, HeadersContributeToWatermarkIquic) { 32 * 1024); quic_stream_->OnWindowUpdateFrame(window_update1); EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillOnce(Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; - })); + .WillOnce( + Invoke([](quic::QuicStreamId, size_t write_length, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{write_length, state != quic::NO_FIN}; + })); quic_session_.OnCanWrite(); // No data should be buffered at this point. EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _, _)) - .WillRepeatedly(Invoke([](quic::QuicStreamId, size_t, quic::QuicStreamOffset, - quic::StreamSendingState state, bool, - quiche::QuicheOptional) { - return quic::QuicConsumedData{0u, state != quic::NO_FIN}; - })); + .WillRepeatedly( + Invoke([](quic::QuicStreamId, size_t, quic::QuicStreamOffset, + quic::StreamSendingState state, bool, absl::optional) { + return quic::QuicConsumedData{0u, state != quic::NO_FIN}; + })); // Send more data. If watermark bytes counting were not cleared in previous // OnCanWrite, this write would have caused the stream to exceed its high watermark. std::string response1(16 * 1024 - 3, 'a'); diff --git a/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc b/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc index d6121ff2ec6a..4c6309620f3d 100644 --- a/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc +++ b/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc @@ -531,5 +531,11 @@ TEST_P(QuicHttpIntegrationTest, CertVerificationFailure) { EXPECT_EQ(failure_reason, codec_client_->connection()->transportFailureReason()); } +TEST_P(QuicHttpIntegrationTest, RequestResponseWithTrailers) { + config_helper_.addConfigModifier(setEnableUpstreamTrailersHttp1()); + testTrailers(/*request_size=*/10, /*response_size=*/10, /*request_trailers_present=*/true, + /*response_trailers_present=*/true); +} + } // namespace Quic } // namespace Envoy diff --git a/test/extensions/quic_listeners/quiche/platform/BUILD b/test/extensions/quic_listeners/quiche/platform/BUILD index 420e812b85a7..7dbb08d821cc 100644 --- a/test/extensions/quic_listeners/quiche/platform/BUILD +++ b/test/extensions/quic_listeners/quiche/platform/BUILD @@ -9,16 +9,6 @@ licenses(["notice"]) # Apache 2 envoy_package() -envoy_cc_test( - name = "quiche_platform_test", - srcs = ["quiche_platform_test.cc"], - external_deps = ["quiche_common_platform"], - deps = [ - "@com_googlesource_quiche//:quiche_common_platform", - "@com_googlesource_quiche//:quiche_common_platform_endian", - ], -) - envoy_cc_test( name = "http2_platform_test", srcs = ["http2_platform_test.cc"], @@ -63,7 +53,6 @@ envoy_cc_test( "@com_googlesource_quiche//:quic_platform_mem_slice_span", "@com_googlesource_quiche//:quic_platform_mem_slice_storage", "@com_googlesource_quiche//:quic_platform_mock_log", - "@com_googlesource_quiche//:quic_platform_port_utils", "@com_googlesource_quiche//:quic_platform_sleep", "@com_googlesource_quiche//:quic_platform_system_event_loop", "@com_googlesource_quiche//:quic_platform_test", @@ -150,17 +139,6 @@ envoy_cc_test_library( deps = ["@com_googlesource_quiche//:quic_platform_base"], ) -envoy_cc_test_library( - name = "quic_platform_port_utils_impl_lib", - srcs = ["quic_port_utils_impl.cc"], - hdrs = ["quic_port_utils_impl.h"], - tags = ["nofips"], - deps = [ - "//source/common/network:utility_lib", - "//test/test_common:environment_lib", - ], -) - envoy_cc_test_library( name = "quic_platform_test_mem_slice_vector_impl_lib", hdrs = ["quic_test_mem_slice_vector_impl.h"], diff --git a/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc index 069a79eab0ef..35aee5d27373 100644 --- a/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc @@ -72,20 +72,14 @@ TEST(Http2PlatformTest, Http2Log) { HTTP2_DLOG_EVERY_N(ERROR, 2) << "DLOG_EVERY_N(ERROR, 2)"; } -TEST(Http2PlatformTest, Http2StringPiece) { - std::string s = "bar"; - quiche::QuicheStringPiece sp(s); - EXPECT_EQ('b', sp[0]); -} - TEST(Http2PlatformTest, Http2Macro) { EXPECT_DEBUG_DEATH(HTTP2_UNREACHABLE(), ""); EXPECT_DEATH(HTTP2_DIE_IF_NULL(nullptr), ""); } TEST(Http2PlatformTest, Http2Flags) { - auto& flag_registry = quiche::FlagRegistry::GetInstance(); - flag_registry.ResetFlags(); + auto& flag_registry = quiche::FlagRegistry::getInstance(); + flag_registry.resetFlags(); EXPECT_FALSE(GetHttp2ReloadableFlag(http2_testonly_default_false)); SetHttp2ReloadableFlag(http2_testonly_default_false, true); EXPECT_TRUE(GetHttp2ReloadableFlag(http2_testonly_default_false)); @@ -93,22 +87,22 @@ TEST(Http2PlatformTest, Http2Flags) { for (std::string s : {"1", "t", "true", "TRUE", "y", "yes", "Yes"}) { SetHttp2ReloadableFlag(http2_testonly_default_false, false); EXPECT_FALSE(GetHttp2ReloadableFlag(http2_testonly_default_false)); - EXPECT_TRUE(flag_registry.FindFlag("http2_reloadable_flag_http2_testonly_default_false") - ->SetValueFromString(s)); + EXPECT_TRUE(flag_registry.findFlag("FLAGS_quic_reloadable_flag_http2_testonly_default_false") + ->setValueFromString(s)); EXPECT_TRUE(GetHttp2ReloadableFlag(http2_testonly_default_false)); } for (std::string s : {"0", "f", "false", "FALSE", "n", "no", "No"}) { SetHttp2ReloadableFlag(http2_testonly_default_false, true); EXPECT_TRUE(GetHttp2ReloadableFlag(http2_testonly_default_false)); - EXPECT_TRUE(flag_registry.FindFlag("http2_reloadable_flag_http2_testonly_default_false") - ->SetValueFromString(s)); + EXPECT_TRUE(flag_registry.findFlag("FLAGS_quic_reloadable_flag_http2_testonly_default_false") + ->setValueFromString(s)); EXPECT_FALSE(GetHttp2ReloadableFlag(http2_testonly_default_false)); } for (std::string s : {"some", "invalid", "values", ""}) { SetHttp2ReloadableFlag(http2_testonly_default_false, false); EXPECT_FALSE(GetHttp2ReloadableFlag(http2_testonly_default_false)); - EXPECT_FALSE(flag_registry.FindFlag("http2_reloadable_flag_http2_testonly_default_false") - ->SetValueFromString(s)); + EXPECT_FALSE(flag_registry.findFlag("FLAGS_quic_reloadable_flag_http2_testonly_default_false") + ->setValueFromString(s)); EXPECT_FALSE(GetHttp2ReloadableFlag(http2_testonly_default_false)); } } diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index 68141aa94039..902ad1a9ea0f 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -30,7 +30,6 @@ #include "gtest/gtest.h" #include "quiche/common/platform/api/quiche_string_piece.h" #include "quiche/epoll_server/fake_simple_epoll_server.h" -#include "quiche/quic/platform/api/quic_aligned.h" #include "quiche/quic/platform/api/quic_bug_tracker.h" #include "quiche/quic/platform/api/quic_cert_utils.h" #include "quiche/quic/platform/api/quic_client_stats.h" @@ -42,7 +41,6 @@ #include "quiche/quic/platform/api/quic_flags.h" #include "quiche/quic/platform/api/quic_hostname_utils.h" #include "quiche/quic/platform/api/quic_logging.h" -#include "quiche/quic/platform/api/quic_macros.h" #include "quiche/quic/platform/api/quic_map_util.h" #include "quiche/quic/platform/api/quic_mem_slice.h" #include "quiche/quic/platform/api/quic_mem_slice_span.h" @@ -50,7 +48,6 @@ #include "quiche/quic/platform/api/quic_mock_log.h" #include "quiche/quic/platform/api/quic_mutex.h" #include "quiche/quic/platform/api/quic_pcc_sender.h" -#include "quiche/quic/platform/api/quic_port_utils.h" #include "quiche/quic/platform/api/quic_ptr_util.h" #include "quiche/quic/platform/api/quic_server_stats.h" #include "quiche/quic/platform/api/quic_sleep.h" @@ -92,8 +89,6 @@ class QuicPlatformTest : public testing::Test { const int verbosity_log_threshold_; }; -TEST_F(QuicPlatformTest, QuicAlignOf) { EXPECT_LT(0, QUIC_ALIGN_OF(int)); } - enum class TestEnum { ZERO = 0, ONE, TWO, COUNT }; TEST_F(QuicPlatformTest, QuicBugTracker) { @@ -468,9 +463,9 @@ TEST_F(QuicPlatformTest, QuicCertUtils) { unsigned char* der = nullptr; int len = i2d_X509(x509_cert.get(), &der); ASSERT_GT(len, 0); - quiche::QuicheStringPiece out; + absl::string_view out; QuicCertUtils::ExtractSubjectNameFromDERCert( - quiche::QuicheStringPiece(reinterpret_cast(der), len), &out); + absl::string_view(reinterpret_cast(der), len), &out); EXPECT_EQ("0z1\v0\t\x6\x3U\x4\x6\x13\x2US1\x13" "0\x11\x6\x3U\x4\b\f\nCalifornia1\x16" "0\x14\x6\x3U\x4\a\f\rSan Francisco1\r" @@ -566,8 +561,8 @@ TEST_F(QuicPlatformTest, MonotonicityWithFakeEpollClock) { } TEST_F(QuicPlatformTest, QuicFlags) { - auto& flag_registry = quiche::FlagRegistry::GetInstance(); - flag_registry.ResetFlags(); + auto& flag_registry = quiche::FlagRegistry::getInstance(); + flag_registry.resetFlags(); EXPECT_FALSE(GetQuicReloadableFlag(quic_testonly_default_false)); EXPECT_TRUE(GetQuicReloadableFlag(quic_testonly_default_true)); @@ -583,14 +578,15 @@ TEST_F(QuicPlatformTest, QuicFlags) { SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 100); EXPECT_EQ(100, GetQuicFlag(FLAGS_quic_time_wait_list_seconds)); - flag_registry.ResetFlags(); + flag_registry.resetFlags(); EXPECT_FALSE(GetQuicReloadableFlag(quic_testonly_default_false)); EXPECT_TRUE(GetQuicRestartFlag(quic_testonly_default_true)); EXPECT_EQ(200, GetQuicFlag(FLAGS_quic_time_wait_list_seconds)); - flag_registry.FindFlag("quic_reloadable_flag_quic_testonly_default_false") - ->SetValueFromString("true"); - flag_registry.FindFlag("quic_restart_flag_quic_testonly_default_true")->SetValueFromString("0"); - flag_registry.FindFlag("quic_time_wait_list_seconds")->SetValueFromString("100"); + flag_registry.findFlag("FLAGS_quic_reloadable_flag_quic_testonly_default_false") + ->setValueFromString("true"); + flag_registry.findFlag("FLAGS_quic_restart_flag_quic_testonly_default_true") + ->setValueFromString("0"); + flag_registry.findFlag("FLAGS_quic_time_wait_list_seconds")->setValueFromString("100"); EXPECT_TRUE(GetQuicReloadableFlag(quic_testonly_default_false)); EXPECT_FALSE(GetQuicRestartFlag(quic_testonly_default_true)); EXPECT_EQ(100, GetQuicFlag(FLAGS_quic_time_wait_list_seconds)); @@ -661,35 +657,6 @@ TEST_F(FileUtilsTest, ReadFileContents) { EXPECT_EQ(data, output); } -TEST_F(QuicPlatformTest, PickUnsedPort) { - int port = QuicPickServerPortForTestsOrDie(); - std::vector supported_versions = - Envoy::TestEnvironment::getIpVersionsForTest(); - for (auto ip_version : supported_versions) { - Envoy::Network::Address::InstanceConstSharedPtr addr = - Envoy::Network::Test::getCanonicalLoopbackAddress(ip_version); - Envoy::Network::Address::InstanceConstSharedPtr addr_with_port = - Envoy::Network::Utility::getAddressWithPort(*addr, port); - Envoy::Network::SocketImpl sock(Envoy::Network::Socket::Type::Datagram, addr_with_port); - // binding of given port should success. - EXPECT_EQ(0, sock.bind(addr_with_port).rc_); - } -} - -TEST_F(QuicPlatformTest, FailToPickUnsedPort) { - Envoy::Api::MockOsSysCalls os_sys_calls; - Envoy::TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - // Actually create sockets. - EXPECT_CALL(os_sys_calls, socket(_, _, _)).WillRepeatedly([](int domain, int type, int protocol) { - os_fd_t fd = ::socket(domain, type, protocol); - return Envoy::Api::SysCallSocketResult{fd, errno}; - }); - // Fail bind call's to mimic port exhaustion. - EXPECT_CALL(os_sys_calls, bind(_, _, _)) - .WillRepeatedly(Return(Envoy::Api::SysCallIntResult{-1, SOCKET_ERROR_ADDR_IN_USE})); - EXPECT_DEATH(QuicPickServerPortForTestsOrDie(), "Failed to pick a port for test."); -} - TEST_F(QuicPlatformTest, TestEnvoyQuicBufferAllocator) { QuicStreamBufferAllocator allocator; Envoy::Stats::TestUtil::MemoryTest memory_test; @@ -711,14 +678,6 @@ TEST_F(QuicPlatformTest, TestSystemEventLoop) { QuicSystemEventLoop("dummy"); } -QUIC_MUST_USE_RESULT bool dummyTestFunction() { return false; } - -TEST_F(QuicPlatformTest, TestQuicMacros) { - // Just make sure it compiles. - EXPECT_FALSE(dummyTestFunction()); - int a QUIC_UNUSED; -} - TEST(EnvoyQuicMemSliceTest, ConstructMemSliceFromBuffer) { std::string str(512, 'b'); // Fragment needs to out-live buffer. diff --git a/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc b/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc index 556f6cd3e18a..9eaf8532aa49 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc @@ -19,7 +19,7 @@ namespace quic { namespace { -void QuicRecordTestOutputToFile(const std::string& filename, quiche::QuicheStringPiece data) { +void quicRecordTestOutputToFile(const std::string& filename, absl::string_view data) { const char* output_dir_env = std::getenv("QUIC_TEST_OUTPUT_DIR"); if (output_dir_env == nullptr) { QUIC_LOG(WARNING) << "Could not save test output since QUIC_TEST_OUTPUT_DIR is not set"; @@ -64,11 +64,13 @@ void QuicRecordTestOutputToFile(const std::string& filename, quiche::QuicheStrin } } // namespace -void QuicSaveTestOutputImpl(quiche::QuicheStringPiece filename, quiche::QuicheStringPiece data) { - QuicRecordTestOutputToFile(filename.data(), data); +// NOLINTNEXTLINE(readability-identifier-naming) +void QuicSaveTestOutputImpl(absl::string_view filename, absl::string_view data) { + quicRecordTestOutputToFile(filename.data(), data); } -bool QuicLoadTestOutputImpl(quiche::QuicheStringPiece filename, std::string* data) { +// NOLINTNEXTLINE(readability-identifier-naming) +bool QuicLoadTestOutputImpl(absl::string_view filename, std::string* data) { const char* read_dir_env = std::getenv("QUIC_TEST_OUTPUT_DIR"); if (read_dir_env == nullptr) { QUIC_LOG(WARNING) << "Could not load test output since QUIC_TEST_OUTPUT_DIR is not set"; @@ -96,7 +98,8 @@ bool QuicLoadTestOutputImpl(quiche::QuicheStringPiece filename, std::string* dat return true; } -void QuicRecordTraceImpl(quiche::QuicheStringPiece identifier, quiche::QuicheStringPiece data) { +// NOLINTNEXTLINE(readability-identifier-naming) +void QuicRecordTraceImpl(absl::string_view identifier, absl::string_view data) { const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); std::string timestamp = absl::FormatTime("%Y%m%d%H%M%S", absl::Now(), absl::LocalTimeZone()); @@ -104,7 +107,7 @@ void QuicRecordTraceImpl(quiche::QuicheStringPiece identifier, quiche::QuicheStr std::string filename = fmt::sprintf("%s.%s.%s.%s.qtr", test_info->name(), test_info->test_case_name(), identifier.data(), timestamp); - QuicRecordTestOutputToFile(filename, data); + quicRecordTestOutputToFile(filename, data); } } // namespace quic diff --git a/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h b/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h index a1c6c7305d48..fcf0c47b3a75 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h +++ b/test/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h @@ -6,14 +6,16 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -#include "quiche/common/platform/api/quiche_string_piece.h" +#include "absl/strings/string_view.h" namespace quic { +// NOLINTNEXTLINE(readability-identifier-naming) +void QuicSaveTestOutputImpl(absl::string_view filename, absl::string_view data); -void QuicSaveTestOutputImpl(quiche::QuicheStringPiece filename, quiche::QuicheStringPiece data); +// NOLINTNEXTLINE(readability-identifier-naming) +bool QuicLoadTestOutputImpl(absl::string_view filename, std::string* data); -bool QuicLoadTestOutputImpl(quiche::QuicheStringPiece filename, std::string* data); - -void QuicRecordTraceImpl(quiche::QuicheStringPiece identifier, quiche::QuicheStringPiece data); +// NOLINTNEXTLINE(readability-identifier-naming) +void QuicRecordTraceImpl(absl::string_view identifier, absl::string_view data); } // namespace quic diff --git a/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc deleted file mode 100644 index a733894b5505..000000000000 --- a/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc +++ /dev/null @@ -1,39 +0,0 @@ -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "gtest/gtest.h" -#include "quiche/common/platform/api/quiche_arraysize.h" -#include "quiche/common/platform/api/quiche_endian.h" -#include "quiche/common/platform/api/quiche_optional.h" -#include "quiche/common/platform/api/quiche_ptr_util.h" -#include "quiche/common/platform/api/quiche_string_piece.h" - -namespace quiche { - -TEST(QuichePlatformTest, Arraysize) { - int array[] = {0, 1, 2, 3, 4}; - EXPECT_EQ(5, QUICHE_ARRAYSIZE(array)); -} - -TEST(QuichePlatformTest, StringPiece) { - std::string s = "bar"; - QuicheStringPiece sp(s); - EXPECT_EQ('b', sp[0]); -} - -TEST(QuichePlatformTest, WrapUnique) { - auto p = QuicheWrapUnique(new int(6)); - EXPECT_EQ(6, *p); -} - -TEST(QuichePlatformTest, TestQuicheOptional) { - QuicheOptional maybe_a; - EXPECT_FALSE(maybe_a.has_value()); - maybe_a = 1; - EXPECT_EQ(1, *maybe_a); -} - -} // namespace quiche diff --git a/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc index 56453e232c1a..eeae58c0ab26 100644 --- a/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc @@ -8,7 +8,6 @@ #include "gtest/gtest.h" #include "quiche/spdy/platform/api/spdy_bug_tracker.h" #include "quiche/spdy/platform/api/spdy_containers.h" -#include "quiche/spdy/platform/api/spdy_endianness_util.h" #include "quiche/spdy/platform/api/spdy_estimate_memory_usage.h" #include "quiche/spdy/platform/api/spdy_flags.h" #include "quiche/spdy/platform/api/spdy_logging.h" @@ -47,11 +46,6 @@ TEST(SpdyPlatformTest, SpdyHashSet) { EXPECT_EQ(0, hset.count("qux")); } -TEST(SpdyPlatformTest, SpdyEndianness) { - EXPECT_EQ(0x1234, spdy::SpdyNetToHost16(spdy::SpdyHostToNet16(0x1234))); - EXPECT_EQ(0x12345678, spdy::SpdyNetToHost32(spdy::SpdyHostToNet32(0x12345678))); -} - TEST(SpdyPlatformTest, SpdyEstimateMemoryUsage) { std::string s = "foo"; // Stubbed out to always return 0. @@ -92,19 +86,19 @@ TEST(SpdyPlatformTest, SpdyTestHelpers) { } TEST(SpdyPlatformTest, SpdyFlags) { - auto& flag_registry = quiche::FlagRegistry::GetInstance(); - flag_registry.ResetFlags(); + auto& flag_registry = quiche::FlagRegistry::getInstance(); + flag_registry.resetFlags(); EXPECT_FALSE(GetSpdyReloadableFlag(spdy_testonly_default_false)); EXPECT_FALSE(GetSpdyRestartFlag(spdy_testonly_default_false)); - flag_registry.FindFlag("spdy_reloadable_flag_spdy_testonly_default_false") - ->SetValueFromString("true"); + flag_registry.findFlag("FLAGS_quic_reloadable_flag_spdy_testonly_default_false") + ->setValueFromString("true"); EXPECT_TRUE(GetSpdyReloadableFlag(spdy_testonly_default_false)); EXPECT_FALSE(GetSpdyRestartFlag(spdy_testonly_default_false)); - flag_registry.ResetFlags(); - flag_registry.FindFlag("spdy_restart_flag_spdy_testonly_default_false") - ->SetValueFromString("yes"); + flag_registry.resetFlags(); + flag_registry.findFlag("FLAGS_quic_restart_flag_spdy_testonly_default_false") + ->setValueFromString("yes"); EXPECT_FALSE(GetSpdyReloadableFlag(spdy_testonly_default_false)); EXPECT_TRUE(GetSpdyRestartFlag(spdy_testonly_default_false)); } diff --git a/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc b/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc index da1d7b1aeae5..7a711ef39d65 100644 --- a/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc +++ b/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc @@ -77,18 +77,19 @@ TEST_F(QuicIoHandleWrapperTest, DelegateIoHandleCalls) { addr = wrapper_->peerAddress(); Network::IoHandle::RecvMsgOutput output(1, nullptr); - EXPECT_CALL(os_sys_calls_, recvmsg(fd, _, 0)).WillOnce(Invoke([](os_fd_t, msghdr* msg, int) { - sockaddr_storage ss; - auto ipv6_addr = reinterpret_cast(&ss); - memset(ipv6_addr, 0, sizeof(sockaddr_in6)); - ipv6_addr->sin6_family = AF_INET6; - ipv6_addr->sin6_addr = in6addr_loopback; - ipv6_addr->sin6_port = htons(54321); - *reinterpret_cast(msg->msg_name) = *ipv6_addr; - msg->msg_namelen = sizeof(sockaddr_in6); - msg->msg_controllen = 0; - return Api::SysCallSizeResult{5u, 0}; - })); + EXPECT_CALL(os_sys_calls_, recvmsg(fd, _, MSG_TRUNC)) + .WillOnce(Invoke([](os_fd_t, msghdr* msg, int) { + sockaddr_storage ss; + auto ipv6_addr = reinterpret_cast(&ss); + memset(ipv6_addr, 0, sizeof(sockaddr_in6)); + ipv6_addr->sin6_family = AF_INET6; + ipv6_addr->sin6_addr = in6addr_loopback; + ipv6_addr->sin6_port = htons(54321); + *reinterpret_cast(msg->msg_name) = *ipv6_addr; + msg->msg_namelen = sizeof(sockaddr_in6); + msg->msg_controllen = 0; + return Api::SysCallSizeResult{5u, 0}; + })); wrapper_->recvmsg(&slice, 1, /*self_port=*/12345, output); size_t num_packet_per_call = 1u; @@ -97,7 +98,7 @@ TEST_F(QuicIoHandleWrapperTest, DelegateIoHandleCalls) { absl::FixedArray({Buffer::RawSlice{data, 5}})); EXPECT_CALL(os_sys_calls_, recvmmsg(fd, _, num_packet_per_call, _, nullptr)) .WillOnce(Invoke([](os_fd_t, struct mmsghdr*, unsigned int, int, struct timespec*) { - return Api::SysCallIntResult{1u, 0}; + return Api::SysCallIntResult{-1, SOCKET_ERROR_AGAIN}; })); wrapper_->recvmmsg(slices, /*self_port=*/12345, output2); diff --git a/test/extensions/quic_listeners/quiche/test_proof_source.h b/test/extensions/quic_listeners/quiche/test_proof_source.h index a249b43144fd..bbedfd6c7b00 100644 --- a/test/extensions/quic_listeners/quiche/test_proof_source.h +++ b/test/extensions/quic_listeners/quiche/test_proof_source.h @@ -36,7 +36,7 @@ class TestProofSource : public EnvoyQuicProofSourceBase { void signPayload(const quic::QuicSocketAddress& /*server_address*/, const quic::QuicSocketAddress& /*client_address*/, const std::string& /*hostname*/, uint16_t /*signature_algorithm*/, - quiche::QuicheStringPiece in, + absl::string_view in, std::unique_ptr callback) override { callback->Run(true, absl::StrCat("Fake signature for { ", in, " }"), std::make_unique(filter_chain_)); diff --git a/test/extensions/quic_listeners/quiche/test_utils.h b/test/extensions/quic_listeners/quiche/test_utils.h index 102f7608e50b..f59720130c70 100644 --- a/test/extensions/quic_listeners/quiche/test_utils.h +++ b/test/extensions/quic_listeners/quiche/test_utils.h @@ -13,6 +13,8 @@ #include "quiche/quic/core/quic_utils.h" #include "quiche/quic/test_tools/crypto_test_utils.h" #include "quiche/quic/test_tools/quic_config_peer.h" +#include "quiche/quic/test_tools/qpack/qpack_test_utils.h" +#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h" #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -46,7 +48,7 @@ class MockEnvoyQuicSession : public quic::QuicSpdySession, public QuicFilterMana MOCK_METHOD(quic::QuicConsumedData, WritevData, (quic::QuicStreamId id, size_t write_length, quic::QuicStreamOffset offset, quic::StreamSendingState state, quic::TransmissionType type, - quiche::QuicheOptional level)); + absl::optional level)); MOCK_METHOD(bool, ShouldYield, (quic::QuicStreamId id)); absl::string_view requestedServerName() const override { @@ -90,7 +92,7 @@ class MockEnvoyQuicClientSession : public quic::QuicSpdyClientSession, MOCK_METHOD(quic::QuicConsumedData, WritevData, (quic::QuicStreamId id, size_t write_length, quic::QuicStreamOffset offset, quic::StreamSendingState state, quic::TransmissionType type, - quiche::QuicheOptional level)); + absl::optional level)); MOCK_METHOD(bool, ShouldYield, (quic::QuicStreamId id)); absl::string_view requestedServerName() const override { @@ -167,6 +169,29 @@ enum class QuicVersionType { Iquic, }; +std::string spdyHeaderToHttp3StreamPayload(const spdy::SpdyHeaderBlock& header) { + quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate; + quic::test::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate; + auto qpack_encoder = std::make_unique(&decoder_stream_error_delegate); + qpack_encoder->set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate); + // QpackEncoder does not use the dynamic table by default, + // therefore the value of |stream_id| does not matter. + std::string payload = qpack_encoder->EncodeHeaderList(/* stream_id = */ 0, header, nullptr); + std::unique_ptr headers_buffer; + quic::QuicByteCount headers_frame_header_length = + quic::HttpEncoder::SerializeHeadersFrameHeader(payload.length(), &headers_buffer); + absl::string_view headers_frame_header(headers_buffer.get(), headers_frame_header_length); + return absl::StrCat(headers_frame_header, payload); +} + +std::string bodyToHttp3StreamPayload(const std::string& body) { + std::unique_ptr data_buffer; + quic::QuicByteCount data_frame_header_length = + quic::HttpEncoder::SerializeDataFrameHeader(body.length(), &data_buffer); + absl::string_view data_frame_header(data_buffer.get(), data_frame_header_length); + return absl::StrCat(data_frame_header, body); +} + // A test suite with variation of ip version and a knob to turn on/off IETF QUIC implementation. class QuicMultiVersionTest : public testing::TestWithParam> {}; diff --git a/test/extensions/stats_sinks/wasm/BUILD b/test/extensions/stats_sinks/wasm/BUILD index 6135c8cfcf0a..b0911d7aaa9f 100644 --- a/test/extensions/stats_sinks/wasm/BUILD +++ b/test/extensions/stats_sinks/wasm/BUILD @@ -24,6 +24,7 @@ envoy_extension_cc_test( extension_name = "envoy.stat_sinks.wasm", deps = [ "//source/extensions/stat_sinks/wasm:config", + "//test/extensions/common/wasm:wasm_runtime", "//test/extensions/stats_sinks/wasm/test_data:test_context_cpp_plugin", "//test/mocks/server:server_mocks", "@envoy_api//envoy/extensions/stat_sinks/wasm/v3:pkg_cc_proto", @@ -41,6 +42,7 @@ envoy_extension_cc_test( deps = [ "//source/common/stats:stats_lib", "//source/extensions/common/wasm:wasm_lib", + "//test/extensions/common/wasm:wasm_runtime", "//test/extensions/stats_sinks/wasm/test_data:test_context_cpp_plugin", "//test/mocks/stats:stats_mocks", "//test/test_common:wasm_lib", diff --git a/test/extensions/stats_sinks/wasm/config_test.cc b/test/extensions/stats_sinks/wasm/config_test.cc index d9b1263215af..012f4ecc2c98 100644 --- a/test/extensions/stats_sinks/wasm/config_test.cc +++ b/test/extensions/stats_sinks/wasm/config_test.cc @@ -8,6 +8,7 @@ #include "extensions/stat_sinks/wasm/wasm_stat_sink_impl.h" #include "extensions/stat_sinks/well_known_names.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/server/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/printers.h" @@ -65,20 +66,8 @@ class WasmStatSinkConfigTest : public testing::TestWithParam { Stats::SinkPtr sink_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8", -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm", -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime", -#endif - "null"); -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmStatSinkConfigTest, testing_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmStatSinkConfigTest, + Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmStatSinkConfigTest, CreateWasmFromEmpty) { envoy::extensions::stat_sinks::wasm::v3::Wasm config; diff --git a/test/extensions/stats_sinks/wasm/wasm_stat_sink_test.cc b/test/extensions/stats_sinks/wasm/wasm_stat_sink_test.cc index 716925bfd12f..db9f4108aedd 100644 --- a/test/extensions/stats_sinks/wasm/wasm_stat_sink_test.cc +++ b/test/extensions/stats_sinks/wasm/wasm_stat_sink_test.cc @@ -2,6 +2,7 @@ #include "extensions/common/wasm/wasm.h" +#include "test/extensions/common/wasm/wasm_runtime.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/wasm_base.h" @@ -54,20 +55,8 @@ class WasmCommonContextTest std::unique_ptr context_; }; -// NB: this is required by VC++ which can not handle the use of macros in the macro definitions -// used by INSTANTIATE_TEST_SUITE_P. -auto testing_values = testing::Values( -#if defined(ENVOY_WASM_V8) - "v8", -#endif -#if defined(ENVOY_WASM_WAVM) - "wavm", -#endif -#if defined(ENVOY_WASM_WASMTIME) - "wasmtime", -#endif - "null"); -INSTANTIATE_TEST_SUITE_P(Runtimes, WasmCommonContextTest, testing_values); +INSTANTIATE_TEST_SUITE_P(Runtimes, WasmCommonContextTest, + Envoy::Extensions::Common::Wasm::runtime_values); TEST_P(WasmCommonContextTest, OnStat) { std::string code; diff --git a/test/extensions/transport_sockets/tls/ssl_socket_test.cc b/test/extensions/transport_sockets/tls/ssl_socket_test.cc index 403a08b61c3a..774b57116d58 100644 --- a/test/extensions/transport_sockets/tls/ssl_socket_test.cc +++ b/test/extensions/transport_sockets/tls/ssl_socket_test.cc @@ -4724,6 +4724,7 @@ TEST_P(SslSocketTest, DownstreamNotReadySslSocket) { auto transport_socket = server_ssl_socket_factory.createTransportSocket(nullptr); EXPECT_EQ(EMPTY_STRING, transport_socket->protocol()); EXPECT_EQ(nullptr, transport_socket->ssl()); + EXPECT_EQ(true, transport_socket->canFlushClose()); Buffer::OwnedImpl buffer; Network::IoResult result = transport_socket->doRead(buffer); EXPECT_EQ(Network::PostIoAction::Close, result.action_); @@ -4759,6 +4760,7 @@ TEST_P(SslSocketTest, UpstreamNotReadySslSocket) { auto transport_socket = client_ssl_socket_factory.createTransportSocket(nullptr); EXPECT_EQ(EMPTY_STRING, transport_socket->protocol()); EXPECT_EQ(nullptr, transport_socket->ssl()); + EXPECT_EQ(true, transport_socket->canFlushClose()); Buffer::OwnedImpl buffer; Network::IoResult result = transport_socket->doRead(buffer); EXPECT_EQ(Network::PostIoAction::Close, result.action_); diff --git a/test/integration/BUILD b/test/integration/BUILD index 43dfa373074d..15731c7e8aef 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1069,10 +1069,14 @@ envoy_cc_test( ":http_integration_lib", "//source/common/buffer:buffer_lib", "//source/common/http:codec_client_lib", + "//source/extensions/access_loggers/file:config", "//source/extensions/filters/listener/proxy_protocol:config", + "//source/extensions/filters/network/tcp_proxy:config", "//test/test_common:utility_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/cluster/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/access_loggers/file/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/filters/network/tcp_proxy/v3:pkg_cc_proto", ], ) diff --git a/test/integration/ads_integration_test.cc b/test/integration/ads_integration_test.cc index a9d96e44a8a2..24468b45f20f 100644 --- a/test/integration/ads_integration_test.cc +++ b/test/integration/ads_integration_test.cc @@ -1521,4 +1521,21 @@ TEST_P(AdsClusterV2Test, XdsBatching) { initialize(); } +// Regression test for https://github.com/envoyproxy/envoy/issues/13681. +TEST_P(AdsClusterV2Test, TypeUrlAnnotationRegression) { + initialize(); + const auto cds_type_url = Config::getTypeUrl( + envoy::config::core::v3::ApiVersion::V2); + + EXPECT_TRUE(compareDiscoveryRequest(cds_type_url, "", {}, {}, {}, true)); + auto cluster = buildCluster("cluster_0"); + auto* bias = cluster.mutable_least_request_lb_config()->mutable_active_request_bias(); + bias->set_default_value(1.1); + bias->set_runtime_key("foo"); + sendDiscoveryResponse(cds_type_url, {cluster}, {cluster}, {}, + "1", true); + + test_server_->waitForCounterGe("cluster_manager.cds.update_rejected", 1); +} + } // namespace Envoy diff --git a/test/integration/h1_corpus/alloc_headers b/test/integration/h1_corpus/alloc_headers new file mode 100644 index 000000000000..3e8a5e62f1a8 --- /dev/null +++ b/test/integration/h1_corpus/alloc_headers @@ -0,0 +1,12 @@ +events { + downstream_send_bytes: "POST /test/long/urlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaattttttaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa448aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa HTTP/1.1\r\nhost: host\r\nx-lyft-user-id: 0\r\nx-forwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarded-for: -1113144117.0.0.1\r\ntransfer-encoding: chunked\r\n\r\n400\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234\234aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\344aaaaaaaaaaaaaaaaaaaaaa\r\n0\r\n\r\n" +} +events { + upstream_send_bytes: "HTTP/1.1 454 \002\002\002\002\002\002\002\002\002\002\002OK\r\ntransfer-encoding: chunked\r\n\r\n200\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_aaaaaaaaaaaaaaaaFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n0\r\n\r\n" +} +events { + upstream_send_bytes: "HTTP/1.1 654 \002\002\002\002\002\002\002\002\002\002\002OK\r\ntransfer-encoding: chunked\r\n\r\n200\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_aaaaaaaaaaaaaaaaFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n0\r\n\r\n" +} +events { + upstream_send_bytes: "HTTP/1.1 454 \002\002\002\002\002\002\002\002\002\002\002OK\r\ntransfer-encoding: chunked\r\n\r\n200\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_aaaaaaaaaaaaaaaaFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n0\r\n\r\n" +} diff --git a/test/integration/h2_corpus/upstream_metadata_after_end_stream b/test/integration/h2_corpus/upstream_metadata_after_end_stream new file mode 100644 index 000000000000..02080248fb6c --- /dev/null +++ b/test/integration/h2_corpus/upstream_metadata_after_end_stream @@ -0,0 +1,2631 @@ +events { + downstream_send_event { + h2_frames { + settings { + } + } + h2_frames { + } + h2_frames { + request { + stream_index: 1 + host: "host" + path: "/p\237ath/to/long/url" + } + } + h2_frames { + } + h2_frames { + } + } +} +events { + downstream_send_event { + h2_frames { + metadata { + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\334377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii-1620iiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377[377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\300\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\226iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000y\177\177\177\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaa\006nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\342\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii116377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiQQQQQQQQQQQQQQQQQiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\035/nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrhx\331\264rrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Timeout SecondSeconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\3737\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGG56\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "<\000\000\000\000\000\000\00010" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341[341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGG26G\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "10" + value: "" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + flags: END_HEADERS + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356666666666666666666666666666666666666666666666666666666666\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\34141\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220\360\220\220\220" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "15" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377S377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "10" + } + metadata { + key: "Timeout Sec)onds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\367\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiio\216iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "15" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377S377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "10" + } + metadata { + key: "Timeout Sec)onds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\367\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\037\257\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiio\216iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "\001\000" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\273\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035/\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrh\370\331\264rrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + } + } + h2_frames { + metadata { + flags: END_HEADERS + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177{7\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078988\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaa\334\276aaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\'\'\'\'\'\'77\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGG\270GGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii-51559iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\003\'\'\'\'\'\'\'\346\350\'\'\'\'\'\'\'\'\'\'\'77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeput Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\355\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\036\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\273\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035/\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrh\370\331\264rrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341conds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\037T\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiQQQQQQQQQQQQQQQQQiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\035/nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrhx\331\264rrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Timeout SecondSeconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\3737\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGG56\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "<\000\000\000\000\000\000\00010" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\177\025\0278888888888878DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bda195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356666666666666666666666666666666666666666666666666666666666\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\010" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\34141\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii56\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiQQQQQQQQQQQQQQQQQiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\035/nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrhx\331\264rrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341041\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\000-99435\035\035\035\035\035\035\035\035\036\035\035\035\035GGGG\341\341\341\341\341\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "host" + value: "11" + } + metadata { + key: "\177\177\177\r" + value: "" + } + } + } + } + h2_frames { + settings { + } + } + h2_frames { + } + h2_frames { + settings { + } + } + } +} +events { +} +events { + upstream_send_event { + h2_frames { + settings { + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341041\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\003\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Timeout SecondSeconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\3737\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\034\276\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "10" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0068454512319142047377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii1111\37711iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + } + } + h2_frames { + metadata { + flags: END_HEADERS + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177{7\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078988[177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaa\334\276aaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\'\'\'\'\'\'77\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGG\270GGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii-51559iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\003\'\'\'\'\'\'\'\346\350\'\'\'\'\'\'\'\'\'\'\'77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\177\025\0278888888888878DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bda195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiQQQQQQQQQQQQQQQQQiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\035/nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrhx\331\264rrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Timeout SecondSeconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\3737\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\034\276\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "10" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\037wk377\377\377\377\377\377\377\377\377\377\377\377\377\0068454512319142047377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035/\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrh\370\331\264rrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^8DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\243356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGG26G\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "10" + value: "" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + malformed_request { + stream_index: 1 + } + } + h2_frames { + metadata { + flags: END_HEADERS + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiQQQQQQQQQQQQQQQQQiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\035/nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrhx\331\264rrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341041\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\000-99435\035\035\035\035\035\035\035\035\036\035\035\035\035GGGG\341\341\341\341\341\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "host" + value: "11" + } + metadata { + key: "\177\177\177\r" + value: "" + } + } + } + } + h2_frames { + settings { + } + } + h2_frames { + } + h2_frames { + settings { + } + } + } +} +events { +} +events { + upstream_send_event { + h2_frames { + settings { + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341041\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\003\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Timeout SecondSeconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\3737\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\034\276\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "10" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0068454512319142047377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii1111\37711iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + } + } + h2_frames { + metadata { + flags: END_HEADERS + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177{7\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078988[177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaa\334\276aaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\'\'\'\'\'\'77\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGG\270GGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii-51559iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\003\'\'\'\'\'\'\'\346\350\'\'\'\'\'\'\'\'\'\'\'77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "10" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q407888iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\177\025\0278888888888878DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bda195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "10" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035\276\2546\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGHGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\034\256\235.\310S\254\222\324\006t)lN\307b1\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiQQQQQQQQQQQQQQQQQiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078888\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\035/nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrhx\331\264rrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000+\03100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "Timeout Seconds" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Timeout SecondSeconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "10" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\037wk377\377\377\377\377\377\377\377\377\377\377\377\377\0068454512319142047377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\035/\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrh\370\331\264rrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^8DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\243356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGGaaaaaaaaaa(aaa\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177{7\177\177\177\177\177\177E\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177aaaaaaa0110Oq4078988\177\177\177\025\0278888888888888DFMing-BdaaaAaaaaaaaaaaaa(aaaaaaaaaaaaaaaa88DFMing-Bdaaaaaa\363\240\201\256BBBBBaaaaaOqaG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaaaaaaaaa(aaaaaaaaaa0110Oq4078888\177\177\177\025\02788888\330\226g88888DFMing-Bdaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa(aG!GGGGGGGGGGGGGGGGGGGGGGGGGGGGG\307\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGaaa\334\276aaaaa01\030\030\030EFMing-Bdaaaaaaaaaaaaaaaa(aaa|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\177\177\177\177\177\177\177\177\177\177\'\'\'\'\'\'77\177\177\177\177\177\177\177\177GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035000\000\000\000\000\000\000000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\3435\035\035\035ons" + value: "15" + } + metadata { + key: "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDw" + value: "" + } + metadata { + key: "Timeout Seconds" + value: "xost" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\334\334\334\334\334\334\334\334\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMin##g-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiieveniiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing-\0349\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + } + } + } + h2_frames { + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\37556339077\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "p" + value: "" + } + } + } + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341!\341\341\341\341\341\341\341\341\341\341\34188DFMing-Bd\341\341\341\341\341\341\363\240\201\256BBBBB\341\341\341\341\341\317q\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\027888888\226\34788888DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341|!GGGGGGGGGGGGG\025\0278888888888888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "\001\000" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\034\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\341\341\341\341\341\341\3410110\317q4078888\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii8\377\377\377\025\0278888888888888DFMing-Bd\341\341\341\301\341\341\006\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356\356GGGGGGGGGGGGG\025\0278888888788888DFMing-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGG\357\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + h2_frames { + } + h2_frames { + metadata { + stream_index: 1 + metadata { + metadata { + key: "" + value: "\001\000" + } + metadata { + key: "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}}}}0\000\000\000\000\000\000\000GGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377E\377\377\377\377\377\377\377\377\377\377\377\377\377iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\035\035\035\035\035nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\003rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr6nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnGGGGGGGGGGGGG\025\0278888888788888DFMing-\177\177\177\177\177\177\177\177\177\177\177\177\177\177\177GGG\317\231GGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035ons" + value: "15" + } + metadata { + key: "Timeout Seconds" + value: "10" + } + metadata { + key: "connecti\377\025\0278888888888878DFMing-Bd\341\341\341\341\341\341\341\341\341\341\341\341\341\341\341\331(\341\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGG\270GGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii-51559iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377?\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\0351\341\341\341\341\341\341\341\341\341\341\341\341(\341G!GGGGGGGGGGGGGGGGGGG\270GGGGGGGGGG\272GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\34101\030\030\030EFMing-Bd\341195262iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihiiiiiiiiiiiiiiiiiiiiiiiiiiiii-51559iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii77\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGGGGGGG\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035G-3071569\341\341\341\3410110\317\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377GGGGGGGGGGGGGGGGGGGGGG\341\341\341\341\341\341\341\341\341\341(\341\341\341\377\377\377\377\377\377000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + value: "" + } + metadata { + key: "w" + value: "" + } + } + } + } + } +} diff --git a/test/integration/http2_flood_integration_test.cc b/test/integration/http2_flood_integration_test.cc index d43643e122c1..b7d8f95c755b 100644 --- a/test/integration/http2_flood_integration_test.cc +++ b/test/integration/http2_flood_integration_test.cc @@ -1162,4 +1162,82 @@ TEST_P(Http2FloodMitigationTest, UpstreamEmptyHeaders) { test_server_->counter("cluster.cluster_0.http2.inbound_empty_frames_flood")->value()); } +// Verify that the HTTP/2 connection is terminated upon receiving invalid HEADERS frame. +TEST_P(Http2FloodMitigationTest, UpstreamZerolenHeader) { + if (!initializeUpstreamFloodTest()) { + return; + } + + // Send client request which will send an upstream request. + codec_client_ = makeHttpConnection(lookupPort("http")); + auto response = codec_client_->makeHeaderOnlyRequest(default_request_headers_); + waitForNextUpstreamRequest(); + + // Send an upstream reply. + auto* upstream = fake_upstreams_.front().get(); + const auto buf = + Http2Frame::makeMalformedResponseWithZerolenHeader(Http2Frame::makeClientStreamId(0)); + ASSERT_TRUE(upstream->rawWriteConnection(0, std::string(buf.begin(), buf.end()))); + + response->waitForEndStream(); + ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); + + EXPECT_EQ(1, test_server_->counter("cluster.cluster_0.http2.rx_messaging_error")->value()); + EXPECT_EQ( + 1, + test_server_->counter("cluster.cluster_0.upstream_cx_destroy_local_with_active_rq")->value()); + EXPECT_EQ("503", response->headers().getStatusValue()); +} + +// Verify that the HTTP/2 connection is terminated upon receiving invalid HEADERS frame. +TEST_P(Http2FloodMitigationTest, UpstreamZerolenHeaderAllowed) { + useAccessLog("%RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS%"); + config_helper_.addConfigModifier([&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) -> void { + RELEASE_ASSERT(bootstrap.mutable_static_resources()->clusters_size() >= 1, ""); + auto* cluster = bootstrap.mutable_static_resources()->mutable_clusters(0); + cluster->mutable_http2_protocol_options() + ->mutable_override_stream_error_on_invalid_http_message() + ->set_value(1); + }); + if (!initializeUpstreamFloodTest()) { + return; + } + + // Send client request which will send an upstream request. + codec_client_ = makeHttpConnection(lookupPort("http")); + auto response = codec_client_->makeHeaderOnlyRequest(default_request_headers_); + waitForNextUpstreamRequest(); + + // Send an upstream reply. + auto* upstream = fake_upstreams_.front().get(); + const auto buf = + Http2Frame::makeMalformedResponseWithZerolenHeader(Http2Frame::makeClientStreamId(0)); + ASSERT_TRUE(upstream->rawWriteConnection(0, std::string(buf.begin(), buf.end()))); + + // Make sure upstream and downstream got RST_STREAM from the server. + ASSERT_TRUE(upstream_request_->waitForReset()); + response->waitForEndStream(); + EXPECT_EQ("503", response->headers().getStatusValue()); + + // Send another request from downstream on the same connection, and make sure + // a new request reaches upstream on its previous connection. + auto response2 = codec_client_->makeHeaderOnlyRequest(default_request_headers_); + waitForNextUpstreamRequest(); + const auto buf2 = + Http2Frame::makeHeadersFrameWithStatus("200", Http2Frame::makeClientStreamId(1)); + ASSERT_TRUE(upstream->rawWriteConnection(0, std::string(buf2.begin(), buf2.end()))); + + response2->waitForEndStream(); + EXPECT_EQ("200", response2->headers().getStatusValue()); + + EXPECT_EQ(1, test_server_->counter("cluster.cluster_0.http2.rx_messaging_error")->value()); + EXPECT_EQ( + 0, + test_server_->counter("cluster.cluster_0.upstream_cx_destroy_local_with_active_rq")->value()); + // Expect a local reset due to upstream reset before a response. + EXPECT_THAT(waitForAccessLog(access_log_name_), + HasSubstr("upstream_reset_before_response_started")); + EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("LR")); +} + } // namespace Envoy diff --git a/test/integration/http2_integration_test.cc b/test/integration/http2_integration_test.cc index 1ad689a4849e..7c0ca001bfd8 100644 --- a/test/integration/http2_integration_test.cc +++ b/test/integration/http2_integration_test.cc @@ -1565,4 +1565,37 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, Http2FrameIntegrationTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), TestUtility::ipTestParamsToString); +// Tests upstream sending a metadata frame after ending a stream. +TEST_P(Http2MetadataIntegrationTest, UpstreamMetadataAfterEndStream) { + initialize(); + codec_client_ = makeHttpConnection(lookupPort("http")); + + // Sends the first request. + auto encoder_decoder = codec_client_->startRequest(default_request_headers_); + auto response = std::move(encoder_decoder.second); + + // Wait for upstream to receive the request + ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); + ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_)); + ASSERT_TRUE(upstream_request_->waitForHeadersComplete()); + + // Upstream sends headers and ends stream. + const Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; + upstream_request_->encodeHeaders(response_headers, true); + + // Upstream sends metadata. + const Http::MetadataMap response_metadata_map = {{"resp_key1", "resp_value1"}}; + Http::MetadataMapPtr metadata_map_ptr = + std::make_unique(response_metadata_map); + Http::MetadataMapVector metadata_map_vector; + metadata_map_vector.push_back(std::move(metadata_map_ptr)); + upstream_request_->encodeMetadata(metadata_map_vector); + + // Cleanup. + ASSERT_TRUE(fake_upstream_connection_->close()); + response->waitForEndStream(); + ASSERT_TRUE(response->complete()); + EXPECT_EQ("200", response->headers().getStatusValue()); +} + } // namespace Envoy diff --git a/test/integration/http_integration.cc b/test/integration/http_integration.cc index bae6f3ba9acb..198ca37278d1 100644 --- a/test/integration/http_integration.cc +++ b/test/integration/http_integration.cc @@ -829,7 +829,9 @@ void HttpIntegrationTest::testGrpcRetry() { } void HttpIntegrationTest::testEnvoyHandling100Continue(bool additional_continue_from_upstream, - const std::string& via) { + const std::string& via, + bool disconnect_after_100) { + useAccessLog("%RESPONSE_CODE%"); initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); @@ -865,6 +867,15 @@ void HttpIntegrationTest::testEnvoyHandling100Continue(bool additional_continue_ upstream_request_->encode100ContinueHeaders( Http::TestResponseHeaderMapImpl{{":status", "100"}}); } + + if (disconnect_after_100) { + response->waitForContinueHeaders(); + codec_client_->close(); + ASSERT_TRUE(fake_upstream_connection_->close()); + EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("100")); + return; + } + upstream_request_->encodeHeaders(default_response_headers_, false); upstream_request_->encodeData(12, true); @@ -879,6 +890,7 @@ void HttpIntegrationTest::testEnvoyHandling100Continue(bool additional_continue_ } else { EXPECT_EQ(via.c_str(), response->headers().getViaValue()); } + EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("200")); } void HttpIntegrationTest::testEnvoyProxying1xx(bool continue_before_upstream_complete, diff --git a/test/integration/http_integration.h b/test/integration/http_integration.h index ae7652d59107..cf8afa9cfa6d 100644 --- a/test/integration/http_integration.h +++ b/test/integration/http_integration.h @@ -216,7 +216,7 @@ class HttpIntegrationTest : public BaseIntegrationTest { void testGrpcRetry(); void testEnvoyHandling100Continue(bool additional_continue_from_upstream = false, - const std::string& via = ""); + const std::string& via = "", bool disconnect_after_100 = false); void testEnvoyProxying1xx(bool continue_before_upstream_complete = false, bool with_encoder_filter = false, bool with_multiple_1xx_headers = false); diff --git a/test/integration/integration_test.cc b/test/integration/integration_test.cc index f76ad6f889e2..944ccfe81343 100644 --- a/test/integration/integration_test.cc +++ b/test/integration/integration_test.cc @@ -483,6 +483,38 @@ TEST_P(IntegrationTest, TestSmuggling) { } } +TEST_P(IntegrationTest, TestPipelinedResponses) { + initialize(); + auto tcp_client = makeTcpConnection(lookupPort("http")); + + ASSERT_TRUE(tcp_client->write( + "POST /test/long/url HTTP/1.1\r\nHost: host\r\ntransfer-encoding: chunked\r\n\r\n")); + + FakeRawConnectionPtr fake_upstream_connection; + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); + std::string data; + ASSERT_TRUE(fake_upstream_connection->waitForData( + FakeRawConnection::waitForInexactMatch("\r\n\r\n"), &data)); + ASSERT_THAT(data, HasSubstr("POST")); + + ASSERT_TRUE(fake_upstream_connection->write( + "HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\n\r\n0\r\n\r\n" + "HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\n\r\n0\r\n\r\n" + "HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\n\r\n0\r\n\r\n")); + + tcp_client->waitForData("0\r\n\r\n", false); + std::string response = tcp_client->data(); + + EXPECT_THAT(response, HasSubstr("HTTP/1.1 200 OK\r\n")); + EXPECT_THAT(response, HasSubstr("transfer-encoding: chunked\r\n")); + EXPECT_THAT(response, EndsWith("0\r\n\r\n")); + + ASSERT_TRUE(fake_upstream_connection->close()); + ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + tcp_client->close(); + EXPECT_EQ(test_server_->counter("cluster.cluster_0.upstream_cx_protocol_error")->value(), 1); +} + TEST_P(IntegrationTest, TestServerAllowChunkedLength) { config_helper_.addConfigModifier( [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc index 358ec1515cc0..acaf97b0ce64 100644 --- a/test/integration/protocol_integration_test.cc +++ b/test/integration/protocol_integration_test.cc @@ -993,6 +993,14 @@ TEST_P(ProtocolIntegrationTest, HittingEncoderFilterLimit) { test_server_->waitForCounterEq("http.config_test.downstream_rq_5xx", 1); } +// The downstream connection is closed when it is read disabled, and on OSX the +// connection error is not detected under these circumstances. +#if !defined(__APPLE__) +TEST_P(ProtocolIntegrationTest, 100ContinueAndClose) { + testEnvoyHandling100Continue(false, "", true); +} +#endif + TEST_P(ProtocolIntegrationTest, EnvoyHandling100Continue) { testEnvoyHandling100Continue(); } TEST_P(ProtocolIntegrationTest, EnvoyHandlingDuplicate100Continue) { diff --git a/test/integration/proxy_proto_integration_test.cc b/test/integration/proxy_proto_integration_test.cc index 064d884899ec..9cea358aa4d1 100644 --- a/test/integration/proxy_proto_integration_test.cc +++ b/test/integration/proxy_proto_integration_test.cc @@ -2,6 +2,8 @@ #include "envoy/config/bootstrap/v3/bootstrap.pb.h" #include "envoy/config/cluster/v3/cluster.pb.h" +#include "envoy/extensions/access_loggers/file/v3/file.pb.h" +#include "envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.pb.h" #include "common/buffer/buffer_impl.h" @@ -14,6 +16,24 @@ namespace Envoy { +static void +insertProxyProtocolFilterConfigModifier(envoy::config::bootstrap::v3::Bootstrap& bootstrap) { + ::envoy::extensions::filters::listener::proxy_protocol::v3::ProxyProtocol proxy_protocol; + auto rule = proxy_protocol.add_rules(); + rule->set_tlv_type(0x02); + rule->mutable_on_tlv_present()->set_key("PP2TypeAuthority"); + + auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0); + auto* ppv_filter = listener->add_listener_filters(); + ppv_filter->set_name("envoy.listener.proxy_protocol"); + ppv_filter->mutable_typed_config()->PackFrom(proxy_protocol); +} + +ProxyProtoIntegrationTest::ProxyProtoIntegrationTest() + : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, GetParam()) { + config_helper_.addConfigModifier(insertProxyProtocolFilterConfigModifier); +} + INSTANTIATE_TEST_SUITE_P(IpVersions, ProxyProtoIntegrationTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), TestUtility::ipTestParamsToString); @@ -201,4 +221,59 @@ TEST_P(ProxyProtoIntegrationTest, ClusterProvided) { testRouterRequestAndResponseWithBody(1024, 512, false, false, &creator); } +ProxyProtoTcpIntegrationTest::ProxyProtoTcpIntegrationTest() + : BaseIntegrationTest(GetParam(), ConfigHelper::tcpProxyConfig()) { + config_helper_.addConfigModifier(insertProxyProtocolFilterConfigModifier); + config_helper_.renameListener("tcp_proxy"); +} + +INSTANTIATE_TEST_SUITE_P(IpVersions, ProxyProtoTcpIntegrationTest, + testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), + TestUtility::ipTestParamsToString); + +// This tests that the StreamInfo contains the correct addresses. +TEST_P(ProxyProtoTcpIntegrationTest, AccessLog) { + std::string access_log_path = TestEnvironment::temporaryPath( + fmt::format("access_log{}.txt", version_ == Network::Address::IpVersion::v4 ? "v4" : "v6")); + config_helper_.addConfigModifier([&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) -> void { + auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0); + auto* filter_chain = listener->mutable_filter_chains(0); + auto* config_blob = filter_chain->mutable_filters(0)->mutable_typed_config(); + + ASSERT_TRUE( + config_blob + ->Is()); + auto tcp_proxy_config = MessageUtil::anyConvert(*config_blob); + + auto* access_log = tcp_proxy_config.add_access_log(); + access_log->set_name("accesslog"); + envoy::extensions::access_loggers::file::v3::FileAccessLog access_log_config; + access_log_config.set_path(access_log_path); + access_log_config.mutable_log_format()->set_text_format( + "remote=%DOWNSTREAM_REMOTE_ADDRESS% local=%DOWNSTREAM_LOCAL_ADDRESS%"); + access_log->mutable_typed_config()->PackFrom(access_log_config); + config_blob->PackFrom(tcp_proxy_config); + }); + initialize(); + + IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); + ASSERT_TRUE(tcp_client->write("PROXY TCP4 1.2.3.4 254.254.254.254 12345 1234\r\nhello", false)); + + FakeRawConnectionPtr fake_upstream_connection; + ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); + ASSERT_TRUE(fake_upstream_connection->waitForData(5)); + ASSERT_TRUE(fake_upstream_connection->close()); + tcp_client->close(); + ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); + + std::string log_result; + // Access logs only get flushed to disk periodically, so poll until the log is non-empty + do { + log_result = api_->fileSystem().fileReadToEnd(access_log_path); + } while (log_result.empty()); + + EXPECT_EQ(log_result, "remote=1.2.3.4:12345 local=254.254.254.254:1234"); +} + } // namespace Envoy diff --git a/test/integration/proxy_proto_integration_test.h b/test/integration/proxy_proto_integration_test.h index 140d5b63d3f7..3a719ad44aaf 100644 --- a/test/integration/proxy_proto_integration_test.h +++ b/test/integration/proxy_proto_integration_test.h @@ -16,19 +16,13 @@ namespace Envoy { class ProxyProtoIntegrationTest : public testing::TestWithParam, public HttpIntegrationTest { public: - ProxyProtoIntegrationTest() : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, GetParam()) { - config_helper_.addConfigModifier( - [&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) -> void { - ::envoy::extensions::filters::listener::proxy_protocol::v3::ProxyProtocol proxy_protocol; - auto rule = proxy_protocol.add_rules(); - rule->set_tlv_type(0x02); - rule->mutable_on_tlv_present()->set_key("PP2TypeAuthority"); - - auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0); - auto* ppv_filter = listener->add_listener_filters(); - ppv_filter->set_name("envoy.listener.proxy_protocol"); - ppv_filter->mutable_typed_config()->PackFrom(proxy_protocol); - }); - } + ProxyProtoIntegrationTest(); }; + +class ProxyProtoTcpIntegrationTest : public testing::TestWithParam, + public BaseIntegrationTest { +public: + ProxyProtoTcpIntegrationTest(); +}; + } // namespace Envoy diff --git a/test/integration/sds_dynamic_key_rotation_setup.sh b/test/integration/sds_dynamic_key_rotation_setup.sh index 2e5f30d88751..a43e2bd82d2b 100755 --- a/test/integration/sds_dynamic_key_rotation_setup.sh +++ b/test/integration/sds_dynamic_key_rotation_setup.sh @@ -2,7 +2,7 @@ set -e -TEST_CERTS=test/config/integration/certs +TEST_CERTS="${TEST_SRCDIR}"/envoy/test/config/integration/certs ROOT="${TEST_TMPDIR}"/root SERVER_KEYCERT="${ROOT}"/server diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index 861f0a10e340..957f06222521 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -227,6 +227,8 @@ class MockFileEvent : public FileEvent { MOCK_METHOD(void, activate, (uint32_t events)); MOCK_METHOD(void, setEnabled, (uint32_t events)); + MOCK_METHOD(void, registerEventIfEmulatedEdge, (uint32_t event)); + MOCK_METHOD(void, unregisterEventIfEmulatedEdge, (uint32_t event)); }; } // namespace Event diff --git a/test/mocks/server/BUILD b/test/mocks/server/BUILD index 7214ca820371..84fe48578be9 100644 --- a/test/mocks/server/BUILD +++ b/test/mocks/server/BUILD @@ -37,6 +37,14 @@ envoy_cc_mock( ], ) +envoy_cc_mock( + name = "fatal_action_factory_mocks", + hdrs = ["fatal_action_factory.h"], + deps = [ + "//include/envoy/server:fatal_action_interface", + ], +) + envoy_cc_mock( name = "options_mocks", srcs = ["options.cc"], @@ -306,6 +314,7 @@ envoy_cc_mock( "//test/mocks/server:config_tracker_mocks", "//test/mocks/server:drain_manager_mocks", "//test/mocks/server:factory_context_mocks", + "//test/mocks/server:fatal_action_factory_mocks", "//test/mocks/server:filter_chain_factory_context_mocks", "//test/mocks/server:guard_dog_mocks", "//test/mocks/server:health_checker_factory_context_mocks", diff --git a/test/mocks/server/fatal_action_factory.h b/test/mocks/server/fatal_action_factory.h new file mode 100644 index 000000000000..751b3f6e1528 --- /dev/null +++ b/test/mocks/server/fatal_action_factory.h @@ -0,0 +1,20 @@ +#pragma once + +#include "envoy/server/fatal_action_config.h" + +#include "gmock/gmock.h" + +namespace Envoy { +namespace Server { +namespace Configuration { +class MockFatalActionFactory : public FatalActionFactory { +public: + MOCK_METHOD(FatalActionPtr, createFatalActionFromProto, + (const envoy::config::bootstrap::v3::FatalAction& config, Instance* server), + (override)); + MOCK_METHOD(ProtobufTypes::MessagePtr, createEmptyConfigProto, (), (override)); + MOCK_METHOD(std::string, name, (), (const, override)); +}; +} // namespace Configuration +} // namespace Server +} // namespace Envoy diff --git a/test/mocks/server/mocks.h b/test/mocks/server/mocks.h index d041412d01d1..731d4c22778e 100644 --- a/test/mocks/server/mocks.h +++ b/test/mocks/server/mocks.h @@ -8,6 +8,7 @@ #include "config_tracker.h" #include "drain_manager.h" #include "factory_context.h" +#include "fatal_action_factory.h" #include "filter_chain_factory_context.h" #include "guard_dog.h" #include "health_checker_factory_context.h" diff --git a/test/mocks/upstream/cluster_manager_factory.h b/test/mocks/upstream/cluster_manager_factory.h index cdcc952d090b..00e4b6c409be 100644 --- a/test/mocks/upstream/cluster_manager_factory.h +++ b/test/mocks/upstream/cluster_manager_factory.h @@ -23,12 +23,13 @@ class MockClusterManagerFactory : public ClusterManagerFactory { MOCK_METHOD(Http::ConnectionPool::InstancePtr, allocateConnPool, (Event::Dispatcher & dispatcher, HostConstSharedPtr host, ResourcePriority priority, Http::Protocol protocol, const Network::ConnectionSocket::OptionsSharedPtr& options, - const Network::TransportSocketOptionsSharedPtr& transport_socket_options)); + const Network::TransportSocketOptionsSharedPtr& transport_socket_options, + ClusterConnectivityState& state)); MOCK_METHOD(Tcp::ConnectionPool::InstancePtr, allocateTcpConnPool, (Event::Dispatcher & dispatcher, HostConstSharedPtr host, ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, - Network::TransportSocketOptionsSharedPtr)); + Network::TransportSocketOptionsSharedPtr, ClusterConnectivityState& state)); MOCK_METHOD((std::pair), clusterFromProto, (const envoy::config::cluster::v3::Cluster& cluster, ClusterManager& cm, diff --git a/test/per_file_coverage.sh b/test/per_file_coverage.sh index 13526f0eebb2..1b33d066f2e4 100755 --- a/test/per_file_coverage.sh +++ b/test/per_file_coverage.sh @@ -3,7 +3,8 @@ # directory:coverage_percent # for existing directories with low coverage. declare -a KNOWN_LOW_COVERAGE=( -"source/common/network:95.6" +"source/common/event:93.5" # Emulated edge events guards don't report LCOV +"source/common/network:95.1" "source/common/http/http3:50.0" "source/common/tracing:94.9" "source/common/protobuf:94.3" @@ -20,7 +21,7 @@ declare -a KNOWN_LOW_COVERAGE=( "source/common/crypto:0.0" "source/common/common:96.1" "source/common/common/posix:94.1" -"source/common/signal:90.4" +"source/common/signal:83.1" # Death tests don't report LCOV "source/common/watchdog:42.9" # Death tests don't report LCOV "source/exe:93.7" "source/extensions:96.3" @@ -62,14 +63,17 @@ declare -a KNOWN_LOW_COVERAGE=( "source/extensions/tracers:96.0" "source/extensions/tracers/opencensus:91.2" "source/extensions/tracers/xray:94.0" -"source/extensions/transport_sockets:95.3" +"source/extensions/transport_sockets:95.1" "source/extensions/transport_sockets/tap:95.6" "source/extensions/transport_sockets/tls:94.2" "source/extensions/transport_sockets/tls/ocsp:95.3" "source/extensions/transport_sockets/tls/private_key:76.9" +"source/extensions/wasm_runtime:50.0" +"source/extensions/wasm_runtime/wasmtime:0.0" # Not enabled in coverage build +"source/extensions/wasm_runtime/wavm:0.0" # Noe enabled in coverage build "source/extensions/watchdog:69.6" # Death tests within extensions "source/extensions/watchdog/profile_action:84.9" -"source/server:94.6" +"source/server:94.5" "source/server/config_validation:76.6" "source/server/admin:95.2" ) diff --git a/test/proto/bookstore.proto b/test/proto/bookstore.proto index 62e697e219ee..559ec4da0ace 100644 --- a/test/proto/bookstore.proto +++ b/test/proto/bookstore.proto @@ -134,6 +134,11 @@ service Bookstore { get: "/bigbook" }; } + rpc PostWildcard(EchoBodyRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post: "/wildcard/{arg=**}" + }; + } } service ServiceWithResponseBody { diff --git a/test/run_envoy_bazel_coverage.sh b/test/run_envoy_bazel_coverage.sh index 48d8b47a5734..5e99411773c2 100755 --- a/test/run_envoy_bazel_coverage.sh +++ b/test/run_envoy_bazel_coverage.sh @@ -2,6 +2,29 @@ set -e +LLVM_VERSION="10.0.0" +CLANG_VERSION=$(clang --version | grep version | sed -e 's/\ *clang version \(.*\)\ /\1/') +LLVM_COV_VERSION=$(llvm-cov --version | grep version | sed -e 's/\ *LLVM version \(.*\)/\1/') +LLVM_PROFDATA_VERSION=$(llvm-profdata show --version | grep version | sed -e 's/\ *LLVM version \(.*\)/\1/') + +if [ "${CLANG_VERSION}" != "${LLVM_VERSION}" ] +then + echo "clang version ${CLANG_VERSION} does not match expected ${LLVM_VERSION}" + exit 1 +fi + +if [ "${LLVM_COV_VERSION}" != "${LLVM_VERSION}" ] +then + echo "llvm-cov version ${LLVM_COV_VERSION} does not match expected ${LLVM_VERSION}" + exit 1 +fi + +if [ "${LLVM_PROFDATA_VERSION}" != "${LLVM_VERSION}" ] +then + echo "llvm-profdata version ${LLVM_PROFDATA_VERSION} does not match expected ${LLVM_VERSION}" + exit 1 +fi + [[ -z "${SRCDIR}" ]] && SRCDIR="${PWD}" [[ -z "${VALIDATE_COVERAGE}" ]] && VALIDATE_COVERAGE=true [[ -z "${FUZZ_COVERAGE}" ]] && FUZZ_COVERAGE=false diff --git a/test/server/BUILD b/test/server/BUILD index c26a2ebcc87a..82766be214b2 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -371,6 +371,7 @@ envoy_cc_test( "//test/common/stats:stat_test_utility_lib", "//test/integration:integration_lib", "//test/mocks/server:bootstrap_extension_factory_mocks", + "//test/mocks/server:fatal_action_factory_mocks", "//test/mocks/server:hot_restart_mocks", "//test/mocks/server:instance_mocks", "//test/mocks/server:options_mocks", diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 3d21de26252e..de70751f4d02 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -371,6 +371,20 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, UdpAddress) { EXPECT_EQ(1u, manager_->listeners().size()); } +TEST_F(ListenerManagerImplWithRealFiltersTest, AllowOnlyDefaultFilterChain) { + const std::string yaml = R"EOF( +address: + socket_address: + address: 127.0.0.1 + port_value: 1234 +default_filter_chain: + filters: [] + )EOF"; + + manager_->addOrUpdateListener(parseListenerFromV3Yaml(yaml), "", true); + EXPECT_EQ(1, manager_->listeners().size()); +} + TEST_F(ListenerManagerImplWithRealFiltersTest, BadListenerConfig) { const std::string yaml = R"EOF( address: @@ -3566,7 +3580,9 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidPrivateKey) Network::Address::IpVersion::v4); EXPECT_THROW_WITH_MESSAGE(manager_->addOrUpdateListener(parseListenerFromV3Yaml(yaml), "", true), - EnvoyException, "Failed to load private key from "); + EnvoyException, + "Failed to load private key from , " + "Cause: error:0900006e:PEM routines:OPENSSL_internal:NO_START_LINE"); } TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidTrustedCA) { @@ -3591,6 +3607,28 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateInvalidTrustedCA) { EnvoyException, "Failed to load trusted CA certificates from "); } +TEST_F(ListenerManagerImplWithRealFiltersTest, TlsCertificateCertPrivateKeyMismatch) { + const std::string yaml = TestEnvironment::substitute(R"EOF( + address: + socket_address: { address: 127.0.0.1, port_value: 1234 } + filter_chains: + - transport_socket: + name: tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + common_tls_context: + tls_certificates: + - certificate_chain: { filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/san_dns3_chain.pem" } + private_key: { filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/san_dns2_key.pem" } + )EOF", + Network::Address::IpVersion::v4); + + EXPECT_THROW_WITH_REGEX( + manager_->addOrUpdateListener(parseListenerFromV3Yaml(yaml), "", true), EnvoyException, + "Failed to load private key from .*, " + "Cause: error:0b000074:X.509 certificate routines:OPENSSL_internal:KEY_VALUES_MISMATCH"); +} + TEST_F(ListenerManagerImplWithRealFiltersTest, Metadata) { const std::string yaml = TestEnvironment::substitute(R"EOF( address: diff --git a/test/server/server_test.cc b/test/server/server_test.cc index d7abaf788c1d..aa097fc787cf 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -1,8 +1,10 @@ #include +#include "envoy/common/scope_tracker.h" #include "envoy/config/core/v3/base.pb.h" #include "envoy/network/exception.h" #include "envoy/server/bootstrap_extension_config.h" +#include "envoy/server/fatal_action_config.h" #include "common/common/assert.h" #include "common/network/address_impl.h" @@ -19,6 +21,7 @@ #include "test/common/stats/stat_test_utility.h" #include "test/integration/server.h" #include "test/mocks/server/bootstrap_extension_factory.h" +#include "test/mocks/server/fatal_action_factory.h" #include "test/mocks/server/hot_restart.h" #include "test/mocks/server/instance.h" #include "test/mocks/server/options.h" @@ -1212,6 +1215,72 @@ TEST_P(ServerInstanceImplTest, WithUnknownBootstrapExtensions) { "Didn't find a registered implementation for name: 'envoy_test.bootstrap.foo'"); } +// Insufficient support on Windows. +#ifndef WIN32 +class SafeFatalAction : public Configuration::FatalAction { +public: + void run(const ScopeTrackedObject* /*current_object*/) override { + std::cerr << "Called SafeFatalAction" << std::endl; + } + + bool isAsyncSignalSafe() const override { return true; } +}; + +class UnsafeFatalAction : public Configuration::FatalAction { +public: + void run(const ScopeTrackedObject* /*current_object*/) override { + std::cerr << "Called UnsafeFatalAction" << std::endl; + } + + bool isAsyncSignalSafe() const override { return false; } +}; + +TEST_P(ServerInstanceImplTest, WithFatalActions) { + // Inject Safe Factory. + NiceMock mock_safe_factory; + EXPECT_CALL(mock_safe_factory, createEmptyConfigProto()).WillRepeatedly(Invoke([]() { + return std::make_unique(); + })); + EXPECT_CALL(mock_safe_factory, name()).WillRepeatedly(Return("envoy_test.fatal_action.safe")); + + Registry::InjectFactory registered_safe_factory( + mock_safe_factory); + + // Inject Unsafe Factory + NiceMock mock_unsafe_factory; + EXPECT_CALL(mock_unsafe_factory, createEmptyConfigProto()).WillRepeatedly(Invoke([]() { + return std::make_unique(); + })); + EXPECT_CALL(mock_unsafe_factory, name()).WillRepeatedly(Return("envoy_test.fatal_action.unsafe")); + + Registry::InjectFactory registered_unsafe_factory( + mock_unsafe_factory); + + EXPECT_DEATH( + { + EXPECT_CALL(mock_safe_factory, createFatalActionFromProto(_, _)) + .WillOnce( + Invoke([](const envoy::config::bootstrap::v3::FatalAction& /*config*/, + Instance* /*server*/) { return std::make_unique(); })); + EXPECT_CALL(mock_unsafe_factory, createFatalActionFromProto(_, _)) + .WillOnce( + Invoke([](const envoy::config::bootstrap::v3::FatalAction& /*config*/, + Instance* /*server*/) { return std::make_unique(); })); + absl::Notification abort_called; + auto server_thread = + startTestServer("test/server/test_data/server/fatal_actions.yaml", false); + // Trigger SIGABRT, wait for the ABORT + server_->dispatcher().post([&] { + abort(); + abort_called.Notify(); + }); + + abort_called.WaitForNotification(); + }, + ""); +} +#endif + // Static configuration validation. We test with both allow/reject settings various aspects of // configuration from YAML. class StaticValidationTest diff --git a/test/server/test_data/server/fatal_actions.yaml b/test/server/test_data/server/fatal_actions.yaml new file mode 100644 index 000000000000..cbebfaa188eb --- /dev/null +++ b/test/server/test_data/server/fatal_actions.yaml @@ -0,0 +1,9 @@ +fatal_actions: + - config: + name: envoy_test.fatal_action.safe + typed_config: + '@type': type.googleapis.com/google.protobuf.Empty + - config: + name: envoy_test.fatal_action.unsafe + typed_config: + '@type': type.googleapis.com/google.protobuf.Empty diff --git a/test/test_common/simulated_time_system_test.cc b/test/test_common/simulated_time_system_test.cc index 4234142114af..e46284925deb 100644 --- a/test/test_common/simulated_time_system_test.cc +++ b/test/test_common/simulated_time_system_test.cc @@ -202,17 +202,17 @@ TEST_P(SimulatedTimeSystemTest, TimerOrderAndRescheduleTimer) { // is delayed since it is rescheduled with a non-zero delta. advanceMsAndLoop(5); if (activateMode() == ActivateMode::DelayActivateTimers) { -#ifdef WIN32 - // Force it to run again to pick up next iteration callbacks. - // The event loop runs for a single iteration in NonBlock mode on Windows as a hack to work - // around LEVEL trigger fd registrations constantly firing events and preventing the NonBlock - // event loop from ever reaching the no-fd event and no-expired timers termination condition. It - // is not possible to get consistent event loop behavior since the time system does not override - // the base scheduler's run behavior, and libevent does not provide a mode where it runs at most - // N iterations before breaking out of the loop for us to prefer over the single iteration mode - // used on Windows. - advanceMsAndLoop(0); -#endif + if constexpr (Event::PlatformDefaultTriggerType == FileTriggerType::Level) { + // Force it to run again to pick up next iteration callbacks. + // The event loop runs for a single iteration in NonBlock mode on Windows as a hack to work + // around LEVEL trigger fd registrations constantly firing events and preventing the NonBlock + // event loop from ever reaching the no-fd event and no-expired timers termination condition. + // It is not possible to get consistent event loop behavior since the time system does not + // override the base scheduler's run behavior, and libevent does not provide a mode where it + // runs at most N iterations before breaking out of the loop for us to prefer over the single + // iteration mode used on Windows. + advanceMsAndLoop(0); + } EXPECT_EQ("p013p4", output_); } else { EXPECT_EQ("p0134", output_); @@ -252,11 +252,11 @@ TEST_P(SimulatedTimeSystemTest, TimerOrderDisableAndRescheduleTimer) { // re-enabled with a non-zero timeout. advanceMsAndLoop(5); if (activateMode() == ActivateMode::DelayActivateTimers) { -#ifdef WIN32 - // The event loop runs for a single iteration in NonBlock mode on Windows. Force it to run again - // to pick up next iteration callbacks. - advanceMsAndLoop(0); -#endif + if constexpr (Event::PlatformDefaultTriggerType == FileTriggerType::Level) { + // The event loop runs for a single iteration in NonBlock mode on Windows. Force it to run + // again to pick up next iteration callbacks. + advanceMsAndLoop(0); + } EXPECT_THAT(output_, testing::AnyOf("p03p14", "p03p41")); } else { EXPECT_EQ("p0314", output_); diff --git a/test/test_common/threadsafe_singleton_injector.h b/test/test_common/threadsafe_singleton_injector.h index 627efa1390e6..b9a0020dc88a 100644 --- a/test/test_common/threadsafe_singleton_injector.h +++ b/test/test_common/threadsafe_singleton_injector.h @@ -12,6 +12,7 @@ template class TestThreadsafeSingletonInjector { ThreadSafeSingleton::instance_ = instance; } ~TestThreadsafeSingletonInjector() { ThreadSafeSingleton::instance_ = latched_instance_; } + T& latched() { return *latched_instance_; } private: T* latched_instance_; diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index b0c7a7c98d5e..7911b3134fd7 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -237,6 +237,7 @@ Postgre Postgres Prereq QDCOUNT +QPACK QUIC QoS RAII