当前位置: 首页 > 知识库问答 >
问题:

如何从一个端口为Jetty提供https和超文本传输协议?

程吕恭
2023-03-14

(我知道这是一个重复的问题,但楼主问的原因是错误的。我不是在暗示我问的原因是正确的,但让我们看看。)

我们有一个在非标准端口号上运行的web服务。尽管用户似乎能够记住端口号,但有时他们会错误地键入http:而不是https:。有人问我们是否可以在该端口上提供HTTP服务,然后将它们重定向到同一端口上的HTTPS。听起来很邪恶。。。我喜欢它的可用性,但感觉也许这应该是浏览器的工作?

我看到的一个解决方案是“在Jetty前面编写自己的代理”这个解决方案会起作用,但我不认为它会起作用,因为我不相信我能编写一个与Jetty本身一样高效的代理。此外,即使代理本身是有效的,所有数据仍然需要进行额外的跳跃,这保证了无论如何都会减慢流量。

还有比这更好的方法吗?也许Jetty本身有一些地方可以嵌入协议检测逻辑,这将允许利用它们的速度,同时还可以消除代理引入的额外跃点。

共有3个答案

全冥夜
2023-03-14

基于答案“是的,我们可以”,我构建了适用于当前码头9.3.11的代码,我想有些人会感兴趣。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ReadPendingException;
import java.nio.channels.WritePendingException;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;

public class MyReadAheadEndpoint implements EndPoint {
/** real endpoint we are wrapping    */ private final EndPoint endPoint;
/** buffer used to read start bytes  */ private final ByteBuffer start     ;
/** how many N start bytes to read   */ private       int        leftToRead;
/** first  N bytes                   */ private final byte[]     bytes     ;
/** buffered exception to throw next */ private IOException pendingException = null;
@Override public InetSocketAddress getLocalAddress            () { return endPoint.getLocalAddress(); }
@Override public InetSocketAddress getRemoteAddress           () { return endPoint.getRemoteAddress(); }
@Override public boolean           isOpen                     () { return endPoint.isOpen(); }
@Override public long              getCreatedTimeStamp        () { return endPoint.getCreatedTimeStamp(); }
@Override public boolean           isOutputShutdown           () { return endPoint.isOutputShutdown(); }
@Override public boolean           isInputShutdown            () { return endPoint.isInputShutdown(); }
@Override public void              shutdownOutput             () { endPoint.shutdownOutput(); }
@Override public void              close                      () { endPoint.close(); }
@Override public Object            getTransport               () { return endPoint.getTransport(); }
@Override public long              getIdleTimeout             () { return endPoint.getIdleTimeout(); }
@Override public Connection        getConnection              () { return endPoint.getConnection(); }
@Override public void              onOpen                     () { endPoint.onOpen(); }
@Override public void              onClose                    () { endPoint.onClose(); }
@Override public boolean           isOptimizedForDirectBuffers() { return endPoint.isOptimizedForDirectBuffers(); }
@Override public boolean           isFillInterested           () { return endPoint.isFillInterested(); }
@Override public boolean           flush                      (final ByteBuffer... v) throws IOException { return endPoint.flush(v); }
@Override public void              setIdleTimeout             (final long          v) { endPoint.setIdleTimeout(v); }
@Override public void              write                      (final Callback      v, final ByteBuffer... b) throws WritePendingException { endPoint.write(v, b); }
@Override public void              setConnection              (final Connection    v) { endPoint.setConnection(v); }
@Override public void              upgrade                    (final Connection    v) { endPoint.upgrade(v); }
@Override public void              fillInterested  (final Callback   v) throws ReadPendingException { endPoint.fillInterested(v); }
@Override public int               hashCode() { return endPoint.hashCode(); }
@Override public boolean           equals(final Object obj) { return endPoint.equals(obj); }
@Override public String            toString() { return endPoint.toString(); }
public byte[] getBytes() { if (pendingException == null) { try { readAhead(); } catch (final IOException e) { pendingException = e; } } return bytes; }
private void throwPendingException() throws IOException { if (pendingException != null) { final IOException e = pendingException; pendingException = null; throw e; } }

public MyReadAheadEndpoint(final EndPoint channel, final int readAheadLength){
    this.endPoint = channel;
    start = ByteBuffer.wrap(bytes = new byte[readAheadLength]);
    start.flip();
    leftToRead = readAheadLength;
}

private synchronized void readAhead() throws IOException {
    if (leftToRead > 0) {
        final int n = endPoint.fill(start);
        if (n == -1) { leftToRead = -1; }
        else         {  leftToRead -= n; }
        if (leftToRead <= 0) start.rewind();
    }
}

private int readFromStart(final ByteBuffer dst) throws IOException {
    final int n = Math.min(dst.remaining(), start.remaining());
    if (n > 0)  {
        dst.put(bytes, start.position(), n);
        start.position(start.position() + n);
        dst.flip();
    }
    return n;
}

@Override public synchronized int fill(final ByteBuffer dst) throws IOException {
    throwPendingException();
    if (leftToRead > 0) readAhead();
    if (leftToRead > 0) return 0;
    final int sr = start.remaining();
    if (sr > 0) {
        dst.compact();
        final int n = readFromStart(dst);
        if (n < sr) return n;
    }
    return sr + endPoint.fill(dst);
}

}

