public static void WriteResponse(this HttpMessageWriter writer, StatusCodes statusCodes, ContentType contentType, byte[] content)
 {
     writer.WriteStatusLine(statusCodes);
     writer.WriteAuxiliaryHeaders();
     writer.WriteContentType(contentType);
     writer.WriteContentLength(content.Length);
     writer.WriteCRLF();
     writer.Write(content);
 }
Exemple #2
0
        public String ShouldWriteHttpMessage(HttpMessageHeader header, Stream body, long?bodyLength)
        {
            var outputStream = new MemoryStream();

            var httpWriter = new HttpMessageWriter(outputStream);

            httpWriter.Write(header, body, bodyLength);

            return(Encoding.ASCII.GetString(outputStream.ToArray()));
        }
        /// <summary>
        /// Handles the OnResponseReceived for the proxy, which occurs after the response is
        /// received from the web server, but before it is forwarded on to the browser.
        /// </summary>
        /// <param name="context">A <see cref="BenderProxy.ProcessingContext"/> object.</param>
        public override void OnResponseReceived(ProcessingContext context)
        {
            // These are valid credentials for the Basic case.
            string userName = "******";
            string password = "******";

            // Only do any processing on the response if the response is 401,
            // or "Unauthorized".
            if (context.ResponseHeader != null && context.ResponseHeader.StatusCode == 401)
            {
                // Read the headers from the response and finish reading the response
                // body, if any.
                Console.WriteLine("Received 401 - Unauthorized response");
                context.ServerStream.ReadTimeout  = 5000;
                context.ServerStream.WriteTimeout = 5000;
                StreamReader     reader       = new StreamReader(context.ServerStream);
                HttpHeaderReader headerReader = new HttpHeaderReader(reader);
                if (context.ResponseHeader.EntityHeaders.ContentLength != 0)
                {
                    string drainBody = ReadFromStream(reader);
                }

                // We do not want the proxy to do any further processing after
                // handling this message.
                context.StopProcessing();

                // Read the WWW-Authenticate header. Because of the way the test
                // web app is configured, it returns multiple headers, with
                // different schemes. We need to select the correct one.
                string authHeader = GetAuthenticationHeader(context.ResponseHeader.WWWAuthenticate, BasicGenerator.AuthorizationHeaderMarker);
                Console.WriteLine("Processing WWW-Authenticate header: {0}", authHeader);

                // Calculate the value for the Authorization header, and resend
                // the request (with the Authorization header) to the server
                // using BenderProxy's HttpMessageWriter.
                Console.WriteLine("Generating authorization header value for user name '{0}' and password '{1}'", userName, password);
                BasicGenerator generator = new BasicGenerator(userName, password, authHeader);
                string         authorizationHeaderValue = generator.GenerateAuthorizationHeader();
                Console.WriteLine("Resending request with Authorization header: {0}", authorizationHeaderValue);
                context.RequestHeader.Authorization = authorizationHeaderValue;
                HttpMessageWriter writer = new HttpMessageWriter(context.ServerStream);
                writer.Write(context.RequestHeader);

                // Get the authorized response, and forward it on to the browser, using
                // BenderProxy's HttpHeaderReader and support classes.
                HttpResponseHeader header     = new HttpResponseHeader(headerReader.ReadHttpMessageHeader());
                string             body       = ReadFromStream(reader);
                Stream             bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
                new HttpResponseWriter(context.ClientStream).Write(header, bodyStream, bodyStream.Length);
            }
        }
Exemple #4
0
        private void SendJsonMessage(Session session)
        {
            using (var writer = new HttpMessageWriter())
            {
                //byte[] json = Encoding.UTF8.GetBytes(string.Format(@"{{id:{0}}}", session.Id));
                byte[] json = Encoding.UTF8.GetBytes(string.Format(@"{0}", session.Id));

                writer.WriteStatusLine(StatusCodes.OK);
                //writer.Write(Encoding.UTF8.GetBytes("Content-Type: application/json\r\n"));
                writer.WriteContentLength(json.Length);
                writer.WriteAccessControlHeaders();
                writer.WriteCRLF();
                writer.Write(json);

                SendWriter(session, writer);
            }
        }
Exemple #5
0
        /// <summary>
        ///     Send <see cref="ProcessingContext.RequestHeader" /> to server,
        ///     copy rest of the <see cref="ProcessingContext.ClientStream" /> to <see cref="ProcessingContext.ServerStream" />
        ///     and read <see cref="ProcessingContext.ResponseHeader" /> from <see cref="ProcessingContext.ServerStream" />.
        ///     Expects <see cref="ProcessingContext.ServerStream" />, <see cref="ProcessingContext.RequestHeader" /> and
        ///     <see cref="ProcessingContext.ClientStream" /> to be defined.
        /// </summary>
        /// <param name="context">current request context</param>
        protected virtual void ReceiveResponse(ProcessingContext context)
        {
            ContractUtils.Requires <ArgumentNullException>(context != null, "context");
            ContractUtils.Requires <InvalidContextException>(context.ServerStream != null, "ServerStream");
            ContractUtils.Requires <InvalidContextException>(context.RequestHeader != null, "RequestHeader");
            ContractUtils.Requires <InvalidContextException>(context.ClientStream != null, "ClientStream");
            ContractUtils.Requires <InvalidContextException>(context.ClientSocket != null, "ClientSocket");

            var requestWriter = new HttpMessageWriter(context.ServerStream);

            requestWriter.Log += this.OnComponentLog;

            var responseReader = new HttpHeaderReader(new PlainStreamReader(context.ServerStream));

            responseReader.Log += this.OnComponentLog;

            try
            {
                requestWriter.Write(context.RequestHeader, context.ClientStream, context.ClientSocket.Available);
                context.ResponseHeader = new HttpResponseHeader(responseReader.ReadHttpMessageHeader());

                OnLog(LogLevel.Debug, "Response Received: {0}", TraceUtils.GetHttpTrace(context.ResponseHeader));
            }
            catch (IOException ex)
            {
                var responseWriter = new HttpResponseWriter(context.ClientStream);

                if (ex.IsSocketException(SocketError.TimedOut))
                {
                    OnLog(LogLevel.Warn, "Request to remote server has timed out. {0}", TraceUtils.GetHttpTrace(context.RequestHeader));

                    responseWriter.WriteGatewayTimeout();
                }
                else
                {
                    throw;
                }

                context.StopProcessing();
            }
        }
        private void ProcessResponse(ProcessingContext context)
        {
            // Only do any processing on the response if the response is 401,
            // or "Unauthorized".
            if (context.ResponseHeader != null && context.ResponseHeader.StatusCode == 401)
            {
                //context.ServerStream.ReadTimeout = 5000;
                //context.ServerStream.WriteTimeout = 5000;
                var reader = new StreamReader(context.ServerStream);
                if (context.ResponseHeader.EntityHeaders.ContentLength != 0)
                {
                    ReadFromStream(reader);
                }
                // We do not want the proxy to do any further processing after
                // handling this message.
                context.StopProcessing();


                if (context.ResponseHeader.WWWAuthenticate.Contains(BasicGenerator.AuthorizationHeaderMarker))
                {
                    // This is the generation of the HTTP Basic authorization header value.
                    var basicAuthHeaderValue = $"user:pass";
                    var encodedHeaderValue   = Convert.ToBase64String(Encoding.ASCII.GetBytes(basicAuthHeaderValue));
                    context.RequestHeader.Authorization = "Basic " + encodedHeaderValue;

                    // Resend the request (with the Authorization header) to the server
                    // using BenderProxy's HttpMessageWriter.
                    var writer = new HttpMessageWriter(context.ServerStream);
                    writer.Write(context.RequestHeader);

                    // Get the authorized response, and forward it on to the browser, using
                    // BenderProxy's HttpHeaderReader and support classes.
                    var    headerReader = new HttpHeaderReader(reader);
                    var    header       = new HttpResponseHeader(headerReader.ReadHttpMessageHeader());
                    var    body         = ReadFromStream(reader);
                    Stream bodyStream   = new MemoryStream(Encoding.UTF8.GetBytes(body));
                    new HttpResponseWriter(context.ClientStream).Write(header, bodyStream, bodyStream.Length);
                }
                else if (context.ResponseHeader.WWWAuthenticate.Contains(NtlmGenerator.AuthorizationHeaderMarker))
                {
                    // Read the WWW-Authenticate header. Because of the way the test
                    // web app is configured, it returns multiple headers, with
                    // different schemes. We need to select the correct one.
                    var authHeader = GetAuthenticationHeader(context.ResponseHeader.WWWAuthenticate,
                                                             NtlmGenerator.AuthorizationHeaderMarker);

                    var type1            = new NtlmNegotiateMessageGenerator();
                    var type1HeaderValue = type1.GenerateAuthorizationHeader();
                    context.RequestHeader.Authorization = type1HeaderValue;
                    var writer = new HttpMessageWriter(context.ServerStream);
                    writer.Write(context.RequestHeader);

                    var headerReader        = new HttpHeaderReader(reader);
                    var challengeHeader     = new HttpResponseHeader(headerReader.ReadHttpMessageHeader());
                    var challengeAuthHeader = challengeHeader.WWWAuthenticate;
                    var challengeBody       = ReadFromStream(reader);

                    if (!string.IsNullOrEmpty(challengeAuthHeader) &&
                        challengeAuthHeader.StartsWith(NtlmGenerator.AuthorizationHeaderMarker))
                    {
                        // If a proper message was received (the "type 2" or "Challenge" message),
                        // parse it, and generate the proper authentication header (the "type 3"
                        // or "Authorization" message).
                        var type2            = new NtlmChallengeMessageGenerator(challengeAuthHeader);
                        var type3            = new NtlmAuthenticateMessageGenerator(null, null, "user", "pass", type2);
                        var type3HeaderValue = type3.GenerateAuthorizationHeader();
                        context.RequestHeader.Authorization = type3HeaderValue;
                        writer.Write(context.RequestHeader);

                        // Get the authorized response from the server, and forward it on to
                        // the browser.
                        var    header     = new HttpResponseHeader(headerReader.ReadHttpMessageHeader());
                        var    body       = ReadFromStream(reader);
                        Stream bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
                        new HttpResponseWriter(context.ClientStream).Write(header, bodyStream, bodyStream.Length);
                        context.ClientStream.Flush();
                    }
                }
            }
        }
        public String ShouldWriteHttpMessage(HttpMessageHeader header, Stream body, long? bodyLength)
        {
            var outputStream = new MemoryStream();

            var httpWriter = new HttpMessageWriter(outputStream);

            httpWriter.Write(header, body, bodyLength);

            return Encoding.ASCII.GetString(outputStream.ToArray());
        }
Exemple #8
0
        /// <summary>
        /// Handles the OnResponseReceived for the proxy, which occurs after the response is
        /// received from the web server, but before it is forwarded on to the browser.
        /// </summary>
        /// <param name="context">A <see cref="BenderProxy.ProcessingContext"/> object.</param>
        public override void OnResponseReceived(ProcessingContext context)
        {
            string userName = "******";
            string password = "******";

            if (context.ResponseHeader != null && context.ResponseHeader.StatusCode == 401)
            {
                // Only process requests for localhost or the redirected-
                // via-hosts-file-entry host, and where NTLM auth is requested.
                List <string> candidateUrls = new List <string>()
                {
                    string.Format("localhost:{0}", TestWebAppPort), string.Format("{0}:{1}", TestWebAppHostName, TestWebAppPort)
                };
                if (candidateUrls.Contains(context.RequestHeader.Host) && context.ResponseHeader.WWWAuthenticate != null && context.ResponseHeader.WWWAuthenticate.Contains(NtlmGenerator.AuthorizationHeaderMarker))
                {
                    // Read the headers from the response and finish reading the response
                    // body, if any.
                    Console.WriteLine("Received 401 - Unauthorized response");
                    context.ServerStream.ReadTimeout  = 5000;
                    context.ServerStream.WriteTimeout = 5000;
                    StreamReader reader = new StreamReader(context.ServerStream);
                    if (context.ResponseHeader.EntityHeaders.ContentLength != 0)
                    {
                        string drainBody = ReadFromStream(reader);
                    }

                    // We do not want the proxy to do any further processing after
                    // handling this message.
                    context.StopProcessing();

                    // Read the WWW-Authenticate header. Because of the way the test
                    // web app is configured, it returns multiple headers, with
                    // different schemes. We need to select the correct one.
                    string authHeader = GetAuthenticationHeader(context.ResponseHeader.WWWAuthenticate, NtlmGenerator.AuthorizationHeaderMarker);
                    Console.WriteLine("Processing WWW-Authenticate header: {0}", authHeader);

                    // Generate the initial message (the "type 1" or "Negotiation" message")
                    // and get the response, using BenderProxy's HttpMessageWriter and
                    // HttpHeaderReader and support classes.
                    Console.WriteLine("Generating authorization header value for Negotiate ('Type 1') message");
                    NtlmNegotiateMessageGenerator type1 = new NtlmNegotiateMessageGenerator();
                    string type1HeaderValue             = type1.GenerateAuthorizationHeader();
                    context.RequestHeader.Authorization = type1HeaderValue;
                    Console.WriteLine("Resending request with Authorization header: {0}", type1HeaderValue);
                    HttpMessageWriter writer = new HttpMessageWriter(context.ServerStream);
                    writer.Write(context.RequestHeader);

                    HttpHeaderReader   headerReader        = new HttpHeaderReader(reader);
                    HttpResponseHeader challengeHeader     = new HttpResponseHeader(headerReader.ReadHttpMessageHeader());
                    string             challengeAuthHeader = challengeHeader.WWWAuthenticate;
                    string             challengeBody       = ReadFromStream(reader);

                    if (!string.IsNullOrEmpty(challengeAuthHeader) && challengeAuthHeader.StartsWith(NtlmGenerator.AuthorizationHeaderMarker))
                    {
                        // If a proper message was received (the "type 2" or "Challenge" message),
                        // parse it, and generate the proper authentication header (the "type 3"
                        // or "Authorization" message).
                        Console.WriteLine("Received 401 response with Challenge ('Type 2') message: {0}", challengeAuthHeader);
                        NtlmChallengeMessageGenerator type2 = new NtlmChallengeMessageGenerator(challengeAuthHeader);
                        Console.WriteLine("Generating Authorization ('Type 3') message for user name '{0}' and password '{1}'", userName, password);
                        NtlmAuthenticateMessageGenerator type3 = new NtlmAuthenticateMessageGenerator(null, null, userName, password, type2);
                        string type3HeaderValue = type3.GenerateAuthorizationHeader();
                        Console.WriteLine("Resending request with Authorization header: {0}", type3HeaderValue);
                        context.RequestHeader.Authorization = type3HeaderValue;
                        writer.Write(context.RequestHeader);

                        // Get the authorized response from the server, and forward it on to
                        // the browser.
                        HttpResponseHeader header     = new HttpResponseHeader(headerReader.ReadHttpMessageHeader());
                        string             body       = ReadFromStream(reader);
                        Stream             bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
                        new HttpResponseWriter(context.ClientStream).Write(header, bodyStream, bodyStream.Length);
                        context.ClientStream.Flush();
                    }
                }
            }
        }
