一、在应用java自带的HttpClient时, 发现一个景象,即有些以前罕用http的header, 是不可能set到申请里进行传递的,在jdk.internal.net.http.common.Utils类中,能够看到

    private static Set<String> getDisallowedHeaders() {        Set<String> headers = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);        headers.addAll(Set.of("connection", "content-length", "expect", "host", "upgrade"));        String v = getNetProperty("jdk.httpclient.allowRestrictedHeaders");        if (v != null) {            // any headers found are removed from set.            String[] tokens = v.trim().split(",");            for (String token : tokens) {                headers.remove(token);            }            return Collections.unmodifiableSet(headers);        } else {            return Collections.unmodifiableSet(headers);        }    }

connection, content-length, expect, host, upgrade这几个, 属于禁止设置的。因为在jdk.internal.net.http.HttpRequestBuilderImpl中, 会进行严格的校验

    private void checkNameAndValue(String name, String value) {        requireNonNull(name, "name");        requireNonNull(value, "value");        if (!isValidName(name)) {            throw newIAE("invalid header name: \"%s\"", name);        }        if (!Utils.ALLOWED_HEADERS.test(name, null)) {            throw newIAE("restricted header name: \"%s\"", name);        }        if (!isValidValue(value)) {            throw newIAE("invalid header value: \"%s\"", value);        }    }

二、它本人管制连贯的复用,所以设置不了connection这个header.从jdk.internal.net.http.ConnectionPool中能够看出一些参数

static final long KEEP_ALIVE = Utils.getIntegerNetProperty(            "jdk.httpclient.keepalive.timeout", 1200); // secondsstatic final long MAX_POOL_SIZE = Utils.getIntegerNetProperty(            "jdk.httpclient.connectionPoolSize", 0); // unbounded

从jdk.internal.net.http.HttpConnection中能够看到连贯如何放入池中

/**     * Forces a call to the native implementation of the     * connection's channel to verify that this channel is still     * open.     * <p>     * This method should only be called just after an HTTP/1.1     * connection is retrieved from the HTTP/1.1 connection pool.     * It is used to trigger an early detection of the channel state,     * before handling the connection over to the HTTP stack.     * It helps minimizing race conditions where the selector manager     * thread hasn't woken up - or hasn't raised the event, before     * the connection was retrieved from the pool. It helps reduce     * the occurrence of "HTTP/1.1 parser received no bytes"     * exception, when the server closes the connection while     * it's being taken out of the pool.     * <p>     * This method attempts to read one byte from the underlying     * channel. Because the connection was in the pool - there     * should be nothing to read.     * <p>     * If {@code read} manages to read a byte off the connection, this is a     * protocol error: the method closes the connection and returns false.     * If {@code read} returns EOF, the method closes the connection and     * returns false.     * If {@code read} throws an exception, the method returns false.     * Otherwise, {@code read} returns 0, the channel appears to be     * still open, and the method returns true.     * @return true if the channel appears to be still open.     */    final boolean checkOpen() {        if (isOpen()) {            try {                // channel is non blocking                int read = channel().read(ByteBuffer.allocate(1));                if (read == 0) return true;                close();            } catch (IOException x) {                debug.log("Pooled connection is no longer operational: %s",                        x.toString());                return false;            }        }        return false;    }
    void closeOrReturnToCache(HttpHeaders hdrs) {        if (hdrs == null) {            // the connection was closed by server, eof            Log.logTrace("Cannot return connection to pool: closing {0}", this);            close();            return;        }        HttpClientImpl client = client();        if (client == null) {            Log.logTrace("Client released: closing {0}", this);            close();            return;        }        ConnectionPool pool = client.connectionPool();        boolean keepAlive = hdrs.firstValue("Connection")                .map((s) -> !s.equalsIgnoreCase("close"))                .orElse(true);        if (keepAlive && checkOpen()) {            Log.logTrace("Returning connection to the pool: {0}", this);            pool.returnToPool(this);        } else {            Log.logTrace("Closing connection (keepAlive={0}, isOpen={1}): {2}",                    keepAlive, isOpen(), this);            close();        }    }