aliyun/aliyun-oss-java-sdk

OSS uploadPart 验证CRC逻辑不能到达

vicasong opened this issue · 2 comments

关键位置:

repeatableInputStream = newRepeatableInputStream(uploadPartRequest.buildPartialStream());

此处会从requestcontent获取clientCrc,但实际上在uploadPart方法组织request的时候已经将inputStream进行至少一次的包装.

此时包装至少为BoundedInputStream (它不扩展自CheckedInputStream)且不会被包装为CheckedInputStreamCheckedInputStream的扩展

public BoundedInputStream buildPartialStream() {
return new BoundedInputStream(inputStream, (int) partSize);
}

public static InputStream newRepeatableInputStream(final BoundedInputStream original) throws IOException {
InputStream repeatable = null;
if (!original.markSupported()) {
if (original.getWrappedInputStream() instanceof FileInputStream) {
repeatable = new RepeatableBoundedFileInputStream(original);
} else {
repeatable = new BufferedInputStream(original, OSSConstants.DEFAULT_STREAM_BUFFER_SIZE);
}
} else {
repeatable = original;
}
return repeatable;
}

而在结果获取后setCRC需要判定request的content是CheckedInputStream才会获取clientCrc,进而才能在后面一步进行Crc比对。

public static <ResultType extends GenericResult> void setCRC(ResultType result, ResponseMessage response) {
InputStream inputStream = response.getRequest().getContent();
if (inputStream instanceof CheckedInputStream) {
CheckedInputStream checkedInputStream = (CheckedInputStream) inputStream;
result.setClientCRC(checkedInputStream.getChecksum().getValue());
}
String strSrvCrc = response.getHeaders().get(OSSHeaders.OSS_HASH_CRC64_ECMA);
if (strSrvCrc != null) {
BigInteger bi = new BigInteger(strSrvCrc);
result.setServerCRC(bi.longValue());
}
}

这部分的逻辑是有问题的,不知道官方还在维护么,=_=

这里应该是有包装:

public void handle(RequestMessage request) throws OSSException, ClientException {
InputStream originalInputStream = request.getContent();
if (originalInputStream == null) {
return;
}
CRC64 crc = new CRC64();
CheckedInputStream checkedInputstream = new CheckedInputStream(originalInputStream, crc);
request.setContent(checkedInputstream);
}

这里应该是有包装:

public void handle(RequestMessage request) throws OSSException, ClientException {
InputStream originalInputStream = request.getContent();
if (originalInputStream == null) {
return;
}
CRC64 crc = new CRC64();
CheckedInputStream checkedInputstream = new CheckedInputStream(originalInputStream, crc);
request.setContent(checkedInputstream);
}

看到了