diff options
author | murgatroid99 <mlumish@google.com> | 2016-01-07 10:03:18 -0800 |
---|---|---|
committer | murgatroid99 <mlumish@google.com> | 2016-01-07 10:03:18 -0800 |
commit | f776f900589577e9cae025da88443320cff2f3b9 (patch) | |
tree | 2790903cfbb371684369c71af0aeb752cf585892 /src | |
parent | 160a690a4cdbb8b359580564bfda215259dc0d52 (diff) |
Make Node library use core metadata validation instead of duplicating it
Diffstat (limited to 'src')
-rw-r--r-- | src/node/ext/call.cc | 8 | ||||
-rw-r--r-- | src/node/ext/node_grpc.cc | 50 | ||||
-rw-r--r-- | src/node/src/metadata.js | 20 |
3 files changed, 62 insertions, 16 deletions
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index c0e2b0f0e8..84a3e227c8 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -95,10 +95,6 @@ Local<Value> nanErrorWithCode(const char *msg, grpc_call_error code) { return scope.Escape(err); } -bool EndsWith(const char *str, const char *substr) { - return strcmp(str+strlen(str)-strlen(substr), substr) == 0; -} - bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array, shared_ptr<Resources> resources) { HandleScope scope; @@ -126,7 +122,7 @@ bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array, grpc_metadata *current = &array->metadata[array->count]; current->key = **utf8_key; // Only allow binary headers for "-bin" keys - if (EndsWith(current->key, "-bin")) { + if (grpc_is_binary_header(current->key, strlen(current->key))) { if (::node::Buffer::HasInstance(value)) { current->value = ::node::Buffer::Data(value); current->value_length = ::node::Buffer::Length(value); @@ -180,7 +176,7 @@ Local<Value> ParseMetadata(const grpc_metadata_array *metadata_array) { } else { array = Local<Array>::Cast(maybe_array.ToLocalChecked()); } - if (EndsWith(elem->key, "-bin")) { + if (grpc_is_binary_header(elem->key, strlen(elem->key))) { Nan::Set(array, index_map[elem->key], MakeFastBuffer( Nan::CopyBuffer(elem->value, diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index 5b5f3c1c5b..a2b8e0d22b 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ #include "completion_queue_async_worker.h" #include "server_credentials.h" +using v8::FunctionTemplate; using v8::Local; using v8::Value; using v8::Object; @@ -230,6 +231,40 @@ void InitWriteFlags(Local<Object> exports) { Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS); } +NAN_METHOD(MetadataKeyIsLegal) { + if (!info[0]->IsString()) { + return Nan::ThrowTypeError( + "headerKeyIsLegal's argument must be a string"); + } + Local<String> key = Nan::To<String>(info[0]).ToLocalChecked(); + char *key_str = *Nan::Utf8String(key); + info.GetReturnValue().Set(static_cast<bool>( + grpc_header_key_is_legal(key_str, static_cast<size_t>(key->Length())))); +} + +NAN_METHOD(MetadataNonbinValueIsLegal) { + if (!info[0]->IsString()) { + return Nan::ThrowTypeError( + "metadataNonbinValueIsLegal's argument must be a string"); + } + Local<String> value = Nan::To<String>(info[0]).ToLocalChecked(); + char *value_str = *Nan::Utf8String(value); + info.GetReturnValue().Set(static_cast<bool>( + grpc_header_nonbin_value_is_legal( + value_str, static_cast<size_t>(value->Length())))); +} + +NAN_METHOD(MetadataKeyIsBinary) { + if (!info[0]->IsString()) { + return Nan::ThrowTypeError( + "metadataKeyIsLegal's argument must be a string"); + } + Local<String> key = Nan::To<String>(info[0]).ToLocalChecked(); + char *key_str = *Nan::Utf8String(key); + info.GetReturnValue().Set(static_cast<bool>( + grpc_is_binary_header(key_str, static_cast<size_t>(key->Length())))); +} + void init(Local<Object> exports) { Nan::HandleScope scope; grpc_init(); @@ -247,6 +282,19 @@ void init(Local<Object> exports) { grpc::node::Server::Init(exports); grpc::node::CompletionQueueAsyncWorker::Init(exports); grpc::node::ServerCredentials::Init(exports); + + // Attach a few utility functions directly to the module + Nan::Set(exports, Nan::New("metadataKeyIsLegal").ToLocalChecked(), + Nan::GetFunction( + Nan::New<FunctionTemplate>(MetadataKeyIsLegal)).ToLocalChecked()); + Nan::Set(exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(), + Nan::GetFunction( + Nan::New<FunctionTemplate>(MetadataNonbinValueIsLegal) + ).ToLocalChecked()); + Nan::Set(exports, Nan::New("metadataKeyIsBinary").ToLocalChecked(), + Nan::GetFunction( + Nan::New<FunctionTemplate>(MetadataKeyIsBinary) + ).ToLocalChecked()); } NODE_MODULE(grpc_node, init) diff --git a/src/node/src/metadata.js b/src/node/src/metadata.js index 0a2f1489b6..fef79f959e 100644 --- a/src/node/src/metadata.js +++ b/src/node/src/metadata.js @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,8 @@ var _ = require('lodash'); +var grpc = require('bindings')('grpc_node'); + /** * Class for storing metadata. Keys are normalized to lowercase ASCII. * @constructor @@ -58,15 +60,16 @@ function Metadata() { } function normalizeKey(key) { - if (!(/^[A-Za-z\d_-]+$/.test(key))) { - throw new Error('Metadata keys must be nonempty strings containing only ' + - 'alphanumeric characters and hyphens'); + key = key.toLowerCase(); + if (grpc.metadataKeyIsLegal(key)) { + return key; + } else { + throw new Error('Metadata key contains illegal characters'); } - return key.toLowerCase(); } function validate(key, value) { - if (_.endsWith(key, '-bin')) { + if (grpc.metadataKeyIsBinary(key)) { if (!(value instanceof Buffer)) { throw new Error('keys that end with \'-bin\' must have Buffer values'); } @@ -75,9 +78,8 @@ function validate(key, value) { throw new Error( 'keys that don\'t end with \'-bin\' must have String values'); } - if (!(/^[\x20-\x7E]*$/.test(value))) { - throw new Error('Metadata string values can only contain printable ' + - 'ASCII characters and space'); + if (!grpc.metadataNonbinValueIsLegal(value)) { + throw new Error('Metadata string value contains illegal characters'); } } } |