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.
		
		
		
		
		
			
		
			
	
	
		
			135 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			135 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											11 years ago
										 | /* vim: ts=4:sw=4:expandtab | ||
|  |  * | ||
|  |  * This program is free software: you can redistribute it and/or modify | ||
|  |  * it under the terms of the GNU Lesser General Public License as published by | ||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||
|  |  * (at your option) any later version. | ||
|  |  * | ||
|  |  * This program is distributed in the hope that it will be useful, | ||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||
|  |  * GNU Lesser General Public License for more details. | ||
|  |  * | ||
|  |  * You should have received a copy of the GNU Lesser General Public License | ||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||
|  |  */ | ||
|  | ;(function(){ | ||
|  |     'use strict'; | ||
|  | 
 | ||
|  |     /* | ||
|  |      * WebSocket-Resources | ||
|  |      * | ||
|  |      * Create a request-response interface over websockets using the | ||
|  |      * WebSocket-Resources sub-protocol[1]. | ||
|  |      * | ||
|  |      * var client = new WebSocketResource(socket, function(request) { | ||
|  |      *    request.respond(200, 'OK'); | ||
|  |      * }); | ||
|  |      * | ||
|  |      * client.sendRequest({ | ||
|  |      *    verb: 'PUT', | ||
|  |      *    path: '/v1/messages', | ||
|  |      *    body: '{ some: "json" }', | ||
|  |      *    success: function(message, status, request) {...}, | ||
|  |      *    error: function(message, status, request) {...} | ||
|  |      * }); | ||
|  |      * | ||
|  |      * 1. https://github.com/WhisperSystems/WebSocket-Resources
 | ||
|  |      * | ||
|  |      */ | ||
|  | 
 | ||
|  |     var Request = function(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) { | ||
|  |             var bits = new Uint32Array(2); | ||
|  |             window.crypto.getRandomValues(bits); | ||
|  |             this.id = dcodeIO.Long.fromBits(bits[0], bits[1], true); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     var IncomingWebSocketRequest = function(options) { | ||
|  |         var request = new Request(options); | ||
|  |         var socket = options.socket; | ||
|  | 
 | ||
|  |         this.verb = request.verb; | ||
|  |         this.path = request.path; | ||
|  |         this.body = request.body; | ||
|  | 
 | ||
|  |         this.respond = function(status, message) { | ||
|  |             socket.send( | ||
|  |                 new textsecure.protobuf.WebSocketMessage({ | ||
|  |                     type: textsecure.protobuf.WebSocketMessage.Type.RESPONSE, | ||
|  |                     response: { id: request.id, message: message, status: status } | ||
|  |                 }).encode().toArrayBuffer() | ||
|  |             ); | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  |     var outgoing = {}; | ||
|  |     var OutgoingWebSocketRequest = function(options, socket) { | ||
|  |         var request = new Request(options); | ||
|  |         outgoing[request.id] = request; | ||
|  |         socket.send( | ||
|  |             new textsecure.protobuf.WebSocketMessage({ | ||
|  |                 type: textsecure.protobuf.WebSocketMessage.Type.REQUEST, | ||
|  |                 request: { | ||
|  |                     verb : request.verb, | ||
|  |                     path : request.path, | ||
|  |                     body : request.body, | ||
|  |                     id   : request.id | ||
|  |                 } | ||
|  |             }).encode().toArrayBuffer() | ||
|  |         ); | ||
|  |     }; | ||
|  | 
 | ||
|  |     window.WebSocketResource = function(socket, handleRequest) { | ||
|  |         this.sendRequest = function(options) { | ||
|  |             return new OutgoingWebSocketRequest(options, socket); | ||
|  |         }; | ||
|  | 
 | ||
|  |         socket.onmessage = function(socketMessage) { | ||
|  |             var blob = socketMessage.data; | ||
|  |             var reader = new FileReader(); | ||
|  |             reader.onload = function() { | ||
|  |                 var message = textsecure.protobuf.WebSocketMessage.decode(reader.result); | ||
|  |                 if (message.type === textsecure.protobuf.WebSocketMessage.Type.REQUEST ) { | ||
|  |                     handleRequest( | ||
|  |                         new IncomingWebSocketRequest({ | ||
|  |                             verb   : message.request.verb, | ||
|  |                             path   : message.request.path, | ||
|  |                             body   : message.request.body, | ||
|  |                             id     : message.request.id, | ||
|  |                             socket : socket | ||
|  |                         }) | ||
|  |                     ); | ||
|  |                 } | ||
|  |                 else if (message.type === textsecure.protobuf.WebSocketMessage.Type.RESPONSE ) { | ||
|  |                     var response = message.response; | ||
|  |                     var request = outgoing[response.id]; | ||
|  |                     if (request) { | ||
|  |                         request.response = response; | ||
|  |                         var callback = request.error; | ||
|  |                         if (response.status >= 200 && response.status < 300) { | ||
|  |                             callback = request.success; | ||
|  |                         } | ||
|  | 
 | ||
|  |                         if (typeof callback === 'function') { | ||
|  |                             callback(response.message, response.status, request); | ||
|  |                         } | ||
|  |                     } else { | ||
|  |                         throw 'Received response for unknown request ' + message.response.id; | ||
|  |                     } | ||
|  |                 } | ||
|  |             }; | ||
|  |             reader.readAsArrayBuffer(blob); | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  | }()); |