19
19
import static io .rsocket .frame .FrameLengthFlyweight .FRAME_LENGTH_MASK ;
20
20
21
21
import io .netty .buffer .ByteBufAllocator ;
22
- import io .netty .handler .codec .http .HttpMethod ;
23
22
import io .rsocket .Closeable ;
24
23
import io .rsocket .DuplexConnection ;
25
24
import io .rsocket .fragmentation .FragmentationDuplexConnection ;
26
25
import io .rsocket .transport .ServerTransport ;
27
26
import io .rsocket .transport .netty .WebsocketDuplexConnection ;
28
- import java .util .ArrayList ;
29
- import java .util .HashMap ;
30
- import java .util .List ;
31
- import java .util .Map ;
32
27
import java .util .Objects ;
33
28
import java .util .function .BiFunction ;
34
29
import java .util .function .Consumer ;
35
- import java .util .regex .Matcher ;
36
- import java .util .regex .Pattern ;
37
30
import org .reactivestreams .Publisher ;
38
31
import reactor .core .publisher .Mono ;
39
32
import reactor .netty .Connection ;
40
33
import reactor .netty .http .server .HttpServer ;
41
34
import reactor .netty .http .server .HttpServerRoutes ;
35
+ import reactor .netty .http .server .WebsocketServerSpec ;
42
36
import reactor .netty .http .websocket .WebsocketInbound ;
43
37
import reactor .netty .http .websocket .WebsocketOutbound ;
44
38
48
42
*/
49
43
public final class WebsocketRouteTransport extends BaseWebsocketServerTransport <Closeable > {
50
44
51
- private final UriPathTemplate template ;
45
+ private final String path ;
52
46
53
47
private final Consumer <? super HttpServerRoutes > routesBuilder ;
54
48
@@ -65,7 +59,7 @@ public WebsocketRouteTransport(
65
59
HttpServer server , Consumer <? super HttpServerRoutes > routesBuilder , String path ) {
66
60
this .server = serverConfigurer .apply (Objects .requireNonNull (server , "server must not be null" ));
67
61
this .routesBuilder = Objects .requireNonNull (routesBuilder , "routesBuilder must not be null" );
68
- this .template = new UriPathTemplate ( Objects .requireNonNull (path , "path must not be null" ) );
62
+ this .path = Objects .requireNonNull (path , "path must not be null" );
69
63
}
70
64
71
65
@ Override
@@ -77,10 +71,9 @@ public Mono<Closeable> start(ConnectionAcceptor acceptor, int mtu) {
77
71
routes -> {
78
72
routesBuilder .accept (routes );
79
73
routes .ws (
80
- hsr -> hsr . method (). equals ( HttpMethod . GET ) && template . matches ( hsr . uri ()) ,
74
+ path ,
81
75
newHandler (acceptor , mtu ),
82
- null ,
83
- FRAME_LENGTH_MASK );
76
+ WebsocketServerSpec .builder ().maxFramePayloadLength (FRAME_LENGTH_MASK ).build ());
84
77
})
85
78
.bind ()
86
79
.map (CloseableChannel ::new );
@@ -118,121 +111,4 @@ public static BiFunction<WebsocketInbound, WebsocketOutbound, Publisher<Void>> n
118
111
return acceptor .apply (connection ).then (out .neverComplete ());
119
112
};
120
113
}
121
-
122
- static final class UriPathTemplate {
123
-
124
- private static final Pattern FULL_SPLAT_PATTERN = Pattern .compile ("[\\ *][\\ *]" );
125
- private static final String FULL_SPLAT_REPLACEMENT = ".*" ;
126
-
127
- private static final Pattern NAME_SPLAT_PATTERN = Pattern .compile ("\\ {([^/]+?)\\ }[\\ *][\\ *]" );
128
- private static final String NAME_SPLAT_REPLACEMENT = "(?<%NAME%>.*)" ;
129
-
130
- private static final Pattern NAME_PATTERN = Pattern .compile ("\\ {([^/]+?)\\ }" );
131
- private static final String NAME_REPLACEMENT = "(?<%NAME%>[^\\ /]*)" ;
132
-
133
- private final List <String > pathVariables = new ArrayList <>();
134
- private final HashMap <String , Matcher > matchers = new HashMap <>();
135
- private final HashMap <String , Map <String , String >> vars = new HashMap <>();
136
-
137
- private final Pattern uriPattern ;
138
-
139
- static String filterQueryParams (String uri ) {
140
- int hasQuery = uri .lastIndexOf ("?" );
141
- if (hasQuery != -1 ) {
142
- return uri .substring (0 , hasQuery );
143
- } else {
144
- return uri ;
145
- }
146
- }
147
-
148
- /**
149
- * Creates a new {@code UriPathTemplate} from the given {@code uriPattern}.
150
- *
151
- * @param uriPattern The pattern to be used by the template
152
- */
153
- UriPathTemplate (String uriPattern ) {
154
- String s = "^" + filterQueryParams (uriPattern );
155
-
156
- Matcher m = NAME_SPLAT_PATTERN .matcher (s );
157
- while (m .find ()) {
158
- for (int i = 1 ; i <= m .groupCount (); i ++) {
159
- String name = m .group (i );
160
- pathVariables .add (name );
161
- s = m .replaceFirst (NAME_SPLAT_REPLACEMENT .replaceAll ("%NAME%" , name ));
162
- m .reset (s );
163
- }
164
- }
165
-
166
- m = NAME_PATTERN .matcher (s );
167
- while (m .find ()) {
168
- for (int i = 1 ; i <= m .groupCount (); i ++) {
169
- String name = m .group (i );
170
- pathVariables .add (name );
171
- s = m .replaceFirst (NAME_REPLACEMENT .replaceAll ("%NAME%" , name ));
172
- m .reset (s );
173
- }
174
- }
175
-
176
- m = FULL_SPLAT_PATTERN .matcher (s );
177
- while (m .find ()) {
178
- s = m .replaceAll (FULL_SPLAT_REPLACEMENT );
179
- m .reset (s );
180
- }
181
-
182
- this .uriPattern = Pattern .compile (s + "$" );
183
- }
184
-
185
- /**
186
- * Tests the given {@code uri} against this template, returning {@code true} if the uri matches
187
- * the template, {@code false} otherwise.
188
- *
189
- * @param uri The uri to match
190
- * @return {@code true} if there's a match, {@code false} otherwise
191
- */
192
- public boolean matches (String uri ) {
193
- return matcher (uri ).matches ();
194
- }
195
-
196
- /**
197
- * Matches the template against the given {@code uri} returning a map of path parameters
198
- * extracted from the uri, keyed by the names in the template. If the uri does not match, or
199
- * there are no path parameters, an empty map is returned.
200
- *
201
- * @param uri The uri to match
202
- * @return the path parameters from the uri. Never {@code null}.
203
- */
204
- final Map <String , String > match (String uri ) {
205
- Map <String , String > pathParameters = vars .get (uri );
206
- if (null != pathParameters ) {
207
- return pathParameters ;
208
- }
209
-
210
- pathParameters = new HashMap <>();
211
- Matcher m = matcher (uri );
212
- if (m .matches ()) {
213
- int i = 1 ;
214
- for (String name : pathVariables ) {
215
- String val = m .group (i ++);
216
- pathParameters .put (name , val );
217
- }
218
- }
219
- synchronized (vars ) {
220
- vars .put (uri , pathParameters );
221
- }
222
-
223
- return pathParameters ;
224
- }
225
-
226
- private Matcher matcher (String uri ) {
227
- uri = filterQueryParams (uri );
228
- Matcher m = matchers .get (uri );
229
- if (null == m ) {
230
- m = uriPattern .matcher (uri );
231
- synchronized (matchers ) {
232
- matchers .put (uri , m );
233
- }
234
- }
235
- return m ;
236
- }
237
- }
238
114
}
0 commit comments