Beispiel #1
0
        public virtual void TestHasAdministratorAccess()
        {
            Configuration conf = new Configuration();

            conf.SetBoolean(CommonConfigurationKeys.HadoopSecurityAuthorization, false);
            ServletContext context = Org.Mockito.Mockito.Mock <ServletContext>();

            Org.Mockito.Mockito.When(context.GetAttribute(HttpServer2.ConfContextAttribute)).
            ThenReturn(conf);
            Org.Mockito.Mockito.When(context.GetAttribute(HttpServer2.AdminsAcl)).ThenReturn(
                null);
            HttpServletRequest request = Org.Mockito.Mockito.Mock <HttpServletRequest>();

            Org.Mockito.Mockito.When(request.GetRemoteUser()).ThenReturn(null);
            HttpServletResponse response = Org.Mockito.Mockito.Mock <HttpServletResponse>();

            //authorization OFF
            Assert.True(HttpServer2.HasAdministratorAccess(context, request
                                                           , response));
            //authorization ON & user NULL
            response = Org.Mockito.Mockito.Mock <HttpServletResponse>();
            conf.SetBoolean(CommonConfigurationKeys.HadoopSecurityAuthorization, true);
            NUnit.Framework.Assert.IsFalse(HttpServer2.HasAdministratorAccess(context, request
                                                                              , response));
            Org.Mockito.Mockito.Verify(response).SendError(Org.Mockito.Mockito.Eq(HttpServletResponse
                                                                                  .ScForbidden), Org.Mockito.Mockito.AnyString());
            //authorization ON & user NOT NULL & ACLs NULL
            response = Org.Mockito.Mockito.Mock <HttpServletResponse>();
            Org.Mockito.Mockito.When(request.GetRemoteUser()).ThenReturn("foo");
            Assert.True(HttpServer2.HasAdministratorAccess(context, request
                                                           , response));
            //authorization ON & user NOT NULL & ACLs NOT NULL & user not in ACLs
            response = Org.Mockito.Mockito.Mock <HttpServletResponse>();
            AccessControlList acls = Org.Mockito.Mockito.Mock <AccessControlList>();

            Org.Mockito.Mockito.When(acls.IsUserAllowed(Org.Mockito.Mockito.Any <UserGroupInformation
                                                                                 >())).ThenReturn(false);
            Org.Mockito.Mockito.When(context.GetAttribute(HttpServer2.AdminsAcl)).ThenReturn(
                acls);
            NUnit.Framework.Assert.IsFalse(HttpServer2.HasAdministratorAccess(context, request
                                                                              , response));
            Org.Mockito.Mockito.Verify(response).SendError(Org.Mockito.Mockito.Eq(HttpServletResponse
                                                                                  .ScForbidden), Org.Mockito.Mockito.AnyString());
            //authorization ON & user NOT NULL & ACLs NOT NULL & user in in ACLs
            response = Org.Mockito.Mockito.Mock <HttpServletResponse>();
            Org.Mockito.Mockito.When(acls.IsUserAllowed(Org.Mockito.Mockito.Any <UserGroupInformation
                                                                                 >())).ThenReturn(true);
            Org.Mockito.Mockito.When(context.GetAttribute(HttpServer2.AdminsAcl)).ThenReturn(
                acls);
            Assert.True(HttpServer2.HasAdministratorAccess(context, request
                                                           , response));
        }
