为啥从亚马逊弹性负载均衡器后面发送重定向时收到 502 错误网关?

Posted

技术标签:

【中文标题】为啥从亚马逊弹性负载均衡器后面发送重定向时收到 502 错误网关?【英文标题】:Why am I getting a 502 bad gateway when sending a redirect from behind amazon elastic load balancer?为什么从亚马逊弹性负载均衡器后面发送重定向时收到 502 错误网关? 【发布时间】:2013-08-02 01:39:23 【问题描述】:

我正在尝试将任何 HTTP 请求重定向到我的服务器到 HTTPS。

ELB 正在侦听端口 80 并将所有请求转发到我的应用程序上的端口 8088。然后,应用程序会发送一个 301 Moved Permanently 响应,重定向到相同的 URL,但会剥离所有端口并在前面加上“https://”。这会导致客户端通过 HTTPS 重新请求 url。

当我在本地测试它时,它工作正常,但是当我将它部署到弹性负载均衡器后面的 EC2 时,我得到 502 Bad Gateway 回来了。服务器正在接收请求并且似乎正在正确发送重定向(正如我所说,当我直接访问服务器时它可以工作,而不是通过负载平衡器)。

【问题讨论】:

【参考方案1】:

事实证明,ELB 对它认为是“有效”响应的内容非常挑剔,如果不满意,它将返回 502 Bad Gateway。我通过确保来自我的服务器的响应具有以下标头来修复它:

例如。如果我在http://example.com听

我发回以下回复:

HTTP/1.1 301 Moved Permanently
Content-Type: */*; charset="UTF-8"
Location: https://example.com/
Content-Length: 0

这让 ELB 很开心,一切正常。

出于兴趣,这里是代码(Java,使用Simpleframework):

private static void startHttpsRedirector() throws IOException 
    org.simpleframework.http.core.Container container = new org.simpleframework.http.core.Container() 
        @Override
        public void handle(Request request, Response response) 
            Path path = request.getPath();
            Query query = request.getQuery();
            String rawHost = request.getValue("host");

            System.out.println("Raw host: " + rawHost);
            System.out.println("Raw path: " + path);
            System.out.println("Raw query: " + query);

            String host = rawHost.replaceFirst("\\:.*", "");
            response.setStatus(Status.MOVED_PERMANENTLY);
            String redirectTo = "https://" + host + path + (query.values().size() > 0 ? "?" + query : "");

            System.out.println("redirectTo = " + redirectTo);
            response.setContentType("*/*; charset=\"UTF-8\"");
            response.setValue("Location", redirectTo);
            response.setContentLength(0);
            try 
                response.commit();
                response.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    ;
    Server server = new ContainerServer(container);
    Connection connection = new SocketConnection(server);
    SocketAddress address = new InetSocketAddress(8088);
    connection.connect(address);

同样的 javascript 代码可以在这里找到:https://gist.github.com/dhobbs/6164710

【讨论】:

以上是关于为啥从亚马逊弹性负载均衡器后面发送重定向时收到 502 错误网关?的主要内容,如果未能解决你的问题,请参考以下文章

在 Google 前端负载均衡器后面运行时如何正确从 Spring Boot 2.3 重定向到 HTTPS

如何使用 aws 弹性负载均衡器将 http 请求强制重定向到独立乘客中的 https?

如何在 ELB 应用程序负载均衡器上将 HTTPS 重定向到 HTTP

AWS 负载均衡器将 www.example.com 重定向到 example.com 不起作用

如何使用正则表达式在 url 中捕获 ec2 弹性 ip 模式 [重复]

如何让Elastic Beanstalk nginx支持的代理服务器从HTTP自动重定向到HTTPS?