18
18
19
19
package io .undertow .client .http ;
20
20
21
+ import static org .xnio .Bits .allAreClear ;
22
+ import static org .xnio .Bits .allAreSet ;
23
+ import static org .xnio .Bits .anyAreSet ;
24
+
25
+ import java .io .IOException ;
26
+ import java .nio .ByteBuffer ;
27
+ import java .nio .channels .ClosedChannelException ;
28
+ import java .nio .channels .FileChannel ;
29
+ import java .util .Iterator ;
30
+ import java .util .concurrent .atomic .AtomicIntegerFieldUpdater ;
31
+
21
32
import io .undertow .client .ClientRequest ;
33
+ import io .undertow .connector .ByteBufferPool ;
34
+ import io .undertow .connector .PooledByteBuffer ;
22
35
import io .undertow .server .TruncatedResponseException ;
23
36
import io .undertow .util .HeaderMap ;
24
37
import io .undertow .util .HttpString ;
25
38
import org .jboss .logging .Logger ;
26
- import io .undertow .connector .ByteBufferPool ;
27
- import io .undertow .connector .PooledByteBuffer ;
28
39
import org .xnio .XnioWorker ;
29
40
import org .xnio .channels .StreamSourceChannel ;
30
41
import org .xnio .conduits .AbstractStreamSinkConduit ;
31
42
import org .xnio .conduits .Conduits ;
32
43
import org .xnio .conduits .StreamSinkConduit ;
33
44
34
- import java .io .IOException ;
35
- import java .nio .ByteBuffer ;
36
- import java .nio .channels .ClosedChannelException ;
37
- import java .nio .channels .FileChannel ;
38
- import java .util .Iterator ;
39
- import java .util .concurrent .atomic .AtomicIntegerFieldUpdater ;
40
-
41
- import static org .xnio .Bits .allAreClear ;
42
- import static org .xnio .Bits .allAreSet ;
43
- import static org .xnio .Bits .anyAreSet ;
44
-
45
45
/**
46
46
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
47
47
* @author Emanuel Muckenhuber
@@ -101,7 +101,7 @@ final class HttpRequestConduit extends AbstractStreamSinkConduit<StreamSinkCondu
101
101
* @return
102
102
* @throws java.io.IOException
103
103
*/
104
- private int processWrite (int state , final ByteBuffer userData ) throws IOException {
104
+ private int processWrite (int state , final Object userData ) throws IOException {
105
105
return doProcessWrite (state , userData );
106
106
}
107
107
@@ -117,7 +117,7 @@ private int processWrite(int state, final ByteBuffer userData) throws IOExceptio
117
117
* @return
118
118
* @throws java.io.IOException
119
119
*/
120
- private int doProcessWrite (int state , final ByteBuffer userData ) throws IOException {
120
+ private int doProcessWrite (int state , final Object userData ) throws IOException {
121
121
if (state == STATE_START ) {
122
122
pooledBuffer = pool .allocate ();
123
123
}
@@ -331,23 +331,22 @@ private int doProcessWrite(int state, final ByteBuffer userData) throws IOExcept
331
331
this .string = null ;
332
332
buffer .flip ();
333
333
//for performance reasons we use a gather write if there is user data
334
- if (userData == null ) {
334
+ if (userData == null ) {
335
335
do {
336
336
res = next .write (buffer );
337
337
if (res == 0 ) {
338
338
log .trace ("Continuation" );
339
339
return STATE_BUF_FLUSH ;
340
340
}
341
341
} while (buffer .hasRemaining ());
342
+ } else if (userData instanceof ByteBuffer []) {
343
+ if (!writeBufferArray (buildDataArray ((ByteBuffer []) userData , buffer ))) {
344
+ return STATE_BUF_FLUSH ;
345
+ }
342
346
} else {
343
- ByteBuffer [] b = {buffer , userData };
344
- do {
345
- long r = next .write (b , 0 , b .length );
346
- if (r == 0 && buffer .hasRemaining ()) {
347
- log .trace ("Continuation" );
348
- return STATE_BUF_FLUSH ;
349
- }
350
- } while (buffer .hasRemaining ());
347
+ if (!writeBufferArray (new ByteBuffer [] {buffer , (ByteBuffer ) userData })) {
348
+ return STATE_BUF_FLUSH ;
349
+ }
351
350
}
352
351
pooledBuffer .close ();
353
352
pooledBuffer = null ;
@@ -439,14 +438,16 @@ private int doProcessWrite(int state, final ByteBuffer userData) throws IOExcept
439
438
}
440
439
} while (buffer .hasRemaining ());
441
440
} else {
442
- ByteBuffer [] b = {buffer , userData };
443
- do {
444
- long r = next .write (b , 0 , b .length );
445
- if (r == 0 && buffer .hasRemaining ()) {
446
- log .trace ("Continuation" );
441
+
442
+ if (userData instanceof ByteBuffer []) {
443
+ if (!writeBufferArray (buildDataArray ((ByteBuffer []) userData , buffer ))) {
447
444
return STATE_BUF_FLUSH ;
448
445
}
449
- } while (buffer .hasRemaining ());
446
+ } else {
447
+ if (!writeBufferArray (new ByteBuffer [] {buffer , (ByteBuffer ) userData })) {
448
+ return STATE_BUF_FLUSH ;
449
+ }
450
+ }
450
451
}
451
452
// fall thru
452
453
}
@@ -565,7 +566,7 @@ public long write(final ByteBuffer[] srcs, final int offset, final int length) t
565
566
try {
566
567
if (state != 0 ) {
567
568
//todo: use gathering write here
568
- state = processWrite (state , null );
569
+ state = processWrite (state , srcs );
569
570
if (state != 0 ) {
570
571
return 0 ;
571
572
}
@@ -749,4 +750,35 @@ public void freeBuffers() {
749
750
this .state = state & ~MASK_STATE | FLAG_SHUTDOWN ;
750
751
}
751
752
}
753
+
754
+ private static ByteBuffer [] buildDataArray (ByteBuffer [] userData , ByteBuffer buffer ) {
755
+ int userDataLen = userData .length ;
756
+ ByteBuffer [] data = new ByteBuffer [userDataLen + 1 ];
757
+ data [0 ] = buffer ;
758
+ System .arraycopy (userData , 0 , data , 1 , userDataLen );
759
+ return data ;
760
+ }
761
+
762
+ private boolean writeBufferArray (ByteBuffer [] data ) throws IOException {
763
+ long totalWritten = 0 ;
764
+ long totalRemaining = 0 ;
765
+
766
+ for (ByteBuffer buffer : data ) {
767
+ totalRemaining += buffer .remaining ();
768
+ }
769
+
770
+ do {
771
+ long r = next .write (data , 0 , data .length );
772
+ totalWritten += r ;
773
+ if ((r == 0 ) && (totalWritten < totalRemaining )) {
774
+ log .trace ("Continuation" );
775
+ return false ;
776
+ }
777
+ } while (totalWritten < totalRemaining );
778
+
779
+ // ? The original code allowed for an early return under certain conditions. If that condition is met, retunr
780
+ // false from the loop. Otherwise, return true here to indicate a successful completion. Can't return bytes
781
+ // written since it might get confused for STATE_BUF_FLUSH
782
+ return true ;
783
+ }
752
784
}
0 commit comments