Skip to content

Commit

Permalink
Support JSON over HTTP POST in prep for geolocation API
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenmcd committed Apr 10, 2017
1 parent 93ff254 commit da36fe1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
4 changes: 3 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@
*/
exports.createClient = function(options) {

var makeApiCall = require('./internal/make-api-call').inject(options || {});
options = options || {};
var makeApiCall = require('./internal/make-api-call').inject(options);

var makeApiMethod = function(apiConfig) {
return function(query, callback, customParams) {
query = apiConfig.validator(query);
query.supportsClientId = apiConfig.supportsClientId !== false;
query.method = apiConfig.method;
if (options.language && !query.language) {
query.language = options.language;
}
Expand Down
38 changes: 31 additions & 7 deletions lib/internal/make-api-call.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,17 @@ exports.inject = function(options) {
var useClientId = query.supportsClientId && clientId && clientSecret;
delete query.supportsClientId;

var requestUrl = formatRequestUrl(path, query, useClientId);
var method = query.method;
delete query.method;

var isPost = method == 'POST'
var postData = isPost ? query : null;
var requestUrl = formatRequestUrl(path, query, method, useClientId);

function rateLimitedGet() {
return requestQueue.add(function() {
return Task.start(function(resolve, reject) {
return makeUrlRequest(requestUrl, resolve, reject);
return makeUrlRequest(requestUrl, resolve, reject, postData);
});
});
}
Expand All @@ -93,6 +98,7 @@ exports.inject = function(options) {
until: function(response) {
return !(
response == null
|| response.status === 403 // Geolocation API only.
|| response.status === 500
|| response.status === 503
|| response.status === 504
Expand All @@ -103,12 +109,25 @@ exports.inject = function(options) {
jitter: retryOptions.jitter
});

// This function determines whether a response indicates success.
// All APIs' JSON responses contain a 'status' field which we use
// to determine if the response is successful, apart from the
// Geolocation API which uses HTTP POST for its request, and HTTP
// status codes for determining success.
var isSuccessResponse = function(response) {
if (!isPost) {
return response.status === 200 && (
response.json.status === 'OK' ||
response.json.status === 'ZERO_RESULTS');
} else {
return response.status === 200 || response.status === 404;
}
};

var task =
Task.race([timeoutTask, requestTask])
.thenDo(function(response) {
if (response.status === 200 && (
response.json.status === 'OK' ||
response.json.status === 'ZERO_RESULTS')) {
if (isSuccessResponse(response)) {
return Task.withValue(response);
} else {
return Task.withError(response);
Expand Down Expand Up @@ -144,7 +163,7 @@ exports.inject = function(options) {
* @param {boolean} useClientId
* @return {string} The formatted URL.
*/
function formatRequestUrl(path, query, useClientId) {
function formatRequestUrl(path, query, method, useClientId) {
if (channel) {
query.channel = channel;
}
Expand All @@ -156,10 +175,15 @@ exports.inject = function(options) {
throw 'Missing either a valid API key, or a client ID and secret';
}

var isPost = method == 'POST';
var requestUrl = url.format({
pathname: path,
query: query
query: isPost ? {key: query.key} : query
});
if (isPost) {
// Remove key from query for HTTP POST, since query is the JSON being posted.
delete query.key;
}

// When using client ID, generate and append the signature param.
if (useClientId) {
Expand Down
16 changes: 14 additions & 2 deletions lib/internal/make-url-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,19 @@ var version = require('../version');
* @param {function(?)} onError
* @return {function()}
*/
module.exports = function makeUrlRequest(url, onSuccess, onError) {
module.exports = function makeUrlRequest(url, onSuccess, onError, postData) {
var isPost = postData != null;
var options = parse(url);
options.headers = {
'User-Agent': 'GoogleGeoApiClientJS/' + version
};

var request = https.get(options, function(response) {
if (isPost) {
options.method = 'POST';
options.headers['content-type'] = 'application/json;';
}

var request = https.request(options, function(response) {

response.on('error', function(error) {
onError(error)
Expand Down Expand Up @@ -77,5 +83,11 @@ module.exports = function makeUrlRequest(url, onSuccess, onError) {
onError(error)
});

if (postData) {
request.write(JSON.stringify(postData));
}

request.end();

return function cancel() { request.abort(); };
};

0 comments on commit da36fe1

Please sign in to comment.