1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.http.nio.netty.internal;
17 
18 import io.netty.channel.Channel;
19 import io.netty.handler.codec.http.LastHttpContent;
20 import io.netty.handler.codec.http2.Http2Connection;
21 import io.netty.handler.codec.http2.Http2FrameStream;
22 import io.netty.util.AttributeKey;
23 import java.nio.ByteBuffer;
24 import java.util.concurrent.CompletableFuture;
25 import org.reactivestreams.Subscriber;
26 import software.amazon.awssdk.annotations.SdkInternalApi;
27 import software.amazon.awssdk.http.Protocol;
28 import software.amazon.awssdk.http.nio.netty.internal.http2.Http2MultiplexedChannelPool;
29 import software.amazon.awssdk.http.nio.netty.internal.http2.PingTracker;
30 import software.amazon.awssdk.http.nio.netty.internal.utils.NettyUtils;
31 
32 /**
33  * Keys for attributes attached via {@link io.netty.channel.Channel#attr(AttributeKey)}.
34  */
35 @SdkInternalApi
36 public final class ChannelAttributeKey {
37 
38     /**
39      * Future that when a protocol (http/1.1 or h2) has been selected.
40      */
41     public static final AttributeKey<CompletableFuture<Protocol>> PROTOCOL_FUTURE = NettyUtils.getOrCreateAttributeKey(
42         "aws.http.nio.netty.async.protocolFuture");
43 
44     /**
45      * Reference to {@link Http2MultiplexedChannelPool} which stores information about leased streams for a multiplexed
46      * connection.
47      */
48     public static final AttributeKey<Http2MultiplexedChannelPool> HTTP2_MULTIPLEXED_CHANNEL_POOL =
49         NettyUtils.getOrCreateAttributeKey("aws.http.nio.netty.async.http2MultiplexedChannelPool");
50 
51     public static final AttributeKey<PingTracker> PING_TRACKER =
52         NettyUtils.getOrCreateAttributeKey("aws.http.nio.netty.async.h2.pingTracker");
53 
54     public static final AttributeKey<Http2Connection> HTTP2_CONNECTION =
55         NettyUtils.getOrCreateAttributeKey("aws.http.nio.netty.async.http2Connection");
56 
57     public static final AttributeKey<Integer> HTTP2_INITIAL_WINDOW_SIZE =
58         NettyUtils.getOrCreateAttributeKey("aws.http.nio.netty.async.http2InitialWindowSize");
59 
60     /**
61      * Value of the MAX_CONCURRENT_STREAMS from the server's SETTING frame.
62      */
63     public static final AttributeKey<Long> MAX_CONCURRENT_STREAMS = NettyUtils.getOrCreateAttributeKey(
64         "aws.http.nio.netty.async.maxConcurrentStreams");
65 
66     /**
67      * The {@link Http2FrameStream} associated with this stream channel. This is added to stream channels when they are created,
68      * before they are fully initialized.
69      */
70     public static final AttributeKey<Http2FrameStream> HTTP2_FRAME_STREAM = NettyUtils.getOrCreateAttributeKey(
71         "aws.http.nio.netty.async.http2FrameStream");
72 
73     public static final AttributeKey<ChannelDiagnostics> CHANNEL_DIAGNOSTICS = NettyUtils.getOrCreateAttributeKey(
74         "aws.http.nio.netty.async.channelDiagnostics");
75 
76     /**
77      * {@link AttributeKey} to keep track of whether the streaming is completed and this is set to true when we receive the *
78      * {@link LastHttpContent}.
79      */
80     public static final AttributeKey<Boolean> STREAMING_COMPLETE_KEY = NettyUtils.getOrCreateAttributeKey(
81         "aws.http.nio.netty.async.streamingComplete");
82 
83     /**
84      * {@link AttributeKey} to keep track of whether we should close the connection after this request
85      * has completed.
86      */
87     static final AttributeKey<Boolean> KEEP_ALIVE = NettyUtils.getOrCreateAttributeKey("aws.http.nio.netty.async.keepAlive");
88 
89     /**
90      * Attribute key for {@link RequestContext}.
91      */
92     static final AttributeKey<RequestContext> REQUEST_CONTEXT_KEY = NettyUtils.getOrCreateAttributeKey(
93         "aws.http.nio.netty.async.requestContext");
94 
95     static final AttributeKey<Subscriber<? super ByteBuffer>> SUBSCRIBER_KEY = NettyUtils.getOrCreateAttributeKey(
96         "aws.http.nio.netty.async.subscriber");
97 
98     static final AttributeKey<Boolean> RESPONSE_COMPLETE_KEY = NettyUtils.getOrCreateAttributeKey(
99         "aws.http.nio.netty.async.responseComplete");
100 
101     static final AttributeKey<Integer> RESPONSE_STATUS_CODE = NettyUtils.getOrCreateAttributeKey(
102         "aws.http.nio.netty.async.responseStatusCode");
103 
104     static final AttributeKey<Long> RESPONSE_CONTENT_LENGTH = NettyUtils.getOrCreateAttributeKey(
105         "aws.http.nio.netty.async.responseContentLength");
106 
107     static final AttributeKey<Long> RESPONSE_DATA_READ = NettyUtils.getOrCreateAttributeKey(
108         "aws.http.nio.netty.async.responseDataRead");
109 
110     static final AttributeKey<CompletableFuture<Void>> EXECUTE_FUTURE_KEY = NettyUtils.getOrCreateAttributeKey(
111             "aws.http.nio.netty.async.executeFuture");
112 
113     static final AttributeKey<Long> EXECUTION_ID_KEY = NettyUtils.getOrCreateAttributeKey(
114             "aws.http.nio.netty.async.executionId");
115 
116     /**
117      * Whether the channel is still in use
118      */
119     static final AttributeKey<Boolean> IN_USE = NettyUtils.getOrCreateAttributeKey("aws.http.nio.netty.async.inUse");
120 
121     /**
122      * Whether the channel should be closed once it is released.
123      */
124     static final AttributeKey<Boolean> CLOSE_ON_RELEASE = NettyUtils.getOrCreateAttributeKey(
125             "aws.http.nio.netty.async.closeOnRelease");
126 
ChannelAttributeKey()127     private ChannelAttributeKey() {
128     }
129 
130     /**
131      * Gets the protocol of the channel assuming that it has already been negotiated.
132      *
133      * @param channel Channel to get protocol for.
134      * @return Protocol of channel.
135      */
getProtocolNow(Channel channel)136     static Protocol getProtocolNow(Channel channel) {
137         // For HTTP/2 the protocol future will be on the parent socket channel
138         return (channel.parent() == null ? channel : channel.parent())
139             .attr(ChannelAttributeKey.PROTOCOL_FUTURE).get().join();
140     }
141 }
142