public static WSHttpRequest ProcessHandShakeData(byte[] data, int offset, int size) { string body = Encoding.ASCII.GetString(data, offset, size); Match match = ProtoConfig.REQUEST_REGEX.Match(body); if (!match.Success) { return(null); } WSHttpRequest request = new WSHttpRequest { method = match.Groups["method"].Value, path = match.Groups["path"].Value, body = match.Groups["body"].Value }; CaptureCollection fields = match.Groups["field_name"].Captures; CaptureCollection values = match.Groups["field_value"].Captures; int count = fields.Count; for (int i = 0; i < count; i++) { string name = fields[i].ToString(); string value = values[i].ToString(); request.headers[name] = value; } return(request); }
public static byte[] ProcessHybi13Handshake(WSHttpRequest request, string subProtocol) { StringBuilder builder = new StringBuilder(); builder.Append("HTTP/1.1 101 Switching Protocols\r\n"); builder.Append("Upgrade: websocket\r\n"); builder.Append("Connection: Upgrade\r\n"); if (!string.IsNullOrEmpty(subProtocol)) { builder.Append($"Sec-WebSocket-Protocol: {subProtocol}\r\n"); } string responseKey = Convert.ToBase64String( SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(request["Sec-WebSocket-Key"] + ProtoConfig.WSRespGuid))); builder.Append($"Sec-WebSocket-Accept: {responseKey}\r\n"); builder.Append("\r\n"); // Logger.Info( builder.ToString() ); return(Encoding.ASCII.GetBytes(builder.ToString())); }
protected override void ProcessData(StreamBuffer cache) { while (true) { if (cache.length == 0) { break; } if (!this._handshakeComplete) { WSHttpRequest request = WSHelper.ProcessHandShakeData(cache.GetBuffer(), 0, cache.length); if (request == null) { break; } //Logger.Log( request ); string subProtocol = WSHelper.Negotiate(this.subProtocols, request.subProtocols); byte[] responseData = WSHelper.ProcessHybi13Handshake(request, subProtocol); if (responseData == null) { break; } this._handshakeComplete = true; this.SendWithoutHeader(responseData, 0, responseData.Length); cache.Clear(); NetEvent netEvent = NetworkMgr.instance.PopEvent(); netEvent.type = NetEvent.Type.Establish; netEvent.session = this.session; NetworkMgr.instance.PushEvent(netEvent); break; } { bool isEof = WSHelper.ProcessClientData(cache.GetBuffer(), 0, cache.length, this._readState, out int len, out WSOPCode op); if (len < 0) //载体没有读取完 { break; } //截断当前缓冲区 cache.Strip(len, cache.length - len); if (isEof) //分片已结束 { if (op == WSOPCode.Close) { //到这里代表连接关闭了 this._readState.Clear(); this.OnError("client closed"); break; } byte[] data = this._readState.ToArray(); this._readState.Clear(); NetEvent netEvent = NetworkMgr.instance.PopEvent(); netEvent.type = NetEvent.Type.Recv; netEvent.session = this.session; netEvent.data = data; NetworkMgr.instance.PushEvent(netEvent); } } } }