| 
					
				 | 
			
			
				@@ -72,6 +72,9 @@ function handleError(call, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     status.metadata = error.metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var error_batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    error_batch[grpc.opType.SEND_INITIAL_METADATA] = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   error_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   call.startBatch(error_batch, function(){}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -115,6 +118,10 @@ function sendUnaryResponse(call, value, serialize, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     status.metadata = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    end_batch[grpc.opType.SEND_INITIAL_METADATA] = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    call.metadataSent = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end_batch[grpc.opType.SEND_MESSAGE] = serialize(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   call.startBatch(end_batch, function (){}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -136,6 +143,10 @@ function setUpWritable(stream, serialize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   stream.serialize = common.wrapIgnoreNull(serialize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   function sendStatus() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     var batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!stream.call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stream.call.metadataSent = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      batch[grpc.opType.SEND_INITIAL_METADATA] = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     batch[grpc.opType.SEND_STATUS_FROM_SERVER] = stream.status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     stream.call.startBatch(batch, function(){}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -239,6 +250,10 @@ function ServerWritableStream(call, serialize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function _write(chunk, encoding, callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* jshint validthis: true */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!this.call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    batch[grpc.opType.SEND_INITIAL_METADATA] = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.call.metadataSent = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   batch[grpc.opType.SEND_MESSAGE] = this.serialize(chunk); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   this.call.startBatch(batch, function(err, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -251,6 +266,23 @@ function _write(chunk, encoding, callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ServerWritableStream.prototype._write = _write; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function sendMetadata(responseMetadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* jshint validthis: true */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!this.call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.call.metadataSent = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var batch = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    batch[grpc.opType.SEND_INITIAL_METADATA] = responseMetadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.call.startBatch(batch, function(err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.emit('error', err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ServerWritableStream.prototype.sendMetadata = sendMetadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 util.inherits(ServerReadableStream, Readable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -339,6 +371,7 @@ function ServerDuplexStream(call, serialize, deserialize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ServerDuplexStream.prototype._read = _read; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ServerDuplexStream.prototype._write = _write; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ServerDuplexStream.prototype.sendMetadata = sendMetadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * Fully handle a unary call 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -348,12 +381,20 @@ ServerDuplexStream.prototype._write = _write; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function handleUnary(call, handler, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var emitter = new EventEmitter(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  emitter.sendMetadata = function(responseMetadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      call.metadataSent = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      batch[grpc.opType.SEND_INITIAL_METADATA] = responseMetadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      call.startBatch(batch, function() {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   emitter.on('error', function(error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     handleError(call, error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  emitter.metadata = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   waitForCancel(call, emitter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  batch[grpc.opType.SEND_INITIAL_METADATA] = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   batch[grpc.opType.RECV_MESSAGE] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   call.startBatch(batch, function(err, result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -392,8 +433,8 @@ function handleUnary(call, handler, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function handleServerStreaming(call, handler, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var stream = new ServerWritableStream(call, handler.serialize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   waitForCancel(call, stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  stream.metadata = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  batch[grpc.opType.SEND_INITIAL_METADATA] = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   batch[grpc.opType.RECV_MESSAGE] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   call.startBatch(batch, function(err, result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -419,13 +460,19 @@ function handleServerStreaming(call, handler, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function handleClientStreaming(call, handler, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var stream = new ServerReadableStream(call, handler.deserialize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  stream.sendMetadata = function(responseMetadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!call.metadataSent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      call.metadataSent = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      batch[grpc.opType.SEND_INITIAL_METADATA] = responseMetadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      call.startBatch(batch, function() {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   stream.on('error', function(error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     handleError(call, error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   waitForCancel(call, stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var metadata_batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  call.startBatch(metadata_batch, function() {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  stream.metadata = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   handler.func(stream, function(err, value, trailer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     stream.terminate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -449,9 +496,7 @@ function handleBidiStreaming(call, handler, metadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var stream = new ServerDuplexStream(call, handler.serialize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                       handler.deserialize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   waitForCancel(call, stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var metadata_batch = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  call.startBatch(metadata_batch, function() {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  stream.metadata = metadata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   handler.func(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -466,13 +511,10 @@ var streamHandlers = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * Constructs a server object that stores request handlers and delegates 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * incoming requests to those handlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @constructor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @param {function(string, Object<string, Array<Buffer>>): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           Object<string, Array<Buffer|string>>=} getMetadata Callback that gets 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- *     metatada for a given method 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @param {Object=} options Options that should be passed to the internal server 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  *     implementation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function Server(getMetadata, options) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function Server(options) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   this.handlers = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var handlers = this.handlers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var server = new grpc.Server(options); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -525,11 +567,7 @@ function Server(getMetadata, options) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         call.startBatch(batch, function() {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var response_metadata = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (getMetadata) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        response_metadata = getMetadata(method, metadata); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      streamHandlers[handler.type](call, handler, response_metadata); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      streamHandlers[handler.type](call, handler, metadata); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     server.requestCall(handleNewCall); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 |