mirror of https://github.com/grpc/grpc-dart.git
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:
parent
d58659507c
commit
d7ae930e7f
|
@ -2,7 +2,6 @@
|
|||
.dart_tool/
|
||||
.packages
|
||||
.pub/
|
||||
.vscode/
|
||||
build/
|
||||
|
||||
# Remove the following pattern if you wish to check in your lock 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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
targets:
|
||||
$default:
|
||||
sources:
|
||||
exclude:
|
||||
- example/**
|
|
@ -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
|
||||
```
|
|
@ -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)));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: echo.proto
|
||||
///
|
||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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'},
|
||||
],
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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'
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -13,4 +13,3 @@ dependencies:
|
|||
|
||||
dev_dependencies:
|
||||
test: ^1.3.0
|
||||
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
});
|
|
@ -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!';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
|
@ -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);
|
||||
});
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue