Use clang-formatter to format source code
This commit is contained in:
@ -141,7 +141,7 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
|
||||
@implementation GCDWebServerHandler
|
||||
|
||||
@synthesize matchBlock=_matchBlock, asyncProcessBlock=_asyncProcessBlock;
|
||||
@synthesize matchBlock = _matchBlock, asyncProcessBlock = _asyncProcessBlock;
|
||||
|
||||
- (id)initWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock {
|
||||
if ((self = [super init])) {
|
||||
@ -162,7 +162,7 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
NSInteger _activeConnections; // Accessed through _syncQueue only
|
||||
BOOL _connected; // Accessed on main thread only
|
||||
CFRunLoopTimerRef _disconnectTimer; // Accessed on main thread only
|
||||
|
||||
|
||||
NSDictionary* _options;
|
||||
NSString* _serverName;
|
||||
NSString* _authenticationRealm;
|
||||
@ -195,9 +195,9 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
|
||||
@implementation GCDWebServer
|
||||
|
||||
@synthesize delegate=_delegate, handlers=_handlers, port=_port, serverName=_serverName, authenticationRealm=_authenticationRealm,
|
||||
authenticationBasicAccounts=_authenticationBasicAccounts, authenticationDigestAccounts=_authenticationDigestAccounts,
|
||||
shouldAutomaticallyMapHEADToGET=_mapHEADToGET, dispatchQueuePriority=_dispatchQueuePriority;
|
||||
@synthesize delegate = _delegate, handlers = _handlers, port = _port, serverName = _serverName, authenticationRealm = _authenticationRealm,
|
||||
authenticationBasicAccounts = _authenticationBasicAccounts, authenticationDigestAccounts = _authenticationDigestAccounts,
|
||||
shouldAutomaticallyMapHEADToGET = _mapHEADToGET, dispatchQueuePriority = _dispatchQueuePriority;
|
||||
|
||||
+ (void)initialize {
|
||||
GCDWebServerInitializeFunctions();
|
||||
@ -220,7 +220,7 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
GWS_DCHECK(_activeConnections == 0);
|
||||
GWS_DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source
|
||||
GWS_DCHECK(_disconnectTimer == NULL); // The server can never be dealloc'ed while the disconnect timer is pending because of the retain-cycle
|
||||
|
||||
|
||||
#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
dispatch_release(_sourceGroup);
|
||||
dispatch_release(_syncQueue);
|
||||
@ -235,10 +235,10 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
if (_backgroundTask == UIBackgroundTaskInvalid) {
|
||||
GWS_LOG_DEBUG(@"Did start background task");
|
||||
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||
|
||||
|
||||
GWS_LOG_WARNING(@"Application is being suspended while %@ is still connected", [self class]);
|
||||
[self _endBackgroundTask];
|
||||
|
||||
|
||||
}];
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
@ -253,13 +253,13 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
GWS_DCHECK(_connected == NO);
|
||||
_connected = YES;
|
||||
GWS_LOG_DEBUG(@"Did connect");
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground) {
|
||||
[self _startBackgroundTask];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(webServerDidConnect:)]) {
|
||||
[_delegate webServerDidConnect:self];
|
||||
}
|
||||
@ -267,7 +267,7 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
|
||||
- (void)willStartConnection:(GCDWebServerConnection*)connection {
|
||||
dispatch_sync(_syncQueue, ^{
|
||||
|
||||
|
||||
GWS_DCHECK(_activeConnections >= 0);
|
||||
if (_activeConnections == 0) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@ -282,7 +282,7 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
});
|
||||
}
|
||||
_activeConnections += 1;
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -309,11 +309,11 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
GWS_DCHECK(_connected == YES);
|
||||
_connected = NO;
|
||||
GWS_LOG_DEBUG(@"Did disconnect");
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
[self _endBackgroundTask];
|
||||
#endif
|
||||
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(webServerDidDisconnect:)]) {
|
||||
[_delegate webServerDidDisconnect:self];
|
||||
}
|
||||
@ -356,9 +356,10 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
}
|
||||
|
||||
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock {
|
||||
[self addHandlerWithMatchBlock:matchBlock asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(processBlock(request));
|
||||
}];
|
||||
[self addHandlerWithMatchBlock:matchBlock
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(processBlock(request));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock {
|
||||
@ -464,7 +465,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
if (listeningSocket > 0) {
|
||||
int yes = 1;
|
||||
setsockopt(listeningSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
||||
|
||||
|
||||
if (bind(listeningSocket, address, length) == 0) {
|
||||
if (listen(listeningSocket, (int)maxPendingConnections) == 0) {
|
||||
GWS_LOG_DEBUG(@"Did open %s listening socket %i", useIPv6 ? "IPv6" : "IPv4", listeningSocket);
|
||||
@ -483,7 +484,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
GWS_LOG_ERROR(@"Failed binding %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
|
||||
close(listeningSocket);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
@ -497,7 +498,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
dispatch_group_enter(_sourceGroup);
|
||||
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, listeningSocket, 0, dispatch_get_global_queue(_dispatchQueuePriority, 0));
|
||||
dispatch_source_set_cancel_handler(source, ^{
|
||||
|
||||
|
||||
@autoreleasepool {
|
||||
int result = close(listeningSocket);
|
||||
if (result != 0) {
|
||||
@ -507,17 +508,17 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
}
|
||||
}
|
||||
dispatch_group_leave(_sourceGroup);
|
||||
|
||||
|
||||
});
|
||||
dispatch_source_set_event_handler(source, ^{
|
||||
|
||||
|
||||
@autoreleasepool {
|
||||
struct sockaddr_storage remoteSockAddr;
|
||||
socklen_t remoteAddrLen = sizeof(remoteSockAddr);
|
||||
int socket = accept(listeningSocket, (struct sockaddr*)&remoteSockAddr, &remoteAddrLen);
|
||||
if (socket > 0) {
|
||||
NSData* remoteAddress = [NSData dataWithBytes:&remoteSockAddr length:remoteAddrLen];
|
||||
|
||||
|
||||
struct sockaddr_storage localSockAddr;
|
||||
socklen_t localAddrLen = sizeof(localSockAddr);
|
||||
NSData* localAddress = nil;
|
||||
@ -527,28 +528,28 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
|
||||
|
||||
int noSigPipe = 1;
|
||||
setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe)); // Make sure this socket cannot generate SIG_PIPE
|
||||
|
||||
|
||||
GCDWebServerConnection* connection = [[_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened
|
||||
[connection self]; // Prevent compiler from complaining about unused variable / useless statement
|
||||
} else {
|
||||
GWS_LOG_ERROR(@"Failed accepting %s socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
return source;
|
||||
}
|
||||
|
||||
- (BOOL)_start:(NSError**)error {
|
||||
GWS_DCHECK(_source4 == NULL);
|
||||
|
||||
|
||||
NSUInteger port = [_GetOption(_options, GCDWebServerOption_Port, @0) unsignedIntegerValue];
|
||||
BOOL bindToLocalhost = [_GetOption(_options, GCDWebServerOption_BindToLocalhost, @NO) boolValue];
|
||||
NSUInteger maxPendingConnections = [_GetOption(_options, GCDWebServerOption_MaxPendingConnections, @16) unsignedIntegerValue];
|
||||
|
||||
|
||||
struct sockaddr_in addr4;
|
||||
bzero(&addr4, sizeof(addr4));
|
||||
addr4.sin_len = sizeof(addr4);
|
||||
@ -568,7 +569,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
GWS_LOG_ERROR(@"Failed retrieving socket address: %s (%i)", strerror(errno), errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct sockaddr_in6 addr6;
|
||||
bzero(&addr6, sizeof(addr6));
|
||||
addr6.sin6_len = sizeof(addr6);
|
||||
@ -580,7 +581,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
close(listeningSocket4);
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
_serverName = [_GetOption(_options, GCDWebServerOption_ServerName, NSStringFromClass([self class])) copy];
|
||||
NSString* authenticationMethod = _GetOption(_options, GCDWebServerOption_AuthenticationMethod, nil);
|
||||
if ([authenticationMethod isEqualToString:GCDWebServerAuthenticationMethod_Basic]) {
|
||||
@ -602,24 +603,24 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
_mapHEADToGET = [_GetOption(_options, GCDWebServerOption_AutomaticallyMapHEADToGET, @YES) boolValue];
|
||||
_disconnectDelay = [_GetOption(_options, GCDWebServerOption_ConnectedStateCoalescingInterval, @1.0) doubleValue];
|
||||
_dispatchQueuePriority = [_GetOption(_options, GCDWebServerOption_DispatchQueuePriority, @(DISPATCH_QUEUE_PRIORITY_DEFAULT)) longValue];
|
||||
|
||||
|
||||
_source4 = [self _createDispatchSourceWithListeningSocket:listeningSocket4 isIPv6:NO];
|
||||
_source6 = [self _createDispatchSourceWithListeningSocket:listeningSocket6 isIPv6:YES];
|
||||
_port = port;
|
||||
_bindToLocalhost = bindToLocalhost;
|
||||
|
||||
|
||||
NSString* bonjourName = _GetOption(_options, GCDWebServerOption_BonjourName, nil);
|
||||
NSString* bonjourType = _GetOption(_options, GCDWebServerOption_BonjourType, @"_http._tcp");
|
||||
if (bonjourName) {
|
||||
_registrationService = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (__bridge CFStringRef)bonjourType, (__bridge CFStringRef)(bonjourName.length ? bonjourName : _serverName), (SInt32)_port);
|
||||
if (_registrationService) {
|
||||
CFNetServiceClientContext context = {0, (__bridge void*)self, NULL, NULL, NULL};
|
||||
|
||||
|
||||
CFNetServiceSetClient(_registrationService, _NetServiceRegisterCallBack, &context);
|
||||
CFNetServiceScheduleWithRunLoop(_registrationService, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
CFStreamError streamError = {0};
|
||||
CFNetServiceRegisterWithOptions(_registrationService, 0, &streamError);
|
||||
|
||||
|
||||
_resolutionService = CFNetServiceCreateCopy(kCFAllocatorDefault, _registrationService);
|
||||
if (_resolutionService) {
|
||||
CFNetServiceSetClient(_resolutionService, _NetServiceResolveCallBack, &context);
|
||||
@ -631,7 +632,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
GWS_LOG_ERROR(@"Failed creating CFNetService for registration");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ([_GetOption(_options, GCDWebServerOption_RequestNATPortMapping, @NO) boolValue]) {
|
||||
DNSServiceErrorType status = DNSServiceNATPortMappingCreate(&_dnsService, 0, 0, kDNSServiceProtocol_TCP, htons(port), htons(port), 0, _DNSServiceCallBack, (__bridge void*)self);
|
||||
if (status == kDNSServiceErr_NoError) {
|
||||
@ -654,7 +655,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
GWS_LOG_ERROR(@"Failed creating NAT port mapping (%i)", status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dispatch_resume(_source4);
|
||||
dispatch_resume(_source6);
|
||||
GWS_LOG_INFO(@"%@ started on port %i and reachable at %@", [self class], (int)_port, self.serverURL);
|
||||
@ -663,13 +664,13 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
[_delegate webServerDidStart:self];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)_stop {
|
||||
GWS_DCHECK(_source4 != NULL);
|
||||
|
||||
|
||||
if (_dnsService) {
|
||||
_dnsAddress = nil;
|
||||
_dnsPort = 0;
|
||||
@ -685,7 +686,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
DNSServiceRefDeallocate(_dnsService);
|
||||
_dnsService = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (_registrationService) {
|
||||
if (_resolutionService) {
|
||||
CFNetServiceUnscheduleFromRunLoop(_resolutionService, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
@ -700,7 +701,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
CFRelease(_registrationService);
|
||||
_registrationService = NULL;
|
||||
}
|
||||
|
||||
|
||||
dispatch_source_cancel(_source6);
|
||||
dispatch_source_cancel(_source4);
|
||||
dispatch_group_wait(_sourceGroup, DISPATCH_TIME_FOREVER); // Wait until the cancellation handlers have been called which guarantees the listening sockets are closed
|
||||
@ -714,12 +715,12 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
_source4 = NULL;
|
||||
_port = 0;
|
||||
_bindToLocalhost = NO;
|
||||
|
||||
|
||||
_serverName = nil;
|
||||
_authenticationRealm = nil;
|
||||
_authenticationBasicAccounts = nil;
|
||||
_authenticationDigestAccounts = nil;
|
||||
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (_disconnectTimer) {
|
||||
CFRunLoopTimerInvalidate(_disconnectTimer);
|
||||
@ -728,7 +729,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
[self _didDisconnect];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
GWS_LOG_INFO(@"%@ stopped", [self class]);
|
||||
if ([_delegate respondsToSelector:@selector(webServerDidStop:)]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@ -896,32 +897,38 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
@implementation GCDWebServer (Handlers)
|
||||
|
||||
- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
||||
[self addDefaultHandlerForMethod:method requestClass:aClass asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(block(request));
|
||||
}];
|
||||
[self addDefaultHandlerForMethod:method
|
||||
requestClass:aClass
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(block(request));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block {
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
if (![requestMethod isEqualToString:method]) {
|
||||
return nil;
|
||||
}
|
||||
return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
|
||||
} asyncProcessBlock:block];
|
||||
|
||||
}
|
||||
asyncProcessBlock:block];
|
||||
}
|
||||
|
||||
- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
||||
[self addHandlerForMethod:method path:path requestClass:aClass asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(block(request));
|
||||
}];
|
||||
[self addHandlerForMethod:method
|
||||
path:path
|
||||
requestClass:aClass
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(block(request));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block {
|
||||
if ([path hasPrefix:@"/"] && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
if (![requestMethod isEqualToString:method]) {
|
||||
return nil;
|
||||
}
|
||||
@ -929,24 +936,28 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
return nil;
|
||||
}
|
||||
return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
|
||||
} asyncProcessBlock:block];
|
||||
|
||||
}
|
||||
asyncProcessBlock:block];
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
||||
[self addHandlerForMethod:method pathRegex:regex requestClass:aClass asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(block(request));
|
||||
}];
|
||||
[self addHandlerForMethod:method
|
||||
pathRegex:regex
|
||||
requestClass:aClass
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
completionBlock(block(request));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block {
|
||||
NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:NULL];
|
||||
if (expression && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
if (![requestMethod isEqualToString:method]) {
|
||||
return nil;
|
||||
}
|
||||
@ -972,8 +983,9 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
GCDWebServerRequest* request = [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
[request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures];
|
||||
return request;
|
||||
|
||||
} asyncProcessBlock:block];
|
||||
|
||||
}
|
||||
asyncProcessBlock:block];
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
@ -984,29 +996,35 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
@implementation GCDWebServer (GETHandlers)
|
||||
|
||||
- (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(NSString*)contentType cacheAge:(NSUInteger)cacheAge {
|
||||
[self addHandlerForMethod:@"GET" path:path requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
|
||||
GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithData:staticData contentType:contentType];
|
||||
response.cacheControlMaxAge = cacheAge;
|
||||
return response;
|
||||
|
||||
}];
|
||||
[self addHandlerForMethod:@"GET"
|
||||
path:path
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
|
||||
|
||||
GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithData:staticData contentType:contentType];
|
||||
response.cacheControlMaxAge = cacheAge;
|
||||
return response;
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addGETHandlerForPath:(NSString*)path filePath:(NSString*)filePath isAttachment:(BOOL)isAttachment cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests {
|
||||
[self addHandlerForMethod:@"GET" path:path requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
|
||||
GCDWebServerResponse* response = nil;
|
||||
if (allowRangeRequests) {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange isAttachment:isAttachment];
|
||||
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
||||
} else {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath isAttachment:isAttachment];
|
||||
}
|
||||
response.cacheControlMaxAge = cacheAge;
|
||||
return response;
|
||||
|
||||
}];
|
||||
[self addHandlerForMethod:@"GET"
|
||||
path:path
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
|
||||
|
||||
GCDWebServerResponse* response = nil;
|
||||
if (allowRangeRequests) {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange isAttachment:isAttachment];
|
||||
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
||||
} else {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath isAttachment:isAttachment];
|
||||
}
|
||||
response.cacheControlMaxAge = cacheAge;
|
||||
return response;
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
- (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path {
|
||||
@ -1042,8 +1060,8 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
- (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests {
|
||||
if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) {
|
||||
GCDWebServer* __unsafe_unretained server = self;
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
if (![requestMethod isEqualToString:@"GET"]) {
|
||||
return nil;
|
||||
}
|
||||
@ -1051,39 +1069,40 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
return nil;
|
||||
}
|
||||
return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
|
||||
} processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
|
||||
GCDWebServerResponse* response = nil;
|
||||
NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
|
||||
NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType];
|
||||
if (fileType) {
|
||||
if ([fileType isEqualToString:NSFileTypeDirectory]) {
|
||||
if (indexFilename) {
|
||||
NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename];
|
||||
NSString* indexType = [[[NSFileManager defaultManager] attributesOfItemAtPath:indexPath error:NULL] fileType];
|
||||
if ([indexType isEqualToString:NSFileTypeRegular]) {
|
||||
return [GCDWebServerFileResponse responseWithFile:indexPath];
|
||||
|
||||
}
|
||||
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
|
||||
|
||||
GCDWebServerResponse* response = nil;
|
||||
NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
|
||||
NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType];
|
||||
if (fileType) {
|
||||
if ([fileType isEqualToString:NSFileTypeDirectory]) {
|
||||
if (indexFilename) {
|
||||
NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename];
|
||||
NSString* indexType = [[[NSFileManager defaultManager] attributesOfItemAtPath:indexPath error:NULL] fileType];
|
||||
if ([indexType isEqualToString:NSFileTypeRegular]) {
|
||||
return [GCDWebServerFileResponse responseWithFile:indexPath];
|
||||
}
|
||||
}
|
||||
response = [server _responseWithContentsOfDirectory:filePath];
|
||||
} else if ([fileType isEqualToString:NSFileTypeRegular]) {
|
||||
if (allowRangeRequests) {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
|
||||
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
||||
} else {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath];
|
||||
}
|
||||
}
|
||||
}
|
||||
response = [server _responseWithContentsOfDirectory:filePath];
|
||||
} else if ([fileType isEqualToString:NSFileTypeRegular]) {
|
||||
if (allowRangeRequests) {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
|
||||
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
||||
if (response) {
|
||||
response.cacheControlMaxAge = cacheAge;
|
||||
} else {
|
||||
response = [GCDWebServerFileResponse responseWithFile:filePath];
|
||||
response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NotFound];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (response) {
|
||||
response.cacheControlMaxAge = cacheAge;
|
||||
} else {
|
||||
response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NotFound];
|
||||
}
|
||||
return response;
|
||||
|
||||
}];
|
||||
return response;
|
||||
|
||||
}];
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
@ -1204,11 +1223,11 @@ static void _LogResult(NSString* format, ...) {
|
||||
|
||||
- (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path {
|
||||
GWS_DCHECK([NSThread isMainThread]);
|
||||
NSArray* ignoredHeaders = @[@"Date", @"Etag"]; // Dates are always different by definition and ETags depend on file system node IDs
|
||||
NSArray* ignoredHeaders = @[ @"Date", @"Etag" ]; // Dates are always different by definition and ETags depend on file system node IDs
|
||||
NSInteger result = -1;
|
||||
if ([self startWithOptions:options error:NULL]) {
|
||||
_ExecuteMainThreadRunLoopSources();
|
||||
|
||||
|
||||
result = 0;
|
||||
NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];
|
||||
for (NSString* requestFile in files) {
|
||||
@ -1230,19 +1249,19 @@ static void _LogResult(NSString* format, ...) {
|
||||
if ([responseFile hasPrefix:prefix] && [responseFile hasSuffix:@".response"]) {
|
||||
NSData* responseData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:responseFile]];
|
||||
if (responseData) {
|
||||
CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromData(responseData, NO);
|
||||
CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromData(responseData, NO);
|
||||
if (expectedResponse) {
|
||||
CFHTTPMessageRef actualResponse = _CreateHTTPMessageFromPerformingRequest(requestData, self.port);
|
||||
if (actualResponse) {
|
||||
success = YES;
|
||||
|
||||
|
||||
CFIndex expectedStatusCode = CFHTTPMessageGetResponseStatusCode(expectedResponse);
|
||||
CFIndex actualStatusCode = CFHTTPMessageGetResponseStatusCode(actualResponse);
|
||||
if (actualStatusCode != expectedStatusCode) {
|
||||
_LogResult(@" Status code not matching:\n Expected: %i\n Actual: %i", (int)expectedStatusCode, (int)actualStatusCode);
|
||||
success = NO;
|
||||
}
|
||||
|
||||
|
||||
NSDictionary* expectedHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(expectedResponse));
|
||||
NSDictionary* actualHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(actualResponse));
|
||||
for (NSString* expectedHeader in expectedHeaders) {
|
||||
@ -1262,7 +1281,7 @@ static void _LogResult(NSString* format, ...) {
|
||||
success = NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NSString* expectedContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(expectedResponse, CFSTR("Content-Length")));
|
||||
NSData* expectedBody = CFBridgingRelease(CFHTTPMessageCopyBody(expectedResponse));
|
||||
NSString* actualContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(actualResponse, CFSTR("Content-Length")));
|
||||
@ -1281,14 +1300,14 @@ static void _LogResult(NSString* format, ...) {
|
||||
if ([expectedBody writeToFile:expectedPath atomically:YES] && [actualBody writeToFile:actualPath atomically:YES]) {
|
||||
NSTask* task = [[NSTask alloc] init];
|
||||
[task setLaunchPath:@"/usr/bin/opendiff"];
|
||||
[task setArguments:@[expectedPath, actualPath]];
|
||||
[task setArguments:@[ expectedPath, actualPath ]];
|
||||
[task launch];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
CFRelease(actualResponse);
|
||||
}
|
||||
CFRelease(expectedResponse);
|
||||
@ -1311,9 +1330,9 @@ static void _LogResult(NSString* format, ...) {
|
||||
}
|
||||
_ExecuteMainThreadRunLoopSources();
|
||||
}
|
||||
|
||||
|
||||
[self stop];
|
||||
|
||||
|
||||
_ExecuteMainThreadRunLoopSources();
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user