hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1758066 - in /httpcomponents/httpcore/trunk/httpcore5-h2/src: main/java/org/apache/hc/core5/http2/ main/java/org/apache/hc/core5/http2/impl/ main/java/org/apache/hc/core5/http2/impl/io/ main/java/org/apache/hc/core5/http2/impl/nio/ main/ja...
Date Sat, 27 Aug 2016 19:39:26 GMT
Author: olegk
Date: Sat Aug 27 19:39:26 2016
New Revision: 1758066

URL: http://svn.apache.org/viewvc?rev=1758066&view=rev
Log:
RFC 7540: redesign of header list to message conversion APIs

Added:
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java   (contents, props changed)
      - copied, changed from r1757445, httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2MessageParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java   (contents, props changed)
      - copied, changed from r1757445, httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2TransportMetrics.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java   (contents, props changed)
      - copied, changed from r1757445, httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicHttp2TransportMetrics.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java   (with props)
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java   (with props)
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java   (with props)
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java   (with props)
Removed:
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicHttp2TransportMetrics.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/AbstractHttp2MessageParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/AbstractHttp2MessageWriter.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/Http2RequestParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/Http2RequestWriter.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/Http2ResponseParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/Http2ResponseWriter.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2MessageParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2MessageWriter.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2TransportMetrics.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestHttp2RequestParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestHttp2RequestWriter.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestHttp2ResponseParser.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestHttp2ResponseWriter.java
Modified:
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameInputBuffer.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameOutputBuffer.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameInputBuffer.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameOutputBuffer.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestFrameInOutBuffers.java
    httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestFrameInOutBuffers.java

