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");
      */
    }
Пример #2
0
        //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");
 }