import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.AbstractConnectionFactory;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.annotation.Name;
public class MySslConnectionFactory extends AbstractConnectionFactory {
private final SslContextFactory _sslContextFactory;
private final String _nextProtocol;

public MySslConnectionFactory() { this(HttpVersion.HTTP_1_1.asString()); }

public MySslConnectionFactory(@Name("next") final String nextProtocol) { this((SslContextFactory)null, nextProtocol); }

public MySslConnectionFactory(@Name("sslContextFactory") final SslContextFactory factory, @Name("next") final String nextProtocol) {
    super("SSL");
    this._sslContextFactory = factory == null?new SslContextFactory():factory;
    this._nextProtocol = nextProtocol;
    this.addBean(this._sslContextFactory);
}

public SslContextFactory getSslContextFactory() { return this._sslContextFactory; }

@Override protected void doStart() throws Exception {
    super.doStart();
    final SSLEngine engine = this._sslContextFactory.newSSLEngine();
    engine.setUseClientMode(false);
    final SSLSession session = engine.getSession();
    if(session.getPacketBufferSize() > this.getInputBufferSize()) this.setInputBufferSize(session.getPacketBufferSize());
}

@Override public Connection newConnection(final Connector connector, final EndPoint realEndPoint) {
    final MyReadAheadEndpoint aheadEndpoint = new MyReadAheadEndpoint(realEndPoint, 1);
    final byte[] bytes = aheadEndpoint.getBytes();
    final boolean isSSL;
    if (bytes == null || bytes.length == 0) {
        System.out.println("NO-Data in newConnection : "+aheadEndpoint.getRemoteAddress());
        isSSL = true;
    } else {
        final byte b = bytes[0];    // TLS first byte is 0x16 , SSLv2 first byte is >= 0x80 , HTTP is guaranteed many bytes of ASCII
        isSSL = b >= 0x7F || (b < 0x20 && b != '\n' && b != '\r' && b != '\t');
        if(!isSSL) System.out.println("newConnection["+isSSL+"] : "+aheadEndpoint.getRemoteAddress());
    }
    final EndPoint      plainEndpoint;
    final SslConnection sslConnection;
    if (isSSL) {
        final SSLEngine engine = this._sslContextFactory.newSSLEngine(aheadEndpoint.getRemoteAddress());
        engine.setUseClientMode(false);
        sslConnection = this.newSslConnection(connector, aheadEndpoint, engine);
        sslConnection.setRenegotiationAllowed(this._sslContextFactory.isRenegotiationAllowed());
        this.configure(sslConnection, connector, aheadEndpoint);
        plainEndpoint = sslConnection.getDecryptedEndPoint();
    } else {
        sslConnection = null;
        plainEndpoint = aheadEndpoint;
    }
    final ConnectionFactory next = connector.getConnectionFactory(_nextProtocol);
    final Connection connection = next.newConnection(connector, plainEndpoint);
    plainEndpoint.setConnection(connection);
    return sslConnection == null ? connection : sslConnection;
}

protected SslConnection newSslConnection(final Connector connector, final EndPoint endPoint, final SSLEngine engine) {
    return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine);
}

@Override public String toString() {
    return String.format("%s@%x{%s->%s}", new Object[]{this.getClass().getSimpleName(), Integer.valueOf(this.hashCode()), this.getProtocol(), this._nextProtocol});
}

}

