Skip to content

Commit

Permalink
Hash calculation fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
SpertsyanKM committed Sep 15, 2023
1 parent 3a6f34f commit a788687
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
10 changes: 5 additions & 5 deletions Sources/Qonversion/Qonversion/Services/QNAPIClient/QNAPIClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ - (NSURLRequest *)handlePurchase:(QONStoreKit2PurchaseModel *)purchaseInfo
NSURLRequest *request = [self.requestBuilder makePurchaseRequestWith:resultData];

[self.rateLimiter processWithRateLimit:QONRateLimitedRequestTypePurchase
hash:[purchaseInfo hash] + [receipt hash]
params:body
completion:^(NSError *rateLimitError) {
if (rateLimitError != nil) {
completion(nil, rateLimitError);
Expand Down Expand Up @@ -170,7 +170,7 @@ - (NSURLRequest *)purchaseRequestWith:(NSDictionary *)body
NSURLRequest *request = [self.requestBuilder makePurchaseRequestWith:resultData];

[self.rateLimiter processWithRateLimit:QONRateLimitedRequestTypePurchase
hash:[body hash]
params:body
completion:^(NSError *rateLimitError) {
if (rateLimitError != nil) {
completion(nil, rateLimitError);
Expand All @@ -193,7 +193,7 @@ - (void)checkTrialIntroEligibilityParamsForProducts:(NSArray<QONProduct *> *)pro
- (void)checkTrialIntroEligibilityParamsForData:(NSDictionary *)data
completion:(QNAPIClientDictCompletionHandler)completion {
[self.rateLimiter processWithRateLimit:QONRateLimitedRequestTypeEligibilityForProducts
hash:[data hash]
params:data
completion:^(NSError *rateLimitError) {
if (rateLimitError != nil) {
completion(nil, rateLimitError);
Expand Down Expand Up @@ -266,7 +266,7 @@ - (void)createIdentityForUserID:(NSString *)userID anonUserID:(NSString *)anonUs
NSDictionary *parameters = @{@"anon_id": anonUserID, @"identity_id": userID};

[self.rateLimiter processWithRateLimit:QONRateLimitedRequestTypeIdentify
hash:[parameters hash]
params:parameters
completion:^(NSError *rateLimitError) {
if (rateLimitError != nil) {
completion(nil, rateLimitError);
Expand Down Expand Up @@ -297,7 +297,7 @@ - (void)attributionRequest:(QONAttributionProvider)provider
NSDictionary *body = [self.requestSerializer attributionDataWithDict:data fromProvider:provider];

[self.rateLimiter processWithRateLimit:QONRateLimitedRequestTypeAttribution
hash:[body hash]
params:body
completion:^(NSError *rateLimitError) {
if (rateLimitError != nil) {
completion(nil, rateLimitError);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ typedef NS_ENUM(NSInteger, QONRateLimitedRequestType) {

- (instancetype _Nullable)initWithMaxRequestsPerSecond:(int)maxRequestsPerSecond;

- (void)processWithRateLimit:(QONRateLimitedRequestType)requestType
params:(NSDictionary *)params
completion:(QONRateLimiterCompletionHandler _Nonnull)completion;

- (void)processWithRateLimit:(QONRateLimitedRequestType)requestType
hash:(NSUInteger)hash
completion:(QONRateLimiterCompletionHandler _Nonnull)completion;
Expand Down
51 changes: 51 additions & 0 deletions Sources/Qonversion/Qonversion/Utils/QNRateLimiter/QONRateLimiter.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ - (instancetype)initWithMaxRequestsPerSecond:(int)maxRequestsPerSecond {
return self;
}

- (void)processWithRateLimit:(QONRateLimitedRequestType)requestType
params:(NSDictionary *)params
completion:(QONRateLimiterCompletionHandler _Nonnull)completion {
NSUInteger hash = [self calculateHashForDictionary:params];
[self processWithRateLimit:requestType hash:hash completion:completion];
}

- (void)processWithRateLimit:(QONRateLimitedRequestType)requestType
hash:(NSUInteger)hash
completion:(QONRateLimiterCompletionHandler)completion {
Expand Down Expand Up @@ -76,4 +83,48 @@ - (BOOL)isRateLimitExceeded:(QONRateLimitedRequestType)requestType hash:(NSUInte
return matchCount >= self.maxRequestsPerSecond;
}

// MARK: Private

- (NSUInteger)calculateHashForDictionary:(NSDictionary *)dict {
NSUInteger prime = 31;
NSUInteger result = 1;

for (NSString *key in dict) {
id value = dict[key];

NSUInteger keyHash = [key hash];
NSUInteger valueHash = [self calculateHashForValue:value];

result = prime * result + keyHash;
result = prime * result + valueHash;
}

return result;
}

- (NSUInteger)calculateHashForArray:(NSArray *)array {
NSUInteger prime = 31;
NSUInteger result = 1;

for (id value in array) {
NSUInteger valueHash = [self calculateHashForValue:value];
result = prime * result + valueHash;
}

return result;
}

- (NSUInteger)calculateHashForValue:(id)value {
NSUInteger valueHash = 0;
if ([value isKindOfClass:[NSDictionary class]]) {
valueHash = [self calculateHashForDictionary:value];
} else if ([value isKindOfClass:[NSArray class]]) {
valueHash = [self calculateHashForArray:value];
} else {
valueHash = [value hash];
}

return valueHash;
}

@end

0 comments on commit a788687

Please sign in to comment.