23
23
24
24
package com .loopj .android .http ;
25
25
26
- import java .io .ByteArrayInputStream ;
26
+ import org .apache .http .Header ;
27
+ import org .apache .http .HttpEntity ;
28
+ import org .apache .http .message .BasicHeader ;
29
+
27
30
import java .io .ByteArrayOutputStream ;
28
31
import java .io .File ;
29
32
import java .io .FileInputStream ;
30
33
import java .io .FileNotFoundException ;
31
- import java .io .InputStream ;
32
34
import java .io .IOException ;
35
+ import java .io .InputStream ;
33
36
import java .io .OutputStream ;
34
37
import java .util .Random ;
35
38
36
- import org .apache .http .Header ;
37
- import org .apache .http .HttpEntity ;
38
- import org .apache .http .message .BasicHeader ;
39
-
40
39
class SimpleMultipartEntity implements HttpEntity {
40
+
41
+ private static final byte [] CR_LF = ("\r \n " ).getBytes ();
42
+ private static final byte [] TRANSFER_ENCODING_BINARY = "Content-Transfer-Encoding: binary\r \n "
43
+ .getBytes ();
44
+
41
45
private final static char [] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .toCharArray ();
42
46
43
- private String boundary = null ;
47
+ private String boundary ;
48
+ private byte [] boundaryLine ;
49
+ private byte [] boundaryEnd ;
44
50
45
- ByteArrayOutputStream out = new ByteArrayOutputStream ();
46
- boolean isSetLast = false ;
47
- boolean isSetFirst = false ;
51
+ // The buffer we use for building the message excluding the last boundary
52
+ private ByteArrayOutputStream out = new ByteArrayOutputStream ();
48
53
49
54
public SimpleMultipartEntity () {
50
55
final StringBuffer buf = new StringBuffer ();
51
56
final Random rand = new Random ();
52
57
for (int i = 0 ; i < 30 ; i ++) {
53
58
buf .append (MULTIPART_CHARS [rand .nextInt (MULTIPART_CHARS .length )]);
54
59
}
55
- this .boundary = buf .toString ();
56
-
57
- }
58
-
59
- public void writeFirstBoundaryIfNeeds (){
60
- if (!isSetFirst ){
61
- try {
62
- out .write (("--" + boundary + "\r \n " ).getBytes ());
63
- } catch (final IOException e ) {
64
- e .printStackTrace ();
65
- }
66
- }
67
-
68
- isSetFirst = true ;
69
- }
70
-
71
- public void writeLastBoundaryIfNeeds () {
72
- if (isSetLast ){
73
- return ;
74
- }
75
-
76
- try {
77
- out .write (("\r \n --" + boundary + "--\r \n " ).getBytes ());
78
- } catch (final IOException e ) {
79
- e .printStackTrace ();
80
- }
81
-
82
- isSetLast = true ;
60
+ boundary = buf .toString ();
61
+ boundaryLine = ("--" + boundary + "\r \n " ).getBytes ();
62
+ boundaryEnd = ("\r \n --" + boundary + "--\r \n " ).getBytes ();
83
63
}
84
64
85
65
public void addPart (final String key , final String value ) {
86
- writeFirstBoundaryIfNeeds ();
87
66
try {
88
- out .write (("Content-Disposition: form-data; name=\" " +key +"\" \r \n \r \n " ).getBytes ());
67
+ out .write (boundaryLine );
68
+ out .write (createContentDisposition (key ));
69
+ out .write (CR_LF );
89
70
out .write (value .getBytes ());
90
- out .write (("\r \n --" + boundary + "\r \n " ).getBytes ());
91
71
} catch (final IOException e ) {
92
- e . printStackTrace ();
72
+ // Can't happen on ByteArrayOutputStream
93
73
}
94
74
}
95
75
@@ -98,44 +78,63 @@ public void addPart(final String key, final String fileName, final InputStream f
98
78
}
99
79
100
80
public void addPart (final String key , final String fileName , final InputStream fin , String type , final boolean isLast ){
101
- writeFirstBoundaryIfNeeds ();
102
81
try {
103
- type = "Content-Type: " +type +"\r \n " ;
104
- out .write (("Content-Disposition: form-data; name=\" " + key +"\" ; filename=\" " + fileName + "\" \r \n " ).getBytes ());
105
- out .write (type .getBytes ());
106
- out .write ("Content-Transfer-Encoding: binary\r \n \r \n " .getBytes ());
82
+ out .write (boundaryLine );
83
+
84
+ // Headers
85
+ out .write (createContentDisposition (key , fileName ));
86
+ out .write (createContentType (type ));
87
+ out .write (TRANSFER_ENCODING_BINARY );
88
+ out .write (CR_LF );
107
89
108
90
final byte [] tmp = new byte [4096 ];
109
91
int l = 0 ;
110
92
while ((l = fin .read (tmp )) != -1 ) {
111
93
out .write (tmp , 0 , l );
112
94
}
113
- if (!isLast )
114
- out .write (("\r \n --" + boundary + "\r \n " ).getBytes ());
115
- out .flush ();
95
+ out .write (CR_LF );
116
96
} catch (final IOException e ) {
117
- e . printStackTrace ();
97
+ // Can't happen on ByteArrayOutputStream
118
98
} finally {
119
99
try {
120
100
fin .close ();
121
101
} catch (final IOException e ) {
122
- e . printStackTrace ();
102
+ // Ignore
123
103
}
124
104
}
125
105
}
126
106
127
- public void addPart (final String key , final File value , final boolean isLast ) {
128
- try {
129
- addPart (key , value .getName (), new FileInputStream (value ), isLast );
130
- } catch (final FileNotFoundException e ) {
131
- e .printStackTrace ();
132
- }
107
+ public void addPart (final String key , final File value , final boolean isLast )
108
+ throws FileNotFoundException {
109
+ addPart (key , value .getName (), new FileInputStream (value ), isLast );
110
+ }
111
+
112
+ private byte [] createContentType (String type ) {
113
+ String result = "Content-Type: " + type + "\r \n " ;
114
+ return result .getBytes ();
115
+ }
116
+
117
+ private byte [] createContentDisposition (final String key ) {
118
+ StringBuilder builder = new StringBuilder ();
119
+ builder .append ("Content-Disposition: form-data; name=\" " );
120
+ builder .append (key );
121
+ builder .append ("\" \r \n " );
122
+ return builder .toString ().getBytes ();
123
+ }
124
+
125
+ private byte [] createContentDisposition (final String key , final String fileName ) {
126
+ StringBuilder builder = new StringBuilder ();
127
+ builder .append ("Content-Disposition: form-data; name=\" " );
128
+ builder .append (key );
129
+ builder .append ("\" ; filename=\" " );
130
+ builder .append (fileName );
131
+ builder .append ("\" \r \n " );
132
+ return builder .toString ().getBytes ();
133
133
}
134
134
135
135
@ Override
136
136
public long getContentLength () {
137
- writeLastBoundaryIfNeeds ();
138
- return out .toByteArray ().length ;
137
+ return out .size () + boundaryEnd .length ;
139
138
}
140
139
141
140
@ Override
@@ -160,7 +159,8 @@ public boolean isStreaming() {
160
159
161
160
@ Override
162
161
public void writeTo (final OutputStream outstream ) throws IOException {
163
- outstream .write (out .toByteArray ());
162
+ out .writeTo (outstream );
163
+ outstream .write (boundaryEnd );
164
164
}
165
165
166
166
@ Override
@@ -178,8 +178,8 @@ public void consumeContent() throws IOException,
178
178
}
179
179
180
180
@ Override
181
- public InputStream getContent () throws IOException ,
182
- UnsupportedOperationException {
183
- return new ByteArrayInputStream ( out . toByteArray () );
181
+ public InputStream getContent () throws IOException , UnsupportedOperationException {
182
+ throw new UnsupportedOperationException (
183
+ "getContent() not supported. Use writeTo() instead." );
184
184
}
185
185
}
0 commit comments