丌官绍元
2023-03-14

更新:自jetty-9.4.15起。码头内置v20190215对港口统一的支持;请参见此答案。

这是可能的,我们已经做到了。此处的代码适用于Jetty 8;我没有使用Jetty 9进行测试,但这个答案与Jetty 9的代码类似。

顺便说一句,这被称为端口统一,显然Glassfish使用Grizzly长期以来一直支持它。

基本思想是生成一个org的实现。日食码头。服务器连接器,可以查看客户端请求的第一个字节。幸运的是,HTTP和HTTPS都让客户端启动了通信。对于HTTPS(通常是TLS/SSL),第一个字节将是0x16(TLS)或

在这里的代码中,我们利用了Jetty的SslSelectChannelConnector本身扩展了SelectChannelConnector,并有一个newPlainConnection()方法(调用其超类来生成非SSL连接)和一个newConnection()方法(生成SSL连接)。因此,我们的新连接器可以扩展SslSelectChannelConnector,并在观察客户端的第一个字节后委托给其中一个方法。

不幸的是,我们需要在第一个字节可用之前创建AsyncConnection的实例。该实例的某些方法甚至可以在第一个字节可用之前调用。因此,我们创建了一个LazyConnection实现了AsyncConnection,它可以在以后确定它将委托给哪种连接,甚至在它知道之前将合理的默认响应返回给某些方法。

基于NIO,我们的Connector将与SocketChannel一起使用。幸运的是,我们可以扩展SocketChannel以创建ReadAhead SocketChannelWrapper,它委托给“真正的”SocketChannel,但可以检查和存储客户端消息的第一个字节。

一个非常粗糙的部分。我们的连接器必须覆盖的方法之一是自定义(endpoint、请求)。如果我们最终得到一个基于SSL的endpoint,那么我们可以直接传递到我们的超类;否则,超类将抛出ClassCastException,但只有在传递到其超类并在请求上设置scheme之后。因此,我们传递给超类,但在看到异常时撤消设置方案。

我们还重写了isConfidential()和isIntegral(),以确保servlet可以正确使用HttpServletRequest。isSecure()以确定是否使用了HTTP或HTTPS。

尝试从客户端读取第一个字节可能会抛出一个IOException,但我们可能必须在不需要IOException的地方进行尝试,在这种情况下,我们会保留异常并稍后抛出。

扩展SocketChannel在Java中看起来不同

public class PortUnificationSelectChannelConnector extends SslSelectChannelConnector {
    public PortUnificationSelectChannelConnector() {
        super();
    }

    public PortUnificationSelectChannelConnector(SslContextFactory sslContextFactory) {
        super(sslContextFactory);
    }

    @Override
    protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException {
        return super.newEndPoint(new ReadAheadSocketChannelWrapper(channel, 1), selectSet, key);
    }

