예제 #1
0
        //private bool IncrementRequestCount(ApplicationInstance instance)
        //{
        //    LbIncrementRequestCountRequest request = new LbIncrementRequestCountRequest(Settings.Credentials);
        //    request.ApplicationId = instance.ApplicationId;
        //    request.InstanceId = instance.Id;
        //    EndPoints.LoadBalancerWebService.IncrementRequestCount(request);
        //    return true;
        //}
        //private void DecrementRequestCount(ApplicationInstance instance)
        //{
        //    LbDecrementRequestCountRequest request = new LbDecrementRequestCountRequest(Settings.Credentials);
        //    request.ApplicationId = instance.ApplicationId;
        //    request.InstanceId = instance.Id;
        //    EndPoints.LoadBalancerWebService.DecrementRequestCount(request);
        //}
        /// <summary>
        /// Sends the request to server
        /// Implemented using Managed Fusion URL Rewriter
        /// Reference: http://www.managedfusion.com/products/url-rewriter/
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private WebResponse SendRequestToTarget(HttpContext context, Uri requestUrl, ReverseProxyContext rpContext, out bool incremented)
        {
            incremented = false;
            // get the request
            WebRequest request = WebRequest.CreateDefault(requestUrl);

            if (request == null)
                throw new HttpException((int)HttpStatusCode.BadRequest, "The requested url, <" + requestUrl + ">, could not be found.");

            // keep the same HTTP request method
            request.Method = context.Request.HttpMethod;
            var knownVerb = KnownHttpVerb.Parse(request.Method);

            // depending on the type of this request specific values for an HTTP request
            if (request is HttpWebRequest)
            {
                var httpRequest = request as HttpWebRequest;
                httpRequest.AllowAutoRedirect = false;
                httpRequest.ServicePoint.Expect100Continue = false;

                // add all the headers from the other proxied session to this request
                foreach (string name in context.Request.Headers.AllKeys)
                {
                    // add the headers that are restricted in their supported manor
                    switch (name)
                    {
                        case "User-Agent":
                            httpRequest.UserAgent = context.Request.UserAgent;
                            break;

                        case "Connection":
                            string connection = context.Request.Headers[name];
                            if (connection.IndexOf("Keep-Alive", StringComparison.OrdinalIgnoreCase) > 0)
                                httpRequest.KeepAlive = true;

                            List<string> list = new List<string>();
                            foreach (string conn in connection.Split(','))
                            {
                                string c = conn.Trim();
                                if (!c.Equals("Keep-Alive", StringComparison.OrdinalIgnoreCase) && !c.Equals("Close", StringComparison.OrdinalIgnoreCase))
                                    list.Add(c);
                            }

                            if (list.Count > 0)
                                httpRequest.Connection = String.Join(", ", list.ToArray());
                            break;

                        case "Transfer-Encoding":
                            httpRequest.SendChunked = true;
                            httpRequest.TransferEncoding = context.Request.Headers[name];
                            break;

                        case "Expect":
                            httpRequest.ServicePoint.Expect100Continue = true;
                            break;

                        case "If-Modified-Since":
                            DateTime ifModifiedSince;
                            if (DateTime.TryParse(context.Request.Headers[name], out ifModifiedSince))
                                httpRequest.IfModifiedSince = ifModifiedSince;
                            break;

                        case "Content-Length":
                            httpRequest.ContentLength = context.Request.ContentLength;
                            break;

                        case "Content-Type":
                            httpRequest.ContentType = context.Request.ContentType;
                            break;

                        case "Accept":
                            httpRequest.Accept = String.Join(", ", context.Request.AcceptTypes);
                            break;

                        case "Referer":
                            httpRequest.Referer = context.Request.UrlReferrer.OriginalString;
                            break;
                    }

                    // add to header if not restricted
                    if (!WebHeaderCollection.IsRestricted(name, false))
                    {
                        // it is nessisary to get the values for headers that are allowed to specifiy
                        // multiple values in an instance (i.e. Cookie)
                        string[] values = context.Request.Headers.GetValues(name);
                        foreach (string value in values)
                            request.Headers.Add(name, value);
                    }
                }
            }

            // Add Proxy Standard Protocol Headers
            // http://en.wikipedia.org/wiki/X-Forwarded-For
            request.Headers.Add("X-Forwarded-For", context.Request.UserHostAddress);
            // Add Server Variables
            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45
            string currentServerName = context.Request.ServerVariables["SERVER_NAME"];
            string currentServerPort = context.Request.ServerVariables["SERVER_PORT"];
            string currentServerProtocol = context.Request.ServerVariables["SERVER_PROTOCOL"];

            if (currentServerProtocol.IndexOf("/") >= 0)
                currentServerProtocol = currentServerProtocol.Substring(currentServerProtocol.IndexOf("/") + 1);

            string currentVia = String.Format("{0} {1}:{2} ({3})", currentServerProtocol, currentServerName, currentServerPort, "Monoscape.LoadBalancerController");
            request.Headers.Add("Via", currentVia);

            //
            // ContentLength is set to -1 if their is no data to send
            if ((request.ContentLength >= 0) && (!knownVerb.ContentBodyNotAllowed))
            {
                int bufferSize = 64 * 1024;
                using (Stream requestStream = request.GetRequestStream(), bufferStream = new BufferedStream(context.Request.InputStream, bufferSize))
                {
                    byte[] buffer = new byte[bufferSize];

                    try
                    {
                        while (true)
                        {
                            // make sure that the stream can be read from
                            if (!bufferStream.CanRead)
                                break;
                            int bytesReturned = bufferStream.Read(buffer, 0, bufferSize);
                            // if not bytes were returned the end of the stream has been reached
                            // and the loop should exit
                            if (bytesReturned == 0)
                                break;
                            // write bytes to the response
                            requestStream.Write(buffer, 0, bytesReturned);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(typeof(ProxyHandler), "", e);
                    }
                }
            }

            WebResponse response;
            try
            {
                // Increment application instance request count
                //incremented = IncrementRequestCount(rpContext.ApplicationInstance);
                if (addReqResult != null)
                {
                    int requestId = rpContext.AddReqCaller.EndInvoke(addReqResult);
                    // Remove request from load balancer request queue
                    ASyncRemoveRequestFromQueue caller = new ASyncRemoveRequestFromQueue(RemoveRequestFromQueue);
                    caller.BeginInvoke(requestId, null, null);
                }
                // Send request to the proxy target
                response = request.GetResponse();
            }
            catch (WebException e)
            {
                Log.Error(typeof(ProxyHandler), "Error received from " + request.RequestUri + ": " + e.Message, e);
                response = e.Response;
            }

            if (response == null)
            {
                Log.Error(typeof(ProxyHandler), "The requested url " + requestUrl + " could not be found.");
                throw new HttpException((int)HttpStatusCode.NotFound, "The requested url could not be found.");
            }

            Log.Info(typeof(ProxyHandler), response.GetType().ToString());
            if (response is HttpWebResponse)
            {
                HttpWebResponse httpResponse = response as HttpWebResponse;
                Log.Info(typeof(ProxyHandler), "Received '" + ((int)httpResponse.StatusCode) + " " + httpResponse.StatusDescription + "'");
            }
            return response;
        }
예제 #2
0
        //private bool IncrementRequestCount(ApplicationInstance instance)
        //{
        //    LbIncrementRequestCountRequest request = new LbIncrementRequestCountRequest(Settings.Credentials);
        //    request.ApplicationId = instance.ApplicationId;
        //    request.InstanceId = instance.Id;
        //    EndPoints.LoadBalancerWebService.IncrementRequestCount(request);
        //    return true;
        //}

        //private void DecrementRequestCount(ApplicationInstance instance)
        //{
        //    LbDecrementRequestCountRequest request = new LbDecrementRequestCountRequest(Settings.Credentials);
        //    request.ApplicationId = instance.ApplicationId;
        //    request.InstanceId = instance.Id;
        //    EndPoints.LoadBalancerWebService.DecrementRequestCount(request);
        //}

        /// <summary>
        /// Sends the request to server
        /// Implemented using Managed Fusion URL Rewriter
        /// Reference: http://www.managedfusion.com/products/url-rewriter/
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private WebResponse SendRequestToTarget(HttpContext context, Uri requestUrl, ReverseProxyContext rpContext, out bool incremented)
        {
            incremented = false;
            // get the request
            WebRequest request = WebRequest.CreateDefault(requestUrl);

            if (request == null)
            {
                throw new HttpException((int)HttpStatusCode.BadRequest, "The requested url, <" + requestUrl + ">, could not be found.");
            }

            // keep the same HTTP request method
            request.Method = context.Request.HttpMethod;
            var knownVerb = KnownHttpVerb.Parse(request.Method);

            // depending on the type of this request specific values for an HTTP request
            if (request is HttpWebRequest)
            {
                var httpRequest = request as HttpWebRequest;
                httpRequest.AllowAutoRedirect = false;
                httpRequest.ServicePoint.Expect100Continue = false;

                // add all the headers from the other proxied session to this request
                foreach (string name in context.Request.Headers.AllKeys)
                {
                    // add the headers that are restricted in their supported manor
                    switch (name)
                    {
                    case "User-Agent":
                        httpRequest.UserAgent = context.Request.UserAgent;
                        break;

                    case "Connection":
                        string connection = context.Request.Headers[name];
                        if (connection.IndexOf("Keep-Alive", StringComparison.OrdinalIgnoreCase) > 0)
                        {
                            httpRequest.KeepAlive = true;
                        }

                        List <string> list = new List <string>();
                        foreach (string conn in connection.Split(','))
                        {
                            string c = conn.Trim();
                            if (!c.Equals("Keep-Alive", StringComparison.OrdinalIgnoreCase) && !c.Equals("Close", StringComparison.OrdinalIgnoreCase))
                            {
                                list.Add(c);
                            }
                        }

                        if (list.Count > 0)
                        {
                            httpRequest.Connection = String.Join(", ", list.ToArray());
                        }
                        break;

                    case "Transfer-Encoding":
                        httpRequest.SendChunked      = true;
                        httpRequest.TransferEncoding = context.Request.Headers[name];
                        break;

                    case "Expect":
                        httpRequest.ServicePoint.Expect100Continue = true;
                        break;

                    case "If-Modified-Since":
                        DateTime ifModifiedSince;
                        if (DateTime.TryParse(context.Request.Headers[name], out ifModifiedSince))
                        {
                            httpRequest.IfModifiedSince = ifModifiedSince;
                        }
                        break;

                    case "Content-Length":
                        httpRequest.ContentLength = context.Request.ContentLength;
                        break;

                    case "Content-Type":
                        httpRequest.ContentType = context.Request.ContentType;
                        break;

                    case "Accept":
                        httpRequest.Accept = String.Join(", ", context.Request.AcceptTypes);
                        break;

                    case "Referer":
                        httpRequest.Referer = context.Request.UrlReferrer.OriginalString;
                        break;
                    }

                    // add to header if not restricted
                    if (!WebHeaderCollection.IsRestricted(name, false))
                    {
                        // it is nessisary to get the values for headers that are allowed to specifiy
                        // multiple values in an instance (i.e. Cookie)
                        string[] values = context.Request.Headers.GetValues(name);
                        foreach (string value in values)
                        {
                            request.Headers.Add(name, value);
                        }
                    }
                }
            }

            // Add Proxy Standard Protocol Headers
            // http://en.wikipedia.org/wiki/X-Forwarded-For
            request.Headers.Add("X-Forwarded-For", context.Request.UserHostAddress);
            // Add Server Variables
            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45
            string currentServerName     = context.Request.ServerVariables["SERVER_NAME"];
            string currentServerPort     = context.Request.ServerVariables["SERVER_PORT"];
            string currentServerProtocol = context.Request.ServerVariables["SERVER_PROTOCOL"];

            if (currentServerProtocol.IndexOf("/") >= 0)
            {
                currentServerProtocol = currentServerProtocol.Substring(currentServerProtocol.IndexOf("/") + 1);
            }

            string currentVia = String.Format("{0} {1}:{2} ({3})", currentServerProtocol, currentServerName, currentServerPort, "Monoscape.LoadBalancerController");

            request.Headers.Add("Via", currentVia);

            //
            // ContentLength is set to -1 if their is no data to send
            if ((request.ContentLength >= 0) && (!knownVerb.ContentBodyNotAllowed))
            {
                int bufferSize = 64 * 1024;
                using (Stream requestStream = request.GetRequestStream(), bufferStream = new BufferedStream(context.Request.InputStream, bufferSize))
                {
                    byte[] buffer = new byte[bufferSize];

                    try
                    {
                        while (true)
                        {
                            // make sure that the stream can be read from
                            if (!bufferStream.CanRead)
                            {
                                break;
                            }
                            int bytesReturned = bufferStream.Read(buffer, 0, bufferSize);
                            // if not bytes were returned the end of the stream has been reached
                            // and the loop should exit
                            if (bytesReturned == 0)
                            {
                                break;
                            }
                            // write bytes to the response
                            requestStream.Write(buffer, 0, bytesReturned);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(typeof(ProxyHandler), "", e);
                    }
                }
            }

            WebResponse response;

            try
            {
                // Increment application instance request count
                //incremented = IncrementRequestCount(rpContext.ApplicationInstance);
                if (addReqResult != null)
                {
                    int requestId = rpContext.AddReqCaller.EndInvoke(addReqResult);
                    // Remove request from load balancer request queue
                    ASyncRemoveRequestFromQueue caller = new ASyncRemoveRequestFromQueue(RemoveRequestFromQueue);
                    caller.BeginInvoke(requestId, null, null);
                }
                // Send request to the proxy target
                response = request.GetResponse();
            }
            catch (WebException e)
            {
                Log.Error(typeof(ProxyHandler), "Error received from " + request.RequestUri + ": " + e.Message, e);
                response = e.Response;
            }

            if (response == null)
            {
                Log.Error(typeof(ProxyHandler), "The requested url " + requestUrl + " could not be found.");
                throw new HttpException((int)HttpStatusCode.NotFound, "The requested url could not be found.");
            }

            Log.Info(typeof(ProxyHandler), response.GetType().ToString());
            if (response is HttpWebResponse)
            {
                HttpWebResponse httpResponse = response as HttpWebResponse;
                Log.Info(typeof(ProxyHandler), "Received '" + ((int)httpResponse.StatusCode) + " " + httpResponse.StatusDescription + "'");
            }
            return(response);
        }