public async Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { OpCode opCode; if (messageType == WebSocketMessageType.Close) { opCode = OpCode.Close; } else if (messageType == WebSocketMessageType.Binary) { opCode = OpCode.Binary; } else if (messageType == WebSocketMessageType.Text) { opCode = OpCode.Text; } else { throw new HttpException(500, "SendAsync: Invalid message type"); } int index = 0; mWriteHeaderBuffer[0] = (byte)((endOfMessage ? 0x80 : 0) | ((int)opCode & 0x0F)); if (buffer.Count < 126) { mWriteHeaderBuffer[1] = (byte)(buffer.Count); index = 2; } else if (buffer.Count < 65536) { mWriteHeaderBuffer[1] = 126; mWriteHeaderBuffer[2] = (byte)(buffer.Count >> 8); mWriteHeaderBuffer[3] = (byte)buffer.Count; index = 4; } else { mWriteHeaderBuffer[1] = 127; mWriteHeaderBuffer[2] = 0; mWriteHeaderBuffer[3] = 0; mWriteHeaderBuffer[4] = 0; mWriteHeaderBuffer[5] = 0; mWriteHeaderBuffer[6] = (byte)(buffer.Count >> 24); mWriteHeaderBuffer[7] = (byte)(buffer.Count >> 16); mWriteHeaderBuffer[8] = (byte)(buffer.Count >> 8); mWriteHeaderBuffer[9] = (byte)buffer.Count; index = 10; } await mWriter.WriteAsync(mWriteHeaderBuffer, 0, index); await mWriter.WriteAsync(buffer.Array, buffer.Offset, buffer.Count); }
/// <summary> /// Set the response header before the stream is read or written /// </summary> void SetHttpHeader() { if (mResponse.HeaderSent) { throw new HttpException(500, "SendHttpHeader: Http header already sent"); } if (mResponse.ContentLength < 0) { throw new HttpException(500, "SendHttpHeader: ConentLength must be set before sending header"); } // Connection: Close or keep-alive if (mResponse.Connection == "") { mResponse.Connection = "close"; var connection = mRequest.Headers["connection"].ToLower(); if (connection == "keep-alive" || mRequest.ProtocolVersionMinor >= 1 && connection != "close") { mResponse.Connection = "keep-alive"; } } // Good to go, reset streams var header = Encoding.UTF8.GetBytes(Response.Generate()); mReader.PositionInternal = 0; mReader.LengthInternal = Math.Max(0, mRequest.ContentLength); mWriter.PositionInternal = -header.Length; // Write position measures content output length mWriter.LengthInternal = Math.Max(0, mResponse.ContentLength); // Freeze HTTP response and send header mResponse.HeaderSent = true; mWriter.SetPreWriteTaskInternal(mWriter.WriteAsync(header)); }