1
1
/*
2
- * Copyright (c) 2013 Sonatype, Inc . All rights reserved.
2
+ * Copyright (c) 2016 AsyncHttpClient Project . All rights reserved.
3
3
*
4
4
* This program is licensed to you under the Apache License Version 2.0,
5
5
* and you may not use this file except in compliance with the Apache License Version 2.0.
6
- * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
+ * You may obtain a copy of the Apache License Version 2.0 at
7
+ * http://www.apache.org/licenses/LICENSE-2.0.
7
8
*
8
9
* Unless required by applicable law or agreed to in writing,
9
10
* software distributed under the Apache License Version 2.0 is distributed on an
12
13
*/
13
14
package com .ning .http .client .multipart ;
14
15
15
- import static java .nio .charset .StandardCharsets .* ;
16
+ import static java .nio .charset .StandardCharsets .UTF_8 ;
16
17
17
18
import org .testng .Assert ;
18
19
import org .testng .annotations .Test ;
19
20
20
- import com .ning .http .client .Body ;
21
21
import com .ning .http .client .FluentCaseInsensitiveStringsMap ;
22
- import com .ning .http .client .multipart .ByteArrayPart ;
23
- import com .ning .http .client .multipart .FilePart ;
24
- import com .ning .http .client .multipart .Part ;
25
- import com .ning .http .client .multipart .StringPart ;
26
22
27
23
import java .io .File ;
28
24
import java .io .IOException ;
29
25
import java .net .URISyntaxException ;
30
26
import java .net .URL ;
31
27
import java .nio .ByteBuffer ;
28
+ import java .nio .channels .WritableByteChannel ;
32
29
import java .util .ArrayList ;
33
30
import java .util .List ;
31
+ import java .util .concurrent .atomic .AtomicLong ;
34
32
35
33
public class MultipartBodyTest {
36
34
37
- @ Test (groups = "fast" )
38
- public void testBasics () {
39
- final List <Part > parts = new ArrayList <>();
35
+ @ Test
36
+ public void transferWithCopy () throws IOException {
37
+ try (MultipartBody multipartBody = buildMultipart ()) {
38
+ long tranferred = transferWithCopy (multipartBody );
39
+ Assert .assertEquals (tranferred , multipartBody .getContentLength ());
40
+ }
41
+ }
40
42
41
- // add a file
42
- final File testFile = getTestfile ();
43
- parts .add (new FilePart ("filePart" , testFile ));
43
+ @ Test
44
+ public void transferZeroCopy () throws IOException {
45
+ try (MultipartBody multipartBody = buildMultipart ()) {
46
+ long tranferred = transferZeroCopy (multipartBody );
47
+ Assert .assertEquals (tranferred , multipartBody .getContentLength ());
48
+ }
49
+ }
44
50
45
- // add a byte array
51
+ private static MultipartBody buildMultipart () {
52
+ List <Part > parts = new ArrayList <>();
53
+ parts .add (new FilePart ("filePart" , getTestfile ()));
46
54
parts .add (new ByteArrayPart ("baPart" , "testMultiPart" .getBytes (UTF_8 ), "application/test" , UTF_8 , "fileName" ));
47
-
48
- // add a string
49
55
parts .add (new StringPart ("stringPart" , "testString" ));
50
-
51
- compareContentLength (parts );
56
+ return MultipartUtils .newMultipartBody (parts , new FluentCaseInsensitiveStringsMap ());
52
57
}
53
58
54
59
private static File getTestfile () {
@@ -64,35 +69,49 @@ private static File getTestfile() {
64
69
return file ;
65
70
}
66
71
67
- private static void compareContentLength (final List <Part > parts ) {
68
- Assert .assertNotNull (parts );
69
- // get expected values
70
- final Body multipartBody = MultipartUtils .newMultipartBody (parts , new FluentCaseInsensitiveStringsMap ());
71
- final long expectedContentLength = multipartBody .getContentLength ();
72
- try {
73
- final ByteBuffer buffer = ByteBuffer .allocate (8192 );
74
- boolean last = false ;
75
- long totalBytes = 0 ;
76
- while (!last ) {
77
- long readBytes = 0 ;
78
- try {
79
- readBytes = multipartBody .read (buffer );
80
- } catch (IOException ie ) {
81
- Assert .fail ("read failure" );
82
- }
83
- if (readBytes >= 0 ) {
84
- totalBytes += readBytes ;
85
- } else {
86
- last = true ;
87
- }
88
- buffer .clear ();
72
+ private static long transferWithCopy (MultipartBody multipartBody ) throws IOException {
73
+
74
+ final ByteBuffer buffer = ByteBuffer .allocate (8192 );
75
+ long totalBytes = 0 ;
76
+ while (true ) {
77
+ long readBytes = multipartBody .read (buffer );
78
+ if (readBytes < 0 ) {
79
+ break ;
80
+ }
81
+ buffer .clear ();
82
+ totalBytes += readBytes ;
83
+ }
84
+ return totalBytes ;
85
+ }
86
+
87
+ private static long transferZeroCopy (MultipartBody multipartBody ) throws IOException {
88
+
89
+ final ByteBuffer buffer = ByteBuffer .allocate (8192 );
90
+ final AtomicLong transferred = new AtomicLong ();
91
+
92
+ WritableByteChannel mockChannel = new WritableByteChannel () {
93
+ @ Override
94
+ public boolean isOpen () {
95
+ return true ;
89
96
}
90
- Assert .assertEquals (totalBytes , expectedContentLength );
91
- } finally {
92
- try {
93
- multipartBody .close ();
94
- } catch (IOException ignore ) {
97
+
98
+ @ Override
99
+ public void close () throws IOException {
100
+ }
101
+
102
+ @ Override
103
+ public int write (ByteBuffer src ) throws IOException {
104
+ int written = src .remaining ();
105
+ transferred .set (transferred .get () + written );
106
+ src .position (src .limit ());
107
+ return written ;
95
108
}
109
+ };
110
+
111
+ while (transferred .get () < multipartBody .getContentLength ()) {
112
+ multipartBody .transferTo (0 , mockChannel );
113
+ buffer .clear ();
96
114
}
115
+ return transferred .get ();
97
116
}
98
117
}
0 commit comments