ok2c commented on code in PR #693: URL: https://github.com/apache/httpcomponents-core/pull/693#discussion_r3972623732
########## httpcore5/src/main/java/org/apache/hc/core5/http/structured/StructuredFieldHeaders.java: ########## @@ -0,0 +1,202 @@ +/* + * ==================================================================== + * 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.core5.http.structured; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.apache.hc.core5.http.FormattedHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.MessageHeaders; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.ProtocolException; +import org.apache.hc.core5.http.message.BufferedHeader; +import org.apache.hc.core5.http.message.MessageSupport; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.CharArrayBuffer; +import org.apache.hc.core5.util.Tokenizer; + +/** + * Integration between Structured Field values and HttpComponents message headers. + * + * @since 5.5 + */ +public final class StructuredFieldHeaders { + + private StructuredFieldHeaders() { + } + + /** + * Parses one header as an Structured Field Item. + * + * @param header the header. + * @return the parsed Item. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldItem parseItem(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseItem(input.value, input.cursor); Review Comment: @arturobernalg This can now be replaced with ``` MessageSupport.parseHeaderValueStrict(header, StructuredFieldParser::parseItem) ```` ########## httpcore5/src/main/java/org/apache/hc/core5/http/structured/StructuredFieldHeaders.java: ########## @@ -0,0 +1,202 @@ +/* + * ==================================================================== + * 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.core5.http.structured; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.apache.hc.core5.http.FormattedHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.MessageHeaders; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.ProtocolException; +import org.apache.hc.core5.http.message.BufferedHeader; +import org.apache.hc.core5.http.message.MessageSupport; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.CharArrayBuffer; +import org.apache.hc.core5.util.Tokenizer; + +/** + * Integration between Structured Field values and HttpComponents message headers. + * + * @since 5.5 + */ +public final class StructuredFieldHeaders { + + private StructuredFieldHeaders() { + } + + /** + * Parses one header as an Structured Field Item. + * + * @param header the header. + * @return the parsed Item. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldItem parseItem(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseItem(input.value, input.cursor); + } + + /** + * Parses the field named {@code name} as a single Structured Field Item. An Item is a single + * value and cannot span field lines, so more than one matching field line is rejected. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed Item. + * @throws ProtocolException if the field is absent, spans multiple field lines, or is invalid. + */ + public static StructuredFieldItem parseItem(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final Iterator<Header> matching = headers.headerIterator(name); + if (!matching.hasNext()) { + throw new ParseException("Missing " + name + " field"); + } + final Header header = matching.next(); + if (matching.hasNext()) { + throw new ParseException(name + " Item must not span multiple field lines"); + } + final StructuredFieldItem[] holder = new StructuredFieldItem[1]; Review Comment: @arturobernalg This can also be now replaced with ``` MessageSupport.parseHeaderValueStrict(header, StructuredFieldParser::parseItem) ```` ########## httpcore5/src/main/java/org/apache/hc/core5/http/structured/StructuredFieldHeaders.java: ########## @@ -0,0 +1,202 @@ +/* + * ==================================================================== + * 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.core5.http.structured; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.apache.hc.core5.http.FormattedHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.MessageHeaders; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.ProtocolException; +import org.apache.hc.core5.http.message.BufferedHeader; +import org.apache.hc.core5.http.message.MessageSupport; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.CharArrayBuffer; +import org.apache.hc.core5.util.Tokenizer; + +/** + * Integration between Structured Field values and HttpComponents message headers. + * + * @since 5.5 + */ +public final class StructuredFieldHeaders { + + private StructuredFieldHeaders() { + } + + /** + * Parses one header as an Structured Field Item. + * + * @param header the header. + * @return the parsed Item. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldItem parseItem(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseItem(input.value, input.cursor); + } + + /** + * Parses the field named {@code name} as a single Structured Field Item. An Item is a single + * value and cannot span field lines, so more than one matching field line is rejected. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed Item. + * @throws ProtocolException if the field is absent, spans multiple field lines, or is invalid. + */ + public static StructuredFieldItem parseItem(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final Iterator<Header> matching = headers.headerIterator(name); + if (!matching.hasNext()) { + throw new ParseException("Missing " + name + " field"); + } + final Header header = matching.next(); + if (matching.hasNext()) { + throw new ParseException(name + " Item must not span multiple field lines"); + } + final StructuredFieldItem[] holder = new StructuredFieldItem[1]; + MessageSupport.parseHeaderStrict(header, (buffer, cursor) -> + holder[0] = StructuredFieldParser.parseItem(buffer, cursor)); + return holder[0]; + } + + /** + * Parses one header as an Structured Field List. + * + * @param header the header. + * @return the parsed List. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldList parseList(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseList(input.value, input.cursor); + } + + /** + * Parses the matching field lines as a Structured Field List, reading each field line in place + * and appending its members, without combining the values into a new buffer. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed List, empty when the field is absent. + * @throws ProtocolException if any field line is invalid. + */ + public static StructuredFieldList parseList(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final List<StructuredFieldMember> members = new ArrayList<>(); + MessageSupport.parseElementListStrict(headers, name, (buffer, cursor) -> + members.add(StructuredFieldParser.parseListElement(buffer, cursor))); + return StructuredFieldList.of(members); + } + + /** + * Parses one header as an Structured Field Dictionary. + * + * @param header the header. + * @return the parsed Dictionary. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldDictionary parseDictionary(final Header header) throws ParseException { + final HeaderInput input = input(header); Review Comment: @arturobernalg This with ``` MessageSupport.parseHeaderValueStrict(header, StructuredFieldParser::parseDictionary) ``` ########## httpcore5/src/main/java/org/apache/hc/core5/http/structured/StructuredFieldHeaders.java: ########## @@ -0,0 +1,202 @@ +/* + * ==================================================================== + * 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.core5.http.structured; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.apache.hc.core5.http.FormattedHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.MessageHeaders; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.ProtocolException; +import org.apache.hc.core5.http.message.BufferedHeader; +import org.apache.hc.core5.http.message.MessageSupport; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.CharArrayBuffer; +import org.apache.hc.core5.util.Tokenizer; + +/** + * Integration between Structured Field values and HttpComponents message headers. + * + * @since 5.5 + */ +public final class StructuredFieldHeaders { + + private StructuredFieldHeaders() { + } + + /** + * Parses one header as an Structured Field Item. + * + * @param header the header. + * @return the parsed Item. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldItem parseItem(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseItem(input.value, input.cursor); + } + + /** + * Parses the field named {@code name} as a single Structured Field Item. An Item is a single + * value and cannot span field lines, so more than one matching field line is rejected. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed Item. + * @throws ProtocolException if the field is absent, spans multiple field lines, or is invalid. + */ + public static StructuredFieldItem parseItem(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final Iterator<Header> matching = headers.headerIterator(name); + if (!matching.hasNext()) { + throw new ParseException("Missing " + name + " field"); + } + final Header header = matching.next(); + if (matching.hasNext()) { + throw new ParseException(name + " Item must not span multiple field lines"); + } + final StructuredFieldItem[] holder = new StructuredFieldItem[1]; + MessageSupport.parseHeaderStrict(header, (buffer, cursor) -> + holder[0] = StructuredFieldParser.parseItem(buffer, cursor)); + return holder[0]; + } + + /** + * Parses one header as an Structured Field List. + * + * @param header the header. + * @return the parsed List. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldList parseList(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseList(input.value, input.cursor); Review Comment: @arturobernalg This with ``` MessageSupport.parseHeaderValueStrict(header, StructuredFieldParser::parseList) ``` ########## httpcore5/src/main/java/org/apache/hc/core5/http/structured/StructuredFieldHeaders.java: ########## @@ -0,0 +1,202 @@ +/* + * ==================================================================== + * 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.core5.http.structured; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.apache.hc.core5.http.FormattedHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.MessageHeaders; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.ProtocolException; +import org.apache.hc.core5.http.message.BufferedHeader; +import org.apache.hc.core5.http.message.MessageSupport; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.CharArrayBuffer; +import org.apache.hc.core5.util.Tokenizer; + +/** + * Integration between Structured Field values and HttpComponents message headers. + * + * @since 5.5 + */ +public final class StructuredFieldHeaders { + + private StructuredFieldHeaders() { + } + + /** + * Parses one header as an Structured Field Item. + * + * @param header the header. + * @return the parsed Item. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldItem parseItem(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseItem(input.value, input.cursor); + } + + /** + * Parses the field named {@code name} as a single Structured Field Item. An Item is a single + * value and cannot span field lines, so more than one matching field line is rejected. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed Item. + * @throws ProtocolException if the field is absent, spans multiple field lines, or is invalid. + */ + public static StructuredFieldItem parseItem(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final Iterator<Header> matching = headers.headerIterator(name); + if (!matching.hasNext()) { + throw new ParseException("Missing " + name + " field"); + } + final Header header = matching.next(); + if (matching.hasNext()) { + throw new ParseException(name + " Item must not span multiple field lines"); + } + final StructuredFieldItem[] holder = new StructuredFieldItem[1]; + MessageSupport.parseHeaderStrict(header, (buffer, cursor) -> + holder[0] = StructuredFieldParser.parseItem(buffer, cursor)); + return holder[0]; + } + + /** + * Parses one header as an Structured Field List. + * + * @param header the header. + * @return the parsed List. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldList parseList(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseList(input.value, input.cursor); + } + + /** + * Parses the matching field lines as a Structured Field List, reading each field line in place + * and appending its members, without combining the values into a new buffer. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed List, empty when the field is absent. + * @throws ProtocolException if any field line is invalid. + */ + public static StructuredFieldList parseList(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final List<StructuredFieldMember> members = new ArrayList<>(); + MessageSupport.parseElementListStrict(headers, name, (buffer, cursor) -> + members.add(StructuredFieldParser.parseListElement(buffer, cursor))); + return StructuredFieldList.of(members); + } + + /** + * Parses one header as an Structured Field Dictionary. + * + * @param header the header. + * @return the parsed Dictionary. + * @throws ParseException if the complete field value is invalid. + */ + public static StructuredFieldDictionary parseDictionary(final Header header) throws ParseException { + final HeaderInput input = input(header); + return StructuredFieldParser.parseDictionary(input.value, input.cursor); + } + + /** + * Parses the matching field lines as a Structured Field Dictionary, reading each field line in + * place and merging its members, without combining the values into a new buffer. A repeated key + * keeps its last value. + * + * @param headers the message headers. + * @param name the case-insensitive field name. + * @return the parsed Dictionary, empty when the field is absent. + * @throws ProtocolException if any field line is invalid. + */ + public static StructuredFieldDictionary parseDictionary(final MessageHeaders headers, final String name) + throws ProtocolException { + Args.notNull(headers, "Message headers"); + Args.notBlank(name, "Header name"); + final Map<String, StructuredFieldMember> members = new LinkedHashMap<>(); + MessageSupport.parseElementListStrict(headers, name, (buffer, cursor) -> + StructuredFieldParser.parseDictionaryElement(buffer, cursor, members)); + return StructuredFieldDictionary.copyOf(members); + } + + /** + * Creates a header for a Structured Field value. + * + * @param name the field name. + * @param value the Structured Field value. + * @return a header, or {@code null} for an empty List or Dictionary. + */ + public static Header format(final String name, final StructuredFieldValue value) { + Args.notBlank(name, "Header name"); + Objects.requireNonNull(value, "Structured Field value"); + if (value instanceof StructuredFieldList && ((StructuredFieldList) value).isEmpty() + || value instanceof StructuredFieldDictionary && ((StructuredFieldDictionary) value).isEmpty()) { + return null; + } + final CharArrayBuffer buffer = new CharArrayBuffer(name.length() + 66); + buffer.append(name); + buffer.append(": "); + StructuredFieldSerializer.serialize(buffer, value); + return BufferedHeader.create(buffer); + } + + private static HeaderInput input(final Header header) { Review Comment: @arturobernalg `HeaderInput` should no longer be necessary -- 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: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
