1
1
/*
2
- * Copyright 2002-2015 the original author or authors.
2
+ * Copyright 2002-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
18
18
19
19
import java .io .ByteArrayOutputStream ;
20
20
import java .io .IOException ;
21
- import java .lang .reflect .Method ;
22
21
import java .net .URI ;
23
22
import java .nio .ByteBuffer ;
24
23
import java .util .List ;
41
40
import io .undertow .util .StringReadChannelListener ;
42
41
import org .xnio .ChannelListener ;
43
42
import org .xnio .ChannelListeners ;
44
- import org .xnio .IoFuture ;
45
43
import org .xnio .IoUtils ;
46
44
import org .xnio .OptionMap ;
47
45
import org .xnio .Options ;
48
- import org .xnio .Pool ;
49
46
import org .xnio .Xnio ;
50
47
import org .xnio .XnioWorker ;
51
48
import org .xnio .channels .StreamSinkChannel ;
55
52
import org .springframework .http .HttpStatus ;
56
53
import org .springframework .http .ResponseEntity ;
57
54
import org .springframework .util .Assert ;
58
- import org .springframework .util .ClassUtils ;
59
- import org .springframework .util .ReflectionUtils ;
60
55
import org .springframework .util .concurrent .SettableListenableFuture ;
61
56
import org .springframework .web .client .HttpServerErrorException ;
62
57
import org .springframework .web .socket .CloseStatus ;
69
64
70
65
/**
71
66
* An XHR transport based on Undertow's {@link io.undertow.client.UndertowClient}.
72
- * Compatible with Undertow 1.0 to 1.3 , as of Spring Framework 4.2.2 .
67
+ * Requires Undertow 1.3 or higher , as of Spring Framework 5.0 .
73
68
*
74
69
* <p>When used for testing purposes (e.g. load testing) or for specific use cases
75
70
* (like HTTPS configuration), a custom OptionMap should be provided:
@@ -94,17 +89,14 @@ public class UndertowXhrTransport extends AbstractXhrTransport {
94
89
95
90
private static final AttachmentKey <String > RESPONSE_BODY = AttachmentKey .create (String .class );
96
91
97
- private static final boolean undertow13Present = ClassUtils .isPresent (
98
- "io.undertow.connector.ByteBufferPool" , UndertowXhrTransport .class .getClassLoader ());
99
-
100
92
101
93
private final OptionMap optionMap ;
102
94
103
95
private final UndertowClient httpClient ;
104
96
105
97
private final XnioWorker worker ;
106
98
107
- private final UndertowBufferSupport undertowBufferSupport ;
99
+ private final ByteBufferPool bufferPool ;
108
100
109
101
110
102
public UndertowXhrTransport () throws IOException {
@@ -116,8 +108,7 @@ public UndertowXhrTransport(OptionMap optionMap) throws IOException {
116
108
this .optionMap = optionMap ;
117
109
this .httpClient = UndertowClient .getInstance ();
118
110
this .worker = Xnio .getInstance ().createWorker (optionMap );
119
- this .undertowBufferSupport =
120
- (undertow13Present ? new Undertow13BufferSupport () : new UndertowXnioBufferSupport ());
111
+ this .bufferPool = new DefaultByteBufferPool (false , 1024 , -1 , 2 );
121
112
}
122
113
123
114
@@ -172,7 +163,7 @@ public void failed(IOException ex) {
172
163
}
173
164
};
174
165
175
- this .undertowBufferSupport . httpClientConnect ( this . httpClient , clientCallback , url , worker , this .optionMap );
166
+ this .httpClient . connect ( clientCallback , url , this . worker , this . bufferPool , this .optionMap );
176
167
}
177
168
178
169
private static void addHttpHeaders (ClientRequest request , HttpHeaders headers ) {
@@ -276,8 +267,8 @@ protected ResponseEntity<String> executeRequest(URI url, HttpString method, Http
276
267
List <ClientResponse > responses = new CopyOnWriteArrayList <ClientResponse >();
277
268
278
269
try {
279
- ClientConnection connection = this . undertowBufferSupport
280
- . httpClientConnect ( this .httpClient , url , this .worker , this .optionMap ).get ();
270
+ ClientConnection connection =
271
+ this .httpClient . connect ( url , this .worker , this . bufferPool , this .optionMap ).get ();
281
272
try {
282
273
ClientRequest request = new ClientRequest ().setMethod (method ).setPath (url .getPath ());
283
274
request .getRequestHeaders ().add (HttpString .tryFromString (HttpHeaders .HOST ), url .getHost ());
@@ -317,7 +308,6 @@ private ClientCallback<ClientExchange> createRequestCallback(final String body,
317
308
public void completed (ClientExchange result ) {
318
309
result .setResponseListener (new ClientCallback <ClientExchange >() {
319
310
@ Override
320
- @ SuppressWarnings ("deprecation" )
321
311
public void completed (final ClientExchange result ) {
322
312
responses .add (result .getResponse ());
323
313
new StringReadChannelListener (result .getConnection ().getBufferPool ()) {
@@ -326,14 +316,12 @@ protected void stringDone(String string) {
326
316
result .getResponse ().putAttachment (RESPONSE_BODY , string );
327
317
latch .countDown ();
328
318
}
329
-
330
319
@ Override
331
320
protected void error (IOException ex ) {
332
321
onFailure (latch , ex );
333
322
}
334
323
}.setup (result .getResponseChannel ());
335
324
}
336
-
337
325
@ Override
338
326
public void failed (IOException ex ) {
339
327
onFailure (latch , ex );
@@ -412,11 +400,11 @@ public void handleEvent(StreamSourceChannel channel) {
412
400
throw new SockJsException ("Session closed." , this .session .getId (), null );
413
401
}
414
402
415
- Object pooled = undertowBufferSupport . allocatePooledResource ();
403
+ PooledByteBuffer pooled = bufferPool . allocate ();
416
404
try {
417
405
int r ;
418
406
do {
419
- ByteBuffer buffer = undertowBufferSupport . getByteBuffer ( pooled );
407
+ ByteBuffer buffer = pooled . getBuffer ( );
420
408
buffer .clear ();
421
409
r = channel .read (buffer );
422
410
buffer .flip ();
@@ -444,7 +432,7 @@ else if (r == -1) {
444
432
onFailure (exc );
445
433
}
446
434
finally {
447
- undertowBufferSupport . closePooledResource ( pooled );
435
+ pooled . close ( );
448
436
}
449
437
}
450
438
@@ -486,118 +474,4 @@ public void onFailure(Throwable failure) {
486
474
}
487
475
}
488
476
489
-
490
- private interface UndertowBufferSupport {
491
-
492
- Object allocatePooledResource ();
493
-
494
- ByteBuffer getByteBuffer (Object pooled );
495
-
496
- void closePooledResource (Object pooled );
497
-
498
- void httpClientConnect (UndertowClient httpClient , final ClientCallback <ClientConnection > listener ,
499
- final URI uri , final XnioWorker worker , OptionMap options );
500
-
501
- IoFuture <ClientConnection > httpClientConnect (UndertowClient httpClient , final URI uri ,
502
- final XnioWorker worker , OptionMap options );
503
- }
504
-
505
-
506
- private class UndertowXnioBufferSupport implements UndertowBufferSupport {
507
-
508
- private final org .xnio .Pool <ByteBuffer > xnioBufferPool ;
509
-
510
- private final Method httpClientConnectCallbackMethod ;
511
-
512
- private final Method httpClientConnectMethod ;
513
-
514
- public UndertowXnioBufferSupport () {
515
- this .xnioBufferPool = new org .xnio .ByteBufferSlicePool (1048 , 1048 );
516
- this .httpClientConnectCallbackMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
517
- ClientCallback .class , URI .class , XnioWorker .class , Pool .class , OptionMap .class );
518
- this .httpClientConnectMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
519
- URI .class , XnioWorker .class , Pool .class , OptionMap .class );
520
- }
521
-
522
- @ Override
523
- public Object allocatePooledResource () {
524
- return this .xnioBufferPool .allocate ();
525
- }
526
-
527
- @ Override
528
- @ SuppressWarnings ("unchecked" )
529
- public ByteBuffer getByteBuffer (Object pooled ) {
530
- return ((org .xnio .Pooled <ByteBuffer >) pooled ).getResource ();
531
- }
532
-
533
- @ Override
534
- @ SuppressWarnings ("unchecked" )
535
- public void closePooledResource (Object pooled ) {
536
- ((org .xnio .Pooled <ByteBuffer >) pooled ).close ();
537
- }
538
-
539
- @ Override
540
- public void httpClientConnect (UndertowClient httpClient , ClientCallback <ClientConnection > listener , URI uri ,
541
- XnioWorker worker , OptionMap options ) {
542
- ReflectionUtils .invokeMethod (httpClientConnectCallbackMethod , httpClient , listener , uri , worker ,
543
- this .xnioBufferPool , options );
544
- }
545
-
546
- @ Override
547
- @ SuppressWarnings ("unchecked" )
548
- public IoFuture <ClientConnection > httpClientConnect (UndertowClient httpClient , URI uri ,
549
- XnioWorker worker , OptionMap options ) {
550
- return (IoFuture <ClientConnection >) ReflectionUtils .invokeMethod (httpClientConnectMethod , httpClient , uri ,
551
- worker , this .xnioBufferPool , options );
552
- }
553
- }
554
-
555
-
556
- private class Undertow13BufferSupport implements UndertowBufferSupport {
557
-
558
- private final ByteBufferPool undertowBufferPool ;
559
-
560
- private final Method httpClientConnectCallbackMethod ;
561
-
562
- private final Method httpClientConnectMethod ;
563
-
564
- public Undertow13BufferSupport () {
565
- this .undertowBufferPool = new DefaultByteBufferPool (false , 1024 , -1 , 2 );
566
- this .httpClientConnectCallbackMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
567
- ClientCallback .class , URI .class , XnioWorker .class , ByteBufferPool .class , OptionMap .class );
568
- this .httpClientConnectMethod = ReflectionUtils .findMethod (UndertowClient .class , "connect" ,
569
- URI .class , XnioWorker .class , ByteBufferPool .class , OptionMap .class );
570
- }
571
-
572
- @ Override
573
- public Object allocatePooledResource () {
574
- return this .undertowBufferPool .allocate ();
575
- }
576
-
577
- @ Override
578
- public ByteBuffer getByteBuffer (Object pooled ) {
579
- return ((PooledByteBuffer ) pooled ).getBuffer ();
580
- }
581
-
582
- @ Override
583
- public void closePooledResource (Object pooled ) {
584
- ((PooledByteBuffer ) pooled ).close ();
585
- }
586
-
587
- @ Override
588
- public void httpClientConnect (UndertowClient httpClient , ClientCallback <ClientConnection > listener , URI uri ,
589
- XnioWorker worker , OptionMap options ) {
590
- ReflectionUtils .invokeMethod (httpClientConnectCallbackMethod , httpClient , listener , uri ,
591
- worker , this .undertowBufferPool , options );
592
- }
593
-
594
- @ Override
595
- @ SuppressWarnings ("unchecked" )
596
- public IoFuture <ClientConnection > httpClientConnect (UndertowClient httpClient , URI uri ,
597
- XnioWorker worker , OptionMap options ) {
598
- return (IoFuture <ClientConnection >) ReflectionUtils .invokeMethod (httpClientConnectMethod , httpClient , uri ,
599
- worker , this .undertowBufferPool , options );
600
- }
601
- }
602
-
603
477
}
0 commit comments