Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions AliyunOSSSDK/OSSClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,21 @@ NS_ASSUME_NONNULL_BEGIN
objectKey:(NSString *)objectKey
error:(const NSError **)error;

/**
Check if the file exists and is consistent with the local file
@bucketName Object's bucket name
@objectKey Object name
@localFileURL Local file path

return YES Object exists
return NO && *error = nil Object does not exist
return NO && *error != nil Error occured.
*/
- (BOOL)doesObjectExistInBucket:(NSString *)bucketName
objectKey:(NSString *)objectKey
localFileURL:(NSURL *)localFileURL
error:(NSError **)error;

@end


Expand Down
45 changes: 45 additions & 0 deletions AliyunOSSSDK/OSSClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import "OSSNetworking.h"
#import "OSSXMLDictionary.h"
#import "OSSIPv6Adapter.h"
#import "OSSInputStreamHelper.h"

#import "OSSNetworkingRequestDelegate.h"
#import "OSSAllRequestNeededMessage.h"
Expand Down Expand Up @@ -2195,6 +2196,50 @@ - (BOOL)doesObjectExistInBucket:(NSString *)bucketName
}
}

- (BOOL)doesObjectExistInBucket:(NSString *)bucketName
objectKey:(NSString *)objectKey
localFileURL:(NSURL *)localFileURL
error:(NSError **)error {
OSSHeadObjectRequest *headRequest = [OSSHeadObjectRequest new];
headRequest.bucketName = bucketName;
headRequest.objectKey = objectKey;

OSSTask *task = [self headObject:headRequest];
[task waitUntilFinished];
if (!task.error) {
OSSHeadObjectResult *headResult = task.result;
OSSInputStreamHelper *inputStreamHelper = [[OSSInputStreamHelper alloc] initWithURL:localFileURL];
[inputStreamHelper syncReadBuffers];

uint64_t clientCrc64 = inputStreamHelper.crc64;
uint64_t remoteCrc64 = 0;
NSString *remoteCRC64ecma = headResult.remoteCRC64ecma;
NSScanner *scanner = [NSScanner scannerWithString:remoteCRC64ecma];
if (clientCrc64 != 0 && [scanner scanUnsignedLongLong:&remoteCrc64]) {
if (remoteCrc64 == clientCrc64) {
return YES;
} else {
OSSLogDebug(@"CRC verification failed: %llu %llu", clientCrc64, remoteCrc64);
return NO;
}
} else {
NSString *message = [NSString stringWithFormat:@"Unable to obtain CRC value. client crc: %llu, remote crc: %@", inputStreamHelper.crc64, remoteCRC64ecma];
OSSLogError(@"%@", message);
*error = [NSError errorWithDomain:OSSClientErrorDomain
code:OSSClientErrorCodeInvalidCRC
userInfo:@{OSSErrorMessageTOKEN: message}];
return NO;
}
} else if (([task.error.domain isEqualToString:OSSServerErrorDomain] &&
task.error.code == -404) ||
[task.error.userInfo[@"Code"] isEqualToString:@"NoSuchKey"]) {
return NO;
} else {
*error = task.error;
return NO;
}
}

@end

@implementation OSSClient (ImageService)
Expand Down
69 changes: 69 additions & 0 deletions AliyunOSSiOSTests/OSSObjectTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,75 @@ - (void)testAPI_doesObjectExistWithError
XCTAssertNotNil(error);
}

- (void)testAPI_doesObjectExistAndEqualLocalFile {
NSString *filePath = [[NSString oss_documentDirectory] stringByAppendingPathComponent:_fileNames[3]];
NSURL * fileURL = [NSURL fileURLWithPath:filePath];

[OSSTestUtils putTestDataWithKey:_fileNames[3]
withClient:_client
withBucket:_privateBucketName];
NSError * error = nil;
BOOL isExist = [_client doesObjectExistInBucket:_privateBucketName
objectKey:_fileNames[3]
localFileURL:fileURL
error:&error];
XCTAssertEqual(isExist, YES);
XCTAssertNil(error);
}

- (void)testAPI_doesObjectEqualLocalFileWithNoExistObject {
NSString *filePath = [[NSString oss_documentDirectory] stringByAppendingPathComponent:_fileNames[3]];
NSURL * fileURL = [NSURL fileURLWithPath:filePath];
NSError * error = nil;
BOOL isExist = [_client doesObjectExistInBucket:_privateBucketName
objectKey:@"wrong-key"
localFileURL:fileURL
error:&error];
XCTAssertEqual(isExist, NO);
XCTAssertNil(error);
}

- (void)testAPI_doesObjectExistAndEqualLocalFileWithError {
NSString *filePath = [[NSString oss_documentDirectory] stringByAppendingPathComponent:_fileNames[3]];
NSURL * fileURL = [NSURL fileURLWithPath:filePath];
NSError * error = nil;
// invalid credentialProvider
id<OSSCredentialProvider> c = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"ak"
secretKeyId:@"sk"
securityToken:@"token"];
OSSClient * tClient = [[OSSClient alloc] initWithEndpoint:OSS_ENDPOINT credentialProvider:c];
BOOL isExist = [tClient doesObjectExistInBucket:_privateBucketName
objectKey:_fileNames[3]
localFileURL:fileURL
error:&error];
XCTAssertEqual(isExist, NO);
XCTAssertNotNil(error);
XCTAssertTrue(error.code == -403);

// different files
filePath = [[NSString oss_documentDirectory] stringByAppendingPathComponent:_fileNames[2]];
fileURL = [NSURL fileURLWithPath:filePath];
[OSSTestUtils putTestDataWithKey:_fileNames[3]
withClient:_client
withBucket:_privateBucketName];
error = nil;
isExist = [_client doesObjectExistInBucket:_privateBucketName
objectKey:_fileNames[3]
localFileURL:fileURL
error:&error];
XCTAssertEqual(isExist, NO);
XCTAssertNil(error);

// error file path
error = nil;
isExist = [_client doesObjectExistInBucket:_privateBucketName
objectKey:_fileNames[3]
localFileURL:[NSURL URLWithString:@"/bin/a"]
error:&error];
XCTAssertEqual(isExist, NO);
XCTAssertNotNil(error);
}

- (void)testAPI_copyAndDeleteObject
{
[OSSTestUtils putTestDataWithKey:_fileNames[3] withClient:_client withBucket:_privateBucketName];
Expand Down