Beispiel #2
0
        /// <summary>
        /// Get
        /// <see cref="Org.Apache.Hadoop.Security.UserGroupInformation"/>
        /// and possibly the delegation token out of
        /// the request.
        /// </summary>
        /// <param name="context">the ServletContext that is serving this request.</param>
        /// <param name="request">the http request</param>
        /// <param name="conf">configuration</param>
        /// <param name="secureAuthMethod">the AuthenticationMethod used in secure mode.</param>
        /// <param name="tryUgiParameter">Should it try the ugi parameter?</param>
        /// <returns>a new user from the request</returns>
        /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException">if the request has no token
        ///     </exception>
        /// <exception cref="System.IO.IOException"/>
        public static UserGroupInformation GetUGI(ServletContext context, HttpServletRequest
                                                  request, Configuration conf, UserGroupInformation.AuthenticationMethod secureAuthMethod
                                                  , bool tryUgiParameter)
        {
            UserGroupInformation ugi = null;
            string usernameFromQuery = GetUsernameFromQuery(request, tryUgiParameter);
            string doAsUserFromQuery = request.GetParameter(DoAsParam.Name);
            string remoteUser;

            if (UserGroupInformation.IsSecurityEnabled())
            {
                remoteUser = request.GetRemoteUser();
                string tokenString = request.GetParameter(DelegationParameterName);
                if (tokenString != null)
                {
                    // Token-based connections need only verify the effective user, and
                    // disallow proxying to different user.  Proxy authorization checks
                    // are not required since the checks apply to issuing a token.
                    ugi = GetTokenUGI(context, request, tokenString, conf);
                    CheckUsername(ugi.GetShortUserName(), usernameFromQuery);
                    CheckUsername(ugi.GetShortUserName(), doAsUserFromQuery);
                }
                else
                {
                    if (remoteUser == null)
                    {
                        throw new IOException("Security enabled but user not authenticated by filter");
                    }
                }
            }
            else
            {
                // Security's not on, pull from url or use default web user
                remoteUser = (usernameFromQuery == null) ? GetDefaultWebUserName(conf) : usernameFromQuery;
            }
            // not specified in request
            if (ugi == null)
            {
                // security is off, or there's no token
                ugi = UserGroupInformation.CreateRemoteUser(remoteUser);
                CheckUsername(ugi.GetShortUserName(), usernameFromQuery);
                if (UserGroupInformation.IsSecurityEnabled())
                {
                    // This is not necessarily true, could have been auth'ed by user-facing
                    // filter
                    ugi.SetAuthenticationMethod(secureAuthMethod);
                }
                if (doAsUserFromQuery != null)
                {
                    // create and attempt to authorize a proxy user
                    ugi = UserGroupInformation.CreateProxyUser(doAsUserFromQuery, ugi);
                    ProxyUsers.Authorize(ugi, GetRemoteAddr(request));
                }
            }
            if (Log.IsDebugEnabled())
            {
                Log.Debug("getUGI is returning: " + ugi.GetShortUserName());
            }
            return(ugi);
        }
Beispiel #3
0
            public override HttpServletRequest Request()
            {
                HttpServletRequest result = Org.Mockito.Mockito.Mock <HttpServletRequest>();

                Org.Mockito.Mockito.When(result.GetRemoteUser()).ThenReturn("User");
                return(result);
            }
        public virtual void TestGetJobCountersAcls()
        {
            HttpServletRequest hsr = Org.Mockito.Mockito.Mock <HttpServletRequest>();

            Org.Mockito.Mockito.When(hsr.GetRemoteUser()).ThenReturn(EnemyUser);
            try
            {
                hsWebServices.GetJobCounters(hsr, jobIdStr);
                NUnit.Framework.Assert.Fail("enemy can access job");
            }
            catch (WebApplicationException e)
            {
                NUnit.Framework.Assert.AreEqual(Response.Status.Unauthorized, Response.Status.FromStatusCode
                                                    (e.GetResponse().GetStatus()));
            }
            Org.Mockito.Mockito.When(hsr.GetRemoteUser()).ThenReturn(FriendlyUser);
            hsWebServices.GetJobCounters(hsr, jobIdStr);
        }
        private static UserGroupInformation GetUser(HttpServletRequest req)
        {
            string remoteUser = req.GetRemoteUser();
            UserGroupInformation callerUGI = null;

            if (remoteUser != null)
            {
                callerUGI = UserGroupInformation.CreateRemoteUser(remoteUser);
            }
            return(callerUGI);
        }
