3535import java .util .Deque ;
3636import java .util .Iterator ;
3737import java .util .List ;
38- import java .util .Map ;
3938import java .util .Queue ;
40- import java .util .concurrent .ConcurrentHashMap ;
4139import java .util .concurrent .ConcurrentLinkedDeque ;
4240import java .util .concurrent .ConcurrentLinkedQueue ;
4341import java .util .concurrent .atomic .AtomicInteger ;
@@ -141,7 +139,6 @@ enum SettingsHandshake { READY, TRANSMITTED, ACKED }
141139 private EndpointDetails endpointDetails ;
142140 private boolean goAwayReceived ;
143141
144- private final Map <Integer , PriorityValue > priorities = new ConcurrentHashMap <>();
145142 private volatile boolean peerNoRfc7540Priorities ;
146143
147144 AbstractH2StreamMultiplexer (
@@ -1011,6 +1008,9 @@ private void consumeFrame(final RawFrame frame) throws HttpException, IOExceptio
10111008 throw new H2ConnectionException (H2Error .FRAME_SIZE_ERROR , "Invalid PRIORITY_UPDATE payload" );
10121009 }
10131010 final int prioritizedId = payload .getInt () & 0x7fffffff ;
1011+ if (prioritizedId == 0 ) {
1012+ throw new H2ConnectionException (H2Error .PROTOCOL_ERROR , "PRIORITY_UPDATE stream id is 0" );
1013+ }
10141014 final int len = payload .remaining ();
10151015 final String field ;
10161016 if (len > 0 ) {
@@ -1020,9 +1020,11 @@ private void consumeFrame(final RawFrame frame) throws HttpException, IOExceptio
10201020 } else {
10211021 field = "" ;
10221022 }
1023- final PriorityValue pv = PriorityParamsParser .parse (field ).toValueWithDefaults ();
1024- priorities .put (prioritizedId , pv );
1025- requestSessionOutput ();
1023+ final PriorityValue pv = parsePriorityValue (field );
1024+ final H2Stream prioritizedStream = streams .lookupSeen (prioritizedId );
1025+ if (prioritizedStream != null ) {
1026+ prioritizedStream .setPriorityValue (pv );
1027+ }
10261028 }
10271029 break ;
10281030 }
@@ -1097,7 +1099,7 @@ private void consumeHeaderFrame(final RawFrame frame, final H2Stream stream) thr
10971099 if (streamListener != null ) {
10981100 streamListener .onHeaderInput (this , streamId , headers );
10991101 }
1100- recordPriorityFromHeaders (streamId , headers );
1102+ recordPriorityFromHeaders (stream , headers );
11011103 stream .consumeHeader (headers , frame .isFlagSet (FrameFlag .END_STREAM ));
11021104 } else {
11031105 continuation .copyPayload (payload );
@@ -1116,7 +1118,7 @@ private void consumeContinuationFrame(final RawFrame frame, final H2Stream strea
11161118 if (streamListener != null ) {
11171119 streamListener .onHeaderInput (this , streamId , headers );
11181120 }
1119- recordPriorityFromHeaders (streamId , headers );
1121+ recordPriorityFromHeaders (stream , headers );
11201122 if (continuation .type == FrameType .PUSH_PROMISE .getValue ()) {
11211123 stream .consumePromise (headers );
11221124 } else {
@@ -1368,19 +1370,27 @@ H2Stream createStream(final H2StreamChannel channel, final H2StreamHandler strea
13681370 return streams .createActive (channel , streamHandler );
13691371 }
13701372
1371- private void recordPriorityFromHeaders (final int streamId , final List <? extends Header > headers ) {
1373+ private void recordPriorityFromHeaders (final H2Stream stream , final List <? extends Header > headers ) {
13721374 if (headers == null || headers .isEmpty ()) {
13731375 return ;
13741376 }
13751377 for (final Header h : headers ) {
13761378 if (HttpHeaders .PRIORITY .equalsIgnoreCase (h .getName ())) {
1377- final PriorityValue pv = PriorityParamsParser . parse ( h . getValue ()). toValueWithDefaults ( );
1378- priorities . put ( streamId , pv );
1379+ final PriorityValue pv = parsePriorityValue ( h );
1380+ stream . setPriorityValue ( pv );
13791381 break ;
13801382 }
13811383 }
13821384 }
13831385
1386+ private PriorityValue parsePriorityValue (final Header header ) {
1387+ return PriorityParamsParser .parse (header ).toValueWithDefaults ();
1388+ }
1389+
1390+ private PriorityValue parsePriorityValue (final String field ) {
1391+ return PriorityParamsParser .parse (field ).toValueWithDefaults ();
1392+ }
1393+
13841394 class H2StreamChannelImpl implements H2StreamChannel {
13851395
13861396 private final int id ;
@@ -1428,18 +1438,21 @@ public void submit(final List<Header> headers, final boolean endStream) throws I
14281438 return ;
14291439 }
14301440 ensureNotClosed ();
1431- if (peerNoRfc7540Priorities && streams . isSameSide ( id ) ) {
1441+ if (peerNoRfc7540Priorities ) {
14321442 for (final Header h : headers ) {
14331443 if (HttpHeaders .PRIORITY .equalsIgnoreCase (h .getName ())) {
14341444 final byte [] ascii = h .getValue () != null
14351445 ? h .getValue ().getBytes (StandardCharsets .US_ASCII )
14361446 : new byte [0 ];
1447+
1448+ final int sid = id & 0x7fffffff ;
14371449 final ByteArrayBuffer b = new ByteArrayBuffer (4 + ascii .length );
1438- b .append ((byte ) (id >> 24 ));
1439- b .append ((byte ) (id >> 16 ));
1440- b .append ((byte ) (id >> 8 ));
1441- b .append ((byte ) id );
1450+ b .append ((byte ) (sid >> 24 ));
1451+ b .append ((byte ) (sid >> 16 ));
1452+ b .append ((byte ) (sid >> 8 ));
1453+ b .append ((byte ) sid );
14421454 b .append (ascii , 0 , ascii .length );
1455+
14431456 final ByteBuffer pl = ByteBuffer .wrap (b .array (), 0 , b .length ());
14441457 final RawFrame priUpd = new RawFrame (FrameType .PRIORITY_UPDATE .getValue (), 0 , 0 , pl );
14451458 commitFrameInternal (priUpd );
0 commit comments