    @Override
    protected AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endPoint) {
        return new LazyConnection((ReadAheadSocketChannelWrapper)channel, endPoint);
    }

    @Override
    public void customize(EndPoint endpoint, Request request) throws IOException {
        String scheme = request.getScheme();
        try {
            super.customize(endpoint, request);
        } catch (ClassCastException e) {
            request.setScheme(scheme);
        }
    }

    @Override
    public boolean isConfidential(Request request) {
        if (request.getAttribute("javax.servlet.request.cipher_suite") != null) return true;
        else return isForwarded() && request.getScheme().equalsIgnoreCase(HttpSchemes.HTTPS);
    }

    @Override
    public boolean isIntegral(Request request) {
        return isConfidential(request);
    }

    class LazyConnection implements AsyncConnection {
        private final ReadAheadSocketChannelWrapper channel;
        private final AsyncEndPoint endPoint;
        private final long timestamp;
        private AsyncConnection connection;

        public LazyConnection(ReadAheadSocketChannelWrapper channel, AsyncEndPoint endPoint) {
            this.channel = channel;
            this.endPoint = endPoint;
            this.timestamp = System.currentTimeMillis();
            this.connection = determineNewConnection(channel, endPoint, false);
        }

        public Connection handle() throws IOException {
            if (connection == null) {
                connection = determineNewConnection(channel, endPoint, false);
                channel.throwPendingException();
            }
            if (connection != null) return connection.handle();
            else return this;
        }

        public long getTimeStamp() {
            return timestamp;
        }

        public void onInputShutdown() throws IOException {
            if (connection == null) connection = determineNewConnection(channel, endPoint, true);
            connection.onInputShutdown();
        }

        public boolean isIdle() {
            if (connection == null) connection = determineNewConnection(channel, endPoint, false);
            if (connection != null) return connection.isIdle();
            else return false;
        }

        public boolean isSuspended() {
            if (connection == null) connection = determineNewConnection(channel, endPoint, false);
            if (connection != null) return connection.isSuspended();
            else return false;
        }

        public void onClose() {
            if (connection == null) connection = determineNewConnection(channel, endPoint, true);
            connection.onClose();
        }

        public void onIdleExpired(long l) {
            if (connection == null) connection = determineNewConnection(channel, endPoint, true);
            connection.onIdleExpired(l);
        }

        AsyncConnection determineNewConnection(ReadAheadSocketChannelWrapper channel, AsyncEndPoint endPoint, boolean force) {
            byte[] bytes = channel.getBytes();
            if ((bytes == null || bytes.length == 0) && !force) return null;
            if (looksLikeSsl(bytes)) {
                return PortUnificationSelectChannelConnector.super.newConnection(channel, endPoint);
            } else {
                return PortUnificationSelectChannelConnector.super.newPlainConnection(channel, endPoint);
            }
        }

        // TLS first byte is 0x16
        // SSLv2 first byte is >= 0x80
        // HTTP is guaranteed many bytes of ASCII
        private boolean looksLikeSsl(byte[] bytes) {
            if (bytes == null || bytes.length == 0) return false; // force HTTP
            byte b = bytes[0];
            return b >= 0x7F || (b < 0x20 && b != '\n' && b != '\r' && b != '\t');
        }
    }

    static class ReadAheadSocketChannelWrapper extends SocketChannel {
        private final SocketChannel channel;
        private final ByteBuffer start;
        private byte[] bytes;
        private IOException pendingException;
        private int leftToRead;

        public ReadAheadSocketChannelWrapper(SocketChannel channel, int readAheadLength) throws IOException {
            super(channel.provider());
            this.channel = channel;
            start = ByteBuffer.allocate(readAheadLength);
            leftToRead = readAheadLength;
            readAhead();
        }

        public synchronized void readAhead() throws IOException {
            if (leftToRead > 0) {
                int n = channel.read(start);
                if (n == -1) {
                    leftToRead = -1;
                } else {
                    leftToRead -= n;
                }
                if (leftToRead <= 0) {
                    start.flip();
                    bytes = new byte[start.remaining()];
                    start.get(bytes);
                    start.rewind();
                }
            }
        }

        public byte[] getBytes() {
            if (pendingException == null) {
                try {
                    readAhead();
                } catch (IOException e) {
                    pendingException = e;
                }
            }
            return bytes;
        }

        public void throwPendingException() throws IOException {
            if (pendingException != null) {
                IOException e = pendingException;
                pendingException = null;
                throw e;
            }
        }

        private int readFromStart(ByteBuffer dst) throws IOException {
            int sr = start.remaining();
            int dr = dst.remaining();
            if (dr == 0) return 0;
            int n = Math.min(dr, sr);
            dst.put(bytes, start.position(), n);
            start.position(start.position() + n);
            return n;
        }

        public synchronized int read(ByteBuffer dst) throws IOException {
            throwPendingException();
            readAhead();
            if (leftToRead > 0) return 0;
            int sr = start.remaining();
            if (sr > 0) {
                int n = readFromStart(dst);
                if (n < sr) return n;
            }
            return sr + channel.read(dst);
        }

        public synchronized long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
            throwPendingException();
            if (offset + length > dsts.length || length < 0 || offset < 0) {
                throw new IndexOutOfBoundsException();
            }
            readAhead();
            if (leftToRead > 0) return 0;
            int sr = start.remaining();
            int newOffset = offset;
            if (sr > 0) {
                int accum = 0;
                for (; newOffset < offset + length; newOffset++) {
                    accum += readFromStart(dsts[newOffset]);
                    if (accum == sr) break;
                }
                if (accum < sr) return accum;
            }
            return sr + channel.read(dsts, newOffset, length - newOffset + offset);
        }

        public int hashCode() {
            return channel.hashCode();
        }

        public boolean equals(Object obj) {
            return channel.equals(obj);
        }

        public String toString() {
            return channel.toString();
        }

        public Socket socket() {
            return channel.socket();
        }

        public boolean isConnected() {
            return channel.isConnected();
        }

        public boolean isConnectionPending() {
            return channel.isConnectionPending();
        }

        public boolean connect(SocketAddress remote) throws IOException {
            return channel.connect(remote);
        }

        public boolean finishConnect() throws IOException {
            return channel.finishConnect();
        }

        public int write(ByteBuffer src) throws IOException {
            return channel.write(src);
        }

        public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
            return channel.write(srcs, offset, length);
        }

        @Override
        protected void implCloseSelectableChannel() throws IOException {
            channel.close();
        }

        @Override
        protected void implConfigureBlocking(boolean block) throws IOException {
            channel.configureBlocking(block);
        }

