Beispiel #1
0
 public static void Add(Host host, bool force= true)
 {
     if (force)
     {
         Remove(host);
     }
     _hosts.TryAdd(host.Name, host);
 }
Beispiel #2
0
        private string UnescapeRemoteUrl(Host host, string url, System.Web.HttpContextBase context)
        {
            string unescapedUrl = UnescapeRemoteUrl(host, url);
            if (string.IsNullOrEmpty(unescapedUrl))
            {
                context.Response.StatusCode = 500;
                context.Response.StatusDescription = "The URL could not be decoded.";
                context.Response.End();
            }

            return unescapedUrl;
        }
Beispiel #3
0
        /// <summary>
        /// Provides static access to get a host or force it to be loaded from configuration
        /// </summary>
        /// <param name="name">The name of the host from the configuraton file</param>
        /// <returns>Telligent.Evolution.Extensibility.Version1.Host</returns>
        public static Host Get(string name)
        {
            var cachedHost = OAuthAuthentication.GetConfiguration(name);
            if (cachedHost != null)
                return cachedHost as Host;

            var newHost = new Host(name, ServiceLocator.Get<IProxyService>(), ServiceLocator.Get<IHostConfigurationManager>(), ServiceLocator.Get<IUrlManipulationService>());
            OAuthAuthentication.RegisterConfiguration(newHost);

            return newHost;
        }
Beispiel #4
0
 public static void Remove(Host host)
 {
     Host removed = null;
     _hosts.TryRemove(host.Name, out removed);
 }
Beispiel #5
0
        public string UnescapeRemoteUrl(Host host, string url)
        {
            var cacheKey = "RemotingServer-RemoteUrl:" + url;
            var unescapedUrl = (string)host.Cache.Get(cacheKey);
            if (unescapedUrl == null)
            {
                var element = _rest.GetEndpointXml(host, 2, "remoting/url/unencode.xml?Url=" + Uri.EscapeDataString(url), false).Descendants("Url").FirstOrDefault();
                if (element == null || string.IsNullOrEmpty(element.Value))
                    unescapedUrl = string.Empty;
                else
                    unescapedUrl = element.Value;

                host.Cache.Put(cacheKey, unescapedUrl, 30 * 60);
            }

            return unescapedUrl;
        }
Beispiel #6
0
        public string MakeFullUrl(Host host, string url)
        {
            if (string.IsNullOrEmpty(url) || url.StartsWith("#"))
                return url;

            // support app-relative urls mapped to the Evolution Root
            if (url.StartsWith("~/"))
                url = url.Substring(2);

            Uri baseUrl = new Uri(host.EvolutionRootUrl);
            Uri combinedUrl = new Uri(baseUrl, url);

            string[] components = combinedUrl.AbsoluteUri.Split(new char[] { '?' }, 2);
            if (components.Length == 2)
                components[1] = host.ResolveRemoteUrlsToHostUrls(components[1]);

            return string.Join("?", components);
        }
Beispiel #7
0
 private void Redirect(Host host, System.Web.HttpContextBase context, string url)
 {
     context.Response.Redirect(MakeFullUrl(host, host.GetEvolutionRedirectUrl(url)));
 }
