Merge branch 'development' into channel_encryption

* development:
  Manually set the dns servers for windows
  Refactor local_loki_server
  Refactor rpc calls to its own function.

# Conflicts:
#	js/modules/loki_message_api.js
This commit is contained in:
sachaaaaa 2019-03-01 10:57:41 +11:00
commit 53b0574a1f
3 changed files with 99 additions and 85 deletions

View file

@ -30,10 +30,7 @@ const fetch = async (url, options = {}) => {
const method = options.method || 'GET';
const address = parse(url).hostname;
const doEncryptChannel =
address.endsWith('.snode') &&
options.headers &&
LOKI_EPHEMKEY_HEADER in options.headers;
const doEncryptChannel = address.endsWith('.snode');
if (doEncryptChannel) {
try {
// eslint-disable-next-line no-param-reassign
@ -42,7 +39,11 @@ const fetch = async (url, options = {}) => {
options.body
);
// eslint-disable-next-line no-param-reassign
options.headers['Content-Type'] = 'text/plain';
options.headers = {
...options.headers,
'Content-Type': 'text/plain',
[LOKI_EPHEMKEY_HEADER]: libloki.crypto.snodeCipher.getChannelPublicKeyHex(),
};
} catch (e) {
log.warn(`Could not encrypt channel for ${address}: `, e);
}
@ -90,6 +91,25 @@ const fetch = async (url, options = {}) => {
}
};
// Wrapper for a JSON RPC request
const rpc = (address, port, method, params, options = {}) => {
const headers = options.headers || {};
const url = `${address}${port}${endpointBase}`;
const body = {
method,
params,
};
const fetchOptions = {
method: 'POST',
...options,
body: JSON.stringify(body),
headers,
};
return fetch(url, fetchOptions);
};
// Will be raised (to 3?) when we get more nodes
const MINIMUM_SUCCESSFUL_REQUESTS = 2;
@ -109,22 +129,13 @@ class LokiMessageAPI {
const data64 = dcodeIO.ByteBuffer.wrap(data).toString('base64');
const p2pDetails = lokiP2pAPI.getContactP2pDetails(pubKey);
const body = {
method: 'store',
params: {
data: data64,
},
};
if (p2pDetails && (isPing || p2pDetails.isOnline)) {
try {
const port = p2pDetails.port ? `:${p2pDetails.port}` : '';
const url = `${p2pDetails.address}${port}${endpointBase}`;
const fetchOptions = {
method: 'POST',
body: JSON.stringify(body),
};
await fetch(url, fetchOptions);
await rpc(p2pDetails.address, port, 'store', {
data: data64,
});
lokiP2pAPI.setContactOnline(pubKey);
window.Whisper.events.trigger('p2pMessageSent', messageEventData);
return;
@ -155,16 +166,6 @@ class LokiMessageAPI {
// Something went horribly wrong
throw err;
}
const storageParams = {
pubKey,
ttl: ttl.toString(),
nonce,
timestamp: timestamp.toString(),
};
body.params = {
...body.params,
...storageParams,
};
const completedNodes = [];
const failedNodes = [];
@ -179,17 +180,16 @@ class LokiMessageAPI {
};
const doRequest = async nodeUrl => {
const url = `${nodeUrl}${this.messageServerPort}${endpointBase}`;
const fetchOptions = {
method: 'POST',
body: JSON.stringify(body),
headers: {
[LOKI_EPHEMKEY_HEADER]: libloki.crypto.snodeCipher.getChannelPublicKeyHex(),
},
const params = {
pubKey,
ttl: ttl.toString(),
nonce,
timestamp: timestamp.toString(),
data: data64,
};
try {
await fetch(url, fetchOptions);
await rpc(nodeUrl, this.messageServerPort, 'store', params);
nodeComplete(nodeUrl);
successfulRequests += 1;
@ -271,24 +271,18 @@ class LokiMessageAPI {
};
const doRequest = async (nodeUrl, nodeData) => {
const url = `${nodeUrl}${this.messageServerPort}${endpointBase}`;
const body = {
method: 'retrieve',
params: {
pubKey: ourKey,
lastHash: nodeData.lastHash,
},
};
const headers = {
[LOKI_EPHEMKEY_HEADER]: libloki.crypto.snodeCipher.getChannelPublicKeyHex(),
};
const fetchOptions = {
method: 'POST',
body: JSON.stringify(body),
headers,
const params = {
pubKey: ourKey,
lastHash: nodeData.lastHash,
};
try {
const result = await fetch(url, fetchOptions);
const result = await rpc(
nodeUrl,
this.messageServerPort,
'retrieve',
params
);
nodeComplete(nodeUrl);

View file

@ -4,6 +4,7 @@
const fetch = require('node-fetch');
const is = require('@sindresorhus/is');
const dns = require('dns');
const process = require('process');
// Will be raised (to 3?) when we get more nodes
const MINIMUM_SWARM_NODES = 1;
@ -42,6 +43,10 @@ class LokiSnodeAPI {
this.swarmsPendingReplenish = {};
this.ourSwarmNodes = {};
this.contactSwarmNodes = {};
// When we package lokinet with messenger we can ensure this ip is correct
if (process.platform === 'win32') {
dns.setServers(['127.0.0.1']);
}
}
async getMyLokiIp() {

View file

@ -1,6 +1,14 @@
const http = require('http');
const EventEmitter = require('events');
const STATUS = {
OK: 200,
BAD_REQUEST: 400,
NOT_FOUND: 404,
METHOD_NOT_ALLOWED: 405,
INTERNAL_SERVER_ERROR: 500,
};
class LocalLokiServer extends EventEmitter {
/**
* Creates an instance of LocalLokiServer.
@ -11,47 +19,54 @@ class LocalLokiServer extends EventEmitter {
this.server = http.createServer((req, res) => {
let body = [];
// Check endpoints
if (req.method === 'POST') {
req
.on('error', () => {
// Internal server error
res.statusCode = 500;
res.end();
})
.on('data', chunk => {
body.push(chunk);
})
.on('end', () => {
try {
body = Buffer.concat(body).toString();
} catch (e) {
// Error occurred while converting to string
res.statusCode = 500;
res.end();
}
const sendResponse = (statusCode, message = null) => {
const headers = message && {
'Content-Type': 'text/plain',
};
res.writeHead(statusCode, headers);
res.end(message);
};
// Check endpoints here
if (req.url === '/v1/storage_rpc') {
if (req.method !== 'POST') {
sendResponse(STATUS.METHOD_NOT_ALLOWED);
return;
}
// Check endpoints
req
.on('error', () => {
// Internal server error
sendResponse(STATUS.INTERNAL_SERVER_ERROR);
})
.on('data', chunk => {
body.push(chunk);
})
.on('end', () => {
try {
body = Buffer.concat(body).toString();
} catch (e) {
// Internal server error: failed to convert body to string
sendResponse(STATUS.INTERNAL_SERVER_ERROR);
}
// Check endpoints here
if (req.url === '/v1/storage_rpc') {
try {
const bodyObject = JSON.parse(body);
if (bodyObject.method !== 'store') {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Invalid endpoint!');
sendResponse(STATUS.NOT_FOUND, 'Invalid endpoint!');
return;
}
this.emit('message', bodyObject.params.data);
res.statusCode = 200;
res.end();
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Invalid endpoint!');
sendResponse(STATUS.OK);
} catch (e) {
// Bad Request: Failed to decode json
sendResponse(STATUS.BAD_REQUEST, 'Failed to decode JSON');
}
});
} else {
// Method Not Allowed
res.statusCode = 405;
res.end();
}
} else {
sendResponse(STATUS.NOT_FOUND, 'Invalid endpoint!');
}
});
});
}