Skip to content

Commit

Permalink
Check if NSURLProtocolClient has private callback before calling it (#…
Browse files Browse the repository at this point in the history
…2765)

* Check if NSURLProtocolClient has private callback before calling it

Fixes #2764

* - Coalesce headers
- Add test for a POST NSURLSessionTask
  • Loading branch information
ms-jihua authored and Raj Seshasankaran committed Jun 9, 2017
1 parent 2d430f1 commit c5fb684
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Frameworks/Foundation/NSURLProtocol.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
#import <NSRaise.h>
#import <LoggingNative.h>

#import <NSURLProtocolInternal.h>
#import <NSURLRequestInternal.h>
#import "NSURLProtocolInternal.h"
#import "NSURLProtocol_file.h"

static const wchar_t* TAG = L"NSURLProtocol";
Expand Down
5 changes: 5 additions & 0 deletions Frameworks/Foundation/NSURLProtocolInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
#pragma once

#import <Foundation/NSURLProtocol.h>
#import <Starboard/SmartTypes.h>

@interface NSURLProtocol ()
+ (id)_URLProtocolClassForRequest:(id)request;
@end

// Internal extension for NSURLProtocolClient, to support POST
@protocol _NSURLProtocolClientInternal <NSURLProtocolClient>
Expand Down
3 changes: 2 additions & 1 deletion Frameworks/Foundation/NSURLProtocol_WinHTTP.mm
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ - (void)startLoading {
// TODO #2721: If this properly supports streaming bodies instead of flattening the data up front,
// more accurate callbacks can be done
NSInteger contentSize = self.request.HTTPBody ? self.request.HTTPBody.length : _flattenedBodyStream.size();
if (contentSize > 0) {
if (([self.client respondsToSelector:@selector(URLProtocol:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)]) &&
(contentSize > 0)) {
__dispatchClientCallback(self, ^void() {
[self.client URLProtocol:self
didWriteData:contentSize
Expand Down
24 changes: 0 additions & 24 deletions Frameworks/include/NSURLProtocolInternal.h

This file was deleted.

52 changes: 52 additions & 0 deletions tests/functionaltests/Tests/NSURLSession.mm
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,58 @@ - (void)URLSession:(NSURLSession*)session
ASSERT_EQ_MSG(nil, taskError, "FAILED: Connection returned error!");
}

/**
* Test to verify a data task post request can be successfully made and a valid data is received with a completion handler
*/
TEST_METHOD(DataTaskWithPostRequest) {
__block THBooleanCondition* condition = [[THBooleanCondition alloc] init];
__block NSURLResponse* taskResponse;
__block NSData* taskData;
__block NSError* taskError;

NSURLSessionDataTaskTestHelper* dataTaskTestHelper = [[NSURLSessionDataTaskTestHelper alloc] init];
NSURLSession* session = [dataTaskTestHelper createSession];
NSURL* url = [NSURL URLWithString:@"https://httpbin.org/post"];
LOG_INFO("Establishing data task with url %@", url);

NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];

static const std::string alphanumeric = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
request.HTTPBody = [NSData dataWithBytes:reinterpret_cast<const void*>(alphanumeric.data()) length:alphanumeric.size()];
request.HTTPMethod = @"POST";
[request setValue:[NSString stringWithFormat:@"%lu", alphanumeric.size()] forHTTPHeaderField:@"Content-Length"];

NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData* data, NSURLResponse* response, NSError* error) {
taskResponse = response;
taskData = data;
taskError = error;
[condition signal];
}];
[dataTask resume];

// Wait for data.
ASSERT_TRUE([condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:c_testTimeoutInSec]]);
ASSERT_TRUE(taskResponse || taskData || taskError);

// Make sure we received a response.
ASSERT_TRUE_MSG((taskResponse != nil), "FAILED: Response cannot be empty!");
if (![taskResponse isKindOfClass:[NSHTTPURLResponse class]]) {
ASSERT_FALSE_MSG(true, "FAILED: Response should be of kind NSHTTPURLResponse class!");
}
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)taskResponse;
LOG_INFO("Received HTTP response status: %ld", [httpResponse statusCode]);
ASSERT_EQ_MSG(200, [httpResponse statusCode], "FAILED: HTTP status 200 expected!");
LOG_INFO("Received HTTP response headers: %@", [httpResponse allHeaderFields]);

// Make sure we received data.
ASSERT_TRUE_MSG((taskData != nil), "FAILED: We should have received some data!");
LOG_INFO("Received data: %@", [[NSString alloc] initWithData:taskData encoding:NSUTF8StringEncoding]);

// Make sure there was no error.
ASSERT_EQ_MSG(nil, taskError, "FAILED: Task returned error!");
}

//
// NSURLSessionDownloadTask tests
//
Expand Down

0 comments on commit c5fb684

Please sign in to comment.