mirror of
https://github.com/DoctorMcKay/node-steamcommunity.git
synced 2025-03-14 06:50:06 +08:00
190 lines
5.2 KiB
JavaScript
190 lines
5.2 KiB
JavaScript
const {HttpResponse} = require('@doctormckay/stdlib/http'); // eslint-disable-line
|
|
const {betterPromise} = require('@doctormckay/stdlib/promises');
|
|
|
|
const SteamCommunity = require('../index.js');
|
|
|
|
/**
|
|
* @param {object} options
|
|
* @param {string} options.method
|
|
* @param {string} options.url
|
|
* @param {string} [options.source='']
|
|
* @param {object} [options.qs]
|
|
* @param {*} [options.body]
|
|
* @param {object} [options.form]
|
|
* @param {object} [options.multipartForm]
|
|
* @param {boolean} [options.json=false] - Controls whether the *REQUEST* should be sent as json.
|
|
* @param {boolean} [options.followRedirect=true]
|
|
* @param {boolean} [options.checkHttpError=true]
|
|
* @param {boolean} [options.checkCommunityError=true]
|
|
* @param {boolean} [options.checkTradeError=true]
|
|
* @param {boolean} [options.checkJsonError=true]
|
|
* @return {Promise<HttpResponse>}
|
|
*/
|
|
SteamCommunity.prototype.httpRequest = function(options) {
|
|
return betterPromise(async (resolve, reject) => {
|
|
let requestID = ++this._httpRequestID;
|
|
let source = options.source || '';
|
|
|
|
await betterPromise((resolve, reject) => {
|
|
if (!this.onPreHttpRequest || !this.onPreHttpRequest(requestID, source, options, (err) => {
|
|
err ? reject(err) : resolve();
|
|
})) {
|
|
// No pre-hook, or the pre-hook doesn't want to delay the request.
|
|
resolve();
|
|
}
|
|
});
|
|
|
|
let result = await this._httpClient.request({
|
|
method: options.method,
|
|
url: options.url,
|
|
queryString: options.qs,
|
|
headers: options.headers,
|
|
body: options.body,
|
|
urlEncodedForm: options.form,
|
|
multipartForm: options.multipartForm,
|
|
json: options.json,
|
|
followRedirects: options.followRedirect
|
|
});
|
|
|
|
let httpError = options.checkHttpError !== false && this._checkHttpError(result);
|
|
let communityError = !options.json && options.checkCommunityError !== false && this._checkCommunityError(result);
|
|
let tradeError = !options.json && options.checkTradeError !== false && this._checkTradeError(result);
|
|
let jsonError = options.json && options.checkJsonError !== false && !result.jsonBody ? new Error('Malformed JSON response') : null;
|
|
|
|
this.emit('postHttpRequest', {
|
|
requestID,
|
|
source,
|
|
options,
|
|
response: result,
|
|
body: result.textBody,
|
|
error: httpError || communityError || tradeError || jsonError || null,
|
|
httpError,
|
|
communityError,
|
|
tradeError,
|
|
jsonError
|
|
});
|
|
|
|
resolve(result);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @param {string|object} endpoint
|
|
* @param {object} [form]
|
|
* @private
|
|
*/
|
|
SteamCommunity.prototype._myProfile = async function(endpoint, form) {
|
|
if (!this._profileURL) {
|
|
let result = await this.httpRequest({
|
|
method: 'GET',
|
|
url: 'https://steamcommunity.com/my',
|
|
followRedirect: false,
|
|
source: 'steamcommunity'
|
|
});
|
|
|
|
if (result.statusCode != 302) {
|
|
throw new Error(`HTTP error ${result.statusCode}`);
|
|
}
|
|
|
|
let match = result.headers.location.match(/steamcommunity\.com(\/(id|profiles)\/[^/]+)\/?/);
|
|
if (!match) {
|
|
throw new Error('Can\'t get profile URL');
|
|
}
|
|
|
|
this._profileURL = match[1];
|
|
setTimeout(() => {
|
|
delete this._profileURL; // delete the cache
|
|
}, 60000).unref();
|
|
}
|
|
|
|
let options = endpoint.endpoint ? endpoint : {};
|
|
options.url = `https://steamcommunity.com${this._profileURL}/${endpoint.endpoint || endpoint}`;
|
|
options.followRedirect = true;
|
|
|
|
if (form) {
|
|
options.method = 'POST';
|
|
options.form = form;
|
|
} else if (!options.method) {
|
|
options.method = 'GET';
|
|
}
|
|
|
|
options.source = 'steamcommunity';
|
|
|
|
return await this.httpRequest(options);
|
|
};
|
|
|
|
SteamCommunity.prototype._notifySessionExpired = function(err) {
|
|
this.emit('sessionExpired', err);
|
|
};
|
|
|
|
/**
|
|
* @param {HttpResponse} response
|
|
* @return {Error|boolean}
|
|
* @private
|
|
*/
|
|
SteamCommunity.prototype._checkHttpError = function(response) {
|
|
if (response.statusCode >= 300 && response.statusCode <= 399 && response.headers.location.indexOf('/login') != -1) {
|
|
let err = new Error('Not Logged In');
|
|
this._notifySessionExpired(err);
|
|
return err;
|
|
}
|
|
|
|
if (
|
|
response.statusCode == 403
|
|
&& typeof response.textBody == 'string'
|
|
&& response.textBody.match(/<div id="parental_notice_instructions">Enter your PIN below to exit Family View.<\/div>/)
|
|
) {
|
|
return new Error('Family View Restricted');
|
|
}
|
|
|
|
if (response.statusCode >= 400) {
|
|
let err = new Error(`HTTP error ${response.statusCode}`);
|
|
err.code = response.statusCode;
|
|
return err;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* @param {HttpResponse} response
|
|
* @return {Error|boolean}
|
|
* @private
|
|
*/
|
|
SteamCommunity.prototype._checkCommunityError = function(response) {
|
|
let html = response.textBody;
|
|
|
|
if (typeof html == 'string' && html.match(/<h1>Sorry!<\/h1>/)) {
|
|
let match = html.match(/<h3>(.+)<\/h3>/);
|
|
return new Error(match ? match[1] : 'Unknown error occurred');
|
|
}
|
|
|
|
if (typeof html == 'string' && html.indexOf('g_steamID = false;') > -1 && html.indexOf('<title>Sign In</title>') > -1) {
|
|
let err = new Error('Not Logged In');
|
|
this._notifySessionExpired(err);
|
|
return err;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* @param {HttpResponse} response
|
|
* @return {Error|boolean}
|
|
* @private
|
|
*/
|
|
SteamCommunity.prototype._checkTradeError = function(response) {
|
|
let html = response.textBody;
|
|
|
|
if (typeof html !== 'string') {
|
|
return false;
|
|
}
|
|
|
|
let match = html.match(/<div id="error_msg">\s*([^<]+)\s*<\/div>/);
|
|
if (match) {
|
|
return new Error(match[1].trim());
|
|
}
|
|
|
|
return false;
|
|
};
|