1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.websocket;
15
16 import java.io.IOException;
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpServletResponse;
19
20 import org.eclipse.jetty.http.HttpException;
21 import org.eclipse.jetty.http.HttpParser;
22 import org.eclipse.jetty.io.ConnectedEndPoint;
23 import org.eclipse.jetty.server.HttpConnection;
24 import org.eclipse.jetty.util.log.Log;
25
26
27
28
29 public class WebSocketFactory
30 {
31 public interface Acceptor
32 {
33 WebSocket doWebSocketConnect(HttpServletRequest request, String protocol);
34
35 String checkOrigin(HttpServletRequest request, String host, String origin);
36 }
37
38 private final Acceptor _acceptor;
39 private WebSocketBuffers _buffers;
40 private int _maxIdleTime = 300000;
41
42 public WebSocketFactory(Acceptor acceptor)
43 {
44 this(acceptor, 64 * 1024);
45 }
46
47 public WebSocketFactory(Acceptor acceptor, int bufferSize)
48 {
49 _buffers = new WebSocketBuffers(bufferSize);
50 _acceptor = acceptor;
51 }
52
53
54
55
56
57
58 public long getMaxIdleTime()
59 {
60 return _maxIdleTime;
61 }
62
63
64
65
66
67
68 public void setMaxIdleTime(int maxIdleTime)
69 {
70 _maxIdleTime = maxIdleTime;
71 }
72
73
74
75
76
77
78 public int getBufferSize()
79 {
80 return _buffers.getBufferSize();
81 }
82
83
84
85
86
87
88 public void setBufferSize(int bufferSize)
89 {
90 if (bufferSize != getBufferSize())
91 _buffers = new WebSocketBuffers(bufferSize);
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 public void upgrade(HttpServletRequest request, HttpServletResponse response, WebSocket websocket, String origin, String protocol)
108 throws IOException
109 {
110 if (!"websocket".equalsIgnoreCase(request.getHeader("Upgrade")))
111 throw new IllegalStateException("!Upgrade:websocket");
112 if (!"HTTP/1.1".equals(request.getProtocol()))
113 throw new IllegalStateException("!HTTP/1.1");
114
115 int draft = request.getIntHeader("Sec-WebSocket-Version");
116 if (draft < 0)
117 draft = request.getIntHeader("Sec-WebSocket-Draft");
118 HttpConnection http = HttpConnection.getCurrentConnection();
119 ConnectedEndPoint endp = (ConnectedEndPoint)http.getEndPoint();
120
121 final WebSocketConnection connection;
122 switch (draft)
123 {
124 case -1:
125 case 0:
126 connection = new WebSocketConnectionD00(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol);
127 break;
128 case 6:
129 connection = new WebSocketConnectionD06(websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol);
130 break;
131 default:
132 Log.warn("Unsupported Websocket version: "+draft);
133 throw new HttpException(400, "Unsupported draft specification: " + draft);
134 }
135
136
137 connection.handshake(request, response, origin, protocol);
138 response.flushBuffer();
139
140
141 connection.fillBuffersFrom(((HttpParser)http.getParser()).getHeaderBuffer());
142 connection.fillBuffersFrom(((HttpParser)http.getParser()).getBodyBuffer());
143
144
145 request.setAttribute("org.eclipse.jetty.io.Connection", connection);
146 }
147
148 public static String[] parseProtocols(String protocol)
149 {
150 if (protocol == null)
151 return new String[]{null};
152 protocol = protocol.trim();
153 if (protocol == null || protocol.length() == 0)
154 return new String[]{null};
155 String[] passed = protocol.split("\\s*,\\s*");
156 String[] protocols = new String[passed.length + 1];
157 System.arraycopy(passed, 0, protocols, 0, passed.length);
158 return protocols;
159 }
160
161 public boolean acceptWebSocket(HttpServletRequest request, HttpServletResponse response)
162 throws IOException
163 {
164 if ("websocket".equalsIgnoreCase(request.getHeader("Upgrade")))
165 {
166 String protocol = request.getHeader("Sec-WebSocket-Protocol");
167 if (protocol == null)
168 protocol = request.getHeader("WebSocket-Protocol");
169
170 WebSocket websocket = null;
171 for (String p : WebSocketFactory.parseProtocols(protocol))
172 {
173 websocket = _acceptor.doWebSocketConnect(request, p);
174 if (websocket != null)
175 {
176 protocol = p;
177 break;
178 }
179 }
180
181 String host = request.getHeader("Host");
182 String origin = request.getHeader("Origin");
183 origin = _acceptor.checkOrigin(request, host, origin);
184
185 if (websocket != null)
186 {
187 upgrade(request, response, websocket, origin, protocol);
188 return true;
189 }
190
191 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
192 }
193
194 return false;
195 }
196 }