//        public SocketAddress getLocalAddress() throws IOException {
//            return channel.getLocalAddress();
//        }
//
//        public <T> T getOption(java.net.SocketOption<T> name) throws IOException {
//            return channel.getOption(name);
//        }
//
//        public Set<java.net.SocketOption<?>> supportedOptions() {
//            return channel.supportedOptions();
//        }
//
//        public SocketChannel bind(SocketAddress local) throws IOException {
//            return channel.bind(local);
//        }
//
//        public SocketAddress getRemoteAddress() throws IOException {
//            return channel.getRemoteAddress();
//        }
//
//        public <T> SocketChannel setOption(java.net.SocketOption<T> name, T value) throws IOException {
//            return channel.setOption(name, value);
//        }
//
//        public SocketChannel shutdownInput() throws IOException {
//            return channel.shutdownInput();
//        }
//
//        public SocketChannel shutdownOutput() throws IOException {
//            return channel.shutdownOutput();
//        }
    }
}
张和豫
2023-03-14

更新:有关如何将单个端口重定向到HTTPS和HTTP侦听器的说明,请参阅此答案。如果出于任何原因,您不使用该解决方案,请参见以下内容:

<罢工> 不可能在同一个端口上同时从超文本传输协议和https传输流量。Jetty使用两个完全不同的连接器来绑定到安全和不安全的端口。事实上,我遇到的每台Web服务器都将这两个协议绑定到两个完全不同的端口。

出于可用性考虑,我建议使用默认端口,这会对用户完全隐藏端口。默认情况下,http使用端口80,默认情况下,https使用端口443。因此,如果您将连接器配置为分别在端口80和端口443上运行,那么您的用户不必键入端口,您的开发团队也不必处理在HTML、CSS、JavaScript和其他资源的绝对路径中包含端口号的问题。

Jetty被设计成一个独立的Web服务器,与较早版本的Tomcat不同,Apache建议Tomcat在Apache HTTP服务器之后运行。因此,只要您没有其他HTTP服务器在运行,并且使用这些端口,您就应该能够将Jetty配置为在默认端口上运行,而不会出现任何问题。这来自经验。我们正是以这种方式经营码头的。

最后,一个协议可以绑定到多个端口。因此,如果您当前在端口8080上运行Jetty用于超文本传输协议,在端口8443上运行Jetty用于https,您可以保持这些连接器处于活动状态,并为端口80和端口443添加另外两个连接器。这为您的应用程序中仍在使用端口号的部分启用了向后兼容性,并为您提供了前进的时间。

<!-- Legacy HTTP connector -->
<Call name="addConnector">
  <Arg>
      <New class="org.mortbay.jetty.nio.SelectChannelConnector">
        <Set name="host"><SystemProperty name="jetty.host" /></Set>
        <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
        <Set name="maxIdleTime">30000</Set>
        <Set name="Acceptors">2</Set>
        <Set name="statsOn">false</Set>
        <Set name="confidentialPort">8443</Set>
        <Set name="lowResourcesConnections">5000</Set>
        <Set name="lowResourcesMaxIdleTime">5000</Set>
      </New>
  </Arg>
