docs: function (req, res) {
  		LOG.warn('handle_request');
  
  		// attach custom res methods (borrowed from express)
  		res = UTIL.mixin(res, response);
  
  		LOG.sys('HTTP req received, header', 'SR.REST');
  		LOG.sys(req.headers, 'SR.REST');
  		
  		var content_type = req.headers['content-type'];
  
  		// NOTE: multi-part needs to be handled first, because req.on('data') will not be able to process correctly
  		if (typeof content_type === 'string' && content_type.startsWith('multipart/form-data; boundary=')) { 
  			LOG.warn('parsing form request...', 'SR.REST');
  			route(req, res);
  			return;
  		}
  		
  		// temp buffer for incoming request
  		var data = '';
  		var JSONobj = undefined;
  		
  		req.on('data', function (chunk) {
  			data += chunk;
  		});
  
  		req.on('end', function () {
  			
  			var JSONobj = undefined;
  			
  			try {
  				if (data !== '') {
  						
  					if (content_type.startsWith('application/x-www-form-urlencoded')) {
  						JSONobj = qs.parse(data);
  					} else if (content_type.startsWith('application/json')) {
  						JSONobj = UTIL.convertJSON(decodeURIComponent(data));
  					} else if (content_type.startsWith('application/sdp')) {
  						JSONobj = data;
  					} else {
  						var msg = 'content type not known: ' + content_type;
  						LOG.warn(msg, 'SR.REST');
  						SR.REST.reply(res, msg);
  						//res.writeHead(200, {'Content-Type': 'text/plain'});
  						//res.end(msg);
  						return;
  					}
  				}
  			} catch (e) {
  				var msg = 'JSON parsing error for data: ' + data + '\n content_type: ' + content_type;
  				LOG.error(msg, 'SR.REST');
  				//res.writeHead(200, {'Content-Type': 'text/plain'});
  				//res.end(msg);
  				SR.REST.reply(res, msg);
  				return;
  			}
  
  			route(req, res, JSONobj);
  		})
  	}