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.
		
		
		
		
		
			
		
			
				
	
	
		
			126 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
| /* global window, dcodeIO, textsecure */
 | |
| 
 | |
| // eslint-disable-next-line func-names
 | |
| (function() {
 | |
|   let server;
 | |
|   const EXHAUSTED_SNODES_RETRY_DELAY = 5000;
 | |
|   const NUM_CONCURRENT_CONNECTIONS = 3;
 | |
| 
 | |
|   function stringToArrayBufferBase64(string) {
 | |
|     return dcodeIO.ByteBuffer.wrap(string, 'base64').toArrayBuffer();
 | |
|   }
 | |
| 
 | |
|   const Response = function Response(options) {
 | |
|     this.verb = options.verb || options.type;
 | |
|     this.path = options.path || options.url;
 | |
|     this.body = options.body || options.data;
 | |
|     this.success = options.success;
 | |
|     this.error = options.error;
 | |
|     this.id = options.id;
 | |
| 
 | |
|     if (this.id === undefined) {
 | |
|       const bits = new Uint32Array(2);
 | |
|       window.crypto.getRandomValues(bits);
 | |
|       this.id = dcodeIO.Long.fromBits(bits[0], bits[1], true);
 | |
|     }
 | |
| 
 | |
|     if (this.body === undefined) {
 | |
|       this.body = null;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   const IncomingHttpResponse = function IncomingHttpResponse(options) {
 | |
|     const request = new Response(options);
 | |
| 
 | |
|     this.verb = request.verb;
 | |
|     this.path = request.path;
 | |
|     this.body = request.body;
 | |
| 
 | |
|     this.respond = (status, message) => {
 | |
|       // Mock websocket response
 | |
|       window.log.info(status, message);
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   window.HttpResource = function HttpResource(_server, opts = {}) {
 | |
|     server = _server;
 | |
|     let { handleRequest } = opts;
 | |
|     if (typeof handleRequest !== 'function') {
 | |
|       handleRequest = request => request.respond(404, 'Not found');
 | |
|     }
 | |
|     let connected = true;
 | |
|     this.calledStop = false;
 | |
|     let resolveStopPolling;
 | |
|     const stopPolling = new Promise(res => {
 | |
|       resolveStopPolling = res;
 | |
|     });
 | |
| 
 | |
|     this.handleMessage = (message, options = {}) => {
 | |
|       try {
 | |
|         const dataPlaintext = stringToArrayBufferBase64(message);
 | |
|         const messageBuf = textsecure.protobuf.WebSocketMessage.decode(
 | |
|           dataPlaintext
 | |
|         );
 | |
|         if (
 | |
|           messageBuf.type === textsecure.protobuf.WebSocketMessage.Type.REQUEST
 | |
|         ) {
 | |
|           handleRequest(
 | |
|             new IncomingHttpResponse({
 | |
|               verb: messageBuf.request.verb,
 | |
|               path: messageBuf.request.path,
 | |
|               body: messageBuf.request.body,
 | |
|               id: messageBuf.request.id,
 | |
|             }),
 | |
|             options
 | |
|           );
 | |
|         }
 | |
|       } catch (error) {
 | |
|         const info = {
 | |
|           message,
 | |
|           error: error.message,
 | |
|         };
 | |
|         window.log.warn('HTTP-Resources Failed to handle message:', info);
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     this.pollServer = async () => {
 | |
|       // This blocking call will return only when all attempts
 | |
|       // at reaching snodes are exhausted or a DNS error occured
 | |
|       try {
 | |
|         await server.startLongPolling(
 | |
|           NUM_CONCURRENT_CONNECTIONS,
 | |
|           stopPolling,
 | |
|           messages => {
 | |
|             connected = true;
 | |
|             messages.forEach(message => {
 | |
|               const { data } = message;
 | |
|               this.handleMessage(data);
 | |
|             });
 | |
|           }
 | |
|         );
 | |
|       } catch (e) {
 | |
|         // we'll try again anyway
 | |
|       }
 | |
| 
 | |
|       if (this.calledStop) {
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       connected = false;
 | |
|       // Exhausted all our snodes urls, trying again later from scratch
 | |
|       setTimeout(() => {
 | |
|         this.pollServer();
 | |
|       }, EXHAUSTED_SNODES_RETRY_DELAY);
 | |
|     };
 | |
| 
 | |
|     this.isConnected = function isConnected() {
 | |
|       return connected;
 | |
|     };
 | |
| 
 | |
|     this.close = () => {
 | |
|       this.calledStop = true;
 | |
|       resolveStopPolling(true);
 | |
|     };
 | |
|   };
 | |
| })();
 |