-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathrequest.js
132 lines (114 loc) · 4.26 KB
/
request.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const https = require('https');
// Connection timeout, ms
let CONNECTION_TIMEOUT = 3000;
// error messages
const E_NOTFOUND = 'BTS not found';
const E_REQERROR = 'Request error';
/**
* Perform request to Location Service.
* Taken from https://github.com/kolonist/bscoords and modified to use https only.
*
* @param {object} options Node.js HTTPS request options.
* @param {*} request_body Request body for POST requests. Can be String or
* Buffer. If you do not need it you can pass null or
* empty string ''.
* @param {*} response_encoding Can be 'utf8' or 'hex' (for Google response).
* @param {*} response_parser Callback function(response) where `response` is
* String with data from Location server. Callback
* function should return object like
* `{lat: 23.12345, lon: 50.12345, range: 1000}` or
* null if there are no coordinates in the answer.
*/
const request = (options, request_body, response_encoding, response_parser) => {
return new Promise((resolve, reject) => {
const req = https.request(options, res => {
res.setEncoding(response_encoding);
// pick data
let buf = '';
res.on('data', chunk => buf += chunk);
// all data came
res.on('end', () => {
const coords = response_parser(buf);
if (coords !== null) {
return resolve(coords);
} else {
return reject(new Error(E_NOTFOUND));
}
});
});
req.on('socket', socket => {
socket.setTimeout(CONNECTION_TIMEOUT, () => req.abort());
});
req.on('error', err => reject(new Error(E_REQERROR)));
if (options.method === 'POST' && request_body !== null && request_body !== '') {
req.write(request_body);
}
req.end();
});
};
module.exports = {
/**
* Get geographical coordinates from OpenCellId.
* Taken from https://github.com/kolonist/bscoords and modified to parse range and code.
*
* @param {Number} mcc Mobile Country Code
* @param {Number} mnc Mobile Network Code
* @param {Number} lac Location area code
* @param {Number} cid Cell Identity
* @param {String} key OpenCellId API key
* @return {Promise} Object containing lat, lon, range and status code. If there is a severe error null.
*/
oci: function (mcc, mnc, lac, cid, key) {
const options = {
hostname: 'eu1.unwiredlabs.com',
method : 'POST',
path : '/v2/process.php'
};
const request_body = JSON.stringify({
token: key,
mcc: mcc,
mnc: mnc,
cells: [{
lac: lac,
cid: cid
}]
});
const response_encoding = 'utf8';
const response_parser = buf => {
try {
const answer = JSON.parse(buf);
if (answer.balance === 0) {
const coords = {
lat: 0,
lon: 0,
range: 0,
statusCode: 429,
balance: answer.balance
};
return coords;
} else if (answer.status === 'error') {
const coords = {
lat: 0,
lon: 0,
range: 0,
statusCode: 404,
balance: answer.balance
};
return coords;
} else {
const coords = {
lat: answer.lat,
lon: answer.lon,
range: answer.accuracy,
statusCode: 200,
balance: answer.balance
};
return coords;
}
} catch(err) {
return null;
}
};
return request(options, request_body, response_encoding, response_parser);
}
};