public void DoHmux(HttpContext context) { Socket hmuxSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); hmuxSocket.Connect("localhost", 6810); HmuxChannel channel = new HmuxChannel(hmuxSocket); channel.StartChannel(); channel.RelayUri(context.Request.RawUrl); channel.RelayHttpMethod(context.Request.HttpMethod); channel.RelayHeaders(context.Request.Headers); channel.RelayServerVariables(context.Request); channel.RelayRequestBody(context.Request); channel.MarkQuit(); //channel.WriteExit(); channel.FlushBuffer(); channel.DoResponse(context); //byte []buffer = new byte[1024]; //int x = channel.Read(buffer); //context.Response.OutputStream.Write(buffer, 0, x); /** hmuxSocket.FlushBuffer( cse_write_byte(hmuxSocket, HMUX_CHANNEL); cse_write_byte(hmuxSocket, channel >> 8); cse_write_byte(hmuxSocket, channel); cse_write_string(hmuxSocket, HMUX_URL, uri); write_var(hmuxSocket, r, "REQUEST_METHOD", HMUX_METHOD); write_var(hmuxSocket, r, "SERVER_PROTOCOL", CSE_PROTOCOL); // write_var(hmuxSocket, r, "PATH_TRANSLATED", CSE_PATH_TRANSLATED); write_var(hmuxSocket, r, "QUERY_STRING", CSE_QUERY_STRING); write_var(hmuxSocket, r, "SERVER_NAME", HMUX_SERVER_NAME); write_var(hmuxSocket, r, "SERVER_PORT", CSE_SERVER_PORT); write_var(hmuxSocket, r, "REMOTE_HOST", CSE_REMOTE_HOST); write_var(hmuxSocket, r, "REMOTE_ADDR", CSE_REMOTE_ADDR); write_var(hmuxSocket, r, "REMOTE_USER", CSE_REMOTE_USER); write_var(hmuxSocket, r, "AUTH_TYPE", CSE_AUTH_TYPE); cse_write_string(hmuxSocket, CSE_SERVER_TYPE, "ISAPI"); */ }
//throws ServletException, IOException private int HandleRequest(HttpRequest request, HttpResponse response, HmuxChannel hmuxChannel, BufferedStream rs, BufferedStream ws, byte[] buf, int length, bool isComplete, bool allowBusy) { String traceId = hmuxChannel.GetTraceId(); StringBuilder cb = new StringBuilder(); bool isDebugFiner = true; String uri = Uri.EscapeUriString(request.RawUrl); Trace.TraceInformation("Hmux[{0}] >>U:uri {1}->{2}", traceId, request.RawUrl, uri); WriteRequestString(ws, HmuxChannel.HMUX_URI, uri, traceId); Trace.TraceInformation("Hmux[{0}] >>m:method {1}", traceId, request.HttpMethod); WriteRequestString(ws, HmuxChannel.HMUX_METHOD, request.HttpMethod, traceId); Trace.TraceInformation("Hmux[{0}] >>u:server type {1}", traceId, "IIS"); WriteRequestString(ws, HmuxChannel.CSE_SERVER_TYPE, "IIS", traceId); NameValueCollection serverVariables = request.ServerVariables; String serverPort = serverVariables.Get("SERVER_PORT"); String serverName = serverVariables.Get("SERVER_NAME") + ':' + serverPort; Trace.TraceInformation("Hmux[{0}] >>v:server name {1}", traceId, serverName); WriteRequestString(ws, HmuxChannel.HMUX_SERVER_NAME, serverName, traceId); Trace.TraceInformation("Hmux[{0}] >>g:server port {1}", traceId, serverPort); WriteRequestString(ws, HmuxChannel.CSE_SERVER_PORT, serverPort, traceId); String remoteAddr = serverVariables.Get("REMOTE_ADDR"); Trace.TraceInformation("Hmux[{0}] >>i:remote address {1}", traceId, remoteAddr); WriteRequestString(ws, HmuxChannel.CSE_REMOTE_ADDR, remoteAddr, traceId); String remoteHost = serverVariables.Get("REMOTE_HOST"); if (remoteHost == null) remoteHost = remoteAddr; Trace.TraceInformation("Hmux[{0}] >>h:remote host {1}", traceId, remoteHost); WriteRequestString(ws, HmuxChannel.CSE_REMOTE_HOST, remoteHost, traceId); String protocol = serverVariables.Get("HTTP_VERSION"); Trace.TraceInformation("Hmux[{0}] >>c:protocol {1}", traceId, protocol); WriteRequestString(ws, HmuxChannel.CSE_PROTOCOL, protocol, traceId); HttpClientCertificate clientCertificate = request.ClientCertificate; if (request.IsSecureConnection) { Trace.TraceInformation("Hmux[{0}] >>r:secure", traceId); WriteRequestString(ws, HmuxChannel.CSE_IS_SECURE, "", traceId); WriteRequestHeader(ws, "HTTPS", "on", traceId); WriteRequestHeader(ws, "SSL_SECRETKEYSIZE", clientCertificate.KeySize.ToString(), traceId); } if (clientCertificate.IsPresent) { Trace.TraceInformation("Hmux[{0}] >>r:certificate ({1})", traceId, clientCertificate.Certificate.Length); ws.WriteByte(HmuxChannel.CSE_CLIENT_CERT); WriteHmuxLength(ws, clientCertificate.Certificate.Length); ws.Write(clientCertificate.Certificate, 0, clientCertificate.Certificate.Length); } NameValueCollection headers = request.Headers; foreach (String key in headers.AllKeys) { if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) continue; String[] values = headers.GetValues(key); foreach (String value in values) { WriteRequestHeader(ws, key, value, traceId); } } Stream requestStream = request.InputStream; Stream responseStream = null; bool hasHeader = true; bool hasStatus = false; if (length > 0) { Trace.TraceInformation("Hmux[{0}] >>D: data ({1})", traceId, length); WriteRequestData(ws, HmuxChannel.HMUX_DATA, buf, length, traceId); } int len; int code; while (!isComplete && (len = requestStream.Read(buf, 0, buf.Length)) > 0) { Trace.TraceInformation("Hmux[{0}] >>D: data ({1})", traceId, length); WriteRequestData(ws, HmuxChannel.HMUX_DATA, buf, len, traceId); Trace.TraceInformation("Hmux[{0}] >>Y: (yield)", traceId); ws.WriteByte(HmuxChannel.HMUX_YIELD); ws.Flush(); while (true) { code = rs.ReadByte(); if (code < 0) { Trace.TraceInformation("Hmux[{0}] <<w: end of file", traceId); if (hasStatus) return OK | EXIT; else { Trace.TraceInformation("Hmux[{0}] <<w: unexpected end of file", traceId); return FAIL | EXIT; } } else if (code == HmuxChannel.HMUX_QUIT) { Trace.TraceInformation("Hmux[{0}] <<Q: (keepalive)", traceId); if (hasStatus) return OK | QUIT; else { Trace.TraceInformation("Hmux[{0}] <<Q: unexpected quit file", traceId); return FAIL | QUIT; } } else if (code == HmuxChannel.HMUX_EXIT) { Trace.TraceInformation("Hmux[{0}] <<X: (exit)", traceId); if (hasStatus) { return OK | EXIT; } else { Trace.TraceInformation("Hmux[{0}] <<X: unexpected exit", traceId); return FAIL | EXIT; } } else if (code == HmuxChannel.HMUX_YIELD) { Trace.TraceInformation("Hmux[{0}] <<Y: (yield)", traceId); continue; } int sublen = ReadHmuxLength(rs); if (code == HmuxChannel.HMUX_ACK) { if (isDebugFiner) Trace.TraceInformation("Hmux[{0}] <<A: (ack) ({1})", traceId, sublen); break; } else if (code == HmuxChannel.HMUX_CHANNEL) { int channel = sublen; Trace.TraceInformation("Hmux[{0}] <<C: (channel) ({1})", traceId, channel); } else if (code == HmuxChannel.HMUX_STATUS && hasHeader) { String status = ReadHmuxString(rs, sublen); Trace.TraceInformation("Hmux[{0}] <<s: (status) ({1})", traceId, status); int statusCode = 0; for (int i = 0; i < 3; i++) statusCode = 10 * statusCode + status[i] - '0'; if (statusCode != 200) response.StatusCode = statusCode; hasStatus = true; } else if (code == HmuxChannel.HMUX_HEADER && hasHeader) { String name = ReadHmuxString(rs, sublen); rs.ReadByte(); sublen = ReadHmuxLength(rs); String value = ReadHmuxString(rs, sublen); Trace.TraceInformation("Hmux[{0}] <<H,S: (header) ({1}={2})", traceId, name, value); RelayResponseHeader(response, name, value); } else if (code == HmuxChannel.HMUX_DATA) { Trace.TraceInformation("Hmux[{0}] <<D: (data)({1})", traceId, sublen); if (responseStream == null) responseStream = response.OutputStream; RelayResponseData(rs, responseStream, sublen); } else if (code == HmuxChannel.HMUX_META_HEADER) { String name = ReadHmuxString(rs, sublen); rs.ReadByte(); sublen = ReadHmuxLength(rs); String value = ReadHmuxString(rs, sublen); Trace.TraceInformation("Hmux[{0}] <<M,S: header ({1}={2})", traceId, name, value); if ("cpu-load".Equals(name)) { double loadAvg = 0.001 * long.Parse(value); hmuxChannel.GetPool().SetCpuLoadAvg(loadAvg); } } else { Skip(rs, sublen); } } } ws.WriteByte(HmuxChannel.HMUX_QUIT); ws.Flush(); code = rs.ReadByte(); // #2369 - A slow modem can cause the app-tier and web-tier times // to get out of sync, with the app-tier thinking it's completed // (and starts the keepalive timeout) 30s before the web-tier reads // its data. // As a temporary measure, we start the idle time at the first data // read (later we might mark the time it takes to read an app-tier // packet. If it's short, e.g. 250ms, don't update the time.) hmuxChannel.SetIdleStartTime(DateTime.Now.Ticks); bool isBusy = false; for (; code >= 0; code = rs.ReadByte()) { if (code == HmuxChannel.HMUX_QUIT) { if (isDebugFiner) Trace.TraceInformation("Hmux[{0}] <<Q: (keepalive)", traceId); return isBusy ? BUSY | QUIT : OK | QUIT; } else if (code == HmuxChannel.HMUX_EXIT) { Trace.TraceInformation("Hmux[{0}] <<X: (exit)", traceId); return (isBusy || !hasStatus) ? BUSY | EXIT : OK | EXIT; } else if (code == HmuxChannel.HMUX_YIELD) { Trace.TraceInformation("Hmux[{0}] <<Y: (yield)", traceId); continue; } int sublen = (rs.ReadByte() << 8) + rs.ReadByte(); if (code == HmuxChannel.HMUX_DATA) { if (responseStream == null) responseStream = response.OutputStream; Trace.TraceInformation("Hmux[{0}] <<D: (data)({1})", traceId, sublen); if (!isBusy) RelayResponseData(rs, responseStream, sublen); else Skip(rs, sublen); } else if (code == HmuxChannel.HMUX_STATUS && hasHeader) { hasStatus = true; String status = ReadHmuxString(rs, sublen); Trace.TraceInformation("Hmux[{0}] <<s: (status) ({1})", traceId, status); int statusCode = 0; for (int i = 0; i < 3; i++) statusCode = 10 * statusCode + status[i] - '0'; if (statusCode == 503 && allowBusy) isBusy = true; else if (statusCode != 200) response.StatusCode = statusCode; } else if (code == HmuxChannel.HMUX_HEADER && hasHeader) { String name = ReadHmuxString(rs, sublen); rs.ReadByte(); sublen = ReadHmuxLength(rs); String value = ReadHmuxString(rs, sublen); Trace.TraceInformation("Hmux[{0}] <<H,S: (header) ({1}={2})", traceId, name, value); if (!isBusy) RelayResponseHeader(response, name, value); } else if (code == HmuxChannel.HMUX_META_HEADER) { String name = ReadHmuxString(rs, sublen); rs.ReadByte(); sublen = ReadHmuxLength(rs); String value = ReadHmuxString(rs, sublen); Trace.TraceInformation("Hmux[{0}] <<M,S: header ({1}={2})", traceId, name, value); if ("cpu-load".Equals(name)) { double loadAvg = 0.001 * long.Parse(value); hmuxChannel.GetPool().SetCpuLoadAvg(loadAvg); } } else if (code == HmuxChannel.HMUX_CHANNEL) { int channel = sublen; Trace.TraceInformation("Hmux[{0}] <<C: (channel) ({1})", traceId, channel); } else if (code == 0) { Trace.TraceInformation("Hmux[{0}] <<0: unknown code (0)", traceId); return FAIL | EXIT; } else { Trace.TraceInformation("Hmux[{0}] <<?: unknown code ({1})", traceId, code); Skip(rs, sublen); } } Trace.TraceInformation("Hmux[{0}] end of file", traceId); // server/269q if (hasStatus) return isBusy ? BUSY | EXIT : OK | EXIT; else { Trace.TraceInformation("Hmux[{0}] unexpected end of file", traceId, code); return FAIL | EXIT; } }
public HmuxChannel OpenServer(String sessionId, HmuxChannelFactory xChannelFactory) { HmuxChannel channel = OpenRecycle(); if (channel != null) return channel; Socket hmuxSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); hmuxSocket.Connect(_address, _port); channel = new HmuxChannel(hmuxSocket, this); return channel; }
internal void Free(HmuxChannel hmuxChannel) { Trace.TraceInformation("HmuxChannelFactory.free() NYI"); }
internal void Close(HmuxChannel hmuxChannel) { Trace.TraceInformation("HmuxChannelFactory.Close(HmuxChannel) NYI"); }