1/* 2 * Copyright (C) 2014 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.spdy; 17 18import com.squareup.okhttp.internal.Util; 19import java.io.IOException; 20import okio.ByteString; 21import okio.OkBuffer; 22import org.junit.Test; 23 24import static org.junit.Assert.assertEquals; 25import static org.junit.Assert.fail; 26 27public class Spdy3Test { 28 static final int expectedStreamId = 15; 29 30 @Test public void tooLargeDataFrame() throws IOException { 31 try { 32 sendDataFrame(new OkBuffer().write(new byte[0x1000000])); 33 fail(); 34 } catch (IllegalArgumentException e) { 35 assertEquals("FRAME_TOO_LARGE max size is 16Mib: " + 0x1000000L, e.getMessage()); 36 } 37 } 38 39 @Test public void badWindowSizeIncrement() throws IOException { 40 try { 41 windowUpdate(0); 42 fail(); 43 } catch (IllegalArgumentException e) { 44 assertEquals("windowSizeIncrement must be between 1 and 0x7fffffff: 0", e.getMessage()); 45 } 46 try { 47 windowUpdate(0x80000000L); 48 fail(); 49 } catch (IllegalArgumentException e) { 50 assertEquals("windowSizeIncrement must be between 1 and 0x7fffffff: 2147483648", 51 e.getMessage()); 52 } 53 } 54 55 @Test public void goAwayRoundTrip() throws IOException { 56 OkBuffer frame = new OkBuffer(); 57 58 final ErrorCode expectedError = ErrorCode.PROTOCOL_ERROR; 59 60 // Compose the expected GOAWAY frame without debug data 61 // |C| Version(15bits) | Type(16bits) | 62 frame.writeInt(0x80000000 | (Spdy3.VERSION & 0x7fff) << 16 | Spdy3.TYPE_GOAWAY & 0xffff); 63 // | Flags (8) | Length (24 bits) | 64 frame.writeInt(8); // no flags and length is 8. 65 frame.writeInt(expectedStreamId); // last good stream. 66 frame.writeInt(expectedError.spdyGoAwayCode); 67 68 // Check writer sends the same bytes. 69 assertEquals(frame, sendGoAway(expectedStreamId, expectedError, Util.EMPTY_BYTE_ARRAY)); 70 71 // SPDY/3 does not send debug data, so bytes should be same! 72 assertEquals(frame, sendGoAway(expectedStreamId, expectedError, new byte[8])); 73 74 FrameReader fr = new Spdy3.Reader(frame, false); 75 76 fr.nextFrame(new BaseTestHandler() { // Consume the goAway frame. 77 @Override public void goAway( 78 int lastGoodStreamId, ErrorCode errorCode, ByteString debugData) { 79 assertEquals(expectedStreamId, lastGoodStreamId); 80 assertEquals(expectedError, errorCode); 81 assertEquals(0, debugData.size()); 82 } 83 }); 84 } 85 86 private void sendDataFrame(OkBuffer source) throws IOException { 87 Spdy3.Writer writer = new Spdy3.Writer(new OkBuffer(), true); 88 writer.sendDataFrame(expectedStreamId, 0, source, (int) source.size()); 89 } 90 91 private void windowUpdate(long increment) throws IOException { 92 new Spdy3.Writer(new OkBuffer(), true).windowUpdate(expectedStreamId, increment); 93 } 94 95 private OkBuffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) 96 throws IOException { 97 OkBuffer out = new OkBuffer(); 98 new Spdy3.Writer(out, true).goAway(lastGoodStreamId, errorCode, debugData); 99 return out; 100 } 101} 102