You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "arturobernalg (via GitHub)" <gi...@apache.org> on 2025/10/06 10:01:54 UTC
[PR] RFC 7639 ALPN [httpcomponents-client]
arturobernalg opened a new pull request, #731:
URL: https://github.com/apache/httpcomponents-client/pull/731
Add ConnectAlpnProvider and inject ALPN header in ConnectExec/AsyncConnectExec. Provide builder hooks for fixed list or provider-driven values.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2682110883
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.7
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header.
+ */
+ public static Header formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ return MessageSupport.headerOfTokens(HttpHeaders.ALPN, protocolIds, AlpnHeaderSupport::encodeId);
+ }
+
+ /**
+ * Parses an {@code ALPN} header into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final Header header) {
+ if (header == null) {
+ return Collections.emptyList();
+ }
+ final List<String> out = new ArrayList<>();
+ MessageSupport.parseTokens(header, token -> {
+ if (!token.isEmpty()) {
+ out.add(decodeId(token));
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Encodes a single raw protocol ID to canonical token form.
+ */
+ public static String encodeId(final String id) {
Review Comment:
@arturobernalg I asked this already, I have to ask it again. What is the reason for having to re-implement percent coding and not using PercentCodec from core? What is wrong with PercentCodec encoding?
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.7
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header.
+ */
+ public static Header formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ return MessageSupport.headerOfTokens(HttpHeaders.ALPN, protocolIds, AlpnHeaderSupport::encodeId);
+ }
+
+ /**
+ * Parses an {@code ALPN} header into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final Header header) {
+ if (header == null) {
Review Comment:
@arturobernalg This is an internal method. It does not need to do strict input validation. This is the responsibility of public methods. Keep it simple and small.
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.7
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header.
+ */
+ public static Header formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ return MessageSupport.headerOfTokens(HttpHeaders.ALPN, protocolIds, AlpnHeaderSupport::encodeId);
+ }
+
+ /**
+ * Parses an {@code ALPN} header into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final Header header) {
+ if (header == null) {
+ return Collections.emptyList();
+ }
+ final List<String> out = new ArrayList<>();
+ MessageSupport.parseTokens(header, token -> {
+ if (!token.isEmpty()) {
+ out.add(decodeId(token));
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Encodes a single raw protocol ID to canonical token form.
+ */
+ public static String encodeId(final String id) {
+ Args.notBlank(id, "id");
+ final byte[] bytes = id.getBytes(StandardCharsets.UTF_8);
+ final StringBuilder sb = new StringBuilder(bytes.length);
+ for (final byte b0 : bytes) {
+ final int b = b0 & 0xFF;
+ if (b == '%' || !isTchar(b)) {
+ appendPctEncoded(b, sb);
+ } else {
+ sb.append((char) b);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Decodes percent-encoded token to raw ID using UTF-8.
+ * Malformed / incomplete sequences are left literal.
+ */
+ public static String decodeId(final String token) {
+ Args.notBlank(token, "token");
+ try {
+ return PercentCodec.decode(token, StandardCharsets.UTF_8);
+ } catch (final IllegalArgumentException ex) {
+ return token;
Review Comment:
@arturobernalg This is a protocol error. Should not we treat it as such?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#issuecomment-3677780392
> @arturobernalg Could you please rebase this change-set?
@ok2c done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r3522991139
##########
httpclient5/src/main/java/org/apache/hc/client5/http/ConnectAlpnProvider.java:
##########
@@ -0,0 +1,59 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http;
+
+import java.util.List;
+
+import org.apache.hc.core5.http.HttpHost;
+
+/**
+ * Supplies the Application-Layer Protocol Negotiation (ALPN) protocol IDs
+ * to advertise in the HTTP {@code ALPN} header on a {@code CONNECT} request
+ * (RFC 7639).
+ *
+ * <p>If this method returns {@code null} or an empty list, the client will
+ * not add the {@code ALPN} header.</p>
+ *
+ * <p>Implementations should be fast and side-effect free; it may be invoked
+ * for each CONNECT attempt.</p>
+ *
+ * @since 5.6
+ */
+@FunctionalInterface
+public interface ConnectAlpnProvider {
+
+ /**
+ * Returns the ALPN protocol IDs to advertise for a tunnel to {@code target}
+ * over the given {@code route}.
+ *
+ * @param target the origin server the tunnel will connect to (non-null)
+ * @param route the planned connection route, including proxy info (non-null)
+ * @return list of protocol IDs (e.g., {@code "h2"}, {@code "http/1.1"});
+ * {@code null} or empty to omit the header
+ */
+ List<String> getAlpnForTunnel(HttpHost target, HttpRoute route);
Review Comment:
@arturobernalg Same question that I already asked you before. What do you think should happen if this provider returns something other than `h2` or `http/1.1` from supported `ApplicationProtocol` enum? Why do we need this interface at all?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg merged PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2683082455
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.7
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header.
+ */
+ public static Header formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ return MessageSupport.headerOfTokens(HttpHeaders.ALPN, protocolIds, AlpnHeaderSupport::encodeId);
+ }
+
+ /**
+ * Parses an {@code ALPN} header into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final Header header) {
+ if (header == null) {
+ return Collections.emptyList();
+ }
+ final List<String> out = new ArrayList<>();
+ MessageSupport.parseTokens(header, token -> {
+ if (!token.isEmpty()) {
+ out.add(decodeId(token));
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Encodes a single raw protocol ID to canonical token form.
+ */
+ public static String encodeId(final String id) {
Review Comment:
@arturobernalg At any rate, could you contribute the correct codec to core? That would be the proper way to start.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2680083085
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,151 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.6
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final String HEADER_NAME = "ALPN";
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header value.
+ */
+ public static String formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ final List<String> tokens = new ArrayList<>(protocolIds.size());
+ for (final String id : protocolIds) {
+ tokens.add(encodeId(id));
+ }
+ final Header header = MessageSupport.headerOfTokens(HEADER_NAME, tokens);
+ return header.getValue();
Review Comment:
@arturobernalg Noooooooo, please do not do that! You create a header with a char buffer, than you you get the value of it as a string, then you make char buffer with a copy of the string and then create a header. Please do not do that.
Please focus more on quality of your contributions than their volume,
My other two comments have not been addressed.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2679398491
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,183 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.6
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header value.
+ */
+ public static String formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ final StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (final String id : protocolIds) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append(encodeId(id));
+ first = false;
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Parses an {@code ALPN} header value into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final String value) {
Review Comment:
@arturobernalg Use `MessageSupport#parseTokens(Header, Consumer)` instead.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r3032759232
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java:
##########
@@ -936,6 +941,26 @@ public final HttpAsyncClientBuilder disableRequestPriority() {
return this;
}
+ /**
+ * Configures the {@code ALPN} header to be sent on {@code CONNECT}
+ * requests when establishing an HTTP tunnel through a proxy.
+ *
+ * <p>The supplied protocol IDs are advertised in the given order (preference order).
+ * If {@code ids} is {@code null} or empty, no {@code ALPN} header will be added.</p>
+ *
+ * <p>This is a convenience method equivalent to installing a {@link ConnectAlpnProvider}
+ * that always returns the same list.</p>
+ *
+ * @param ids ALPN protocol IDs to advertise (for example {@code "h2"} and {@code "http/1.1"})
+ * @return this builder
+ * @since 5.6
+ */
+ public HttpAsyncClientBuilder setConnectAlpn(final String... ids) {
Review Comment:
@arturobernalg What should happen if the caller passes `h3`, `http/0.75`, `srtuff` to this method?
Why do we even need this method at all? There is already `HttpVersionPolicy` settable on a per route basis and this is exactly what you should be using should you decide to proceed further with this feature.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r3783288981
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java:
##########
@@ -552,6 +553,8 @@ public void connect(final ConnectionEndpoint endpoint, final TimeValue timeout,
final HttpHost firstHop = route.getProxyHost() != null ? route.getProxyHost() : route.getTargetHost();
final SocketConfig socketConfig = resolveSocketConfig(route);
final ConnectionConfig connectionConfig = resolveConnectionConfig(route);
+ final TlsConfig tlsConfig = resolveTlsConfig(route.getTargetHost());
+ HttpClientContext.castOrCreate(context).setHttpVersionPolicy(tlsConfig.getHttpVersionPolicy());
Review Comment:
@arturobernalg One last bit. Let's do `HttpClientContext#cast` here instead and assign the attribute only if the context is non null. There is no point creating a new context here.
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java:
##########
@@ -504,13 +505,15 @@ public Future<AsyncConnectionEndpoint> connect(
if (LOG.isDebugEnabled()) {
LOG.debug("{} connecting endpoint to {} ({})", ConnPoolSupport.getId(endpoint), firstHop, connectTimeout);
}
+ final TlsConfig targetTlsConfig = resolveTlsConfig(route.getTargetHost());
+ HttpClientContext.castOrCreate(context).setHttpVersionPolicy(targetTlsConfig.getHttpVersionPolicy());
Review Comment:
@arturobernalg Same
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#issuecomment-5293152016
> @arturobernalg Almost there. See my comments
Please do a
> @arturobernalg Almost there. See my comments
@ok2c Please do another pass.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#issuecomment-3591797763
@arturobernalg Could you please rebase this change-set?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2679397439
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,183 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.6
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header value.
+ */
+ public static String formatValue(final List<String> protocolIds) {
Review Comment:
@arturobernalg Use `MessageSupport#headerOfTokens` instead
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2681688430
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,151 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.6
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final String HEADER_NAME = "ALPN";
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header value.
+ */
+ public static String formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ final List<String> tokens = new ArrayList<>(protocolIds.size());
+ for (final String id : protocolIds) {
+ tokens.add(encodeId(id));
+ }
+ final Header header = MessageSupport.headerOfTokens(HEADER_NAME, tokens);
+ return header.getValue();
Review Comment:
@ok2c sorry about that. I think all are fine now
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#issuecomment-4586249548
@arturobernalg This change can still make it into `5.7` if you are willing to invest time into it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#issuecomment-4751421874
> @arturobernalg This change can still make it into `5.7` if you are willing to invest time into it.
@ok2c please do another pass
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2679385304
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,183 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.6
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header value.
+ */
+ public static String formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ final StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (final String id : protocolIds) {
+ if (!first) {
+ sb.append(", ");
+ }
+ sb.append(encodeId(id));
+ first = false;
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Parses an {@code ALPN} header value into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final String value) {
+ if (value == null || value.isEmpty()) {
+ return Collections.emptyList();
+ }
+ final List<String> out = new ArrayList<>();
+ final ParserCursor cursor = new ParserCursor(0, value.length());
+ MessageSupport.parseTokens(value, cursor, token -> {
+ if (!token.isEmpty()) {
+ out.add(decodeId(token));
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Encodes a single raw protocol ID to canonical token form.
+ */
+ public static String encodeId(final String id) {
+ Args.notBlank(id, "id");
+ final byte[] bytes = id.getBytes(StandardCharsets.UTF_8);
+ final StringBuilder sb = new StringBuilder(bytes.length);
+ for (final byte b0 : bytes) {
+ final int b = b0 & 0xFF;
+ if (b == '%' || !isTchar(b)) {
+ appendPctEncoded(b, sb);
+ } else {
+ sb.append((char) b);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Decodes percent-encoded token to raw ID using UTF-8.
+ * Accepts lowercase hex; malformed/incomplete sequences are left literal.
+ */
+ public static String decodeId(final String token) {
Review Comment:
@arturobernalg what is the reason having to re-implement percent coding and not using `PercentCodec` from core?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "arturobernalg (via GitHub)" <gi...@apache.org>.
arturobernalg commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2682666800
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.7
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header.
+ */
+ public static Header formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ return MessageSupport.headerOfTokens(HttpHeaders.ALPN, protocolIds, AlpnHeaderSupport::encodeId);
+ }
+
+ /**
+ * Parses an {@code ALPN} header into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final Header header) {
+ if (header == null) {
+ return Collections.emptyList();
+ }
+ final List<String> out = new ArrayList<>();
+ MessageSupport.parseTokens(header, token -> {
+ if (!token.isEmpty()) {
+ out.add(decodeId(token));
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Encodes a single raw protocol ID to canonical token form.
+ */
+ public static String encodeId(final String id) {
Review Comment:
@ok2c RFC 7639 requires canonical token encoding: octets MUST NOT be percent-encoded if they are valid RFC 7230 tchar (except ‘%’), and percent-encoding MUST use uppercase hex.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org
Re: [PR] RFC 7639 ALPN [httpcomponents-client]
Posted by "ok2c (via GitHub)" <gi...@apache.org>.
ok2c commented on code in PR #731:
URL: https://github.com/apache/httpcomponents-client/pull/731#discussion_r2683070960
##########
httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.net.PercentCodec;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Codec for the HTTP {@code ALPN} header field (RFC 7639).
+ *
+ * @since 5.7
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+@Internal
+public final class AlpnHeaderSupport {
+
+ private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
+
+ private AlpnHeaderSupport() {
+ }
+
+ /**
+ * Formats a list of raw ALPN protocol IDs into a single {@code ALPN} header.
+ */
+ public static Header formatValue(final List<String> protocolIds) {
+ Args.notEmpty(protocolIds, "protocolIds");
+ return MessageSupport.headerOfTokens(HttpHeaders.ALPN, protocolIds, AlpnHeaderSupport::encodeId);
+ }
+
+ /**
+ * Parses an {@code ALPN} header into decoded protocol IDs.
+ */
+ public static List<String> parseValue(final Header header) {
+ if (header == null) {
+ return Collections.emptyList();
+ }
+ final List<String> out = new ArrayList<>();
+ MessageSupport.parseTokens(header, token -> {
+ if (!token.isEmpty()) {
+ out.add(decodeId(token));
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Encodes a single raw protocol ID to canonical token form.
+ */
+ public static String encodeId(final String id) {
Review Comment:
@arturobernalg There are two publicly accessible instances and they both do not fit the requirements?
```
public static final PercentCodec RFC3986 = new PercentCodec(UNRESERVED);
public static final PercentCodec RFC5987 = new PercentCodec(RFC5987_UNRESERVED);
```
> percent-encoding MUST use uppercase hex
This I do not quite understand. Can you give me an example of what `PercentCodec` produces and what this new RFC requires?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org