一个以"http://"开头的网站是否可以使用HTTPS协议?

9
我有一个网站,其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;
}       

堆栈跟踪

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)                  

页面本身可以通过http加载,但是请求资源(脚本、图片等)通过https,这可能会导致出现该错误。 - Anthony Grist
我该如何解决这个错误 - 我应该使用HTTPSURLCONNECTION吗?目前我正在使用HTTPURLCONNECTION。 - linusunis fed
我已经把它添加到我的问题中了。谢谢。 - linusunis fed
也可能会有重定向。建议您使用 Fiddler 工具来确定连接实际上正在发生什么。 - Reacher Gilt
我对Fiddler不是很了解。你能详细说明一下吗? - linusunis fed
显示剩余3条评论
3个回答

15

你有注意到异常消息中不匹配的撇号吗?

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

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

提问者的根本问题在聊天会话中已经确定: 他正在访问一个将他重定向到https:// URL的http:// URL。该https地址的web服务器正在提供一个他的JRE / HttpClient不信任的证书。

实际的异常应该是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.

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

默认情况下,Java的Http[s]URLConnection会自动且悄无声息地遵循重定向。如果你想知道你被重定向到哪里,可以尝试以下代码:

connection.setInstanceFollowRedirects(false);
String location = connection.getHeaderField("Location");
System.out.println("Redirected to: " + location);
请注意,您被重定向到的URL可能会进一步重定向,甚至达到 http.maxRedirects 次。重定向可以以这种方式“链接”。如果它们链接在一起,您需要继续遵循重定向,直到到达不发出重定向的URL为止。这就是当 setInstanceFollowRedirects(true) 时 URL 连接最终完成的地方。
此外,在 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有自己不同的HttpURLConnection实现,但它可能包含类似的逻辑以防止协议切换。 因此,即使提问者解决了证书信任问题,他仍然可能无法使用HttpURLConnection自动跟随从HTTP到HTTPS的重定向链。 解决方法是使用setInstanceFollowRedirects(false)手动跟随重定向。或直接访问HTTPS站点。


1
这是一个惊人的发现,全部基于一个无与伦比的撇号。好极了,霍姆斯先生! :) - fgysin

5

HTTP 是运行在 TCP/IP 协议上的协议。HTTPS 是基于安全套接字(SSL 或较新的 TLS)的 HTTP。那么 URL 是什么?它是用来标识资源的字符串,大致长这样:

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

请注意,有时我们不需要指定端口号,因为某些协议具有关联的“众所周知”的端口号。对于HTTP是80,对于HTTPS是443,因此这些数字是被暗示的。但是,请注意,您可以在任何端口上绑定服务器套接字:如果您告诉您的HTTP服务器程序将其套接字绑定到localhost上的端口8273,则它将愉快地执行此操作。
话虽如此,在您的情况下,消息显示“不支持的协议:https”。我们只能在这里猜测,但我认为您传递给URL的字符串不是您想要的。

1
URL可能是正确的,但代码可能是错误的。请发布整个方法。 - Raffaele
好的,我现在已经粘贴了整个方法。 - linusunis fed
1
@linusunisfed 谢谢。另外,你能把整个堆栈跟踪放在pastebin.com上吗? - Raffaele
1
@linusunisfed你的客户端不支持HTTPS,而目标站点将你重定向到HTTPS服务器。你可以选择更换客户端(或添加HTTPS支持),或者重新配置服务器以提供纯HTTP访问(如果它在你的控制范围内并且安全的话)。 - Raffaele
1
让我们在聊天中继续这个讨论 - linusunis fed
显示剩余2条评论

0
另一种可能性是HTTP地址响应3xx重定向响应到HTTPS URL,但您的客户端尝试跟随却不支持。 您可以通过使用tcpdump或wireshark捕获网络流量来验证。
有很多Java HTTP客户端库支持HTTPS,为什么不切换到其中之一呢?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接