Beispiel #8
0
        private void ProcessProxiedResponse(Host host, System.Web.HttpContextBase context, ProxyInfo proxyInfo, HttpWebRequest request, HttpWebResponse response, string cacheKey)
        {
            var buffer = new byte[8 * 1024];
            int read;
            CachedProxyResponse cachedResponse = null;
            var cacheInfo = (request.Method != "GET") ? null : GetCacheInfo(response);
            MemoryStream cachedOutput = null;
            if (cacheInfo != null && ((cacheInfo.IsPublic && response.ContentLength < 256 * 1024 && ((int)response.StatusCode) - 200 < 100) || response.ContentLength < 64 * 1024))
            {
                cachedResponse = new CachedProxyResponse { Headers = new Dictionary<string, string>(), Status = ((int)response.StatusCode), StatusDescription = response.StatusDescription };
                cachedOutput = new MemoryStream();
            }

            context.Response.StatusCode = (int)response.StatusCode;
            context.Response.StatusDescription = response.StatusDescription;
            context.Response.TrySkipIisCustomErrors = true;

            foreach (string name in proxyInfo.ResponseHeaders)
            {
                if (!string.IsNullOrEmpty(response.Headers[name]))
                {
                    if (RestrictedResponseHeaders.ContainsKey(name))
                        AttemptSetRestrictedHeader(context.Response, name, response.Headers[name]);
                    else
                        context.Response.Headers[name] = response.Headers[name];

                    if (cachedResponse != null)
                        cachedResponse.Headers[name] = response.Headers[name];
                }
            }

            using (var outStream = context.Response.OutputStream)
            {
                using (var inStream = response.GetResponseStream())
                {
                    while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        outStream.Write(buffer, 0, read);
                        outStream.Flush();
                        if (cachedOutput != null)
                            cachedOutput.Write(buffer, 0, read);
                    }

                    inStream.Close();
                }

                outStream.Close();
            }

            if (cacheInfo != null && cachedResponse != null && cachedOutput != null && cachedOutput.Length < 256000)
            {
                cachedResponse.Content = cachedOutput.ToArray();
                if (cacheInfo.IsPublic)
                    host.Cache.Put(cacheKey, cachedResponse, cacheInfo.CacheDurationSeconds);
                else
                    System.Web.HttpContext.Current.Items[cacheKey] = cachedResponse;
            }
        }
Beispiel #9
0
        private ProxyInfo GetProxyInfo(Host host)
        {
            var proxyInfo = (ProxyInfo)host.Cache.Get(ProxyInfoCacheKey);
            if (proxyInfo == null)
            {
                var x = _rest .GetEndpointXml(host,2, "remoting/proxyinfo.xml", false);
                proxyInfo = new ProxyInfo();

                var e = x.Descendants("UrlPattern").FirstOrDefault();
                if (e != null)
                    proxyInfo.ShouldProxy = new Regex(e.Value, RegexOptions.Singleline | RegexOptions.IgnoreCase);

                e = x.Descendants("HttpRequestHeaders").FirstOrDefault();
                if (e != null)
                    proxyInfo.RequestHeaders = e.Descendants("string").Select(y => y.Value).ToArray();
                else
                    proxyInfo.RequestHeaders = new string[0];

                e = x.Descendants("HttpResponseHeaders").FirstOrDefault();
                if (e != null)
                    proxyInfo.ResponseHeaders = e.Descendants("string").Select(y => y.Value).ToArray();
                else
                    proxyInfo.ResponseHeaders = new string[0];

                host.Cache.Put(ProxyInfoCacheKey, proxyInfo, 60 * 10);
            }

            return proxyInfo;
        }
