Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error occurs after updating grpc to 2.7.0 from 2.3.0 (grpc-web) #394

Closed
supermuka opened this issue Nov 5, 2020 · 3 comments
Closed

Error occurs after updating grpc to 2.7.0 from 2.3.0 (grpc-web) #394

supermuka opened this issue Nov 5, 2020 · 3 comments

Comments

@supermuka
Copy link

supermuka commented Nov 5, 2020

After updating grpc package from 2.3.0 to 2.7.0 this error occurs in the console browser:

gRPC Error (code: 14, codeName: UNAVAILABLE, message: Missing trailers, details: null)

version of the grpc-dart packages used: 2.7.0
dart-sdk: 2.10.3

if downgrade grpc to 2.3.0 it works fine!

Repro steps

  1. Update grpc from 2.3.0 to 2.7.0
  2. Update protobuf from 1.0.1 to 1.1.0
  3. Generete again the protos dart files with protoc
  4. Start grpc server
  5. Start web application
  6. When web application access grpc server, the error is thrown.

Expected result: To connect.

Actual result: gRPC Error

Details

- Server Side:

Future<void> main(List<String> args) async {
  final server = Server([
    CommonService(),
    UserService(),
    UserIdentityService(),
    UserAccessService(),
    UserControlService()]);
  await server.serve(port: 9091 /*, security: serverTlsCredentials */);

  print('Server listening on port ${server.port}...');
}

class UserIdentityService extends UserIdentityServiceBase {

  // API
  @override
  Future<UserIdentitiesResponse> getUserIdentities(ServiceCall call,
      UserIdentityGetRequest request) async {
    return UserIdentitiesResponse()/*..webWorkAround = true*/..userIdentities.addAll(await querySelectUserIdentities(request));
  }

 // ...
}

- Proxy Envoy (envoy.yaml):

static_resources:
  listeners:
  - name: listener_http
    address:
      socket_address: { address: 0.0.0.0, port_value: 8440 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route_http
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              cors:
                allow_origin_string_match:
                  - safe_regex:
                      google_re2: {}
                      regex: \*
                allow_methods: GET, PUT, DELETE, POST, OPTIONS
                allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                max_age: "1728000"
                expose_headers: custom-header-1,grpc-status,grpc-message
                #enabled: true
                filter_enabled:
                  default_value:
                    numerator: 100
                    denominator: HUNDRED
              routes:
              - match: { prefix: "/" }
                route:
                  cluster: auge_service
                  max_grpc_timeout: 30s
          http_filters:
            - name: envoy.grpc_web
            - name: envoy.cors
            - name: envoy.router
  - name: listener_https
    address:
      socket_address: { address: 0.0.0.0, port_value: 8443 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route_https
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              cors:
                allow_origin_string_match:
                  - safe_regex:
                      google_re2: {}
                      regex: \*
                allow_methods: GET, PUT, DELETE, POST, OPTIONS
                allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                max_age: "1728000"
                expose_headers: custom-header-1,grpc-status,grpc-message
                #enabled: true
                filter_enabled:
                  default_value:
                    numerator: 100
                    denominator: HUNDRED
              routes:
              - match: { prefix: "/" }
                route:
                  cluster: auge_service
                  max_grpc_timeout: 30s
          http_filters:
          - name: envoy.grpc_web
          - name: envoy.cors
          - name: envoy.router
      tls_context:
        common_tls_context:
          tls_certificates:
            - certificate_chain:
                filename: "/etc/auge_server/certificate/cert.pem"
              private_key:
                filename: "/etc/auge_server/certificate/privkey.pem"
  clusters:
  - name: auge_service
    connect_timeout: 10s
    type: logical_dns
    http2_protocol_options: {}
    upstream_connection_options:
      tcp_keepalive:
        keepalive_time: 300
    lb_policy: round_robin
    hosts: [{ socket_address: { address: auge-server, port_value: 9091 }}]
admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 8081 }

- Client Side (Web)

@Injectable()
class AugeApiService {

  final String _protocol = window.location.protocol;
  final String _urlChannel = window.location.hostname; // 0.0.0.0
  final String _port = window.location.protocol.contains('https') ? '8443' : '8440'; // ':8080'

  GrpcWebClientChannel _channel;

  AugeApiService(this._channel) {
    _channel = GrpcWebClientChannel.xhr(Uri.parse('$_protocol//$_urlChannel:$_port'));
  }

  GrpcWebClientChannel get channel {

    return _channel;
  }
}

@Injectable()
class AuthService  {

  AuthorizationPolicy _generalAuthorizationPolicy;
  UserAccess authUserAccess;

  user_identity_pbgrpc.UserIdentityServiceClient _userIdentityServiceClient;

  AuthService(this._channel)  {

    _userIdentityServiceClient =
        user_identity_pbgrpc.UserIdentityServiceClient(this._channel);  // *** ERROR HERE.  gRPC Error (code: 14, codeName: UNAVAILABLE, message: Missing trailers, details: null) ***
 }
}
@mraleph
Copy link
Member

mraleph commented Nov 5, 2020

Duplicate of #380

@mraleph mraleph marked this as a duplicate of #380 Nov 5, 2020
@mraleph mraleph closed this as completed Nov 5, 2020
@mraleph
Copy link
Member

mraleph commented Nov 5, 2020

We are going to revert offending change and publish a fixed version of the package, but most likely this is not going to happen earlier than next week.

@mraleph
Copy link
Member

mraleph commented Nov 13, 2020

We have published 2.8.0 which fixes the issue and we have switched our testing to use envoy proxy to catch this sort of errors earlier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants