From d5b74a10449d013662c87a311af7fdca79d31380 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 27 Aug 2015 09:26:33 -0700 Subject: [PATCH 1/6] Add metadata echo functionality to interop server, and corresponding interop test --- interop/interop_client.js | 73 +++++++++++++++++++++++++++++++++++++ interop/interop_server.js | 48 +++++++++++++++++++++--- test/interop_sanity_test.js | 4 ++ 3 files changed, 120 insertions(+), 5 deletions(-) diff --git a/interop/interop_client.js b/interop/interop_client.js index 8fb8d669..14ae0452 100644 --- a/interop/interop_client.js +++ b/interop/interop_client.js @@ -49,6 +49,9 @@ var AUTH_USER = ('155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk' + var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' + '@developer.gserviceaccount.com'); +var ECHO_INITIAL_KEY = "x-grpc-test-echo-initial"; +var ECHO_TRAILING_KEY = "x-grpc-test-echo-trailing-bin"; + /** * Create a buffer filled with size zeroes * @param {number} size The length of the buffer @@ -60,6 +63,27 @@ function zeroBuffer(size) { return zeros; } +/** + * This is used for testing functions with multiple asynchronous calls that + * can happen in different orders. This should be passed the number of async + * function invocations that can occur last, and each of those should call this + * function's return value + * @param {function()} done The function that should be called when a test is + * complete. + * @param {number} count The number of calls to the resulting function if the + * test passes. + * @return {function()} The function that should be called at the end of each + * sequence of asynchronous functions. + */ +function multiDone(done, count) { + return function() { + count -= 1; + if (count <= 0) { + done(); + } + }; +} + /** * Run the empty_unary test * @param {Client} client The client to test against @@ -271,6 +295,54 @@ function timeoutOnSleepingServer(client, done) { }); } +function customMetadata(client, done) { + done = multiDone(done, 5); + var metadata = new grpc.Metadata(); + metadata.set(ECHO_INITIAL_KEY, 'test_initial_metadata_value'); + metadata.set(ECHO_TRAILING_KEY, new Buffer('ababab', 'hex')); + var arg = { + response_type: 'COMPRESSABLE', + response_size: 314159, + payload: { + body: zeroBuffer(271828) + } + }; + var streaming_arg = { + payload: { + body: zeroBuffer(271828) + } + }; + var unary = client.unaryCall(arg, function(err, resp) { + assert.ifError(err); + done(); + }, metadata); + unary.on('metadata', function(metadata) { + assert.deepEqual(metadata.get(ECHO_INITIAL_KEY), + ['test_initial_metadata_value']); + done(); + }); + unary.on('status', function(status) { + var echo_trailer = status.metadata.get(ECHO_TRAILING_KEY); + assert(echo_trailer.length > 0); + assert.strictEqual(echo_trailer.toString('hex'), 'ababab'); + done(); + }); + var stream = client.fullDuplexCall(metadata); + stream.on('metadata', function(metadata) { + assert.deepEqual(metadata.get(ECHO_INITIAL_KEY), + ['test_initial_metadata_value']); + done(); + }); + stream.on('status', function(status) { + var echo_trailer = status.metadata.get(ECHO_TRAILING_KEY); + assert(echo_trailer.length > 0); + assert.strictEqual(echo_trailer.toString('hex'), 'ababab'); + done(); + }); + stream.write(streaming_arg); + stream.end(); +} + /** * Run one of the authentication tests. * @param {string} expected_user The expected username in the response @@ -358,6 +430,7 @@ var test_cases = { cancel_after_begin: cancelAfterBegin, cancel_after_first_response: cancelAfterFirstResponse, timeout_on_sleeping_server: timeoutOnSleepingServer, + custom_metadata: customMetadata, compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER, null), service_account_creds: _.partial(authTest, AUTH_USER, AUTH_SCOPE), jwt_token_creds: _.partial(authTest, AUTH_USER, null), diff --git a/interop/interop_server.js b/interop/interop_server.js index 99155e99..c23f2376 100644 --- a/interop/interop_server.js +++ b/interop/interop_server.js @@ -39,6 +39,9 @@ var _ = require('lodash'); var grpc = require('..'); var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; +var ECHO_INITIAL_KEY = "x-grpc-test-echo-initial"; +var ECHO_TRAILING_KEY = "x-grpc-test-echo-trailing-bin"; + /** * Create a buffer filled with size zeroes * @param {number} size The length of the buffer @@ -50,6 +53,34 @@ function zeroBuffer(size) { return zeros; } +/** + * Echos a header metadata item as specified in the interop spec. + * @param {Call} call The call to echo metadata on + */ +function echoHeader(call) { + var echo_initial = call.metadata.get(ECHO_INITIAL_KEY); + if (echo_initial.length > 0) { + var response_metadata = new grpc.Metadata(); + response_metadata.set(ECHO_INITIAL_KEY, echo_initial[0]); + call.sendMetadata(response_metadata); + } +} + +/** + * Gets the trailer metadata that should be echoed when the call is done, + * as specified in the interop spec. + * @param {Call} call The call to get metadata from + * @return {grpc.Metadata} The metadata to send as a trailer + */ +function getEchoTrailer(call) { + var echo_trailer = call.metadata.get(ECHO_TRAILING_KEY); + var response_trailer = new grpc.Metadata(); + if (echo_trailer.length > 0) { + response_trailer.set(ECHO_TRAILING_KEY, echo_trailer[0]); + } + return response_trailer; +} + /** * Respond to an empty parameter with an empty response. * NOTE: this currently does not work due to issue #137 @@ -58,7 +89,8 @@ function zeroBuffer(size) { * or error */ function handleEmpty(call, callback) { - callback(null, {}); + echoHeader(call); + callback(null, {}, getEchoTrailer(call)); } /** @@ -68,6 +100,7 @@ function handleEmpty(call, callback) { * error */ function handleUnary(call, callback) { + echoHeader(call); var req = call.request; var zeros = zeroBuffer(req.response_size); var payload_type = req.response_type; @@ -75,7 +108,8 @@ function handleUnary(call, callback) { payload_type = ['COMPRESSABLE', 'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1]; } - callback(null, {payload: {type: payload_type, body: zeros}}); + callback(null, {payload: {type: payload_type, body: zeros}}, + getEchoTrailer(call)); } /** @@ -85,12 +119,14 @@ function handleUnary(call, callback) { * error */ function handleStreamingInput(call, callback) { + echoHeader(call); var aggregate_size = 0; call.on('data', function(value) { aggregate_size += value.payload.body.length; }); call.on('end', function() { - callback(null, {aggregated_payload_size: aggregate_size}); + callback(null, {aggregated_payload_size: aggregate_size}, + getEchoTrailer(call)); }); } @@ -99,6 +135,7 @@ function handleStreamingInput(call, callback) { * @param {Call} call Call to handle */ function handleStreamingOutput(call) { + echoHeader(call); var req = call.request; var payload_type = req.response_type; if (payload_type === 'RANDOM') { @@ -113,7 +150,7 @@ function handleStreamingOutput(call) { } }); }); - call.end(); + call.end(getEchoTrailer(call)); } /** @@ -122,6 +159,7 @@ function handleStreamingOutput(call) { * @param {Call} call Call to handle */ function handleFullDuplex(call) { + echoHeader(call); call.on('data', function(value) { var payload_type = value.response_type; if (payload_type === 'RANDOM') { @@ -138,7 +176,7 @@ function handleFullDuplex(call) { }); }); call.on('end', function() { - call.end(); + call.end(getEchoTrailer(call)); }); } diff --git a/test/interop_sanity_test.js b/test/interop_sanity_test.js index 2ca07c1d..d7b6f331 100644 --- a/test/interop_sanity_test.js +++ b/test/interop_sanity_test.js @@ -90,4 +90,8 @@ describe('Interop tests', function() { interop_client.runTest(port, name_override, 'timeout_on_sleeping_server', true, true, done); }); + it.only('should pass custom_metadata', function(done) { + interop_client.runTest(port, name_override, 'custom_metadata', + true, true, done); + }); }); From 85423a907d826884197852312f8d96b626d21cd2 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 27 Aug 2015 10:02:00 -0700 Subject: [PATCH 2/6] Fixed the tests --- interop/interop_client.js | 8 ++++---- interop/interop_server.js | 4 ++-- test/interop_sanity_test.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/interop/interop_client.js b/interop/interop_client.js index 14ae0452..7945ab19 100644 --- a/interop/interop_client.js +++ b/interop/interop_client.js @@ -49,8 +49,8 @@ var AUTH_USER = ('155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk' + var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' + '@developer.gserviceaccount.com'); -var ECHO_INITIAL_KEY = "x-grpc-test-echo-initial"; -var ECHO_TRAILING_KEY = "x-grpc-test-echo-trailing-bin"; +var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial'; +var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin'; /** * Create a buffer filled with size zeroes @@ -324,7 +324,7 @@ function customMetadata(client, done) { unary.on('status', function(status) { var echo_trailer = status.metadata.get(ECHO_TRAILING_KEY); assert(echo_trailer.length > 0); - assert.strictEqual(echo_trailer.toString('hex'), 'ababab'); + assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab'); done(); }); var stream = client.fullDuplexCall(metadata); @@ -336,7 +336,7 @@ function customMetadata(client, done) { stream.on('status', function(status) { var echo_trailer = status.metadata.get(ECHO_TRAILING_KEY); assert(echo_trailer.length > 0); - assert.strictEqual(echo_trailer.toString('hex'), 'ababab'); + assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab'); done(); }); stream.write(streaming_arg); diff --git a/interop/interop_server.js b/interop/interop_server.js index c23f2376..762e6700 100644 --- a/interop/interop_server.js +++ b/interop/interop_server.js @@ -39,8 +39,8 @@ var _ = require('lodash'); var grpc = require('..'); var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; -var ECHO_INITIAL_KEY = "x-grpc-test-echo-initial"; -var ECHO_TRAILING_KEY = "x-grpc-test-echo-trailing-bin"; +var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial'; +var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin'; /** * Create a buffer filled with size zeroes diff --git a/test/interop_sanity_test.js b/test/interop_sanity_test.js index d7b6f331..804c1d45 100644 --- a/test/interop_sanity_test.js +++ b/test/interop_sanity_test.js @@ -90,7 +90,7 @@ describe('Interop tests', function() { interop_client.runTest(port, name_override, 'timeout_on_sleeping_server', true, true, done); }); - it.only('should pass custom_metadata', function(done) { + it('should pass custom_metadata', function(done) { interop_client.runTest(port, name_override, 'custom_metadata', true, true, done); }); From 6fa3d2614dd9e8b0404655411280654cc92c3fa6 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 27 Aug 2015 10:02:24 -0700 Subject: [PATCH 3/6] Fixed handling of binary metadata values --- ext/call.cc | 23 ++++++++++++----------- src/metadata.js | 4 +++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ext/call.cc b/ext/call.cc index 18858fa3..fddc1e21 100644 --- a/ext/call.cc +++ b/ext/call.cc @@ -111,17 +111,19 @@ bool CreateMetadataArray(Handle metadata, grpc_metadata_array *array, NanAssignPersistent(*handle, value); resources->handles.push_back(unique_ptr( new PersistentHolder(handle))); - continue; + } else { + return false; } - } - if (value->IsString()) { - Handle string_value = value->ToString(); - NanUtf8String *utf8_value = new NanUtf8String(string_value); - resources->strings.push_back(unique_ptr(utf8_value)); - current->value = **utf8_value; - current->value_length = string_value->Length(); } else { - return false; + if (value->IsString()) { + Handle string_value = value->ToString(); + NanUtf8String *utf8_value = new NanUtf8String(string_value); + resources->strings.push_back(unique_ptr(utf8_value)); + current->value = **utf8_value; + current->value_length = string_value->Length(); + } else { + return false; + } } array->count += 1; } @@ -156,8 +158,7 @@ Handle ParseMetadata(const grpc_metadata_array *metadata_array) { } if (EndsWith(elem->key, "-bin")) { array->Set(index_map[elem->key], - MakeFastBuffer( - NanNewBufferHandle(elem->value, elem->value_length))); + NanNewBufferHandle(elem->value, elem->value_length)); } else { array->Set(index_map[elem->key], NanNew(elem->value)); } diff --git a/src/metadata.js b/src/metadata.js index 65fd91f3..c1da70b1 100644 --- a/src/metadata.js +++ b/src/metadata.js @@ -147,7 +147,9 @@ Metadata.prototype.getMap = function() { */ Metadata.prototype.clone = function() { var copy = new Metadata(); - copy._internal_repr = _.cloneDeep(this._internal_repr); + _.forOwn(this._internal_repr, function(value, key) { + copy._internal_repr[key] = _.clone(value); + }); return copy; }; From 2254fd5aa79eb55cbae4e382a26b25e6ca258049 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 1 Oct 2015 11:54:00 -0700 Subject: [PATCH 4/6] Moved gRPC node package root to repo root, made it depend on grpc.gyp --- .istanbul.yml | 6 -- LICENSE | 28 -------- README.md | 36 ----------- binding.gyp | 100 ----------------------------- index.js | 3 +- interop/empty.proto | 43 ------------- interop/interop_client.js | 4 +- interop/interop_server.js | 4 +- interop/messages.proto | 132 -------------------------------------- interop/test.proto | 72 --------------------- package.json | 63 ------------------ src/client.js | 4 +- src/server.js | 2 +- test/call_test.js | 2 +- test/channel_test.js | 2 +- test/constant_test.js | 2 +- test/end_to_end_test.js | 2 +- test/server_test.js | 2 +- test/surface_test.js | 2 +- 19 files changed, 16 insertions(+), 493 deletions(-) delete mode 100644 .istanbul.yml delete mode 100644 LICENSE delete mode 100644 binding.gyp delete mode 100644 interop/empty.proto delete mode 100644 interop/messages.proto delete mode 100644 interop/test.proto delete mode 100644 package.json diff --git a/.istanbul.yml b/.istanbul.yml deleted file mode 100644 index 9ff1379f..00000000 --- a/.istanbul.yml +++ /dev/null @@ -1,6 +0,0 @@ -reporting: - watermarks: - statements: [80, 95] - lines: [80, 95] - functions: [80, 95] - branches: [80, 95] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0209b570..00000000 --- a/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2015, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 7719d082..5d89e222 100644 --- a/README.md +++ b/README.md @@ -5,51 +5,19 @@ Beta ## PREREQUISITES - `node`: This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package. -- [homebrew][] on Mac OS X. These simplify the installation of the gRPC C core. ## INSTALLATION -**Linux (Debian):** - -Add [Debian jessie-backports][] to your `sources.list` file. Example: - -```sh -echo "deb http://http.debian.net/debian jessie-backports main" | \ -sudo tee -a /etc/apt/sources.list -``` - -Install the gRPC Debian package - -```sh -sudo apt-get update -sudo apt-get install libgrpc-dev -``` - Install the gRPC NPM package ```sh npm install grpc ``` -**Mac OS X** - -Install [homebrew][]. Run the following command to install gRPC Node.js. -```sh -$ curl -fsSL https://goo.gl/getgrpc | bash -s nodejs -``` -This will download and run the [gRPC install script][], then install the latest version of gRPC Nodejs npm package. - ## BUILD FROM SOURCE 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). - 2. Follow the instructions in the `INSTALL` file in the root of that repository to install the C core library that this package depends on. 3. Run `npm install`. -If you install the gRPC C core library in a custom location, then you need to set some environment variables to install this library. The command will look like this: - -```sh -CXXFLAGS=-I/include LDFLAGS=-L/lib npm install [grpc] -``` - ## TESTING To run the test suite, simply run `npm test` in the install location. @@ -110,7 +78,3 @@ ServerCredentials ``` An object with factory methods for creating credential objects for servers. - -[homebrew]:http://brew.sh -[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install -[Debian jessie-backports]:http://backports.debian.org/Instructions/ diff --git a/binding.gyp b/binding.gyp deleted file mode 100644 index 247719e9..00000000 --- a/binding.gyp +++ /dev/null @@ -1,100 +0,0 @@ -{ - "variables" : { - 'config': '/dev/null 2>&1 && echo true || echo false)' - }, - 'conditions': [ - ['config=="gcov"', { - 'cflags': [ - '-ftest-coverage', - '-fprofile-arcs', - '-O0' - ], - 'ldflags': [ - '-ftest-coverage', - '-fprofile-arcs' - ] - } - ], - ['pkg_config_grpc == "true"', { - 'link_settings': { - 'libraries': [ - '=0.10.13" - }, - "files": [ - "LICENSE", - "README.md", - "index.js", - "binding.gyp", - "bin", - "cli", - "examples", - "ext", - "interop", - "src", - "test" - ], - "main": "index.js", - "license": "BSD-3-Clause" -} diff --git a/src/client.js b/src/client.js index 7f510231..33ddb3ce 100644 --- a/src/client.js +++ b/src/client.js @@ -40,7 +40,7 @@ var _ = require('lodash'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); var common = require('./common'); @@ -54,7 +54,7 @@ var Readable = stream.Readable; var Writable = stream.Writable; var Duplex = stream.Duplex; var util = require('util'); -var version = require('../package.json').version; +var version = require('../../../package.json').version; util.inherits(ClientWritableStream, Writable); diff --git a/src/server.js b/src/server.js index 70b4a9d8..87b5b7ad 100644 --- a/src/server.js +++ b/src/server.js @@ -40,7 +40,7 @@ var _ = require('lodash'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); var common = require('./common'); diff --git a/test/call_test.js b/test/call_test.js index e7f071bc..ec502183 100644 --- a/test/call_test.js +++ b/test/call_test.js @@ -34,7 +34,7 @@ 'use strict'; var assert = require('assert'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); /** * Helper function to return an absolute deadline given a relative timeout in diff --git a/test/channel_test.js b/test/channel_test.js index d81df2a3..4418dfff 100644 --- a/test/channel_test.js +++ b/test/channel_test.js @@ -34,7 +34,7 @@ 'use strict'; var assert = require('assert'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); /** * This is used for testing functions with multiple asynchronous calls that diff --git a/test/constant_test.js b/test/constant_test.js index fa06ad4e..b17cd339 100644 --- a/test/constant_test.js +++ b/test/constant_test.js @@ -34,7 +34,7 @@ 'use strict'; var assert = require('assert'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); /** * List of all status names diff --git a/test/end_to_end_test.js b/test/end_to_end_test.js index 4b8da3bf..813221da 100644 --- a/test/end_to_end_test.js +++ b/test/end_to_end_test.js @@ -34,7 +34,7 @@ 'use strict'; var assert = require('assert'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); /** * This is used for testing functions with multiple asynchronous calls that diff --git a/test/server_test.js b/test/server_test.js index 1e69d52e..999a183b 100644 --- a/test/server_test.js +++ b/test/server_test.js @@ -36,7 +36,7 @@ var assert = require('assert'); var fs = require('fs'); var path = require('path'); -var grpc = require('bindings')('grpc.node'); +var grpc = require('bindings')('grpc_node'); describe('server', function() { describe('constructor', function() { diff --git a/test/surface_test.js b/test/surface_test.js index d917c7a1..89ea0869 100644 --- a/test/surface_test.js +++ b/test/surface_test.js @@ -356,7 +356,7 @@ describe('Echo metadata', function() { call.end(); }); it('shows the correct user-agent string', function(done) { - var version = require('../package.json').version; + var version = require('../../../package.json').version; var call = client.unary({}, function(err, data) { assert.ifError(err); }, metadata); call.on('metadata', function(metadata) { From 2e758434b1f63723c59eb971d8d3517ad04a7c47 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 2 Oct 2015 12:49:03 -0700 Subject: [PATCH 5/6] Fixed node extension module name --- ext/node_grpc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/node_grpc.cc b/ext/node_grpc.cc index caca0fc4..8ea0c64b 100644 --- a/ext/node_grpc.cc +++ b/ext/node_grpc.cc @@ -247,4 +247,4 @@ void init(Local exports) { grpc::node::ServerCredentials::Init(exports); } -NODE_MODULE(grpc, init) +NODE_MODULE(grpc_node, init) From 9b0fbb4cf0d1e63d09682f2ccfc81213d0866441 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 6 Oct 2015 16:51:50 -0700 Subject: [PATCH 6/6] Fixed issues with binary metadata type checking --- ext/call.cc | 5 +++-- src/metadata.js | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ext/call.cc b/ext/call.cc index b08a9f96..f98fe246 100644 --- a/ext/call.cc +++ b/ext/call.cc @@ -168,8 +168,9 @@ Local ParseMetadata(const grpc_metadata_array *metadata_array) { } if (EndsWith(elem->key, "-bin")) { Nan::Set(array, index_map[elem->key], - Nan::CopyBuffer(elem->value, - elem->value_length).ToLocalChecked()); + MakeFastBuffer( + Nan::CopyBuffer(elem->value, + elem->value_length).ToLocalChecked())); } else { Nan::Set(array, index_map[elem->key], Nan::New(elem->value).ToLocalChecked()); diff --git a/src/metadata.js b/src/metadata.js index c1da70b1..5c24e46c 100644 --- a/src/metadata.js +++ b/src/metadata.js @@ -59,6 +59,7 @@ function normalizeKey(key) { function validate(key, value) { if (_.endsWith(key, '-bin')) { if (!(value instanceof Buffer)) { + console.log(value.constructor.toString()); throw new Error('keys that end with \'-bin\' must have Buffer values'); } } else { @@ -173,7 +174,9 @@ Metadata.prototype._getCoreRepresentation = function() { Metadata._fromCoreRepresentation = function(metadata) { var newMetadata = new Metadata(); if (metadata) { - newMetadata._internal_repr = _.cloneDeep(metadata); + _.forOwn(metadata, function(value, key) { + newMetadata._internal_repr[key] = _.clone(value); + }); } return newMetadata; };