Beispiel #10
0
        private void Proxy(Host  host, System.Web.HttpContextBase context, string url, ProxyInfo proxyInfo)
        {
            CachedProxyResponse cachedResponse = null;
            string cacheKey = null;
            if (context.Request.HttpMethod == "GET")
            {
                cacheKey = string.Concat(host.Name, url);
                cachedResponse = (CachedProxyResponse)System.Web.HttpContext.Current.Items[cacheKey];
                if (cachedResponse == null)
                    cachedResponse = (CachedProxyResponse)host.Cache.Get(cacheKey);

                if (cachedResponse != null)
                {
                    context.Response.StatusCode = cachedResponse.Status;
                    context.Response.StatusDescription = cachedResponse.StatusDescription;
                    context.Response.TrySkipIisCustomErrors = true;

                    foreach (string name in cachedResponse.Headers.Keys)
                    {
                        if (RestrictedResponseHeaders.ContainsKey(name))
                            AttemptSetRestrictedHeader(context.Response, name, cachedResponse.Headers[name]);
                        else
                            context.Response.Headers[name] = cachedResponse.Headers[name];
                    }

                    using (var outputStream = context.Response.OutputStream)
                    {
                        outputStream.Write(cachedResponse.Content, 0, cachedResponse.Content.Length);
                        outputStream.Close();
                    }

                    return;
                }
            }

            bool retry = true;
            HttpWebRequest request = null;
            while (retry)
            {
                retry = false;

                try
                {
                    request = (HttpWebRequest)WebRequest.Create(MakeFullUrl(host, url));
                    request.Method = context.Request.HttpMethod;
                    request.Timeout = context.Request.HttpMethod == "GET" ? host.GetTimeout : host.PostTimeout;
                    host.ApplyAuthenticationToHostRequest(request, true);
                    host.ApplyRemoteHeadersToRequest(request);

                    foreach (string name in proxyInfo.RequestHeaders)
                    {
                        if (name.StartsWith("Cookie:"))
                        {
                            var cookieName = name.Substring(7);
                            var cookie = context.Request.Cookies[cookieName];
                            if (cookie != null)
                            {
                                if (request.CookieContainer == null)
                                    request.CookieContainer = new CookieContainer();

                                request.CookieContainer.Add(new Cookie(cookieName, cookie.Value, "/", request.RequestUri.Host));
                            }
                        }
                        else
                        {
                            var value = context.Request.Headers[name];
                            if (!string.IsNullOrEmpty(value))
                            {
                                if (WebHeaderCollection.IsRestricted(name))
                                    AttemptSetRestrictedHeader(request, name, value);
                                else
                                    request.Headers[name] = value;
                            }
                        }
                    }

                    if (request.Method == "POST")
                    {
                        // assume the content type is x-www-form-urlencoded if it isn't set (not great, but this occurs in the wild)
                        if (string.IsNullOrEmpty(request.ContentType) || request.ContentType.StartsWith("application/x-www-form-urlencoded"))
                        {
                            var buffer = new byte[(int)context.Request.ContentLength];
                            using (var inStream = context.Request.InputStream)
                            {
                                inStream.Read(buffer, 0, buffer.Length);
                                inStream.Close();
                            }

                            try
                            {
                                buffer = Encoding.UTF8.GetBytes(host.ResolveRemoteUrlsToHostUrls(Encoding.UTF8.GetString(buffer)));
                            }
                            catch
                            {
                                // this is likely because the content type wasn't set correctly, ignore.
                            }

                            request.ContentLength = buffer.Length;

                            using (var outStream = request.GetRequestStream())
                            {
                                outStream.Write(buffer, 0, buffer.Length);
                                outStream.Close();
                            }
                        }
                        else
                        {
                            request.ContentLength = context.Request.ContentLength;
                            var buffer = new byte[8 * 1024];
                            int read;

                            using (var inStream = context.Request.InputStream)
                            {
                                using (var outStream = request.GetRequestStream())
                                {
                                    while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        outStream.Write(buffer, 0, read);
                                    }

                                    outStream.Close();
                                }

                                inStream.Close();
                            }
                        }
                    }

                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        ProcessProxiedResponse(host, context, proxyInfo, request, response, cacheKey);
                    }
                }
                catch (WebException ex)
                {
                    var errorResponse = ex.Response as HttpWebResponse;
                    if (errorResponse != null)
                    {
                        if (errorResponse.StatusCode == HttpStatusCode.Forbidden && host.RetryFailedRemoteRequest(request))
                            retry = true;

                        if (!retry)
                            ProcessProxiedResponse(host, context, proxyInfo, request, errorResponse, cacheKey);
                    }
                    else
                        throw;
                }
            }
        }
Beispiel #11
0
        public void ProxyOrRedirect(Host host, string url, System.Web.HttpContextBase context)
        {
            var proxyInfo = GetProxyInfo(host);
            if (string.IsNullOrEmpty(url))
            {
                context.Response.StatusCode = 500;
                context.Response.StatusDescription = "The URL was null or empty.";
            }

            url = UnescapeRemoteUrl(host, url, context);
            if (!string.IsNullOrEmpty(url) && proxyInfo.ShouldProxy != null && proxyInfo.ShouldProxy.IsMatch(url))
                Proxy(host, context, url, proxyInfo);
            else
                Redirect(host, context, url);
        }