async Task HandleSession(HttpSession session) { var closeSessionOnReturn = true; try { var continueSession = true; while (continueSession && !session.IsDisconnected()) { try { TrackSessionRead(session.Id); if (await session.ReadToBufferAsync().ConfigureAwait(false) == 0) // 0 => client clean disconnect { break; } } finally { UntrackSessionRead(session.Id); } int requestBytesParsed, responseBytesWritten; HttpRequest request; while (continueSession && session.TryParseNextRequestFromBuffer(out requestBytesParsed, out request)) { Router.HandleResult result = await router.HandleRequest(request, DateTime.UtcNow).ConfigureAwait(false); HttpResponse response = result.HttpResponse; var webSocketUpgradeResponse = response as WebSocketUpgradeResponse; if (webSocketUpgradeResponse == null) { responseBytesWritten = session.WriteResponse(response, request.IsKeepAlive); continueSession = request.IsKeepAlive && session.KeepAlivesRemaining > 0; } else { var isUpgraded = HandleWebsocketUpgrade(session, result.MatchedRouteTableIndex, result.MatchedEndpointIndex, webSocketUpgradeResponse, out responseBytesWritten); continueSession = false; closeSessionOnReturn = !isUpgraded; } if (result.MatchedRouteTableIndex >= 0 && result.MatchedEndpointIndex >= 0) { router.Metrics.CountBytes(result.MatchedRouteTableIndex, result.MatchedEndpointIndex, requestBytesParsed, responseBytesWritten); } } } } catch (RequestException e) { logger.Warn("Error parsing or bad request - {0}", e.Message); } catch (SessionStreamException) { // forced disconnect, socket errors } catch (Exception e) { //TODO: count session-fatal errors (not captured as route table 500s) logger.Fatal("Internal server error handling session - {0}", e.ToString()); } finally { UntrackSession(session.Id); if (closeSessionOnReturn) { session.CloseQuiety(); } } }
async Task HandleSession(HttpSession session) { var closeSessionOnReturn = true; try { var continueRequestLoop = true; while (continueRequestLoop && !session.IsDisconnected()) // request loop { try { TrackSessionRead(session.Id); if (await session.ReadToBufferAsync().ConfigureAwait(false) == 0) // 0 => client clean disconnect { break; } } finally { UntrackSessionRead(session.Id); } int requestBytesParsed, responseBytesWritten; HttpRequest request; while (continueRequestLoop && session.TryParseNextRequestFromBuffer(out requestBytesParsed, out request)) { Router.HandleResult result = await router.HandleRequest(request, DateTime.UtcNow).ConfigureAwait(false); HttpResponse response = result.HttpResponse; if (response is WebSocketUpgradeResponse) { continueRequestLoop = false; var acceptUpgrade = response as WebSocketUpgradeResponse.AcceptUpgradeResponse; if (acceptUpgrade == null) { var rejectUpgrade = (WebSocketUpgradeResponse.RejectUpgradeResponse)response; responseBytesWritten = await rejectUpgrade.WriteToAsync(session.Stream, 0, sessionReadTimeout).ConfigureAwait(false); } else { responseBytesWritten = await AcceptWebSocketUpgrade(session, result.MatchedRouteTableIndex, result.MatchedEndpointIndex, acceptUpgrade).ConfigureAwait(false); closeSessionOnReturn = false; } } else { responseBytesWritten = await response.WriteToAsync(session.Stream, request.IsKeepAlive ? session.KeepAlivesRemaining : 0, sessionReadTimeout).ConfigureAwait(false); continueRequestLoop = request.IsKeepAlive && session.KeepAlivesRemaining > 0; } if (result.MatchedRouteTableIndex >= 0 && result.MatchedEndpointIndex >= 0) { router.Metrics.CountBytes(result.MatchedRouteTableIndex, result.MatchedEndpointIndex, requestBytesParsed, responseBytesWritten); } } } } catch (RequestException e) { sessionExceptionCounters.Count(e.GetType()); logger.Warn("Error parsing or bad request - {0}", e.Message); } catch (SessionStreamException e) { sessionExceptionCounters.Count(e.GetType()); } catch (Exception e) { sessionExceptionCounters.Count(e.GetType()); logger.Fatal("Error handling session - {0}", e.ToString()); } finally { UntrackSession(session.Id); if (closeSessionOnReturn) { session.CloseQuiety(); } } }