Copied: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java (from r1757445, httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2MessageParser.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java?p2=httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java&p1=httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2MessageParser.java&r1=1757445&r2=1758066&rev=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2MessageParser.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java Sat Aug 27 19:39:26 2016
@@ -25,30 +25,42 @@
  *
  */
 
-package org.apache.hc.core5.http2.io;
+package org.apache.hc.core5.http2;
 
-import java.nio.ByteBuffer;
+import java.util.List;
 
+import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.MessageHead;
 
 /**
- * Abstract message parser intended to build HTTP message head from an arbitrary data source.
+ * Abstract message converter intended to convert from a list of HTTP/2 headers to object
+ * representing an HTTP message and from an object representing an HTTP message to a list
+ * of HTTP/2 headers.
  *
  * @param <T>
  *            {@link MessageHead} or a subclass
  *
  * @since 5.0
  */
-public interface Http2MessageParser<T extends MessageHead> {
+public interface H2MessageConverter<T extends MessageHead> {
 
     /**
-     * Generates an instance of {@link MessageHead} from the given input buffer.
+     * Converts given list of HTTP/2 headers to a {@link MessageHead}.
      *
-     * @param buffer input buffer
-     * @return HTTP message head
+     * @param headers list of HTTP/2 headers
+     * @return HTTP message
      * @throws HttpException in case of HTTP protocol violation
      */
-    T parse(ByteBuffer buffer) throws HttpException;
+    T convert(List<Header> headers) throws HttpException;
+
+    /**
+     * Converts given {@link MessageHead} to a list of HTTP/2 headers.
+     *
+     * @param message HTTP message
+     * @return list of HTTP/2 headers
+     * @throws HttpException in case of HTTP protocol violation
+     */
+    List<Header> convert(T message) throws HttpException;
 
 }

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2MessageConverter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java (from r1757445, httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2TransportMetrics.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java?p2=httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java&p1=httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2TransportMetrics.java&r1=1757445&r2=1758066&rev=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/io/Http2TransportMetrics.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java Sat Aug 27 19:39:26 2016
@@ -25,7 +25,7 @@
  *
  */
 
-package org.apache.hc.core5.http2.io;
+package org.apache.hc.core5.http2;
 
 import org.apache.hc.core5.http.io.HttpTransportMetrics;
 
@@ -34,7 +34,7 @@ import org.apache.hc.core5.http.io.HttpT
  *
  * @since 5.0
  */
-public interface Http2TransportMetrics extends HttpTransportMetrics {
+public interface H2TransportMetrics extends HttpTransportMetrics {
 
     long getFramesTransferred();
 

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2TransportMetrics.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java (from r1757445, httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicHttp2TransportMetrics.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java?p2=httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java&p1=httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicHttp2TransportMetrics.java&r1=1757445&r2=1758066&rev=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicHttp2TransportMetrics.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java Sat Aug 27 19:39:26 2016
@@ -28,14 +28,14 @@
 package org.apache.hc.core5.http2.impl;
 
 import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
-import org.apache.hc.core5.http2.io.Http2TransportMetrics;
+import org.apache.hc.core5.http2.H2TransportMetrics;
 
 /**
- * Default implementation of {@link Http2TransportMetrics}.
+ * Default implementation of {@link H2TransportMetrics}.
  *
  * @since 5.0
  */
-public class BasicHttp2TransportMetrics extends BasicHttpTransportMetrics implements Http2TransportMetrics {
+public class BasicH2TransportMetrics extends BasicHttpTransportMetrics implements H2TransportMetrics {
 
     private long framesTransferred;
 

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/BasicH2TransportMetrics.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java?rev=1758066&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java Sat Aug 27 19:39:26 2016
@@ -0,0 +1,198 @@
+/*
+ * ====================================================================
+ * 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.http2.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpRequestFactory;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.impl.DefaultHttpRequestFactory;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http2.H2MessageConverter;
+import org.apache.hc.core5.http2.H2PseudoRequestHeaders;
+import org.apache.hc.core5.util.TextUtils;
+
+/**
+ * HTTP/2 request converter.
+ *
+ * @since 5.0
+ */
+public final class DefaultH2RequestConverter implements H2MessageConverter<HttpRequest> {
+
+    public final static DefaultH2RequestConverter INSTANCE = new DefaultH2RequestConverter();
+
+    private final HttpRequestFactory requestFactory;
+
+    public DefaultH2RequestConverter() {
+        this(null);
+    }
+
+    public DefaultH2RequestConverter(final HttpRequestFactory requestFactory) {
+        this.requestFactory = requestFactory != null ? requestFactory : DefaultHttpRequestFactory.INSTANCE;
+    }
+
+    @Override
+    public HttpRequest convert(final List<Header> headers) throws HttpException {
+        String method = null;
+        String scheme = null;
+        String authority = null;
+        String path = null;
+        final List<Header> messageHeaders = new ArrayList<>();
+
+        for (int i = 0; i < headers.size(); i++) {
+            final Header header = headers.get(i);
+            final String name = header.getName();
+            final String value = header.getValue();
+
+            for (int n = 0; n < name.length(); n++) {
+                final char ch = name.charAt(n);
+                if (Character.isAlphabetic(ch) && !Character.isLowerCase(ch)) {
+                    throw new ProtocolException("Header name '" + name + "' is invalid (header name contains uppercase characters)");
+                }
+            }
+
+            if (name.startsWith(":")) {
+                if (!messageHeaders.isEmpty()) {
+                    throw new ProtocolException("Invalid sequence of headers (pseudo-headers must precede message headers)");
+                }
+
+                if (name.equals(H2PseudoRequestHeaders.METHOD)) {
+                    if (method != null) {
+                        throw new ProtocolException("Multiple '" + name + "' request headers are illegal");
+                    }
+                    method = value;
+                } else if (name.equals(H2PseudoRequestHeaders.SCHEME)) {
+                    if (scheme != null) {
+                        throw new ProtocolException("Multiple '" + name + "' request headers are illegal");
+                    }
+                    scheme = value;
+                } else if (name.equals(H2PseudoRequestHeaders.PATH)) {
+                    if (path != null) {
+                        throw new ProtocolException("Multiple '" + name + "' request headers are illegal");
+                    }
+                    path = value;
+                } else if (name.equals(H2PseudoRequestHeaders.AUTHORITY)) {
+                    authority = value;
+                } else {
+                    throw new ProtocolException("Unsupported request header '" + name + "'");
+                }
+            } else {
+                if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
+                    throw new ProtocolException("Header '" + header.getName() + ": " + header.getValue() + "' is illegal for HTTP/2 messages");
+                }
+                messageHeaders.add(header);
+            }
+        }
+        if (method == null) {
+            throw new ProtocolException("Mandatory request header ':method' not found");
+        }
+        if (method.equalsIgnoreCase("CONNECT")) {
+            if (authority == null) {
+                throw new ProtocolException("Header ':authority' is mandatory for CONNECT request");
+            }
+            if (scheme != null) {
+                throw new ProtocolException("Header ':scheme' must not be set for CONNECT request");
+            }
+            if (path != null) {
+                throw new ProtocolException("Header ':path' must not be set for CONNECT request");
+            }
+        } else {
+            if (scheme == null) {
+                throw new ProtocolException("Mandatory request header ':scheme' not found");
+            }
+            if (path == null) {
+                throw new ProtocolException("Mandatory request header ':path' not found");
+            }
+        }
+
+        final HttpRequest httpRequest = this.requestFactory.newHttpRequest(HttpVersion.HTTP_2, method, path);
+        httpRequest.setScheme(scheme);
+        httpRequest.setAuthority(authority);
+        httpRequest.setPath(path);
+        for (int i = 0; i < messageHeaders.size(); i++) {
+            httpRequest.addHeader(messageHeaders.get(i));
+        }
+        return httpRequest;
+    }
+
+    @Override
+    public List<Header> convert(final HttpRequest message) throws HttpException {
+        if (TextUtils.isBlank(message.getMethod())) {
+            throw new ProtocolException("Request method is empty");
+        }
+        final boolean optionMethod = "CONNECT".equalsIgnoreCase(message.getMethod());
+        if (optionMethod) {
+            if (TextUtils.isBlank(message.getAuthority())) {
+                throw new ProtocolException("CONNECT request authority is not set");
+            }
+            if (message.getPath() != null) {
+                throw new ProtocolException("CONNECT request path must be null");
+            }
+        } else {
+            if (TextUtils.isBlank(message.getScheme())) {
+                throw new ProtocolException("Request scheme is not set");
+            }
+            if (TextUtils.isBlank(message.getPath())) {
+                throw new ProtocolException("Request path is not set");
+            }
+        }
+        final List<Header> headers = new ArrayList<>();
+        headers.add(new BasicHeader(H2PseudoRequestHeaders.METHOD, message.getMethod(), false));
+        if (optionMethod) {
+            headers.add(new BasicHeader(H2PseudoRequestHeaders.AUTHORITY, message.getAuthority(), false));
+        }  else {
+            headers.add(new BasicHeader(H2PseudoRequestHeaders.SCHEME, message.getScheme(), false));
+            if (message.getAuthority() != null) {
+                headers.add(new BasicHeader(H2PseudoRequestHeaders.AUTHORITY, message.getAuthority(), false));
+            }
+            headers.add(new BasicHeader(H2PseudoRequestHeaders.PATH, message.getPath(), false));
+        }
+
+        for (final Iterator<Header> it = message.headerIterator(); it.hasNext(); ) {
+            final Header header = it.next();
+            final String name = header.getName();
+            if (name.startsWith(":")) {
+                throw new ProtocolException("Header name '" + name + "' is invalid");
+            }
+            if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
+                throw new ProtocolException("Header '" + header.getName() + ": " + header.getValue() + "' is illegal for HTTP/2 messages");
+            }
+            headers.add(header);
+        }
+
+        return headers;
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java?rev=1758066&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java Sat Aug 27 19:39:26 2016
@@ -0,0 +1,142 @@
+/*
+ * ====================================================================
+ * 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.http2.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpResponseFactory;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.impl.DefaultHttpResponseFactory;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http2.H2MessageConverter;
+import org.apache.hc.core5.http2.H2PseudoResponseHeaders;
+
+/**
+ * HTTP/2 response converter.
+ *
+ * @since 5.0
+ */
+public class DefaultH2ResponseConverter implements H2MessageConverter<HttpResponse> {
+
+    public final static DefaultH2ResponseConverter INSTANCE = new DefaultH2ResponseConverter();
+
+    private HttpResponseFactory responseFactory;
+
+    public DefaultH2ResponseConverter() {
+        this(null);
+    }
+
+    public DefaultH2ResponseConverter(final HttpResponseFactory responseFactory) {
+        this.responseFactory = responseFactory != null ? responseFactory : DefaultHttpResponseFactory.INSTANCE;
+    }
+
+    @Override
+    public HttpResponse convert(final List<Header> headers) throws HttpException {
+        String statusText = null;
+        final List<Header> messageHeaders = new ArrayList<>();
+
+        for (int i = 0; i < headers.size(); i++) {
+            final Header header = headers.get(i);
+            final String name = header.getName();
+            final String value = header.getValue();
+
+            for (int n = 0; n < name.length(); n++) {
+                final char ch = name.charAt(n);
+                if (Character.isAlphabetic(ch) && !Character.isLowerCase(ch)) {
+                    throw new ProtocolException("Header name '" + name + "' is invalid (header name contains uppercase characters)");
+                }
+            }
+
+            if (name.startsWith(":")) {
+                if (!messageHeaders.isEmpty()) {
+                    throw new ProtocolException("Invalid sequence of headers (pseudo-headers must precede message headers)");
+                }
+                if (name.equals(H2PseudoResponseHeaders.STATUS)) {
+                    if (statusText != null) {
+                        throw new ProtocolException("Multiple '" + name + "' response headers are illegal");
+                    }
+                    statusText = value;
+                } else {
+                    throw new ProtocolException("Unsupported response header '" + name + "'");
+                }
+            } else {
+                if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
+                    throw new ProtocolException("Header '" + header.getName() + ": " + header.getValue() + "' is illegal for HTTP/2 messages");
+                }
+                messageHeaders.add(header);
+            }
+
+        }
+
+        if (statusText == null) {
+            throw new ProtocolException("Mandatory response header ':status' not found");
+        }
+        final int statusCode;
+        try {
+            statusCode = Integer.parseInt(statusText);
+        } catch (NumberFormatException ex) {
+            throw new ProtocolException("Invalid response status: " + statusText);
+        }
+        final HttpResponse response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_2, statusCode, null);
+        for (int i = 0; i < messageHeaders.size(); i++) {
+            response.addHeader(messageHeaders.get(i));
+        }
+        return response;
+    }
+
+    @Override
+    public List<Header> convert(final HttpResponse message) throws HttpException {
+        final int code = message.getCode();
+        if (code < 100 || code >= 600) {
+            throw new ProtocolException("Response status " + code + " is invalid");
+        }
+        final List<Header> headers = new ArrayList<>();
+        headers.add(new BasicHeader(H2PseudoResponseHeaders.STATUS, Integer.toString(code), false));
+
+        for (final Iterator<Header> it = message.headerIterator(); it.hasNext(); ) {
+            final Header header = it.next();
+            final String name = header.getName();
+            if (name.startsWith(":")) {
+                throw new ProtocolException("Header name '" + name + "' is invalid");
+            }
+            if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
+                throw new ProtocolException("Header '" + header.getName() + ": " + header.getValue() + "' is illegal for HTTP/2 messages");
+            }
+            headers.add(header);
+        }
+        return headers;
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2ResponseConverter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameInputBuffer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameInputBuffer.java?rev=1758066&r1=1758065&r2=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameInputBuffer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameInputBuffer.java Sat Aug 27 19:39:26 2016
@@ -38,8 +38,8 @@ import org.apache.hc.core5.http2.H2Error
 import org.apache.hc.core5.http2.frame.FrameConsts;
 import org.apache.hc.core5.http2.frame.FrameFlag;
 import org.apache.hc.core5.http2.frame.RawFrame;
-import org.apache.hc.core5.http2.impl.BasicHttp2TransportMetrics;
-import org.apache.hc.core5.http2.io.Http2TransportMetrics;
+import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
+import org.apache.hc.core5.http2.H2TransportMetrics;
 import org.apache.hc.core5.util.Args;
 
 /**
@@ -49,14 +49,14 @@ import org.apache.hc.core5.util.Args;
  */
 public final class FrameInputBuffer {
 
-    private final BasicHttp2TransportMetrics metrics;
+    private final BasicH2TransportMetrics metrics;
     private final int maxFramePayloadSize;
     private final byte[] buffer;
 
     private int off;
     private int dataLen;
 
-    FrameInputBuffer(final BasicHttp2TransportMetrics metrics, final int bufferLen, final int maxFramePayloadSize) {
+    FrameInputBuffer(final BasicH2TransportMetrics metrics, final int bufferLen, final int maxFramePayloadSize) {
         Args.notNull(metrics, "HTTP2 transport metrcis");
         Args.positive(maxFramePayloadSize, "Maximum payload size");
         this.metrics = metrics;
@@ -65,12 +65,12 @@ public final class FrameInputBuffer {
         this.dataLen = 0;
     }
 
-    public FrameInputBuffer(final BasicHttp2TransportMetrics metrics, final int maxFramePayloadSize) {
+    public FrameInputBuffer(final BasicH2TransportMetrics metrics, final int maxFramePayloadSize) {
         this(metrics, FrameConsts.HEAD_LEN + maxFramePayloadSize, maxFramePayloadSize);
     }
 
     public FrameInputBuffer(final int maxFramePayloadSize) {
-        this(new BasicHttp2TransportMetrics(), maxFramePayloadSize);
+        this(new BasicH2TransportMetrics(), maxFramePayloadSize);
     }
 
     boolean hasData() {
@@ -134,7 +134,7 @@ public final class FrameInputBuffer {
         return frame;
     }
 
-    public Http2TransportMetrics getMetrics() {
+    public H2TransportMetrics getMetrics() {
         return metrics;
     }
 

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameOutputBuffer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameOutputBuffer.java?rev=1758066&r1=1758065&r2=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameOutputBuffer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/io/FrameOutputBuffer.java Sat Aug 27 19:39:26 2016
@@ -36,8 +36,8 @@ import org.apache.hc.core5.http2.H2Error
 import org.apache.hc.core5.http2.frame.FrameConsts;
 import org.apache.hc.core5.http2.frame.FrameFlag;
 import org.apache.hc.core5.http2.frame.RawFrame;
-import org.apache.hc.core5.http2.impl.BasicHttp2TransportMetrics;
-import org.apache.hc.core5.http2.io.Http2TransportMetrics;
+import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
+import org.apache.hc.core5.http2.H2TransportMetrics;
 import org.apache.hc.core5.util.Args;
 
 /**
@@ -47,11 +47,11 @@ import org.apache.hc.core5.util.Args;
  */
 public final class FrameOutputBuffer {
 
-    private final BasicHttp2TransportMetrics metrics;
+    private final BasicH2TransportMetrics metrics;
     private final int maxFramePayloadSize;
     private final byte[] buffer;
 
-    public FrameOutputBuffer(final BasicHttp2TransportMetrics metrics, final int maxFramePayloadSize) {
+    public FrameOutputBuffer(final BasicH2TransportMetrics metrics, final int maxFramePayloadSize) {
         super();
         Args.notNull(metrics, "HTTP2 transport metrcis");
         Args.positive(maxFramePayloadSize, "Maximum payload size");
@@ -61,7 +61,7 @@ public final class FrameOutputBuffer {
     }
 
     public FrameOutputBuffer(final int maxFramePayloadSize) {
-        this(new BasicHttp2TransportMetrics(), maxFramePayloadSize);
+        this(new BasicH2TransportMetrics(), maxFramePayloadSize);
     }
 
     public void write(final RawFrame frame, final OutputStream outstream) throws IOException {
@@ -108,7 +108,7 @@ public final class FrameOutputBuffer {
         metrics.incrementBytesTransferred(frameLen);
     }
 
-    public Http2TransportMetrics getMetrics() {
+    public H2TransportMetrics getMetrics() {
         return metrics;
     }
 

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameInputBuffer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameInputBuffer.java?rev=1758066&r1=1758065&r2=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameInputBuffer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameInputBuffer.java Sat Aug 27 19:39:26 2016
@@ -37,8 +37,8 @@ import org.apache.hc.core5.http2.H2Error
 import org.apache.hc.core5.http2.frame.FrameConsts;
 import org.apache.hc.core5.http2.frame.FrameFlag;
 import org.apache.hc.core5.http2.frame.RawFrame;
-import org.apache.hc.core5.http2.impl.BasicHttp2TransportMetrics;
-import org.apache.hc.core5.http2.io.Http2TransportMetrics;
+import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
+import org.apache.hc.core5.http2.H2TransportMetrics;
 import org.apache.hc.core5.util.Args;
 
 /**
@@ -50,7 +50,7 @@ public final class FrameInputBuffer {
 
     enum State { HEAD_EXPECTED, PAYLOAD_EXPECTED }
 
-    private final BasicHttp2TransportMetrics metrics;
+    private final BasicH2TransportMetrics metrics;
     private final int maxFramePayloadSize;
     private final byte[] bytes;
     private final ByteBuffer buffer;
@@ -61,7 +61,7 @@ public final class FrameInputBuffer {
     private int flags;
     private int streamId;
 
-    FrameInputBuffer(final BasicHttp2TransportMetrics metrics, final int bufferLen, final int maxFramePayloadSize) {
+    FrameInputBuffer(final BasicH2TransportMetrics metrics, final int bufferLen, final int maxFramePayloadSize) {
         Args.notNull(metrics, "HTTP2 transport metrcis");
         Args.positive(maxFramePayloadSize, "Maximum payload size");
         this.metrics = metrics;
@@ -72,12 +72,12 @@ public final class FrameInputBuffer {
         this.state = State.HEAD_EXPECTED;
     }
 
-    public FrameInputBuffer(final BasicHttp2TransportMetrics metrics, final int maxFramePayloadSize) {
+    public FrameInputBuffer(final BasicH2TransportMetrics metrics, final int maxFramePayloadSize) {
         this(metrics, FrameConsts.HEAD_LEN + maxFramePayloadSize, maxFramePayloadSize);
     }
 
     public FrameInputBuffer(final int maxFramePayloadSize) {
-        this(new BasicHttp2TransportMetrics(), maxFramePayloadSize);
+        this(new BasicH2TransportMetrics(), maxFramePayloadSize);
     }
 
     public RawFrame read(final ReadableByteChannel channel) throws IOException {
@@ -145,7 +145,7 @@ public final class FrameInputBuffer {
         state = State.HEAD_EXPECTED;
     }
 
-    public Http2TransportMetrics getMetrics() {
+    public H2TransportMetrics getMetrics() {
         return metrics;
     }
 

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameOutputBuffer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameOutputBuffer.java?rev=1758066&r1=1758065&r2=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameOutputBuffer.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/FrameOutputBuffer.java Sat Aug 27 19:39:26 2016
@@ -35,8 +35,8 @@ import org.apache.hc.core5.http2.H2Conne
 import org.apache.hc.core5.http2.H2Error;
 import org.apache.hc.core5.http2.frame.FrameConsts;
 import org.apache.hc.core5.http2.frame.RawFrame;
-import org.apache.hc.core5.http2.impl.BasicHttp2TransportMetrics;
-import org.apache.hc.core5.http2.io.Http2TransportMetrics;
+import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
+import org.apache.hc.core5.http2.H2TransportMetrics;
 import org.apache.hc.core5.util.Args;
 
 /**
@@ -46,11 +46,11 @@ import org.apache.hc.core5.util.Args;
  */
 public final class FrameOutputBuffer {
 
-    private final BasicHttp2TransportMetrics metrics;
+    private final BasicH2TransportMetrics metrics;
     private final int maxFramePayloadSize;
     private final ByteBuffer buffer;
 
-    public FrameOutputBuffer(final BasicHttp2TransportMetrics metrics, final int maxFramePayloadSize) {
+    public FrameOutputBuffer(final BasicH2TransportMetrics metrics, final int maxFramePayloadSize) {
         Args.notNull(metrics, "HTTP2 transport metrcis");
         Args.positive(maxFramePayloadSize, "Maximum payload size");
         this.metrics = metrics;
@@ -59,7 +59,7 @@ public final class FrameOutputBuffer {
     }
 
     public FrameOutputBuffer(final int maxFramePayloadSize) {
-        this(new BasicHttp2TransportMetrics(), maxFramePayloadSize);
+        this(new BasicH2TransportMetrics(), maxFramePayloadSize);
     }
 
     private void writeToChannel(final WritableByteChannel channel, final ByteBuffer src) throws IOException {
@@ -115,7 +115,7 @@ public final class FrameOutputBuffer {
         return buffer.position() == 0;
     }
 
-    public Http2TransportMetrics getMetrics() {
+    public H2TransportMetrics getMetrics() {
         return metrics;
     }
 

Added: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java?rev=1758066&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java Sat Aug 27 19:39:26 2016
@@ -0,0 +1,432 @@
+/*
+ * ====================================================================
+ * 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.http2.impl;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.BasicHttpRequest;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class TestDefaultH2RequestConverter {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    @Test
+    public void testConvertFromFieldsBasic() throws Exception {
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom123", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        final HttpRequest request = converter.convert(headers);
+        Assert.assertNotNull(request);
+        Assert.assertEquals("GET", request.getMethod());
+        Assert.assertEquals("http", request.getScheme());
+        Assert.assertEquals("www.example.com", request.getAuthority());
+        Assert.assertEquals("/", request.getPath());
+        final Header[] allHeaders = request.getAllHeaders();
+        Assert.assertEquals(1, allHeaders.length);
+        Assert.assertEquals("custom123", allHeaders[0].getName());
+        Assert.assertEquals("value", allHeaders[0].getValue());
+    }
+
+    @Test
+    public void testConvertFromFieldsUpperCaseHeaderName() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header name ':Path' is invalid (header name contains uppercase characters)");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":Path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsConnectionHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header 'connection: keep-alive' is illegal for HTTP/2 messages");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("connection", "keep-alive"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsPseudoHeaderSequence() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Invalid sequence of headers (pseudo-headers must precede message headers)");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader("custom", "value"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMissingMethod() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Mandatory request header ':method' not found");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMissingScheme() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Mandatory request header ':scheme' not found");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMissingPath() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Mandatory request header ':path' not found");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsUnknownPseudoHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Unsupported request header ':custom'");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader(":custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMultipleMethod() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Multiple ':method' request headers are illegal");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMultipleScheme() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Multiple ':scheme' request headers are illegal");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":scheme", "https"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMultiplePath() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Multiple ':path' request headers are illegal");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "GET"),
+                new BasicHeader(":scheme", "https"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsConnect() throws Exception {
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "CONNECT"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsConnectMissingAuthority() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header ':authority' is mandatory for CONNECT request");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "CONNECT"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsConnectPresentScheme() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header ':scheme' must not be set for CONNECT request");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "CONNECT"),
+                new BasicHeader(":scheme", "http"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsConnectPresentPath() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header ':path' must not be set for CONNECT request");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":method", "CONNECT"),
+                new BasicHeader(":authority", "www.example.com"),
+                new BasicHeader(":path", "/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromMessageBasic() throws Exception {
+
+        final HttpRequest request = new BasicHttpRequest("GET", new HttpHost("host"), "/");
+        request.addHeader("custom123", "Value");
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        final List<Header> headers = converter.convert(request);
+
+        Assert.assertNotNull(headers);
+        Assert.assertEquals(5, headers.size());
+        final Header header1 = headers.get(0);
+        Assert.assertEquals(":method", header1.getName());
+        Assert.assertEquals("GET", header1.getValue());
+        final Header header2 = headers.get(1);
+        Assert.assertEquals(":scheme", header2.getName());
+        Assert.assertEquals("http", header2.getValue());
+        final Header header3 = headers.get(2);
+        Assert.assertEquals(":authority", header3.getName());
+        Assert.assertEquals("host", header3.getValue());
+        final Header header4 = headers.get(3);
+        Assert.assertEquals(":path", header4.getName());
+        Assert.assertEquals("/", header4.getValue());
+        final Header header5 = headers.get(4);
+        Assert.assertEquals("custom123", header5.getName());
+        Assert.assertEquals("Value", header5.getValue());
+    }
+
+    @Test
+    public void testConvertFromMessageMissingScheme() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Request scheme is not set");
+
+        final HttpRequest request = new BasicHttpRequest("GET", new HttpHost("host"), "/");
+        request.addHeader("Custom123", "Value");
+        request.setScheme(null);
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(request);
+    }
+
+    @Test
+    public void testConvertFromMessageMissingPath() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Request path is not set");
+
+        final HttpRequest request = new BasicHttpRequest("GET", new HttpHost("host"), "/");
+        request.addHeader("Custom123", "Value");
+        request.setPath(null);
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(request);
+    }
+
+    @Test
+    public void testConvertFromMessageConnect() throws Exception {
+
+        final HttpRequest request = new BasicHttpRequest("CONNECT", new HttpHost("host:80"), null);
+        request.addHeader("custom123", "Value");
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        final List<Header> headers = converter.convert(request);
+
+        Assert.assertNotNull(headers);
+        Assert.assertEquals(3, headers.size());
+        final Header header1 = headers.get(0);
+        Assert.assertEquals(":method", header1.getName());
+        Assert.assertEquals("CONNECT", header1.getValue());
+        final Header header2 = headers.get(1);
+        Assert.assertEquals(":authority", header2.getName());
+        Assert.assertEquals("host:80", header2.getValue());
+        final Header header3 = headers.get(2);
+        Assert.assertEquals("custom123", header3.getName());
+        Assert.assertEquals("Value", header3.getValue());
+    }
+
+    @Test
+    public void testConvertFromMessageConnectMissingAuthority() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("CONNECT request authority is not set");
+
+        final HttpRequest request = new BasicHttpRequest("CONNECT", null, null);
+        request.addHeader("Custom123", "Value");
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(request);
+    }
+
+    @Test
+    public void testConvertFromMessageConnectWithPath() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("CONNECT request path must be null");
+
+        final HttpRequest request = new BasicHttpRequest("CONNECT", "/");
+        request.setAuthority("host");
+        request.addHeader("Custom123", "Value");
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(request);
+    }
+
+    @Test
+    public void testConvertFromMessageConnectionHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header 'Connection: Keep-Alive' is illegal for HTTP/2 messages");
+
+        final HttpRequest request = new BasicHttpRequest("GET", new HttpHost("host"), "/");
+        request.addHeader("Connection", "Keep-Alive");
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(request);
+    }
+
+    @Test
+    public void testConvertFromMessageInvalidHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header name ':custom' is invalid");
+
+        final HttpRequest request = new BasicHttpRequest("GET", new HttpHost("host"), "/");
+        request.addHeader(":custom", "stuff");
+
+        final DefaultH2RequestConverter converter = new DefaultH2RequestConverter();
+        converter.convert(request);
+    }
+
+}
+

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java?rev=1758066&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java (added)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java Sat Aug 27 19:39:26 2016
@@ -0,0 +1,218 @@
+/*
+ * ====================================================================
+ * 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.http2.impl;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class TestDefaultH2ResponseConverter {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    @Test
+    public void testConvertFromFieldsBasic() throws Exception {
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":status", "200"),
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("custom123", "value"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        final HttpResponse response = converter.convert(headers);
+        Assert.assertNotNull(response );
+        Assert.assertEquals(200, response .getCode());
+        final Header[] allHeaders = response.getAllHeaders();
+        Assert.assertEquals(2, allHeaders.length);
+        Assert.assertEquals("location", allHeaders[0].getName());
+        Assert.assertEquals("http://www.example.com/", allHeaders[0].getValue());
+        Assert.assertEquals("custom123", allHeaders[1].getName());
+        Assert.assertEquals("value", allHeaders[1].getValue());
+    }
+
+    @Test
+    public void testConvertFromFieldsUpperCaseHeaderName() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header name ':Status' is invalid (header name contains uppercase characters)");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":Status", "200"),
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("custom123", "value"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsInvalidStatusCode() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Invalid response status: boom");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":status", "boom"),
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("custom123", "value"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsConnectionHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header 'connection: keep-alive' is illegal for HTTP/2 messages");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":status", "200"),
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("connection", "keep-alive"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMissingStatus() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Mandatory response header ':status' not found");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("custom", "value"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsUnknownPseudoHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Unsupported response header ':custom'");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":status", "200"),
+                new BasicHeader(":custom", "200"),
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("custom1", "value"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromFieldsMultipleStatus() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Multiple ':status' response headers are illegal");
+
+        final List<Header> headers = Arrays.<Header>asList(
+                new BasicHeader(":status", "200"),
+                new BasicHeader(":status", "200"),
+                new BasicHeader("location", "http://www.example.com/"),
+                new BasicHeader("custom1", "value"));
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(headers);
+    }
+
+    @Test
+    public void testConvertFromMessageBasic() throws Exception {
+
+        final HttpResponse response = new BasicHttpResponse(200);
+        response.addHeader("custom123", "Value");
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        final List<Header> headers = converter.convert(response);
+
+        Assert.assertNotNull(headers);
+        Assert.assertEquals(2, headers.size());
+        final Header header1 = headers.get(0);
+        Assert.assertEquals(":status", header1.getName());
+        Assert.assertEquals("200", header1.getValue());
+        final Header header2 = headers.get(1);
+        Assert.assertEquals("custom123", header2.getName());
+        Assert.assertEquals("Value", header2.getValue());
+    }
+
+    @Test
+    public void testConvertFromMessageInvalidStatus() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Response status 99 is invalid");
+
+        final HttpResponse response = new BasicHttpResponse(99);
+        response.addHeader("Custom123", "Value");
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(response);
+    }
+
+    @Test
+    public void testConvertFromMessageConnectionHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header 'Connection: Keep-Alive' is illegal for HTTP/2 messages");
+
+        final HttpResponse response = new BasicHttpResponse(200);
+        response.addHeader("Connection", "Keep-Alive");
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(response);
+    }
+
+    @Test
+    public void testConvertFromMessageInvalidHeader() throws Exception {
+
+        thrown.expect(HttpException.class);
+        thrown.expectMessage("Header name ':custom' is invalid");
+
+        final HttpResponse response = new BasicHttpResponse(200);
+        response.addHeader(":custom", "stuff");
+
+        final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
+        converter.convert(response);
+    }
+
+}
+

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestFrameInOutBuffers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestFrameInOutBuffers.java?rev=1758066&r1=1758065&r2=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestFrameInOutBuffers.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/io/TestFrameInOutBuffers.java Sat Aug 27 19:39:26 2016
@@ -38,7 +38,7 @@ import org.apache.hc.core5.http2.frame.F
 import org.apache.hc.core5.http2.frame.FrameFlag;
 import org.apache.hc.core5.http2.frame.FrameType;
 import org.apache.hc.core5.http2.frame.RawFrame;
-import org.apache.hc.core5.http2.impl.BasicHttp2TransportMetrics;
+import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -119,7 +119,7 @@ public class TestFrameInOutBuffers {
 
     @Test
     public void testReadFrameMultipleSmallBuffer() throws Exception {
-        final FrameInputBuffer inbuffer = new FrameInputBuffer(new BasicHttp2TransportMetrics(), 20, 10);
+        final FrameInputBuffer inbuffer = new FrameInputBuffer(new BasicH2TransportMetrics(), 20, 10);
         final ByteArrayInputStream inputStream = new ByteArrayInputStream(
                 new byte[] {
                         0,0,10,0,8,0,0,0,8,4,1,1,1,1,1,0,0,0,0,

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestFrameInOutBuffers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestFrameInOutBuffers.java?rev=1758066&r1=1758065&r2=1758066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestFrameInOutBuffers.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestFrameInOutBuffers.java Sat Aug 27 19:39:26 2016
@@ -36,7 +36,7 @@ import org.apache.hc.core5.http2.frame.F
 import org.apache.hc.core5.http2.frame.FrameFlag;
 import org.apache.hc.core5.http2.frame.FrameType;
 import org.apache.hc.core5.http2.frame.RawFrame;
-import org.apache.hc.core5.http2.impl.BasicHttp2TransportMetrics;
+import org.apache.hc.core5.http2.impl.BasicH2TransportMetrics;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -139,7 +139,7 @@ public class TestFrameInOutBuffers {
 
     @Test
     public void testReadFrameMultipleSmallBuffer() throws Exception {
-        final FrameInputBuffer inbuffer = new FrameInputBuffer(new BasicHttp2TransportMetrics(), 20, 10);
+        final FrameInputBuffer inbuffer = new FrameInputBuffer(new BasicH2TransportMetrics(), 20, 10);
         final ReadableByteChannelMock readableChannel = new ReadableByteChannelMock(
                 new byte[] {
                         0,0,10,0,8,0,0,0,8,4,1,1,1,1,1,0,0,0,0,



Mime
View raw message