You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
| import fetch from 'node-fetch';
 | |
| import https from 'https';
 | |
| 
 | |
| import { Snode } from './snodePool';
 | |
| 
 | |
| import { lokiOnionFetch, SnodeResponse } from './onions';
 | |
| 
 | |
| const snodeHttpsAgent = new https.Agent({
 | |
|   rejectUnauthorized: false,
 | |
| });
 | |
| 
 | |
| async function lokiPlainFetch(
 | |
|   url: string,
 | |
|   fetchOptions: any
 | |
| ): Promise<boolean | SnodeResponse> {
 | |
|   const { log } = window;
 | |
| 
 | |
|   if (url.match(/https:\/\//)) {
 | |
|     // import that this does not get set in lokiFetch fetchOptions
 | |
|     fetchOptions.agent = snodeHttpsAgent;
 | |
|     process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
 | |
|   } else {
 | |
|     log.debug('lokirpc:::lokiFetch - http communication', url);
 | |
|   }
 | |
|   const response = await fetch(url, fetchOptions);
 | |
|   // restore TLS checking
 | |
|   process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
 | |
| 
 | |
|   if (!response.ok) {
 | |
|     throw new window.textsecure.HTTPError('Loki_rpc error', response);
 | |
|   }
 | |
|   const result = await response.text();
 | |
| 
 | |
|   return {
 | |
|     body: result,
 | |
|     status: response.status,
 | |
|   };
 | |
| }
 | |
| 
 | |
| interface FetchOptions {
 | |
|   method: string;
 | |
| }
 | |
| 
 | |
| // A small wrapper around node-fetch which deserializes response
 | |
| // returns nodeFetch response or false
 | |
| async function lokiFetch(
 | |
|   url: string,
 | |
|   options: FetchOptions,
 | |
|   targetNode?: Snode
 | |
| ): Promise<boolean | SnodeResponse> {
 | |
|   const timeout = 10000;
 | |
|   const method = options.method || 'GET';
 | |
| 
 | |
|   const fetchOptions: any = {
 | |
|     ...options,
 | |
|     timeout,
 | |
|     method,
 | |
|   };
 | |
| 
 | |
|   try {
 | |
|     // Absence of targetNode indicates that we want a direct connection
 | |
|     // (e.g. to connect to a seed node for the first time)
 | |
|     if (window.lokiFeatureFlags.useOnionRequests && targetNode) {
 | |
|       return await lokiOnionFetch(fetchOptions.body, targetNode);
 | |
|     }
 | |
| 
 | |
|     return await lokiPlainFetch(url, fetchOptions);
 | |
|   } catch (e) {
 | |
|     if (e.code === 'ENOTFOUND') {
 | |
|       throw new window.textsecure.NotFoundError('Failed to resolve address', e);
 | |
|     }
 | |
|     throw e;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Wrapper for a JSON RPC request
 | |
| // Annoyngly, this is used for Lokid requests too
 | |
| export async function snodeRpc(
 | |
|   method: string,
 | |
|   params: any,
 | |
|   targetNode: Snode
 | |
| ): Promise<boolean | SnodeResponse> {
 | |
|   const url = `https://${targetNode.ip}:${targetNode.port}/storage_rpc/v1`;
 | |
| 
 | |
|   // TODO: The jsonrpc and body field will be ignored on storage server
 | |
|   if (params.pubKey) {
 | |
|     // Ensure we always take a copy
 | |
|     // tslint:disable-next-line no-parameter-reassignment
 | |
|     params = {
 | |
|       ...params,
 | |
|       pubKey: window.getStoragePubKey(params.pubKey),
 | |
|     };
 | |
|   }
 | |
|   const body = {
 | |
|     jsonrpc: '2.0',
 | |
|     id: '0',
 | |
|     method,
 | |
|     params,
 | |
|   };
 | |
| 
 | |
|   const fetchOptions = {
 | |
|     method: 'POST',
 | |
|     body: JSON.stringify(body),
 | |
|     headers: {
 | |
|       'Content-Type': 'application/json',
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   return lokiFetch(url, fetchOptions, targetNode);
 | |
| }
 |