private void DoHmux(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
String sessionId;
if (!_isStickySessions)
{
sessionId = null;
}
else
{
sessionId = GetRequestedSessionId(request);
}
TempBuffer tempBuf = TempBuffer.Allocate();
byte[] buf = tempBuf.GetBuffer();
try {
Stream is_ = request.InputStream;
int len = is_.Read(buf, 0, buf.Length);
bool isComplete;
if (len < 0)
{
isComplete = true;
}
else if (len < buf.Length)
{
int sublen = is_.Read(buf, len, 1);
if (sublen == 0) //.NET return 0 for Stream.EOF
{
isComplete = true;
}
else
{
len += sublen;
isComplete = false;
}
}
else
{
isComplete = false;
}
Server client = null;
int result = OK | EXIT;
HmuxConnection channel = _loadBalancer.OpenServer(sessionId, null);
// If everything fails, return an error
if (channel == null)
{
SendNotAvailable(response);
return;
}
client = channel.GetPool();
BufferedStream rs = channel.GetSocketStream();
BufferedStream ws = channel.GetSocketStream();
result = FAIL | EXIT;
long requestStartTime = Utils.CurrentTimeMillis();
try {
result = HandleRequest(context, request, response, channel, rs, ws,
buf, len, isComplete, isComplete);
if ((result & STATUS_MASK) == OK)
{
client.ClearBusy();
return;
}
else if ((result & STATUS_MASK) == BUSY)
{
client.Busy();
}
else
{
client.FailSocket();
}
} catch (ClientDisconnectException) {
_log.Info("Client disconnect detected for '{0}'", channel.GetTraceId());
return;
} catch (IOException e) {
client.FailSocket();
_log.Error("IOException '{0}': '{1}' {2}", channel.GetTraceId(), e.Message, e.StackTrace);
} finally {
if ((result & EXIT_MASK) == QUIT)
{
channel.Free(requestStartTime);
}
else
{
channel.Close();
}
}
// server/2675
if (isComplete && (result & STATUS_MASK) == BUSY ||
"GET".Equals(request.HttpMethod))
{
channel = _loadBalancer.OpenServer(sessionId, client);
// If everything fails, return an error
if (channel == null)
{
_log.Info("load-balance failed" + (client != null ? (" for " + client.GetDebugId()) : ""));
SendNotAvailable(response);
return;
}
Server client2 = channel.GetPool();
if (_log.IsLoggable(EventLogEntryType.Information))
{
_log.Info("load-balance failing over"
+ (client != null ? (" from " + client.GetDebugId()) : "")
+ " to " + client2.GetDebugId());
}
rs = channel.GetSocketStream();
ws = channel.GetSocketStream();
result = FAIL | EXIT;
requestStartTime = Utils.CurrentTimeMillis();
try {
result = HandleRequest(context, request, response, channel, rs, ws,
buf, len, isComplete, false);
if ((result & STATUS_MASK) == OK)
{
client2.ClearBusy();
return;
}
else if ((result & STATUS_MASK) == BUSY)
{
client2.Busy();
}
else
{
client2.FailSocket();
}
} catch (IOException e) {
client2.FailSocket();
_log.Info("Failover to '{0}' did not succeed '{1}', {2} ", client2.GetDebugId(), e.Message, e.StackTrace);
} finally {
if ((result & EXIT_MASK) == QUIT)
{
channel.Free(requestStartTime);
}
else
{
channel.Close();
}
}
}
SendNotAvailable(response);
} finally {
TempBuffer.Free(tempBuf);
tempBuf = null;
}
}