View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http2.impl;
29  
30  import java.util.Arrays;
31  import java.util.List;
32  
33  import org.apache.hc.core5.http.Header;
34  import org.apache.hc.core5.http.HttpException;
35  import org.apache.hc.core5.http.HttpResponse;
36  import org.apache.hc.core5.http.message.BasicHeader;
37  import org.apache.hc.core5.http.message.BasicHttpResponse;
38  import org.junit.jupiter.api.Assertions;
39  import org.junit.jupiter.api.Test;
40  
41  public class TestDefaultH2ResponseConverter {
42  
43      @Test
44      public void testConvertFromFieldsBasic() throws Exception {
45  
46          final List<Header> headers = Arrays.asList(
47                  new BasicHeader(":status", "200"),
48                  new BasicHeader("location", "http://www.example.com/"),
49                  new BasicHeader("custom123", "value"));
50  
51          final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
52          final HttpResponse response = converter.convert(headers);
53          Assertions.assertNotNull(response );
54          Assertions.assertEquals(200, response .getCode());
55          final Header[] allHeaders = response.getHeaders();
56          Assertions.assertEquals(2, allHeaders.length);
57          Assertions.assertEquals("location", allHeaders[0].getName());
58          Assertions.assertEquals("http://www.example.com/", allHeaders[0].getValue());
59          Assertions.assertEquals("custom123", allHeaders[1].getName());
60          Assertions.assertEquals("value", allHeaders[1].getValue());
61      }
62  
63      @Test
64      public void testConvertFromFieldsUpperCaseHeaderName() throws Exception {
65          final List<Header> headers = Arrays.asList(
66                  new BasicHeader(":Status", "200"),
67                  new BasicHeader("location", "http://www.example.com/"),
68                  new BasicHeader("custom123", "value"));
69  
70          final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
71          Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
72                  "Header name ':Status' is invalid (header name contains uppercase characters)");
73      }
74  
75      @Test
76      public void testConvertFromFieldsInvalidStatusCode() throws Exception {
77          final List<Header> headers = Arrays.asList(
78                  new BasicHeader(":status", "boom"),
79                  new BasicHeader("location", "http://www.example.com/"),
80                  new BasicHeader("custom123", "value"));
81  
82          final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
83          Assertions.assertThrows(HttpException.class, () -> converter.convert(headers));
84      }
85  
86      @Test
87      public void testConvertFromFieldsConnectionHeader() throws Exception {
88          final List<Header> headers = Arrays.asList(
89                  new BasicHeader(":status", "200"),
90                  new BasicHeader("location", "http://www.example.com/"),
91                  new BasicHeader("connection", "keep-alive"));
92  
93          final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
94          Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
95                  "Header 'connection: keep-alive' is illegal for HTTP/2 messages");
96      }
97  
98      @Test
99      public void testConvertFromFieldsKeepAliveHeader() throws Exception {
100         final List<Header> headers = Arrays.asList(
101             new BasicHeader(":status", "200"),
102             new BasicHeader("location", "http://www.example.com/"),
103             new BasicHeader("keep-alive", "timeout=5, max=1000"));
104 
105         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
106         Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
107                 "Header 'keep-alive: timeout=5, max=1000' is illegal for HTTP/2 messages");
108     }
109 
110     @Test
111     public void testConvertFromFieldsTransferEncodingHeader() throws Exception {
112         final List<Header> headers = Arrays.asList(
113             new BasicHeader(":status", "200"),
114             new BasicHeader("location", "http://www.example.com/"),
115             new BasicHeader("transfer-encoding", "gzip"));
116 
117         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
118         Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
119                 "Header 'transfer-encoding: gzip' is illegal for HTTP/2 messages");
120     }
121 
122     @Test
123     public void testConvertFromFieldsUpgradeHeader() throws Exception {
124         final List<Header> headers = Arrays.asList(
125             new BasicHeader(":status", "200"),
126             new BasicHeader("location", "http://www.example.com/"),
127             new BasicHeader("upgrade", "example/1, foo/2"));
128 
129         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
130         Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
131                 "Header 'upgrade: example/1, foo/2' is illegal for HTTP/2 messages");
132     }
133 
134     @Test
135     public void testConvertFromFieldsMissingStatus() throws Exception {
136         final List<Header> headers = Arrays.asList(
137                 new BasicHeader("location", "http://www.example.com/"),
138                 new BasicHeader("custom", "value"));
139 
140         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
141         Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
142                 "Mandatory response header ':status' not found");
143     }
144 
145     @Test
146     public void testConvertFromFieldsUnknownPseudoHeader() throws Exception {
147         final List<Header> headers = Arrays.asList(
148                 new BasicHeader(":status", "200"),
149                 new BasicHeader(":custom", "200"),
150                 new BasicHeader("location", "http://www.example.com/"),
151                 new BasicHeader("custom1", "value"));
152 
153         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
154         Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
155                 "Unsupported response header ':custom'");
156     }
157 
158     @Test
159     public void testConvertFromFieldsMultipleStatus() throws Exception {
160         final List<Header> headers = Arrays.asList(
161                 new BasicHeader(":status", "200"),
162                 new BasicHeader(":status", "200"),
163                 new BasicHeader("location", "http://www.example.com/"),
164                 new BasicHeader("custom1", "value"));
165 
166         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
167         Assertions.assertThrows(HttpException.class, () -> converter.convert(headers),
168                 "Multiple ':status' response headers are illegal");
169     }
170 
171     @Test
172     public void testConvertFromMessageBasic() throws Exception {
173 
174         final HttpResponse response = new BasicHttpResponse(200);
175         response.addHeader("custom123", "Value");
176 
177         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
178         final List<Header> headers = converter.convert(response);
179 
180         Assertions.assertNotNull(headers);
181         Assertions.assertEquals(2, headers.size());
182         final Header header1 = headers.get(0);
183         Assertions.assertEquals(":status", header1.getName());
184         Assertions.assertEquals("200", header1.getValue());
185         final Header header2 = headers.get(1);
186         Assertions.assertEquals("custom123", header2.getName());
187         Assertions.assertEquals("Value", header2.getValue());
188     }
189 
190     @Test
191     public void testConvertFromMessageInvalidStatus() throws Exception {
192         final HttpResponse response = new BasicHttpResponse(99);
193         response.addHeader("Custom123", "Value");
194 
195         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
196         Assertions.assertThrows(HttpException.class, () -> converter.convert(response),
197                 "Response status 99 is invalid");
198     }
199 
200     @Test
201     public void testConvertFromMessageConnectionHeader() throws Exception {
202         final HttpResponse response = new BasicHttpResponse(200);
203         response.addHeader("Connection", "Keep-Alive");
204 
205         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
206         Assertions.assertThrows(HttpException.class, () -> converter.convert(response),
207                 "Header 'Connection: Keep-Alive' is illegal for HTTP/2 messages");
208     }
209 
210     @Test
211     public void testConvertFromMessageInvalidHeader() throws Exception {
212         final HttpResponse response = new BasicHttpResponse(200);
213         response.addHeader(":custom", "stuff");
214 
215         final DefaultH2ResponseConverter converter = new DefaultH2ResponseConverter();
216         Assertions.assertThrows(HttpException.class, () -> converter.convert(response),
217                 "Header name ':custom' is invalid");
218     }
219 
220 }
221