Beispiel #6
0
        private bool HasAccess(Org.Apache.Hadoop.Mapreduce.V2.App.Job.Job job, HttpServletRequest
                               request)
        {
            string remoteUser = request.GetRemoteUser();

            if (remoteUser != null)
            {
                return(job.CheckAccess(UserGroupInformation.CreateRemoteUser(remoteUser), JobACL.
                                       ViewJob));
            }
            return(true);
        }
Beispiel #7
0
        /// <exception cref="Javax.Servlet.ServletException"/>
        /// <exception cref="System.IO.IOException"/>
        protected override void DoGet(HttpServletRequest req, HttpServletResponse resp)
        {
            resp.SetContentType("text/plain");
            resp.SetStatus(HttpServletResponse.ScOk);
            string user      = req.GetRemoteUser();
            string principal = (req.GetUserPrincipal() != null) ? req.GetUserPrincipal().GetName
                                   () : null;
            TextWriter writer = resp.GetWriter();

            writer.Write(MessageFormat.Format("You are: user[{0}] principal[{1}]\n", user, principal
                                              ));
        }
Beispiel #8
0
        private HttpServletRequest GetMockRequest(string remoteUser, string user, string
                                                  doAs)
        {
            HttpServletRequest request = Org.Mockito.Mockito.Mock <HttpServletRequest>();

            Org.Mockito.Mockito.When(request.GetParameter(UserParam.Name)).ThenReturn(user);
            if (doAs != null)
            {
                Org.Mockito.Mockito.When(request.GetParameter(DoAsParam.Name)).ThenReturn(doAs);
            }
            Org.Mockito.Mockito.When(request.GetRemoteUser()).ThenReturn(remoteUser);
            return(request);
        }
Beispiel #9
0
        internal virtual bool HasAccess(Org.Apache.Hadoop.Mapreduce.V2.App.Job.Job job, HttpServletRequest
                                        request)
        {
            string remoteUser = request.GetRemoteUser();
            UserGroupInformation callerUGI = null;

            if (remoteUser != null)
            {
                callerUGI = UserGroupInformation.CreateRemoteUser(remoteUser);
            }
            if (callerUGI != null && !job.CheckAccess(callerUGI, JobACL.ViewJob))
            {
                return(false);
            }
            return(true);
        }
Beispiel #10
0
            // NOTHING
            /// <exception cref="System.IO.IOException"/>
            /// <exception cref="Javax.Servlet.ServletException"/>
            public virtual void DoFilter(ServletRequest request, ServletResponse response, FilterChain
                                         chain)
            {
                HttpServletRequest httpRequest = (HttpServletRequest)request;

                // if the user is already authenticated, don't override it
                if (httpRequest.GetRemoteUser() != null)
                {
                    chain.DoFilter(request, response);
                }
                else
                {
                    HttpServletRequestWrapper wrapper = new _HttpServletRequestWrapper_99(this, httpRequest
                                                                                          );
                    chain.DoFilter(wrapper, response);
                }
            }
        private AggregatedLogsBlockForTest GetAggregatedLogsBlockForTest(Configuration configuration
                                                                         , string user, string containerId)
        {
            HttpServletRequest request = Org.Mockito.Mockito.Mock <HttpServletRequest>();

            Org.Mockito.Mockito.When(request.GetRemoteUser()).ThenReturn(user);
            AggregatedLogsBlockForTest aggregatedBlock = new AggregatedLogsBlockForTest(configuration
                                                                                        );

            aggregatedBlock.SetRequest(request);
            aggregatedBlock.MoreParams()[YarnWebParams.ContainerId] = containerId;
            aggregatedBlock.MoreParams()[YarnWebParams.NmNodename]  = "localhost:1234";
            aggregatedBlock.MoreParams()[YarnWebParams.AppOwner]    = user;
            aggregatedBlock.MoreParams()["start"] = string.Empty;
            aggregatedBlock.MoreParams()["end"]   = string.Empty;
            aggregatedBlock.MoreParams()[YarnWebParams.EntityString] = "entity";
            return(aggregatedBlock);
        }
