static Http2Headers h1HeadersToH2Headers()

in servicetalk-http-netty/src/main/java/io/servicetalk/http/netty/H2ToStH1Utils.java [109:187]


    static Http2Headers h1HeadersToH2Headers(HttpHeaders h1Headers) {
        if (h1Headers.isEmpty()) {
            if (h1Headers instanceof NettyH2HeadersToHttpHeaders) {
                return ((NettyH2HeadersToHttpHeaders) h1Headers).nettyHeaders();
            }
            return new DefaultHttp2Headers(false, 0);
        }

        // H2 doesn't support connection headers, so remove each one, and the headers corresponding to the
        // connection value.
        // https://tools.ietf.org/html/rfc7540#section-8.1.2.2
        Iterator<? extends CharSequence> connectionItr = h1Headers.valuesIterator(CONNECTION);
        if (connectionItr.hasNext()) {
            do {
                String connectionHeader = connectionItr.next().toString();
                connectionItr.remove();
                int i = connectionHeader.indexOf(',');
                if (i != -1) {
                    int start = 0;
                    do {
                        h1Headers.remove(connectionHeader.substring(start, i));
                        start = i + 1;
                    } while (start < connectionHeader.length() && (i = connectionHeader.indexOf(',', start)) != -1);
                    h1Headers.remove(connectionHeader.substring(start));
                } else {
                    h1Headers.remove(connectionHeader);
                }
            } while (connectionItr.hasNext());
        }

        // remove other illegal headers
        h1Headers.remove(KEEP_ALIVE);
        h1Headers.remove(TRANSFER_ENCODING);
        h1Headers.remove(UPGRADE);

        // TE header is treated specially https://tools.ietf.org/html/rfc7540#section-8.1.2.2
        // (only value of "trailers" is allowed).
        Iterator<? extends CharSequence> teItr = h1Headers.valuesIterator(TE);
        boolean addTrailers = false;
        while (teItr.hasNext()) {
            String teValue = teItr.next().toString();
            int i = teValue.indexOf(',');
            if (i != -1) {
                int start = 0;
                do {
                    if (teValue.substring(start, i).compareToIgnoreCase(TRAILERS.toString()) == 0) {
                        addTrailers = true;
                        break;
                    }
                } while (start < teValue.length() && (i = teValue.indexOf(',', start)) != -1);
                teItr.remove();
            } else if (teValue.compareToIgnoreCase(TRAILERS.toString()) != 0) {
                teItr.remove();
            }
        }
        if (addTrailers) { // add after iteration to avoid concurrent modification.
            h1Headers.add(TE, TRAILERS);
        }

        h1HeadersSplitCookieCrumbs(h1Headers);

        if (h1Headers instanceof NettyH2HeadersToHttpHeaders) {
            // Assume header field names are already lowercase if they reside in the Http2Headers. We may want to be
            // more strict in the future, but that would require iteration.
            return ((NettyH2HeadersToHttpHeaders) h1Headers).nettyHeaders();
        }

        if (h1Headers.isEmpty()) {
            return new DefaultHttp2Headers(false, 0);
        }

        DefaultHttp2Headers http2Headers = new DefaultHttp2Headers(false);
        for (Map.Entry<CharSequence, CharSequence> h1Entry : h1Headers) {
            // header field names MUST be converted to lowercase prior to their encoding in HTTP/2
            // https://tools.ietf.org/html/rfc7540#section-8.1.2
            http2Headers.add(h1Entry.getKey().toString().toLowerCase(), h1Entry.getValue());
        }
        return http2Headers;
    }