Esempio n. 1
0
        public async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
        {
            if (mState == WebSocketState.Closed || mState == WebSocketState.CloseSent)
            {
                throw new HttpException(500, "Websocket: Sent 'close' message after connection was already closed.  Connection state=" + mState);
            }
            mState = mState == WebSocketState.CloseReceived ? WebSocketState.Closed : WebSocketState.CloseSent;

            // Prepend two bytes for status
            var message = Encoding.UTF8.GetBytes("XX" + statusDescription);

            message[0] = (byte)((int)closeStatus >> 8);
            message[1] = (byte)(int)closeStatus;
            await SendAsync(new ArraySegment <byte>(message), WebSocketMessageType.Close, true, cancellationToken);

            await mWriter.FlushAsync();
        }
Esempio n. 2
0
        /// <summary>
        /// Process requests as long as there is not an error
        /// </summary>
        async Task ProcessRequests(HttpContext context, HttpReader reader, HttpWriter writer)
        {
            int persistentConnections = 0;

            do
            {
                persistentConnections++;
                try
                {
                    // Read header
                    reader.ReadTimeout = HeaderTimeout;
                    var buffer = await reader.ReadHttpHeaderAsyncInternal();

                    reader.PositionInternal = 0;
                    reader.LengthInternal   = HttpContext.HTTP_HEADER_MAX_SIZE;
                    if (buffer.Count == 0)
                    {
                        return;  // Connection closed
                    }
                    // Parse header
                    context.ResetRequestInternal(HttpRequest.Parse(buffer), new HttpResponse());
                }
                catch (Exception ex)
                {
                    Log.Write("HTTP header exception: " + ex.GetType() + " - " + ex.Message);
                    return; // Close connection
                }

                // Handle body
                reader.ReadTimeout  = BodyTimeout;
                writer.WriteTimeout = BodyTimeout;
                try
                {
                    // Process HTTP request
                    var handler = HttpHandler;
                    if (handler == null)
                    {
                        throw new HttpException(503, "HTTP request handler not installed");
                    }
                    await handler(context).ConfigureAwait(false);
                }
                catch (HttpException ex) when(ex.KeepConnectionOpen && !context.Response.HeaderSent)
                {
                    // Keep the persistent connection open only if it's OK to do so.
                    await ProcessExceptionAsync(context, ex);
                }
                await writer.FlushAsync();

                // Any of these problems will terminate a persistent connection
                var response    = context.Response;
                var request     = context.Request;
                var isWebsocket = request.IsWebSocketRequest;
                if (!response.HeaderSent)
                {
                    throw new HttpException(500, "Request handler did not send a response for: " + context.Request.Path);
                }
                if (!isWebsocket && reader.Position != request.ContentLength && request.ContentLength >= 0)
                {
                    throw new HttpException(500, "Request handler did not read correct number of bytes: " + request.Path);
                }
                if (!isWebsocket && writer.Position != response.ContentLength)
                {
                    throw new HttpException(500, "Request handler did not write correct number of bytes: " + request.Path);
                }
            } while (!context.Request.IsWebSocketRequest && context.Response.Connection == "keep-alive");
        }