Skip to content

Commit f768dac

Browse files
committed
Merge pull request #127 from simon-liubin/update/un-chuncked
流上传前获得流的大小
2 parents 1db7b3b + 01760b6 commit f768dac

File tree

6 files changed

+188
-12
lines changed

6 files changed

+188
-12
lines changed

src/main/java/com/qiniu/api/auth/digest/Mac.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public String signRequest(HttpPost post) throws AuthException {
115115
if (entity != null) {
116116
org.apache.http.Header ct = entity.getContentType();
117117
if (ct != null
118-
&& ct.getValue() == "application/x-www-form-urlencoded") {
118+
&& "application/x-www-form-urlencoded".equals(ct.getValue())) {
119119
ByteArrayOutputStream w = new ByteArrayOutputStream();
120120
try {
121121
entity.writeTo(w);

src/main/java/com/qiniu/api/io/IoApi.java

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.File;
44
import java.io.FileInputStream;
5+
import java.io.FileOutputStream;
56
import java.io.InputStream;
67
import java.io.UnsupportedEncodingException;
78
import java.nio.charset.Charset;
@@ -33,6 +34,7 @@ private static PutRet put(String uptoken, String key, File file,
3334
return new PutRet(new CallRet(Config.ERROR_CODE, new Exception(
3435
"File does not exist or not readable.")));
3536
}
37+
extra = extra == null ? new PutExtra() : extra;
3638
MultipartEntity requestEntity = new MultipartEntity();
3739
try {
3840
requestEntity.addPart("token", new StringBody(uptoken));
@@ -85,11 +87,14 @@ private static void setParam(MultipartEntity requestEntity, Map<String, String>
8587
}
8688
}
8789

88-
private static PutRet putStream(String uptoken, String key, InputStream reader,PutExtra extra, String fileName) {
90+
private static PutRet putStream(String uptoken, String key, InputStream reader,
91+
PutExtra extra, long length) {
92+
extra = extra == null ? new PutExtra() : extra;
8993
MultipartEntity requestEntity = new MultipartEntity();
9094
try {
9195
requestEntity.addPart("token", new StringBody(uptoken));
92-
AbstractContentBody inputBody = buildInputStreamBody(reader, extra, fileName != null ? fileName : "null");
96+
String fileName = key != null ? key : "null";
97+
AbstractContentBody inputBody = buildInputStreamBody(reader, extra, fileName, length);
9398
requestEntity.addPart("file", inputBody);
9499
setKey(requestEntity, key);
95100
setParam(requestEntity, extra.params);
@@ -109,26 +114,97 @@ private static PutRet putStream(String uptoken, String key, InputStream reader,P
109114
return new PutRet(ret);
110115
}
111116

112-
private static InputStreamBody buildInputStreamBody(InputStream reader,PutExtra extra, String fileName){
117+
private static AbstractContentBody buildInputStreamBody(InputStream reader,
118+
PutExtra extra, String fileName, final long length){
113119
if(extra.mimeType != null){
114-
return new InputStreamBody(reader, extra.mimeType, fileName);
120+
return new InputStreamBody(reader, extra.mimeType, fileName){
121+
public long getContentLength() {
122+
return length;
123+
}
124+
};
115125
}else{
116-
return new InputStreamBody(reader, fileName);
126+
return new InputStreamBody(reader, fileName){
127+
public long getContentLength() {
128+
return length;
129+
}
130+
};
117131
}
118132
}
119133

120-
public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra){
121-
return putStream(uptoken,key,reader,extra, null);
134+
135+
private static PutRet putStream0(String uptoken, String key, InputStream reader,
136+
PutExtra extra, long length){
137+
length = length <= 0 ? getLength(reader) : length;
138+
if(length != -1) {
139+
return putStream(uptoken,key,reader,extra, length);
140+
}else{
141+
return toPutFile(uptoken, key, reader, extra);
142+
}
143+
122144
}
123145

124-
public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra, String fileName){
125-
return putStream(uptoken,key,reader,extra, fileName);
146+
private static long getLength(InputStream is){
147+
try {
148+
return is.available();
149+
} catch (Exception e) {
150+
return -1;
151+
}
126152
}
127153

154+
private static PutRet toPutFile(String uptoken, String key,
155+
InputStream reader, PutExtra extra) {
156+
File file = null;
157+
try{
158+
file = copyToTmpFile(reader);
159+
return put(uptoken, key, file, extra);
160+
}finally{
161+
if(file != null){
162+
try{file.delete();}catch(Exception e){}
163+
}
164+
}
165+
}
166+
167+
168+
private static File copyToTmpFile(InputStream from){
169+
FileOutputStream os = null;
170+
try{
171+
File to = File.createTempFile("qiniu_", ".tmp");
172+
os = new FileOutputStream(to);
173+
byte[] b = new byte[64 * 1024];
174+
int l;
175+
while ((l = from.read(b)) != -1) {
176+
os.write(b, 0, l);
177+
}
178+
os.flush();
179+
return to;
180+
}catch(Exception e){
181+
throw new RuntimeException("create tmp file failed.", e);
182+
}finally{
183+
if (os != null){
184+
try{os.close();}catch(Exception e){}
185+
}
186+
if (from != null){
187+
try{from.close();}catch(Exception e){}
188+
}
189+
}
190+
}
191+
192+
193+
/**
194+
* @param uptoken
195+
* @param key
196+
* @param reader
197+
* @param extra
198+
* @param length 部分流 is.available() == 0,此时可指定内容长度
199+
* @return
200+
*/
201+
public static PutRet Put(String uptoken,String key,InputStream reader,PutExtra extra, long length){
202+
return putStream0(uptoken,key,reader,extra, length);
203+
}
128204

129205
public static PutRet Put(String uptoken,String key,InputStream reader,PutExtra extra)
130206
{
131-
return put(uptoken,key,reader,extra);
207+
return Put(uptoken,key,reader,extra, -1);
132208
}
133209

134210

@@ -171,4 +247,5 @@ private static long getCRC32(File file) throws Exception {
171247
}
172248
return crc;
173249
}
250+
174251
}

src/main/java/com/qiniu/api/resumableio/StreamSliceUpload.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public StreamSliceUpload(InputStream is,
3030
@Override
3131
protected boolean hasNext() {
3232
try {
33-
return is != null && is.available() > 0;
33+
// 部分流 is.available() == 0,此时通过设定的内容长度判断,
34+
return is != null && (is.available() > 0 || currentBlockIdx * BLOCK_SIZE < contentLength);
3435
} catch (IOException e) {
3536
return false;
3637
}
@@ -39,6 +40,7 @@ protected boolean hasNext() {
3940
@Override
4041
protected UploadBlock buildNextBlockUpload() throws IOException {
4142
long left = is.available();
43+
left = left > 0 ? left : (contentLength - currentBlockIdx * BLOCK_SIZE);
4244
long start = currentBlockIdx * BLOCK_SIZE;
4345
int len = (int) Math.min(BLOCK_SIZE, left);
4446

src/test/java/com/qiniu/testing/HttpClientTimeOutTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public void testCONNECTION_TIMEOUT() {
3838
Config.SO_TIMEOUT = 20 * 1000;
3939

4040
HttpClient client = Http.getClient();
41+
tearDown();
42+
4143
HttpGet httpget = new HttpGet("http://www.qiniu.com");
4244

4345
s = System.currentTimeMillis();
@@ -62,6 +64,8 @@ public void testSO_TIMEOUT() {
6264
Config.SO_TIMEOUT = 5;
6365

6466
HttpClient client = Http.getClient();
67+
tearDown();
68+
6569
HttpGet httpget = new HttpGet("http://www.qiniu.com");
6670

6771
s = System.currentTimeMillis();

src/test/java/com/qiniu/testing/IOTest.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
import java.util.Map;
66
import java.util.UUID;
77

8+
import org.apache.http.HttpEntity;
9+
import org.apache.http.HttpResponse;
10+
import org.apache.http.client.ClientProtocolException;
11+
import org.apache.http.client.HttpClient;
12+
import org.apache.http.client.methods.HttpGet;
813
import org.json.JSONObject;
914

1015
import junit.framework.TestCase;
@@ -14,6 +19,8 @@
1419
import com.qiniu.api.io.IoApi;
1520
import com.qiniu.api.io.PutExtra;
1621
import com.qiniu.api.io.PutRet;
22+
import com.qiniu.api.net.Http;
23+
import com.qiniu.api.resumableio.ResumeableIoApi;
1724
import com.qiniu.api.rs.PutPolicy;
1825
import com.qiniu.api.rs.RSClient;
1926

@@ -98,6 +105,67 @@ private String getJsonValue(JSONObject jsonObject, String name){
98105
return null;
99106
}
100107
}
108+
109+
public void testNoLengthStream() throws Exception {
110+
PutPolicy p = new PutPolicy(bucketName);
111+
p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
112+
String upToken = p.token(mac);
113+
114+
HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg");
115+
116+
class MyInputStream extends InputStream{
117+
InputStream in;
118+
MyInputStream(InputStream is){
119+
this.in = is;
120+
}
121+
122+
@Override
123+
public int read() throws IOException {
124+
// TODO Auto-generated method stub
125+
return in.read();
126+
}
127+
128+
public int available() throws IOException {
129+
throw new IOException();
130+
}
131+
132+
public void close() throws IOException {
133+
in.close();
134+
}
135+
136+
}
137+
138+
139+
140+
PutRet ret = IoApi.Put(upToken, key, new MyInputStream(en.getContent()), null);
141+
142+
System.out.println(ret);
143+
assertTrue(ret.ok());
144+
System.out.println("is.available() = " + en.getContent().available());
145+
}
146+
147+
public void testSetLengthStream() throws Exception {
148+
PutPolicy p = new PutPolicy(bucketName);
149+
p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
150+
String upToken = p.token(mac);
151+
152+
HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg");
153+
PutExtra extra = new PutExtra();
154+
extra.mimeType = en.getContentType().getValue();
155+
PutRet ret = IoApi.Put(upToken, key, en.getContent(), extra, en.getContentLength());
156+
157+
System.out.println(ret);
158+
assertTrue(ret.ok());
159+
System.out.println("is.available() = " + en.getContent().available());
160+
}
161+
162+
private HttpEntity getHttpEntity(String url) throws ClientProtocolException, IOException{
163+
HttpClient client = Http.getClient();
164+
HttpGet httpget = new HttpGet(url);
165+
HttpResponse res = client.execute(httpget);
166+
return res.getEntity();
167+
}
168+
101169

102170
@Override
103171
public void tearDown() {

src/test/java/com/qiniu/testing/ResumeableioTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
import java.io.IOException;
88
import java.util.UUID;
99

10+
import org.apache.http.HttpEntity;
11+
import org.apache.http.HttpResponse;
12+
import org.apache.http.client.ClientProtocolException;
13+
import org.apache.http.client.HttpClient;
14+
import org.apache.http.client.methods.HttpGet;
1015
import org.json.JSONException;
1116
import org.json.JSONObject;
1217

@@ -17,6 +22,7 @@
1722
import com.qiniu.api.config.Config;
1823
import com.qiniu.api.io.PutRet;
1924
import com.qiniu.api.net.CallRet;
25+
import com.qiniu.api.net.Http;
2026
import com.qiniu.api.resumableio.ResumeableIoApi;
2127
import com.qiniu.api.rs.PutPolicy;
2228
import com.qiniu.api.rs.RSClient;
@@ -108,7 +114,26 @@ private void uploadStream() throws AuthException, JSONException, FileNotFoundExc
108114
assertEquals(mimeType, mt);
109115
}
110116
}
117+
118+
public void testStream() throws Exception {
119+
PutPolicy p = new PutPolicy(bucketName);
120+
p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
121+
String upToken = p.token(mac);
122+
123+
HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg");
124+
PutRet ret = ResumeableIoApi.put(en.getContent(), upToken, currentKey, en.getContentType().getValue(), en.getContentLength());
125+
126+
System.out.println(ret);
127+
assertTrue(ret.ok());
128+
System.out.println("is.available() = " + en.getContent().available());
129+
}
111130

131+
private HttpEntity getHttpEntity(String url) throws ClientProtocolException, IOException{
132+
HttpClient client = Http.getClient();
133+
HttpGet httpget = new HttpGet(url);
134+
HttpResponse res = client.execute(httpget);
135+
return res.getEntity();
136+
}
112137

113138
@Override
114139
public void tearDown() {

0 commit comments

Comments
 (0)