public const long MaxPayloadSize = 8388608; // 8 MB private void ProcessWebSocketData(WebSocketClient client, byte[] buffer, int offset, int length) { if (client.Buffer.Length + length > MaxWebSocketDataLength) { client.Disconnect("WebSocket buffer overflow"); return; } client.Buffer.Offset = client.Buffer.Length; client.Buffer.Write(buffer, offset, length); var header = new WebSocketHeader(); while (client.Buffer.Length > 0) { client.Buffer.Offset = 0; var result = header.Read(client.Buffer); if (result != WebSocketHeaderReadResult.Succeeded) { if (result != WebSocketHeaderReadResult.NeedMoreData) { client.Disconnect("WebSocket protocol error"); } break; } /*if (header.OpCode != WebSocketOpCode.Text && * header.OpCode ) * { * Logger.Log(LogType.Warning, "Unsupported WebSocket OpCode: {0}", header.OpCode); * webClient.Disconnect(); * break; * }*/ if (header.PayloadSize > MaxPayloadSize) { client.Disconnect("Too big websocket packet received. Payload size: " + header.PayloadSize); break; } if (!header.Masked) { client.Disconnect("WebSocket clients must send masked data."); break; } if (!header.Finished) { client.Disconnect("Continuation frames not supported."); break; } // parse if (client.Buffer.Offset + header.PayloadSize <= client.Buffer.Length) // check if we received all data { if (header.Masked) { DecodeWebSocketData( header.Mask, client.Buffer.InternalBuffer, client.Buffer.Offset, (int)header.PayloadSize); } if (header.PayloadSize > 0 && header.OpCode == WebSocketOpCode.Text) { var str_data = Encoding.GetEncoding(1252).GetString( client.Buffer.InternalBuffer, client.Buffer.Offset, (int)header.PayloadSize); OnWebSocketData( client, str_data); } if (client.IsDisconnect) { break; } // delete from buffer client.Buffer.Remove(header.HeaderSize + (int)header.PayloadSize); } else { return; // need more data } } }
protected virtual void OnWebSocketData(WebSocketClient client, string data) { }
protected virtual void OnWebSocketClosed(WebSocketClient client) { }
protected virtual void OnWebSocketOpen(WebSocketClient client) { }
protected virtual bool AuthorizeRequest(WebSocketClient client, HttpHeader header) { return(true); }
private void ProcessHttpData(WebSocketClient client, byte[] buffer, int offset, int length) { var encoding = Encoding.GetEncoding(1252); var data = encoding.GetString(buffer, offset, length); int pos; bool hasRowFeed; while ((pos = HttpHeader.FindHttpHeaderEnd(ref data, out hasRowFeed)) != -1) { if (client.Buffer.Length > 0) { pos += client.Buffer.Length; data = encoding.GetString(client.Buffer.InternalBuffer, 0, client.Buffer.Length) + data; client.Buffer.Reset(); } var packet = data.Substring(0, pos); data = data.Substring(pos + (hasRowFeed ? 4 : 2)); if (packet.Length > 0) { // log packet //System.IO.File.AppendAllText("web_datalog.txt", string.Format("[{0}]\r\n{1}\r\n\r\n", DateTime.Now.ToString("HH:mm:ss"), packet)); HttpHeader header; try { foreach (char c in packet) { if (c == 0) { throw new UrlDecodingException(string.Empty); } } if (packet.Contains("%0")) { throw new UrlDecodingException(string.Empty); } header = HttpHeader.ParseHeader(ref packet); } catch (UrlDecodingException ex) { client.SendErrorResponse(500, "Internal Error", "Malformed URL" + (ex.Message.Length > 0 ? (": " + ex.Message) : ".")); client.Disconnect(ex.Message); return; } if (string.Compare(header.Version, "HTTP/1.1", true) != 0) { client.Disconnect("Invalid HTTP verson: " + header.Version); return; } if (header.Method == HttpRequestMethod.Unknown) { client.Disconnect("Invalid request method."); return; } //////////////////////////////////////////////////////////////////////////////////////////// // Reverse Proxy implementation /* * X-Original-URL: /app/assets/img/icon_plus.png * X-Forwarded-For: 78.70.113.225:65346 * X-ARR-LOG-ID: 7b5980f7-9854-45f4-91cf-6cfba7cb29a9 */ if (_isBackendServer) { string reverseProxyIp = null; if (header.GetParameter("X-Forwarded-For", ref reverseProxyIp)) { int colonPos; if ((colonPos = reverseProxyIp.IndexOf(':')) != -1) { reverseProxyIp = reverseProxyIp.Substring(0, colonPos); } if (reverseProxyIp.Length > 0) { //Logger.Log(LogType.Warning, "X-Forwarded-For in request was empty."); client.SetUserAddress(reverseProxyIp); } } } //////////////////////////////////////////////////////////////////////////////////////////// long contentLength = 0; header.GetParameter("Content-Length", ref contentLength); // does not edit contentLength if the parameter doesn't exist if (contentLength != 0) // we only handle websocket initial http requests, no content is expected { client.Disconnect("Client sent unexpected content of " + contentLength + " bytes"); return; } InternalHandleRequest(client, header); if (client.IsDisconnect) { return; } } } if (data.Length > 0) { var binaryData = encoding.GetBytes(data); client.Buffer.Offset = client.Buffer.Length; client.Buffer.Write(binaryData, 0, binaryData.Length); } }