1/*
2 * Copyright (C) 2012 Square, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.squareup.okhttp.internal.http;
17
18import com.squareup.okhttp.Headers;
19import com.squareup.okhttp.Protocol;
20import com.squareup.okhttp.Request;
21import com.squareup.okhttp.Response;
22import com.squareup.okhttp.internal.spdy.Header;
23import java.io.IOException;
24import java.util.List;
25import org.junit.Test;
26
27import static com.squareup.okhttp.internal.Util.headerEntries;
28import static org.junit.Assert.assertEquals;
29import static org.junit.Assert.assertNull;
30
31public final class HeadersTest {
32  @Test public void parseNameValueBlock() throws IOException {
33    List<Header> headerBlock = headerEntries(
34        "cache-control", "no-cache, no-store",
35        "set-cookie", "Cookie1\u0000Cookie2",
36        ":status", "200 OK",
37        ":version", "HTTP/1.1");
38    Request request = new Request.Builder().url("http://square.com/").build();
39    Response response =
40        SpdyTransport.readNameValueBlock(headerBlock, Protocol.SPDY_3).request(request).build();
41    Headers headers = response.headers();
42    assertEquals(4, headers.size());
43    assertEquals("HTTP/1.1 200 OK", response.statusLine());
44    assertEquals("no-cache, no-store", headers.get("cache-control"));
45    assertEquals("Cookie2", headers.get("set-cookie"));
46    assertEquals(Protocol.SPDY_3.name.utf8(), headers.get(OkHeaders.SELECTED_PROTOCOL));
47    assertEquals(OkHeaders.SELECTED_PROTOCOL, headers.name(0));
48    assertEquals(Protocol.SPDY_3.name.utf8(), headers.value(0));
49    assertEquals("cache-control", headers.name(1));
50    assertEquals("no-cache, no-store", headers.value(1));
51    assertEquals("set-cookie", headers.name(2));
52    assertEquals("Cookie1", headers.value(2));
53    assertEquals("set-cookie", headers.name(3));
54    assertEquals("Cookie2", headers.value(3));
55    assertNull(headers.get(":status"));
56    assertNull(headers.get(":version"));
57  }
58
59  @Test public void readNameValueBlockDropsForbiddenHeadersSpdy3() throws IOException {
60    List<Header> headerBlock = headerEntries(
61        ":status", "200 OK",
62        ":version", "HTTP/1.1",
63        "connection", "close");
64    Request request = new Request.Builder().url("http://square.com/").build();
65    Response response =
66        SpdyTransport.readNameValueBlock(headerBlock, Protocol.SPDY_3).request(request).build();
67    Headers headers = response.headers();
68    assertEquals(1, headers.size());
69    assertEquals(OkHeaders.SELECTED_PROTOCOL, headers.name(0));
70    assertEquals(Protocol.SPDY_3.name.utf8(), headers.value(0));
71  }
72
73  @Test public void readNameValueBlockDropsForbiddenHeadersHttp2() throws IOException {
74    List<Header> headerBlock = headerEntries(
75        ":status", "200 OK",
76        ":version", "HTTP/1.1",
77        "connection", "close");
78    Request request = new Request.Builder().url("http://square.com/").build();
79    Response response = SpdyTransport.readNameValueBlock(headerBlock, Protocol.HTTP_2)
80        .request(request).build();
81    Headers headers = response.headers();
82    assertEquals(1, headers.size());
83    assertEquals(OkHeaders.SELECTED_PROTOCOL, headers.name(0));
84    assertEquals(Protocol.HTTP_2.name.utf8(), headers.value(0));
85  }
86
87  @Test public void toNameValueBlock() {
88    Request request = new Request.Builder()
89        .url("http://square.com/")
90        .header("cache-control", "no-cache, no-store")
91        .addHeader("set-cookie", "Cookie1")
92        .addHeader("set-cookie", "Cookie2")
93        .header(":status", "200 OK")
94        .build();
95    List<Header> headerBlock =
96        SpdyTransport.writeNameValueBlock(request, Protocol.SPDY_3, "HTTP/1.1");
97    List<Header> expected = headerEntries(
98        ":method", "GET",
99        ":path", "/",
100        ":version", "HTTP/1.1",
101        ":host", "square.com",
102        ":scheme", "http",
103        "cache-control", "no-cache, no-store",
104        "set-cookie", "Cookie1\u0000Cookie2",
105        ":status", "200 OK");
106    assertEquals(expected, headerBlock);
107  }
108
109  @Test public void toNameValueBlockDropsForbiddenHeadersSpdy3() {
110    Request request = new Request.Builder()
111        .url("http://square.com/")
112        .header("Connection", "close")
113        .header("Transfer-Encoding", "chunked")
114        .build();
115    List<Header> expected = headerEntries(
116        ":method", "GET",
117        ":path", "/",
118        ":version", "HTTP/1.1",
119        ":host", "square.com",
120        ":scheme", "http");
121    assertEquals(expected, SpdyTransport.writeNameValueBlock(request, Protocol.SPDY_3, "HTTP/1.1"));
122  }
123
124  @Test public void toNameValueBlockDropsForbiddenHeadersHttp2() {
125    Request request = new Request.Builder()
126        .url("http://square.com/")
127        .header("Connection", "upgrade")
128        .header("Upgrade", "websocket")
129        .build();
130    List<Header> expected = headerEntries(
131        ":method", "GET",
132        ":path", "/",
133        ":authority", "square.com",
134        ":scheme", "http");
135    assertEquals(expected,
136        SpdyTransport.writeNameValueBlock(request, Protocol.HTTP_2, "HTTP/1.1"));
137  }
138}
139