java 是否可以使用 HTTPS 协议使 URL 以“http://”开头的站点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14161386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:17:45  来源:igfitidea点击:

Is it possible for a site having URL starting with "http://" using HTTPS protocol

javahttphttps

提问by linusunis fed

I have a site whose URL starts with "http://" but that is giving me an exception with the message - Unsupported protocol: https. Is it possible that the site is using HTTPS protocol still its URL is starting with "http://" and not "https://".

我有一个网站,其 URL 以“http://”开头,但这给了我一个例外消息 - 不支持的协议:https。该站点是否可能使用 HTTPS 协议,但其 URL 仍以“http://”而不是“https://”开头。

public ActionForward executeAction(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      throws Exception {

    ActionForward forward = mapping.findForward(Constants.SUCCESS);
    String link = "http://abc.fgh.jkl.mno";
    URL thisURL;
    HttpURLConnection conn = null;
    try {
        thisURL = new URL(link);
        conn = (HttpURLConnection) thisURL.openConnection();
        System.out.println(conn.getResponseCode());
        System.out.println(conn.getResponseMessage());
        } catch (Exception ex) {
        ex.printStackTrace();
    }
    return forward;
}       

Stack trace

堆栈跟踪

java.net.ProtocolException: Unsupported protocol: https'
    at weblogic.net.http.HttpClient.openServer(HttpClient.java:342)
    at weblogic.net.http.HttpClient.New(HttpClient.java:238)
    at weblogic.net.http.HttpURLConnection.connect(HttpURLConnection.java:172)
    at weblogic.net.http.HttpURLConnection.followRedirect(HttpURLConnection.java:643)
    at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:422)
    at           weblogic.net.http.SOAPHttpURLConnection.getInputStream(SOAPHttpURLConnection.java:36)
    at weblogic.net.http.HttpURLConnection.getResponseCode(HttpURLConnection.java:947)
    at com.cingular.cscape.da.struts.action.thisAction.executeAction(thisAction.java:56)
    at com.cingular.cscape.da.struts.action.BaseAction.execute(BaseAction.java:300)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at org.extremecomponents.table.filter.AbstractExportFilter.doFilter(AbstractExportFilter.java:53)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3496)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(Unknown Source)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)                  

回答by Mike Clark

Did you notice the unmatched apostrophe in the exception message?

您是否注意到异常消息中不匹配的撇号?

java.net.ProtocolException: Unsupported protocol: https'
                                                       ^

Update: looks like this apostrophe is just a quirk of how the WebLogic HttpClient prints this exception.

更新:看起来这个撇号只是 WebLogic HttpClient 打印此异常的一个怪癖。

Asker's root problem was identified in a chat session: he's accessing an http:// URL that redirects him to an https:// URL. The webserver at that https address is serving up a certificate that his JRE/HttpClient does not trust.

在聊天会话中发现Asker 的根本问题:他正在访问一个 http:// URL,该 URL 将他重定向到一个 https:// URL。该 https 地址的网络服务器正在提供他的 JRE/HttpClient 不信任的证书。

The actual exception should be a SSLKeyException. I think the WebLogic HttpClient is misreporting this problem as an unsupported protocol issue. I think the core issue is:

实际的异常应该是 SSLKeyException。我认为 WebLogic HttpClient 将此问题误报为不受支持的协议问题。我认为核心问题是:

<Warning> <Security> <BEA-090477> javax.net.ssl.SSLKeyException: [Security:090477] Certificate chain received from www.X.com - nnn.nnn.nnn.nnn was not trusted causing SSL handshake failure.

<Warning> <Security> <BEA-090477> javax.net.ssl.SSLKeyException: [Security:090477] Certificate chain received from www.X.com - nnn.nnn.nnn.nnn was not trusted causing SSL handshake failure.

This is the message that the Asker sees when accessing the https:// URL directly (instead of through a redirect chain).

这是提问者在直接(而不是通过重定向链)访问 https:// URL 时看到的消息。

By default Java's Http[s]URLConnection follows redirects automatically and quietly. If you are curious about where you are being redirected to, try this code:

默认情况下,Java 的 Http[s]URLConnection 会自动且安静地跟随重定向。如果您对重定向到的位置感到好奇,请尝试以下代码:

connection.setInstanceFollowRedirects(false);
String location = connection.getHeaderField("Location");
System.out.println("Redirected to: " + location);

Note that the URL you get redirected to may also redirect you somewhere else and on and on, up to http.maxRedirectstimes. Redirects may "chain" in this way. If they do chain, you will need to keep following the redirects until you reach a URL that does not issue a redirect. That is where the URL connection eventually finalizes when setInstanceFollowRedirects(true).

请注意,您被重定向到的 URL 也可能将您重定向到其他地方,直到http.maxRedirects次。重定向可能以这种方式“链接”。如果它们确实链接,您将需要继续跟踪重定向,直到到达不发出重定向的 URL。这就是 URL 连接最终在setInstanceFollowRedirects(true).

Also, I found some code in sun.net.www.protocol.http.HttpURLConnection that seems to indicate that HttpURLConnection may not support switching protocols (HTTP -> HTTPS) as part of its automatic redirect following logic:

另外,我在 sun.net.www.protocol.http.HttpURLConnection 中发现了一些代码,似乎表明HttpURLConnection 可能不支持切换协议(HTTP - > HTTPS)作为其自动重定向以下逻辑的一部分

private boolean followRedirect() throws IOException {
    // ... [snip] ...
    if (!url.getProtocol().equalsIgnoreCase(locUrl.getProtocol())) {
        return false;
    // ... [snip] ...

WebLogic has its own (different) implementation of HttpURLConnection, but it may contain similar logic to prevent protocol switching. So, even if the Asker resolves his certificate trust issues, he still may not be able to use HttpURLConnection to automatically follow a redirect chain that goes from HTTP to HTTPS. A workaround would be to use setInstanceFollowRedirects(false)and follow redirects manually. Or access the HTTPS site directly.

WebLogic 有自己的(不同的)HttpURLConnection 实现,但它可能包含类似的逻辑来防止协议切换。因此,即使提问者解决了他的证书信任问题,他仍然可能无法使用 HttpURLConnection 自动跟踪从 HTTP 到 HTTPS 的重定向链。一种解决方法是setInstanceFollowRedirects(false)手动使用和跟踪重定向。或者直接访问HTTPS站点。

回答by Raffaele

HTTP is a protocol that runs on TCP/IP. HTTPS is HTTP on secure socket (SSL or newer TLS). Now, what is a URL? It's a string that identify a resource, and looks roughly like:

HTTP 是一种运行在 TCP/IP 上的协议。HTTPS 是基于安全套接字的 HTTP(SSL 或更新的 TLS)。现在,什么是 URL?它是一个标识资源的字符串,大致如下所示:

scheme://host:port/path/to/resource

Note that sometimes we don't specify the port number, because some protcols have an associated well-knownport number. For HTTP is 80, and for HTTPS is 443, so these numbers are implied. However, note that you can bind your server socket on whatever port you want to: if you tell your HTTP server program to bind its socket to the port 8273 on localhost, it will happily do so.

请注意,有时我们不指定端口号,因为某些协议具有关联的众所周知的端口号。对于 HTTP 是 80,对于 HTTPS 是 443,所以这些数字是隐含的。但是,请注意,您可以将服务器套接字绑定到您想要的任何端口:如果您告诉 HTTP 服务器程序将其套接字绑定到本地主机上的端口 8273,它会很乐意这样做。

Said that, in your case the message says "unsupported protocol: https". We can just guess here, however I think the string you pass to the URL is not the one you think.

说,在您的情况下,消息显示“不受支持的协议:https”。我们可以在这里猜测,但是我认为您传递给 URL 的字符串不是您想的那样。

回答by Szocske

Another possibility is the HTTP address responding with a 3xx redirect response to an HTTPS URL, which your client tries to follow, but does not support. You can very by capturing the network traffic with tcpdump or wireshark.

另一种可能性是 HTTP 地址响应 3xx 重定向响应到 HTTPS URL,您的客户端尝试遵循,但不支持。您可以使用 tcpdump 或wireshark 捕获网络流量。

There are so many Java HTTP client libraries that do support HTTPS, why not switch to one of those?

有这么多支持 HTTPS 的 Java HTTP 客户端库,为什么不切换到其中之一呢?