Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

grpc-server-js

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grpc-server-js - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

124

lib/compression-filter.js

@@ -36,2 +36,7 @@ 'use strict';

class IdentityHandler extends CompressionHandler {
constructor () {
super();
this.name = 'identity';
}
compressMessage (message) { // eslint-disable-line class-methods-use-this

@@ -60,2 +65,7 @@ throw new Error('Identity encoding does not support compression');

class GzipHandler extends CompressionHandler {
constructor () {
super();
this.name = 'gzip';
}
compressMessage (message) { // eslint-disable-line class-methods-use-this

@@ -88,2 +98,7 @@ return new Promise((resolve, reject) => {

class DeflateHandler extends CompressionHandler {
constructor () {
super();
this.name = 'deflate';
}
compressMessage (message) { // eslint-disable-line class-methods-use-this

@@ -115,32 +130,80 @@ return new Promise((resolve, reject) => {

function getCompressionHandler (compressionName) {
if (typeof compressionName !== 'string') {
throw new Error('Compression method must be a string');
// This class tracks all compression methods supported by a server.
// TODO: Export this class and make it configurable by the Server class.
class CompressionMethodMap {
constructor () {
this.default = null;
this.accepts = null;
this.map = new Map();
this.register('identity', IdentityHandler);
this.register('deflate', DeflateHandler);
this.register('gzip', GzipHandler);
this.setDefault('identity');
}
switch (compressionName) {
case 'identity' :
return new IdentityHandler();
case 'deflate' :
return new DeflateHandler();
case 'gzip' :
return new GzipHandler();
default :
register (compressionName, compressionMethodConstructor) {
if (typeof compressionName !== 'string') {
throw new TypeError('Compression method must be a string');
}
if (typeof compressionMethodConstructor !== 'function') {
throw new TypeError('Compression method constructor must be a function');
}
this.map.set(compressionName, compressionMethodConstructor);
this.accepts = Array.from(this.map.keys());
}
setDefault (compressionName) {
if (typeof compressionName !== 'string') {
throw new TypeError('Compression method must be a string');
}
if (!this.map.has(compressionName)) {
// TODO: This error code must be UNIMPLEMENTED.
throw new Error(`Compression method not supported: ${compressionName}`);
}
this.default = compressionName;
}
getDefaultInstance () {
return this.getInstance(this.default);
}
getInstance (compressionName) {
if (typeof compressionName !== 'string') {
throw new TypeError('Compression method must be a string');
}
const Ctor = this.map.get(compressionName);
if (Ctor === undefined) {
// TODO: This error code must be UNIMPLEMENTED.
throw new Error(`Compression method not supported: ${compressionName}`);
}
return new Ctor();
}
}
const compressionMethods = new CompressionMethodMap();
const defaultCompression = compressionMethods.getDefaultInstance();
const defaultAcceptedEncoding = compressionMethods.accepts;
class CompressionFilter {
constructor () {
this.send = new IdentityHandler();
this.receive = new IdentityHandler();
this.supportedMethods = compressionMethods;
this.send = defaultCompression;
this.receive = defaultCompression;
this.accepts = defaultAcceptedEncoding;
}
sendMetadata (metadata) { // eslint-disable-line class-methods-use-this
// TODO: These values shouldn't be hard coded.
metadata.set(kGrpcEncodingHeader, 'identity');
metadata.set(kGrpcAcceptEncodingHeader, 'identity,deflate,gzip');
return metadata;
sendHeaders () {
return {
[kGrpcEncodingHeader]: this.send.name,
[kGrpcAcceptEncodingHeader]: this.accepts.join(',')
};
}

@@ -154,5 +217,26 @@

this.receive = getCompressionHandler(encoding);
if (encoding !== this.receive.name) {
this.receive = this.supportedMethods.getInstance(encoding);
}
}
const acceptedEncoding = metadata.get(kGrpcAcceptEncodingHeader);
if (acceptedEncoding.length > 0) {
this.accepts = acceptedEncoding;
}
// Check that the client supports the incoming compression type.
if (this.accepts.includes(this.receive.name)) {
if (this.send.name !== this.receive.name) {
this.send = this.supportedMethods.getInstance(this.receive.name);
}
} else {
// The client does not support this compression type, so send
// back uncompressed data.
if (this.send.name !== 'identity') {
this.send = this.supportedMethods.getInstance(this.receive.name);
}
}
metadata.remove(kGrpcEncodingHeader);

@@ -159,0 +243,0 @@ metadata.remove(kGrpcAcceptEncodingHeader);

13

lib/server-call.js

@@ -43,11 +43,6 @@ 'use strict';

let headers;
const custom = customMetadata ? customMetadata.toHttp2Headers() : null;
const headers = Object.assign(this.compression.sendHeaders(),
defaultResponseHeaders, custom);
if (customMetadata) {
headers = Object.assign({}, defaultResponseHeaders,
customMetadata.toHttp2Headers());
} else {
headers = defaultResponseHeaders;
}
this.stream.once('wantTrailers', onWantTrailers.bind(this));

@@ -227,3 +222,3 @@ this.stream.respond(headers, defaultResponseOptions);

[kGrpcStatusHeader]: this.status.code,
[kGrpcMessageHeader]: this.status.details
[kGrpcMessageHeader]: encodeURI(this.status.details)
};

@@ -230,0 +225,0 @@ const metadata = this.status.metadata;

{
"name": "grpc-server-js",
"version": "0.0.4",
"version": "0.0.5",
"description": "Pure JavaScript gRPC Server",

@@ -5,0 +5,0 @@ "author": "Colin J. Ihrig <cjihrig@gmail.com> (http://www.cjihrig.com/)",

@@ -10,8 +10,34 @@ # grpc-server-js

## Public API Deviations from `grpc.Server`
## Documentation
The goal is to be largely compatible with the existing [`Server`](https://grpc.io/grpc/node/grpc.Server.html) and [`ServerCredentials`](https://grpc.io/grpc/node/grpc.ServerCredentials.html) documentation.
## Features
- Unary calls.
- Streaming client request calls.
- Streaming server response calls.
- Bidirectional streaming calls.
- Deadline and cancellation support.
- Support for gzip and deflate compression, as well as uncompressed messages.
- The only third party dependency is [`@grpc/grpc-js`](https://www.npmjs.com/package/@grpc/grpc-js), which is used for some shared data structures.
- No C++ dependencies. This implementation relies on Node's [`http2`](https://nodejs.org/api/http2.html) module.
## Public API Deviations from the Existing `grpc.Server`
- `Server.prototype.bind()` is an `async` function.
- The deprecated `Server.prototype.addProtoService()` is not implemented.
- `Server.prototype.addHttp2Port()` is not implemented.
- `Server.prototype.forceShutdown()` is not implemented.
- The `private_key` and `cert_chain` properties of `keyCertPair` instances have
been renamed to `privateKey` and `certChain`.
## Acknowledgement
This module is heavily inspired by the [`grpc`](https://www.npmjs.com/package/grpc) native module. Some of the source code is adapted from the [`@grpc/grpc-js`](https://www.npmjs.com/package/@grpc/grpc-js) module.
## Useful References
- [What is gRPC?](https://grpc.io/docs/guides/index.html)
- [gRPC over HTTP2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md)
- [gRPC Compression](https://github.com/grpc/grpc/blob/master/doc/compression.md)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc