1 /* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.net.http; 27 28 import java.io.IOException; 29 import java.nio.ByteBuffer; 30 31 class HeadersFrame extends HeaderFrame { 32 33 public final static int TYPE = 0x1; 34 35 // Flags 36 public static final int END_STREAM = 0x1; 37 public static final int PADDED = 0x8; 38 public static final int PRIORITY = 0x20; 39 40 41 int padLength; 42 int streamDependency; 43 int weight; 44 boolean exclusive; 45 46 HeadersFrame() { 47 type = TYPE; 48 } 49 50 @Override 51 String flagAsString(int flag) { 52 switch (flag) { 53 case END_STREAM: 54 return "END_STREAM"; 55 case PADDED: 56 return "PADDED"; 57 case PRIORITY: 58 return "PRIORITY"; 59 } 60 return super.flagAsString(flag); 61 } 62 63 public void setPadLength(int padLength) { 64 this.padLength = padLength; 65 flags |= PADDED; 66 } 67 68 public void setPriority(int streamDependency, boolean exclusive, int weight) { 69 this.streamDependency = streamDependency; 70 this.exclusive = exclusive; 71 this.weight = weight; 72 this.flags |= PRIORITY; 73 } 74 75 public int getStreamDependency() { 76 return streamDependency; 77 } 78 79 public int getWeight() { 80 return weight; 81 } 82 83 @Override 84 public boolean endHeaders() { 85 return getFlag(END_HEADERS); 86 } 87 88 public boolean getExclusive() { 89 return exclusive; 90 } 91 92 @Override 93 void readIncomingImpl(ByteBufferConsumer bc) throws IOException { 94 if ((flags & PADDED) != 0) { 95 padLength = bc.getByte(); 96 } 97 if ((flags & PRIORITY) != 0) { 98 int x = bc.getInt(); 99 exclusive = (x & 0x80000000) != 0; 100 streamDependency = x & 0x7fffffff; 101 weight = bc.getByte(); 102 } 103 headerLength = length - padLength; 104 headerBlocks = bc.getBuffers(headerLength); 105 } 106 107 @Override 108 void computeLength() { 109 int len = 0; 110 if ((flags & PADDED) != 0) { 111 len += (1 + padLength); 112 } 113 if ((flags & PRIORITY) != 0) { 114 len += 5; 115 } 116 len += headerLength; 117 this.length = len; 118 } 119 120 @Override 121 void writeOutgoing(ByteBufferGenerator bg) { 122 super.writeOutgoing(bg); 123 ByteBuffer buf = bg.getBuffer(6); 124 if ((flags & PADDED) != 0) { 125 buf.put((byte)padLength); 126 } 127 if ((flags & PRIORITY) != 0) { 128 int x = exclusive ? 1 << 31 + streamDependency : streamDependency; 129 buf.putInt(x); 130 buf.put((byte)weight); 131 } 132 for (int i=0; i<headerBlocks.length; i++) { 133 bg.addByteBuffer(headerBlocks[i]); 134 } 135 if ((flags & PADDED) != 0) { 136 bg.addPadding(padLength); 137 } 138 } 139 }