welsonjs/lib/http.js

495 lines
15 KiB
JavaScript
Raw Normal View History

2020-06-28 14:22:57 +00:00
////////////////////////////////////////////////////////////////////////
// HTTP API
////////////////////////////////////////////////////////////////////////
2020-12-07 08:33:12 +00:00
var FILE = require("lib/file");
2022-01-13 07:21:20 +00:00
var SHELL = require("lib/shell");
2020-06-28 14:22:57 +00:00
2022-01-13 07:21:20 +00:00
// UUID v4
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
var HTTPObject = function(engine) {
2020-11-10 09:13:41 +00:00
this.interface = null;
2020-11-25 06:10:02 +00:00
this.contentType = "application/x-www-form-urlencoded";
2020-11-10 09:13:41 +00:00
this.requestBody = "";
this.responseBody = null;
2020-11-26 08:13:13 +00:00
this.method = "GET";
2020-11-10 09:13:41 +00:00
this.headers = {};
2020-11-25 06:10:02 +00:00
this.parameters = {};
2020-11-26 08:13:13 +00:00
this.dataType = null;
2020-11-12 06:39:50 +00:00
this.userAgent = "WelsonJS/0.1.4-dev (https://github.com/gnh1201/welsonjs)";
2020-11-26 08:13:13 +00:00
this.isAsync = false;
2022-01-13 07:21:20 +00:00
this.engine = (typeof(engine) !== "undefined" ? engine : "MSXML");
this.cookie = null;
this.states = [];
2020-12-07 03:48:37 +00:00
2020-11-10 09:13:41 +00:00
this.create = function() {
2022-01-13 07:21:20 +00:00
if (this.engine == "MSXML") {
this.interface = CreateObject([
"Microsoft.XMLHTTP",
"WinHttp.WinHttpRequest.5.1",
"Msxml3.XMLHTTP",
"Msxml2.XMLHTTP",
"Msxml2.XMLHTTP.7.0",
"Msxml2.XMLHTTP.6.0",
"Msxml2.XMLHTTP.5.O",
"Msxml2.XMLHTTP.4.O",
"Msxml2.XMLHTTP.3.O",
"Msxml2.XMLHTTP.2.6",
"Msxml2.ServerXMLHTTP",
"Msxml2.ServerXMLHTTP.6.0",
"Msxml2.ServerXMLHTTP.5.0",
"Msxml2.ServerXMLHTTP.4.0",
"Msxml2.ServerXMLHTTP.3.0"
]);
} else if (this.engine == "CURL") {
this.interface = SHELL.create();
}
2020-11-10 09:13:41 +00:00
return this;
2020-11-26 08:13:13 +00:00
};
this.jqEnabled = function() {
return (typeof(window) !== "undefined" && typeof(window.jQuery) !== "undefined");
};
this.jqAjax = function(options) {
return (this.jqEnabled() ? window.jQuery.ajax(options) : null);
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.isJSONRequest = function() {
return (this.contentType === "application/json");
};
this.isJSONResponse = function() {
2020-12-07 08:33:12 +00:00
try {
if (this.dataType === "json") {
return true;
2022-01-13 07:21:20 +00:00
} else if (this.engine == "MSXML") {
2020-12-07 08:33:12 +00:00
var headers = this.getHeaders();
for (var key in headers) {
var _k = key.toLowerCase();
var _v = headers[key].toLowerCase();
if (_k === "content-type" && _v === "application/json") {
this.dataType = "json";
return true;
}
2020-11-10 09:13:41 +00:00
}
}
2020-12-07 08:33:12 +00:00
} catch (e) {
console.error("HTTPObject.isJSONResponse() -> ", e.message);
2020-11-10 09:13:41 +00:00
}
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
return false;
};
2020-06-28 14:22:57 +00:00
2022-01-13 07:21:20 +00:00
this.setEngine = function(engine) {
if (typeof(engine) == "string") {
this.engine = engine.toUpperCase();
} else {
this.engine = engine;
}
return this;
};
2020-11-10 09:13:41 +00:00
this.setMethod = function(method) {
this.method = method;
2022-01-13 07:21:20 +00:00
return this;
2020-11-10 09:13:41 +00:00
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.setDataType = function(type) {
this.dataType = type;
return this;
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.setContentType = function(type) {
this.contentType = type;
return this;
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.setRequestBody = function(data) {
this.requestBody = data;
return this;
2020-06-28 14:22:57 +00:00
}
2020-11-10 09:13:41 +00:00
this.setResponseBody = function(data) {
this.responseBody = data;
return this;
2020-11-05 05:09:20 +00:00
}
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.setHeader = function(key, value) {
2020-11-12 03:16:31 +00:00
this.headers[key] = value;
2020-11-10 09:13:41 +00:00
return this;
};
2022-01-13 07:21:20 +00:00
this.setCookie = function(cookie) {
this.cookie = cookie;
};
2020-11-10 09:13:41 +00:00
this.setHeaders = function(headers) {
2020-12-07 08:33:12 +00:00
try {
var headers = (typeof(headers) !== "undefined") ? headers : {};
for (var key in headers) {
var value = headers[key];
2022-01-13 07:21:20 +00:00
switch (key.toUpperCase()) {
case "CONTENT-TYPE":
this.setContentType(value.toLowerCase());
break;
case "COOKIE":
this.setCookie(value);
break;
default:
this.setHeader(key, value);
2020-12-07 08:33:12 +00:00
}
2020-11-10 09:13:41 +00:00
}
2020-12-07 08:33:12 +00:00
} catch (e) {
console.error("HTTPObject.setHeaders() -> ", e.message);
2020-11-10 09:13:41 +00:00
}
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
return this;
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.getHeader = function(key) {
2020-11-25 02:46:20 +00:00
try {
return this.interface.getResponseHeader(key);
} catch (e) {
2020-11-25 06:10:02 +00:00
console.error("HTTPObject.getHeader() -> ", e.message);
2020-11-25 02:46:20 +00:00
}
2020-11-10 09:13:41 +00:00
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.getHeaders = function() {
2020-11-25 02:46:20 +00:00
try {
var raw = this.interface.getAllResponseHeaders();
return raw.split(/[\r\n]+/).filter(function(s) {
return s.trim().length > 0;
}).map(function(s) {
return s.trim().split(": ");
}).reduce(function(acc, c) {
acc[c[0].trim()] = c[1].trim();
return acc;
}, {});
} catch (e) {
2020-11-25 06:10:02 +00:00
console.error("HTTPObject.getHeaders() -> ", e.message);
2020-11-25 02:46:20 +00:00
}
2020-11-10 09:13:41 +00:00
};
2020-11-05 05:32:27 +00:00
2020-11-25 06:10:02 +00:00
this.setParameter = function(key, value) {
this.parameters[key] = value;
return this;
};
this.getParameter = function(key) {
return this.parameters[key];
};
this.setParameters = function(params) {
2020-12-07 08:33:12 +00:00
try {
var params = (typeof(params) !== "undefined") ? params : {};
for (var key in params) {
var value = params[key];
this.setParameter(key, value);
}
} catch (e) {
console.error("HTTPObject.setParameters() -> ", e.message);
2020-11-25 06:10:02 +00:00
}
return this;
};
this.getParameters = function() {
return this.parameters;
};
2020-11-12 03:16:31 +00:00
this.setBearerAuth = function(token) {
this.setHeader("Authorization", "Bearer " + token);
return this;
};
this.setUseCache = function(flag) {
if (flag === false) {
this.setHeaders({
//"Pragma": "no-cache",
//"Cache-Control": "no-cache",
"If-Modified-Since": "Sat, 1 Jan 2000 00:00:00 GMT"
});
}
return this;
};
2020-11-26 08:13:13 +00:00
this.setUseAsync = function(flag) {
this.isAsync = flag;
return this;
}
2020-11-12 06:39:50 +00:00
this.setUserAgent = function(agent) {
2022-01-13 08:46:57 +00:00
this.userAgent = agent;
2022-01-13 07:21:20 +00:00
return this;
2020-11-12 06:39:50 +00:00
};
2020-11-25 06:10:02 +00:00
this.serialize = function() {
if (this.isJSONRequest() && typeof(this.requestBody) === "object") {
return JSON.stringify(this.requestBody);
} else if (typeof(requestBody) === "object") {
return this.serializeURL(this.requestBody);
} else {
return this.requestBody;
}
};
2022-01-03 04:17:00 +00:00
this.serializeURL = function(parametersObject) {
2020-11-25 06:10:02 +00:00
var str = [];
2022-01-03 04:17:00 +00:00
for (var k in parametersObject) {
if (parametersObject.hasOwnProperty(k)) {
str.push(encodeURIComponent(k) + "=" + encodeURIComponent(parametersObject[k]));
}
2020-11-25 06:10:02 +00:00
}
return str.join("&");
};
2022-01-03 04:17:00 +00:00
// Type 1: http://domain?a=1&b=2&c=3
// Type 2: http://domain/:a/:b/:c
2020-11-25 06:10:02 +00:00
this.serializeParameters = function(url) {
console.log(Object.keys(this.parameters).join(","));
2022-01-13 07:21:20 +00:00
// Bind parameters
2020-11-25 06:10:02 +00:00
if (Object.keys(this.parameters).length > 0) {
2022-01-03 04:17:00 +00:00
// Type 2
var parameters = {};
for (var k in this.parameters) {
if (url.indexOf(':' + k) > -1) {
url = url.replace(':' + k, this.parameters[k]);
2022-01-13 07:46:02 +00:00
} else if(this.parameters[k] == "{uuidv4}") {
2022-01-13 07:59:30 +00:00
parameters[k] = uuidv4(); // Generate UUID v4
} else {
2022-01-03 04:17:00 +00:00
parameters[k] = this.parameters[k];
}
}
// Type 1
if (Object.keys(parameters).length > 0) {
if (url.indexOf('?') > -1) {
url += '&' + this.serializeURL(parameters);
} else {
url += '?' + this.serializeURL(parameters);
}
2020-11-25 06:10:02 +00:00
}
}
console.log("Requested URL: " + url);
return url;
2020-11-25 06:10:02 +00:00
};
2020-11-26 08:13:13 +00:00
this.open = function(method, url) {
2022-01-13 07:21:20 +00:00
var url = this.serializeParameters(url);
2020-06-28 14:22:57 +00:00
2022-01-13 07:21:20 +00:00
this.setMethod(method.toUpperCase()); // set method
2022-01-13 08:46:57 +00:00
this.pushState(null, null, url); // push stat
this.setHeader("User-Agent", (this.userAgent != null ? this.userAgent : "")); // set user agent
2020-06-28 14:22:57 +00:00
2022-01-13 07:21:20 +00:00
try {
if (this.engine == "MSXML") {
switch (this.method) {
case "POST":
this.interface.open(method, url, this.isAsync);
break;
case "GET":
this.interface.open(method, url, this.isAsync);
break;
default:
console.error("Not supported HTTP method: " + method);
}
} else {
console.log("Selected engine: " + this.engine);
2020-11-25 02:46:20 +00:00
}
} catch (e) {
2020-11-25 06:10:02 +00:00
console.error("HTTPObject.open() -> ", e.message);
2020-11-10 09:13:41 +00:00
}
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
return this;
};
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
this.send = function(callback) {
2022-01-13 07:21:20 +00:00
var responseText = null;
if (this.contentType != null) {
this.setHeader("Content-Type", this.contentType);
}
2020-06-28 14:22:57 +00:00
2020-11-25 02:46:20 +00:00
try {
2022-01-13 07:21:20 +00:00
if (this.engine == "MSXML") {
for (var key in this.headers) {
this.interface.setRequestHeader(key, this.headers[key]);
}
switch (this.method) {
case "GET":
this.interface.send();
break;
default:
this.interface.send(this.serialize(this.requestBody));
}
2020-11-10 09:13:41 +00:00
2022-01-13 07:21:20 +00:00
// Waiting a response
while (this.interface.readyState < 4) sleep(100);
// Get response text
responseText = this.interface.responseText;
} else if (this.engine == "CURL") {
if (this.states.length > 0) {
// Make CURL context
var state = this.states[this.states.length - 1];
var cmd = ["bin\\curl", "-X", this.method];
2022-01-13 07:59:30 +00:00
var url = state.url;
2022-01-13 07:21:20 +00:00
2022-01-13 07:29:01 +00:00
if (Object.keys(this.headers).length > 0) {
2022-01-13 07:21:20 +00:00
for (var key in this.headers) {
var value = this.headers[key];
if (value != null) {
cmd.push("-H");
cmd.push(key + ": " + value);
}
}
}
if (this.cookie != null) {
cmd.push("-b");
cmd.push(this.cookie);
}
2022-01-13 08:46:57 +00:00
cmd.push("-A");
cmd.push((this.userAgent != null ? this.userAgent : ''));
2022-01-13 07:21:20 +00:00
2022-01-13 07:59:30 +00:00
var pos = url.indexOf('?');
if (pos > -1) {
cmd.push("-d");
cmd.push(state.url.substring(pos + 1));
cmd.push(state.url.substring(0, pos));
} else {
cmd.push(state.url);
}
2022-01-13 07:21:20 +00:00
// Get response text
responseText = this.interface.exec(cmd);
}
2020-12-07 03:48:37 +00:00
}
2022-01-13 07:21:20 +00:00
console.log("ResponseText: " + responseText);
2020-11-25 02:46:20 +00:00
if (this.isJSONResponse()) {
2020-12-07 08:33:12 +00:00
if (typeof(WScript) !== "undefined") {
JSON = {};
FILE.includeFile("app/assets/js/json2.js");
}
2022-01-13 07:21:20 +00:00
this.setResponseBody(JSON.parse(responseText));
2020-11-25 02:46:20 +00:00
} else {
2022-01-13 07:21:20 +00:00
this.setResponseBody(responseText);
2020-11-25 02:46:20 +00:00
}
2020-11-10 09:13:41 +00:00
2020-11-25 02:46:20 +00:00
if (typeof(callback) === "function") {
2020-12-07 08:33:12 +00:00
try {
callback(this.responseBody);
} catch (e) {
console.log("callback of HTTPObject.send() -> ", e.message);
}
2020-11-25 02:46:20 +00:00
}
} catch (e) {
2020-11-25 06:10:02 +00:00
console.error("HTTPObject.send() -> ", e.message);
2020-11-10 09:13:41 +00:00
}
2020-06-28 14:22:57 +00:00
2020-11-10 09:13:41 +00:00
return this;
};
this.post = function(url, callback) {
2020-11-26 08:13:13 +00:00
try {
return this.open("POST", url).send(callback);
} catch (e) {
console.error("HTTPObject.post() -> ", e.message);
}
2020-11-10 09:13:41 +00:00
};
this.get = function(url, callback) {
2020-11-26 08:13:13 +00:00
try {
2022-01-03 04:17:00 +00:00
if (this.jqEnabled()) {
return this.jqAjax({
2020-11-27 06:58:43 +00:00
type: "GET",
headers: this.headers,
2020-11-27 07:11:59 +00:00
url: this.serializeParameters(url),
2020-11-27 06:58:43 +00:00
data: this.requestBody,
contentType: this.contentType,
success: callback,
async: this.isAsync,
2022-01-03 04:17:00 +00:00
error: function(request, status, error) {
console.error("code: ", request.status, ", message: " + request.responseText + ", error: " + error);
}
});
} else {
return this.open("GET", url).send(callback);
}
2020-11-26 08:13:13 +00:00
} catch (e) {
console.error("HTTPObject.get() -> ", e.message);
}
2020-11-10 09:13:41 +00:00
};
2020-11-12 04:36:16 +00:00
this.patch = function(url, callback) {
2020-11-25 02:46:20 +00:00
try {
2020-11-26 08:13:13 +00:00
if (this.jqEnabled()) {
return this.jqAjax({
type: "PATCH",
headers: this.headers,
2020-11-27 07:11:59 +00:00
url: this.serializeParameters(url),
2020-11-26 08:13:13 +00:00
data: this.requestBody,
contentType: this.contentType,
success: callback,
2020-11-27 06:58:43 +00:00
async: this.isAsync,
error: function(request, status, error) {
2022-01-03 04:17:00 +00:00
console.error("code: ", request.status, ", message: " + request.responseText + ", error: " + error);
}
2020-11-26 08:13:13 +00:00
});
2020-11-12 04:36:16 +00:00
} else {
2020-11-26 08:13:13 +00:00
throw Error("PATCH does not supported on GUI mode");
2020-11-12 04:36:16 +00:00
}
2020-11-25 02:46:20 +00:00
} catch (e) {
2020-11-25 06:10:02 +00:00
console.error("HTTPObject.patch() -> ", e.message);
2020-11-25 02:46:20 +00:00
}
2020-11-12 04:36:16 +00:00
};
2022-01-13 07:21:20 +00:00
this.pushState = function(state, title, url) {
this.states.push({
"state": state,
"title": title,
"url": url
});
};
this.popState = function() {
return this.states.pop();
};
2020-11-12 04:36:16 +00:00
2020-11-10 09:13:41 +00:00
this.create();
2020-06-28 14:22:57 +00:00
};
2022-01-13 07:21:20 +00:00
exports.create = function(engine) {
return (new HTTPObject(engine));
2020-06-28 14:22:57 +00:00
};
2020-11-10 09:13:41 +00:00
2020-11-25 06:10:02 +00:00
exports.post = function(url, data, headers, params) {
return (new HTTPObject()).setHeaders(headers).setRequestBody(data).setParameters(params).post(url).responseBody;
};
2020-11-12 05:02:25 +00:00
exports.get = function(url, data, headers) {
2021-08-10 16:45:56 +00:00
return (new HTTPObject()).setHeaders(headers).setParameters(data).setUseCache(false).get(url).responseBody;
2020-11-25 06:10:02 +00:00
};
2020-11-12 05:02:25 +00:00
2022-01-13 07:21:20 +00:00
exports.VERSIONINFO = "HTTP Lib (http.js) version 0.3";
2020-11-10 09:13:41 +00:00
exports.global = global;
exports.require = global.require;