diff --git a/CHANGELOG.md b/CHANGELOG.md index 4632fae01..b1b00d4a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## CHANGE LOG +### v6.1.5 + +2014-07-04 [#128](https://github.com/qiniu/java-sdk/pull/128) + +- [#127] 普通上传前计算文件大小 + + ### v6.1.5 2014-06-10 [#121](https://github.com/qiniu/java-sdk/pull/121) @@ -9,7 +16,7 @@ - [#117] 整理未连接的error code - [#116] 增加pipeline - [#112] 增加一个 put 方法 -- + ### v6.1.4 diff --git a/pom.xml b/pom.xml index 1345254c4..09f3ab65e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,30 +1,36 @@ - + + 4.0.0 com.qiniu sdk - 6.0.3 + 6.1.6 jar java-sdk - http://www.qiniutek.com/ - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - utf-8 - - + http://www.qiniu.com/ + Qiniu Resource (Cloud) Storage SDK demo for Java + + + The MIT License + http://opensource.org/licenses/MIT + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + utf-8 + + + - - - + UTF-8 diff --git a/src/main/java/com/qiniu/api/auth/digest/Mac.java b/src/main/java/com/qiniu/api/auth/digest/Mac.java index 246614b73..decd809ca 100644 --- a/src/main/java/com/qiniu/api/auth/digest/Mac.java +++ b/src/main/java/com/qiniu/api/auth/digest/Mac.java @@ -115,7 +115,7 @@ public String signRequest(HttpPost post) throws AuthException { if (entity != null) { org.apache.http.Header ct = entity.getContentType(); if (ct != null - && ct.getValue() == "application/x-www-form-urlencoded") { + && "application/x-www-form-urlencoded".equals(ct.getValue())) { ByteArrayOutputStream w = new ByteArrayOutputStream(); try { entity.writeTo(w); diff --git a/src/main/java/com/qiniu/api/io/IoApi.java b/src/main/java/com/qiniu/api/io/IoApi.java index 86990d82c..31273450d 100644 --- a/src/main/java/com/qiniu/api/io/IoApi.java +++ b/src/main/java/com/qiniu/api/io/IoApi.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; @@ -33,6 +34,7 @@ private static PutRet put(String uptoken, String key, File file, return new PutRet(new CallRet(Config.ERROR_CODE, new Exception( "File does not exist or not readable."))); } + extra = extra == null ? new PutExtra() : extra; MultipartEntity requestEntity = new MultipartEntity(); try { requestEntity.addPart("token", new StringBody(uptoken)); @@ -85,11 +87,14 @@ private static void setParam(MultipartEntity requestEntity, Map } } - private static PutRet putStream(String uptoken, String key, InputStream reader,PutExtra extra, String fileName) { + private static PutRet putStream(String uptoken, String key, InputStream reader, + PutExtra extra, long length) { + extra = extra == null ? new PutExtra() : extra; MultipartEntity requestEntity = new MultipartEntity(); try { requestEntity.addPart("token", new StringBody(uptoken)); - AbstractContentBody inputBody = buildInputStreamBody(reader, extra, fileName != null ? fileName : "null"); + String fileName = key != null ? key : "null"; + AbstractContentBody inputBody = buildInputStreamBody(reader, extra, fileName, length); requestEntity.addPart("file", inputBody); setKey(requestEntity, key); setParam(requestEntity, extra.params); @@ -109,26 +114,97 @@ private static PutRet putStream(String uptoken, String key, InputStream reader,P return new PutRet(ret); } - private static InputStreamBody buildInputStreamBody(InputStream reader,PutExtra extra, String fileName){ + private static AbstractContentBody buildInputStreamBody(InputStream reader, + PutExtra extra, String fileName, final long length){ if(extra.mimeType != null){ - return new InputStreamBody(reader, extra.mimeType, fileName); + return new InputStreamBody(reader, extra.mimeType, fileName){ + public long getContentLength() { + return length; + } + }; }else{ - return new InputStreamBody(reader, fileName); + return new InputStreamBody(reader, fileName){ + public long getContentLength() { + return length; + } + }; } } - public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra){ - return putStream(uptoken,key,reader,extra, null); + + private static PutRet putStream0(String uptoken, String key, InputStream reader, + PutExtra extra, long length){ + length = length <= 0 ? getLength(reader) : length; + if(length != -1) { + return putStream(uptoken,key,reader,extra, length); + }else{ + return toPutFile(uptoken, key, reader, extra); + } + } - public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra, String fileName){ - return putStream(uptoken,key,reader,extra, fileName); + private static long getLength(InputStream is){ + try { + return is.available(); + } catch (Exception e) { + return -1; + } } + private static PutRet toPutFile(String uptoken, String key, + InputStream reader, PutExtra extra) { + File file = null; + try{ + file = copyToTmpFile(reader); + return put(uptoken, key, file, extra); + }finally{ + if(file != null){ + try{file.delete();}catch(Exception e){} + } + } + } + + + private static File copyToTmpFile(InputStream from){ + FileOutputStream os = null; + try{ + File to = File.createTempFile("qiniu_", ".tmp"); + os = new FileOutputStream(to); + byte[] b = new byte[64 * 1024]; + int l; + while ((l = from.read(b)) != -1) { + os.write(b, 0, l); + } + os.flush(); + return to; + }catch(Exception e){ + throw new RuntimeException("create tmp file failed.", e); + }finally{ + if (os != null){ + try{os.close();}catch(Exception e){} + } + if (from != null){ + try{from.close();}catch(Exception e){} + } + } + } + + + /** + * @param uptoken + * @param key + * @param reader + * @param extra + * @param length 部分流 is.available() == 0,此时可指定内容长度 + * @return + */ + public static PutRet Put(String uptoken,String key,InputStream reader,PutExtra extra, long length){ + return putStream0(uptoken,key,reader,extra, length); + } public static PutRet Put(String uptoken,String key,InputStream reader,PutExtra extra) { - return put(uptoken,key,reader,extra); + return Put(uptoken,key,reader,extra, -1); } @@ -171,4 +247,5 @@ private static long getCRC32(File file) throws Exception { } return crc; } + } diff --git a/src/main/java/com/qiniu/api/net/EncodeUtils.java b/src/main/java/com/qiniu/api/net/EncodeUtils.java index 9612e9f70..e8e4aaa20 100644 --- a/src/main/java/com/qiniu/api/net/EncodeUtils.java +++ b/src/main/java/com/qiniu/api/net/EncodeUtils.java @@ -16,30 +16,14 @@ /** * URLEncoding is the alternate base64 encoding defined in RFC 4648. It is * typically used in URLs and file names. - * + * */ public class EncodeUtils { public static byte[] urlsafeEncodeBytes(byte[] src) { - if (src.length % 3 == 0) { - return encodeBase64Ex(src); - } - - byte[] b = encodeBase64Ex(src); - if (b.length % 4 == 0) { - return b; - } - - int pad = 4 - b.length % 4; - byte[] b2 = new byte[b.length + pad]; - System.arraycopy(b, 0, b2, 0, b.length); - b2[b.length] = '='; - if (pad > 1) { - b2[b.length + 1] = '='; - } - return b2; + return encodeBase64Ex(src); } - + public static byte[] urlsafeBase64Decode(String encoded){ byte[] rawbs = toByte(encoded); for(int i=0;i 0; + // 部分流 is.available() == 0,此时通过设定的内容长度判断, + return is != null && (is.available() > 0 || currentBlockIdx * BLOCK_SIZE < contentLength); } catch (IOException e) { return false; } @@ -39,6 +40,7 @@ protected boolean hasNext() { @Override protected UploadBlock buildNextBlockUpload() throws IOException { long left = is.available(); + left = left > 0 ? left : (contentLength - currentBlockIdx * BLOCK_SIZE); long start = currentBlockIdx * BLOCK_SIZE; int len = (int) Math.min(BLOCK_SIZE, left); diff --git a/src/test/java/com/qiniu/testing/HttpClientTimeOutTest.java b/src/test/java/com/qiniu/testing/HttpClientTimeOutTest.java index 753f979ee..c6cd84670 100644 --- a/src/test/java/com/qiniu/testing/HttpClientTimeOutTest.java +++ b/src/test/java/com/qiniu/testing/HttpClientTimeOutTest.java @@ -38,6 +38,8 @@ public void testCONNECTION_TIMEOUT() { Config.SO_TIMEOUT = 20 * 1000; HttpClient client = Http.getClient(); + tearDown(); + HttpGet httpget = new HttpGet("http://www.qiniu.com"); s = System.currentTimeMillis(); @@ -62,6 +64,8 @@ public void testSO_TIMEOUT() { Config.SO_TIMEOUT = 5; HttpClient client = Http.getClient(); + tearDown(); + HttpGet httpget = new HttpGet("http://www.qiniu.com"); s = System.currentTimeMillis(); diff --git a/src/test/java/com/qiniu/testing/IOTest.java b/src/test/java/com/qiniu/testing/IOTest.java index 84fd78180..74101216b 100644 --- a/src/test/java/com/qiniu/testing/IOTest.java +++ b/src/test/java/com/qiniu/testing/IOTest.java @@ -5,6 +5,11 @@ import java.util.Map; import java.util.UUID; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; import org.json.JSONObject; import junit.framework.TestCase; @@ -14,6 +19,8 @@ import com.qiniu.api.io.IoApi; import com.qiniu.api.io.PutExtra; import com.qiniu.api.io.PutRet; +import com.qiniu.api.net.Http; +import com.qiniu.api.resumableio.ResumeableIoApi; import com.qiniu.api.rs.PutPolicy; import com.qiniu.api.rs.RSClient; @@ -98,6 +105,67 @@ private String getJsonValue(JSONObject jsonObject, String name){ return null; } } + + public void testNoLengthStream() throws Exception { + PutPolicy p = new PutPolicy(bucketName); + p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}"; + String upToken = p.token(mac); + + HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg"); + + class MyInputStream extends InputStream{ + InputStream in; + MyInputStream(InputStream is){ + this.in = is; + } + + @Override + public int read() throws IOException { + // TODO Auto-generated method stub + return in.read(); + } + + public int available() throws IOException { + throw new IOException(); + } + + public void close() throws IOException { + in.close(); + } + + } + + + + PutRet ret = IoApi.Put(upToken, key, new MyInputStream(en.getContent()), null); + + System.out.println(ret); + assertTrue(ret.ok()); + System.out.println("is.available() = " + en.getContent().available()); + } + + public void testSetLengthStream() throws Exception { + PutPolicy p = new PutPolicy(bucketName); + p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}"; + String upToken = p.token(mac); + + HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg"); + PutExtra extra = new PutExtra(); + extra.mimeType = en.getContentType().getValue(); + PutRet ret = IoApi.Put(upToken, key, en.getContent(), extra, en.getContentLength()); + + System.out.println(ret); + assertTrue(ret.ok()); + System.out.println("is.available() = " + en.getContent().available()); + } + + private HttpEntity getHttpEntity(String url) throws ClientProtocolException, IOException{ + HttpClient client = Http.getClient(); + HttpGet httpget = new HttpGet(url); + HttpResponse res = client.execute(httpget); + return res.getEntity(); + } + @Override public void tearDown() { diff --git a/src/test/java/com/qiniu/testing/ResumeableioTest.java b/src/test/java/com/qiniu/testing/ResumeableioTest.java index 79c0889a8..f9b90324a 100644 --- a/src/test/java/com/qiniu/testing/ResumeableioTest.java +++ b/src/test/java/com/qiniu/testing/ResumeableioTest.java @@ -7,6 +7,11 @@ import java.io.IOException; import java.util.UUID; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; import org.json.JSONException; import org.json.JSONObject; @@ -17,6 +22,7 @@ import com.qiniu.api.config.Config; import com.qiniu.api.io.PutRet; import com.qiniu.api.net.CallRet; +import com.qiniu.api.net.Http; import com.qiniu.api.resumableio.ResumeableIoApi; import com.qiniu.api.rs.PutPolicy; import com.qiniu.api.rs.RSClient; @@ -108,7 +114,26 @@ private void uploadStream() throws AuthException, JSONException, FileNotFoundExc assertEquals(mimeType, mt); } } + + public void testStream() throws Exception { + PutPolicy p = new PutPolicy(bucketName); + p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}"; + String upToken = p.token(mac); + + HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg"); + PutRet ret = ResumeableIoApi.put(en.getContent(), upToken, currentKey, en.getContentType().getValue(), en.getContentLength()); + + System.out.println(ret); + assertTrue(ret.ok()); + System.out.println("is.available() = " + en.getContent().available()); + } + private HttpEntity getHttpEntity(String url) throws ClientProtocolException, IOException{ + HttpClient client = Http.getClient(); + HttpGet httpget = new HttpGet(url); + HttpResponse res = client.execute(httpget); + return res.getEntity(); + } @Override public void tearDown() {