Beispiel #12
0
        public virtual void TestGetUgi()
        {
            conf.Set(DFSConfigKeys.FsDefaultNameKey, "hdfs://localhost:4321/");
            HttpServletRequest request = Org.Mockito.Mockito.Mock <HttpServletRequest>();
            ServletContext     context = Org.Mockito.Mockito.Mock <ServletContext>();
            string             user    = "******";
            Text userText = new Text(user);
            DelegationTokenIdentifier dtId = new DelegationTokenIdentifier(userText, userText
                                                                           , null);

            Org.Apache.Hadoop.Security.Token.Token <DelegationTokenIdentifier> token = new Org.Apache.Hadoop.Security.Token.Token
                                                                                       <DelegationTokenIdentifier>(dtId, new TestJspHelper.DummySecretManager(0, 0, 0,
                                                                                                                                                              0));
            string tokenString = token.EncodeToUrlString();

            Org.Mockito.Mockito.When(request.GetParameter(JspHelper.DelegationParameterName))
            .ThenReturn(tokenString);
            Org.Mockito.Mockito.When(request.GetRemoteUser()).ThenReturn(user);
            //Test attribute in the url to be used as service in the token.
            Org.Mockito.Mockito.When(request.GetParameter(JspHelper.NamenodeAddress)).ThenReturn
                ("1.1.1.1:1111");
            conf.Set(DFSConfigKeys.HadoopSecurityAuthentication, "kerberos");
            UserGroupInformation.SetConfiguration(conf);
            VerifyServiceInToken(context, request, "1.1.1.1:1111");
            //Test attribute name.node.address
            //Set the nnaddr url parameter to null.
            Org.Mockito.Mockito.When(request.GetParameter(JspHelper.NamenodeAddress)).ThenReturn
                (null);
            IPEndPoint addr = new IPEndPoint("localhost", 2222);

            Org.Mockito.Mockito.When(context.GetAttribute(NameNodeHttpServer.NamenodeAddressAttributeKey
                                                          )).ThenReturn(addr);
            VerifyServiceInToken(context, request, addr.Address.GetHostAddress() + ":2222");
            //Test service already set in the token
            token.SetService(new Text("3.3.3.3:3333"));
            tokenString = token.EncodeToUrlString();
            //Set the name.node.address attribute in Servlet context to null
            Org.Mockito.Mockito.When(context.GetAttribute(NameNodeHttpServer.NamenodeAddressAttributeKey
                                                          )).ThenReturn(null);
            Org.Mockito.Mockito.When(request.GetParameter(JspHelper.DelegationParameterName))
            .ThenReturn(tokenString);
            VerifyServiceInToken(context, request, "3.3.3.3:3333");
        }
