diff --git a/docs/client/api.html b/docs/client/api.html
index c0a1ac35dc..57b150328b 100644
--- a/docs/client/api.html
+++ b/docs/client/api.html
@@ -1401,20 +1401,20 @@ Contents of the result object:
- statusCode
- Number or null
+ Number
- Numeric HTTP result status code, or null on error.
-- headers()
- Object
-- Return a dictionary of HTTP headers from the response.
-
-- content()
+
- content
String
- - Return the body of the HTTP response as a string.
+- The body of the HTTP response as a string.
-- data()
+
- data
+ Object or null
+ - If the response headers indicate JSON content, this contains the body of the document parsed as a JSON object.
+
+- headers
Object
-- Return the body of the document parsed as a JSON object.
+- A dictionary of HTTP headers from the response.
- error
Error
@@ -1446,6 +1446,11 @@ Example asynchronous HTTP call:
{{/better_markdown}}
+
+
+{{> api_box httphelpers}}
+
+
diff --git a/docs/client/api.js b/docs/client/api.js
index 831392779d..fa1b288f54 100644
--- a/docs/client/api.js
+++ b/docs/client/api.js
@@ -791,4 +791,11 @@ Template.api.httpcall = {
]
};
+Template.api.httphelpers = {
+ id: "meteor_http_helpers",
+ name: "Meteor.http.[get, post, put, del] (...)",
+ locus: "Anywhere",
+ descr: ["Convience shortcuts for `Meteor.http.call` with `method` argument specified."]
+};
+
diff --git a/docs/client/docs.js b/docs/client/docs.js
index 197c304868..329862d813 100644
--- a/docs/client/docs.js
+++ b/docs/client/docs.js
@@ -165,7 +165,11 @@ var toc = [
],
"Meteor.http", [
- "Meteor.http.call"
+ "Meteor.http.call",
+ {name: "Meteor.http.get", id: "meteor_http_helpers"},
+ {name: "Meteor.http.post", id: "meteor_http_helpers"},
+ {name: "Meteor.http.put", id: "meteor_http_helpers"},
+ {name: "Meteor.http.del", id: "meteor_http_helpers"}
]
],
diff --git a/packages/http/httpcall_client.js b/packages/http/httpcall_client.js
index b0f2b52bd5..cd124c7e95 100644
--- a/packages/http/httpcall_client.js
+++ b/packages/http/httpcall_client.js
@@ -111,24 +111,28 @@ Meteor.http = Meteor.http || {};
// no HTTP response
callback(new Error("network"));
} else {
+
var response = {};
response.statusCode = xhr.status;
- response.content = function() {
- return xhr.responseText;
- };
- response.data = function() {
- return JSON.parse(response.content());
- };
- response.headers = function () {
- var header_str = xhr.getAllResponseHeaders();
- var headers_raw = header_str.split(/\r?\n/);
- var headers = {};
- _.each(headers_raw, function (h) {
- var m = /^(.*?):(?:\s+)(.*)$/.exec(h);
- if (m && m.length === 3)
- headers[m[1].toLowerCase()] = m[2];
- });
- return headers;
+ response.content = xhr.responseText;
+
+ response.headers = {};
+ var header_str = xhr.getAllResponseHeaders();
+ var headers_raw = header_str.split(/\r?\n/);
+ _.each(headers_raw, function (h) {
+ var m = /^(.*?):(?:\s+)(.*)$/.exec(h);
+ if (m && m.length === 3)
+ response.headers[m[1].toLowerCase()] = m[2];
+ });
+
+ // only parse data if correct content type.
+ if (_.include(['application/json', 'text/javascript'],
+ response.headers['content-type'])) {
+ try {
+ response.data = JSON.parse(response.content);
+ } catch (err) {
+ response.data = null;
+ }
};
var error = null;
diff --git a/packages/http/httpcall_common.js b/packages/http/httpcall_common.js
index e6755e458a..61ee09239a 100644
--- a/packages/http/httpcall_common.js
+++ b/packages/http/httpcall_common.js
@@ -35,4 +35,19 @@ Meteor.http = Meteor.http || {};
return url;
};
-})();
\ No newline at end of file
+
+ Meteor.http.get = function (/* varargs */) {
+ return Meteor.http.call.apply(this, ["GET"].concat(_.toArray(arguments)));
+ };
+ Meteor.http.post = function (/* varargs */) {
+ return Meteor.http.call.apply(this, ["POST"].concat(_.toArray(arguments)));
+ };
+ Meteor.http.put = function (/* varargs */) {
+ return Meteor.http.call.apply(this, ["PUT"].concat(_.toArray(arguments)));
+ };
+ Meteor.http.del = function (/* varargs */) {
+ return Meteor.http.call.apply(this, ["DELETE"].concat(_.toArray(arguments)));
+ };
+
+
+})();
diff --git a/packages/http/httpcall_server.js b/packages/http/httpcall_server.js
index 83761eab1f..95c6dfe297 100644
--- a/packages/http/httpcall_server.js
+++ b/packages/http/httpcall_server.js
@@ -108,14 +108,17 @@ Meteor.http = Meteor.http || {};
response = {};
response.statusCode = res.statusCode;
- response.content = function() {
- return body;
- };
- response.data = function() {
- return JSON.parse(response.content());
- };
- response.headers = function () {
- return res.headers;
+ response.content = body;
+ response.headers = res.headers;
+
+ // only parse data if correct content type.
+ if (_.include(['application/json', 'text/javascript'],
+ response.headers['content-type'])) {
+ try {
+ response.data = JSON.parse(response.content);
+ } catch (err) {
+ response.data = null;
+ }
};
if (res.statusCode >= 400)
diff --git a/packages/http/httpcall_tests.js b/packages/http/httpcall_tests.js
index c0aa891dc8..ea881b516f 100644
--- a/packages/http/httpcall_tests.js
+++ b/packages/http/httpcall_tests.js
@@ -20,7 +20,7 @@ testAsyncMulti("httpcall - basic", [
test.equal(typeof result, "object");
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
// allow dropping of final ? (which mobile browsers seem to do)
var allowed = [expected_url];
@@ -105,7 +105,7 @@ testAsyncMulti("httpcall - failure", [
test.isFalse(error);
test.isTrue(result);
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.url, "/foo");
test.equal(data.method, "GET");
@@ -123,7 +123,7 @@ testAsyncMulti("httpcall - redirect", [
// should be redirected transparently to /foo
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.url, "/foo");
test.equal(data.method, "GET");
}));
@@ -142,7 +142,7 @@ testAsyncMulti("httpcall - redirect", [
if (followRedirects) {
// should be redirected transparently to /foo
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.url, "/foo");
test.equal(data.method, "GET");
} else {
@@ -166,34 +166,29 @@ testAsyncMulti("httpcall - methods", [
function(test, expect) {
// non-get methods
- var test_method = function(meth, should_throw) {
- var maybe_expect = (should_throw ? _.identity : expect);
- var func = function() {
- Meteor.http.call(
- meth, url_prefix()+"/foo",
- maybe_expect(function(error, result) {
- test.isFalse(error);
- test.isTrue(result);
- test.equal(result.statusCode, 200);
- var data = result.data();
- test.equal(data.url, "/foo");
- // IE <= 8 turns seems to turn POSTs with no body into
- // GETs, inexplicably.
- if (Meteor.is_client && $.browser.msie && $.browser.version <= 8
- && meth === "POST")
- meth = "GET";
- test.equal(data.method, meth);
- }));
- };
- if (should_throw)
- test.throws(func);
- else
- func();
+ var test_method = function(meth, func_name) {
+ func_name = func_name || meth.toLowerCase();
+ Meteor.http[func_name](
+ url_prefix()+"/foo",
+ expect(function(error, result) {
+ test.isFalse(error);
+ test.isTrue(result);
+ test.equal(result.statusCode, 200);
+ var data = result.data;
+ test.equal(data.url, "/foo");
+ // IE <= 8 turns seems to turn POSTs with no body into
+ // GETs, inexplicably.
+ if (Meteor.is_client && $.browser.msie && $.browser.version <= 8
+ && meth === "POST")
+ meth = "GET";
+ test.equal(data.method, meth);
+ }));
};
+ test_method("GET");
test_method("POST");
test_method("PUT");
- test_method("DELETE");
+ test_method("DELETE", 'del');
},
function(test, expect) {
@@ -205,7 +200,7 @@ testAsyncMulti("httpcall - methods", [
test.isFalse(error);
test.isTrue(result);
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.body, "Hello World!");
}));
@@ -216,7 +211,7 @@ testAsyncMulti("httpcall - methods", [
test.isFalse(error);
test.isTrue(result);
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.body, {greeting: "Hello World!"});
}));
}
@@ -239,7 +234,7 @@ testAsyncMulti("httpcall - http auth", [
test.isFalse(error);
test.isTrue(result);
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.url, "/login?"+password);
}));
@@ -264,7 +259,7 @@ testAsyncMulti("httpcall - headers", [
test.isTrue(result);
test.equal(result.statusCode, 200);
- var data = result.data();
+ var data = result.data;
test.equal(data.url, "/foo-with-headers");
test.equal(data.method, "GET");
test.equal(data.headers['test-header'], "Value");
@@ -278,8 +273,8 @@ testAsyncMulti("httpcall - headers", [
test.isTrue(result);
test.equal(result.statusCode, 201);
- test.equal(result.headers()['a-silly-header'], "Tis a");
- test.equal(result.headers()['another-silly-header'], "Silly place.");
+ test.equal(result.headers['a-silly-header'], "Tis a");
+ test.equal(result.headers['another-silly-header'], "Silly place.");
}));
}
]);
@@ -304,7 +299,7 @@ testAsyncMulti("httpcall - params", [
test.isTrue(result);
test.equal(result.statusCode, 200);
if (method !== "HEAD") {
- var data = result.data();
+ var data = result.data;
test.equal(data.method, method);
test.equal(data.url, expect_url);
test.equal(data.body, expect_body);
diff --git a/packages/http/test_responder.js b/packages/http/test_responder.js
index ce9569d132..c4070c9b08 100644
--- a/packages/http/test_responder.js
+++ b/packages/http/test_responder.js
@@ -63,6 +63,7 @@ var respond = function(req, res) {
response_string = JSON.stringify(response_data);
res.statusCode = 200;
+ res.setHeader("Content-Type", "application/json");
res.end(response_string);
});