Home | History | Annotate | Download | only in framed
      1 /*
      2  * Copyright (C) 2013 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  */
     16 package com.squareup.okhttp.internal.framed;
     17 
     18 import com.squareup.okhttp.Headers;
     19 import com.squareup.okhttp.Protocol;
     20 import com.squareup.okhttp.mockwebserver.MockResponse;
     21 import com.squareup.okhttp.mockwebserver.PushPromise;
     22 import com.squareup.okhttp.mockwebserver.RecordedRequest;
     23 import java.net.HttpURLConnection;
     24 import org.junit.Test;
     25 
     26 import static org.junit.Assert.assertEquals;
     27 
     28 public class HttpOverHttp2Test extends HttpOverSpdyTest {
     29 
     30   public HttpOverHttp2Test() {
     31     super(Protocol.HTTP_2);
     32     this.hostHeader = ":authority";
     33   }
     34 
     35   @Test public void serverSendsPushPromise_GET() throws Exception {
     36     PushPromise pushPromise = new PushPromise("GET", "/foo/bar", Headers.of("foo", "bar"),
     37         new MockResponse().setBody("bar").setStatus("HTTP/1.1 200 Sweet"));
     38     MockResponse response = new MockResponse()
     39         .setBody("ABCDE")
     40         .setStatus("HTTP/1.1 200 Sweet")
     41         .withPush(pushPromise);
     42     server.enqueue(response);
     43 
     44     connection = client.open(server.getUrl("/foo"));
     45     assertContent("ABCDE", connection, Integer.MAX_VALUE);
     46     assertEquals(200, connection.getResponseCode());
     47     assertEquals("Sweet", connection.getResponseMessage());
     48 
     49     RecordedRequest request = server.takeRequest();
     50     assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
     51     assertEquals("https", request.getHeader(":scheme"));
     52     assertEquals(server.getHostName() + ":" + server.getPort(), request.getHeader(hostHeader));
     53 
     54     RecordedRequest pushedRequest = server.takeRequest();
     55     assertEquals("GET /foo/bar HTTP/1.1", pushedRequest.getRequestLine());
     56     assertEquals("bar", pushedRequest.getHeader("foo"));
     57   }
     58 
     59   @Test public void serverSendsPushPromise_HEAD() throws Exception {
     60     PushPromise pushPromise = new PushPromise("HEAD", "/foo/bar", Headers.of("foo", "bar"),
     61         new MockResponse().setStatus("HTTP/1.1 204 Sweet"));
     62     MockResponse response = new MockResponse()
     63         .setBody("ABCDE")
     64         .setStatus("HTTP/1.1 200 Sweet")
     65         .withPush(pushPromise);
     66     server.enqueue(response);
     67 
     68     connection = client.open(server.getUrl("/foo"));
     69     assertContent("ABCDE", connection, Integer.MAX_VALUE);
     70     assertEquals(200, connection.getResponseCode());
     71     assertEquals("Sweet", connection.getResponseMessage());
     72 
     73     RecordedRequest request = server.takeRequest();
     74     assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
     75     assertEquals("https", request.getHeader(":scheme"));
     76     assertEquals(server.getHostName() + ":" + server.getPort(), request.getHeader(hostHeader));
     77 
     78     RecordedRequest pushedRequest = server.takeRequest();
     79     assertEquals("HEAD /foo/bar HTTP/1.1", pushedRequest.getRequestLine());
     80     assertEquals("bar", pushedRequest.getHeader("foo"));
     81   }
     82 
     83   /**
     84    * Push a setting that permits up to 2 concurrent streams, then make 3 concurrent requests and
     85    * confirm that the third concurrent request prepared a new connection.
     86    */
     87   @Test public void settingsLimitsMaxConcurrentStreams() throws Exception {
     88     Settings settings = new Settings();
     89     settings.set(Settings.MAX_CONCURRENT_STREAMS, 0, 2);
     90 
     91     // Read & write a full request to confirm settings are accepted.
     92     server.enqueue(new MockResponse().withSettings(settings));
     93     HttpURLConnection settingsConnection = client.open(server.getUrl("/"));
     94     assertContent("", settingsConnection, Integer.MAX_VALUE);
     95 
     96     server.enqueue(new MockResponse().setBody("ABC"));
     97     server.enqueue(new MockResponse().setBody("DEF"));
     98     server.enqueue(new MockResponse().setBody("GHI"));
     99 
    100     HttpURLConnection connection1 = client.open(server.getUrl("/"));
    101     connection1.connect();
    102     HttpURLConnection connection2 = client.open(server.getUrl("/"));
    103     connection2.connect();
    104     HttpURLConnection connection3 = client.open(server.getUrl("/"));
    105     connection3.connect();
    106     assertContent("ABC", connection1, Integer.MAX_VALUE);
    107     assertContent("DEF", connection2, Integer.MAX_VALUE);
    108     assertContent("GHI", connection3, Integer.MAX_VALUE);
    109     assertEquals(0, server.takeRequest().getSequenceNumber()); // Settings connection.
    110     assertEquals(1, server.takeRequest().getSequenceNumber()); // Reuse settings connection.
    111     assertEquals(2, server.takeRequest().getSequenceNumber()); // Reuse settings connection.
    112     assertEquals(0, server.takeRequest().getSequenceNumber()); // New connection!
    113   }
    114 }
    115