Revert "Support grpc-web" (#159)

This reverts commit d58659507c.

Development of grpc-web will continue on the branch
https://github.com/grpc/grpc-dart/tree/grpc-web until it is ready.
This commit is contained in:
Sigurd Meldgaard 2019-03-18 13:46:50 +01:00 committed by GitHub
parent d58659507c
commit d7ae930e7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 910 additions and 2217 deletions

1
.gitignore vendored
View File

@ -2,7 +2,6 @@
.dart_tool/
.packages
.pub/
.vscode/
build/
# Remove the following pattern if you wish to check in your lock file

View File

@ -1,11 +1,7 @@
language: dart
sudo: false
# necessary to avoid chrome sandboxing issues
sudo: required
addons:
chrome: stable
# Run against both the dev and stable channel.
# Run against both the dev and channel.
dart:
- stable
- dev
@ -13,7 +9,6 @@ dart:
# Define test tasks to run.
dart_task:
- test: --platform vm
- test: --platform chrome
# Only run one instance of the formatter and the analyzer, rather than running
# them against each Dart version.

View File

@ -1,8 +1,3 @@
## 1.1.0
* Add initial support for grpc-web.
See `example/grpc-web` for an example of this working.
## 1.0.1
* Add `service_api.dart` that only contains the minimal imports needed by the code generated by

View File

@ -1,5 +0,0 @@
targets:
$default:
sources:
exclude:
- example/**

View File

@ -1,62 +0,0 @@
# Description
The grpc-web example shows how to use the Dart gRPC library with a gRPC-Web capable server.
This is meant to be used with the echo example provided by the grpc-web repository. The definition of the service is given in echo.proto.
# Prerequistes
You will need a clone of the [grpc-web](https://github.com/grpc/grpc-web) repository to run the example server.
You will also need the dart 'webdev' tool, which you can get by running:
```sh
$ pub global activate webdev
```
# Run the sample code
Follow the instructions for starting the grpc-web example server. The simplest version of this involves running the grpc-web server in a docker container with:
```sh
$ docker-compose up echo-server envoy
```
To compile and run the example, assuming you are in the root of the grpc-web
folder, i.e., .../example/grpc-web/, first get the dependencies by running:
```sh
$ pub get
```
Compile and run the website with:
```sh
$ webdev serve web:9000
```
Note that the alternate port (9000) is necessary because the grpc-web server runs the grpc server on port 8080 by default (the save as webdev).
You can then navigate to http://localhost:9000/ to try out the example.
# Regenerate the stubs
If you have made changes to the message or service definition in
`protos/echo.proto` and need to regenerate the corresponding Dart files,
you will need to have protoc version 3.0.0 or higher and the Dart protoc plugin
version 16.0.0 or higher on your PATH.
To install protoc, see the instructions on
[the Protocol Buffers website](https://developers.google.com/protocol-buffers/).
The easiest way to get the Dart protoc plugin is by running
```sh
$ pub global activate protoc_plugin
```
and follow the directions to add `~/.pub-cache/bin` to your PATH, if you haven't
already done so.
You can now regenerate the Dart files by running
```sh
$ protoc --dart_out=grpc:lib/src/generated -Iprotos protos/echo.proto
```

View File

@ -1,47 +0,0 @@
import 'dart:async';
import 'dart:html';
import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
class EchoApp {
final EchoServiceClient _service;
EchoApp(this._service);
Future<void> echo(String message) async {
_addLeftMessage(message);
final response = await _service.echo(new EchoRequest()..message = message);
_addRightMessage(response.message);
}
void repeatEcho(String message, int count) {
_addLeftMessage(message);
final request = ServerStreamingEchoRequest()
..message = message
..messageCount = count
..messageInterval = 500;
_service.serverStreamingEcho(request).listen((response) {
_addRightMessage(response.message);
}, onDone: () => print('Closed connection to server.'));
}
void _addLeftMessage(String message) {
_addMessage(message, "label-primary pull-left");
}
void _addRightMessage(String message) {
_addMessage(message, "label-default pull-right");
}
void _addMessage(String message, String cssClass) {
final classes = cssClass.split(' ');
querySelector('#first').after(DivElement()
..classes.add('row')
..append(Element.tag('h2')
..append(SpanElement()
..classes.add('label')
..classes.addAll(classes)
..text = message)));
}
}

View File

@ -1,131 +0,0 @@
///
// Generated code. Do not modify.
// source: echo.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
// ignore: UNUSED_SHOWN_NAME
import 'dart:core' show int, bool, double, String, List, Map, override;
import 'package:protobuf/protobuf.dart' as $pb;
class EchoRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EchoRequest', package: const $pb.PackageName('grpc.gateway.testing'))
..aOS(1, 'message')
..hasRequiredFields = false
;
EchoRequest() : super();
EchoRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
EchoRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
EchoRequest clone() => new EchoRequest()..mergeFromMessage(this);
EchoRequest copyWith(void Function(EchoRequest) updates) => super.copyWith((message) => updates(message as EchoRequest));
$pb.BuilderInfo get info_ => _i;
static EchoRequest create() => new EchoRequest();
EchoRequest createEmptyInstance() => create();
static $pb.PbList<EchoRequest> createRepeated() => new $pb.PbList<EchoRequest>();
static EchoRequest getDefault() => _defaultInstance ??= create()..freeze();
static EchoRequest _defaultInstance;
static void $checkItem(EchoRequest v) {
if (v is! EchoRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
}
String get message => $_getS(0, '');
set message(String v) { $_setString(0, v); }
bool hasMessage() => $_has(0);
void clearMessage() => clearField(1);
}
class EchoResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EchoResponse', package: const $pb.PackageName('grpc.gateway.testing'))
..aOS(1, 'message')
..hasRequiredFields = false
;
EchoResponse() : super();
EchoResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
EchoResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
EchoResponse clone() => new EchoResponse()..mergeFromMessage(this);
EchoResponse copyWith(void Function(EchoResponse) updates) => super.copyWith((message) => updates(message as EchoResponse));
$pb.BuilderInfo get info_ => _i;
static EchoResponse create() => new EchoResponse();
EchoResponse createEmptyInstance() => create();
static $pb.PbList<EchoResponse> createRepeated() => new $pb.PbList<EchoResponse>();
static EchoResponse getDefault() => _defaultInstance ??= create()..freeze();
static EchoResponse _defaultInstance;
static void $checkItem(EchoResponse v) {
if (v is! EchoResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
}
String get message => $_getS(0, '');
set message(String v) { $_setString(0, v); }
bool hasMessage() => $_has(0);
void clearMessage() => clearField(1);
}
class ServerStreamingEchoRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServerStreamingEchoRequest', package: const $pb.PackageName('grpc.gateway.testing'))
..aOS(1, 'message')
..a<int>(2, 'messageCount', $pb.PbFieldType.O3)
..a<int>(3, 'messageInterval', $pb.PbFieldType.O3)
..hasRequiredFields = false
;
ServerStreamingEchoRequest() : super();
ServerStreamingEchoRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
ServerStreamingEchoRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
ServerStreamingEchoRequest clone() => new ServerStreamingEchoRequest()..mergeFromMessage(this);
ServerStreamingEchoRequest copyWith(void Function(ServerStreamingEchoRequest) updates) => super.copyWith((message) => updates(message as ServerStreamingEchoRequest));
$pb.BuilderInfo get info_ => _i;
static ServerStreamingEchoRequest create() => new ServerStreamingEchoRequest();
ServerStreamingEchoRequest createEmptyInstance() => create();
static $pb.PbList<ServerStreamingEchoRequest> createRepeated() => new $pb.PbList<ServerStreamingEchoRequest>();
static ServerStreamingEchoRequest getDefault() => _defaultInstance ??= create()..freeze();
static ServerStreamingEchoRequest _defaultInstance;
static void $checkItem(ServerStreamingEchoRequest v) {
if (v is! ServerStreamingEchoRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
}
String get message => $_getS(0, '');
set message(String v) { $_setString(0, v); }
bool hasMessage() => $_has(0);
void clearMessage() => clearField(1);
int get messageCount => $_get(1, 0);
set messageCount(int v) { $_setSignedInt32(1, v); }
bool hasMessageCount() => $_has(1);
void clearMessageCount() => clearField(2);
int get messageInterval => $_get(2, 0);
set messageInterval(int v) { $_setSignedInt32(2, v); }
bool hasMessageInterval() => $_has(2);
void clearMessageInterval() => clearField(3);
}
class ServerStreamingEchoResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServerStreamingEchoResponse', package: const $pb.PackageName('grpc.gateway.testing'))
..aOS(1, 'message')
..hasRequiredFields = false
;
ServerStreamingEchoResponse() : super();
ServerStreamingEchoResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
ServerStreamingEchoResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
ServerStreamingEchoResponse clone() => new ServerStreamingEchoResponse()..mergeFromMessage(this);
ServerStreamingEchoResponse copyWith(void Function(ServerStreamingEchoResponse) updates) => super.copyWith((message) => updates(message as ServerStreamingEchoResponse));
$pb.BuilderInfo get info_ => _i;
static ServerStreamingEchoResponse create() => new ServerStreamingEchoResponse();
ServerStreamingEchoResponse createEmptyInstance() => create();
static $pb.PbList<ServerStreamingEchoResponse> createRepeated() => new $pb.PbList<ServerStreamingEchoResponse>();
static ServerStreamingEchoResponse getDefault() => _defaultInstance ??= create()..freeze();
static ServerStreamingEchoResponse _defaultInstance;
static void $checkItem(ServerStreamingEchoResponse v) {
if (v is! ServerStreamingEchoResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
}
String get message => $_getS(0, '');
set message(String v) { $_setString(0, v); }
bool hasMessage() => $_has(0);
void clearMessage() => clearField(1);
}

View File

@ -1,6 +0,0 @@
///
// Generated code. Do not modify.
// source: echo.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import

View File

@ -1,79 +0,0 @@
///
// Generated code. Do not modify.
// source: echo.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
import 'dart:async' as $async;
import 'package:grpc/service_api.dart' as $grpc;
import 'echo.pb.dart';
export 'echo.pb.dart';
class EchoServiceClient extends $grpc.Client {
static final _$echo = new $grpc.ClientMethod<EchoRequest, EchoResponse>(
'/grpc.gateway.testing.EchoService/Echo',
(EchoRequest value) => value.writeToBuffer(),
(List<int> value) => new EchoResponse.fromBuffer(value));
static final _$serverStreamingEcho = new $grpc.ClientMethod<
ServerStreamingEchoRequest, ServerStreamingEchoResponse>(
'/grpc.gateway.testing.EchoService/ServerStreamingEcho',
(ServerStreamingEchoRequest value) => value.writeToBuffer(),
(List<int> value) => new ServerStreamingEchoResponse.fromBuffer(value));
EchoServiceClient($grpc.ClientChannel channel, {$grpc.CallOptions options})
: super(channel, options: options);
$grpc.ResponseFuture<EchoResponse> echo(EchoRequest request,
{$grpc.CallOptions options}) {
final call = $createCall(_$echo, new $async.Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
}
$grpc.ResponseStream<ServerStreamingEchoResponse> serverStreamingEcho(
ServerStreamingEchoRequest request,
{$grpc.CallOptions options}) {
final call = $createCall(
_$serverStreamingEcho, new $async.Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseStream(call);
}
}
abstract class EchoServiceBase extends $grpc.Service {
String get $name => 'grpc.gateway.testing.EchoService';
EchoServiceBase() {
$addMethod(new $grpc.ServiceMethod<EchoRequest, EchoResponse>(
'Echo',
echo_Pre,
false,
false,
(List<int> value) => new EchoRequest.fromBuffer(value),
(EchoResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<ServerStreamingEchoRequest,
ServerStreamingEchoResponse>(
'ServerStreamingEcho',
serverStreamingEcho_Pre,
false,
true,
(List<int> value) => new ServerStreamingEchoRequest.fromBuffer(value),
(ServerStreamingEchoResponse value) => value.writeToBuffer()));
}
$async.Future<EchoResponse> echo_Pre(
$grpc.ServiceCall call, $async.Future request) async {
return echo(call, await request);
}
$async.Stream<ServerStreamingEchoResponse> serverStreamingEcho_Pre(
$grpc.ServiceCall call, $async.Future request) async* {
yield* serverStreamingEcho(
call, (await request) as ServerStreamingEchoRequest);
}
$async.Future<EchoResponse> echo($grpc.ServiceCall call, EchoRequest request);
$async.Stream<ServerStreamingEchoResponse> serverStreamingEcho(
$grpc.ServiceCall call, ServerStreamingEchoRequest request);
}

View File

@ -1,36 +0,0 @@
///
// Generated code. Do not modify.
// source: echo.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
const EchoRequest$json = const {
'1': 'EchoRequest',
'2': const [
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
],
};
const EchoResponse$json = const {
'1': 'EchoResponse',
'2': const [
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
],
};
const ServerStreamingEchoRequest$json = const {
'1': 'ServerStreamingEchoRequest',
'2': const [
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
const {'1': 'message_count', '3': 2, '4': 1, '5': 5, '10': 'messageCount'},
const {'1': 'message_interval', '3': 3, '4': 1, '5': 5, '10': 'messageInterval'},
],
};
const ServerStreamingEchoResponse$json = const {
'1': 'ServerStreamingEchoResponse',
'2': const [
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
],
};

View File

@ -1,41 +0,0 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package grpc.gateway.testing;
message EchoRequest {
string message = 1;
}
message EchoResponse {
string message = 1;
}
message ServerStreamingEchoRequest {
string message = 1;
int32 message_count = 2;
int32 message_interval = 3;
}
message ServerStreamingEchoResponse {
string message = 1;
}
service EchoService {
rpc Echo(EchoRequest) returns (EchoResponse);
rpc ServerStreamingEcho(ServerStreamingEchoRequest)
returns (stream ServerStreamingEchoResponse);
}

View File

@ -1,15 +0,0 @@
name: grpc_web
description: Dart gRPC-Web sample client
homepage: https://github.com/dart-lang/grpc-dart
environment:
sdk: '>=2.0.0 <3.0.0'
dependencies:
grpc:
path: ../../
protobuf: ^0.13.4
dev_dependencies:
build_runner: ^0.10.0
build_web_compilers: '^0.4.1'

View File

@ -1,42 +0,0 @@
<!--
Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
for details. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Echo Example</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script defer src="main.dart.js"></script>
</head>
<body>
<div class="container">
<div class="row" id="first">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="msg">
<span class="input-group-btn">
<button class="btn btn-primary" type="button" id="send">Send
</button>
</span>
</div>
<p class="help-block">Example: "Hello", "4 Hello"</p>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,48 +0,0 @@
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:html';
import 'package:grpc/grpc_web.dart';
import 'package:grpc_web/app.dart';
import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
void main() {
final channel = new GrpcWebClientChannel.xhr('http://localhost',
port: 8080);
final service = EchoServiceClient(channel);
final app = EchoApp(service);
final button = querySelector('#send') as ButtonElement;
button.onClick.listen((e) async {
final msg = querySelector('#msg') as TextInputElement;
final value = msg.value.trim();
msg.value = '';
if (value.isEmpty) return false;
if (value.indexOf(' ') > 0) {
final countStr = value.substring(0, value.indexOf(' '));
final count = int.tryParse(countStr);
if (count != null) {
app.repeatEcho(value.substring(value.indexOf(' ') + 1), count);
} else {
app.echo(value);
}
} else {
app.echo(value);
}
});
}

View File

@ -20,7 +20,7 @@ class GreeterClient extends Client {
GreeterClient(ClientChannel channel, {CallOptions options})
: super(channel, options: options);
Future<HelloReply> sayHello(HelloRequest request,
ResponseFuture<HelloReply> sayHello(HelloRequest request,
{CallOptions options}) {
final call = $createCall(_$sayHello, new Stream.fromIterable([request]),
options: options);

View File

@ -13,4 +13,3 @@ dependencies:
dev_dependencies:
test: ^1.3.0

View File

@ -114,12 +114,6 @@ class TestService extends TestServiceBase {
final bufferedResponses = await request.map(_responseForRequest).toList();
yield* new Stream.fromIterable(bufferedResponses);
}
@override
Future<Empty> unimplementedCall(ServiceCall call, Empty request) {
// TODO: implement unimplementedCall
return null;
}
}
Future<void> main(List<String> args) async {

View File

@ -19,9 +19,9 @@ import 'dart:typed_data';
import 'package:collection/collection.dart';
import 'package:grpc/grpc.dart';
import 'generated/empty.pb.dart';
import 'generated/messages.pb.dart';
import 'generated/test.pbgrpc.dart';
import 'package:interop/src/generated/empty.pb.dart';
import 'package:interop/src/generated/messages.pb.dart';
import 'package:interop/src/generated/test.pbgrpc.dart';
const _headerEchoKey = 'x-grpc-test-echo-initial';
const _headerEchoData = 'test_initial_metadata_value';
@ -95,7 +95,7 @@ class Tester {
if (_useTestCA) {
trustedRoot = new File('ca.pem').readAsBytesSync();
}
credentials = new Http2ChannelCredentials.secure(
credentials = new ChannelCredentials.secure(
certificates: trustedRoot, authority: serverHostOverride);
} else {
credentials = const ChannelCredentials.insecure();

View File

@ -1,32 +1,36 @@
///
// Generated code. Do not modify.
// source: empty.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
// ignore_for_file: non_constant_identifier_names,library_prefixes
library grpc.testing_empty;
// ignore: UNUSED_SHOWN_NAME
import 'dart:core' show int, bool, double, String, List, Map, override;
import 'dart:core' show int, bool, double, String, List, override;
import 'package:protobuf/protobuf.dart' as $pb;
import 'package:protobuf/protobuf.dart';
class Empty extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Empty', package: const $pb.PackageName('grpc.testing'))
..hasRequiredFields = false
;
class Empty extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('Empty')
..hasRequiredFields = false;
Empty() : super();
Empty.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
Empty.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
Empty.fromBuffer(List<int> i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
Empty.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
Empty clone() => new Empty()..mergeFromMessage(this);
Empty copyWith(void Function(Empty) updates) => super.copyWith((message) => updates(message as Empty));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static Empty create() => new Empty();
Empty createEmptyInstance() => create();
static $pb.PbList<Empty> createRepeated() => new $pb.PbList<Empty>();
static Empty getDefault() => _defaultInstance ??= create()..freeze();
static PbList<Empty> createRepeated() => new PbList<Empty>();
static Empty getDefault() {
if (_defaultInstance == null) _defaultInstance = new _ReadonlyEmpty();
return _defaultInstance;
}
static Empty _defaultInstance;
static void $checkItem(Empty v) {
if (v is! Empty) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! Empty) checkItemFailed(v, 'Empty');
}
}
class _ReadonlyEmpty extends Empty with ReadonlyMessageMixin {}

View File

@ -1,441 +1,655 @@
///
// Generated code. Do not modify.
// source: messages.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
// ignore_for_file: non_constant_identifier_names,library_prefixes
library grpc.testing_messages;
// ignore: UNUSED_SHOWN_NAME
import 'dart:core' show int, bool, double, String, List, Map, override;
import 'dart:core' show int, bool, double, String, List, override;
import 'package:protobuf/protobuf.dart' as $pb;
import 'package:protobuf/protobuf.dart';
import 'messages.pbenum.dart';
export 'messages.pbenum.dart';
class BoolValue extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('BoolValue', package: const $pb.PackageName('grpc.testing'))
class BoolValue extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('BoolValue')
..aOB(1, 'value')
..hasRequiredFields = false
;
..hasRequiredFields = false;
BoolValue() : super();
BoolValue.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
BoolValue.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
BoolValue.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
BoolValue.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
BoolValue clone() => new BoolValue()..mergeFromMessage(this);
BoolValue copyWith(void Function(BoolValue) updates) => super.copyWith((message) => updates(message as BoolValue));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static BoolValue create() => new BoolValue();
BoolValue createEmptyInstance() => create();
static $pb.PbList<BoolValue> createRepeated() => new $pb.PbList<BoolValue>();
static BoolValue getDefault() => _defaultInstance ??= create()..freeze();
static PbList<BoolValue> createRepeated() => new PbList<BoolValue>();
static BoolValue getDefault() {
if (_defaultInstance == null) _defaultInstance = new _ReadonlyBoolValue();
return _defaultInstance;
}
static BoolValue _defaultInstance;
static void $checkItem(BoolValue v) {
if (v is! BoolValue) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! BoolValue) checkItemFailed(v, 'BoolValue');
}
bool get value => $_get(0, false);
set value(bool v) { $_setBool(0, v); }
set value(bool v) {
$_setBool(0, v);
}
bool hasValue() => $_has(0);
void clearValue() => clearField(1);
}
class Payload extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Payload', package: const $pb.PackageName('grpc.testing'))
..e<PayloadType>(1, 'type', $pb.PbFieldType.OE, PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
..a<List<int>>(2, 'body', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
class _ReadonlyBoolValue extends BoolValue with ReadonlyMessageMixin {}
class Payload extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('Payload')
..e<PayloadType>(1, 'type', PbFieldType.OE, PayloadType.COMPRESSABLE,
PayloadType.valueOf, PayloadType.values)
..a<List<int>>(2, 'body', PbFieldType.OY)
..hasRequiredFields = false;
Payload() : super();
Payload.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
Payload.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
Payload.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
Payload.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
Payload clone() => new Payload()..mergeFromMessage(this);
Payload copyWith(void Function(Payload) updates) => super.copyWith((message) => updates(message as Payload));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static Payload create() => new Payload();
Payload createEmptyInstance() => create();
static $pb.PbList<Payload> createRepeated() => new $pb.PbList<Payload>();
static Payload getDefault() => _defaultInstance ??= create()..freeze();
static PbList<Payload> createRepeated() => new PbList<Payload>();
static Payload getDefault() {
if (_defaultInstance == null) _defaultInstance = new _ReadonlyPayload();
return _defaultInstance;
}
static Payload _defaultInstance;
static void $checkItem(Payload v) {
if (v is! Payload) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! Payload) checkItemFailed(v, 'Payload');
}
PayloadType get type => $_getN(0);
set type(PayloadType v) { setField(1, v); }
set type(PayloadType v) {
setField(1, v);
}
bool hasType() => $_has(0);
void clearType() => clearField(1);
List<int> get body => $_getN(1);
set body(List<int> v) { $_setBytes(1, v); }
set body(List<int> v) {
$_setBytes(1, v);
}
bool hasBody() => $_has(1);
void clearBody() => clearField(2);
}
class EchoStatus extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EchoStatus', package: const $pb.PackageName('grpc.testing'))
..a<int>(1, 'code', $pb.PbFieldType.O3)
class _ReadonlyPayload extends Payload with ReadonlyMessageMixin {}
class EchoStatus extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('EchoStatus')
..a<int>(1, 'code', PbFieldType.O3)
..aOS(2, 'message')
..hasRequiredFields = false
;
..hasRequiredFields = false;
EchoStatus() : super();
EchoStatus.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
EchoStatus.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
EchoStatus.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
EchoStatus.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
EchoStatus clone() => new EchoStatus()..mergeFromMessage(this);
EchoStatus copyWith(void Function(EchoStatus) updates) => super.copyWith((message) => updates(message as EchoStatus));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static EchoStatus create() => new EchoStatus();
EchoStatus createEmptyInstance() => create();
static $pb.PbList<EchoStatus> createRepeated() => new $pb.PbList<EchoStatus>();
static EchoStatus getDefault() => _defaultInstance ??= create()..freeze();
static PbList<EchoStatus> createRepeated() => new PbList<EchoStatus>();
static EchoStatus getDefault() {
if (_defaultInstance == null) _defaultInstance = new _ReadonlyEchoStatus();
return _defaultInstance;
}
static EchoStatus _defaultInstance;
static void $checkItem(EchoStatus v) {
if (v is! EchoStatus) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! EchoStatus) checkItemFailed(v, 'EchoStatus');
}
int get code => $_get(0, 0);
set code(int v) { $_setSignedInt32(0, v); }
set code(int v) {
$_setUnsignedInt32(0, v);
}
bool hasCode() => $_has(0);
void clearCode() => clearField(1);
String get message => $_getS(1, '');
set message(String v) { $_setString(1, v); }
set message(String v) {
$_setString(1, v);
}
bool hasMessage() => $_has(1);
void clearMessage() => clearField(2);
}
class SimpleRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SimpleRequest', package: const $pb.PackageName('grpc.testing'))
..e<PayloadType>(1, 'responseType', $pb.PbFieldType.OE, PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
..a<int>(2, 'responseSize', $pb.PbFieldType.O3)
..a<Payload>(3, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
class _ReadonlyEchoStatus extends EchoStatus with ReadonlyMessageMixin {}
class SimpleRequest extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('SimpleRequest')
..e<PayloadType>(1, 'responseType', PbFieldType.OE,
PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
..a<int>(2, 'responseSize', PbFieldType.O3)
..a<Payload>(
3, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
..aOB(4, 'fillUsername')
..aOB(5, 'fillOauthScope')
..a<BoolValue>(6, 'responseCompressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
..a<EchoStatus>(7, 'responseStatus', $pb.PbFieldType.OM, EchoStatus.getDefault, EchoStatus.create)
..a<BoolValue>(8, 'expectCompressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
..hasRequiredFields = false
;
..a<BoolValue>(6, 'responseCompressed', PbFieldType.OM,
BoolValue.getDefault, BoolValue.create)
..a<EchoStatus>(7, 'responseStatus', PbFieldType.OM, EchoStatus.getDefault,
EchoStatus.create)
..a<BoolValue>(8, 'expectCompressed', PbFieldType.OM, BoolValue.getDefault,
BoolValue.create)
..hasRequiredFields = false;
SimpleRequest() : super();
SimpleRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
SimpleRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
SimpleRequest.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
SimpleRequest.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
SimpleRequest clone() => new SimpleRequest()..mergeFromMessage(this);
SimpleRequest copyWith(void Function(SimpleRequest) updates) => super.copyWith((message) => updates(message as SimpleRequest));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static SimpleRequest create() => new SimpleRequest();
SimpleRequest createEmptyInstance() => create();
static $pb.PbList<SimpleRequest> createRepeated() => new $pb.PbList<SimpleRequest>();
static SimpleRequest getDefault() => _defaultInstance ??= create()..freeze();
static PbList<SimpleRequest> createRepeated() => new PbList<SimpleRequest>();
static SimpleRequest getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlySimpleRequest();
return _defaultInstance;
}
static SimpleRequest _defaultInstance;
static void $checkItem(SimpleRequest v) {
if (v is! SimpleRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! SimpleRequest) checkItemFailed(v, 'SimpleRequest');
}
PayloadType get responseType => $_getN(0);
set responseType(PayloadType v) { setField(1, v); }
set responseType(PayloadType v) {
setField(1, v);
}
bool hasResponseType() => $_has(0);
void clearResponseType() => clearField(1);
int get responseSize => $_get(1, 0);
set responseSize(int v) { $_setSignedInt32(1, v); }
set responseSize(int v) {
$_setUnsignedInt32(1, v);
}
bool hasResponseSize() => $_has(1);
void clearResponseSize() => clearField(2);
Payload get payload => $_getN(2);
set payload(Payload v) { setField(3, v); }
set payload(Payload v) {
setField(3, v);
}
bool hasPayload() => $_has(2);
void clearPayload() => clearField(3);
bool get fillUsername => $_get(3, false);
set fillUsername(bool v) { $_setBool(3, v); }
set fillUsername(bool v) {
$_setBool(3, v);
}
bool hasFillUsername() => $_has(3);
void clearFillUsername() => clearField(4);
bool get fillOauthScope => $_get(4, false);
set fillOauthScope(bool v) { $_setBool(4, v); }
set fillOauthScope(bool v) {
$_setBool(4, v);
}
bool hasFillOauthScope() => $_has(4);
void clearFillOauthScope() => clearField(5);
BoolValue get responseCompressed => $_getN(5);
set responseCompressed(BoolValue v) { setField(6, v); }
set responseCompressed(BoolValue v) {
setField(6, v);
}
bool hasResponseCompressed() => $_has(5);
void clearResponseCompressed() => clearField(6);
EchoStatus get responseStatus => $_getN(6);
set responseStatus(EchoStatus v) { setField(7, v); }
set responseStatus(EchoStatus v) {
setField(7, v);
}
bool hasResponseStatus() => $_has(6);
void clearResponseStatus() => clearField(7);
BoolValue get expectCompressed => $_getN(7);
set expectCompressed(BoolValue v) { setField(8, v); }
set expectCompressed(BoolValue v) {
setField(8, v);
}
bool hasExpectCompressed() => $_has(7);
void clearExpectCompressed() => clearField(8);
}
class SimpleResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SimpleResponse', package: const $pb.PackageName('grpc.testing'))
..a<Payload>(1, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
class _ReadonlySimpleRequest extends SimpleRequest with ReadonlyMessageMixin {}
class SimpleResponse extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('SimpleResponse')
..a<Payload>(
1, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
..aOS(2, 'username')
..aOS(3, 'oauthScope')
..hasRequiredFields = false
;
..hasRequiredFields = false;
SimpleResponse() : super();
SimpleResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
SimpleResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
SimpleResponse.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
SimpleResponse.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
SimpleResponse clone() => new SimpleResponse()..mergeFromMessage(this);
SimpleResponse copyWith(void Function(SimpleResponse) updates) => super.copyWith((message) => updates(message as SimpleResponse));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static SimpleResponse create() => new SimpleResponse();
SimpleResponse createEmptyInstance() => create();
static $pb.PbList<SimpleResponse> createRepeated() => new $pb.PbList<SimpleResponse>();
static SimpleResponse getDefault() => _defaultInstance ??= create()..freeze();
static PbList<SimpleResponse> createRepeated() =>
new PbList<SimpleResponse>();
static SimpleResponse getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlySimpleResponse();
return _defaultInstance;
}
static SimpleResponse _defaultInstance;
static void $checkItem(SimpleResponse v) {
if (v is! SimpleResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! SimpleResponse) checkItemFailed(v, 'SimpleResponse');
}
Payload get payload => $_getN(0);
set payload(Payload v) { setField(1, v); }
set payload(Payload v) {
setField(1, v);
}
bool hasPayload() => $_has(0);
void clearPayload() => clearField(1);
String get username => $_getS(1, '');
set username(String v) { $_setString(1, v); }
set username(String v) {
$_setString(1, v);
}
bool hasUsername() => $_has(1);
void clearUsername() => clearField(2);
String get oauthScope => $_getS(2, '');
set oauthScope(String v) { $_setString(2, v); }
set oauthScope(String v) {
$_setString(2, v);
}
bool hasOauthScope() => $_has(2);
void clearOauthScope() => clearField(3);
}
class StreamingInputCallRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingInputCallRequest', package: const $pb.PackageName('grpc.testing'))
..a<Payload>(1, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
..a<BoolValue>(2, 'expectCompressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
..hasRequiredFields = false
;
class _ReadonlySimpleResponse extends SimpleResponse with ReadonlyMessageMixin {
}
class StreamingInputCallRequest extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('StreamingInputCallRequest')
..a<Payload>(
1, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
..a<BoolValue>(2, 'expectCompressed', PbFieldType.OM, BoolValue.getDefault,
BoolValue.create)
..hasRequiredFields = false;
StreamingInputCallRequest() : super();
StreamingInputCallRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
StreamingInputCallRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
StreamingInputCallRequest clone() => new StreamingInputCallRequest()..mergeFromMessage(this);
StreamingInputCallRequest copyWith(void Function(StreamingInputCallRequest) updates) => super.copyWith((message) => updates(message as StreamingInputCallRequest));
$pb.BuilderInfo get info_ => _i;
StreamingInputCallRequest.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
StreamingInputCallRequest.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
StreamingInputCallRequest clone() =>
new StreamingInputCallRequest()..mergeFromMessage(this);
BuilderInfo get info_ => _i;
static StreamingInputCallRequest create() => new StreamingInputCallRequest();
StreamingInputCallRequest createEmptyInstance() => create();
static $pb.PbList<StreamingInputCallRequest> createRepeated() => new $pb.PbList<StreamingInputCallRequest>();
static StreamingInputCallRequest getDefault() => _defaultInstance ??= create()..freeze();
static PbList<StreamingInputCallRequest> createRepeated() =>
new PbList<StreamingInputCallRequest>();
static StreamingInputCallRequest getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyStreamingInputCallRequest();
return _defaultInstance;
}
static StreamingInputCallRequest _defaultInstance;
static void $checkItem(StreamingInputCallRequest v) {
if (v is! StreamingInputCallRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! StreamingInputCallRequest)
checkItemFailed(v, 'StreamingInputCallRequest');
}
Payload get payload => $_getN(0);
set payload(Payload v) { setField(1, v); }
set payload(Payload v) {
setField(1, v);
}
bool hasPayload() => $_has(0);
void clearPayload() => clearField(1);
BoolValue get expectCompressed => $_getN(1);
set expectCompressed(BoolValue v) { setField(2, v); }
set expectCompressed(BoolValue v) {
setField(2, v);
}
bool hasExpectCompressed() => $_has(1);
void clearExpectCompressed() => clearField(2);
}
class StreamingInputCallResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingInputCallResponse', package: const $pb.PackageName('grpc.testing'))
..a<int>(1, 'aggregatedPayloadSize', $pb.PbFieldType.O3)
..hasRequiredFields = false
;
class _ReadonlyStreamingInputCallRequest extends StreamingInputCallRequest
with ReadonlyMessageMixin {}
class StreamingInputCallResponse extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('StreamingInputCallResponse')
..a<int>(1, 'aggregatedPayloadSize', PbFieldType.O3)
..hasRequiredFields = false;
StreamingInputCallResponse() : super();
StreamingInputCallResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
StreamingInputCallResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
StreamingInputCallResponse clone() => new StreamingInputCallResponse()..mergeFromMessage(this);
StreamingInputCallResponse copyWith(void Function(StreamingInputCallResponse) updates) => super.copyWith((message) => updates(message as StreamingInputCallResponse));
$pb.BuilderInfo get info_ => _i;
static StreamingInputCallResponse create() => new StreamingInputCallResponse();
StreamingInputCallResponse createEmptyInstance() => create();
static $pb.PbList<StreamingInputCallResponse> createRepeated() => new $pb.PbList<StreamingInputCallResponse>();
static StreamingInputCallResponse getDefault() => _defaultInstance ??= create()..freeze();
StreamingInputCallResponse.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
StreamingInputCallResponse.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
StreamingInputCallResponse clone() =>
new StreamingInputCallResponse()..mergeFromMessage(this);
BuilderInfo get info_ => _i;
static StreamingInputCallResponse create() =>
new StreamingInputCallResponse();
static PbList<StreamingInputCallResponse> createRepeated() =>
new PbList<StreamingInputCallResponse>();
static StreamingInputCallResponse getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyStreamingInputCallResponse();
return _defaultInstance;
}
static StreamingInputCallResponse _defaultInstance;
static void $checkItem(StreamingInputCallResponse v) {
if (v is! StreamingInputCallResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! StreamingInputCallResponse)
checkItemFailed(v, 'StreamingInputCallResponse');
}
int get aggregatedPayloadSize => $_get(0, 0);
set aggregatedPayloadSize(int v) { $_setSignedInt32(0, v); }
set aggregatedPayloadSize(int v) {
$_setUnsignedInt32(0, v);
}
bool hasAggregatedPayloadSize() => $_has(0);
void clearAggregatedPayloadSize() => clearField(1);
}
class ResponseParameters extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ResponseParameters', package: const $pb.PackageName('grpc.testing'))
..a<int>(1, 'size', $pb.PbFieldType.O3)
..a<int>(2, 'intervalUs', $pb.PbFieldType.O3)
..a<BoolValue>(3, 'compressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
..hasRequiredFields = false
;
class _ReadonlyStreamingInputCallResponse extends StreamingInputCallResponse
with ReadonlyMessageMixin {}
class ResponseParameters extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('ResponseParameters')
..a<int>(1, 'size', PbFieldType.O3)
..a<int>(2, 'intervalUs', PbFieldType.O3)
..a<BoolValue>(
3, 'compressed', PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
..hasRequiredFields = false;
ResponseParameters() : super();
ResponseParameters.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
ResponseParameters.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
ResponseParameters clone() => new ResponseParameters()..mergeFromMessage(this);
ResponseParameters copyWith(void Function(ResponseParameters) updates) => super.copyWith((message) => updates(message as ResponseParameters));
$pb.BuilderInfo get info_ => _i;
ResponseParameters.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
ResponseParameters.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
ResponseParameters clone() =>
new ResponseParameters()..mergeFromMessage(this);
BuilderInfo get info_ => _i;
static ResponseParameters create() => new ResponseParameters();
ResponseParameters createEmptyInstance() => create();
static $pb.PbList<ResponseParameters> createRepeated() => new $pb.PbList<ResponseParameters>();
static ResponseParameters getDefault() => _defaultInstance ??= create()..freeze();
static PbList<ResponseParameters> createRepeated() =>
new PbList<ResponseParameters>();
static ResponseParameters getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyResponseParameters();
return _defaultInstance;
}
static ResponseParameters _defaultInstance;
static void $checkItem(ResponseParameters v) {
if (v is! ResponseParameters) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! ResponseParameters) checkItemFailed(v, 'ResponseParameters');
}
int get size => $_get(0, 0);
set size(int v) { $_setSignedInt32(0, v); }
set size(int v) {
$_setUnsignedInt32(0, v);
}
bool hasSize() => $_has(0);
void clearSize() => clearField(1);
int get intervalUs => $_get(1, 0);
set intervalUs(int v) { $_setSignedInt32(1, v); }
set intervalUs(int v) {
$_setUnsignedInt32(1, v);
}
bool hasIntervalUs() => $_has(1);
void clearIntervalUs() => clearField(2);
BoolValue get compressed => $_getN(2);
set compressed(BoolValue v) { setField(3, v); }
set compressed(BoolValue v) {
setField(3, v);
}
bool hasCompressed() => $_has(2);
void clearCompressed() => clearField(3);
}
class StreamingOutputCallRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingOutputCallRequest', package: const $pb.PackageName('grpc.testing'))
..e<PayloadType>(1, 'responseType', $pb.PbFieldType.OE, PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
..pp<ResponseParameters>(2, 'responseParameters', $pb.PbFieldType.PM, ResponseParameters.$checkItem, ResponseParameters.create)
..a<Payload>(3, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
..a<EchoStatus>(7, 'responseStatus', $pb.PbFieldType.OM, EchoStatus.getDefault, EchoStatus.create)
..hasRequiredFields = false
;
class _ReadonlyResponseParameters extends ResponseParameters
with ReadonlyMessageMixin {}
class StreamingOutputCallRequest extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('StreamingOutputCallRequest')
..e<PayloadType>(1, 'responseType', PbFieldType.OE,
PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
..pp<ResponseParameters>(2, 'responseParameters', PbFieldType.PM,
ResponseParameters.$checkItem, ResponseParameters.create)
..a<Payload>(
3, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
..a<EchoStatus>(7, 'responseStatus', PbFieldType.OM, EchoStatus.getDefault,
EchoStatus.create)
..hasRequiredFields = false;
StreamingOutputCallRequest() : super();
StreamingOutputCallRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
StreamingOutputCallRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
StreamingOutputCallRequest clone() => new StreamingOutputCallRequest()..mergeFromMessage(this);
StreamingOutputCallRequest copyWith(void Function(StreamingOutputCallRequest) updates) => super.copyWith((message) => updates(message as StreamingOutputCallRequest));
$pb.BuilderInfo get info_ => _i;
static StreamingOutputCallRequest create() => new StreamingOutputCallRequest();
StreamingOutputCallRequest createEmptyInstance() => create();
static $pb.PbList<StreamingOutputCallRequest> createRepeated() => new $pb.PbList<StreamingOutputCallRequest>();
static StreamingOutputCallRequest getDefault() => _defaultInstance ??= create()..freeze();
StreamingOutputCallRequest.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
StreamingOutputCallRequest.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
StreamingOutputCallRequest clone() =>
new StreamingOutputCallRequest()..mergeFromMessage(this);
BuilderInfo get info_ => _i;
static StreamingOutputCallRequest create() =>
new StreamingOutputCallRequest();
static PbList<StreamingOutputCallRequest> createRepeated() =>
new PbList<StreamingOutputCallRequest>();
static StreamingOutputCallRequest getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyStreamingOutputCallRequest();
return _defaultInstance;
}
static StreamingOutputCallRequest _defaultInstance;
static void $checkItem(StreamingOutputCallRequest v) {
if (v is! StreamingOutputCallRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! StreamingOutputCallRequest)
checkItemFailed(v, 'StreamingOutputCallRequest');
}
PayloadType get responseType => $_getN(0);
set responseType(PayloadType v) { setField(1, v); }
set responseType(PayloadType v) {
setField(1, v);
}
bool hasResponseType() => $_has(0);
void clearResponseType() => clearField(1);
List<ResponseParameters> get responseParameters => $_getList(1);
Payload get payload => $_getN(2);
set payload(Payload v) { setField(3, v); }
set payload(Payload v) {
setField(3, v);
}
bool hasPayload() => $_has(2);
void clearPayload() => clearField(3);
EchoStatus get responseStatus => $_getN(3);
set responseStatus(EchoStatus v) { setField(7, v); }
set responseStatus(EchoStatus v) {
setField(7, v);
}
bool hasResponseStatus() => $_has(3);
void clearResponseStatus() => clearField(7);
}
class StreamingOutputCallResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingOutputCallResponse', package: const $pb.PackageName('grpc.testing'))
..a<Payload>(1, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
..hasRequiredFields = false
;
class _ReadonlyStreamingOutputCallRequest extends StreamingOutputCallRequest
with ReadonlyMessageMixin {}
class StreamingOutputCallResponse extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('StreamingOutputCallResponse')
..a<Payload>(
1, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
..hasRequiredFields = false;
StreamingOutputCallResponse() : super();
StreamingOutputCallResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
StreamingOutputCallResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
StreamingOutputCallResponse clone() => new StreamingOutputCallResponse()..mergeFromMessage(this);
StreamingOutputCallResponse copyWith(void Function(StreamingOutputCallResponse) updates) => super.copyWith((message) => updates(message as StreamingOutputCallResponse));
$pb.BuilderInfo get info_ => _i;
static StreamingOutputCallResponse create() => new StreamingOutputCallResponse();
StreamingOutputCallResponse createEmptyInstance() => create();
static $pb.PbList<StreamingOutputCallResponse> createRepeated() => new $pb.PbList<StreamingOutputCallResponse>();
static StreamingOutputCallResponse getDefault() => _defaultInstance ??= create()..freeze();
StreamingOutputCallResponse.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
StreamingOutputCallResponse.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
StreamingOutputCallResponse clone() =>
new StreamingOutputCallResponse()..mergeFromMessage(this);
BuilderInfo get info_ => _i;
static StreamingOutputCallResponse create() =>
new StreamingOutputCallResponse();
static PbList<StreamingOutputCallResponse> createRepeated() =>
new PbList<StreamingOutputCallResponse>();
static StreamingOutputCallResponse getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyStreamingOutputCallResponse();
return _defaultInstance;
}
static StreamingOutputCallResponse _defaultInstance;
static void $checkItem(StreamingOutputCallResponse v) {
if (v is! StreamingOutputCallResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! StreamingOutputCallResponse)
checkItemFailed(v, 'StreamingOutputCallResponse');
}
Payload get payload => $_getN(0);
set payload(Payload v) { setField(1, v); }
set payload(Payload v) {
setField(1, v);
}
bool hasPayload() => $_has(0);
void clearPayload() => clearField(1);
}
class ReconnectParams extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ReconnectParams', package: const $pb.PackageName('grpc.testing'))
..a<int>(1, 'maxReconnectBackoffMs', $pb.PbFieldType.O3)
..hasRequiredFields = false
;
class _ReadonlyStreamingOutputCallResponse extends StreamingOutputCallResponse
with ReadonlyMessageMixin {}
class ReconnectParams extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('ReconnectParams')
..a<int>(1, 'maxReconnectBackoffMs', PbFieldType.O3)
..hasRequiredFields = false;
ReconnectParams() : super();
ReconnectParams.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
ReconnectParams.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
ReconnectParams.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
ReconnectParams.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
ReconnectParams clone() => new ReconnectParams()..mergeFromMessage(this);
ReconnectParams copyWith(void Function(ReconnectParams) updates) => super.copyWith((message) => updates(message as ReconnectParams));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static ReconnectParams create() => new ReconnectParams();
ReconnectParams createEmptyInstance() => create();
static $pb.PbList<ReconnectParams> createRepeated() => new $pb.PbList<ReconnectParams>();
static ReconnectParams getDefault() => _defaultInstance ??= create()..freeze();
static PbList<ReconnectParams> createRepeated() =>
new PbList<ReconnectParams>();
static ReconnectParams getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyReconnectParams();
return _defaultInstance;
}
static ReconnectParams _defaultInstance;
static void $checkItem(ReconnectParams v) {
if (v is! ReconnectParams) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! ReconnectParams) checkItemFailed(v, 'ReconnectParams');
}
int get maxReconnectBackoffMs => $_get(0, 0);
set maxReconnectBackoffMs(int v) { $_setSignedInt32(0, v); }
set maxReconnectBackoffMs(int v) {
$_setUnsignedInt32(0, v);
}
bool hasMaxReconnectBackoffMs() => $_has(0);
void clearMaxReconnectBackoffMs() => clearField(1);
}
class ReconnectInfo extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ReconnectInfo', package: const $pb.PackageName('grpc.testing'))
class _ReadonlyReconnectParams extends ReconnectParams
with ReadonlyMessageMixin {}
class ReconnectInfo extends GeneratedMessage {
static final BuilderInfo _i = new BuilderInfo('ReconnectInfo')
..aOB(1, 'passed')
..p<int>(2, 'backoffMs', $pb.PbFieldType.P3)
..hasRequiredFields = false
;
..p<int>(2, 'backoffMs', PbFieldType.P3)
..hasRequiredFields = false;
ReconnectInfo() : super();
ReconnectInfo.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
ReconnectInfo.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
ReconnectInfo.fromBuffer(List<int> i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromBuffer(i, r);
ReconnectInfo.fromJson(String i,
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
: super.fromJson(i, r);
ReconnectInfo clone() => new ReconnectInfo()..mergeFromMessage(this);
ReconnectInfo copyWith(void Function(ReconnectInfo) updates) => super.copyWith((message) => updates(message as ReconnectInfo));
$pb.BuilderInfo get info_ => _i;
BuilderInfo get info_ => _i;
static ReconnectInfo create() => new ReconnectInfo();
ReconnectInfo createEmptyInstance() => create();
static $pb.PbList<ReconnectInfo> createRepeated() => new $pb.PbList<ReconnectInfo>();
static ReconnectInfo getDefault() => _defaultInstance ??= create()..freeze();
static PbList<ReconnectInfo> createRepeated() => new PbList<ReconnectInfo>();
static ReconnectInfo getDefault() {
if (_defaultInstance == null)
_defaultInstance = new _ReadonlyReconnectInfo();
return _defaultInstance;
}
static ReconnectInfo _defaultInstance;
static void $checkItem(ReconnectInfo v) {
if (v is! ReconnectInfo) $pb.checkItemFailed(v, _i.qualifiedMessageName);
if (v is! ReconnectInfo) checkItemFailed(v, 'ReconnectInfo');
}
bool get passed => $_get(0, false);
set passed(bool v) { $_setBool(0, v); }
set passed(bool v) {
$_setBool(0, v);
}
bool hasPassed() => $_has(0);
void clearPassed() => clearField(1);
List<int> get backoffMs => $_getList(1);
}
class _ReadonlyReconnectInfo extends ReconnectInfo with ReadonlyMessageMixin {}

View File

@ -1,26 +1,26 @@
///
// Generated code. Do not modify.
// source: messages.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
// ignore_for_file: non_constant_identifier_names,library_prefixes
library grpc.testing_messages_pbenum;
// ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME
import 'dart:core' show int, dynamic, String, List, Map;
import 'package:protobuf/protobuf.dart' as $pb;
import 'package:protobuf/protobuf.dart';
class PayloadType extends $pb.ProtobufEnum {
static const PayloadType COMPRESSABLE = const PayloadType._(0, 'COMPRESSABLE');
class PayloadType extends ProtobufEnum {
static const PayloadType COMPRESSABLE =
const PayloadType._(0, 'COMPRESSABLE');
static const List<PayloadType> values = const <PayloadType> [
static const List<PayloadType> values = const <PayloadType>[
COMPRESSABLE,
];
static final Map<int, PayloadType> _byValue = $pb.ProtobufEnum.initByValue(values);
static PayloadType valueOf(int value) => _byValue[value];
static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
static PayloadType valueOf(int value) => _byValue[value] as PayloadType;
static void $checkItem(PayloadType v) {
if (v is! PayloadType) $pb.checkItemFailed(v, 'PayloadType');
if (v is! PayloadType) checkItemFailed(v, 'PayloadType');
}
const PayloadType._(int v, String n) : super(v, n);
}

View File

@ -1,9 +1,8 @@
///
// Generated code. Do not modify.
// source: test.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
// ignore_for_file: non_constant_identifier_names,library_prefixes
library grpc.testing_test;
// ignore: UNUSED_SHOWN_NAME
import 'dart:core' show int, bool, double, String, List, Map, override;
import 'dart:core' show int, bool, double, String, List, override;

View File

@ -1,343 +1,307 @@
///
// Generated code. Do not modify.
// source: test.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
// ignore_for_file: non_constant_identifier_names,library_prefixes
library grpc.testing_test_pbgrpc;
import 'dart:async' as $async;
import 'dart:async';
import 'package:grpc/service_api.dart' as $grpc;
import 'empty.pb.dart' as $0;
import 'messages.pb.dart' as $1;
import 'package:grpc/grpc.dart';
import 'empty.pb.dart';
import 'messages.pb.dart';
export 'test.pb.dart';
class TestServiceClient extends $grpc.Client {
static final _$emptyCall = new $grpc.ClientMethod<$0.Empty, $0.Empty>(
class TestServiceClient extends Client {
static final _$emptyCall = new ClientMethod<Empty, Empty>(
'/grpc.testing.TestService/EmptyCall',
($0.Empty value) => value.writeToBuffer(),
(List<int> value) => new $0.Empty.fromBuffer(value));
static final _$unaryCall =
new $grpc.ClientMethod<$1.SimpleRequest, $1.SimpleResponse>(
'/grpc.testing.TestService/UnaryCall',
($1.SimpleRequest value) => value.writeToBuffer(),
(List<int> value) => new $1.SimpleResponse.fromBuffer(value));
(Empty value) => value.writeToBuffer(),
(List<int> value) => new Empty.fromBuffer(value));
static final _$unaryCall = new ClientMethod<SimpleRequest, SimpleResponse>(
'/grpc.testing.TestService/UnaryCall',
(SimpleRequest value) => value.writeToBuffer(),
(List<int> value) => new SimpleResponse.fromBuffer(value));
static final _$cacheableUnaryCall =
new $grpc.ClientMethod<$1.SimpleRequest, $1.SimpleResponse>(
new ClientMethod<SimpleRequest, SimpleResponse>(
'/grpc.testing.TestService/CacheableUnaryCall',
($1.SimpleRequest value) => value.writeToBuffer(),
(List<int> value) => new $1.SimpleResponse.fromBuffer(value));
static final _$streamingOutputCall = new $grpc.ClientMethod<
$1.StreamingOutputCallRequest, $1.StreamingOutputCallResponse>(
'/grpc.testing.TestService/StreamingOutputCall',
($1.StreamingOutputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new $1.StreamingOutputCallResponse.fromBuffer(value));
static final _$streamingInputCall = new $grpc.ClientMethod<
$1.StreamingInputCallRequest, $1.StreamingInputCallResponse>(
'/grpc.testing.TestService/StreamingInputCall',
($1.StreamingInputCallRequest value) => value.writeToBuffer(),
(List<int> value) => new $1.StreamingInputCallResponse.fromBuffer(value));
static final _$fullDuplexCall = new $grpc.ClientMethod<
$1.StreamingOutputCallRequest, $1.StreamingOutputCallResponse>(
'/grpc.testing.TestService/FullDuplexCall',
($1.StreamingOutputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new $1.StreamingOutputCallResponse.fromBuffer(value));
static final _$halfDuplexCall = new $grpc.ClientMethod<
$1.StreamingOutputCallRequest, $1.StreamingOutputCallResponse>(
'/grpc.testing.TestService/HalfDuplexCall',
($1.StreamingOutputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new $1.StreamingOutputCallResponse.fromBuffer(value));
static final _$unimplementedCall = new $grpc.ClientMethod<$0.Empty, $0.Empty>(
(SimpleRequest value) => value.writeToBuffer(),
(List<int> value) => new SimpleResponse.fromBuffer(value));
static final _$streamingOutputCall =
new ClientMethod<StreamingOutputCallRequest, StreamingOutputCallResponse>(
'/grpc.testing.TestService/StreamingOutputCall',
(StreamingOutputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new StreamingOutputCallResponse.fromBuffer(value));
static final _$streamingInputCall =
new ClientMethod<StreamingInputCallRequest, StreamingInputCallResponse>(
'/grpc.testing.TestService/StreamingInputCall',
(StreamingInputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new StreamingInputCallResponse.fromBuffer(value));
static final _$fullDuplexCall =
new ClientMethod<StreamingOutputCallRequest, StreamingOutputCallResponse>(
'/grpc.testing.TestService/FullDuplexCall',
(StreamingOutputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new StreamingOutputCallResponse.fromBuffer(value));
static final _$halfDuplexCall =
new ClientMethod<StreamingOutputCallRequest, StreamingOutputCallResponse>(
'/grpc.testing.TestService/HalfDuplexCall',
(StreamingOutputCallRequest value) => value.writeToBuffer(),
(List<int> value) =>
new StreamingOutputCallResponse.fromBuffer(value));
static final _$unimplementedCall = new ClientMethod<Empty, Empty>(
'/grpc.testing.TestService/UnimplementedCall',
($0.Empty value) => value.writeToBuffer(),
(List<int> value) => new $0.Empty.fromBuffer(value));
(Empty value) => value.writeToBuffer(),
(List<int> value) => new Empty.fromBuffer(value));
TestServiceClient($grpc.ClientChannel channel, {$grpc.CallOptions options})
TestServiceClient(ClientChannel channel, {CallOptions options})
: super(channel, options: options);
$grpc.ResponseFuture<$0.Empty> emptyCall($0.Empty request,
{$grpc.CallOptions options}) {
final call = $createCall(
_$emptyCall, new $async.Stream.fromIterable([request]),
ResponseFuture<Empty> emptyCall(Empty request, {CallOptions options}) {
final call = $createCall(_$emptyCall, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
$grpc.ResponseFuture<$1.SimpleResponse> unaryCall($1.SimpleRequest request,
{$grpc.CallOptions options}) {
final call = $createCall(
_$unaryCall, new $async.Stream.fromIterable([request]),
ResponseFuture<SimpleResponse> unaryCall(SimpleRequest request,
{CallOptions options}) {
final call = $createCall(_$unaryCall, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
$grpc.ResponseFuture<$1.SimpleResponse> cacheableUnaryCall(
$1.SimpleRequest request,
{$grpc.CallOptions options}) {
ResponseFuture<SimpleResponse> cacheableUnaryCall(SimpleRequest request,
{CallOptions options}) {
final call = $createCall(
_$cacheableUnaryCall, new $async.Stream.fromIterable([request]),
_$cacheableUnaryCall, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
$grpc.ResponseStream<$1.StreamingOutputCallResponse> streamingOutputCall(
$1.StreamingOutputCallRequest request,
{$grpc.CallOptions options}) {
ResponseStream<StreamingOutputCallResponse> streamingOutputCall(
StreamingOutputCallRequest request,
{CallOptions options}) {
final call = $createCall(
_$streamingOutputCall, new $async.Stream.fromIterable([request]),
_$streamingOutputCall, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseStream(call);
return new ResponseStream(call);
}
$grpc.ResponseFuture<$1.StreamingInputCallResponse> streamingInputCall(
$async.Stream<$1.StreamingInputCallRequest> request,
{$grpc.CallOptions options}) {
ResponseFuture<StreamingInputCallResponse> streamingInputCall(
Stream<StreamingInputCallRequest> request,
{CallOptions options}) {
final call = $createCall(_$streamingInputCall, request, options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
$grpc.ResponseStream<$1.StreamingOutputCallResponse> fullDuplexCall(
$async.Stream<$1.StreamingOutputCallRequest> request,
{$grpc.CallOptions options}) {
ResponseStream<StreamingOutputCallResponse> fullDuplexCall(
Stream<StreamingOutputCallRequest> request,
{CallOptions options}) {
final call = $createCall(_$fullDuplexCall, request, options: options);
return new $grpc.ResponseStream(call);
return new ResponseStream(call);
}
$grpc.ResponseStream<$1.StreamingOutputCallResponse> halfDuplexCall(
$async.Stream<$1.StreamingOutputCallRequest> request,
{$grpc.CallOptions options}) {
ResponseStream<StreamingOutputCallResponse> halfDuplexCall(
Stream<StreamingOutputCallRequest> request,
{CallOptions options}) {
final call = $createCall(_$halfDuplexCall, request, options: options);
return new $grpc.ResponseStream(call);
return new ResponseStream(call);
}
$grpc.ResponseFuture<$0.Empty> unimplementedCall($0.Empty request,
{$grpc.CallOptions options}) {
ResponseFuture<Empty> unimplementedCall(Empty request,
{CallOptions options}) {
final call = $createCall(
_$unimplementedCall, new $async.Stream.fromIterable([request]),
_$unimplementedCall, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
}
abstract class TestServiceBase extends $grpc.Service {
abstract class TestServiceBase extends Service {
String get $name => 'grpc.testing.TestService';
TestServiceBase() {
$addMethod(new $grpc.ServiceMethod<$0.Empty, $0.Empty>(
$addMethod(new ServiceMethod<Empty, Empty>(
'EmptyCall',
emptyCall_Pre,
false,
false,
(List<int> value) => new $0.Empty.fromBuffer(value),
($0.Empty value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$1.SimpleRequest, $1.SimpleResponse>(
(List<int> value) => new Empty.fromBuffer(value),
(Empty value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<SimpleRequest, SimpleResponse>(
'UnaryCall',
unaryCall_Pre,
false,
false,
(List<int> value) => new $1.SimpleRequest.fromBuffer(value),
($1.SimpleResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$1.SimpleRequest, $1.SimpleResponse>(
(List<int> value) => new SimpleRequest.fromBuffer(value),
(SimpleResponse value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<SimpleRequest, SimpleResponse>(
'CacheableUnaryCall',
cacheableUnaryCall_Pre,
false,
false,
(List<int> value) => new $1.SimpleRequest.fromBuffer(value),
($1.SimpleResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$1.StreamingOutputCallRequest,
$1.StreamingOutputCallResponse>(
(List<int> value) => new SimpleRequest.fromBuffer(value),
(SimpleResponse value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<StreamingOutputCallRequest,
StreamingOutputCallResponse>(
'StreamingOutputCall',
streamingOutputCall_Pre,
false,
true,
(List<int> value) =>
new $1.StreamingOutputCallRequest.fromBuffer(value),
($1.StreamingOutputCallResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$1.StreamingInputCallRequest,
$1.StreamingInputCallResponse>(
(List<int> value) => new StreamingOutputCallRequest.fromBuffer(value),
(StreamingOutputCallResponse value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<StreamingInputCallRequest,
StreamingInputCallResponse>(
'StreamingInputCall',
streamingInputCall,
true,
false,
(List<int> value) => new $1.StreamingInputCallRequest.fromBuffer(value),
($1.StreamingInputCallResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$1.StreamingOutputCallRequest,
$1.StreamingOutputCallResponse>(
(List<int> value) => new StreamingInputCallRequest.fromBuffer(value),
(StreamingInputCallResponse value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<StreamingOutputCallRequest,
StreamingOutputCallResponse>(
'FullDuplexCall',
fullDuplexCall,
true,
true,
(List<int> value) =>
new $1.StreamingOutputCallRequest.fromBuffer(value),
($1.StreamingOutputCallResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$1.StreamingOutputCallRequest,
$1.StreamingOutputCallResponse>(
(List<int> value) => new StreamingOutputCallRequest.fromBuffer(value),
(StreamingOutputCallResponse value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<StreamingOutputCallRequest,
StreamingOutputCallResponse>(
'HalfDuplexCall',
halfDuplexCall,
true,
true,
(List<int> value) =>
new $1.StreamingOutputCallRequest.fromBuffer(value),
($1.StreamingOutputCallResponse value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$0.Empty, $0.Empty>(
'UnimplementedCall',
unimplementedCall_Pre,
false,
false,
(List<int> value) => new $0.Empty.fromBuffer(value),
($0.Empty value) => value.writeToBuffer()));
(List<int> value) => new StreamingOutputCallRequest.fromBuffer(value),
(StreamingOutputCallResponse value) => value.writeToBuffer()));
}
$async.Future<$0.Empty> emptyCall_Pre(
$grpc.ServiceCall call, $async.Future request) async {
Future<Empty> emptyCall_Pre(ServiceCall call, Future request) async {
return emptyCall(call, await request);
}
$async.Future<$1.SimpleResponse> unaryCall_Pre(
$grpc.ServiceCall call, $async.Future request) async {
Future<SimpleResponse> unaryCall_Pre(ServiceCall call, Future request) async {
return unaryCall(call, await request);
}
$async.Future<$1.SimpleResponse> cacheableUnaryCall_Pre(
$grpc.ServiceCall call, $async.Future request) async {
Future<SimpleResponse> cacheableUnaryCall_Pre(
ServiceCall call, Future request) async {
return cacheableUnaryCall(call, await request);
}
$async.Stream<$1.StreamingOutputCallResponse> streamingOutputCall_Pre(
$grpc.ServiceCall call, $async.Future request) async* {
Stream<StreamingOutputCallResponse> streamingOutputCall_Pre(
ServiceCall call, Future request) async* {
yield* streamingOutputCall(
call, (await request) as $1.StreamingOutputCallRequest);
call, (await request) as StreamingOutputCallRequest);
}
$async.Future<$0.Empty> unimplementedCall_Pre(
$grpc.ServiceCall call, $async.Future request) async {
return unimplementedCall(call, await request);
}
$async.Future<$0.Empty> emptyCall($grpc.ServiceCall call, $0.Empty request);
$async.Future<$1.SimpleResponse> unaryCall(
$grpc.ServiceCall call, $1.SimpleRequest request);
$async.Future<$1.SimpleResponse> cacheableUnaryCall(
$grpc.ServiceCall call, $1.SimpleRequest request);
$async.Stream<$1.StreamingOutputCallResponse> streamingOutputCall(
$grpc.ServiceCall call, $1.StreamingOutputCallRequest request);
$async.Future<$1.StreamingInputCallResponse> streamingInputCall(
$grpc.ServiceCall call,
$async.Stream<$1.StreamingInputCallRequest> request);
$async.Stream<$1.StreamingOutputCallResponse> fullDuplexCall(
$grpc.ServiceCall call,
$async.Stream<$1.StreamingOutputCallRequest> request);
$async.Stream<$1.StreamingOutputCallResponse> halfDuplexCall(
$grpc.ServiceCall call,
$async.Stream<$1.StreamingOutputCallRequest> request);
$async.Future<$0.Empty> unimplementedCall(
$grpc.ServiceCall call, $0.Empty request);
Future<Empty> emptyCall(ServiceCall call, Empty request);
Future<SimpleResponse> unaryCall(ServiceCall call, SimpleRequest request);
Future<SimpleResponse> cacheableUnaryCall(
ServiceCall call, SimpleRequest request);
Stream<StreamingOutputCallResponse> streamingOutputCall(
ServiceCall call, StreamingOutputCallRequest request);
Future<StreamingInputCallResponse> streamingInputCall(
ServiceCall call, Stream<StreamingInputCallRequest> request);
Stream<StreamingOutputCallResponse> fullDuplexCall(
ServiceCall call, Stream<StreamingOutputCallRequest> request);
Stream<StreamingOutputCallResponse> halfDuplexCall(
ServiceCall call, Stream<StreamingOutputCallRequest> request);
}
class UnimplementedServiceClient extends $grpc.Client {
static final _$unimplementedCall = new $grpc.ClientMethod<$0.Empty, $0.Empty>(
class UnimplementedServiceClient extends Client {
static final _$unimplementedCall = new ClientMethod<Empty, Empty>(
'/grpc.testing.UnimplementedService/UnimplementedCall',
($0.Empty value) => value.writeToBuffer(),
(List<int> value) => new $0.Empty.fromBuffer(value));
(Empty value) => value.writeToBuffer(),
(List<int> value) => new Empty.fromBuffer(value));
UnimplementedServiceClient($grpc.ClientChannel channel,
{$grpc.CallOptions options})
UnimplementedServiceClient(ClientChannel channel, {CallOptions options})
: super(channel, options: options);
$grpc.ResponseFuture<$0.Empty> unimplementedCall($0.Empty request,
{$grpc.CallOptions options}) {
ResponseFuture<Empty> unimplementedCall(Empty request,
{CallOptions options}) {
final call = $createCall(
_$unimplementedCall, new $async.Stream.fromIterable([request]),
_$unimplementedCall, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
}
abstract class UnimplementedServiceBase extends $grpc.Service {
abstract class UnimplementedServiceBase extends Service {
String get $name => 'grpc.testing.UnimplementedService';
UnimplementedServiceBase() {
$addMethod(new $grpc.ServiceMethod<$0.Empty, $0.Empty>(
$addMethod(new ServiceMethod<Empty, Empty>(
'UnimplementedCall',
unimplementedCall_Pre,
false,
false,
(List<int> value) => new $0.Empty.fromBuffer(value),
($0.Empty value) => value.writeToBuffer()));
(List<int> value) => new Empty.fromBuffer(value),
(Empty value) => value.writeToBuffer()));
}
$async.Future<$0.Empty> unimplementedCall_Pre(
$grpc.ServiceCall call, $async.Future request) async {
Future<Empty> unimplementedCall_Pre(ServiceCall call, Future request) async {
return unimplementedCall(call, await request);
}
$async.Future<$0.Empty> unimplementedCall(
$grpc.ServiceCall call, $0.Empty request);
Future<Empty> unimplementedCall(ServiceCall call, Empty request);
}
class ReconnectServiceClient extends $grpc.Client {
static final _$start = new $grpc.ClientMethod<$1.ReconnectParams, $0.Empty>(
class ReconnectServiceClient extends Client {
static final _$start = new ClientMethod<ReconnectParams, Empty>(
'/grpc.testing.ReconnectService/Start',
($1.ReconnectParams value) => value.writeToBuffer(),
(List<int> value) => new $0.Empty.fromBuffer(value));
static final _$stop = new $grpc.ClientMethod<$0.Empty, $1.ReconnectInfo>(
(ReconnectParams value) => value.writeToBuffer(),
(List<int> value) => new Empty.fromBuffer(value));
static final _$stop = new ClientMethod<Empty, ReconnectInfo>(
'/grpc.testing.ReconnectService/Stop',
($0.Empty value) => value.writeToBuffer(),
(List<int> value) => new $1.ReconnectInfo.fromBuffer(value));
(Empty value) => value.writeToBuffer(),
(List<int> value) => new ReconnectInfo.fromBuffer(value));
ReconnectServiceClient($grpc.ClientChannel channel,
{$grpc.CallOptions options})
ReconnectServiceClient(ClientChannel channel, {CallOptions options})
: super(channel, options: options);
$grpc.ResponseFuture<$0.Empty> start($1.ReconnectParams request,
{$grpc.CallOptions options}) {
final call = $createCall(_$start, new $async.Stream.fromIterable([request]),
ResponseFuture<Empty> start(ReconnectParams request, {CallOptions options}) {
final call = $createCall(_$start, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
$grpc.ResponseFuture<$1.ReconnectInfo> stop($0.Empty request,
{$grpc.CallOptions options}) {
final call = $createCall(_$stop, new $async.Stream.fromIterable([request]),
ResponseFuture<ReconnectInfo> stop(Empty request, {CallOptions options}) {
final call = $createCall(_$stop, new Stream.fromIterable([request]),
options: options);
return new $grpc.ResponseFuture(call);
return new ResponseFuture(call);
}
}
abstract class ReconnectServiceBase extends $grpc.Service {
abstract class ReconnectServiceBase extends Service {
String get $name => 'grpc.testing.ReconnectService';
ReconnectServiceBase() {
$addMethod(new $grpc.ServiceMethod<$1.ReconnectParams, $0.Empty>(
$addMethod(new ServiceMethod<ReconnectParams, Empty>(
'Start',
start_Pre,
false,
false,
(List<int> value) => new $1.ReconnectParams.fromBuffer(value),
($0.Empty value) => value.writeToBuffer()));
$addMethod(new $grpc.ServiceMethod<$0.Empty, $1.ReconnectInfo>(
(List<int> value) => new ReconnectParams.fromBuffer(value),
(Empty value) => value.writeToBuffer()));
$addMethod(new ServiceMethod<Empty, ReconnectInfo>(
'Stop',
stop_Pre,
false,
false,
(List<int> value) => new $0.Empty.fromBuffer(value),
($1.ReconnectInfo value) => value.writeToBuffer()));
(List<int> value) => new Empty.fromBuffer(value),
(ReconnectInfo value) => value.writeToBuffer()));
}
$async.Future<$0.Empty> start_Pre(
$grpc.ServiceCall call, $async.Future request) async {
Future<Empty> start_Pre(ServiceCall call, Future request) async {
return start(call, await request);
}
$async.Future<$1.ReconnectInfo> stop_Pre(
$grpc.ServiceCall call, $async.Future request) async {
Future<ReconnectInfo> stop_Pre(ServiceCall call, Future request) async {
return stop(call, await request);
}
$async.Future<$0.Empty> start(
$grpc.ServiceCall call, $1.ReconnectParams request);
$async.Future<$1.ReconnectInfo> stop(
$grpc.ServiceCall call, $0.Empty request);
Future<Empty> start(ServiceCall call, ReconnectParams request);
Future<ReconnectInfo> stop(ServiceCall call, Empty request);
}

View File

@ -16,15 +16,12 @@
export 'src/auth/auth.dart';
export 'src/client/call.dart';
export 'src/client/channel.dart' hide ClientChannel;
export 'src/client/channel.dart';
export 'src/client/client.dart';
export 'src/client/common.dart';
export 'src/client/connection.dart';
export 'src/client/http2_channel.dart' show ClientChannel;
export 'src/client/method.dart';
export 'src/client/options.dart';
export 'src/client/transport/http2_credentials.dart';
export 'src/client/transport/transport.dart';
export 'src/server/call.dart';
export 'src/server/handler.dart';
@ -32,7 +29,6 @@ export 'src/server/interceptor.dart';
export 'src/server/server.dart';
export 'src/server/service.dart';
export 'src/shared/message.dart';
export 'src/shared/security.dart';
export 'src/shared/status.dart';
export 'src/shared/streams.dart';

View File

@ -1,30 +0,0 @@
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
export 'src/auth/auth.dart';
export 'src/client/call.dart';
export 'src/client/channel.dart' hide ClientChannel;
export 'src/client/client.dart';
export 'src/client/common.dart';
export 'src/client/connection.dart';
export 'src/client/method.dart';
export 'src/client/options.dart';
export 'src/client/transport/transport.dart';
export 'src/client/web_channel.dart' show GrpcWebClientChannel;
export 'src/shared/status.dart';
export 'src/shared/streams.dart';
export 'src/shared/timeout.dart';

View File

@ -24,4 +24,5 @@ export 'src/client/common.dart' show ResponseFuture, ResponseStream;
export 'src/client/method.dart' show ClientMethod;
export 'src/client/options.dart' show CallOptions;
export 'src/server/call.dart' show ServiceCall;
export 'src/server/server.dart' show Server;
export 'src/server/service.dart' show Service, ServiceMethod;

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -15,14 +15,15 @@
import 'dart:async';
import 'package:http2/transport.dart';
import '../shared/status.dart';
import '../shared/message.dart';
import '../shared/streams.dart';
import 'common.dart';
import 'connection.dart';
import 'method.dart';
import 'options.dart';
import 'transport/transport.dart';
const _reservedHeaders = const [
'content-type',
@ -44,9 +45,9 @@ class ClientCall<Q, R> implements Response {
Map<String, String> _headerMetadata;
GrpcTransportStream _stream;
TransportStream _stream;
StreamController<R> _responses;
StreamSubscription<List<int>> _requestSubscription;
StreamSubscription<StreamMessage> _requestSubscription;
StreamSubscription<GrpcMessage> _responseSubscription;
bool isCancelled = false;
@ -119,6 +120,8 @@ class ClientCall<Q, R> implements Response {
}
_requestSubscription = _requests
.map(_method.requestSerializer)
.map(GrpcHttpEncoder.frame)
.map<StreamMessage>((bytes) => new DataStreamMessage(bytes))
.handleError(_onRequestError)
.listen(_stream.outgoingMessages.add,
onError: _stream.outgoingMessages.addError,
@ -140,10 +143,13 @@ class ClientCall<Q, R> implements Response {
if (_stream != null &&
_responses.hasListener &&
_responseSubscription == null) {
_responseSubscription = _stream.incomingMessages.listen(_onResponseData,
onError: _onResponseError,
onDone: _onResponseDone,
cancelOnError: true);
_responseSubscription = _stream.incomingMessages
.transform(new GrpcHttpDecoder())
.transform(grpcDecompressor())
.listen(_onResponseData,
onError: _onResponseError,
onDone: _onResponseDone,
cancelOnError: true);
if (_responses.isPaused) {
_responseSubscription.pause();
}

View File

@ -21,28 +21,23 @@ import 'call.dart';
import 'connection.dart';
import 'method.dart';
import 'options.dart';
import 'transport/transport.dart';
typedef ConnectTransport = Future<Transport> Function(
String host, int port, ChannelOptions options);
/// A channel to a virtual RPC endpoint.
///
/// For each RPC, the channel picks a [ClientConnection] to dispatch the call.
/// RPCs on the same channel may be sent to different connections, depending on
/// load balancing settings.
abstract class ClientChannel {
class ClientChannel {
final String host;
final int port;
final ChannelOptions options;
final ConnectTransport connectTransport;
// TODO(jakobr): Multiple connections, load balancing.
ClientConnection _connection;
bool _isShutdown = false;
ClientChannel(this.host, this.connectTransport,
ClientChannel(this.host,
{this.port = 443, this.options = const ChannelOptions()});
/// Shuts down this channel.
@ -69,7 +64,7 @@ abstract class ClientChannel {
/// The connection may be shared between multiple RPCs.
Future<ClientConnection> getConnection() async {
if (_isShutdown) throw new GrpcError.unavailable('Channel shutting down.');
return _connection ??= new ClientConnection(host, port, options, connectTransport);
return _connection ??= new ClientConnection(host, port, options);
}
/// Initiates a new RPC on this connection.

View File

@ -14,16 +14,17 @@
// limitations under the License.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:grpc/src/client/channel.dart';
import 'package:http2/transport.dart';
import 'package:meta/meta.dart';
import '../shared/status.dart';
import '../shared/timeout.dart';
import 'call.dart';
import 'options.dart';
import 'transport/transport.dart';
enum ConnectionState {
/// Actively trying to connect.
connecting,
@ -45,38 +46,98 @@ enum ConnectionState {
///
/// RPCs made on a connection are always sent to the same endpoint.
class ClientConnection {
static final _methodPost = new Header.ascii(':method', 'POST');
static final _schemeHttp = new Header.ascii(':scheme', 'http');
static final _schemeHttps = new Header.ascii(':scheme', 'https');
static final _contentTypeGrpc =
new Header.ascii('content-type', 'application/grpc');
static final _teTrailers = new Header.ascii('te', 'trailers');
static final _grpcAcceptEncoding =
new Header.ascii('grpc-accept-encoding', 'identity');
static final _userAgent = new Header.ascii('user-agent', 'dart-grpc/0.2.0');
final String host;
final int port;
final ChannelOptions options;
final ConnectTransport connectTransport;
ConnectionState _state = ConnectionState.idle;
void Function(ClientConnection connection) onStateChanged;
final _pendingCalls = <ClientCall>[];
Transport _transport;
ClientTransportConnection _transport;
/// Used for idle and reconnect timeout, depending on [_state].
Timer _timer;
Duration _currentReconnectDelay;
ClientConnection(this.host, this.port, this.options, this.connectTransport);
ClientConnection(this.host, this.port, this.options);
ConnectionState get state => _state;
static List<Header> createCallHeaders(bool useTls, String authority,
String path, Duration timeout, Map<String, String> metadata) {
final headers = [
_methodPost,
useTls ? _schemeHttps : _schemeHttp,
new Header(ascii.encode(':path'), utf8.encode(path)),
new Header(ascii.encode(':authority'), utf8.encode(authority)),
];
if (timeout != null) {
headers.add(new Header.ascii('grpc-timeout', toTimeoutString(timeout)));
}
headers.addAll([
_contentTypeGrpc,
_teTrailers,
_grpcAcceptEncoding,
_userAgent,
]);
metadata?.forEach((key, value) {
headers.add(new Header(ascii.encode(key), utf8.encode(value)));
});
return headers;
}
String get authority => options.credentials.authority ?? host;
@visibleForTesting
Future<ClientTransportConnection> connectTransport() async {
final securityContext = options.credentials.securityContext;
var socket = await Socket.connect(host, port);
if (_state == ConnectionState.shutdown) {
socket.destroy();
throw 'Shutting down';
}
if (securityContext != null) {
socket = await SecureSocket.secure(socket,
host: authority,
context: securityContext,
onBadCertificate: _validateBadCertificate);
if (_state == ConnectionState.shutdown) {
socket.destroy();
throw 'Shutting down';
}
}
socket.done.then(_handleSocketClosed);
return new ClientTransportConnection.viaSocket(socket);
}
bool _validateBadCertificate(X509Certificate certificate) {
final validator = options.credentials.onBadCertificate;
if (validator == null) return false;
return validator(certificate, authority);
}
void _connect() {
if (_state != ConnectionState.idle &&
_state != ConnectionState.transientFailure) {
return;
}
_setState(ConnectionState.connecting);
connectTransport(host, port, options).then((transport) {
connectTransport().then((transport) {
_currentReconnectDelay = null;
_transport = transport;
_transport.onActiveStateChanged = _handleActiveStateChanged;
_transport.onSocketClosed = _handleSocketClosed;
_setState(ConnectionState.ready);
_pendingCalls.forEach(_startCall);
_pendingCalls.clear();
@ -99,9 +160,11 @@ class ClientConnection {
}
}
GrpcTransportStream makeRequest(
ClientTransportStream makeRequest(
String path, Duration timeout, Map<String, String> metadata) {
return _transport.makeRequest(path, timeout, metadata);
final headers = createCallHeaders(
options.credentials.isSecure, authority, path, timeout, metadata);
return _transport.makeRequest(headers);
}
void _startCall(ClientCall call) {
@ -198,7 +261,7 @@ class ClientConnection {
_connect();
}
void _handleSocketClosed() {
void _handleSocketClosed(_) {
_cancelTimer();
_transport = null;

View File

@ -1,33 +0,0 @@
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:meta/meta.dart';
import 'channel.dart' as channel;
import 'options.dart';
import 'transport/transport.dart';
import 'transport/http2_transport.dart';
@visibleForTesting
Future<Transport> connectTransport(
String host, int port, ChannelOptions options) async {
return Http2Transport(host, port, options)..connect();
}
class ClientChannel extends channel.ClientChannel {
ClientChannel(String host,
{int port = 443, ChannelOptions options = const ChannelOptions()})
: super(host, connectTransport, port: port, options: options);
}

View File

@ -14,15 +14,18 @@
// limitations under the License.
import 'dart:async';
import 'package:meta/meta.dart';
import 'dart:io';
import 'dart:math';
import '../shared/security.dart';
const defaultIdleTimeout = const Duration(minutes: 5);
typedef Duration BackoffStrategy(Duration lastBackoff);
// Backoff algorithm from https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
const _minConnectTimeout = const Duration(seconds: 20);
const _initialBackoff = const Duration(seconds: 1);
const _maxBackoff = const Duration(seconds: 120);
const _multiplier = 1.6;
@ -36,16 +39,54 @@ Duration defaultBackoffStrategy(Duration lastBackoff) {
return nextBackoff < _maxBackoff ? nextBackoff : _maxBackoff;
}
/// Handler for checking certificates that fail validation. If this handler
/// returns `true`, the bad certificate is allowed, and the TLS handshake can
/// continue. If the handler returns `false`, the TLS handshake fails, and the
/// connection is aborted.
typedef bool BadCertificateHandler(X509Certificate certificate, String host);
/// Bad certificate handler that disables all certificate checks.
/// DO NOT USE IN PRODUCTION!
/// Can be used during development and testing to accept self-signed
/// certificates, etc.
bool allowBadCertificates(X509Certificate certificate, String host) => true;
/// Options controlling TLS security settings on a [ClientChannel].
class ChannelCredentials {
final bool isSecure;
final List<int> _certificateBytes;
final String _certificatePassword;
final String authority;
final BadCertificateHandler onBadCertificate;
@visibleForOverriding
const ChannelCredentials(this.isSecure, this.authority);
const ChannelCredentials._(this.isSecure, this._certificateBytes,
this._certificatePassword, this.authority, this.onBadCertificate);
/// Disable TLS. RPCs are sent in clear text.
const ChannelCredentials.insecure() : this(false, null);
const ChannelCredentials.insecure() : this._(false, null, null, null, null);
/// Enable TLS and optionally specify the [certificates] to trust. If
/// [certificates] is not provided, the default trust store is used.
const ChannelCredentials.secure(
{List<int> certificates,
String password,
String authority,
BadCertificateHandler onBadCertificate})
: this._(true, certificates, password, authority, onBadCertificate);
SecurityContext get securityContext {
if (!isSecure) return null;
if (_certificateBytes != null) {
return createSecurityContext(false)
..setTrustedCertificatesBytes(_certificateBytes,
password: _certificatePassword);
}
final context = new SecurityContext(withTrustedRoots: true);
if (SecurityContext.alpnSupported) {
context.setAlpnProtocols(supportedAlpnProtocols, false);
}
return context;
}
}
/// Options controlling how connections are made on a [ClientChannel].
@ -54,11 +95,14 @@ class ChannelOptions {
final Duration idleTimeout;
final BackoffStrategy backoffStrategy;
const ChannelOptions({
ChannelCredentials credentials,
this.idleTimeout = defaultIdleTimeout,
this.backoffStrategy = defaultBackoffStrategy,
}) : this.credentials = credentials ?? const ChannelCredentials.insecure();
const ChannelOptions(
{ChannelCredentials credentials,
Duration idleTimeout,
BackoffStrategy backoffStrategy =
defaultBackoffStrategy}) // Remove when dart-lang/sdk#31066 is fixed.
: this.credentials = credentials ?? const ChannelCredentials.secure(),
this.idleTimeout = idleTimeout ?? defaultIdleTimeout,
this.backoffStrategy = backoffStrategy ?? defaultBackoffStrategy;
}
/// Provides per-RPC metadata.

View File

@ -1,63 +0,0 @@
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:io';
import '../../shared/security.dart';
import '../options.dart';
/// Handler for checking certificates that fail validation. If this handler
/// returns `true`, the bad certificate is allowed, and the TLS handshake can
/// continue. If the handler returns `false`, the TLS handshake fails, and the
/// connection is aborted.
typedef bool BadCertificateHandler(X509Certificate certificate, String host);
/// Bad certificate handler that disables all certificate checks.
/// DO NOT USE IN PRODUCTION!
/// Can be used during development and testing to accept self-signed
/// certificates, etc.
bool allowBadCertificates(X509Certificate certificate, String host) => true;
class Http2ChannelCredentials extends ChannelCredentials {
final List<int> _certificateBytes;
final String _certificatePassword;
final BadCertificateHandler onBadCertificate;
const Http2ChannelCredentials._(bool isSecure, String authority,
this._certificateBytes, this._certificatePassword, this.onBadCertificate)
: super(isSecure, authority);
/// Enable TLS and optionally specify the [certificates] to trust. If
/// [certificates] is not provided, the default trust store is used.
const Http2ChannelCredentials.secure(
{List<int> certificates,
String password,
String authority,
BadCertificateHandler onBadCertificate})
: this._(true, authority, certificates, password, onBadCertificate);
SecurityContext get securityContext {
if (!isSecure) return null;
if (_certificateBytes != null) {
return createSecurityContext(false)
..setTrustedCertificatesBytes(_certificateBytes,
password: _certificatePassword);
}
final context = new SecurityContext(withTrustedRoots: true);
context.setAlpnProtocols(supportedAlpnProtocols, false);
return context;
}
}

View File

@ -1,169 +0,0 @@
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http2/transport.dart';
import 'package:meta/meta.dart';
import '../../shared/message.dart';
import '../../shared/streams.dart';
import '../../shared/timeout.dart';
import '../options.dart';
import 'http2_credentials.dart';
import 'transport.dart';
class Http2TransportStream extends GrpcTransportStream {
TransportStream _transportStream;
StreamController<GrpcMessage> _incomingMessages;
StreamController<List<int>> _outgoingMessages;
Stream<GrpcMessage> get incomingMessages => _incomingMessages.stream;
StreamSink<List<int>> get outgoingMessages => _outgoingMessages.sink;
Http2TransportStream(this._transportStream) {
_incomingMessages = new StreamController();
_outgoingMessages = new StreamController();
_transportStream.incomingMessages
.transform(new GrpcHttpDecoder())
.transform(grpcDecompressor())
.pipe(_incomingMessages);
_outgoingMessages.stream
.map(frame)
.map<StreamMessage>((bytes) => new DataStreamMessage(bytes))
.handleError(_onRequestError)
.listen(_transportStream.outgoingMessages.add,
onError: _transportStream.outgoingMessages.addError,
onDone: _transportStream.outgoingMessages.close,
cancelOnError: true);
}
void _onRequestError() {
// TODO: Implement errors on requests
}
@override
Future<void> terminate() async {
await _incomingMessages.close();
await _outgoingMessages.close();
_transportStream.terminate();
}
}
class Http2Transport extends Transport {
static final _methodPost = new Header.ascii(':method', 'POST');
static final _schemeHttp = new Header.ascii(':scheme', 'http');
static final _schemeHttps = new Header.ascii(':scheme', 'https');
static final _contentTypeGrpc =
new Header.ascii('content-type', 'application/grpc');
static final _teTrailers = new Header.ascii('te', 'trailers');
static final _grpcAcceptEncoding =
new Header.ascii('grpc-accept-encoding', 'identity');
static final _userAgent = new Header.ascii('user-agent', 'dart-grpc/0.2.0');
final String host;
final int port;
final ChannelOptions options;
@visibleForTesting
ClientTransportConnection transportConnection;
Http2Transport(this.host, this.port, this.options);
String get authority => options.credentials.authority ?? host;
static List<Header> createCallHeaders(bool useTls, String authority,
String path, Duration timeout, Map<String, String> metadata) {
final headers = [
_methodPost,
useTls ? _schemeHttps : _schemeHttp,
new Header(ascii.encode(':path'), utf8.encode(path)),
new Header(ascii.encode(':authority'), utf8.encode(authority)),
];
if (timeout != null) {
headers.add(new Header.ascii('grpc-timeout', toTimeoutString(timeout)));
}
headers.addAll([
_contentTypeGrpc,
_teTrailers,
_grpcAcceptEncoding,
_userAgent,
]);
metadata?.forEach((key, value) {
headers.add(new Header(ascii.encode(key), utf8.encode(value)));
});
return headers;
}
@override
Future<void> connect() async {
var socket = await Socket.connect(host, port);
final credentials = options.credentials;
if (credentials is Http2ChannelCredentials) {
final securityContext = credentials.securityContext;
if (securityContext != null) {
socket = await SecureSocket.secure(socket,
host: authority,
context: securityContext,
onBadCertificate: _validateBadCertificate);
}
}
socket.done.then(_handleSocketClosed);
transportConnection = ClientTransportConnection.viaSocket(socket);
}
@override
GrpcTransportStream makeRequest(
String path, Duration timeout, Map<String, String> metadata) {
final headers = createCallHeaders(
options.credentials.isSecure, authority, path, timeout, metadata);
final stream = transportConnection.makeRequest(headers);
return new Http2TransportStream(stream);
}
@override
Future<void> finish() async {
await transportConnection.finish();
}
@override
Future<void> terminate() async {
await transportConnection.terminate();
}
bool _validateBadCertificate(X509Certificate certificate) {
final credentials = options.credentials;
if (credentials is Http2ChannelCredentials) {
final validator = credentials.onBadCertificate;
if (validator == null) return false;
return validator(certificate, authority);
}
return false;
}
void _handleSocketClosed(_) {
if (onSocketClosed != null) {
onSocketClosed();
}
}
}

View File

@ -1,39 +0,0 @@
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:async';
import '../../shared/message.dart';
typedef void SocketClosedHandler();
typedef void ActiveStateHandler(bool isActive);
abstract class GrpcTransportStream {
Stream<GrpcMessage> get incomingMessages;
StreamSink<List<int>> get outgoingMessages;
Future<void> terminate();
}
abstract class Transport {
ActiveStateHandler onActiveStateChanged;
SocketClosedHandler onSocketClosed;
Future<void> connect();
GrpcTransportStream makeRequest(
String path, Duration timeout, Map<String, String> metadata);
Future<void> finish();
Future<void> terminate();
}

View File

@ -1,160 +0,0 @@
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import '../../shared/message.dart';
import '../../shared/status.dart';
enum _GrpcWebParseState { Init, Length, Message }
class GrpcWebDecoder extends Converter<ByteBuffer, GrpcMessage> {
@override
GrpcMessage convert(ByteBuffer input) {
final sink = GrpcMessageSink();
startChunkedConversion(sink)
..add(input)
..close();
return sink.message;
}
@override
Sink<ByteBuffer> startChunkedConversion(Sink<GrpcMessage> sink) {
return _GrpcWebConversionSink(sink);
}
}
class _GrpcWebConversionSink extends ChunkedConversionSink<ByteBuffer> {
static const int frameTypeData = 0x00;
static const int frameTypeTrailers = 0x80;
final Sink<GrpcMessage> _out;
final _dataHeader = new Uint8List(4);
_GrpcWebParseState _state = _GrpcWebParseState.Init;
int _chunkOffset;
int _frameType;
int _dataOffset = 0;
Uint8List _data;
_GrpcWebConversionSink(this._out);
int _parseFrameType(List<int> chunkData) {
final frameType = chunkData[_chunkOffset];
_chunkOffset++;
if (frameType != frameTypeData && frameType != frameTypeTrailers) {
throw GrpcError.unimplemented('Invalid frame type: ${frameType}');
}
_state = _GrpcWebParseState.Length;
return frameType;
}
void _parseLength(List<int> chunkData) {
final chunkLength = chunkData.length;
final headerRemaining = _dataHeader.lengthInBytes - _dataOffset;
final chunkRemaining = chunkLength - _chunkOffset;
final toCopy = min(headerRemaining, chunkRemaining);
_dataHeader.setRange(
_dataOffset, _dataOffset + toCopy, chunkData, _chunkOffset);
_dataOffset += toCopy;
_chunkOffset += toCopy;
if (_dataOffset == _dataHeader.lengthInBytes) {
final dataLength = _dataHeader.buffer.asByteData().getUint32(0);
_dataOffset = 0;
_state = _GrpcWebParseState.Message;
if (dataLength == 0) {
// empty message
_finishMessage();
}
_data = new Uint8List(dataLength);
}
}
void _parseMessage(List<int> chunkData) {
final dataRemaining = _data.lengthInBytes - _dataOffset;
if (dataRemaining > 0) {
final chunkRemaining = chunkData.length - _chunkOffset;
final toCopy = min(dataRemaining, chunkRemaining);
_data.setRange(
_dataOffset, _dataOffset + toCopy, chunkData, _chunkOffset);
_dataOffset += toCopy;
_chunkOffset += toCopy;
}
if (_dataOffset == _data.lengthInBytes) {
_finishMessage();
}
}
void _finishMessage() {
switch (_frameType) {
case frameTypeData:
_out.add(new GrpcData(_data, isCompressed: false));
break;
case frameTypeTrailers:
final stringData = String.fromCharCodes(_data);
final headers = _parseHttp1Headers(stringData);
_out.add(new GrpcMetadata(headers));
break;
}
_state = _GrpcWebParseState.Init;
_data = null;
_dataOffset = 0;
}
Map<String, String> _parseHttp1Headers(String stringData) {
final chunks = stringData.trim().split('\r\n');
final headers = <String, String>{};
for (final chunk in chunks) {
final pos = chunk.indexOf(':');
headers[chunk.substring(0, pos).trim()] = chunk.substring(pos + 1).trim();
}
return headers;
}
@override
void add(ByteBuffer chunk) {
_chunkOffset = 0;
final chunkData = chunk.asUint8List();
while (_chunkOffset < chunk.lengthInBytes) {
switch (_state) {
case _GrpcWebParseState.Init:
_frameType = _parseFrameType(chunkData);
break;
case _GrpcWebParseState.Length:
_parseLength(chunkData);
break;
case _GrpcWebParseState.Message:
_parseMessage(chunkData);
break;
}
}
_chunkOffset = 0;
}
@override
void close() {
if (_data != null || _dataOffset != 0) {
throw new GrpcError.unavailable('Closed in non-idle state');
}
_out.close();
}
}

View File

@ -1,140 +0,0 @@
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:async';
import 'dart:html';
import 'dart:typed_data';
import 'package:meta/meta.dart';
import '../../shared/message.dart';
import 'transport.dart';
import 'web_streams.dart';
class XhrTransportStream implements GrpcTransportStream {
HttpRequest _request;
int _requestBytesRead = 0;
StreamController<ByteBuffer> _incomingProcessor;
StreamController<GrpcMessage> _incomingMessages;
StreamController<List<int>> _outgoingMessages;
@override
Stream<GrpcMessage> get incomingMessages => _incomingMessages.stream;
@override
StreamSink<List<int>> get outgoingMessages => _outgoingMessages.sink;
XhrTransportStream(this._request) {
_incomingProcessor = StreamController();
_incomingMessages = StreamController();
_outgoingMessages = StreamController();
_incomingProcessor.stream
.transform(GrpcWebDecoder())
.transform(grpcDecompressor())
.listen(_incomingMessages.add,
onError: _incomingMessages.addError,
onDone: _incomingMessages.close);
_outgoingMessages.stream
.map(frame)
.listen((data) => _request.send(data));
_request.onReadyStateChange.listen((data) {
final contentType = _request.getResponseHeader('Content-Type');
if (contentType == null) {
return;
}
if (_request.readyState == HttpRequest.HEADERS_RECEIVED) {
if (contentType.startsWith('application/grpc')) {
if (_request.response == null) {
return;
}
// Force a metadata message with headers
final headers = GrpcMetadata(_request.responseHeaders);
_incomingMessages.add(headers);
}
}
if (_request.readyState == HttpRequest.DONE) {
_incomingProcessor.close();
_outgoingMessages.close();
}
});
_request.onProgress.listen((_) {
// use response over responseText as most browsers don't support
// using responseText during an onProgress event.
final responseString = _request.response as String;
final bytes = Uint8List.fromList(
responseString.substring(_requestBytesRead).codeUnits)
.buffer;
_requestBytesRead = responseString.length;
_incomingProcessor.add(bytes);
});
}
@override
Future<void> terminate() async {
await _incomingProcessor.close();
await _outgoingMessages.close();
_request.abort();
}
}
class XhrTransport extends Transport {
final String host;
final int port;
HttpRequest _request;
XhrTransport(this.host, this.port);
@override
Future<void> connect() async {}
@override
Future<void> finish() async {}
@visibleForTesting
void initializeRequest(HttpRequest request, Map<String, String> metadata) {
for (final header in metadata.keys) {
request.setRequestHeader(header, metadata[header]);
}
request.setRequestHeader('Content-Type', 'application/grpc-web+proto');
request.setRequestHeader('X-User-Agent', 'grpc-web-dart/0.1');
request.setRequestHeader('X-Grpc-Web', '1');
// Overriding the mimetype allows us to stream and parse the data
request.overrideMimeType('text/plain; charset=x-user-defined');
request.responseType = 'text';
}
@override
GrpcTransportStream makeRequest(
String path, Duration timeout, Map<String, String> metadata) {
_request = HttpRequest();
_request.open('POST', '${host}:${port}${path}');
initializeRequest(_request, metadata);
return XhrTransportStream(_request);
}
@override
Future<void> terminate() async {}
}

View File

@ -1,32 +0,0 @@
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:grpc/src/client/options.dart';
import 'package:grpc/src/client/transport/transport.dart';
import 'package:grpc/src/client/transport/xhr_transport.dart';
import 'package:meta/meta.dart';
import 'channel.dart';
@visibleForTesting
Future<Transport> connectXhrTransport(
String host, int port, ChannelOptions _) async {
return XhrTransport(host, port)..connect();
}
class GrpcWebClientChannel extends ClientChannel {
GrpcWebClientChannel.xhr(String host,
{int port = 443}) : super(host, connectXhrTransport, port: port);
}

View File

@ -18,7 +18,6 @@ import 'dart:convert';
import 'package:http2/transport.dart';
import '../shared/message.dart';
import '../shared/status.dart';
import '../shared/streams.dart';
import '../shared/timeout.dart';
@ -229,7 +228,7 @@ class ServerHandler extends ServiceCall {
if (!_headersSent) {
sendHeaders();
}
_stream.sendData(frame(bytes));
_stream.sendData(GrpcHttpEncoder.frame(bytes));
} catch (error) {
final grpcError =
new GrpcError.internal('Error sending response: $error');

View File

@ -1,63 +0,0 @@
import 'dart:async';
import 'dart:typed_data';
abstract class GrpcMessage {}
class GrpcMetadata extends GrpcMessage {
final Map<String, String> metadata;
GrpcMetadata(this.metadata);
@override
String toString() => 'gRPC Metadata ($metadata)';
}
class GrpcData extends GrpcMessage {
final List<int> data;
final bool isCompressed;
GrpcData(this.data, {this.isCompressed});
@override
String toString() => 'gRPC Data (${data.length} bytes)';
}
class GrpcMessageSink extends Sink<GrpcMessage> {
GrpcMessage message;
@override
void add(GrpcMessage data) {
if (message != null) {
throw 'Too many messages received!';
}
message = data;
}
@override
void close() {
if (message == null) {
throw 'No messages received!';
}
}
}
List<int> frame(List<int> payload) {
final payloadLength = payload.length;
final bytes = new Uint8List(payloadLength + 5);
final header = bytes.buffer.asByteData(0, 5);
header.setUint8(0, 0); // TODO(dart-lang/grpc-dart#6): Handle compression
header.setUint32(1, payloadLength);
bytes.setRange(5, bytes.length, payload);
return bytes;
}
StreamTransformer<GrpcMessage, GrpcMessage> grpcDecompressor() =>
new StreamTransformer<GrpcMessage, GrpcMessage>.fromHandlers(
handleData: (GrpcMessage value, EventSink<GrpcMessage> sink) {
if (value is GrpcData) {
if (value.isCompressed) {
// TODO(dart-lang/grpc-dart#6): Actually handle decompression.
sink.add(new GrpcData(value.data, isCompressed: false));
return;
}
}
sink.add(value);
});

View File

@ -20,9 +20,40 @@ import 'dart:typed_data';
import 'package:http2/transport.dart';
import 'message.dart';
import 'status.dart';
abstract class GrpcMessage {}
class GrpcMetadata extends GrpcMessage {
final Map<String, String> metadata;
GrpcMetadata(this.metadata);
@override
String toString() => 'gRPC Metadata ($metadata)';
}
class GrpcData extends GrpcMessage {
final List<int> data;
final bool isCompressed;
GrpcData(this.data, {this.isCompressed});
@override
String toString() => 'gRPC Data (${data.length} bytes)';
}
StreamTransformer<GrpcMessage, GrpcMessage> grpcDecompressor() =>
new StreamTransformer<GrpcMessage, GrpcMessage>.fromHandlers(
handleData: (GrpcMessage value, EventSink<GrpcMessage> sink) {
if (value is GrpcData) {
if (value.isCompressed) {
// TODO(dart-lang/grpc-dart#6): Actually handle decompression.
sink.add(new GrpcData(value.data, isCompressed: false));
return;
}
}
sink.add(value);
});
class GrpcHttpEncoder extends Converter<GrpcMessage, StreamMessage> {
@override
StreamMessage convert(GrpcMessage input) {
@ -37,12 +68,22 @@ class GrpcHttpEncoder extends Converter<GrpcMessage, StreamMessage> {
}
throw new GrpcError.internal('Unexpected message type');
}
static List<int> frame(List<int> payload) {
final payloadLength = payload.length;
final bytes = new Uint8List(payloadLength + 5);
final header = bytes.buffer.asByteData(0, 5);
header.setUint8(0, 0); // TODO(dart-lang/grpc-dart#6): Handle compression
header.setUint32(1, payloadLength);
bytes.setRange(5, bytes.length, payload);
return bytes;
}
}
class GrpcHttpDecoder extends Converter<StreamMessage, GrpcMessage> {
@override
GrpcMessage convert(StreamMessage input) {
final sink = new GrpcMessageSink();
final sink = new _GrpcMessageSink();
startChunkedConversion(sink)
..add(input)
..close();
@ -142,3 +183,22 @@ class _GrpcMessageConversionSink extends ChunkedConversionSink<StreamMessage> {
_out.close();
}
}
class _GrpcMessageSink extends Sink<GrpcMessage> {
GrpcMessage message;
@override
void add(GrpcMessage data) {
if (message != null) {
throw 'Too many messages received!';
}
message = data;
}
@override
void close() {
if (message == null) {
throw 'No messages received!';
}
}
}

View File

@ -1,6 +1,6 @@
name: grpc
description: Dart implementation of gRPC, a high performance, open-source universal RPC framework.
version: 1.1.0
version: 1.0.1
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/grpc-dart
@ -8,14 +8,12 @@ environment:
sdk: '>=2.0.0 <3.0.0'
dependencies:
async: '>=1.13.3 <3.0.0'
googleapis_auth: ^0.2.5+3
meta: ^1.0.5
http: '>=0.11.3+17 <0.13.0'
http2: '>=0.1.7 <2.0.0'
dev_dependencies:
build_runner: ^0.10.0
build_test: ^0.10.3
build_web_compilers: ^0.4.3
mockito: ^4.0.0
test: ^1.5.0

View File

@ -16,11 +16,11 @@
import 'dart:async';
import 'package:grpc/grpc.dart';
import 'package:grpc/src/shared/message.dart';
import 'package:http2/transport.dart';
import 'package:test/test.dart';
import '../src/client_utils.dart';
import '../src/utils.dart';
import 'src/client_utils.dart';
import 'src/utils.dart';
void main() {
const dummyValue = 0;
@ -39,8 +39,8 @@ void main() {
const requestValue = 17;
const responseValue = 19;
void handleRequest(List<int> message) {
final data = validateClientDataMessage(message);
void handleRequest(StreamMessage message) {
final data = validateDataMessage(message);
expect(mockDecode(data.data), requestValue);
harness
@ -63,8 +63,8 @@ void main() {
var index = 0;
void handleRequest(List<int> message) {
final data = validateClientDataMessage(message);
void handleRequest(StreamMessage message) {
final data = validateDataMessage(message);
expect(mockDecode(data.data), requests[index++]);
}
@ -89,8 +89,8 @@ void main() {
const request = 4;
const responses = const [3, 17, 9];
void handleRequest(List<int> message) {
final data = validateClientDataMessage(message);
void handleRequest(StreamMessage message) {
final data = validateDataMessage(message);
expect(mockDecode(data.data), request);
harness.sendResponseHeader();
@ -112,8 +112,8 @@ void main() {
var index = 0;
void handleRequest(List<int> message) {
final data = validateClientDataMessage(message);
void handleRequest(StreamMessage message) {
final data = validateDataMessage(message);
expect(mockDecode(data.data), requests[index]);
if (index == 0) {
@ -244,11 +244,10 @@ void main() {
const customStatusMessage = 'Custom message';
void handleRequest(_) {
final headers = <String, String>{
'grpc-status': '$customStatusCode',
'grpc-message': customStatusMessage
};
harness.toClient.add(new GrpcMetadata(headers));
harness.toClient.add(new HeadersStreamMessage([
new Header.ascii('grpc-status', '$customStatusCode'),
new Header.ascii('grpc-message', customStatusMessage)
], endStream: true));
harness.toClient.close();
}
@ -313,8 +312,8 @@ void main() {
);
});
Future<Null> makeUnaryCall() async {
void handleRequest(List<int> message) {
Future<void> makeUnaryCall() async {
void handleRequest(StreamMessage message) {
harness
..sendResponseHeader()
..sendResponseValue(1)

View File

@ -1,162 +0,0 @@
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@TestOn('vm')
import 'dart:async';
import 'package:grpc/grpc.dart';
import 'package:grpc/src/client/transport/http2_credentials.dart';
import 'package:grpc/src/client/transport/http2_transport.dart';
import 'package:http2/transport.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import '../src/utils.dart';
class MockTransport extends Mock implements ClientTransportConnection {}
class MockStream extends Mock implements ClientTransportStream {}
typedef void VerifyHeadersCallback(List<Header> headers);
class MockHttp2Transport extends Http2Transport {
MockStream mockClientStream;
VerifyHeadersCallback onVerifyHeaders;
StreamController<StreamMessage> fromClient;
StreamController<StreamMessage> toClient;
MockHttp2Transport(String host, int port, ChannelOptions options)
: super(host, port, options);
@override
Future<void> connect() async {
transportConnection = MockTransport();
when(transportConnection.makeRequest(any)).thenAnswer((call) {
if (onVerifyHeaders != null) {
onVerifyHeaders(call.positionalArguments[0]);
}
mockClientStream = new MockStream();
fromClient = StreamController<StreamMessage>();
toClient = StreamController<StreamMessage>();
when(mockClientStream.outgoingMessages)
.thenAnswer((_) => fromClient.sink);
when(mockClientStream.incomingMessages)
.thenAnswer((_) => toClient.stream);
return mockClientStream;
});
}
@override
Future<void> terminate() async {
fromClient.close();
toClient.close();
}
}
void main() {
final MockHttp2Transport transport = new MockHttp2Transport(
'host',
9999,
ChannelOptions(
credentials: new Http2ChannelCredentials.secure(authority: 'test')));
setUp(() {
transport.connect();
});
tearDown(() {
transport.terminate();
});
test('Make request passes proper headers', () async {
final metadata = <String, String>{
"parameter_1": "value_1",
"parameter_2": "value_2"
};
transport.onVerifyHeaders = (headers) {
final headerMap = headersToMap(headers);
validateRequestHeaders(headerMap,
path: 'test_path',
customHeaders: metadata,
timeout: toTimeoutString(Duration(seconds: 10)));
};
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
});
test('Sent data converted to StreamMessages properly', () async {
final metadata = <String, String>{
"parameter_1": "value_1",
"parameter_2": "value_2"
};
final stream =
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
transport.fromClient.stream.listen((message) {
final dataMessage = validateDataMessage(message);
expect(dataMessage.data.length, 10);
});
stream.outgoingMessages.add(List.filled(10, 0));
});
test('StreamMessages deserializes headers properly', () async {
final metadata = <String, String>{
"parameter_1": "value_1",
"parameter_2": "value_2"
};
final stream =
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
stream.incomingMessages.listen((message) {
expect(message, TypeMatcher<GrpcMetadata>());
if (message is GrpcMetadata) {
message.metadata.forEach((key, value) {
expect(value, metadata[key]);
});
}
});
final httpMessage = GrpcHttpEncoder().convert(GrpcMetadata(metadata));
transport.toClient.add(httpMessage);
});
test('StreamMessages deserializes data properly', () async {
final metadata = <String, String>{
"parameter_1": "value_1",
"parameter_2": "value_2"
};
final stream =
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
final data = List<int>.filled(10, 0);
stream.incomingMessages.listen((message) {
expect(message, TypeMatcher<GrpcData>());
if (message is GrpcData) {
expect(message.data, equals(data));
}
});
final httpMessage = GrpcHttpEncoder().convert(GrpcData(data));
transport.toClient.add(httpMessage);
});
}

View File

@ -1,214 +0,0 @@
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
// for details. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@TestOn('browser')
import 'dart:async';
import 'dart:html';
import 'package:grpc/grpc.dart';
import 'package:grpc/src/client/transport/xhr_transport.dart';
import 'package:grpc/src/shared/message.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
class MockHttpRequest extends Mock implements HttpRequest {}
class MockXhrTransport extends XhrTransport {
StreamController<Event> readyStateChangeStream = StreamController<Event>();
StreamController<ProgressEvent> progressStream =
StreamController<ProgressEvent>();
MockHttpRequest mockRequest;
MockXhrTransport(this.mockRequest) : super('test', 8080) {}
@override
GrpcTransportStream makeRequest(
String path, Duration timeout, Map<String, String> metadata) {
when(mockRequest.onReadyStateChange)
.thenAnswer((_) => readyStateChangeStream.stream);
when(mockRequest.onProgress).thenAnswer((_) => progressStream.stream);
initializeRequest(mockRequest, metadata);
return XhrTransportStream(mockRequest);
}
@override
Future<void> terminate() async {
readyStateChangeStream.close();
progressStream.close();
}
}
void main() {
test('Make request sends correct headers', () async {
final metadata = <String, String>{
'parameter_1': 'value_1',
'parameter_2': 'value_2'
};
final mockRequest = MockHttpRequest();
final transport = MockXhrTransport(mockRequest);
transport.makeRequest('path', Duration(seconds: 10), metadata);
verify(mockRequest.setRequestHeader(
'Content-Type', 'application/grpc-web+proto'));
verify(mockRequest.setRequestHeader('X-User-Agent', 'grpc-web-dart/0.1'));
verify(mockRequest.setRequestHeader('X-Grpc-Web', '1'));
verify(mockRequest.overrideMimeType('text/plain; charset=x-user-defined'));
verify(mockRequest.responseType = 'text');
});
test('Sent data converted to stream properly', () async {
final metadata = <String, String>{
'parameter_1': 'value_1',
'parameter_2': 'value_2'
};
final mockRequest = MockHttpRequest();
final transport = MockXhrTransport(mockRequest);
final stream =
transport.makeRequest('path', Duration(seconds: 10), metadata);
final data = List.filled(10, 0);
stream.outgoingMessages.add(data);
await stream.terminate();
final expectedData = frame(data);
expect(verify(mockRequest.send(captureAny)).captured.single, expectedData);
});
test('Stream handles headers properly', () async {
final metadata = <String, String>{
'parameter_1': 'value_1',
'parameter_2': 'value_2'
};
final mockRequest = MockHttpRequest();
final transport = MockXhrTransport(mockRequest);
final stream =
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
stream.incomingMessages.listen((message) {
expect(message, TypeMatcher<GrpcMetadata>());
if (message is GrpcMetadata) {
message.metadata.forEach((key, value) {
expect(value, metadata[key]);
});
}
});
});
test('Stream deserializes data properly', () async {
final metadata = <String, String>{
'parameter_1': 'value_1',
'parameter_2': 'value_2'
};
final mockRequest = MockHttpRequest();
final transport = MockXhrTransport(mockRequest);
final stream =
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
final data = List<int>.filled(10, 224);
final encoded = frame(data);
final encodedString = String.fromCharCodes(encoded);
bool dataVerified = false;
stream.incomingMessages.listen((message) {
if (message is GrpcData) {
dataVerified = true;
expect(message.data, equals(data));
}
});
when(mockRequest.getResponseHeader('Content-Type'))
.thenReturn('application/grpc+proto');
when(mockRequest.responseHeaders).thenReturn(metadata);
when(mockRequest.readyState).thenReturn(HttpRequest.HEADERS_RECEIVED);
when(mockRequest.response).thenReturn(encodedString);
transport.readyStateChangeStream.add(null);
transport.progressStream.add(null);
// Wait for all streams to process
await Future.sync(() {});
await stream.terminate();
expect(dataVerified, true);
});
test('Stream recieves multiple messages', () async {
final metadata = <String, String>{
'parameter_1': 'value_1',
'parameter_2': 'value_2'
};
final mockRequest = MockHttpRequest();
final transport = MockXhrTransport(mockRequest);
final stream =
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
final data = <List<int>>[
List<int>.filled(10, 224),
List<int>.filled(5, 124)
];
final encoded = data.map((d) => frame(d));
final encodedStrings = encoded.map((e) => String.fromCharCodes(e)).toList();
// to start - expected response is the first message
var expectedResponse = encodedStrings[0];
final expectedMessages = <GrpcMessage>[
GrpcMetadata(metadata),
GrpcData(data[0]),
GrpcData(data[1])
];
stream.incomingMessages.listen((message) {
final expectedMessage = expectedMessages.removeAt(0);
expect(message.runtimeType, expectedMessage.runtimeType);
if (message is GrpcMetadata) {
expect(message.metadata, (expectedMessage as GrpcMetadata).metadata);
} else if (message is GrpcData) {
expect(message.data, (expectedMessage as GrpcData).data);
}
});
when(mockRequest.getResponseHeader('Content-Type'))
.thenReturn('application/grpc+proto');
when(mockRequest.responseHeaders).thenReturn(metadata);
when(mockRequest.readyState).thenReturn(HttpRequest.HEADERS_RECEIVED);
when(mockRequest.response).thenAnswer((_) => expectedResponse);
transport.readyStateChangeStream.add(null);
transport.progressStream.add(null);
// Wait for all streams to process
await Future.sync(() {});
// After the first call, expected response should now be both responses together
expectedResponse = encodedStrings[0] + encodedStrings[1];
transport.progressStream.add(null);
// Wait for all streams to process
await Future.sync(() {});
await stream.terminate();
expect(expectedMessages.isEmpty, isTrue);
});
}

View File

@ -12,7 +12,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@TestOn('vm')
import 'dart:io';
@ -28,14 +27,14 @@ void main() {
await new File('test/data/certstore.p12').readAsBytes();
final missingPassword =
new Http2ChannelCredentials.secure(certificates: certificates);
new ChannelCredentials.secure(certificates: certificates);
expect(() => missingPassword.securityContext, throwsA(isTlsException));
final wrongPassword = new Http2ChannelCredentials.secure(
final wrongPassword = new ChannelCredentials.secure(
certificates: certificates, password: 'wrong');
expect(() => wrongPassword.securityContext, throwsA(isTlsException));
final correctPassword = new Http2ChannelCredentials.secure(
final correctPassword = new ChannelCredentials.secure(
certificates: certificates, password: 'correct');
expect(correctPassword.securityContext, isNotNull);
});

View File

@ -12,7 +12,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@TestOn('vm')
import 'dart:async';

View File

@ -15,7 +15,8 @@
import 'dart:async';
import 'package:grpc/src/shared/message.dart';
import 'package:grpc/src/shared/streams.dart';
import 'package:http2/transport.dart';
import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
@ -23,41 +24,29 @@ import 'package:grpc/grpc.dart';
import 'utils.dart';
typedef void ClientTestMessageHandler(List<int> message);
class MockTransport extends Mock implements ClientTransportConnection {}
GrpcData validateClientDataMessage(List<int> message) {
final decoded = new GrpcData(message);
expect(decoded, new TypeMatcher<GrpcData>());
return decoded;
}
class MockTransport extends Mock implements Transport {}
class MockStream extends Mock implements GrpcTransportStream {}
class MockStream extends Mock implements ClientTransportStream {}
class FakeConnection extends ClientConnection {
final ClientTransportConnection transport;
var connectionError;
FakeConnection._(String host, Transport transport, ChannelOptions options,
ConnectTransport connectTransport)
: super(host, 443, options, connectTransport);
FakeConnection(String host, this.transport, ChannelOptions options)
: super(host, 443, options);
factory FakeConnection(
String host, Transport transport, ChannelOptions options) {
FakeConnection f;
f = FakeConnection._(host, transport, options, (_, _1, _2) async {
if (f.connectionError != null) throw f.connectionError;
return transport;
});
return f;
@override
Future<ClientTransportConnection> connectTransport() async {
if (connectionError != null) throw connectionError;
return transport;
}
}
Duration testBackoff(Duration lastBackoff) => const Duration(milliseconds: 1);
class FakeChannelOptions implements ChannelOptions {
ChannelCredentials credentials = const Http2ChannelCredentials.secure();
ChannelCredentials credentials = const ChannelCredentials.secure();
Duration idleTimeout = const Duration(seconds: 1);
BackoffStrategy backoffStrategy = testBackoff;
}
@ -73,6 +62,8 @@ class FakeChannel extends ClientChannel {
Future<ClientConnection> getConnection() async => connection;
}
typedef ServerMessageHandler = void Function(StreamMessage message);
class TestClient extends Client {
static final _$unary =
new ClientMethod<int, int>('/Test/Unary', mockEncode, mockDecode);
@ -119,8 +110,8 @@ class ClientHarness {
FakeChannelOptions channelOptions;
MockStream stream;
StreamController<List<int>> fromClient;
StreamController<GrpcMessage> toClient;
StreamController<StreamMessage> fromClient;
StreamController<StreamMessage> toClient;
TestClient client;
@ -132,7 +123,8 @@ class ClientHarness {
stream = new MockStream();
fromClient = new StreamController();
toClient = new StreamController();
when(transport.makeRequest(any, any, any)).thenReturn(stream);
when(transport.makeRequest(any, endStream: anyNamed('endStream')))
.thenReturn(stream);
when(transport.onActiveStateChanged = captureAny).thenReturn(null);
when(stream.outgoingMessages).thenReturn(fromClient.sink);
when(stream.incomingMessages).thenAnswer((_) => toClient.stream);
@ -144,17 +136,18 @@ class ClientHarness {
toClient.close();
}
void sendResponseHeader({Map<String, String> headers = const {}}) {
toClient.add(new GrpcMetadata(headers));
void sendResponseHeader({List<Header> headers = const []}) {
toClient.add(new HeadersStreamMessage(headers));
}
void sendResponseValue(int value) {
toClient.add(new GrpcData(mockEncode(value)));
toClient
.add(new DataStreamMessage(GrpcHttpEncoder.frame(mockEncode(value))));
}
void sendResponseTrailer(
{Map<String, String> headers = const {}, bool closeStream = true}) {
toClient.add(new GrpcMetadata(headers));
{List<Header> headers = const [], bool closeStream = true}) {
toClient.add(new HeadersStreamMessage(headers, endStream: true));
if (closeStream) toClient.close();
}
@ -171,11 +164,11 @@ class ClientHarness {
String expectedPath,
Duration expectedTimeout,
Map<String, String> expectedCustomHeaders,
List<ClientTestMessageHandler> serverHandlers = const [],
List<MessageHandler> serverHandlers = const [],
Function doneHandler,
bool expectDone = true}) async {
int serverHandlerIndex = 0;
void handleServerMessage(List<int> message) {
void handleServerMessage(StreamMessage message) {
serverHandlers[serverHandlerIndex++](message);
}
@ -189,17 +182,12 @@ class ClientHarness {
expect(result, expectedResult);
}
final capturedParameters =
verify(transport.makeRequest(captureAny, captureAny, captureAny))
.captured;
if (expectedPath != null) {
expect(capturedParameters[0], expectedPath);
}
expect(capturedParameters[1], expectedTimeout);
final Map<String, String> headers = capturedParameters[2];
headers?.forEach((key, value) {
expect(expectedCustomHeaders[key], value);
});
final List<Header> capturedHeaders =
verify(transport.makeRequest(captureAny)).captured.single;
validateRequestHeaders(capturedHeaders,
path: expectedPath,
timeout: toTimeoutString(expectedTimeout),
customHeaders: expectedCustomHeaders);
await clientSubscription.cancel();
}
@ -219,7 +207,7 @@ class ClientHarness {
String expectedPath,
Duration expectedTimeout,
Map<String, String> expectedCustomHeaders,
List<ClientTestMessageHandler> serverHandlers = const [],
List<MessageHandler> serverHandlers = const [],
bool expectDone = true}) async {
return runTest(
clientCall: expectThrows(clientCall, expectedException),

View File

@ -15,13 +15,11 @@
import 'dart:async';
import 'package:grpc/src/shared/message.dart';
import 'package:grpc/src/shared/streams.dart';
import 'package:http2/transport.dart';
import 'package:test/test.dart';
import 'package:grpc/grpc.dart';
import 'package:grpc/src/client/transport/http2_transport.dart';
import 'utils.dart';
@ -172,14 +170,14 @@ class ServerHarness {
{String authority = 'test',
Map<String, String> metadata,
Duration timeout}) {
final headers = Http2Transport.createCallHeaders(
final headers = ClientConnection.createCallHeaders(
true, authority, path, timeout, metadata);
toServer.add(new HeadersStreamMessage(headers));
}
void sendData(int value) {
toServer
.add(new DataStreamMessage(frame(mockEncode(value))));
.add(new DataStreamMessage(GrpcHttpEncoder.frame(mockEncode(value))));
}
void runTest(String path, List<int> requests, List<int> expectedResponses) {

View File

@ -16,7 +16,6 @@
import 'dart:convert';
import 'package:grpc/src/shared/streams.dart';
import 'package:grpc/src/shared/message.dart';
import 'package:http2/transport.dart';
import 'package:test/test.dart';
@ -30,25 +29,26 @@ Map<String, String> headersToMap(List<Header> headers) =>
new Map.fromIterable(headers,
key: (h) => ascii.decode(h.name), value: (h) => ascii.decode(h.value));
void validateRequestHeaders(Map<String, String> headers,
void validateRequestHeaders(List<Header> headers,
{String path,
String authority = 'test',
String timeout,
Map<String, String> customHeaders}) {
expect(headers[':method'], 'POST');
expect(headers[':scheme'], 'https');
final headerMap = headersToMap(headers);
expect(headerMap[':method'], 'POST');
expect(headerMap[':scheme'], 'https');
if (path != null) {
expect(headers[':path'], path);
expect(headerMap[':path'], path);
}
expect(headers[':authority'], authority);
expect(headers['grpc-timeout'], timeout);
expect(headers['content-type'], 'application/grpc');
expect(headers['te'], 'trailers');
expect(headers['grpc-accept-encoding'], 'identity');
expect(headers['user-agent'], startsWith('dart-grpc/'));
expect(headerMap[':authority'], authority);
expect(headerMap['grpc-timeout'], timeout);
expect(headerMap['content-type'], 'application/grpc');
expect(headerMap['te'], 'trailers');
expect(headerMap['grpc-accept-encoding'], 'identity');
expect(headerMap['user-agent'], startsWith('dart-grpc/'));
customHeaders?.forEach((key, value) {
expect(headers[key], value);
expect(headerMap[key], value);
});
}

View File

@ -16,10 +16,12 @@
import 'dart:async';
import 'package:grpc/grpc.dart';
import 'package:http2/transport.dart';
import 'package:test/test.dart';
import 'src/client_utils.dart';
import 'src/server_utils.dart';
import 'src/utils.dart';
void main() {
const dummyValue = 0;
@ -73,8 +75,8 @@ void main() {
});
test('Calls time out if deadline is exceeded', () async {
void handleRequest(List<int> message) {
validateClientDataMessage(message);
void handleRequest(StreamMessage message) {
validateDataMessage(message);
final Future delay = new Future.delayed(new Duration(milliseconds: 2));
expect(delay, completes);
delay.then((_) {
@ -140,5 +142,5 @@ void main() {
timeout: new Duration(microseconds: 1));
await harness.fromServer.done;
});
}, testOn: 'vm');
});
}