1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.core5.http2.impl.nio;
28
29 import java.io.IOException;
30
31 import org.apache.hc.core5.annotation.Internal;
32 import org.apache.hc.core5.http.config.CharCodingConfig;
33 import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
34 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
35 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
36 import org.apache.hc.core5.http.nio.HandlerFactory;
37 import org.apache.hc.core5.http.nio.command.ExecutableCommand;
38 import org.apache.hc.core5.http.nio.command.RequestExecutionCommand;
39 import org.apache.hc.core5.http.protocol.HttpCoreContext;
40 import org.apache.hc.core5.http.protocol.HttpProcessor;
41 import org.apache.hc.core5.http2.H2ConnectionException;
42 import org.apache.hc.core5.http2.H2Error;
43 import org.apache.hc.core5.http2.config.H2Config;
44 import org.apache.hc.core5.http2.frame.DefaultFrameFactory;
45 import org.apache.hc.core5.http2.frame.FrameFactory;
46 import org.apache.hc.core5.http2.frame.StreamIdGenerator;
47 import org.apache.hc.core5.reactor.ProtocolIOSession;
48
49
50
51
52
53
54
55
56 @Internal
57 public class ClientH2StreamMultiplexer extends AbstractH2StreamMultiplexer {
58
59 private final HandlerFactory<AsyncPushConsumer> pushHandlerFactory;
60
61 public ClientH2StreamMultiplexer(
62 final ProtocolIOSession ioSession,
63 final FrameFactory frameFactory,
64 final HttpProcessor httpProcessor,
65 final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
66 final H2Config h2Config,
67 final CharCodingConfig charCodingConfig,
68 final H2StreamListener streamListener) {
69 super(ioSession, frameFactory, StreamIdGenerator.ODD, httpProcessor, charCodingConfig, h2Config, streamListener);
70 this.pushHandlerFactory = pushHandlerFactory;
71 }
72
73 public ClientH2StreamMultiplexer(
74 final ProtocolIOSession ioSession,
75 final HttpProcessor httpProcessor,
76 final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
77 final H2Config h2Config,
78 final CharCodingConfig charCodingConfig) {
79 this(ioSession, DefaultFrameFactory.INSTANCE, httpProcessor, pushHandlerFactory, h2Config, charCodingConfig, null);
80 }
81
82 public ClientH2StreamMultiplexer(
83 final ProtocolIOSession ioSession,
84 final HttpProcessor httpProcessor,
85 final H2Config h2Config,
86 final CharCodingConfig charCodingConfig) {
87 this(ioSession, httpProcessor, null, h2Config, charCodingConfig);
88 }
89
90 @Override
91 void acceptHeaderFrame() throws H2ConnectionException {
92 throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, "Illegal HEADERS frame");
93 }
94
95 @Override
96 void acceptPushFrame() throws H2ConnectionException {
97 }
98
99 @Override
100 void acceptPushRequest() throws H2ConnectionException {
101 throw new H2ConnectionException(H2Error.INTERNAL_ERROR, "Illegal attempt to push a response");
102 }
103
104 @Override
105 H2StreamHandler createLocallyInitiatedStream(
106 final ExecutableCommand command,
107 final H2StreamChannel channel,
108 final HttpProcessor httpProcessor,
109 final BasicHttpConnectionMetrics connMetrics) throws IOException {
110 if (command instanceof RequestExecutionCommand) {
111 final RequestExecutionCommand executionCommand = (RequestExecutionCommand) command;
112 final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
113 final HandlerFactory<AsyncPushConsumer> pushHandlerFactory = executionCommand.getPushHandlerFactory();
114 final HttpCoreContext context = HttpCoreContext.adapt(executionCommand.getContext());
115 context.setAttribute(HttpCoreContext.SSL_SESSION, getSSLSession());
116 context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, getEndpointDetails());
117 return new ClientH2StreamHandler(channel, httpProcessor, connMetrics, exchangeHandler,
118 pushHandlerFactory != null ? pushHandlerFactory : this.pushHandlerFactory,
119 context);
120 }
121 throw new H2ConnectionException(H2Error.INTERNAL_ERROR, "Unexpected executable command");
122 }
123
124 @Override
125 H2StreamHandler createRemotelyInitiatedStream(
126 final H2StreamChannel channel,
127 final HttpProcessor httpProcessor,
128 final BasicHttpConnectionMetrics connMetrics,
129 final HandlerFactory<AsyncPushConsumer> pushHandlerFactory) throws IOException {
130 final HttpCoreContext context = HttpCoreContext.create();
131 context.setAttribute(HttpCoreContext.SSL_SESSION, getSSLSession());
132 context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, getEndpointDetails());
133 return new ClientPushH2StreamHandler(channel, httpProcessor, connMetrics,
134 pushHandlerFactory != null ? pushHandlerFactory : this.pushHandlerFactory,
135 context);
136 }
137
138 @Override
139 public String toString() {
140 final StringBuilder buf = new StringBuilder();
141 buf.append("[");
142 appendState(buf);
143 buf.append("]");
144 return buf.toString();
145 }
146
147 }
148