Exemple #9
0
        /// <summary>
        ///     Send <see cref="ProcessingContext.RequestHeader" /> to server,
        ///     copy rest of the <see cref="ProcessingContext.ClientStream" /> to <see cref="ProcessingContext.ServerStream" />
        ///     and read <see cref="ProcessingContext.ResponseHeader" /> from <see cref="ProcessingContext.ServerStream" />.
        ///     Expects <see cref="ProcessingContext.ServerStream" />, <see cref="ProcessingContext.RequestHeader" /> and
        ///     <see cref="ProcessingContext.ClientStream" /> to be defined.
        /// </summary>
        /// <param name="context">current request context</param>
        protected virtual void ReceiveResponse(ProcessingContext context)
        {
            Contract.Requires<ArgumentNullException>(context != null, "context");
            Contract.Requires<InvalidContextException>(context.ServerStream != null, "ServerStream");
            Contract.Requires<InvalidContextException>(context.RequestHeader != null, "RequestHeader");
            Contract.Requires<InvalidContextException>(context.ClientStream != null, "ClientStream");
            Contract.Requires<InvalidContextException>(context.ClientSocket != null, "ClientSocket");

            var requestWriter = new HttpMessageWriter(context.ServerStream);
            var responseReader = new HttpHeaderReader(new PlainStreamReader(context.ServerStream));

            try
            {
                requestWriter.Write(context.RequestHeader, context.ClientStream, context.ClientSocket.Available);
                context.ResponseHeader = new HttpResponseHeader(responseReader.ReadHttpMessageHeader());

                if (Logger.IsDebugEnabled)
                {
                    Logger.DebugFormat("Response Received: {0}", TraceUtils.GetHttpTrace(context.ResponseHeader));
                }
            }
            catch (IOException ex)
            {
                var responseWriter = new HttpResponseWriter(context.ClientStream);

                if (ex.IsSocketException(SocketError.TimedOut))
                {
                    Logger.WarnFormat("Request to remote server has timed out. {0}", TraceUtils.GetHttpTrace(context.RequestHeader));

                    responseWriter.WriteGatewayTimeout();
                }
                else
                {
                    throw;
                }

                context.StopProcessing();
            }
        }