</Call>
<!-- Second connector for http on port 80 -->
<Call name="addConnector">
  <Arg>
      <New class="org.mortbay.jetty.nio.SelectChannelConnector">
        <Set name="host"><SystemProperty name="jetty.host" /></Set>
        <Set name="port"><SystemProperty name="jetty.port" default="80"/></Set>
        <Set name="maxIdleTime">30000</Set>
        <Set name="Acceptors">2</Set>
        <Set name="statsOn">false</Set>
        <Set name="confidentialPort">8443</Set>
        <Set name="lowResourcesConnections">5000</Set>
        <Set name="lowResourcesMaxIdleTime">5000</Set>
      </New>
  </Arg>
</Call>

<!-- Legacy SSL Connector for https port 8443 -->
<Call name="addConnector">
 <Arg>
  <New class="org.mortbay.jetty.security.SslSocketConnector">
    <Set name="Port">8443</Set>
    <Set name="maxIdleTime">30000</Set>
    <Set name="handshakeTimeout">2000</Set>
    <Set name="keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
    <Set name="password">xxxxxx</Set>
    <Set name="keyPassword">xxxxxx</Set>
    <Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
    <Set name="trustPassword">OBF:xxxxx</Set>
    <Set name="handshakeTimeout">2000</Set>
    <!-- Set name="ThreadPool">
      <New class="org.mortbay.thread.BoundedThreadPool">
        <Set name="minThreads">10</Set>
        <Set name="maxThreads">250</Set>
     </New>
    </Set -->
  </New>
 </Arg>
</Call>



<!-- Default SSL Connector for https port 443 -->
<Call name="addConnector">
 <Arg>
  <New class="org.mortbay.jetty.security.SslSocketConnector">
    <Set name="Port">443</Set>
    <Set name="maxIdleTime">30000</Set>
    <Set name="handshakeTimeout">2000</Set>
    <Set name="keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
    <Set name="password">xxxxxx</Set>
    <Set name="keyPassword">xxxxxx</Set>
    <Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
    <Set name="trustPassword">OBF:xxxxx</Set>
    <Set name="handshakeTimeout">2000</Set>
    <!-- Set name="ThreadPool">
      <New class="org.mortbay.thread.BoundedThreadPool">
        <Set name="minThreads">10</Set>
        <Set name="maxThreads">250</Set>
     </New>
    </Set -->
  </New>
 </Arg>
</Call>

对于第2个和第4个连接器,唯一真正的区别是端口号。简而言之,您可以为每个连接器/协议配置多个端口,但不能为同一端口配置多个协议/连接器。

 类似资料:
  • 我正在使用oauth签名生成我的oauth签名,以便与woocommerce api连接。我遵循了woocommerce rest api文档中所述的所有步骤: 所需的参数是:oauth_consumer_密钥、oauth_时间戳、oauth_nonce、oauth_签名和oauth_签名方法。oauth_版本不是必需的,应该省略。OAuth nonce可以是消费者密钥唯一的任意随机生成的32个字

  • 有可能发球吗。只使用来自节点的http模块,而不使用任何其他框架?我是否拥有一个简单web应用程序所需的所有功能? 这就是我尝试过的: 是否有一些步骤我错过了,或者我需要阅读一些东西来了解文件是如何链接的?

  • 我们在Glassfish v4上创建了一个网站,它使用8080端口作为http,8081端口作为https。我们的cisco防火墙将请求转发到端口80到端口8080,并将请求转发到端口443到端口8081。 但是我们不希望用户能够访问超文本传输协议网站。我们希望将所有请求重定向到超文本传输协议站点到https。怎么能做到呢?在Glassfish管理面板中,我们对配置进行了更改-

  • 我使用Laravel 8。用户点击一个包含id的链接#()我的应用程序从浏览器收到一个$请求,并通过我的问题是如何将id#输入php变量?

  • 我必须向一些没有任何参数的API发送GET请求,所以我编写了代码: 当API url是HTTP时,它可以工作,但不适用于HTTPS。它说: 太阳安全验证器。ValidatorException:PKIX路径生成失败:sun。安全供应商。certpath。SunCertPathBuilderException:找不到请求目标的有效证书路径;嵌套的异常是javax。网ssl。例外:太阳。安全验证器。V

  • 我已经安装了Apache 2.2负载平衡器和Weblogic 12c服务器。 我观察到一个https URL试图在我的应用程序中打开一个http URL,但没有成功,正如预期的那样。我搜索了一下为什么这会导致问题,并注意到了一些问题- http://geekexplains.blogspot.in/2008/06/https-becoming-http-in-case-of.html 当我试图寻找