Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search Solr using POST instead of GET #129

Merged
merged 9 commits into from
Sep 7, 2015
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ docs/out
coverage.html
lib-cov
report
.idea
120 changes: 114 additions & 6 deletions lib/solr.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ function Client(options){
path : options.path || '/solr',
agent : options.agent,
secure : options.secure || false,
bigint : options.bigint || false
bigint : options.bigint || false,
get_max_request_entity_size: options.get_max_request_entity_size || 2048
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default it to false, so that this is not a breaking change
get_max_request_entity_size: options.get_max_request_entity_size || false

};

// Default paths of all request handlers
Expand Down Expand Up @@ -570,21 +571,72 @@ Client.prototype.get = function(handler,query,callback){
}

var fullPath = [this.options.path,this.options.core,handler + '?' + parameters + '&wt=json']
.filter(function(element){
return element;
})
.join('/');
.filter(function(element){
return element;
})
.join('/'),
approxUrlLength = 10 + this.options.host.length + (this.options.port+"").length + fullPath.length; // Buffer (10) accounts for protocol and special characters like ://, port colon, and initial slash etc

if (approxUrlLength <= this.options.get_max_request_entity_size) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if this.options.get_max_request_entity_size is truthy first to allow users to bypass this feature if they need to.
if(this.options.get_max_request_entity_size && approxUrlLength <= this.options.get_max_request_entity_size) {

var params = {
host: this.options.host,
port: this.options.port,
fullPath: fullPath,
secure: this.options.secure,
bigint: this.options.bigint,
authorization: this.options.authorization,
agent: this.options.agent
};
return getJSON(params, callback);
} else {

// Funnel this through a POST because it's too large
return this.post(handler, query, callback);
}
}

/**
* Send an arbitrary HTTP POST request to Solr on the specified `handler` (as Solr like to call it i.e path)
*
* @param {String} handler
* @param {Query|Object|String} [query]
* @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs
* @param {Error} callback().err
* @param {Object} callback().obj - JSON response sent by the Solr server deserialized
*
* @return {http.ClientRequest}
* @api public
*/
Client.prototype.post = function(handler,query,callback){

var parameters = '';
if(typeof query === 'function'){
callback = query;
}else if(query instanceof Query){
parameters += query.build();
}else if(typeof query === 'object'){
parameters += querystring.stringify(query);
}else if(typeof query === 'string'){
parameters += query;
}

var fullPath = [this.options.path,this.options.core, handler + '?wt=json']
.filter(function(element){
return element;
})
.join('/');

var params = {
host : this.options.host,
port : this.options.port,
fullPath : fullPath,
params : parameters,
secure : this.options.secure,
bigint : this.options.bigint,
authorization : this.options.authorization,
agent : this.options.agent
};
return getJSON(params,callback);
return postForm(params,callback);
}

/**
Expand Down Expand Up @@ -699,6 +751,62 @@ function postJSON(params,callback){
return request;
};

/**
* HTTP POST request. Send update commands to the Solr server using form encoding (e.g. search)
*
* @param {Object} params
* @param {String} params.host - IP address or host address of the Solr server
* @param {Number|String} params.port - port of the Solr server
* @param {String} params.core - name of the Solr core requested
* @param {String} params.authorization - value of the authorization header
* @param {String} params.fullPath - full path of the request
* @param {String} params.params - form params
* @param {Boolean} params.secure -
* @param {Boolean} params.bigint -
* @param {http.Agent} [params.agent] -
* @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs
* @param {Error} callback().err
* @param {Object} callback().obj - JSON response sent by the Solr server deserialized
*
* @return {http.ClientRequest}
* @api private
*/

function postForm(params,callback){
var headers = {
'content-type' : 'application/x-www-form-urlencoded; charset=utf-8',
'content-length': Buffer.byteLength(params.params),
'accept' : 'application/json; charset=utf-8'
};
if(params.authorization){
headers['authorization'] = params.authorization;
}
var options = {
host : params.host,
port : params.port,
method : 'POST',
headers : headers,
path : params.fullPath
};

if(params.agent !== undefined){
options.agent = params.agent;
}

var request = pickProtocol(params.secure).request(options);

request.on('response', handleJSONResponse(request, params.bigint, callback));

request.on('error',function onError(err){
if (callback) callback(err,null);
});

request.write(params.params);
request.end();

return request;
};

/**
* HTTP GET request. Send a query command to the Solr server (query)
*
Expand Down