1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.spdy.client.http;
20
21 import java.nio.channels.AsynchronousCloseException;
22 import java.util.Set;
23 import java.util.concurrent.atomic.AtomicBoolean;
24
25 import org.eclipse.jetty.client.HttpChannel;
26 import org.eclipse.jetty.client.HttpConnection;
27 import org.eclipse.jetty.client.HttpDestination;
28 import org.eclipse.jetty.client.HttpExchange;
29 import org.eclipse.jetty.spdy.api.GoAwayInfo;
30 import org.eclipse.jetty.spdy.api.Session;
31 import org.eclipse.jetty.util.Callback;
32 import org.eclipse.jetty.util.ConcurrentHashSet;
33
34 public class HttpConnectionOverSPDY extends HttpConnection
35 {
36 private final Set<HttpChannel> channels = new ConcurrentHashSet<>();
37 private final AtomicBoolean closed = new AtomicBoolean();
38 private final Session session;
39
40 public HttpConnectionOverSPDY(HttpDestination destination, Session session)
41 {
42 super(destination);
43 this.session = session;
44 }
45
46 @Override
47 protected void send(HttpExchange exchange)
48 {
49 normalizeRequest(exchange.getRequest());
50
51 HttpChannel channel = new HttpChannelOverSPDY(getHttpDestination(), this, session);
52 channels.add(channel);
53 if (channel.associate(exchange))
54 channel.send();
55 else
56 channel.release();
57 }
58
59 protected void release(HttpChannel channel)
60 {
61 channels.remove(channel);
62 }
63
64 @Override
65 public void close()
66 {
67 if (closed.compareAndSet(false, true))
68 {
69
70
71 getHttpDestination().close(this);
72 session.goAway(new GoAwayInfo(), Callback.Adapter.INSTANCE);
73 abort(new AsynchronousCloseException());
74 }
75 }
76
77 @Override
78 public boolean isClosed()
79 {
80 return closed.get();
81 }
82
83 private void abort(Throwable failure)
84 {
85 for (HttpChannel channel : channels)
86 {
87 HttpExchange exchange = channel.getHttpExchange();
88 if (exchange != null)
89 exchange.getRequest().abort(failure);
90 }
91 channels.clear();
92 }
93 }