13c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller/* 23c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Copyright (C) 2012 Square, Inc. 33c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 43c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License"); 53c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * you may not use this file except in compliance with the License. 63c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * You may obtain a copy of the License at 73c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 83c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * http://www.apache.org/licenses/LICENSE-2.0 93c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Unless required by applicable law or agreed to in writing, software 113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * See the License for the specific language governing permissions and 143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * limitations under the License. 153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpackage com.squareup.okhttp.internal.http; 173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Headers; 193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Protocol; 203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Request; 213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.Response; 223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.internal.spdy.Header; 233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.io.IOException; 243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.List; 253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport org.junit.Test; 263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static com.squareup.okhttp.internal.Util.headerEntries; 283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static org.junit.Assert.assertEquals; 293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static org.junit.Assert.assertNull; 303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpublic final class HeadersTest { 323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void parseNameValueBlock() throws IOException { 333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> headerBlock = headerEntries( 343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller "cache-control", "no-cache, no-store", 353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller "set-cookie", "Cookie1\u0000Cookie2", 363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":status", "200 OK", 373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":version", "HTTP/1.1"); 383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder().url("http://square.com/").build(); 393c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Response response = 403c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller SpdyTransport.readNameValueBlock(headerBlock, Protocol.SPDY_3).request(request).build(); 413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Headers headers = response.headers(); 423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(4, headers.size()); 433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("HTTP/1.1 200 OK", response.statusLine()); 443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("no-cache, no-store", headers.get("cache-control")); 453c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("Cookie2", headers.get("set-cookie")); 463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(Protocol.SPDY_3.name.utf8(), headers.get(OkHeaders.SELECTED_PROTOCOL)); 473c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(OkHeaders.SELECTED_PROTOCOL, headers.name(0)); 483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(Protocol.SPDY_3.name.utf8(), headers.value(0)); 493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("cache-control", headers.name(1)); 503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("no-cache, no-store", headers.value(1)); 513c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("set-cookie", headers.name(2)); 523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("Cookie1", headers.value(2)); 533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("set-cookie", headers.name(3)); 543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("Cookie2", headers.value(3)); 553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertNull(headers.get(":status")); 563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertNull(headers.get(":version")); 573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void readNameValueBlockDropsForbiddenHeadersSpdy3() throws IOException { 603c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> headerBlock = headerEntries( 613c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":status", "200 OK", 623c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":version", "HTTP/1.1", 633c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller "connection", "close"); 643c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder().url("http://square.com/").build(); 653c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Response response = 663c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller SpdyTransport.readNameValueBlock(headerBlock, Protocol.SPDY_3).request(request).build(); 673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Headers headers = response.headers(); 683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(1, headers.size()); 693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(OkHeaders.SELECTED_PROTOCOL, headers.name(0)); 703c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(Protocol.SPDY_3.name.utf8(), headers.value(0)); 713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 723c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 733c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void readNameValueBlockDropsForbiddenHeadersHttp2() throws IOException { 743c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> headerBlock = headerEntries( 753c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":status", "200 OK", 763c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":version", "HTTP/1.1", 773c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller "connection", "close"); 783c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder().url("http://square.com/").build(); 793c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Response response = SpdyTransport.readNameValueBlock(headerBlock, Protocol.HTTP_2) 803c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .request(request).build(); 813c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Headers headers = response.headers(); 823c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(1, headers.size()); 833c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(OkHeaders.SELECTED_PROTOCOL, headers.name(0)); 843c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(Protocol.HTTP_2.name.utf8(), headers.value(0)); 853c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 863c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 873c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void toNameValueBlock() { 883c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder() 893c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .url("http://square.com/") 903c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header("cache-control", "no-cache, no-store") 913c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("set-cookie", "Cookie1") 923c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("set-cookie", "Cookie2") 933c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header(":status", "200 OK") 943c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .build(); 953c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> headerBlock = 963c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller SpdyTransport.writeNameValueBlock(request, Protocol.SPDY_3, "HTTP/1.1"); 973c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> expected = headerEntries( 983c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":method", "GET", 993c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":path", "/", 1003c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":version", "HTTP/1.1", 1013c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":host", "square.com", 1023c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":scheme", "http", 1033c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller "cache-control", "no-cache, no-store", 1043c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller "set-cookie", "Cookie1\u0000Cookie2", 1053c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":status", "200 OK"); 1063c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(expected, headerBlock); 1073c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1083c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1093c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void toNameValueBlockDropsForbiddenHeadersSpdy3() { 1103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder() 1113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .url("http://square.com/") 1123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header("Connection", "close") 1133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header("Transfer-Encoding", "chunked") 1143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .build(); 1153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> expected = headerEntries( 1163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":method", "GET", 1173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":path", "/", 1183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":version", "HTTP/1.1", 1193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":host", "square.com", 1203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":scheme", "http"); 1213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(expected, SpdyTransport.writeNameValueBlock(request, Protocol.SPDY_3, "HTTP/1.1")); 1223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void toNameValueBlockDropsForbiddenHeadersHttp2() { 1253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder() 1263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .url("http://square.com/") 1273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header("Connection", "upgrade") 1283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header("Upgrade", "websocket") 1293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .build(); 1303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller List<Header> expected = headerEntries( 1313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":method", "GET", 1323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":path", "/", 1333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":authority", "square.com", 1343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller ":scheme", "http"); 1353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(expected, 1363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller SpdyTransport.writeNameValueBlock(request, Protocol.HTTP_2, "HTTP/1.1")); 1373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller} 139