@@ -0,0 +1,171 @@
+"use strict";
+/*
+ * Copyright 2019 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+const http2 = require("http2");
+const url_1 = require("url");
+const constants_1 = require("./constants");
+function noop() { }
+const unimplementedStatusResponse = {
+ code: constants_1.Status.UNIMPLEMENTED,
+ details: 'The server does not implement this method',
+};
+const defaultHandler = {
+ unary(call, callback) {
+ callback(unimplementedStatusResponse, null);
+ },
+ clientStream(call, callback) {
+ callback(unimplementedStatusResponse, null);
+ },
+ serverStream(call) {
+ call.emit('error', unimplementedStatusResponse);
+ },
+ bidi(call) {
+ call.emit('error', unimplementedStatusResponse);
+ }
+};
+// tslint:enable:no-any
+class Server {
+ constructor(options) {
+ this.http2Server = null;
+ this.handlers = new Map();
+ this.started = false;
+ }
+ addProtoService() {
+ throw new Error('Not implemented. Use addService() instead');
+ }
+ addService(service, implementation) {
+ if (this.started === true) {
+ throw new Error('Can\'t add a service to a started server.');
+ }
+ if (service === null || typeof service !== 'object' ||
+ implementation === null || typeof implementation !== 'object') {
+ throw new Error('addService() requires two objects as arguments');
+ }
+ const serviceKeys = Object.keys(service);
+ if (serviceKeys.length === 0) {
+ throw new Error('Cannot add an empty service to a server');
+ }
+ const implMap = implementation;
+ serviceKeys.forEach((name) => {
+ const attrs = service[name];
+ let methodType;
+ if (attrs.requestStream) {
+ if (attrs.responseStream) {
+ methodType = 'bidi';
+ }
+ else {
+ methodType = 'clientStream';
+ }
+ }
+ else {
+ if (attrs.responseStream) {
+ methodType = 'serverStream';
+ }
+ else {
+ methodType = 'unary';
+ }
+ }
+ let implFn = implMap[name];
+ let impl;
+ if (implFn === undefined && typeof attrs.originalName === 'string') {
+ implFn = implMap[attrs.originalName];
+ }
+ if (implFn !== undefined) {
+ impl = implFn.bind(implementation);
+ }
+ else {
+ impl = defaultHandler[methodType];
+ }
+ const success = this.register(attrs.path, impl, attrs.responseSerialize, attrs.requestDeserialize, methodType);
+ if (success === false) {
+ throw new Error(`Method handler for ${attrs.path} already provided.`);
+ }
+ });
+ }
+ bind(port, creds) {
+ throw new Error('Not implemented. Use bindAsync() instead');
+ }
+ bindAsync(port, creds, callback) {
+ if (this.started === true) {
+ throw new Error('server is already started');
+ }
+ if (typeof port !== 'string') {
+ throw new TypeError('port must be a string');
+ }
+ if (creds === null || typeof creds !== 'object') {
+ throw new TypeError('creds must be an object');
+ }
+ if (typeof callback !== 'function') {
+ throw new TypeError('callback must be a function');
+ }
+ const url = new url_1.URL(`http://${port}`);
+ const options = { host: url.hostname, port: +url.port };
+ if (creds._isSecure()) {
+ this.http2Server = http2.createSecureServer(creds._getSettings());
+ }
+ else {
+ this.http2Server = http2.createServer();
+ }
+ // TODO(cjihrig): Set up the handlers, to allow requests to be processed.
+ function onError(err) {
+ callback(err, -1);
+ }
+ this.http2Server.once('error', onError);
+ this.http2Server.listen(options, () => {
+ const server = this.http2Server;
+ const port = server.address().port;
+ server.removeListener('error', onError);
+ callback(null, port);
+ });
+ }
+ forceShutdown() {
+ throw new Error('Not yet implemented');
+ }
+ register(name, handler, serialize, deserialize, type) {
+ if (this.handlers.has(name)) {
+ return false;
+ }
+ this.handlers.set(name, { func: handler, serialize, deserialize, type: type });
+ return true;
+ }
+ start() {
+ if (this.http2Server === null || this.http2Server.listening !== true) {
+ throw new Error('server must be bound in order to start');
+ }
+ if (this.started === true) {
+ throw new Error('server is already started');
+ }
+ this.started = true;
+ }
+ tryShutdown(callback) {
+ callback = typeof callback === 'function' ? callback : noop;
+ if (this.http2Server === null) {
+ callback(new Error('server is not running'));
+ return;
+ }
+ this.http2Server.close((err) => {
+ this.started = false;
+ callback(err);
+ });
+ }
+ addHttp2Port() {
+ throw new Error('Not yet implemented');
+ }
+}
+exports.Server = Server;
+//# sourceMappingURL=server.js.map
\ No newline at end of file