Beispiel #13
0
            /// <exception cref="Javax.Servlet.ServletException"/>
            /// <exception cref="System.IO.IOException"/>
            protected override void DoGet(HttpServletRequest req, HttpServletResponse resp)
            {
                UserGroupInformation ugi = HttpUserGroupInformation.Get();

                if (ugi != null)
                {
                    string ret = "remoteuser="******":ugi=" + ugi.GetShortUserName
                                     ();
                    if (ugi.GetAuthenticationMethod() == UserGroupInformation.AuthenticationMethod.Proxy)
                    {
                        ret = "realugi=" + ugi.GetRealUser().GetShortUserName() + ":" + ret;
                    }
                    resp.SetStatus(HttpServletResponse.ScOk);
                    resp.GetWriter().Write(ret);
                }
                else
                {
                    resp.SetStatus(HttpServletResponse.ScInternalServerError);
                }
            }
        /// <exception cref="System.IO.IOException"/>
        protected internal virtual bool IsValidRequestor(HttpServletRequest request, Configuration
                                                         conf)
        {
            string remotePrincipal = request.GetUserPrincipal().GetName();
            string remoteShortName = request.GetRemoteUser();

            if (remotePrincipal == null)
            {
                // This really shouldn't happen...
                Log.Warn("Received null remoteUser while authorizing access to " + "GetJournalEditServlet"
                         );
                return(false);
            }
            if (Log.IsDebugEnabled())
            {
                Log.Debug("Validating request made by " + remotePrincipal + " / " + remoteShortName
                          + ". This user is: " + UserGroupInformation.GetLoginUser());
            }
            ICollection <string> validRequestors = new HashSet <string>();

            Sharpen.Collections.AddAll(validRequestors, DFSUtil.GetAllNnPrincipals(conf));
            try
            {
                validRequestors.AddItem(SecurityUtil.GetServerPrincipal(conf.Get(DFSConfigKeys.DfsSecondaryNamenodeKerberosPrincipalKey
                                                                                 ), SecondaryNameNode.GetHttpAddress(conf).GetHostName()));
            }
            catch (Exception e)
            {
                // Don't halt if SecondaryNameNode principal could not be added.
                Log.Debug("SecondaryNameNode principal could not be added", e);
                string msg = string.Format("SecondaryNameNode principal not considered, %s = %s, %s = %s"
                                           , DFSConfigKeys.DfsSecondaryNamenodeKerberosPrincipalKey, conf.Get(DFSConfigKeys
                                                                                                              .DfsSecondaryNamenodeKerberosPrincipalKey), DFSConfigKeys.DfsNamenodeSecondaryHttpAddressKey
                                           , conf.Get(DFSConfigKeys.DfsNamenodeSecondaryHttpAddressKey, DFSConfigKeys.DfsNamenodeSecondaryHttpAddressDefault
                                                      ));
                Log.Warn(msg);
            }
            // Check the full principal name of all the configured valid requestors.
            foreach (string v in validRequestors)
            {
                if (Log.IsDebugEnabled())
                {
                    Log.Debug("isValidRequestor is comparing to valid requestor: " + v);
                }
                if (v != null && v.Equals(remotePrincipal))
                {
                    if (Log.IsDebugEnabled())
                    {
                        Log.Debug("isValidRequestor is allowing: " + remotePrincipal);
                    }
                    return(true);
                }
            }
            // Additionally, we compare the short name of the requestor to this JN's
            // username, because we want to allow requests from other JNs during
            // recovery, but we can't enumerate the full list of JNs.
            if (remoteShortName.Equals(UserGroupInformation.GetLoginUser().GetShortUserName()
                                       ))
            {
                if (Log.IsDebugEnabled())
                {
                    Log.Debug("isValidRequestor is allowing other JN principal: " + remotePrincipal);
                }
                return(true);
            }
            if (Log.IsDebugEnabled())
            {
                Log.Debug("isValidRequestor is rejecting: " + remotePrincipal);
            }
            return(false);
        }
        /// <exception cref="System.IO.IOException"/>
        protected override void DoGet(HttpServletRequest req, HttpServletResponse resp)
        {
            try
            {
                string   userApprovedParamS = req.GetParameter(ProxyUriUtils.ProxyApprovalParam);
                bool     userWasWarned      = false;
                bool     userApproved       = Sharpen.Extensions.ValueOf(userApprovedParamS);
                bool     securityEnabled    = IsSecurityEnabled();
                string   remoteUser         = req.GetRemoteUser();
                string   pathInfo           = req.GetPathInfo();
                string[] parts = pathInfo.Split("/", 3);
                if (parts.Length < 2)
                {
                    Log.Warn("{} gave an invalid proxy path {}", remoteUser, pathInfo);
                    NotFound(resp, "Your path appears to be formatted incorrectly.");
                    return;
                }
                //parts[0] is empty because path info always starts with a /
                string        appId = parts[1];
                string        rest  = parts.Length > 2 ? parts[2] : string.Empty;
                ApplicationId id    = Apps.ToAppID(appId);
                if (id == null)
                {
                    Log.Warn("{} attempting to access {} that is invalid", remoteUser, appId);
                    NotFound(resp, appId + " appears to be formatted incorrectly.");
                    return;
                }
                if (securityEnabled)
                {
                    string   cookieName = GetCheckCookieName(id);
                    Cookie[] cookies    = req.GetCookies();
                    if (cookies != null)
                    {
                        foreach (Cookie c in cookies)
                        {
                            if (cookieName.Equals(c.GetName()))
                            {
                                userWasWarned = true;
                                userApproved  = userApproved || Sharpen.Extensions.ValueOf(c.GetValue());
                                break;
                            }
                        }
                    }
                }
                bool checkUser = securityEnabled && (!userWasWarned || !userApproved);
                AppReportFetcher.FetchedAppReport fetchedAppReport = null;
                ApplicationReport applicationReport = null;
                try
                {
                    fetchedAppReport = GetApplicationReport(id);
                    if (fetchedAppReport != null)
                    {
                        if (fetchedAppReport.GetAppReportSource() != AppReportFetcher.AppReportSource.Rm &&
                            fetchedAppReport.GetAppReportSource() != AppReportFetcher.AppReportSource.Ahs)
                        {
                            throw new NotSupportedException("Application report not " + "fetched from RM or history server."
                                                            );
                        }
                        applicationReport = fetchedAppReport.GetApplicationReport();
                    }
                }
                catch (ApplicationNotFoundException)
                {
                    applicationReport = null;
                }
                if (applicationReport == null)
                {
                    Log.Warn("{} attempting to access {} that was not found", remoteUser, id);
                    URI toFetch = ProxyUriUtils.GetUriFromTrackingPlugins(id, this.trackingUriPlugins
                                                                          );
                    if (toFetch != null)
                    {
                        ProxyUtils.SendRedirect(req, resp, toFetch.ToString());
                        return;
                    }
                    NotFound(resp, "Application " + appId + " could not be found " + "in RM or history server"
                             );
                    return;
                }
                string original = applicationReport.GetOriginalTrackingUrl();
                URI    trackingUri;
                if (original == null || original.Equals("N/A") || original.Equals(string.Empty))
                {
                    if (fetchedAppReport.GetAppReportSource() == AppReportFetcher.AppReportSource.Rm)
                    {
                        // fallback to ResourceManager's app page if no tracking URI provided
                        // and Application Report was fetched from RM
                        Log.Debug("Original tracking url is '{}'. Redirecting to RM app page", original ==
                                  null ? "NULL" : original);
                        ProxyUtils.SendRedirect(req, resp, StringHelper.Pjoin(rmAppPageUrlBase, id.ToString
                                                                                  ()));
                    }
                    else
                    {
                        if (fetchedAppReport.GetAppReportSource() == AppReportFetcher.AppReportSource.Ahs)
                        {
                            // fallback to Application History Server app page if the application
                            // report was fetched from AHS
                            Log.Debug("Original tracking url is '{}'. Redirecting to AHS app page", original
                                      == null ? "NULL" : original);
                            ProxyUtils.SendRedirect(req, resp, StringHelper.Pjoin(ahsAppPageUrlBase, id.ToString
                                                                                      ()));
                        }
                    }
                    return;
                }
                else
                {
                    if (ProxyUriUtils.GetSchemeFromUrl(original).IsEmpty())
                    {
                        trackingUri = ProxyUriUtils.GetUriFromAMUrl(WebAppUtils.GetHttpSchemePrefix(conf)
                                                                    , original);
                    }
                    else
                    {
                        trackingUri = new URI(original);
                    }
                }
                string runningUser = applicationReport.GetUser();
                if (checkUser && !runningUser.Equals(remoteUser))
                {
                    Log.Info("Asking {} if they want to connect to the " + "app master GUI of {} owned by {}"
                             , remoteUser, appId, runningUser);
                    WarnUserPage(resp, ProxyUriUtils.GetPathAndQuery(id, rest, req.GetQueryString(),
                                                                     true), runningUser, id);
                    return;
                }
                // Append the user-provided path and query parameter to the original
                // tracking url.
                IList <NameValuePair> queryPairs = URLEncodedUtils.Parse(req.GetQueryString(), null
                                                                         );
                UriBuilder builder = UriBuilder.FromUri(trackingUri);
                foreach (NameValuePair pair in queryPairs)
                {
                    builder.QueryParam(pair.GetName(), pair.GetValue());
                }
                URI toFetch_1 = builder.Path(rest).Build();
                Log.Info("{} is accessing unchecked {}" + " which is the app master GUI of {} owned by {}"
                         , remoteUser, toFetch_1, appId, runningUser);
                switch (applicationReport.GetYarnApplicationState())
                {
                case YarnApplicationState.Killed:
                case YarnApplicationState.Finished:
                case YarnApplicationState.Failed:
                {
                    ProxyUtils.SendRedirect(req, resp, toFetch_1.ToString());
                    return;
                }

                default:
                {
                    break;
                }
                }
                // fall out of the switch
                Cookie c_1 = null;
                if (userWasWarned && userApproved)
                {
                    c_1 = MakeCheckCookie(id, true);
                }
                ProxyLink(req, resp, toFetch_1, c_1, GetProxyHost());
            }
            catch (Exception e)
            {
                throw new IOException(e);
            }
        }
        /// <summary>Download link and have it be the response.</summary>
        /// <param name="req">the http request</param>
        /// <param name="resp">the http response</param>
        /// <param name="link">the link to download</param>
        /// <param name="c">the cookie to set if any</param>
        /// <exception cref="System.IO.IOException">on any error.</exception>
        private static void ProxyLink(HttpServletRequest req, HttpServletResponse resp, URI
                                      link, Cookie c, string proxyHost)
        {
            DefaultHttpClient client = new DefaultHttpClient();

            client.GetParams().SetParameter(ClientPNames.CookiePolicy, CookiePolicy.BrowserCompatibility
                                            ).SetBooleanParameter(ClientPNames.AllowCircularRedirects, true);
            // Make sure we send the request from the proxy address in the config
            // since that is what the AM filter checks against. IP aliasing or
            // similar could cause issues otherwise.
            IPAddress localAddress = Sharpen.Extensions.GetAddressByName(proxyHost);

            if (Log.IsDebugEnabled())
            {
                Log.Debug("local InetAddress for proxy host: {}", localAddress);
            }
            client.GetParams().SetParameter(ConnRoutePNames.LocalAddress, localAddress);
            HttpGet httpGet            = new HttpGet(link);
            Enumeration <string> names = req.GetHeaderNames();

            while (names.MoveNext())
            {
                string name = names.Current;
                if (passThroughHeaders.Contains(name))
                {
                    string value = req.GetHeader(name);
                    if (Log.IsDebugEnabled())
                    {
                        Log.Debug("REQ HEADER: {} : {}", name, value);
                    }
                    httpGet.SetHeader(name, value);
                }
            }
            string user = req.GetRemoteUser();

            if (user != null && !user.IsEmpty())
            {
                httpGet.SetHeader("Cookie", ProxyUserCookieName + "=" + URLEncoder.Encode(user, "ASCII"
                                                                                          ));
            }
            OutputStream @out = resp.GetOutputStream();

            try
            {
                HttpResponse httpResp = client.Execute(httpGet);
                resp.SetStatus(httpResp.GetStatusLine().GetStatusCode());
                foreach (Header header in httpResp.GetAllHeaders())
                {
                    resp.SetHeader(header.GetName(), header.GetValue());
                }
                if (c != null)
                {
                    resp.AddCookie(c);
                }
                InputStream @in = httpResp.GetEntity().GetContent();
                if (@in != null)
                {
                    IOUtils.CopyBytes(@in, @out, 4096, true);
                }
            }
            finally
            {
                httpGet.ReleaseConnection();
            }
        }