<commit_before>package com.worlize.websocket
{
	import com.adobe.crypto.SHA1;
	import com.adobe.net.URI;
	import com.adobe.net.URIEncodingBitmap;
	import com.hurlant.crypto.tls.TLSConfig;
	import com.hurlant.crypto.tls.TLSEngine;
	import com.hurlant.crypto.tls.TLSSecurityParameters;
	import com.hurlant.crypto.tls.TLSSocket;
	import com.wirelust.as3zlib.Deflate;
	import com.wirelust.as3zlib.Inflate;
	import com.wirelust.as3zlib.JZlib;
	import com.wirelust.as3zlib.ZStream;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import flash.utils.IDataInput;
	import flash.utils.Timer;
	
	import flashx.textLayout.debug.assert;
	
	import mx.utils.Base64Encoder;
	import mx.utils.URLUtil;
	
	[Event(name="connectionFail",type="com.worlize.websocket.WebSocketErrorEvent")]
	[Event(name="message",type="com.worlize.websocket.WebSocketEvent")]
	[Event(name="open",type="com.worlize.websocket.WebSocketEvent")]
	[Event(name="closed",type="com.worlize.websocket.WebSocketEvent")]
	public class WebSocket extends EventDispatcher
	{
		private static const MODE_UTF8:int = 0;
		private static const MODE_BINARY:int = 0;
		
		private static const MAX_HANDSHAKE_BYTES:int = 10 * 1024; // 10KiB
		
		private var _bufferedAmount:int = 0;
		
		private var _readyState:int;
		private var _uri:URI;
		private var _protocol:String;
		private var _host:String;
		private var _port:uint;
		private var _resource:String;
		private var _secure:Boolean;
		private var _origin:String;
		
		private var rawSocket:Socket;
		private var socket:Socket;
		private var timeout:uint;
		
		private var nonce:ByteArray;
		private var base64nonce:String;
		private var serverHandshakeResponse:String;
		private var serverExtensions:Array;
		private var currentFrame:WebSocketFrame;
		private var frameQueue:Vector.<WebSocketFrame>;
		private var fragmentationOpcode:int = 0;
		
		private var waitingForServerClose:Boolean = false;
		private var closeTimeout:int = 5000;
		private var closeTimer:Timer;
		
		private var handshakeBytesReceived:int;
		private var handshakeTimer:Timer;
		private var handshakeTimeout:int = 5000;
		
		private var deflateStream:Boolean = false;
		private var zstreamOut:ZStream;
		private var zstreamIn:ZStream;
		
		private var incomingBuffer:ByteArray;
		private var outgoingBuffer:ByteArray;
		
		private var tlsConfig:TLSConfig;
		private var tlsSocket:TLSSocket;
		
		private var URIpathExcludedBitmap:URIEncodingBitmap =
			new URIEncodingBitmap(URI.URIpathEscape);
		
		public var enableDeflateStream:Boolean = true;
		
		public var config:WebSocketConfig = new WebSocketConfig();
		
		public static var debug:Boolean = false;
		
		public static var logger:Function = function(text:String):void {
			trace(text);
		};
		
		public function WebSocket(uri:String, origin:String, protocol:String = null, timeout:uint = 10000)
		{
			super(null);
			_uri = new URI(uri);
			_protocol = protocol;
			_origin = origin;
			this.timeout = timeout;
			this.handshakeTimeout = timeout;
			init();
		}
		
		private function init():void {
			parseUrl();

			closeTimer = new Timer(closeTimeout, 1);
			closeTimer.addEventListener(TimerEvent.TIMER, handleCloseTimer);
			
			handshakeTimer = new Timer(handshakeTimeout, 1);
			handshakeTimer.addEventListener(TimerEvent.TIMER, handleHandshakeTimer);
			
			rawSocket = socket = new Socket();
			socket.timeout = timeout;
			
			if (secure) {
				tlsConfig = new TLSConfig(TLSEngine.CLIENT,
										  null, null, null, null, null,
										  TLSSecurityParameters.PROTOCOL_VERSION);
				tlsConfig.trustAllCertificates = true;
				tlsConfig.ignoreCommonNameMismatch = true;
				socket = tlsSocket = new TLSSocket();
			}
			
			rawSocket.addEventListener(Event.CONNECT, handleSocketConnect);
			rawSocket.addEventListener(Event.CLOSE, handleSocketClose);
			rawSocket.addEventListener(IOErrorEvent.IO_ERROR, handleSocketIOError);
			rawSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSocketSecurityError);
			
			socket.addEventListener(ProgressEvent.SOCKET_DATA, handleSocketData);
			
			_readyState = WebSocketState.INIT;
		}
		
		public function connect():void {
			if (_readyState === WebSocketState.INIT || _readyState === WebSocketState.CLOSED) {
				_readyState = WebSocketState.CONNECTING;
				generateNonce();
				handshakeBytesReceived = 0;
				
				rawSocket.connect(_host, _port);
				if (debug) {
					logger("Connecting to " + _host + " on port " + _port);
				}
			}
		}
		
		private function parseUrl():void {
			_host = _uri.authority;
			var scheme:String = _uri.scheme.toLocaleLowerCase();
			if (scheme === 'wss') {<commit_msg>Adding additional subprotocol format verification.<commit_after>package com.worlize.websocket
{
	import com.adobe.crypto.SHA1;
	import com.adobe.net.URI;
	import com.adobe.net.URIEncodingBitmap;
	import com.hurlant.crypto.tls.TLSConfig;
	import com.hurlant.crypto.tls.TLSEngine;
	import com.hurlant.crypto.tls.TLSSecurityParameters;
	import com.hurlant.crypto.tls.TLSSocket;
	import com.wirelust.as3zlib.Deflate;
	import com.wirelust.as3zlib.Inflate;
	import com.wirelust.as3zlib.JZlib;
	import com.wirelust.as3zlib.ZStream;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import flash.utils.IDataInput;
	import flash.utils.Timer;
	
	import flashx.textLayout.debug.assert;
	
	import mx.utils.Base64Encoder;
	import mx.utils.URLUtil;
	
	[Event(name="connectionFail",type="com.worlize.websocket.WebSocketErrorEvent")]
	[Event(name="message",type="com.worlize.websocket.WebSocketEvent")]
	[Event(name="open",type="com.worlize.websocket.WebSocketEvent")]
	[Event(name="closed",type="com.worlize.websocket.WebSocketEvent")]
	public class WebSocket extends EventDispatcher
	{
		private static const MODE_UTF8:int = 0;
		private static const MODE_BINARY:int = 0;
		
		private static const MAX_HANDSHAKE_BYTES:int = 10 * 1024; // 10KiB
		
		private var _bufferedAmount:int = 0;
		
		private var _readyState:int;
		private var _uri:URI;
		private var _protocol:String;
		private var _host:String;
		private var _port:uint;
		private var _resource:String;
		private var _secure:Boolean;
		private var _origin:String;
		
		private var rawSocket:Socket;
		private var socket:Socket;
		private var timeout:uint;
		
		private var nonce:ByteArray;
		private var base64nonce:String;
		private var serverHandshakeResponse:String;
		private var serverExtensions:Array;
		private var currentFrame:WebSocketFrame;
		private var frameQueue:Vector.<WebSocketFrame>;
		private var fragmentationOpcode:int = 0;
		
		private var waitingForServerClose:Boolean = false;
		private var closeTimeout:int = 5000;
		private var closeTimer:Timer;
		
		private var handshakeBytesReceived:int;
		private var handshakeTimer:Timer;
		private var handshakeTimeout:int = 5000;
		
		private var deflateStream:Boolean = false;
		private var zstreamOut:ZStream;
		private var zstreamIn:ZStream;
		
		private var incomingBuffer:ByteArray;
		private var outgoingBuffer:ByteArray;
		
		private var tlsConfig:TLSConfig;
		private var tlsSocket:TLSSocket;
		
		private var URIpathExcludedBitmap:URIEncodingBitmap =
			new URIEncodingBitmap(URI.URIpathEscape);
		
		public var enableDeflateStream:Boolean = true;
		
		public var config:WebSocketConfig = new WebSocketConfig();
		
		public static var debug:Boolean = false;
		
		public static var logger:Function = function(text:String):void {
			trace(text);
		};
		
		public function WebSocket(uri:String, origin:String, protocol:String = null, timeout:uint = 10000)
		{
			super(null);
			_uri = new URI(uri);
			_protocol = protocol;
			_origin = origin;
			this.timeout = timeout;
			this.handshakeTimeout = timeout;
			init();
		}
		
		private function init():void {
			parseUrl();
			
			validateProtocol();

			closeTimer = new Timer(closeTimeout, 1);
			closeTimer.addEventListener(TimerEvent.TIMER, handleCloseTimer);
			
			handshakeTimer = new Timer(handshakeTimeout, 1);
			handshakeTimer.addEventListener(TimerEvent.TIMER, handleHandshakeTimer);
			
			rawSocket = socket = new Socket();
			socket.timeout = timeout;
			
			if (secure) {
				tlsConfig = new TLSConfig(TLSEngine.CLIENT,
										  null, null, null, null, null,
										  TLSSecurityParameters.PROTOCOL_VERSION);
				tlsConfig.trustAllCertificates = true;
				tlsConfig.ignoreCommonNameMismatch = true;
				socket = tlsSocket = new TLSSocket();
			}
			
			rawSocket.addEventListener(Event.CONNECT, handleSocketConnect);
			rawSocket.addEventListener(Event.CLOSE, handleSocketClose);
			rawSocket.addEventListener(IOErrorEvent.IO_ERROR, handleSocketIOError);
			rawSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSocketSecurityError);
			
			socket.addEventListener(ProgressEvent.SOCKET_DATA, handleSocketData);
			
			_readyState = WebSocketState.INIT;
		}
		
		private function validateProtocol():void {
			if (_protocol) {
				var separators:Array = [
					"(", ")", "<", ">", "@",
					",", ";", ":", "\\", "\"",
					"/", "[", "]", "?", "=",
					"{", "}", " ", String.fromCharCode(9)
				];
				for (var i:int = 0; i < _protocol.length; i++) {
					var charCode:int = _protocol.charCodeAt(i);
					var char:String = _protocol.charAt(i);
					if (charCode < 0x21 || charCode > 0x7E || separators.indexOf(char) !== -1) {
						throw new WebSocketError("Illegal character '" + String.fromCharCode(char) + "' in subprotocol.");
					}
				}
			}
		}
		
		public function connect():void {
			if (_readyState === WebSocketState.INIT || _readyState === WebSocketState.CLOSED) {
				_readyState = WebSocketState.CONNECTING;
				generateNonce();
				handshakeBytesReceived = 0;
				
				rawSocket.connect(_host, _port);
				if (debug) {
					logger("Connecting to " + _host + " on port " + _port);
				}
			}
		}
		
		private function parseUrl():void {
			_host = _uri.authority;
			var scheme:String = _uri.scheme.toLocaleLowerCase();
			if (scheme === 'wss') {
{'fraction_non_alphanumeric': 0.10440613026819924, 'fraction_numerical': 0.008045977011494253, 'mean_word_length': 4.407042982910409, 'pattern_counts': {'":': 1, '<': 8, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '973498', 'n_tokens_mistral': 3837, 'n_tokens_neox': 3195, 'n_words': 670}