├── .gitignore
├── APN.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── APN
├── APN-Info.plist
├── APN-Prefix.pch
├── APN.storyboard
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-60@2x.png
│ │ ├── Icon-Small-40@2x.png
│ │ └── Icon-Small@2x.png
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── LTAPNListViewController.h
├── LTAPNListViewController.m
├── LTAPNViewController.h
├── LTAPNViewController.m
├── LTAppDelegate.h
├── LTAppDelegate.m
├── LTWebViewController.h
├── LTWebViewController.m
├── Models
│ ├── LTAPN.h
│ ├── LTAPN.m
│ ├── LTAPNField.h
│ ├── LTAPNField.m
│ ├── LTAPNManager.h
│ ├── LTAPNManager.m
│ ├── LTHTTPConnection.h
│ └── LTHTTPConnection.m
├── Vendor
│ ├── CocoaAsyncSocket
│ │ ├── GCDAsyncSocket.h
│ │ └── GCDAsyncSocket.m
│ ├── CocoaHTTPServer
│ │ ├── Categories
│ │ │ ├── DDData.h
│ │ │ ├── DDData.m
│ │ │ ├── DDNumber.h
│ │ │ ├── DDNumber.m
│ │ │ ├── DDRange.h
│ │ │ └── DDRange.m
│ │ ├── HTTPAuthenticationRequest.h
│ │ ├── HTTPAuthenticationRequest.m
│ │ ├── HTTPConnection.h
│ │ ├── HTTPConnection.m
│ │ ├── HTTPLogging.h
│ │ ├── HTTPMessage.h
│ │ ├── HTTPMessage.m
│ │ ├── HTTPResponse.h
│ │ ├── HTTPServer.h
│ │ ├── HTTPServer.m
│ │ ├── Mime
│ │ │ ├── MultipartFormDataParser.h
│ │ │ ├── MultipartFormDataParser.m
│ │ │ ├── MultipartMessageHeader.h
│ │ │ ├── MultipartMessageHeader.m
│ │ │ ├── MultipartMessageHeaderField.h
│ │ │ └── MultipartMessageHeaderField.m
│ │ ├── Responses
│ │ │ ├── HTTPAsyncFileResponse.h
│ │ │ ├── HTTPAsyncFileResponse.m
│ │ │ ├── HTTPDataResponse.h
│ │ │ ├── HTTPDataResponse.m
│ │ │ ├── HTTPDynamicFileResponse.h
│ │ │ ├── HTTPDynamicFileResponse.m
│ │ │ ├── HTTPErrorResponse.h
│ │ │ ├── HTTPErrorResponse.m
│ │ │ ├── HTTPFileResponse.h
│ │ │ ├── HTTPFileResponse.m
│ │ │ ├── HTTPRedirectResponse.h
│ │ │ └── HTTPRedirectResponse.m
│ │ ├── WebSocket.h
│ │ └── WebSocket.m
│ └── CocoaLumberjack
│ │ ├── DDASLLogger.h
│ │ ├── DDASLLogger.m
│ │ ├── DDAbstractDatabaseLogger.h
│ │ ├── DDAbstractDatabaseLogger.m
│ │ ├── DDFileLogger.h
│ │ ├── DDFileLogger.m
│ │ ├── DDLog.h
│ │ ├── DDLog.m
│ │ ├── DDTTYLogger.h
│ │ ├── DDTTYLogger.m
│ │ └── Extensions
│ │ ├── ContextFilterLogFormatter.h
│ │ ├── ContextFilterLogFormatter.m
│ │ ├── DispatchQueueLogFormatter.h
│ │ └── DispatchQueueLogFormatter.m
├── Views
│ ├── LTAPNCell.h
│ ├── LTAPNCell.m
│ ├── LTButtonCell.h
│ ├── LTButtonCell.m
│ ├── LTPrimaryButtonCell.h
│ ├── LTPrimaryButtonCell.m
│ ├── LTSwitchCell.h
│ ├── LTSwitchCell.m
│ ├── LTTextCell.h
│ └── LTTextCell.m
├── apn.mobileconfig
├── en.lproj
│ └── Localizable.strings
├── main.m
├── zh-Hans.lproj
│ └── Localizable.strings
└── zh-Hant.lproj
│ └── Localizable.strings
├── APNTests
├── APNTests-Info.plist
├── APNTests.m
└── en.lproj
│ └── InfoPlist.strings
├── README.md
└── Vendor
├── CocoaAsyncSocket
├── GCDAsyncSocket.h
└── GCDAsyncSocket.m
├── CocoaHTTPServer
├── Categories
│ ├── DDData.h
│ ├── DDData.m
│ ├── DDNumber.h
│ ├── DDNumber.m
│ ├── DDRange.h
│ └── DDRange.m
├── HTTPAuthenticationRequest.h
├── HTTPAuthenticationRequest.m
├── HTTPConnection.h
├── HTTPConnection.m
├── HTTPLogging.h
├── HTTPMessage.h
├── HTTPMessage.m
├── HTTPResponse.h
├── HTTPServer.h
├── HTTPServer.m
├── Mime
│ ├── MultipartFormDataParser.h
│ ├── MultipartFormDataParser.m
│ ├── MultipartMessageHeader.h
│ ├── MultipartMessageHeader.m
│ ├── MultipartMessageHeaderField.h
│ └── MultipartMessageHeaderField.m
├── Responses
│ ├── HTTPAsyncFileResponse.h
│ ├── HTTPAsyncFileResponse.m
│ ├── HTTPDataResponse.h
│ ├── HTTPDataResponse.m
│ ├── HTTPDynamicFileResponse.h
│ ├── HTTPDynamicFileResponse.m
│ ├── HTTPErrorResponse.h
│ ├── HTTPErrorResponse.m
│ ├── HTTPFileResponse.h
│ ├── HTTPFileResponse.m
│ ├── HTTPRedirectResponse.h
│ └── HTTPRedirectResponse.m
├── WebSocket.h
└── WebSocket.m
└── CocoaLumberjack
├── DDASLLogger.h
├── DDASLLogger.m
├── DDAbstractDatabaseLogger.h
├── DDAbstractDatabaseLogger.m
├── DDFileLogger.h
├── DDFileLogger.m
├── DDLog.h
├── DDLog.m
├── DDTTYLogger.h
├── DDTTYLogger.m
└── Extensions
├── ContextFilterLogFormatter.h
├── ContextFilterLogFormatter.m
├── DispatchQueueLogFormatter.h
└── DispatchQueueLogFormatter.m
/.gitignore:
--------------------------------------------------------------------------------
1 | *LocalOverrides.h
2 |
3 | # Node.js modules
4 | node_modules/*
5 |
6 | # Compiled Python files
7 | *.pyc
8 |
9 | # Folder view configuration files
10 | .DS_Store
11 | Desktop.ini
12 |
13 | # Thumbnail cache files
14 | ._*
15 | Thumbs.db
16 |
17 | # Files that might appear on external disks
18 | .Spotlight-V100
19 | .Trashes
20 |
21 | # Exclude the Podspecs
22 | Pods/*
23 | Podfile.lock
24 |
25 | # Exclude any PSD/AI source
26 | #*.psd
27 | #*.ai
28 |
29 | # Exclude generated files
30 | VersionX-revision.h
31 |
32 | # Exclude the build products
33 | build/*
34 | build.output
35 | pkg/*
36 | *.o
37 |
38 | # Exclude temp nibs and swap files
39 | *~.nib
40 | *.swp
41 | *~
42 |
43 | # Sparkle distribution Private Key (Don't check me in!)
44 | dsa_priv.pem
45 |
46 | # Exclude user-specific XCode 3 and 4 files
47 | *.mode1
48 | *.mode1v3
49 | *.mode2v3
50 | *.perspective
51 | *.perspectivev3
52 | *.pbxuser
53 | *.xcuserdatad
54 | xcuserdata
55 | profile
56 | DerivedData
57 |
58 | # Exclude ReleaseNotes
59 | RELEASENOTES
60 | RELEASENOTES.*
61 | release_notes
62 | release_notes.*
63 |
64 | # Other source repository archive directories (protects when importing)
65 | .hg
66 | .svn
67 | CVS
68 |
69 | # idea project files
70 | .idea
71 | *.hmap
72 |
73 | # twistd pid files
74 | twistd.pid
75 |
76 | # Rails
77 | # Ignore bundler config.
78 | .bundle
79 |
80 | # Ignore the default SQLite database.
81 | db/*.sqlite3
82 | db/*.sqlite3-journal
83 |
84 | # Ignore all logfiles and templates.
85 | log/*.log
86 | tmp
87 |
88 | # Ignore vendor cache
89 | vendor/cache
90 |
--------------------------------------------------------------------------------
/APN.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/APN/APN-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.lextang.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 0.1
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 3
25 | LSRequiresIPhoneOS
26 |
27 | UIBackgroundModes
28 |
29 | UIMainStoryboardFile
30 | APN
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/APN/APN-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_6_0
10 | #warning "This project uses features only available in iOS SDK 6.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #import "LTAPNManager.h"
17 |
18 | #define $ [LTAPNManager shared]
19 |
20 | #ifdef DEBUG
21 | # define NSLog(...) NSLog(__VA_ARGS__)
22 | #else
23 | # define NSLog(...) {}
24 | #endif
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/APN/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "40x40",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small-40@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "60x60",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-60@2x.png",
19 | "scale" : "2x"
20 | }
21 | ],
22 | "info" : {
23 | "version" : 1,
24 | "author" : "xcode"
25 | }
26 | }
--------------------------------------------------------------------------------
/APN/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lexrus/APN/15ccd2a99bc4a69357af7c9eabadd78d9c86e44f/APN/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/APN/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lexrus/APN/15ccd2a99bc4a69357af7c9eabadd78d9c86e44f/APN/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/APN/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lexrus/APN/15ccd2a99bc4a69357af7c9eabadd78d9c86e44f/APN/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/APN/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/APN/LTAPNListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPNListViewController.h
3 | // APN
4 | //
5 | // Created by Lex on 11/20/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTAPNListViewController : UITableViewController
12 |
13 | - (IBAction)showAbout:(id)sender;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/APN/LTAPNViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPNViewController.h
3 | // APN
4 | //
5 | // Created by Lex on 11/23/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTAPNViewController : UITableViewController
12 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
13 | @property (nonatomic, strong) NSString *APNUUID;
14 |
15 | - (void) save;
16 | - (IBAction) saveAndBack:(id)sender;
17 | - (IBAction) remove:(id)sender;
18 | - (IBAction) install:(id)sender;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/APN/LTAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAppDelegate.h
3 | // APN
4 | //
5 | // Created by Lex on 11/20/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/APN/LTAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTAppDelegate.m
3 | // APN
4 | //
5 | // Created by Lex on 11/20/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTAppDelegate.h"
10 |
11 | @implementation LTAppDelegate
12 |
13 | - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | return YES;
16 | }
17 |
18 | - (void) applicationWillResignActive:(UIApplication *)application
19 | {
20 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
21 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
22 | }
23 |
24 | - (void) applicationDidEnterBackground:(UIApplication *)application
25 | {
26 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
27 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
28 | }
29 |
30 | - (void) applicationWillEnterForeground:(UIApplication *)application
31 | {
32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
33 | }
34 |
35 | - (void) applicationDidBecomeActive:(UIApplication *)application
36 | {
37 | if ($.isServerOn)
38 | {
39 | [$ rebroadcast];
40 | }
41 | }
42 |
43 | - (void) applicationWillTerminate:(UIApplication *)application
44 | {
45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/APN/LTWebViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTWebViewController.h
3 | // APN
4 | //
5 | // Created by Lex on 11/27/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTWebViewController : UIViewController
12 | @property (weak, nonatomic) IBOutlet UIWebView *webView;
13 | @property (nonatomic, copy) NSString *URLString;
14 |
15 | - (IBAction) share:(id)sender;
16 | @end
17 |
--------------------------------------------------------------------------------
/APN/LTWebViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTWebViewController.m
3 | // APN
4 | //
5 | // Created by Lex on 11/27/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTWebViewController.h"
10 |
11 | @interface LTWebViewController ()
12 | {
13 | NSString *_URLString;
14 | }
15 |
16 | @end
17 |
18 | @implementation LTWebViewController
19 |
20 | - (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
21 | {
22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
23 | if (self)
24 | {
25 | // Custom initialization
26 | }
27 | return self;
28 | }
29 |
30 | - (void) viewDidLoad
31 | {
32 | [super viewDidLoad];
33 | // Do any additional setup after loading the view.
34 | }
35 |
36 | - (void) viewWillAppear:(BOOL)animated
37 | {
38 | [super viewWillAppear:animated];
39 |
40 | if (_URLString)
41 | {
42 | self.title = _URLString;
43 | NSURL *URL = [NSURL URLWithString:_URLString];
44 | NSURLRequest *request = [NSURLRequest requestWithURL:URL];
45 | [self.webView loadRequest:request];
46 | }
47 | }
48 |
49 | - (void) didReceiveMemoryWarning
50 | {
51 | [super didReceiveMemoryWarning];
52 | // Dispose of any resources that can be recreated.
53 | }
54 |
55 | - (IBAction) share:(id)sender
56 | {
57 | __block UIBarButtonItem *shareButton = sender;
58 |
59 | [shareButton setEnabled:NO];
60 | UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[_URLString] applicationActivities:nil];
61 | [self presentViewController:activityViewController animated:YES completion: ^{
62 | [shareButton setEnabled:YES];
63 | }];
64 | }
65 |
66 | #pragma mark - WebView delegate
67 |
68 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
69 | {
70 | if ([request.URL.absoluteString rangeOfString:@".mobileconfig" options:NSCaseInsensitiveSearch].location != NSNotFound)
71 | {
72 | [[UIApplication sharedApplication] openURL:request.URL];
73 | return NO;
74 | }
75 | return YES;
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/APN/Models/LTAPN.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPN.h
3 | //
4 | // Created by Lex on 11/25/13
5 | // Copyright (c) 2013 LexTang.com. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | FOUNDATION_EXPORT NSString *const kLTAPNUUID;
11 | FOUNDATION_EXPORT NSString *const kLTAPNPort;
12 | FOUNDATION_EXPORT NSString *const kLTAPNPassword;
13 | FOUNDATION_EXPORT NSString *const kLTAPNSummary;
14 | FOUNDATION_EXPORT NSString *const kLTAPNCode;
15 | FOUNDATION_EXPORT NSString *const kLTAPNUsername;
16 | FOUNDATION_EXPORT NSString *const kLTAPNHost;
17 |
18 | @class LTAPNField;
19 |
20 | @interface LTAPN : NSObject
21 |
22 | @property (nonatomic, strong) NSString *UUID;
23 | @property (nonatomic, assign) NSUInteger port;
24 | @property (nonatomic, strong) NSString *password;
25 | @property (nonatomic, strong) NSString *summary;
26 | @property (nonatomic, strong) NSString *code;
27 | @property (nonatomic, strong) NSString *username;
28 | @property (nonatomic, strong) NSString *host;
29 |
30 | + (LTAPN *) modelObjectWithDictionary:(NSDictionary *)dict;
31 | - (instancetype) initWithDictionary:(NSDictionary *)dict;
32 | - (NSDictionary *) dictionaryRepresentation;
33 |
34 | - (id) objectForKeyedSubscript:(NSString *)key;
35 | - (void) setObject:(id)obj forKeyedSubscript:(NSString *)key;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/APN/Models/LTAPN.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPN.m
3 | //
4 | // Created by Lex on 11/25/13
5 | // Copyright (c) 2013 LexTang.com. All rights reserved.
6 | //
7 |
8 | #import "LTAPN.h"
9 | #import "LTAPNField.h"
10 |
11 | NSString *const kLTAPNUUID = @"uuid";
12 | NSString *const kLTAPNPort = @"port";
13 | NSString *const kLTAPNPassword = @"password";
14 | NSString *const kLTAPNSummary = @"summary";
15 | NSString *const kLTAPNCode = @"code";
16 | NSString *const kLTAPNUsername = @"username";
17 | NSString *const kLTAPNHost = @"host";
18 | NSString *const kLTAPNName = @"name";
19 |
20 |
21 | @interface LTAPN ()
22 |
23 | - (id) objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
24 |
25 | @end
26 |
27 | @implementation LTAPN
28 |
29 | @synthesize UUID = _UUID;
30 | @synthesize port = _port;
31 | @synthesize password = _password;
32 | @synthesize summary = _summary;
33 | @synthesize code = _code;
34 | @synthesize username = _username;
35 | @synthesize host = _host;
36 |
37 |
38 | + (LTAPN *) modelObjectWithDictionary:(NSDictionary *)dict
39 | {
40 | LTAPN *instance = [[LTAPN alloc] initWithDictionary:dict];
41 |
42 | return instance;
43 | }
44 |
45 | - (instancetype) initWithDictionary:(NSDictionary *)dict
46 | {
47 | self = [super init];
48 |
49 | if (self && [dict isKindOfClass:[NSDictionary class]])
50 | {
51 | self.UUID = [self objectOrNilForKey:kLTAPNUUID fromDictionary:dict];
52 | self.port = [[self objectOrNilForKey:kLTAPNPort fromDictionary:dict] unsignedIntegerValue];
53 | self.password = [self objectOrNilForKey:kLTAPNPassword fromDictionary:dict];
54 | self.summary = [self objectOrNilForKey:kLTAPNSummary fromDictionary:dict];
55 | self.code = [self objectOrNilForKey:kLTAPNCode fromDictionary:dict];
56 | self.username = [self objectOrNilForKey:kLTAPNUsername fromDictionary:dict];
57 | self.host = [self objectOrNilForKey:kLTAPNHost fromDictionary:dict];
58 |
59 | }
60 |
61 | return self;
62 |
63 | }
64 |
65 | - (NSDictionary *) dictionaryRepresentation
66 | {
67 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
68 |
69 | [mutableDict setValue:self.UUID forKey:kLTAPNUUID];
70 | [mutableDict setValue:[NSNumber numberWithUnsignedInteger:self.port] forKey:kLTAPNPort];
71 | [mutableDict setValue:self.password forKey:kLTAPNPassword];
72 | [mutableDict setValue:self.summary forKey:kLTAPNSummary];
73 | [mutableDict setValue:self.code forKey:kLTAPNCode];
74 | [mutableDict setValue:self.username forKey:kLTAPNUsername];
75 | [mutableDict setValue:self.host forKey:kLTAPNHost];
76 |
77 | return [NSDictionary dictionaryWithDictionary:mutableDict];
78 | }
79 |
80 | - (NSString *) description
81 | {
82 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
83 | }
84 |
85 | - (NSString *) UUID
86 | {
87 | if (!_UUID)
88 | {
89 | _UUID = [[NSUUID UUID] UUIDString];
90 | }
91 | return _UUID;
92 | }
93 |
94 | #pragma mark - Helper Method
95 | - (id) objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
96 | {
97 | id object = [dict objectForKey:aKey];
98 |
99 | return [object isEqual:[NSNull null]] ? nil : object;
100 | }
101 |
102 |
103 | #pragma mark - NSCoding Methods
104 |
105 | - (id) initWithCoder:(NSCoder *)aDecoder
106 | {
107 | self = [super init];
108 |
109 | self.UUID = [aDecoder decodeObjectForKey:kLTAPNUUID];
110 | self.port = [aDecoder decodeIntegerForKey:kLTAPNPort];
111 | self.password = [aDecoder decodeObjectForKey:kLTAPNPassword];
112 | self.summary = [aDecoder decodeObjectForKey:kLTAPNSummary];
113 | self.code = [aDecoder decodeObjectForKey:kLTAPNCode];
114 | self.username = [aDecoder decodeObjectForKey:kLTAPNUsername];
115 | self.host = [aDecoder decodeObjectForKey:kLTAPNHost];
116 | return self;
117 | }
118 |
119 | - (void) encodeWithCoder:(NSCoder *)aCoder
120 | {
121 | [aCoder encodeObject:_UUID forKey:kLTAPNUUID];
122 | [aCoder encodeInteger:_port forKey:kLTAPNPort];
123 | [aCoder encodeObject:_password forKey:kLTAPNPassword];
124 | [aCoder encodeObject:_summary forKey:kLTAPNSummary];
125 | [aCoder encodeObject:_code forKey:kLTAPNCode];
126 | [aCoder encodeObject:_username forKey:kLTAPNUsername];
127 | [aCoder encodeObject:_host forKey:kLTAPNHost];
128 | }
129 |
130 |
131 | - (id) objectForKeyedSubscript:(NSString *)key
132 | {
133 | if ([key isEqualToString:kLTAPNCode])
134 | {
135 | return self.code;
136 | }
137 | else if ([key isEqualToString:kLTAPNSummary])
138 | {
139 | return self.summary;
140 | }
141 | else if ([key isEqualToString:kLTAPNHost])
142 | {
143 | return self.host;
144 | }
145 | else if ([key isEqualToString:kLTAPNPort])
146 | {
147 | return [@(self.port)stringValue];
148 | }
149 | else if ([key isEqualToString:kLTAPNUsername])
150 | {
151 | return self.username;
152 | }
153 | else if ([key isEqualToString:kLTAPNPassword])
154 | {
155 | return self.password;
156 | }
157 | return nil;
158 | }
159 |
160 | - (void) setObject:(id)obj forKeyedSubscript:(NSString *)key
161 | {
162 | if ([key isEqualToString:kLTAPNCode])
163 | {
164 | self.code = obj;
165 | }
166 | else if ([key isEqualToString:kLTAPNSummary])
167 | {
168 | self.summary = obj;
169 | }
170 | else if ([key isEqualToString:kLTAPNHost])
171 | {
172 | self.host = obj;
173 | }
174 | else if ([key isEqualToString:kLTAPNPort])
175 | {
176 | self.port = [obj integerValue];
177 | }
178 | else if ([key isEqualToString:kLTAPNUsername])
179 | {
180 | self.username = obj;
181 | }
182 | else if ([key isEqualToString:kLTAPNPassword])
183 | {
184 | self.password = obj;
185 | }
186 | }
187 |
188 | @end
189 |
--------------------------------------------------------------------------------
/APN/Models/LTAPNField.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPN.h
3 | // APN
4 | //
5 | // Created by Lex on 11/23/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM (NSUInteger, LTFieldType)
12 | {
13 | LTTextFieldType,
14 | LTButtonFieldType,
15 | LTSwitchFieldType,
16 | LTPasswordFieldType,
17 | LTPortFieldType
18 | };
19 |
20 | @interface LTAPNField : NSObject
21 |
22 | @property (nonatomic, copy) NSString *fieldName;
23 | @property (nonatomic, copy) NSString *title;
24 | @property (nonatomic, copy) NSString *placeholder;
25 | @property (nonatomic, assign) LTFieldType fieldType;
26 | @property (nonatomic, copy) NSString *fieldValue;
27 | @property (nonatomic, assign, getter = isRequired) BOOL required;
28 |
29 | + (LTAPNField *) fieldWithName:(NSString *)fieldName
30 | title:(NSString *)title
31 | value:(id)cellValue
32 | required:(BOOL)required;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/APN/Models/LTAPNField.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPNField.m
3 | // APN
4 | //
5 | // Created by Lex on 11/23/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTAPNField.h"
10 |
11 | @implementation LTAPNField
12 |
13 | + (LTAPNField *) fieldWithName:(NSString *)fieldName
14 | title:(NSString *)title
15 | value:(NSString *)fieldValue
16 | required:(BOOL)required
17 | {
18 | LTAPNField *fieldData = [[LTAPNField alloc] init];
19 |
20 | fieldData.fieldName = fieldName;
21 | fieldData.title = title;
22 | fieldData.fieldType = LTTextFieldType;
23 | fieldData.fieldValue = fieldValue;
24 | fieldData.required = required;
25 | if (required)
26 | {
27 | fieldData.placeholder = NSLocalizedString(@"Required", nil);
28 | }
29 | return fieldData;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/APN/Models/LTAPNManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPNManager.h
3 | // APN
4 | //
5 | // Created by Lex on 11/24/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol LTAPNManagerDelegate
12 |
13 | - (void) serverDidStart;
14 | - (void) serverDidFailToStart;
15 | - (void) serverDidStop;
16 |
17 | @end
18 |
19 | @interface LTAPNManager : NSObject
20 |
21 | @property (nonatomic, strong) NSMutableArray *APNs;
22 | @property (nonatomic, readonly) BOOL isServerOn;
23 | @property (nonatomic, strong) NSString *address;
24 | @property (nonatomic, readonly) NSString *hostName;
25 | @property (nonatomic, weak) id delegate;
26 |
27 | + (LTAPNManager *) shared;
28 |
29 | - (BOOL) synchronize;
30 | - (void) updateFiles;
31 | - (BOOL) startServer;
32 | - (void) rebroadcast;
33 | - (void) stopServer;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/APN/Models/LTHTTPConnection.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTHTTPConnection.h
3 | // APN
4 | //
5 | // Created by Lex on 12/2/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "HTTPConnection.h"
10 |
11 | @interface LTHTTPConnection : HTTPConnection
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Models/LTHTTPConnection.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTHTTPConnection.m
3 | // APN
4 | //
5 | // Created by Lex on 12/2/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTHTTPConnection.h"
10 |
11 | @implementation LTHTTPConnection
12 |
13 | //- (void)finishBody
14 | //{
15 | // [super finishBody];
16 | //
17 | // if ([self.requestURI rangeOfString:@".mobileconfig"].location != NSNotFound)
18 | // {
19 | //
20 | // }
21 | //}
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Categories/DDData.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NSData (DDData)
4 |
5 | - (NSData *)md5Digest;
6 |
7 | - (NSData *)sha1Digest;
8 |
9 | - (NSString *)hexStringValue;
10 |
11 | - (NSString *)base64Encoded;
12 | - (NSData *)base64Decoded;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Categories/DDData.m:
--------------------------------------------------------------------------------
1 | #import "DDData.h"
2 | #import
3 |
4 |
5 | @implementation NSData (DDData)
6 |
7 | static char encodingTable[64] = {
8 | 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
9 | 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
10 | 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
11 | 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };
12 |
13 | - (NSData *)md5Digest
14 | {
15 | unsigned char result[CC_MD5_DIGEST_LENGTH];
16 |
17 | CC_MD5([self bytes], (CC_LONG)[self length], result);
18 | return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
19 | }
20 |
21 | - (NSData *)sha1Digest
22 | {
23 | unsigned char result[CC_SHA1_DIGEST_LENGTH];
24 |
25 | CC_SHA1([self bytes], (CC_LONG)[self length], result);
26 | return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH];
27 | }
28 |
29 | - (NSString *)hexStringValue
30 | {
31 | NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)];
32 |
33 | const unsigned char *dataBuffer = [self bytes];
34 | int i;
35 |
36 | for (i = 0; i < [self length]; ++i)
37 | {
38 | [stringBuffer appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
39 | }
40 |
41 | return [stringBuffer copy];
42 | }
43 |
44 | - (NSString *)base64Encoded
45 | {
46 | const unsigned char *bytes = [self bytes];
47 | NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
48 | unsigned long ixtext = 0;
49 | unsigned long lentext = [self length];
50 | long ctremaining = 0;
51 | unsigned char inbuf[3], outbuf[4];
52 | unsigned short i = 0;
53 | unsigned short charsonline = 0, ctcopy = 0;
54 | unsigned long ix = 0;
55 |
56 | while( YES )
57 | {
58 | ctremaining = lentext - ixtext;
59 | if( ctremaining <= 0 ) break;
60 |
61 | for( i = 0; i < 3; i++ ) {
62 | ix = ixtext + i;
63 | if( ix < lentext ) inbuf[i] = bytes[ix];
64 | else inbuf [i] = 0;
65 | }
66 |
67 | outbuf [0] = (inbuf [0] & 0xFC) >> 2;
68 | outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
69 | outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
70 | outbuf [3] = inbuf [2] & 0x3F;
71 | ctcopy = 4;
72 |
73 | switch( ctremaining )
74 | {
75 | case 1:
76 | ctcopy = 2;
77 | break;
78 | case 2:
79 | ctcopy = 3;
80 | break;
81 | }
82 |
83 | for( i = 0; i < ctcopy; i++ )
84 | [result appendFormat:@"%c", encodingTable[outbuf[i]]];
85 |
86 | for( i = ctcopy; i < 4; i++ )
87 | [result appendString:@"="];
88 |
89 | ixtext += 3;
90 | charsonline += 4;
91 | }
92 |
93 | return [NSString stringWithString:result];
94 | }
95 |
96 | - (NSData *)base64Decoded
97 | {
98 | const unsigned char *bytes = [self bytes];
99 | NSMutableData *result = [NSMutableData dataWithCapacity:[self length]];
100 |
101 | unsigned long ixtext = 0;
102 | unsigned long lentext = [self length];
103 | unsigned char ch = 0;
104 | unsigned char inbuf[4] = {0, 0, 0, 0};
105 | unsigned char outbuf[3] = {0, 0, 0};
106 | short i = 0, ixinbuf = 0;
107 | BOOL flignore = NO;
108 | BOOL flendtext = NO;
109 |
110 | while( YES )
111 | {
112 | if( ixtext >= lentext ) break;
113 | ch = bytes[ixtext++];
114 | flignore = NO;
115 |
116 | if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
117 | else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
118 | else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
119 | else if( ch == '+' ) ch = 62;
120 | else if( ch == '=' ) flendtext = YES;
121 | else if( ch == '/' ) ch = 63;
122 | else flignore = YES;
123 |
124 | if( ! flignore )
125 | {
126 | short ctcharsinbuf = 3;
127 | BOOL flbreak = NO;
128 |
129 | if( flendtext )
130 | {
131 | if( ! ixinbuf ) break;
132 | if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
133 | else ctcharsinbuf = 2;
134 | ixinbuf = 3;
135 | flbreak = YES;
136 | }
137 |
138 | inbuf [ixinbuf++] = ch;
139 |
140 | if( ixinbuf == 4 )
141 | {
142 | ixinbuf = 0;
143 | outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
144 | outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
145 | outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );
146 |
147 | for( i = 0; i < ctcharsinbuf; i++ )
148 | [result appendBytes:&outbuf[i] length:1];
149 | }
150 |
151 | if( flbreak ) break;
152 | }
153 | }
154 |
155 | return [NSData dataWithData:result];
156 | }
157 |
158 | @end
159 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Categories/DDNumber.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 |
4 | @interface NSNumber (DDNumber)
5 |
6 | + (BOOL)parseString:(NSString *)str intoSInt64:(SInt64 *)pNum;
7 | + (BOOL)parseString:(NSString *)str intoUInt64:(UInt64 *)pNum;
8 |
9 | + (BOOL)parseString:(NSString *)str intoNSInteger:(NSInteger *)pNum;
10 | + (BOOL)parseString:(NSString *)str intoNSUInteger:(NSUInteger *)pNum;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Categories/DDNumber.m:
--------------------------------------------------------------------------------
1 | #import "DDNumber.h"
2 |
3 |
4 | @implementation NSNumber (DDNumber)
5 |
6 | + (BOOL)parseString:(NSString *)str intoSInt64:(SInt64 *)pNum
7 | {
8 | if(str == nil)
9 | {
10 | *pNum = 0;
11 | return NO;
12 | }
13 |
14 | errno = 0;
15 |
16 | // On both 32-bit and 64-bit machines, long long = 64 bit
17 |
18 | *pNum = strtoll([str UTF8String], NULL, 10);
19 |
20 | if(errno != 0)
21 | return NO;
22 | else
23 | return YES;
24 | }
25 |
26 | + (BOOL)parseString:(NSString *)str intoUInt64:(UInt64 *)pNum
27 | {
28 | if(str == nil)
29 | {
30 | *pNum = 0;
31 | return NO;
32 | }
33 |
34 | errno = 0;
35 |
36 | // On both 32-bit and 64-bit machines, unsigned long long = 64 bit
37 |
38 | *pNum = strtoull([str UTF8String], NULL, 10);
39 |
40 | if(errno != 0)
41 | return NO;
42 | else
43 | return YES;
44 | }
45 |
46 | + (BOOL)parseString:(NSString *)str intoNSInteger:(NSInteger *)pNum
47 | {
48 | if(str == nil)
49 | {
50 | *pNum = 0;
51 | return NO;
52 | }
53 |
54 | errno = 0;
55 |
56 | // On LP64, NSInteger = long = 64 bit
57 | // Otherwise, NSInteger = int = long = 32 bit
58 |
59 | *pNum = strtol([str UTF8String], NULL, 10);
60 |
61 | if(errno != 0)
62 | return NO;
63 | else
64 | return YES;
65 | }
66 |
67 | + (BOOL)parseString:(NSString *)str intoNSUInteger:(NSUInteger *)pNum
68 | {
69 | if(str == nil)
70 | {
71 | *pNum = 0;
72 | return NO;
73 | }
74 |
75 | errno = 0;
76 |
77 | // On LP64, NSUInteger = unsigned long = 64 bit
78 | // Otherwise, NSUInteger = unsigned int = unsigned long = 32 bit
79 |
80 | *pNum = strtoul([str UTF8String], NULL, 10);
81 |
82 | if(errno != 0)
83 | return NO;
84 | else
85 | return YES;
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Categories/DDRange.h:
--------------------------------------------------------------------------------
1 | /**
2 | * DDRange is the functional equivalent of a 64 bit NSRange.
3 | * The HTTP Server is designed to support very large files.
4 | * On 32 bit architectures (ppc, i386) NSRange uses unsigned 32 bit integers.
5 | * This only supports a range of up to 4 gigabytes.
6 | * By defining our own variant, we can support a range up to 16 exabytes.
7 | *
8 | * All effort is given such that DDRange functions EXACTLY the same as NSRange.
9 | **/
10 |
11 | #import
12 | #import
13 |
14 | @class NSString;
15 |
16 | typedef struct _DDRange {
17 | UInt64 location;
18 | UInt64 length;
19 | } DDRange;
20 |
21 | typedef DDRange *DDRangePointer;
22 |
23 | NS_INLINE DDRange DDMakeRange(UInt64 loc, UInt64 len) {
24 | DDRange r;
25 | r.location = loc;
26 | r.length = len;
27 | return r;
28 | }
29 |
30 | NS_INLINE UInt64 DDMaxRange(DDRange range) {
31 | return (range.location + range.length);
32 | }
33 |
34 | NS_INLINE BOOL DDLocationInRange(UInt64 loc, DDRange range) {
35 | return (loc - range.location < range.length);
36 | }
37 |
38 | NS_INLINE BOOL DDEqualRanges(DDRange range1, DDRange range2) {
39 | return ((range1.location == range2.location) && (range1.length == range2.length));
40 | }
41 |
42 | FOUNDATION_EXPORT DDRange DDUnionRange(DDRange range1, DDRange range2);
43 | FOUNDATION_EXPORT DDRange DDIntersectionRange(DDRange range1, DDRange range2);
44 | FOUNDATION_EXPORT NSString *DDStringFromRange(DDRange range);
45 | FOUNDATION_EXPORT DDRange DDRangeFromString(NSString *aString);
46 |
47 | NSInteger DDRangeCompare(DDRangePointer pDDRange1, DDRangePointer pDDRange2);
48 |
49 | @interface NSValue (NSValueDDRangeExtensions)
50 |
51 | + (NSValue *)valueWithDDRange:(DDRange)range;
52 | - (DDRange)ddrangeValue;
53 |
54 | - (NSInteger)ddrangeCompare:(NSValue *)ddrangeValue;
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Categories/DDRange.m:
--------------------------------------------------------------------------------
1 | #import "DDRange.h"
2 | #import "DDNumber.h"
3 |
4 | DDRange DDUnionRange(DDRange range1, DDRange range2)
5 | {
6 | DDRange result;
7 |
8 | result.location = MIN(range1.location, range2.location);
9 | result.length = MAX(DDMaxRange(range1), DDMaxRange(range2)) - result.location;
10 |
11 | return result;
12 | }
13 |
14 | DDRange DDIntersectionRange(DDRange range1, DDRange range2)
15 | {
16 | DDRange result;
17 |
18 | if((DDMaxRange(range1) < range2.location) || (DDMaxRange(range2) < range1.location))
19 | {
20 | return DDMakeRange(0, 0);
21 | }
22 |
23 | result.location = MAX(range1.location, range2.location);
24 | result.length = MIN(DDMaxRange(range1), DDMaxRange(range2)) - result.location;
25 |
26 | return result;
27 | }
28 |
29 | NSString *DDStringFromRange(DDRange range)
30 | {
31 | return [NSString stringWithFormat:@"{%qu, %qu}", range.location, range.length];
32 | }
33 |
34 | DDRange DDRangeFromString(NSString *aString)
35 | {
36 | DDRange result = DDMakeRange(0, 0);
37 |
38 | // NSRange will ignore '-' characters, but not '+' characters
39 | NSCharacterSet *cset = [NSCharacterSet characterSetWithCharactersInString:@"+0123456789"];
40 |
41 | NSScanner *scanner = [NSScanner scannerWithString:aString];
42 | [scanner setCharactersToBeSkipped:[cset invertedSet]];
43 |
44 | NSString *str1 = nil;
45 | NSString *str2 = nil;
46 |
47 | BOOL found1 = [scanner scanCharactersFromSet:cset intoString:&str1];
48 | BOOL found2 = [scanner scanCharactersFromSet:cset intoString:&str2];
49 |
50 | if(found1) [NSNumber parseString:str1 intoUInt64:&result.location];
51 | if(found2) [NSNumber parseString:str2 intoUInt64:&result.length];
52 |
53 | return result;
54 | }
55 |
56 | NSInteger DDRangeCompare(DDRangePointer pDDRange1, DDRangePointer pDDRange2)
57 | {
58 | // Comparison basis:
59 | // Which range would you encouter first if you started at zero, and began walking towards infinity.
60 | // If you encouter both ranges at the same time, which range would end first.
61 |
62 | if(pDDRange1->location < pDDRange2->location)
63 | {
64 | return NSOrderedAscending;
65 | }
66 | if(pDDRange1->location > pDDRange2->location)
67 | {
68 | return NSOrderedDescending;
69 | }
70 | if(pDDRange1->length < pDDRange2->length)
71 | {
72 | return NSOrderedAscending;
73 | }
74 | if(pDDRange1->length > pDDRange2->length)
75 | {
76 | return NSOrderedDescending;
77 | }
78 |
79 | return NSOrderedSame;
80 | }
81 |
82 | @implementation NSValue (NSValueDDRangeExtensions)
83 |
84 | + (NSValue *)valueWithDDRange:(DDRange)range
85 | {
86 | return [NSValue valueWithBytes:&range objCType:@encode(DDRange)];
87 | }
88 |
89 | - (DDRange)ddrangeValue
90 | {
91 | DDRange result;
92 | [self getValue:&result];
93 | return result;
94 | }
95 |
96 | - (NSInteger)ddrangeCompare:(NSValue *)other
97 | {
98 | DDRange r1 = [self ddrangeValue];
99 | DDRange r2 = [other ddrangeValue];
100 |
101 | return DDRangeCompare(&r1, &r2);
102 | }
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/HTTPAuthenticationRequest.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #if TARGET_OS_IPHONE
4 | // Note: You may need to add the CFNetwork Framework to your project
5 | #import
6 | #endif
7 |
8 | @class HTTPMessage;
9 |
10 |
11 | @interface HTTPAuthenticationRequest : NSObject
12 | {
13 | BOOL isBasic;
14 | BOOL isDigest;
15 |
16 | NSString *base64Credentials;
17 |
18 | NSString *username;
19 | NSString *realm;
20 | NSString *nonce;
21 | NSString *uri;
22 | NSString *qop;
23 | NSString *nc;
24 | NSString *cnonce;
25 | NSString *response;
26 | }
27 | - (id)initWithRequest:(HTTPMessage *)request;
28 |
29 | - (BOOL)isBasic;
30 | - (BOOL)isDigest;
31 |
32 | // Basic
33 | - (NSString *)base64Credentials;
34 |
35 | // Digest
36 | - (NSString *)username;
37 | - (NSString *)realm;
38 | - (NSString *)nonce;
39 | - (NSString *)uri;
40 | - (NSString *)qop;
41 | - (NSString *)nc;
42 | - (NSString *)cnonce;
43 | - (NSString *)response;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/HTTPAuthenticationRequest.m:
--------------------------------------------------------------------------------
1 | #import "HTTPAuthenticationRequest.h"
2 | #import "HTTPMessage.h"
3 |
4 | #if ! __has_feature(objc_arc)
5 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6 | #endif
7 |
8 | @interface HTTPAuthenticationRequest (PrivateAPI)
9 | - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header;
10 | - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header;
11 | @end
12 |
13 |
14 | @implementation HTTPAuthenticationRequest
15 |
16 | - (id)initWithRequest:(HTTPMessage *)request
17 | {
18 | if ((self = [super init]))
19 | {
20 | NSString *authInfo = [request headerField:@"Authorization"];
21 |
22 | isBasic = NO;
23 | if ([authInfo length] >= 6)
24 | {
25 | isBasic = [[authInfo substringToIndex:6] caseInsensitiveCompare:@"Basic "] == NSOrderedSame;
26 | }
27 |
28 | isDigest = NO;
29 | if ([authInfo length] >= 7)
30 | {
31 | isDigest = [[authInfo substringToIndex:7] caseInsensitiveCompare:@"Digest "] == NSOrderedSame;
32 | }
33 |
34 | if (isBasic)
35 | {
36 | NSMutableString *temp = [[authInfo substringFromIndex:6] mutableCopy];
37 | CFStringTrimWhitespace((__bridge CFMutableStringRef)temp);
38 |
39 | base64Credentials = [temp copy];
40 | }
41 |
42 | if (isDigest)
43 | {
44 | username = [self quotedSubHeaderFieldValue:@"username" fromHeaderFieldValue:authInfo];
45 | realm = [self quotedSubHeaderFieldValue:@"realm" fromHeaderFieldValue:authInfo];
46 | nonce = [self quotedSubHeaderFieldValue:@"nonce" fromHeaderFieldValue:authInfo];
47 | uri = [self quotedSubHeaderFieldValue:@"uri" fromHeaderFieldValue:authInfo];
48 |
49 | // It appears from RFC 2617 that the qop is to be given unquoted
50 | // Tests show that Firefox performs this way, but Safari does not
51 | // Thus we'll attempt to retrieve the value as nonquoted, but we'll verify it doesn't start with a quote
52 | qop = [self nonquotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo];
53 | if(qop && ([qop characterAtIndex:0] == '"'))
54 | {
55 | qop = [self quotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo];
56 | }
57 |
58 | nc = [self nonquotedSubHeaderFieldValue:@"nc" fromHeaderFieldValue:authInfo];
59 | cnonce = [self quotedSubHeaderFieldValue:@"cnonce" fromHeaderFieldValue:authInfo];
60 | response = [self quotedSubHeaderFieldValue:@"response" fromHeaderFieldValue:authInfo];
61 | }
62 | }
63 | return self;
64 | }
65 |
66 |
67 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68 | #pragma mark Accessors:
69 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 |
71 | - (BOOL)isBasic {
72 | return isBasic;
73 | }
74 |
75 | - (BOOL)isDigest {
76 | return isDigest;
77 | }
78 |
79 | - (NSString *)base64Credentials {
80 | return base64Credentials;
81 | }
82 |
83 | - (NSString *)username {
84 | return username;
85 | }
86 |
87 | - (NSString *)realm {
88 | return realm;
89 | }
90 |
91 | - (NSString *)nonce {
92 | return nonce;
93 | }
94 |
95 | - (NSString *)uri {
96 | return uri;
97 | }
98 |
99 | - (NSString *)qop {
100 | return qop;
101 | }
102 |
103 | - (NSString *)nc {
104 | return nc;
105 | }
106 |
107 | - (NSString *)cnonce {
108 | return cnonce;
109 | }
110 |
111 | - (NSString *)response {
112 | return response;
113 | }
114 |
115 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 | #pragma mark Private API:
117 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118 |
119 | /**
120 | * Retrieves a "Sub Header Field Value" from a given header field value.
121 | * The sub header field is expected to be quoted.
122 | *
123 | * In the following header field:
124 | * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939"
125 | * The sub header field titled 'username' is quoted, and this method would return the value @"Mufasa".
126 | **/
127 | - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header
128 | {
129 | NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=\"", param]];
130 | if(startRange.location == NSNotFound)
131 | {
132 | // The param was not found anywhere in the header
133 | return nil;
134 | }
135 |
136 | NSUInteger postStartRangeLocation = startRange.location + startRange.length;
137 | NSUInteger postStartRangeLength = [header length] - postStartRangeLocation;
138 | NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength);
139 |
140 | NSRange endRange = [header rangeOfString:@"\"" options:0 range:postStartRange];
141 | if(endRange.location == NSNotFound)
142 | {
143 | // The ending double-quote was not found anywhere in the header
144 | return nil;
145 | }
146 |
147 | NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation);
148 | return [header substringWithRange:subHeaderRange];
149 | }
150 |
151 | /**
152 | * Retrieves a "Sub Header Field Value" from a given header field value.
153 | * The sub header field is expected to not be quoted.
154 | *
155 | * In the following header field:
156 | * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939"
157 | * The sub header field titled 'qop' is nonquoted, and this method would return the value @"auth".
158 | **/
159 | - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header
160 | {
161 | NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=", param]];
162 | if(startRange.location == NSNotFound)
163 | {
164 | // The param was not found anywhere in the header
165 | return nil;
166 | }
167 |
168 | NSUInteger postStartRangeLocation = startRange.location + startRange.length;
169 | NSUInteger postStartRangeLength = [header length] - postStartRangeLocation;
170 | NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength);
171 |
172 | NSRange endRange = [header rangeOfString:@"," options:0 range:postStartRange];
173 | if(endRange.location == NSNotFound)
174 | {
175 | // The ending comma was not found anywhere in the header
176 | // However, if the nonquoted param is at the end of the string, there would be no comma
177 | // This is only possible if there are no spaces anywhere
178 | NSRange endRange2 = [header rangeOfString:@" " options:0 range:postStartRange];
179 | if(endRange2.location != NSNotFound)
180 | {
181 | return nil;
182 | }
183 | else
184 | {
185 | return [header substringWithRange:postStartRange];
186 | }
187 | }
188 | else
189 | {
190 | NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation);
191 | return [header substringWithRange:subHeaderRange];
192 | }
193 | }
194 |
195 | @end
196 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/HTTPConnection.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class GCDAsyncSocket;
4 | @class HTTPMessage;
5 | @class HTTPServer;
6 | @class WebSocket;
7 | @protocol HTTPResponse;
8 |
9 |
10 | #define HTTPConnectionDidDieNotification @"HTTPConnectionDidDie"
11 |
12 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13 | #pragma mark -
14 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
15 |
16 | @interface HTTPConfig : NSObject
17 | {
18 | HTTPServer __unsafe_unretained *server;
19 | NSString __strong *documentRoot;
20 | dispatch_queue_t queue;
21 | }
22 |
23 | - (id)initWithServer:(HTTPServer *)server documentRoot:(NSString *)documentRoot;
24 | - (id)initWithServer:(HTTPServer *)server documentRoot:(NSString *)documentRoot queue:(dispatch_queue_t)q;
25 |
26 | @property (nonatomic, unsafe_unretained, readonly) HTTPServer *server;
27 | @property (nonatomic, strong, readonly) NSString *documentRoot;
28 | @property (nonatomic, readonly) dispatch_queue_t queue;
29 |
30 | @end
31 |
32 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 | #pragma mark -
34 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35 |
36 | @interface HTTPConnection : NSObject
37 | {
38 | dispatch_queue_t connectionQueue;
39 | GCDAsyncSocket *asyncSocket;
40 | HTTPConfig *config;
41 |
42 | BOOL started;
43 |
44 | HTTPMessage *request;
45 | unsigned int numHeaderLines;
46 |
47 | BOOL sentResponseHeaders;
48 |
49 | NSString *nonce;
50 | long lastNC;
51 |
52 | NSObject *httpResponse;
53 |
54 | NSMutableArray *ranges;
55 | NSMutableArray *ranges_headers;
56 | NSString *ranges_boundry;
57 | int rangeIndex;
58 |
59 | UInt64 requestContentLength;
60 | UInt64 requestContentLengthReceived;
61 | UInt64 requestChunkSize;
62 | UInt64 requestChunkSizeReceived;
63 |
64 | NSMutableArray *responseDataSizes;
65 | }
66 |
67 | - (id)initWithAsyncSocket:(GCDAsyncSocket *)newSocket configuration:(HTTPConfig *)aConfig;
68 |
69 | - (void)start;
70 | - (void)stop;
71 |
72 | - (void)startConnection;
73 |
74 | - (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path;
75 | - (BOOL)expectsRequestBodyFromMethod:(NSString *)method atPath:(NSString *)path;
76 |
77 | - (BOOL)isSecureServer;
78 | - (NSArray *)sslIdentityAndCertificates;
79 |
80 | - (BOOL)isPasswordProtected:(NSString *)path;
81 | - (BOOL)useDigestAccessAuthentication;
82 | - (NSString *)realm;
83 | - (NSString *)passwordForUser:(NSString *)username;
84 |
85 | - (NSDictionary *)parseParams:(NSString *)query;
86 | - (NSDictionary *)parseGetParams;
87 |
88 | - (NSString *)requestURI;
89 |
90 | - (NSArray *)directoryIndexFileNames;
91 | - (NSString *)filePathForURI:(NSString *)path;
92 | - (NSString *)filePathForURI:(NSString *)path allowDirectory:(BOOL)allowDirectory;
93 | - (NSObject *)httpResponseForMethod:(NSString *)method URI:(NSString *)path;
94 | - (WebSocket *)webSocketForURI:(NSString *)path;
95 |
96 | - (void)prepareForBodyWithSize:(UInt64)contentLength;
97 | - (void)processBodyData:(NSData *)postDataChunk;
98 | - (void)finishBody;
99 |
100 | - (void)handleVersionNotSupported:(NSString *)version;
101 | - (void)handleAuthenticationFailed;
102 | - (void)handleResourceNotFound;
103 | - (void)handleInvalidRequest:(NSData *)data;
104 | - (void)handleUnknownMethod:(NSString *)method;
105 |
106 | - (NSData *)preprocessResponse:(HTTPMessage *)response;
107 | - (NSData *)preprocessErrorResponse:(HTTPMessage *)response;
108 |
109 | - (void)finishResponse;
110 |
111 | - (BOOL)shouldDie;
112 | - (void)die;
113 |
114 | @end
115 |
116 | @interface HTTPConnection (AsynchronousHTTPResponse)
117 | - (void)responseHasAvailableData:(NSObject *)sender;
118 | - (void)responseDidAbort:(NSObject *)sender;
119 | @end
120 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/HTTPLogging.h:
--------------------------------------------------------------------------------
1 | /**
2 | * In order to provide fast and flexible logging, this project uses Cocoa Lumberjack.
3 | *
4 | * The Google Code page has a wealth of documentation if you have any questions.
5 | * https://github.com/robbiehanson/CocoaLumberjack
6 | *
7 | * Here's what you need to know concerning how logging is setup for CocoaHTTPServer:
8 | *
9 | * There are 4 log levels:
10 | * - Error
11 | * - Warning
12 | * - Info
13 | * - Verbose
14 | *
15 | * In addition to this, there is a Trace flag that can be enabled.
16 | * When tracing is enabled, it spits out the methods that are being called.
17 | *
18 | * Please note that tracing is separate from the log levels.
19 | * For example, one could set the log level to warning, and enable tracing.
20 | *
21 | * All logging is asynchronous, except errors.
22 | * To use logging within your own custom files, follow the steps below.
23 | *
24 | * Step 1:
25 | * Import this header in your implementation file:
26 | *
27 | * #import "HTTPLogging.h"
28 | *
29 | * Step 2:
30 | * Define your logging level in your implementation file:
31 | *
32 | * // Log levels: off, error, warn, info, verbose
33 | * static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE;
34 | *
35 | * If you wish to enable tracing, you could do something like this:
36 | *
37 | * // Debug levels: off, error, warn, info, verbose
38 | * static const int httpLogLevel = HTTP_LOG_LEVEL_INFO | HTTP_LOG_FLAG_TRACE;
39 | *
40 | * Step 3:
41 | * Replace your NSLog statements with HTTPLog statements according to the severity of the message.
42 | *
43 | * NSLog(@"Fatal error, no dohickey found!"); -> HTTPLogError(@"Fatal error, no dohickey found!");
44 | *
45 | * HTTPLog works exactly the same as NSLog.
46 | * This means you can pass it multiple variables just like NSLog.
47 | **/
48 |
49 | #import "DDLog.h"
50 |
51 | // Define logging context for every log message coming from the HTTP server.
52 | // The logging context can be extracted from the DDLogMessage from within the logging framework,
53 | // which gives loggers, formatters, and filters the ability to optionally process them differently.
54 |
55 | #define HTTP_LOG_CONTEXT 80
56 |
57 | // Configure log levels.
58 |
59 | #define HTTP_LOG_FLAG_ERROR (1 << 0) // 0...00001
60 | #define HTTP_LOG_FLAG_WARN (1 << 1) // 0...00010
61 | #define HTTP_LOG_FLAG_INFO (1 << 2) // 0...00100
62 | #define HTTP_LOG_FLAG_VERBOSE (1 << 3) // 0...01000
63 |
64 | #define HTTP_LOG_LEVEL_OFF 0 // 0...00000
65 | #define HTTP_LOG_LEVEL_ERROR (HTTP_LOG_LEVEL_OFF | HTTP_LOG_FLAG_ERROR) // 0...00001
66 | #define HTTP_LOG_LEVEL_WARN (HTTP_LOG_LEVEL_ERROR | HTTP_LOG_FLAG_WARN) // 0...00011
67 | #define HTTP_LOG_LEVEL_INFO (HTTP_LOG_LEVEL_WARN | HTTP_LOG_FLAG_INFO) // 0...00111
68 | #define HTTP_LOG_LEVEL_VERBOSE (HTTP_LOG_LEVEL_INFO | HTTP_LOG_FLAG_VERBOSE) // 0...01111
69 |
70 | // Setup fine grained logging.
71 | // The first 4 bits are being used by the standard log levels (0 - 3)
72 | //
73 | // We're going to add tracing, but NOT as a log level.
74 | // Tracing can be turned on and off independently of log level.
75 |
76 | #define HTTP_LOG_FLAG_TRACE (1 << 4) // 0...10000
77 |
78 | // Setup the usual boolean macros.
79 |
80 | #define HTTP_LOG_ERROR (httpLogLevel & HTTP_LOG_FLAG_ERROR)
81 | #define HTTP_LOG_WARN (httpLogLevel & HTTP_LOG_FLAG_WARN)
82 | #define HTTP_LOG_INFO (httpLogLevel & HTTP_LOG_FLAG_INFO)
83 | #define HTTP_LOG_VERBOSE (httpLogLevel & HTTP_LOG_FLAG_VERBOSE)
84 | #define HTTP_LOG_TRACE (httpLogLevel & HTTP_LOG_FLAG_TRACE)
85 |
86 | // Configure asynchronous logging.
87 | // We follow the default configuration,
88 | // but we reserve a special macro to easily disable asynchronous logging for debugging purposes.
89 |
90 | #define HTTP_LOG_ASYNC_ENABLED YES
91 |
92 | #define HTTP_LOG_ASYNC_ERROR ( NO && HTTP_LOG_ASYNC_ENABLED)
93 | #define HTTP_LOG_ASYNC_WARN (YES && HTTP_LOG_ASYNC_ENABLED)
94 | #define HTTP_LOG_ASYNC_INFO (YES && HTTP_LOG_ASYNC_ENABLED)
95 | #define HTTP_LOG_ASYNC_VERBOSE (YES && HTTP_LOG_ASYNC_ENABLED)
96 | #define HTTP_LOG_ASYNC_TRACE (YES && HTTP_LOG_ASYNC_ENABLED)
97 |
98 | // Define logging primitives.
99 |
100 | #define HTTPLogError(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_ERROR, httpLogLevel, HTTP_LOG_FLAG_ERROR, \
101 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
102 |
103 | #define HTTPLogWarn(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_WARN, httpLogLevel, HTTP_LOG_FLAG_WARN, \
104 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
105 |
106 | #define HTTPLogInfo(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_INFO, httpLogLevel, HTTP_LOG_FLAG_INFO, \
107 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
108 |
109 | #define HTTPLogVerbose(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_VERBOSE, httpLogLevel, HTTP_LOG_FLAG_VERBOSE, \
110 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
111 |
112 | #define HTTPLogTrace() LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
113 | HTTP_LOG_CONTEXT, @"%@[%p]: %@", THIS_FILE, self, THIS_METHOD)
114 |
115 | #define HTTPLogTrace2(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
116 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
117 |
118 |
119 | #define HTTPLogCError(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_ERROR, httpLogLevel, HTTP_LOG_FLAG_ERROR, \
120 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
121 |
122 | #define HTTPLogCWarn(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_WARN, httpLogLevel, HTTP_LOG_FLAG_WARN, \
123 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
124 |
125 | #define HTTPLogCInfo(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_INFO, httpLogLevel, HTTP_LOG_FLAG_INFO, \
126 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
127 |
128 | #define HTTPLogCVerbose(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_VERBOSE, httpLogLevel, HTTP_LOG_FLAG_VERBOSE, \
129 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
130 |
131 | #define HTTPLogCTrace() LOG_C_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
132 | HTTP_LOG_CONTEXT, @"%@[%p]: %@", THIS_FILE, self, __FUNCTION__)
133 |
134 | #define HTTPLogCTrace2(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
135 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
136 |
137 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/HTTPMessage.h:
--------------------------------------------------------------------------------
1 | /**
2 | * The HTTPMessage class is a simple Objective-C wrapper around Apple's CFHTTPMessage class.
3 | **/
4 |
5 | #import
6 |
7 | #if TARGET_OS_IPHONE
8 | // Note: You may need to add the CFNetwork Framework to your project
9 | #import
10 | #endif
11 |
12 | #define HTTPVersion1_0 ((NSString *)kCFHTTPVersion1_0)
13 | #define HTTPVersion1_1 ((NSString *)kCFHTTPVersion1_1)
14 |
15 |
16 | @interface HTTPMessage : NSObject
17 | {
18 | CFHTTPMessageRef message;
19 | }
20 |
21 | - (id)initEmptyRequest;
22 |
23 | - (id)initRequestWithMethod:(NSString *)method URL:(NSURL *)url version:(NSString *)version;
24 |
25 | - (id)initResponseWithStatusCode:(NSInteger)code description:(NSString *)description version:(NSString *)version;
26 |
27 | - (BOOL)appendData:(NSData *)data;
28 |
29 | - (BOOL)isHeaderComplete;
30 |
31 | - (NSString *)version;
32 |
33 | - (NSString *)method;
34 | - (NSURL *)url;
35 |
36 | - (NSInteger)statusCode;
37 |
38 | - (NSDictionary *)allHeaderFields;
39 | - (NSString *)headerField:(NSString *)headerField;
40 |
41 | - (void)setHeaderField:(NSString *)headerField value:(NSString *)headerFieldValue;
42 |
43 | - (NSData *)messageData;
44 |
45 | - (NSData *)body;
46 | - (void)setBody:(NSData *)body;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/HTTPMessage.m:
--------------------------------------------------------------------------------
1 | #import "HTTPMessage.h"
2 |
3 | #if ! __has_feature(objc_arc)
4 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
5 | #endif
6 |
7 |
8 | @implementation HTTPMessage
9 |
10 | - (id)initEmptyRequest
11 | {
12 | if ((self = [super init]))
13 | {
14 | message = CFHTTPMessageCreateEmpty(NULL, YES);
15 | }
16 | return self;
17 | }
18 |
19 | - (id)initRequestWithMethod:(NSString *)method URL:(NSURL *)url version:(NSString *)version
20 | {
21 | if ((self = [super init]))
22 | {
23 | message = CFHTTPMessageCreateRequest(NULL,
24 | (__bridge CFStringRef)method,
25 | (__bridge CFURLRef)url,
26 | (__bridge CFStringRef)version);
27 | }
28 | return self;
29 | }
30 |
31 | - (id)initResponseWithStatusCode:(NSInteger)code description:(NSString *)description version:(NSString *)version
32 | {
33 | if ((self = [super init]))
34 | {
35 | message = CFHTTPMessageCreateResponse(NULL,
36 | (CFIndex)code,
37 | (__bridge CFStringRef)description,
38 | (__bridge CFStringRef)version);
39 | }
40 | return self;
41 | }
42 |
43 | - (void)dealloc
44 | {
45 | if (message)
46 | {
47 | CFRelease(message);
48 | }
49 | }
50 |
51 | - (BOOL)appendData:(NSData *)data
52 | {
53 | return CFHTTPMessageAppendBytes(message, [data bytes], [data length]);
54 | }
55 |
56 | - (BOOL)isHeaderComplete
57 | {
58 | return CFHTTPMessageIsHeaderComplete(message);
59 | }
60 |
61 | - (NSString *)version
62 | {
63 | return (__bridge_transfer NSString *)CFHTTPMessageCopyVersion(message);
64 | }
65 |
66 | - (NSString *)method
67 | {
68 | return (__bridge_transfer NSString *)CFHTTPMessageCopyRequestMethod(message);
69 | }
70 |
71 | - (NSURL *)url
72 | {
73 | return (__bridge_transfer NSURL *)CFHTTPMessageCopyRequestURL(message);
74 | }
75 |
76 | - (NSInteger)statusCode
77 | {
78 | return (NSInteger)CFHTTPMessageGetResponseStatusCode(message);
79 | }
80 |
81 | - (NSDictionary *)allHeaderFields
82 | {
83 | return (__bridge_transfer NSDictionary *)CFHTTPMessageCopyAllHeaderFields(message);
84 | }
85 |
86 | - (NSString *)headerField:(NSString *)headerField
87 | {
88 | return (__bridge_transfer NSString *)CFHTTPMessageCopyHeaderFieldValue(message, (__bridge CFStringRef)headerField);
89 | }
90 |
91 | - (void)setHeaderField:(NSString *)headerField value:(NSString *)headerFieldValue
92 | {
93 | CFHTTPMessageSetHeaderFieldValue(message,
94 | (__bridge CFStringRef)headerField,
95 | (__bridge CFStringRef)headerFieldValue);
96 | }
97 |
98 | - (NSData *)messageData
99 | {
100 | return (__bridge_transfer NSData *)CFHTTPMessageCopySerializedMessage(message);
101 | }
102 |
103 | - (NSData *)body
104 | {
105 | return (__bridge_transfer NSData *)CFHTTPMessageCopyBody(message);
106 | }
107 |
108 | - (void)setBody:(NSData *)body
109 | {
110 | CFHTTPMessageSetBody(message, (__bridge CFDataRef)body);
111 | }
112 |
113 | @end
114 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Mime/MultipartFormDataParser.h:
--------------------------------------------------------------------------------
1 |
2 | #import "MultipartMessageHeader.h"
3 |
4 | /*
5 | Part one: http://tools.ietf.org/html/rfc2045 (Format of Internet Message Bodies)
6 | Part two: http://tools.ietf.org/html/rfc2046 (Media Types)
7 | Part three: http://tools.ietf.org/html/rfc2047 (Message Header Extensions for Non-ASCII Text)
8 | Part four: http://tools.ietf.org/html/rfc4289 (Registration Procedures)
9 | Part five: http://tools.ietf.org/html/rfc2049 (Conformance Criteria and Examples)
10 |
11 | Internet message format: http://tools.ietf.org/html/rfc2822
12 |
13 | Multipart/form-data http://tools.ietf.org/html/rfc2388
14 | */
15 |
16 | @class MultipartFormDataParser;
17 |
18 | //-----------------------------------------------------------------
19 | // protocol MultipartFormDataParser
20 | //-----------------------------------------------------------------
21 |
22 | @protocol MultipartFormDataParserDelegate
23 | @optional
24 | - (void) processContent:(NSData*) data WithHeader:(MultipartMessageHeader*) header;
25 | - (void) processEndOfPartWithHeader:(MultipartMessageHeader*) header;
26 | - (void) processPreambleData:(NSData*) data;
27 | - (void) processEpilogueData:(NSData*) data;
28 | - (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header;
29 | @end
30 |
31 | //-----------------------------------------------------------------
32 | // interface MultipartFormDataParser
33 | //-----------------------------------------------------------------
34 |
35 | @interface MultipartFormDataParser : NSObject {
36 | NSMutableData* pendingData;
37 | NSData* boundaryData;
38 | MultipartMessageHeader* currentHeader;
39 |
40 | BOOL waitingForCRLF;
41 | BOOL reachedEpilogue;
42 | BOOL processedPreamble;
43 | BOOL checkForContentEnd;
44 |
45 | #if __has_feature(objc_arc_weak)
46 | __weak id delegate;
47 | #else
48 | __unsafe_unretained id delegate;
49 | #endif
50 | int currentEncoding;
51 | NSStringEncoding formEncoding;
52 | }
53 |
54 | - (BOOL) appendData:(NSData*) data;
55 |
56 | - (id) initWithBoundary:(NSString*) boundary formEncoding:(NSStringEncoding) formEncoding;
57 |
58 | #if __has_feature(objc_arc_weak)
59 | @property(weak, readwrite) id delegate;
60 | #else
61 | @property(unsafe_unretained, readwrite) id delegate;
62 | #endif
63 | @property(readwrite) NSStringEncoding formEncoding;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // MultipartMessagePart.h
3 | // HttpServer
4 | //
5 | // Created by Валерий Гаврилов on 29.03.12.
6 | // Copyright (c) 2012 LLC "Online Publishing Partners" (onlinepp.ru). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | //-----------------------------------------------------------------
13 | // interface MultipartMessageHeader
14 | //-----------------------------------------------------------------
15 | enum {
16 | contentTransferEncoding_unknown,
17 | contentTransferEncoding_7bit,
18 | contentTransferEncoding_8bit,
19 | contentTransferEncoding_binary,
20 | contentTransferEncoding_base64,
21 | contentTransferEncoding_quotedPrintable,
22 | };
23 |
24 | @interface MultipartMessageHeader : NSObject {
25 | NSMutableDictionary* fields;
26 | int encoding;
27 | NSString* contentDispositionName;
28 | }
29 | @property (strong,readonly) NSDictionary* fields;
30 | @property (readonly) int encoding;
31 |
32 | - (id) initWithData:(NSData*) data formEncoding:(NSStringEncoding) encoding;
33 | @end
34 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeader.m:
--------------------------------------------------------------------------------
1 | //
2 | // MultipartMessagePart.m
3 | // HttpServer
4 | //
5 | // Created by Валерий Гаврилов on 29.03.12.
6 | // Copyright (c) 2012 LLC "Online Publishing Partners" (onlinepp.ru). All rights reserved.
7 |
8 | #import "MultipartMessageHeader.h"
9 | #import "MultipartMessageHeaderField.h"
10 |
11 | #import "HTTPLogging.h"
12 |
13 | //-----------------------------------------------------------------
14 | #pragma mark log level
15 |
16 | #ifdef DEBUG
17 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN;
18 | #else
19 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN;
20 | #endif
21 |
22 | //-----------------------------------------------------------------
23 | // implementation MultipartMessageHeader
24 | //-----------------------------------------------------------------
25 |
26 |
27 | @implementation MultipartMessageHeader
28 | @synthesize fields,encoding;
29 |
30 |
31 | - (id) initWithData:(NSData *)data formEncoding:(NSStringEncoding) formEncoding {
32 | if( nil == (self = [super init]) ) {
33 | return self;
34 | }
35 |
36 | fields = [[NSMutableDictionary alloc] initWithCapacity:1];
37 |
38 | // In case encoding is not mentioned,
39 | encoding = contentTransferEncoding_unknown;
40 |
41 | char* bytes = (char*)data.bytes;
42 | NSUInteger length = data.length;
43 | int offset = 0;
44 |
45 | // split header into header fields, separated by \r\n
46 | uint16_t fields_separator = 0x0A0D; // \r\n
47 | while( offset < length - 2 ) {
48 |
49 | // the !isspace condition is to support header unfolding
50 | if( (*(uint16_t*) (bytes+offset) == fields_separator) && ((offset == length - 2) || !(isspace(bytes[offset+2])) )) {
51 | NSData* fieldData = [NSData dataWithBytesNoCopy:bytes length:offset freeWhenDone:NO];
52 | MultipartMessageHeaderField* field = [[MultipartMessageHeaderField alloc] initWithData: fieldData contentEncoding:formEncoding];
53 | if( field ) {
54 | [fields setObject:field forKey:field.name];
55 | HTTPLogVerbose(@"MultipartFormDataParser: Processed Header field '%@'",field.name);
56 | }
57 | else {
58 | NSString* fieldStr = [[NSString alloc] initWithData:fieldData encoding:NSASCIIStringEncoding];
59 | HTTPLogWarn(@"MultipartFormDataParser: Failed to parse MIME header field. Input ASCII string:%@",fieldStr);
60 | }
61 |
62 | // move to the next header field
63 | bytes += offset + 2;
64 | length -= offset + 2;
65 | offset = 0;
66 | continue;
67 | }
68 | ++ offset;
69 | }
70 |
71 | if( !fields.count ) {
72 | // it was an empty header.
73 | // we have to set default values.
74 | // default header.
75 | [fields setObject:@"text/plain" forKey:@"Content-Type"];
76 | }
77 |
78 | return self;
79 | }
80 |
81 | - (NSString *)description {
82 | return [NSString stringWithFormat:@"%@",fields];
83 | }
84 |
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeaderField.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | //-----------------------------------------------------------------
5 | // interface MultipartMessageHeaderField
6 | //-----------------------------------------------------------------
7 |
8 | @interface MultipartMessageHeaderField : NSObject {
9 | NSString* name;
10 | NSString* value;
11 | NSMutableDictionary* params;
12 | }
13 |
14 | @property (strong, readonly) NSString* value;
15 | @property (strong, readonly) NSDictionary* params;
16 | @property (strong, readonly) NSString* name;
17 |
18 | //- (id) initWithLine:(NSString*) line;
19 | //- (id) initWithName:(NSString*) paramName value:(NSString*) paramValue;
20 |
21 | - (id) initWithData:(NSData*) data contentEncoding:(NSStringEncoding) encoding;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeaderField.m:
--------------------------------------------------------------------------------
1 |
2 | #import "MultipartMessageHeaderField.h"
3 | #import "HTTPLogging.h"
4 |
5 | //-----------------------------------------------------------------
6 | #pragma mark log level
7 |
8 | #ifdef DEBUG
9 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN;
10 | #else
11 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN;
12 | #endif
13 |
14 |
15 | // helpers
16 | int findChar(const char* str,NSUInteger length, char c);
17 | NSString* extractParamValue(const char* bytes, NSUInteger length, NSStringEncoding encoding);
18 |
19 | //-----------------------------------------------------------------
20 | // interface MultipartMessageHeaderField (private)
21 | //-----------------------------------------------------------------
22 |
23 |
24 | @interface MultipartMessageHeaderField (private)
25 | -(BOOL) parseHeaderValueBytes:(char*) bytes length:(NSUInteger) length encoding:(NSStringEncoding) encoding;
26 | @end
27 |
28 |
29 | //-----------------------------------------------------------------
30 | // implementation MultipartMessageHeaderField
31 | //-----------------------------------------------------------------
32 |
33 | @implementation MultipartMessageHeaderField
34 | @synthesize name,value,params;
35 |
36 | - (id) initWithData:(NSData *)data contentEncoding:(NSStringEncoding)encoding {
37 | params = [[NSMutableDictionary alloc] initWithCapacity:1];
38 |
39 | char* bytes = (char*)data.bytes;
40 | NSUInteger length = data.length;
41 |
42 | int separatorOffset = findChar(bytes, length, ':');
43 | if( (-1 == separatorOffset) || (separatorOffset >= length-2) ) {
44 | HTTPLogError(@"MultipartFormDataParser: Bad format.No colon in field header.");
45 | // tear down
46 | return nil;
47 | }
48 |
49 | // header name is always ascii encoded;
50 | name = [[NSString alloc] initWithBytes: bytes length: separatorOffset encoding: NSASCIIStringEncoding];
51 | if( nil == name ) {
52 | HTTPLogError(@"MultipartFormDataParser: Bad MIME header name.");
53 | // tear down
54 | return nil;
55 | }
56 |
57 | // skip the separator and the next ' ' symbol
58 | bytes += separatorOffset + 2;
59 | length -= separatorOffset + 2;
60 |
61 | separatorOffset = findChar(bytes, length, ';');
62 | if( separatorOffset == -1 ) {
63 | // couldn't find ';', means we don't have extra params here.
64 | value = [[NSString alloc] initWithBytes:bytes length: length encoding:encoding];
65 |
66 | if( nil == value ) {
67 | HTTPLogError(@"MultipartFormDataParser: Bad MIME header value for header name: '%@'",name);
68 | // tear down
69 | return nil;
70 | }
71 | return self;
72 | }
73 |
74 | value = [[NSString alloc] initWithBytes:bytes length: separatorOffset encoding:encoding];
75 | HTTPLogVerbose(@"MultipartFormDataParser: Processing header field '%@' : '%@'",name,value);
76 | // skipe the separator and the next ' ' symbol
77 | bytes += separatorOffset + 2;
78 | length -= separatorOffset + 2;
79 |
80 | // parse the "params" part of the header
81 | if( ![self parseHeaderValueBytes:bytes length:length encoding:encoding] ) {
82 | NSString* paramsStr = [[NSString alloc] initWithBytes:bytes length:length encoding:NSASCIIStringEncoding];
83 | HTTPLogError(@"MultipartFormDataParser: Bad params for header with name '%@' and value '%@'",name,value);
84 | HTTPLogError(@"MultipartFormDataParser: Params str: %@",paramsStr);
85 |
86 | return nil;
87 | }
88 | return self;
89 | }
90 |
91 | -(BOOL) parseHeaderValueBytes:(char*) bytes length:(NSUInteger) length encoding:(NSStringEncoding) encoding {
92 | int offset = 0;
93 | NSString* currentParam = nil;
94 | BOOL insideQuote = NO;
95 | while( offset < length ) {
96 | if( bytes[offset] == '\"' ) {
97 | if( !offset || bytes[offset-1] != '\\' ) {
98 | insideQuote = !insideQuote;
99 | }
100 | }
101 |
102 | // skip quoted symbols
103 | if( insideQuote ) {
104 | ++ offset;
105 | continue;
106 | }
107 | if( bytes[offset] == '=' ) {
108 | if( currentParam ) {
109 | // found '=' before terminating previous param.
110 | return NO;
111 | }
112 | currentParam = [[NSString alloc] initWithBytes:bytes length:offset encoding:NSASCIIStringEncoding];
113 |
114 | bytes+=offset + 1;
115 | length -= offset + 1;
116 | offset = 0;
117 | continue;
118 | }
119 | if( bytes[offset] == ';' ) {
120 | if( !currentParam ) {
121 | // found ; before stating '='.
122 | HTTPLogError(@"MultipartFormDataParser: Unexpected ';' when parsing header");
123 | return NO;
124 | }
125 | NSString* paramValue = extractParamValue(bytes, offset,encoding);
126 | if( nil == paramValue ) {
127 | HTTPLogWarn(@"MultipartFormDataParser: Failed to exctract paramValue for key %@ in header %@",currentParam,name);
128 | }
129 | else {
130 | #ifdef DEBUG
131 | if( [params objectForKey:currentParam] ) {
132 | HTTPLogWarn(@"MultipartFormDataParser: param %@ mentioned more then once in header %@",currentParam,name);
133 | }
134 | #endif
135 | [params setObject:paramValue forKey:currentParam];
136 | HTTPLogVerbose(@"MultipartFormDataParser: header param: %@ = %@",currentParam,paramValue);
137 | }
138 |
139 | currentParam = nil;
140 |
141 | // ';' separator has ' ' following, skip them.
142 | bytes+=offset + 2;
143 | length -= offset + 2;
144 | offset = 0;
145 | }
146 | ++ offset;
147 | }
148 |
149 | // add last param
150 | if( insideQuote ) {
151 | HTTPLogWarn(@"MultipartFormDataParser: unterminated quote in header %@",name);
152 | // return YES;
153 | }
154 | if( currentParam ) {
155 | NSString* paramValue = extractParamValue(bytes, length, encoding);
156 |
157 | if( nil == paramValue ) {
158 | HTTPLogError(@"MultipartFormDataParser: Failed to exctract paramValue for key %@ in header %@",currentParam,name);
159 | }
160 |
161 | #ifdef DEBUG
162 | if( [params objectForKey:currentParam] ) {
163 | HTTPLogWarn(@"MultipartFormDataParser: param %@ mentioned more then once in one header",currentParam);
164 | }
165 | #endif
166 | [params setObject:paramValue forKey:currentParam];
167 | HTTPLogVerbose(@"MultipartFormDataParser: header param: %@ = %@",currentParam,paramValue);
168 | currentParam = nil;
169 | }
170 |
171 | return YES;
172 | }
173 |
174 | - (NSString *)description {
175 | return [NSString stringWithFormat:@"%@:%@\n params: %@",name,value,params];
176 | }
177 |
178 | @end
179 |
180 | int findChar(const char* str, NSUInteger length, char c) {
181 | int offset = 0;
182 | while( offset < length ) {
183 | if( str[offset] == c )
184 | return offset;
185 | ++ offset;
186 | }
187 | return -1;
188 | }
189 |
190 | NSString* extractParamValue(const char* bytes, NSUInteger length, NSStringEncoding encoding) {
191 | if( !length )
192 | return nil;
193 | NSMutableString* value = nil;
194 |
195 | if( bytes[0] == '"' ) {
196 | // values may be quoted. Strip the quotes to get what we need.
197 | value = [[NSMutableString alloc] initWithBytes:bytes + 1 length: length - 2 encoding:encoding];
198 | }
199 | else {
200 | value = [[NSMutableString alloc] initWithBytes:bytes length: length encoding:encoding];
201 | }
202 | // restore escaped symbols
203 | NSRange range= [value rangeOfString:@"\\"];
204 | while ( range.length ) {
205 | [value deleteCharactersInRange:range];
206 | range.location ++;
207 | range = [value rangeOfString:@"\\" options:NSLiteralSearch range: range];
208 | }
209 | return value;
210 | }
211 |
212 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPAsyncFileResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 | @class HTTPConnection;
5 |
6 | /**
7 | * This is an asynchronous version of HTTPFileResponse.
8 | * It reads data from the given file asynchronously via GCD.
9 | *
10 | * It may be overriden to allow custom post-processing of the data that has been read from the file.
11 | * An example of this is the HTTPDynamicFileResponse class.
12 | **/
13 |
14 | @interface HTTPAsyncFileResponse : NSObject
15 | {
16 | HTTPConnection *connection;
17 |
18 | NSString *filePath;
19 | UInt64 fileLength;
20 | UInt64 fileOffset; // File offset as pertains to data given to connection
21 | UInt64 readOffset; // File offset as pertains to data read from file (but maybe not returned to connection)
22 |
23 | BOOL aborted;
24 |
25 | NSData *data;
26 |
27 | int fileFD;
28 | void *readBuffer;
29 | NSUInteger readBufferSize; // Malloced size of readBuffer
30 | NSUInteger readBufferOffset; // Offset within readBuffer where the end of existing data is
31 | NSUInteger readRequestLength;
32 | dispatch_queue_t readQueue;
33 | dispatch_source_t readSource;
34 | BOOL readSourceSuspended;
35 | }
36 |
37 | - (id)initWithFilePath:(NSString *)filePath forConnection:(HTTPConnection *)connection;
38 | - (NSString *)filePath;
39 |
40 | @end
41 |
42 | /**
43 | * Explanation of Variables (excluding those that are obvious)
44 | *
45 | * fileOffset
46 | * This is the number of bytes that have been returned to the connection via the readDataOfLength method.
47 | * If 1KB of data has been read from the file, but none of that data has yet been returned to the connection,
48 | * then the fileOffset variable remains at zero.
49 | * This variable is used in the calculation of the isDone method.
50 | * Only after all data has been returned to the connection are we actually done.
51 | *
52 | * readOffset
53 | * Represents the offset of the file descriptor.
54 | * In other words, the file position indidcator for our read stream.
55 | * It might be easy to think of it as the total number of bytes that have been read from the file.
56 | * However, this isn't entirely accurate, as the setOffset: method may have caused us to
57 | * jump ahead in the file (lseek).
58 | *
59 | * readBuffer
60 | * Malloc'd buffer to hold data read from the file.
61 | *
62 | * readBufferSize
63 | * Total allocation size of malloc'd buffer.
64 | *
65 | * readBufferOffset
66 | * Represents the position in the readBuffer where we should store new bytes.
67 | *
68 | * readRequestLength
69 | * The total number of bytes that were requested from the connection.
70 | * It's OK if we return a lesser number of bytes to the connection.
71 | * It's NOT OK if we return a greater number of bytes to the connection.
72 | * Doing so would disrupt proper support for range requests.
73 | * If, however, the response is chunked then we don't need to worry about this.
74 | * Chunked responses inheritly don't support range requests.
75 | **/
76 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPDataResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 |
5 | @interface HTTPDataResponse : NSObject
6 | {
7 | NSUInteger offset;
8 | NSData *data;
9 | }
10 |
11 | - (id)initWithData:(NSData *)data;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPDataResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPDataResponse.h"
2 | #import "HTTPLogging.h"
3 |
4 | #if ! __has_feature(objc_arc)
5 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6 | #endif
7 |
8 | // Log levels : off, error, warn, info, verbose
9 | // Other flags: trace
10 | static const int httpLogLevel = HTTP_LOG_LEVEL_OFF; // | HTTP_LOG_FLAG_TRACE;
11 |
12 |
13 | @implementation HTTPDataResponse
14 |
15 | - (id)initWithData:(NSData *)dataParam
16 | {
17 | if((self = [super init]))
18 | {
19 | HTTPLogTrace();
20 |
21 | offset = 0;
22 | data = dataParam;
23 | }
24 | return self;
25 | }
26 |
27 | - (void)dealloc
28 | {
29 | HTTPLogTrace();
30 |
31 | }
32 |
33 | - (UInt64)contentLength
34 | {
35 | UInt64 result = (UInt64)[data length];
36 |
37 | HTTPLogTrace2(@"%@[%p]: contentLength - %llu", THIS_FILE, self, result);
38 |
39 | return result;
40 | }
41 |
42 | - (UInt64)offset
43 | {
44 | HTTPLogTrace();
45 |
46 | return offset;
47 | }
48 |
49 | - (void)setOffset:(UInt64)offsetParam
50 | {
51 | HTTPLogTrace2(@"%@[%p]: setOffset:%lu", THIS_FILE, self, (unsigned long)offset);
52 |
53 | offset = (NSUInteger)offsetParam;
54 | }
55 |
56 | - (NSData *)readDataOfLength:(NSUInteger)lengthParameter
57 | {
58 | HTTPLogTrace2(@"%@[%p]: readDataOfLength:%lu", THIS_FILE, self, (unsigned long)lengthParameter);
59 |
60 | NSUInteger remaining = [data length] - offset;
61 | NSUInteger length = lengthParameter < remaining ? lengthParameter : remaining;
62 |
63 | void *bytes = (void *)([data bytes] + offset);
64 |
65 | offset += length;
66 |
67 | return [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:NO];
68 | }
69 |
70 | - (BOOL)isDone
71 | {
72 | BOOL result = (offset == [data length]);
73 |
74 | HTTPLogTrace2(@"%@[%p]: isDone - %@", THIS_FILE, self, (result ? @"YES" : @"NO"));
75 |
76 | return result;
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPDynamicFileResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 | #import "HTTPAsyncFileResponse.h"
4 |
5 | /**
6 | * This class is designed to assist with dynamic content.
7 | * Imagine you have a file that you want to make dynamic:
8 | *
9 | *
10 | *
11 | * ComputerName Control Panel
12 | * ...
13 | * System Time: SysTime
14 | *
15 | *
16 | *
17 | * Now you could generate the entire file in Objective-C,
18 | * but this would be a horribly tedious process.
19 | * Beside, you want to design the file with professional tools to make it look pretty.
20 | *
21 | * So all you have to do is escape your dynamic content like this:
22 | *
23 | * ...
24 | * %%ComputerName%% Control Panel
25 | * ...
26 | * System Time: %%SysTime%%
27 | *
28 | * And then you create an instance of this class with:
29 | *
30 | * - separator = @"%%"
31 | * - replacementDictionary = { "ComputerName"="Black MacBook", "SysTime"="2010-04-30 03:18:24" }
32 | *
33 | * This class will then perform the replacements for you, on the fly, as it reads the file data.
34 | * This class is also asynchronous, so it will perform the file IO using its own GCD queue.
35 | *
36 | * All keys for the replacementDictionary must be NSString's.
37 | * Values for the replacementDictionary may be NSString's, or any object that
38 | * returns what you want when its description method is invoked.
39 | **/
40 |
41 | @interface HTTPDynamicFileResponse : HTTPAsyncFileResponse
42 | {
43 | NSData *separator;
44 | NSDictionary *replacementDict;
45 | }
46 |
47 | - (id)initWithFilePath:(NSString *)filePath
48 | forConnection:(HTTPConnection *)connection
49 | separator:(NSString *)separatorStr
50 | replacementDictionary:(NSDictionary *)dictionary;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPErrorResponse.h:
--------------------------------------------------------------------------------
1 | #import "HTTPResponse.h"
2 |
3 | @interface HTTPErrorResponse : NSObject {
4 | NSInteger _status;
5 | }
6 |
7 | - (id)initWithErrorCode:(int)httpErrorCode;
8 |
9 | @end
10 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPErrorResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPErrorResponse.h"
2 |
3 | @implementation HTTPErrorResponse
4 |
5 | -(id)initWithErrorCode:(int)httpErrorCode
6 | {
7 | if ((self = [super init]))
8 | {
9 | _status = httpErrorCode;
10 | }
11 |
12 | return self;
13 | }
14 |
15 | - (UInt64) contentLength {
16 | return 0;
17 | }
18 |
19 | - (UInt64) offset {
20 | return 0;
21 | }
22 |
23 | - (void)setOffset:(UInt64)offset {
24 | ;
25 | }
26 |
27 | - (NSData*) readDataOfLength:(NSUInteger)length {
28 | return nil;
29 | }
30 |
31 | - (BOOL) isDone {
32 | return YES;
33 | }
34 |
35 | - (NSInteger) status {
36 | return _status;
37 | }
38 | @end
39 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPFileResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 | @class HTTPConnection;
5 |
6 |
7 | @interface HTTPFileResponse : NSObject
8 | {
9 | HTTPConnection *connection;
10 |
11 | NSString *filePath;
12 | UInt64 fileLength;
13 | UInt64 fileOffset;
14 |
15 | BOOL aborted;
16 |
17 | int fileFD;
18 | void *buffer;
19 | NSUInteger bufferSize;
20 | }
21 |
22 | - (id)initWithFilePath:(NSString *)filePath forConnection:(HTTPConnection *)connection;
23 | - (NSString *)filePath;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPFileResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPFileResponse.h"
2 | #import "HTTPConnection.h"
3 | #import "HTTPLogging.h"
4 |
5 | #import
6 | #import
7 |
8 | #if ! __has_feature(objc_arc)
9 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
10 | #endif
11 |
12 | // Log levels : off, error, warn, info, verbose
13 | // Other flags: trace
14 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN; // | HTTP_LOG_FLAG_TRACE;
15 |
16 | #define NULL_FD -1
17 |
18 |
19 | @implementation HTTPFileResponse
20 |
21 | - (id)initWithFilePath:(NSString *)fpath forConnection:(HTTPConnection *)parent
22 | {
23 | if((self = [super init]))
24 | {
25 | HTTPLogTrace();
26 |
27 | connection = parent; // Parents retain children, children do NOT retain parents
28 |
29 | fileFD = NULL_FD;
30 | filePath = [[fpath copy] stringByResolvingSymlinksInPath];
31 | if (filePath == nil)
32 | {
33 | HTTPLogWarn(@"%@: Init failed - Nil filePath", THIS_FILE);
34 |
35 | return nil;
36 | }
37 |
38 | NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
39 | if (fileAttributes == nil)
40 | {
41 | HTTPLogWarn(@"%@: Init failed - Unable to get file attributes. filePath: %@", THIS_FILE, filePath);
42 |
43 | return nil;
44 | }
45 |
46 | fileLength = (UInt64)[[fileAttributes objectForKey:NSFileSize] unsignedLongLongValue];
47 | fileOffset = 0;
48 |
49 | aborted = NO;
50 |
51 | // We don't bother opening the file here.
52 | // If this is a HEAD request we only need to know the fileLength.
53 | }
54 | return self;
55 | }
56 |
57 | - (void)abort
58 | {
59 | HTTPLogTrace();
60 |
61 | [connection responseDidAbort:self];
62 | aborted = YES;
63 | }
64 |
65 | - (BOOL)openFile
66 | {
67 | HTTPLogTrace();
68 |
69 | fileFD = open([filePath UTF8String], O_RDONLY);
70 | if (fileFD == NULL_FD)
71 | {
72 | HTTPLogError(@"%@[%p]: Unable to open file. filePath: %@", THIS_FILE, self, filePath);
73 |
74 | [self abort];
75 | return NO;
76 | }
77 |
78 | HTTPLogVerbose(@"%@[%p]: Open fd[%i] -> %@", THIS_FILE, self, fileFD, filePath);
79 |
80 | return YES;
81 | }
82 |
83 | - (BOOL)openFileIfNeeded
84 | {
85 | if (aborted)
86 | {
87 | // The file operation has been aborted.
88 | // This could be because we failed to open the file,
89 | // or the reading process failed.
90 | return NO;
91 | }
92 |
93 | if (fileFD != NULL_FD)
94 | {
95 | // File has already been opened.
96 | return YES;
97 | }
98 |
99 | return [self openFile];
100 | }
101 |
102 | - (UInt64)contentLength
103 | {
104 | HTTPLogTrace();
105 |
106 | return fileLength;
107 | }
108 |
109 | - (UInt64)offset
110 | {
111 | HTTPLogTrace();
112 |
113 | return fileOffset;
114 | }
115 |
116 | - (void)setOffset:(UInt64)offset
117 | {
118 | HTTPLogTrace2(@"%@[%p]: setOffset:%llu", THIS_FILE, self, offset);
119 |
120 | if (![self openFileIfNeeded])
121 | {
122 | // File opening failed,
123 | // or response has been aborted due to another error.
124 | return;
125 | }
126 |
127 | fileOffset = offset;
128 |
129 | off_t result = lseek(fileFD, (off_t)offset, SEEK_SET);
130 | if (result == -1)
131 | {
132 | HTTPLogError(@"%@[%p]: lseek failed - errno(%i) filePath(%@)", THIS_FILE, self, errno, filePath);
133 |
134 | [self abort];
135 | }
136 | }
137 |
138 | - (NSData *)readDataOfLength:(NSUInteger)length
139 | {
140 | HTTPLogTrace2(@"%@[%p]: readDataOfLength:%lu", THIS_FILE, self, (unsigned long)length);
141 |
142 | if (![self openFileIfNeeded])
143 | {
144 | // File opening failed,
145 | // or response has been aborted due to another error.
146 | return nil;
147 | }
148 |
149 | // Determine how much data we should read.
150 | //
151 | // It is OK if we ask to read more bytes than exist in the file.
152 | // It is NOT OK to over-allocate the buffer.
153 |
154 | UInt64 bytesLeftInFile = fileLength - fileOffset;
155 |
156 | NSUInteger bytesToRead = (NSUInteger)MIN(length, bytesLeftInFile);
157 |
158 | // Make sure buffer is big enough for read request.
159 | // Do not over-allocate.
160 |
161 | if (buffer == NULL || bufferSize < bytesToRead)
162 | {
163 | bufferSize = bytesToRead;
164 | buffer = reallocf(buffer, (size_t)bufferSize);
165 |
166 | if (buffer == NULL)
167 | {
168 | HTTPLogError(@"%@[%p]: Unable to allocate buffer", THIS_FILE, self);
169 |
170 | [self abort];
171 | return nil;
172 | }
173 | }
174 |
175 | // Perform the read
176 |
177 | HTTPLogVerbose(@"%@[%p]: Attempting to read %lu bytes from file", THIS_FILE, self, (unsigned long)bytesToRead);
178 |
179 | ssize_t result = read(fileFD, buffer, bytesToRead);
180 |
181 | // Check the results
182 |
183 | if (result < 0)
184 | {
185 | HTTPLogError(@"%@: Error(%i) reading file(%@)", THIS_FILE, errno, filePath);
186 |
187 | [self abort];
188 | return nil;
189 | }
190 | else if (result == 0)
191 | {
192 | HTTPLogError(@"%@: Read EOF on file(%@)", THIS_FILE, filePath);
193 |
194 | [self abort];
195 | return nil;
196 | }
197 | else // (result > 0)
198 | {
199 | HTTPLogVerbose(@"%@[%p]: Read %ld bytes from file", THIS_FILE, self, (long)result);
200 |
201 | fileOffset += result;
202 |
203 | return [NSData dataWithBytes:buffer length:result];
204 | }
205 | }
206 |
207 | - (BOOL)isDone
208 | {
209 | BOOL result = (fileOffset == fileLength);
210 |
211 | HTTPLogTrace2(@"%@[%p]: isDone - %@", THIS_FILE, self, (result ? @"YES" : @"NO"));
212 |
213 | return result;
214 | }
215 |
216 | - (NSString *)filePath
217 | {
218 | return filePath;
219 | }
220 |
221 | - (void)dealloc
222 | {
223 | HTTPLogTrace();
224 |
225 | if (fileFD != NULL_FD)
226 | {
227 | HTTPLogVerbose(@"%@[%p]: Close fd[%i]", THIS_FILE, self, fileFD);
228 |
229 | close(fileFD);
230 | }
231 |
232 | if (buffer)
233 | free(buffer);
234 |
235 | }
236 |
237 | @end
238 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPRedirectResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 |
5 | @interface HTTPRedirectResponse : NSObject
6 | {
7 | NSString *redirectPath;
8 | }
9 |
10 | - (id)initWithPath:(NSString *)redirectPath;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/Responses/HTTPRedirectResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPRedirectResponse.h"
2 | #import "HTTPLogging.h"
3 |
4 | #if ! __has_feature(objc_arc)
5 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6 | #endif
7 |
8 | // Log levels : off, error, warn, info, verbose
9 | // Other flags: trace
10 | static const int httpLogLevel = HTTP_LOG_LEVEL_OFF; // | HTTP_LOG_FLAG_TRACE;
11 |
12 |
13 | @implementation HTTPRedirectResponse
14 |
15 | - (id)initWithPath:(NSString *)path
16 | {
17 | if ((self = [super init]))
18 | {
19 | HTTPLogTrace();
20 |
21 | redirectPath = [path copy];
22 | }
23 | return self;
24 | }
25 |
26 | - (UInt64)contentLength
27 | {
28 | return 0;
29 | }
30 |
31 | - (UInt64)offset
32 | {
33 | return 0;
34 | }
35 |
36 | - (void)setOffset:(UInt64)offset
37 | {
38 | // Nothing to do
39 | }
40 |
41 | - (NSData *)readDataOfLength:(NSUInteger)length
42 | {
43 | HTTPLogTrace();
44 |
45 | return nil;
46 | }
47 |
48 | - (BOOL)isDone
49 | {
50 | return YES;
51 | }
52 |
53 | - (NSDictionary *)httpHeaders
54 | {
55 | HTTPLogTrace();
56 |
57 | return [NSDictionary dictionaryWithObject:redirectPath forKey:@"Location"];
58 | }
59 |
60 | - (NSInteger)status
61 | {
62 | HTTPLogTrace();
63 |
64 | return 302;
65 | }
66 |
67 | - (void)dealloc
68 | {
69 | HTTPLogTrace();
70 |
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaHTTPServer/WebSocket.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class HTTPMessage;
4 | @class GCDAsyncSocket;
5 |
6 |
7 | #define WebSocketDidDieNotification @"WebSocketDidDie"
8 |
9 | @interface WebSocket : NSObject
10 | {
11 | dispatch_queue_t websocketQueue;
12 |
13 | HTTPMessage *request;
14 | GCDAsyncSocket *asyncSocket;
15 |
16 | NSData *term;
17 |
18 | BOOL isStarted;
19 | BOOL isOpen;
20 | BOOL isVersion76;
21 |
22 | id __unsafe_unretained delegate;
23 | }
24 |
25 | + (BOOL)isWebSocketRequest:(HTTPMessage *)request;
26 |
27 | - (id)initWithRequest:(HTTPMessage *)request socket:(GCDAsyncSocket *)socket;
28 |
29 | /**
30 | * Delegate option.
31 | *
32 | * In most cases it will be easier to subclass WebSocket,
33 | * but some circumstances may lead one to prefer standard delegate callbacks instead.
34 | **/
35 | @property (/* atomic */ unsafe_unretained) id delegate;
36 |
37 | /**
38 | * The WebSocket class is thread-safe, generally via it's GCD queue.
39 | * All public API methods are thread-safe,
40 | * and the subclass API methods are thread-safe as they are all invoked on the same GCD queue.
41 | **/
42 | @property (nonatomic, readonly) dispatch_queue_t websocketQueue;
43 |
44 | /**
45 | * Public API
46 | *
47 | * These methods are automatically called by the HTTPServer.
48 | * You may invoke the stop method yourself to close the WebSocket manually.
49 | **/
50 | - (void)start;
51 | - (void)stop;
52 |
53 | /**
54 | * Public API
55 | *
56 | * Sends a message over the WebSocket.
57 | * This method is thread-safe.
58 | **/
59 | - (void)sendMessage:(NSString *)msg;
60 |
61 | /**
62 | * Public API
63 | *
64 | * Sends a message over the WebSocket.
65 | * This method is thread-safe.
66 | **/
67 | - (void)sendData:(NSData *)msg;
68 |
69 | /**
70 | * Subclass API
71 | *
72 | * These methods are designed to be overriden by subclasses.
73 | **/
74 | - (void)didOpen;
75 | - (void)didReceiveMessage:(NSString *)msg;
76 | - (void)didClose;
77 |
78 | @end
79 |
80 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 | #pragma mark -
82 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
83 |
84 | /**
85 | * There are two ways to create your own custom WebSocket:
86 | *
87 | * - Subclass it and override the methods you're interested in.
88 | * - Use traditional delegate paradigm along with your own custom class.
89 | *
90 | * They both exist to allow for maximum flexibility.
91 | * In most cases it will be easier to subclass WebSocket.
92 | * However some circumstances may lead one to prefer standard delegate callbacks instead.
93 | * One such example, you're already subclassing another class, so subclassing WebSocket isn't an option.
94 | **/
95 |
96 | @protocol WebSocketDelegate
97 | @optional
98 |
99 | - (void)webSocketDidOpen:(WebSocket *)ws;
100 |
101 | - (void)webSocket:(WebSocket *)ws didReceiveMessage:(NSString *)msg;
102 |
103 | - (void)webSocketDidClose:(WebSocket *)ws;
104 |
105 | @end
106 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/DDASLLogger.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import "DDLog.h"
5 |
6 | /**
7 | * Welcome to Cocoa Lumberjack!
8 | *
9 | * The project page has a wealth of documentation if you have any questions.
10 | * https://github.com/robbiehanson/CocoaLumberjack
11 | *
12 | * If you're new to the project you may wish to read the "Getting Started" wiki.
13 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
14 | *
15 | *
16 | * This class provides a logger for the Apple System Log facility.
17 | *
18 | * As described in the "Getting Started" page,
19 | * the traditional NSLog() function directs it's output to two places:
20 | *
21 | * - Apple System Log
22 | * - StdErr (if stderr is a TTY) so log statements show up in Xcode console
23 | *
24 | * To duplicate NSLog() functionality you can simply add this logger and a tty logger.
25 | * However, if you instead choose to use file logging (for faster performance),
26 | * you may choose to use a file logger and a tty logger.
27 | **/
28 |
29 | @interface DDASLLogger : DDAbstractLogger
30 | {
31 | aslclient client;
32 | }
33 |
34 | + (DDASLLogger *)sharedInstance;
35 |
36 | // Inherited from DDAbstractLogger
37 |
38 | // - (id )logFormatter;
39 | // - (void)setLogFormatter:(id )formatter;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/DDASLLogger.m:
--------------------------------------------------------------------------------
1 | #import "DDASLLogger.h"
2 |
3 | #import
4 |
5 | /**
6 | * Welcome to Cocoa Lumberjack!
7 | *
8 | * The project page has a wealth of documentation if you have any questions.
9 | * https://github.com/robbiehanson/CocoaLumberjack
10 | *
11 | * If you're new to the project you may wish to read the "Getting Started" wiki.
12 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
13 | **/
14 |
15 | #if ! __has_feature(objc_arc)
16 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
17 | #endif
18 |
19 |
20 | @implementation DDASLLogger
21 |
22 | static DDASLLogger *sharedInstance;
23 |
24 | /**
25 | * The runtime sends initialize to each class in a program exactly one time just before the class,
26 | * or any class that inherits from it, is sent its first message from within the program. (Thus the
27 | * method may never be invoked if the class is not used.) The runtime sends the initialize message to
28 | * classes in a thread-safe manner. Superclasses receive this message before their subclasses.
29 | *
30 | * This method may also be called directly (assumably by accident), hence the safety mechanism.
31 | **/
32 | + (void)initialize
33 | {
34 | static BOOL initialized = NO;
35 | if (!initialized)
36 | {
37 | initialized = YES;
38 |
39 | sharedInstance = [[DDASLLogger alloc] init];
40 | }
41 | }
42 |
43 | + (DDASLLogger *)sharedInstance
44 | {
45 | return sharedInstance;
46 | }
47 |
48 | - (id)init
49 | {
50 | if (sharedInstance != nil)
51 | {
52 | return nil;
53 | }
54 |
55 | if ((self = [super init]))
56 | {
57 | // A default asl client is provided for the main thread,
58 | // but background threads need to create their own client.
59 |
60 | client = asl_open(NULL, "com.apple.console", 0);
61 | }
62 | return self;
63 | }
64 |
65 | - (void)logMessage:(DDLogMessage *)logMessage
66 | {
67 | NSString *logMsg = logMessage->logMsg;
68 |
69 | if (formatter)
70 | {
71 | logMsg = [formatter formatLogMessage:logMessage];
72 | }
73 |
74 | if (logMsg)
75 | {
76 | const char *msg = [logMsg UTF8String];
77 |
78 | int aslLogLevel;
79 | switch (logMessage->logFlag)
80 | {
81 | // Note: By default ASL will filter anything above level 5 (Notice).
82 | // So our mappings shouldn't go above that level.
83 |
84 | case LOG_FLAG_ERROR : aslLogLevel = ASL_LEVEL_CRIT; break;
85 | case LOG_FLAG_WARN : aslLogLevel = ASL_LEVEL_ERR; break;
86 | case LOG_FLAG_INFO : aslLogLevel = ASL_LEVEL_WARNING; break;
87 | default : aslLogLevel = ASL_LEVEL_NOTICE; break;
88 | }
89 |
90 | asl_log(client, NULL, aslLogLevel, "%s", msg);
91 | }
92 | }
93 |
94 | - (NSString *)loggerName
95 | {
96 | return @"cocoa.lumberjack.aslLogger";
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "DDLog.h"
4 |
5 | /**
6 | * Welcome to Cocoa Lumberjack!
7 | *
8 | * The project page has a wealth of documentation if you have any questions.
9 | * https://github.com/robbiehanson/CocoaLumberjack
10 | *
11 | * If you're new to the project you may wish to read the "Getting Started" wiki.
12 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
13 | *
14 | *
15 | * This class provides an abstract implementation of a database logger.
16 | *
17 | * That is, it provides the base implementation for a database logger to build atop of.
18 | * All that is needed for a concrete database logger is to extend this class
19 | * and override the methods in the implementation file that are prefixed with "db_".
20 | **/
21 |
22 | @interface DDAbstractDatabaseLogger : DDAbstractLogger {
23 | @protected
24 | NSUInteger saveThreshold;
25 | NSTimeInterval saveInterval;
26 | NSTimeInterval maxAge;
27 | NSTimeInterval deleteInterval;
28 | BOOL deleteOnEverySave;
29 |
30 | BOOL saveTimerSuspended;
31 | NSUInteger unsavedCount;
32 | dispatch_time_t unsavedTime;
33 | dispatch_source_t saveTimer;
34 | dispatch_time_t lastDeleteTime;
35 | dispatch_source_t deleteTimer;
36 | }
37 |
38 | /**
39 | * Specifies how often to save the data to disk.
40 | * Since saving is an expensive operation (disk io) it is not done after every log statement.
41 | * These properties allow you to configure how/when the logger saves to disk.
42 | *
43 | * A save is done when either (whichever happens first):
44 | *
45 | * - The number of unsaved log entries reaches saveThreshold
46 | * - The amount of time since the oldest unsaved log entry was created reaches saveInterval
47 | *
48 | * You can optionally disable the saveThreshold by setting it to zero.
49 | * If you disable the saveThreshold you are entirely dependent on the saveInterval.
50 | *
51 | * You can optionally disable the saveInterval by setting it to zero (or a negative value).
52 | * If you disable the saveInterval you are entirely dependent on the saveThreshold.
53 | *
54 | * It's not wise to disable both saveThreshold and saveInterval.
55 | *
56 | * The default saveThreshold is 500.
57 | * The default saveInterval is 60 seconds.
58 | **/
59 | @property (assign, readwrite) NSUInteger saveThreshold;
60 | @property (assign, readwrite) NSTimeInterval saveInterval;
61 |
62 | /**
63 | * It is likely you don't want the log entries to persist forever.
64 | * Doing so would allow the database to grow infinitely large over time.
65 | *
66 | * The maxAge property provides a way to specify how old a log statement can get
67 | * before it should get deleted from the database.
68 | *
69 | * The deleteInterval specifies how often to sweep for old log entries.
70 | * Since deleting is an expensive operation (disk io) is is done on a fixed interval.
71 | *
72 | * An alternative to the deleteInterval is the deleteOnEverySave option.
73 | * This specifies that old log entries should be deleted during every save operation.
74 | *
75 | * You can optionally disable the maxAge by setting it to zero (or a negative value).
76 | * If you disable the maxAge then old log statements are not deleted.
77 | *
78 | * You can optionally disable the deleteInterval by setting it to zero (or a negative value).
79 | *
80 | * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted.
81 | *
82 | * It's not wise to enable both deleteInterval and deleteOnEverySave.
83 | *
84 | * The default maxAge is 7 days.
85 | * The default deleteInterval is 5 minutes.
86 | * The default deleteOnEverySave is NO.
87 | **/
88 | @property (assign, readwrite) NSTimeInterval maxAge;
89 | @property (assign, readwrite) NSTimeInterval deleteInterval;
90 | @property (assign, readwrite) BOOL deleteOnEverySave;
91 |
92 | /**
93 | * Forces a save of any pending log entries (flushes log entries to disk).
94 | **/
95 | - (void)savePendingLogEntries;
96 |
97 | /**
98 | * Removes any log entries that are older than maxAge.
99 | **/
100 | - (void)deleteOldLogEntries;
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/DDTTYLogger.h:
--------------------------------------------------------------------------------
1 | #import
2 | #if TARGET_OS_IPHONE
3 | #import
4 | #else
5 | #import
6 | #endif
7 |
8 | #import "DDLog.h"
9 |
10 | /**
11 | * Welcome to Cocoa Lumberjack!
12 | *
13 | * The project page has a wealth of documentation if you have any questions.
14 | * https://github.com/robbiehanson/CocoaLumberjack
15 | *
16 | * If you're new to the project you may wish to read the "Getting Started" wiki.
17 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
18 | *
19 | *
20 | * This class provides a logger for Terminal output or Xcode console output,
21 | * depending on where you are running your code.
22 | *
23 | * As described in the "Getting Started" page,
24 | * the traditional NSLog() function directs it's output to two places:
25 | *
26 | * - Apple System Log (so it shows up in Console.app)
27 | * - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
28 | *
29 | * To duplicate NSLog() functionality you can simply add this logger and an asl logger.
30 | * However, if you instead choose to use file logging (for faster performance),
31 | * you may choose to use only a file logger and a tty logger.
32 | **/
33 |
34 | @interface DDTTYLogger : DDAbstractLogger
35 | {
36 | NSCalendar *calendar;
37 | NSUInteger calendarUnitFlags;
38 |
39 | NSString *appName;
40 | char *app;
41 | size_t appLen;
42 |
43 | NSString *processID;
44 | char *pid;
45 | size_t pidLen;
46 |
47 | BOOL colorsEnabled;
48 | NSMutableArray *colorProfilesArray;
49 | NSMutableDictionary *colorProfilesDict;
50 | }
51 |
52 | + (DDTTYLogger *)sharedInstance;
53 |
54 | /* Inherited from the DDLogger protocol:
55 | *
56 | * Formatters may optionally be added to any logger.
57 | *
58 | * If no formatter is set, the logger simply logs the message as it is given in logMessage,
59 | * or it may use its own built in formatting style.
60 | *
61 | * More information about formatters can be found here:
62 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
63 | *
64 | * The actual implementation of these methods is inherited from DDAbstractLogger.
65 |
66 | - (id )logFormatter;
67 | - (void)setLogFormatter:(id )formatter;
68 |
69 | */
70 |
71 | /**
72 | * Want to use different colors for different log levels?
73 | * Enable this property.
74 | *
75 | * If you run the application via the Terminal (not Xcode),
76 | * the logger will map colors to xterm-256color or xterm-color (if available).
77 | *
78 | * Xcode does NOT natively support colors in the Xcode debugging console.
79 | * You'll need to install the XcodeColors plugin to see colors in the Xcode console.
80 | * https://github.com/robbiehanson/XcodeColors
81 | *
82 | * The default value if NO.
83 | **/
84 | @property (readwrite, assign) BOOL colorsEnabled;
85 |
86 | /**
87 | * The default color set (foregroundColor, backgroundColor) is:
88 | *
89 | * - LOG_FLAG_ERROR = (red, nil)
90 | * - LOG_FLAG_WARN = (orange, nil)
91 | *
92 | * You can customize the colors however you see fit.
93 | * Please note that you are passing a flag, NOT a level.
94 | *
95 | * GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :)
96 | * BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :(
97 | *
98 | * LOG_FLAG_INFO = 0...00100
99 | * LOG_LEVEL_INFO = 0...00111 <- Would match LOG_FLAG_INFO and LOG_FLAG_WARN and LOG_FLAG_ERROR
100 | *
101 | * If you run the application within Xcode, then the XcodeColors plugin is required.
102 | *
103 | * If you run the application from a shell, then DDTTYLogger will automatically map the given color to
104 | * the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
105 | *
106 | * This method invokes setForegroundColor:backgroundColor:forFlag:context: and passes the default context (0).
107 | **/
108 | #if TARGET_OS_IPHONE
109 | - (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask;
110 | #else
111 | - (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask;
112 | #endif
113 |
114 | /**
115 | * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
116 | *
117 | * A logging context is often used to identify log messages coming from a 3rd party framework,
118 | * although logging context's can be used for many different functions.
119 | *
120 | * Logging context's are explained in further detail here:
121 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext
122 | **/
123 | #if TARGET_OS_IPHONE
124 | - (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask context:(int)ctxt;
125 | #else
126 | - (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask context:(int)ctxt;
127 | #endif
128 |
129 | /**
130 | * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
131 | * For example, you could do something like this:
132 | *
133 | * static NSString *const PurpleTag = @"PurpleTag";
134 | *
135 | * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
136 | *
137 | * And then in your applicationDidFinishLaunching, or wherever you configure Lumberjack:
138 | *
139 | * #if TARGET_OS_IPHONE
140 | * UIColor *purple = [UIColor colorWithRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
141 | * #else
142 | * NSColor *purple = [NSColor colorWithCalibratedRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
143 | *
144 | * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
145 | * [DDLog addLogger:[DDTTYLogger sharedInstance]];
146 | *
147 | * This would essentially give you a straight NSLog replacement that prints in purple:
148 | *
149 | * DDLogPurple(@"I'm a purple log message!");
150 | **/
151 | #if TARGET_OS_IPHONE
152 | - (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forTag:(id )tag;
153 | #else
154 | - (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forTag:(id )tag;
155 | #endif
156 |
157 | /**
158 | * Clearing color profiles.
159 | **/
160 | - (void)clearColorsForFlag:(int)mask;
161 | - (void)clearColorsForFlag:(int)mask context:(int)context;
162 | - (void)clearColorsForTag:(id )tag;
163 | - (void)clearColorsForAllFlags;
164 | - (void)clearColorsForAllTags;
165 | - (void)clearAllColors;
166 |
167 | @end
168 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "DDLog.h"
3 |
4 | @class ContextFilterLogFormatter;
5 |
6 | /**
7 | * Welcome to Cocoa Lumberjack!
8 | *
9 | * The project page has a wealth of documentation if you have any questions.
10 | * https://github.com/robbiehanson/CocoaLumberjack
11 | *
12 | * If you're new to the project you may wish to read the "Getting Started" page.
13 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
14 | *
15 | *
16 | * This class provides a log formatter that filters log statements from a logging context not on the whitelist.
17 | *
18 | * A log formatter can be added to any logger to format and/or filter its output.
19 | * You can learn more about log formatters here:
20 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
21 | *
22 | * You can learn more about logging context's here:
23 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext
24 | *
25 | * But here's a quick overview / refresher:
26 | *
27 | * Every log statement has a logging context.
28 | * These come from the underlying logging macros defined in DDLog.h.
29 | * The default logging context is zero.
30 | * You can define multiple logging context's for use in your application.
31 | * For example, logically separate parts of your app each have a different logging context.
32 | * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context.
33 | **/
34 | @interface ContextWhitelistFilterLogFormatter : NSObject
35 |
36 | - (id)init;
37 |
38 | - (void)addToWhitelist:(int)loggingContext;
39 | - (void)removeFromWhitelist:(int)loggingContext;
40 |
41 | - (NSArray *)whitelist;
42 |
43 | - (BOOL)isOnWhitelist:(int)loggingContext;
44 |
45 | @end
46 |
47 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48 | #pragma mark -
49 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 |
51 | /**
52 | * This class provides a log formatter that filters log statements from a logging context on the blacklist.
53 | **/
54 | @interface ContextBlacklistFilterLogFormatter : NSObject
55 |
56 | - (id)init;
57 |
58 | - (void)addToBlacklist:(int)loggingContext;
59 | - (void)removeFromBlacklist:(int)loggingContext;
60 |
61 | - (NSArray *)blacklist;
62 |
63 | - (BOOL)isOnBlacklist:(int)loggingContext;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.m:
--------------------------------------------------------------------------------
1 | #import "ContextFilterLogFormatter.h"
2 | #import
3 |
4 | /**
5 | * Welcome to Cocoa Lumberjack!
6 | *
7 | * The project page has a wealth of documentation if you have any questions.
8 | * https://github.com/robbiehanson/CocoaLumberjack
9 | *
10 | * If you're new to the project you may wish to read the "Getting Started" wiki.
11 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
12 | **/
13 |
14 | #if ! __has_feature(objc_arc)
15 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
16 | #endif
17 |
18 | @interface LoggingContextSet : NSObject
19 |
20 | - (void)addToSet:(int)loggingContext;
21 | - (void)removeFromSet:(int)loggingContext;
22 |
23 | - (NSArray *)currentSet;
24 |
25 | - (BOOL)isInSet:(int)loggingContext;
26 |
27 | @end
28 |
29 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30 | #pragma mark -
31 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 |
33 | @implementation ContextWhitelistFilterLogFormatter
34 | {
35 | LoggingContextSet *contextSet;
36 | }
37 |
38 | - (id)init
39 | {
40 | if ((self = [super init]))
41 | {
42 | contextSet = [[LoggingContextSet alloc] init];
43 | }
44 | return self;
45 | }
46 |
47 |
48 | - (void)addToWhitelist:(int)loggingContext
49 | {
50 | [contextSet addToSet:loggingContext];
51 | }
52 |
53 | - (void)removeFromWhitelist:(int)loggingContext
54 | {
55 | [contextSet removeFromSet:loggingContext];
56 | }
57 |
58 | - (NSArray *)whitelist
59 | {
60 | return [contextSet currentSet];
61 | }
62 |
63 | - (BOOL)isOnWhitelist:(int)loggingContext
64 | {
65 | return [contextSet isInSet:loggingContext];
66 | }
67 |
68 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage
69 | {
70 | if ([self isOnWhitelist:logMessage->logContext])
71 | return logMessage->logMsg;
72 | else
73 | return nil;
74 | }
75 |
76 | @end
77 |
78 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79 | #pragma mark -
80 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 |
82 | @implementation ContextBlacklistFilterLogFormatter
83 | {
84 | LoggingContextSet *contextSet;
85 | }
86 |
87 | - (id)init
88 | {
89 | if ((self = [super init]))
90 | {
91 | contextSet = [[LoggingContextSet alloc] init];
92 | }
93 | return self;
94 | }
95 |
96 |
97 | - (void)addToBlacklist:(int)loggingContext
98 | {
99 | [contextSet addToSet:loggingContext];
100 | }
101 |
102 | - (void)removeFromBlacklist:(int)loggingContext
103 | {
104 | [contextSet removeFromSet:loggingContext];
105 | }
106 |
107 | - (NSArray *)blacklist
108 | {
109 | return [contextSet currentSet];
110 | }
111 |
112 | - (BOOL)isOnBlacklist:(int)loggingContext
113 | {
114 | return [contextSet isInSet:loggingContext];
115 | }
116 |
117 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage
118 | {
119 | if ([self isOnBlacklist:logMessage->logContext])
120 | return nil;
121 | else
122 | return logMessage->logMsg;
123 | }
124 |
125 | @end
126 |
127 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
128 | #pragma mark -
129 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130 |
131 | @implementation LoggingContextSet
132 | {
133 | OSSpinLock lock;
134 | NSMutableSet *set;
135 | }
136 |
137 | - (id)init
138 | {
139 | if ((self = [super init]))
140 | {
141 | set = [[NSMutableSet alloc] init];
142 | }
143 | return self;
144 | }
145 |
146 |
147 | - (void)addToSet:(int)loggingContext
148 | {
149 | OSSpinLockLock(&lock);
150 | {
151 | [set addObject:@(loggingContext)];
152 | }
153 | OSSpinLockUnlock(&lock);
154 | }
155 |
156 | - (void)removeFromSet:(int)loggingContext
157 | {
158 | OSSpinLockLock(&lock);
159 | {
160 | [set removeObject:@(loggingContext)];
161 | }
162 | OSSpinLockUnlock(&lock);
163 | }
164 |
165 | - (NSArray *)currentSet
166 | {
167 | NSArray *result = nil;
168 |
169 | OSSpinLockLock(&lock);
170 | {
171 | result = [set allObjects];
172 | }
173 | OSSpinLockUnlock(&lock);
174 |
175 | return result;
176 | }
177 |
178 | - (BOOL)isInSet:(int)loggingContext
179 | {
180 | BOOL result = NO;
181 |
182 | OSSpinLockLock(&lock);
183 | {
184 | result = [set containsObject:@(loggingContext)];
185 | }
186 | OSSpinLockUnlock(&lock);
187 |
188 | return result;
189 | }
190 |
191 | @end
192 |
--------------------------------------------------------------------------------
/APN/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "DDLog.h"
4 |
5 |
6 | /**
7 | * Welcome to Cocoa Lumberjack!
8 | *
9 | * The project page has a wealth of documentation if you have any questions.
10 | * https://github.com/robbiehanson/CocoaLumberjack
11 | *
12 | * If you're new to the project you may wish to read the "Getting Started" page.
13 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
14 | *
15 | *
16 | * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id.
17 | *
18 | * A log formatter can be added to any logger to format and/or filter its output.
19 | * You can learn more about log formatters here:
20 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
21 | *
22 | * A typical NSLog (or DDTTYLogger) prints detailed info as [:].
23 | * For example:
24 | *
25 | * 2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here
26 | *
27 | * Where:
28 | * - 19928 = process id
29 | * - 5207 = thread id (mach_thread_id printed in hex)
30 | *
31 | * When using grand central dispatch (GCD), this information is less useful.
32 | * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool.
33 | * For example:
34 | *
35 | * 2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue
36 | * 2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue
37 | * 2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue
38 | *
39 | * This formatter allows you to replace the standard [box:info] with the dispatch_queue name.
40 | * For example:
41 | *
42 | * 2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue
43 | * 2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue
44 | * 2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue
45 | *
46 | * If the dispatch_queue doesn't have a set name, then it falls back to the thread name.
47 | * If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal).
48 | *
49 | * Note: If manually creating your own background threads (via NSThread/alloc/init or NSThread/detachNeThread),
50 | * you can use [[NSThread currentThread] setName:(NSString *)].
51 | **/
52 | @interface DispatchQueueLogFormatter : NSObject {
53 | @protected
54 |
55 | NSString *dateFormatString;
56 | }
57 |
58 | /**
59 | * Standard init method.
60 | * Configure using properties as desired.
61 | **/
62 | - (id)init;
63 |
64 | /**
65 | * The minQueueLength restricts the minimum size of the [detail box].
66 | * If the minQueueLength is set to 0, there is no restriction.
67 | *
68 | * For example, say a dispatch_queue has a label of "diskIO":
69 | *
70 | * If the minQueueLength is 0: [diskIO]
71 | * If the minQueueLength is 4: [diskIO]
72 | * If the minQueueLength is 5: [diskIO]
73 | * If the minQueueLength is 6: [diskIO]
74 | * If the minQueueLength is 7: [diskIO ]
75 | * If the minQueueLength is 8: [diskIO ]
76 | *
77 | * The default minQueueLength is 0 (no minimum, so [detail box] won't be padded).
78 | *
79 | * If you want every [detail box] to have the exact same width,
80 | * set both minQueueLength and maxQueueLength to the same value.
81 | **/
82 | @property (assign) NSUInteger minQueueLength;
83 |
84 | /**
85 | * The maxQueueLength restricts the number of characters that will be inside the [detail box].
86 | * If the maxQueueLength is 0, there is no restriction.
87 | *
88 | * For example, say a dispatch_queue has a label of "diskIO":
89 | *
90 | * If the maxQueueLength is 0: [diskIO]
91 | * If the maxQueueLength is 4: [disk]
92 | * If the maxQueueLength is 5: [diskI]
93 | * If the maxQueueLength is 6: [diskIO]
94 | * If the maxQueueLength is 7: [diskIO]
95 | * If the maxQueueLength is 8: [diskIO]
96 | *
97 | * The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated).
98 | *
99 | * If you want every [detail box] to have the exact same width,
100 | * set both minQueueLength and maxQueueLength to the same value.
101 | **/
102 | @property (assign) NSUInteger maxQueueLength;
103 |
104 | /**
105 | * Sometimes queue labels have long names like "com.apple.main-queue",
106 | * but you'd prefer something shorter like simply "main".
107 | *
108 | * This method allows you to set such preferred replacements.
109 | * The above example is set by default.
110 | *
111 | * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter.
112 | **/
113 | - (NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
114 | - (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
115 |
116 | @end
117 |
--------------------------------------------------------------------------------
/APN/Views/LTAPNCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPNCell.h
3 | // APN
4 | //
5 | // Created by Lex on 11/22/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTAPNCell : UITableViewCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Views/LTAPNCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTAPNCell.m
3 | // APN
4 | //
5 | // Created by Lex on 11/22/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTAPNCell.h"
10 |
11 | @implementation LTAPNCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Views/LTButtonCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTButtonCell.h
3 | // APN
4 | //
5 | // Created by Lex on 11/22/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTButtonCell : UITableViewCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Views/LTButtonCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTButtonCell.m
3 | // APN
4 | //
5 | // Created by Lex on 11/22/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTButtonCell.h"
10 |
11 | @implementation LTButtonCell
12 |
13 | - (id) initWithCoder:(NSCoder *)aDecoder
14 | {
15 | self = [super initWithCoder:aDecoder];
16 | if (self)
17 | {
18 | self.textLabel.font = [UIFont boldSystemFontOfSize:16];
19 | }
20 | return self;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/APN/Views/LTPrimaryButtonCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTPrimaryButtonCell.h
3 | // APN
4 | //
5 | // Created by Lex on 11/25/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTPrimaryButtonCell : UITableViewCell
12 | @property (nonatomic, weak) IBOutlet UIButton *button;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/APN/Views/LTPrimaryButtonCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTPrimaryButtonCell.m
3 | // APN
4 | //
5 | // Created by Lex on 11/25/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTPrimaryButtonCell.h"
10 |
11 | @implementation LTPrimaryButtonCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Views/LTSwitchCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTSwitchCell.h
3 | // APN
4 | //
5 | // Created by Lex on 11/22/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTSwitchCell : UITableViewCell
12 |
13 | @property (nonatomic, weak) IBOutlet UISwitch *switchButton;
14 | @property (nonatomic, weak) IBOutlet UIActivityIndicatorView *activityIndicator;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/APN/Views/LTSwitchCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTSwitchCell.m
3 | // APN
4 | //
5 | // Created by Lex on 11/22/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTSwitchCell.h"
10 |
11 | @implementation LTSwitchCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/APN/Views/LTTextCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTTextCell.h
3 | // APN
4 | //
5 | // Created by Lex on 11/23/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTTextCell : UITableViewCell
12 | @property (nonatomic, assign, getter = isRequired) BOOL required;
13 | @property (nonatomic, weak) IBOutlet UITextField *textField;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/APN/Views/LTTextCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTTextCell.m
3 | // APN
4 | //
5 | // Created by Lex on 11/23/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import "LTTextCell.h"
10 |
11 | @implementation LTTextCell
12 |
13 | - (id) initWithCoder:(NSCoder *)aDecoder
14 | {
15 | self = [super initWithCoder:aDecoder];
16 | if (self)
17 | {
18 | [self.textLabel setFont:[UIFont systemFontOfSize:16]];
19 | self.textLabel.adjustsFontSizeToFitWidth = YES;
20 | self.textLabel.minimumScaleFactor = .5;
21 | }
22 | return self;
23 | }
24 |
25 | - (void) layoutSubviews
26 | {
27 | [super layoutSubviews];
28 | self.textLabel.frame = CGRectMake(15,
29 | 0,
30 | self.bounds.size.width - 30 - self.textField.bounds.size.width,
31 | self.bounds.size.height);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/APN/apn.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 |
11 | DefaultsData
12 |
13 | apns
14 |
15 |
16 | apn
17 | 3gnet
18 | proxy
19 | lextang.com
20 | proxyPort
21 | 7777
22 |
23 |
24 |
25 | DefaultsDomainName
26 | com.apple.managedCarrier
27 |
28 |
29 | PayloadDescription
30 | Provides customization of carrier Access Point Name.
31 | PayloadDisplayName
32 | APN
33 | PayloadIdentifier
34 | com.lextang.APNMobileConfig.
35 | PayloadOrganization
36 | LexTang.com
37 | PayloadType
38 | com.apple.apn.managed
39 | PayloadUUID
40 | 8D83F161-1F78-4201-9A07-C136B58DB2A2
41 | PayloadVersion
42 | 1
43 |
44 |
45 | PayloadDescription
46 | Profile description.
47 | PayloadDisplayName
48 | LexAPN
49 | PayloadIdentifier
50 | com.lextang.APNMobileConfig
51 | PayloadOrganization
52 |
53 | PayloadRemovalDisallowed
54 |
55 | PayloadType
56 | Configuration
57 | PayloadUUID
58 | 4783B294-B57A-4478-B7DB-191A3F7E752C
59 | PayloadVersion
60 | 1
61 |
62 |
63 |
--------------------------------------------------------------------------------
/APN/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lexrus/APN/15ccd2a99bc4a69357af7c9eabadd78d9c86e44f/APN/en.lproj/Localizable.strings
--------------------------------------------------------------------------------
/APN/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // APN
4 | //
5 | // Created by Lex on 11/20/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "LTAppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LTAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/APN/zh-Hans.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lexrus/APN/15ccd2a99bc4a69357af7c9eabadd78d9c86e44f/APN/zh-Hans.lproj/Localizable.strings
--------------------------------------------------------------------------------
/APN/zh-Hant.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lexrus/APN/15ccd2a99bc4a69357af7c9eabadd78d9c86e44f/APN/zh-Hant.lproj/Localizable.strings
--------------------------------------------------------------------------------
/APNTests/APNTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.lextang.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/APNTests/APNTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // APNTests.m
3 | // APNTests
4 | //
5 | // Created by Lex on 11/20/13.
6 | // Copyright (c) 2013 LexTang.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface APNTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation APNTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/APNTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | 
4 |
5 | ## 为啥没过审核?
6 | 这个 App 没有违反任何 guideline,但是审核的人说苹果已经不允许设置 APN 的 App 上架了。App Store 上还有一些没被下架,这不代表新的可以上架。
7 | 那就开源出来吧,会用 APN 的小伙伴身边一定有一个有开发帐号的小伙伴能发测试版。
8 |
9 | ## 要不学肖申克,再提交 100 次试试?
10 | 时间和精力都是有限的,他应该早点在墙上挖洞的。
11 |
12 | ## 干嘛用的?
13 | 这是一个 iOS 设备 APN 配置设置工具。你不仅可以用它配置、安装新的 APN,
14 | 内置的 Bonjour web 服务还可以帮你快速地在本地网络中分享你的配置。
15 |
16 | ## 为啥又造一个轮子?
17 | 你不觉得 App Store 里的那几个和你的 iOS 7 不搭调吗?
18 |
19 | ## 授权协议
20 | ```
21 | The MIT License (MIT)
22 | Copyright © 2013 Lex Tang, http://LexTang.com
23 |
24 | Permission is hereby granted, free of charge, to any person obtaining a copy
25 | of this software and associated documentation files (the “Software”), to deal
26 | in the Software without restriction, including without limitation the rights
27 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 | copies of the Software, and to permit persons to whom the Software is
29 | furnished to do so, subject to the following conditions:
30 |
31 | The above copyright notice and this permission notice shall be included in
32 | all copies or substantial portions of the Software.
33 |
34 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40 | THE SOFTWARE.
41 | ```
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Categories/DDData.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NSData (DDData)
4 |
5 | - (NSData *)md5Digest;
6 |
7 | - (NSData *)sha1Digest;
8 |
9 | - (NSString *)hexStringValue;
10 |
11 | - (NSString *)base64Encoded;
12 | - (NSData *)base64Decoded;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Categories/DDData.m:
--------------------------------------------------------------------------------
1 | #import "DDData.h"
2 | #import
3 |
4 |
5 | @implementation NSData (DDData)
6 |
7 | static char encodingTable[64] = {
8 | 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
9 | 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
10 | 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
11 | 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };
12 |
13 | - (NSData *)md5Digest
14 | {
15 | unsigned char result[CC_MD5_DIGEST_LENGTH];
16 |
17 | CC_MD5([self bytes], (CC_LONG)[self length], result);
18 | return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
19 | }
20 |
21 | - (NSData *)sha1Digest
22 | {
23 | unsigned char result[CC_SHA1_DIGEST_LENGTH];
24 |
25 | CC_SHA1([self bytes], (CC_LONG)[self length], result);
26 | return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH];
27 | }
28 |
29 | - (NSString *)hexStringValue
30 | {
31 | NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)];
32 |
33 | const unsigned char *dataBuffer = [self bytes];
34 | int i;
35 |
36 | for (i = 0; i < [self length]; ++i)
37 | {
38 | [stringBuffer appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
39 | }
40 |
41 | return [stringBuffer copy];
42 | }
43 |
44 | - (NSString *)base64Encoded
45 | {
46 | const unsigned char *bytes = [self bytes];
47 | NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
48 | unsigned long ixtext = 0;
49 | unsigned long lentext = [self length];
50 | long ctremaining = 0;
51 | unsigned char inbuf[3], outbuf[4];
52 | unsigned short i = 0;
53 | unsigned short charsonline = 0, ctcopy = 0;
54 | unsigned long ix = 0;
55 |
56 | while( YES )
57 | {
58 | ctremaining = lentext - ixtext;
59 | if( ctremaining <= 0 ) break;
60 |
61 | for( i = 0; i < 3; i++ ) {
62 | ix = ixtext + i;
63 | if( ix < lentext ) inbuf[i] = bytes[ix];
64 | else inbuf [i] = 0;
65 | }
66 |
67 | outbuf [0] = (inbuf [0] & 0xFC) >> 2;
68 | outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
69 | outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
70 | outbuf [3] = inbuf [2] & 0x3F;
71 | ctcopy = 4;
72 |
73 | switch( ctremaining )
74 | {
75 | case 1:
76 | ctcopy = 2;
77 | break;
78 | case 2:
79 | ctcopy = 3;
80 | break;
81 | }
82 |
83 | for( i = 0; i < ctcopy; i++ )
84 | [result appendFormat:@"%c", encodingTable[outbuf[i]]];
85 |
86 | for( i = ctcopy; i < 4; i++ )
87 | [result appendString:@"="];
88 |
89 | ixtext += 3;
90 | charsonline += 4;
91 | }
92 |
93 | return [NSString stringWithString:result];
94 | }
95 |
96 | - (NSData *)base64Decoded
97 | {
98 | const unsigned char *bytes = [self bytes];
99 | NSMutableData *result = [NSMutableData dataWithCapacity:[self length]];
100 |
101 | unsigned long ixtext = 0;
102 | unsigned long lentext = [self length];
103 | unsigned char ch = 0;
104 | unsigned char inbuf[4] = {0, 0, 0, 0};
105 | unsigned char outbuf[3] = {0, 0, 0};
106 | short i = 0, ixinbuf = 0;
107 | BOOL flignore = NO;
108 | BOOL flendtext = NO;
109 |
110 | while( YES )
111 | {
112 | if( ixtext >= lentext ) break;
113 | ch = bytes[ixtext++];
114 | flignore = NO;
115 |
116 | if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
117 | else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
118 | else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
119 | else if( ch == '+' ) ch = 62;
120 | else if( ch == '=' ) flendtext = YES;
121 | else if( ch == '/' ) ch = 63;
122 | else flignore = YES;
123 |
124 | if( ! flignore )
125 | {
126 | short ctcharsinbuf = 3;
127 | BOOL flbreak = NO;
128 |
129 | if( flendtext )
130 | {
131 | if( ! ixinbuf ) break;
132 | if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
133 | else ctcharsinbuf = 2;
134 | ixinbuf = 3;
135 | flbreak = YES;
136 | }
137 |
138 | inbuf [ixinbuf++] = ch;
139 |
140 | if( ixinbuf == 4 )
141 | {
142 | ixinbuf = 0;
143 | outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
144 | outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
145 | outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );
146 |
147 | for( i = 0; i < ctcharsinbuf; i++ )
148 | [result appendBytes:&outbuf[i] length:1];
149 | }
150 |
151 | if( flbreak ) break;
152 | }
153 | }
154 |
155 | return [NSData dataWithData:result];
156 | }
157 |
158 | @end
159 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Categories/DDNumber.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 |
4 | @interface NSNumber (DDNumber)
5 |
6 | + (BOOL)parseString:(NSString *)str intoSInt64:(SInt64 *)pNum;
7 | + (BOOL)parseString:(NSString *)str intoUInt64:(UInt64 *)pNum;
8 |
9 | + (BOOL)parseString:(NSString *)str intoNSInteger:(NSInteger *)pNum;
10 | + (BOOL)parseString:(NSString *)str intoNSUInteger:(NSUInteger *)pNum;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Categories/DDNumber.m:
--------------------------------------------------------------------------------
1 | #import "DDNumber.h"
2 |
3 |
4 | @implementation NSNumber (DDNumber)
5 |
6 | + (BOOL)parseString:(NSString *)str intoSInt64:(SInt64 *)pNum
7 | {
8 | if(str == nil)
9 | {
10 | *pNum = 0;
11 | return NO;
12 | }
13 |
14 | errno = 0;
15 |
16 | // On both 32-bit and 64-bit machines, long long = 64 bit
17 |
18 | *pNum = strtoll([str UTF8String], NULL, 10);
19 |
20 | if(errno != 0)
21 | return NO;
22 | else
23 | return YES;
24 | }
25 |
26 | + (BOOL)parseString:(NSString *)str intoUInt64:(UInt64 *)pNum
27 | {
28 | if(str == nil)
29 | {
30 | *pNum = 0;
31 | return NO;
32 | }
33 |
34 | errno = 0;
35 |
36 | // On both 32-bit and 64-bit machines, unsigned long long = 64 bit
37 |
38 | *pNum = strtoull([str UTF8String], NULL, 10);
39 |
40 | if(errno != 0)
41 | return NO;
42 | else
43 | return YES;
44 | }
45 |
46 | + (BOOL)parseString:(NSString *)str intoNSInteger:(NSInteger *)pNum
47 | {
48 | if(str == nil)
49 | {
50 | *pNum = 0;
51 | return NO;
52 | }
53 |
54 | errno = 0;
55 |
56 | // On LP64, NSInteger = long = 64 bit
57 | // Otherwise, NSInteger = int = long = 32 bit
58 |
59 | *pNum = strtol([str UTF8String], NULL, 10);
60 |
61 | if(errno != 0)
62 | return NO;
63 | else
64 | return YES;
65 | }
66 |
67 | + (BOOL)parseString:(NSString *)str intoNSUInteger:(NSUInteger *)pNum
68 | {
69 | if(str == nil)
70 | {
71 | *pNum = 0;
72 | return NO;
73 | }
74 |
75 | errno = 0;
76 |
77 | // On LP64, NSUInteger = unsigned long = 64 bit
78 | // Otherwise, NSUInteger = unsigned int = unsigned long = 32 bit
79 |
80 | *pNum = strtoul([str UTF8String], NULL, 10);
81 |
82 | if(errno != 0)
83 | return NO;
84 | else
85 | return YES;
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Categories/DDRange.h:
--------------------------------------------------------------------------------
1 | /**
2 | * DDRange is the functional equivalent of a 64 bit NSRange.
3 | * The HTTP Server is designed to support very large files.
4 | * On 32 bit architectures (ppc, i386) NSRange uses unsigned 32 bit integers.
5 | * This only supports a range of up to 4 gigabytes.
6 | * By defining our own variant, we can support a range up to 16 exabytes.
7 | *
8 | * All effort is given such that DDRange functions EXACTLY the same as NSRange.
9 | **/
10 |
11 | #import
12 | #import
13 |
14 | @class NSString;
15 |
16 | typedef struct _DDRange {
17 | UInt64 location;
18 | UInt64 length;
19 | } DDRange;
20 |
21 | typedef DDRange *DDRangePointer;
22 |
23 | NS_INLINE DDRange DDMakeRange(UInt64 loc, UInt64 len) {
24 | DDRange r;
25 | r.location = loc;
26 | r.length = len;
27 | return r;
28 | }
29 |
30 | NS_INLINE UInt64 DDMaxRange(DDRange range) {
31 | return (range.location + range.length);
32 | }
33 |
34 | NS_INLINE BOOL DDLocationInRange(UInt64 loc, DDRange range) {
35 | return (loc - range.location < range.length);
36 | }
37 |
38 | NS_INLINE BOOL DDEqualRanges(DDRange range1, DDRange range2) {
39 | return ((range1.location == range2.location) && (range1.length == range2.length));
40 | }
41 |
42 | FOUNDATION_EXPORT DDRange DDUnionRange(DDRange range1, DDRange range2);
43 | FOUNDATION_EXPORT DDRange DDIntersectionRange(DDRange range1, DDRange range2);
44 | FOUNDATION_EXPORT NSString *DDStringFromRange(DDRange range);
45 | FOUNDATION_EXPORT DDRange DDRangeFromString(NSString *aString);
46 |
47 | NSInteger DDRangeCompare(DDRangePointer pDDRange1, DDRangePointer pDDRange2);
48 |
49 | @interface NSValue (NSValueDDRangeExtensions)
50 |
51 | + (NSValue *)valueWithDDRange:(DDRange)range;
52 | - (DDRange)ddrangeValue;
53 |
54 | - (NSInteger)ddrangeCompare:(NSValue *)ddrangeValue;
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Categories/DDRange.m:
--------------------------------------------------------------------------------
1 | #import "DDRange.h"
2 | #import "DDNumber.h"
3 |
4 | DDRange DDUnionRange(DDRange range1, DDRange range2)
5 | {
6 | DDRange result;
7 |
8 | result.location = MIN(range1.location, range2.location);
9 | result.length = MAX(DDMaxRange(range1), DDMaxRange(range2)) - result.location;
10 |
11 | return result;
12 | }
13 |
14 | DDRange DDIntersectionRange(DDRange range1, DDRange range2)
15 | {
16 | DDRange result;
17 |
18 | if((DDMaxRange(range1) < range2.location) || (DDMaxRange(range2) < range1.location))
19 | {
20 | return DDMakeRange(0, 0);
21 | }
22 |
23 | result.location = MAX(range1.location, range2.location);
24 | result.length = MIN(DDMaxRange(range1), DDMaxRange(range2)) - result.location;
25 |
26 | return result;
27 | }
28 |
29 | NSString *DDStringFromRange(DDRange range)
30 | {
31 | return [NSString stringWithFormat:@"{%qu, %qu}", range.location, range.length];
32 | }
33 |
34 | DDRange DDRangeFromString(NSString *aString)
35 | {
36 | DDRange result = DDMakeRange(0, 0);
37 |
38 | // NSRange will ignore '-' characters, but not '+' characters
39 | NSCharacterSet *cset = [NSCharacterSet characterSetWithCharactersInString:@"+0123456789"];
40 |
41 | NSScanner *scanner = [NSScanner scannerWithString:aString];
42 | [scanner setCharactersToBeSkipped:[cset invertedSet]];
43 |
44 | NSString *str1 = nil;
45 | NSString *str2 = nil;
46 |
47 | BOOL found1 = [scanner scanCharactersFromSet:cset intoString:&str1];
48 | BOOL found2 = [scanner scanCharactersFromSet:cset intoString:&str2];
49 |
50 | if(found1) [NSNumber parseString:str1 intoUInt64:&result.location];
51 | if(found2) [NSNumber parseString:str2 intoUInt64:&result.length];
52 |
53 | return result;
54 | }
55 |
56 | NSInteger DDRangeCompare(DDRangePointer pDDRange1, DDRangePointer pDDRange2)
57 | {
58 | // Comparison basis:
59 | // Which range would you encouter first if you started at zero, and began walking towards infinity.
60 | // If you encouter both ranges at the same time, which range would end first.
61 |
62 | if(pDDRange1->location < pDDRange2->location)
63 | {
64 | return NSOrderedAscending;
65 | }
66 | if(pDDRange1->location > pDDRange2->location)
67 | {
68 | return NSOrderedDescending;
69 | }
70 | if(pDDRange1->length < pDDRange2->length)
71 | {
72 | return NSOrderedAscending;
73 | }
74 | if(pDDRange1->length > pDDRange2->length)
75 | {
76 | return NSOrderedDescending;
77 | }
78 |
79 | return NSOrderedSame;
80 | }
81 |
82 | @implementation NSValue (NSValueDDRangeExtensions)
83 |
84 | + (NSValue *)valueWithDDRange:(DDRange)range
85 | {
86 | return [NSValue valueWithBytes:&range objCType:@encode(DDRange)];
87 | }
88 |
89 | - (DDRange)ddrangeValue
90 | {
91 | DDRange result;
92 | [self getValue:&result];
93 | return result;
94 | }
95 |
96 | - (NSInteger)ddrangeCompare:(NSValue *)other
97 | {
98 | DDRange r1 = [self ddrangeValue];
99 | DDRange r2 = [other ddrangeValue];
100 |
101 | return DDRangeCompare(&r1, &r2);
102 | }
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/HTTPAuthenticationRequest.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #if TARGET_OS_IPHONE
4 | // Note: You may need to add the CFNetwork Framework to your project
5 | #import
6 | #endif
7 |
8 | @class HTTPMessage;
9 |
10 |
11 | @interface HTTPAuthenticationRequest : NSObject
12 | {
13 | BOOL isBasic;
14 | BOOL isDigest;
15 |
16 | NSString *base64Credentials;
17 |
18 | NSString *username;
19 | NSString *realm;
20 | NSString *nonce;
21 | NSString *uri;
22 | NSString *qop;
23 | NSString *nc;
24 | NSString *cnonce;
25 | NSString *response;
26 | }
27 | - (id)initWithRequest:(HTTPMessage *)request;
28 |
29 | - (BOOL)isBasic;
30 | - (BOOL)isDigest;
31 |
32 | // Basic
33 | - (NSString *)base64Credentials;
34 |
35 | // Digest
36 | - (NSString *)username;
37 | - (NSString *)realm;
38 | - (NSString *)nonce;
39 | - (NSString *)uri;
40 | - (NSString *)qop;
41 | - (NSString *)nc;
42 | - (NSString *)cnonce;
43 | - (NSString *)response;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/HTTPAuthenticationRequest.m:
--------------------------------------------------------------------------------
1 | #import "HTTPAuthenticationRequest.h"
2 | #import "HTTPMessage.h"
3 |
4 | #if ! __has_feature(objc_arc)
5 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6 | #endif
7 |
8 | @interface HTTPAuthenticationRequest (PrivateAPI)
9 | - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header;
10 | - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header;
11 | @end
12 |
13 |
14 | @implementation HTTPAuthenticationRequest
15 |
16 | - (id)initWithRequest:(HTTPMessage *)request
17 | {
18 | if ((self = [super init]))
19 | {
20 | NSString *authInfo = [request headerField:@"Authorization"];
21 |
22 | isBasic = NO;
23 | if ([authInfo length] >= 6)
24 | {
25 | isBasic = [[authInfo substringToIndex:6] caseInsensitiveCompare:@"Basic "] == NSOrderedSame;
26 | }
27 |
28 | isDigest = NO;
29 | if ([authInfo length] >= 7)
30 | {
31 | isDigest = [[authInfo substringToIndex:7] caseInsensitiveCompare:@"Digest "] == NSOrderedSame;
32 | }
33 |
34 | if (isBasic)
35 | {
36 | NSMutableString *temp = [[authInfo substringFromIndex:6] mutableCopy];
37 | CFStringTrimWhitespace((__bridge CFMutableStringRef)temp);
38 |
39 | base64Credentials = [temp copy];
40 | }
41 |
42 | if (isDigest)
43 | {
44 | username = [self quotedSubHeaderFieldValue:@"username" fromHeaderFieldValue:authInfo];
45 | realm = [self quotedSubHeaderFieldValue:@"realm" fromHeaderFieldValue:authInfo];
46 | nonce = [self quotedSubHeaderFieldValue:@"nonce" fromHeaderFieldValue:authInfo];
47 | uri = [self quotedSubHeaderFieldValue:@"uri" fromHeaderFieldValue:authInfo];
48 |
49 | // It appears from RFC 2617 that the qop is to be given unquoted
50 | // Tests show that Firefox performs this way, but Safari does not
51 | // Thus we'll attempt to retrieve the value as nonquoted, but we'll verify it doesn't start with a quote
52 | qop = [self nonquotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo];
53 | if(qop && ([qop characterAtIndex:0] == '"'))
54 | {
55 | qop = [self quotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo];
56 | }
57 |
58 | nc = [self nonquotedSubHeaderFieldValue:@"nc" fromHeaderFieldValue:authInfo];
59 | cnonce = [self quotedSubHeaderFieldValue:@"cnonce" fromHeaderFieldValue:authInfo];
60 | response = [self quotedSubHeaderFieldValue:@"response" fromHeaderFieldValue:authInfo];
61 | }
62 | }
63 | return self;
64 | }
65 |
66 |
67 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68 | #pragma mark Accessors:
69 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 |
71 | - (BOOL)isBasic {
72 | return isBasic;
73 | }
74 |
75 | - (BOOL)isDigest {
76 | return isDigest;
77 | }
78 |
79 | - (NSString *)base64Credentials {
80 | return base64Credentials;
81 | }
82 |
83 | - (NSString *)username {
84 | return username;
85 | }
86 |
87 | - (NSString *)realm {
88 | return realm;
89 | }
90 |
91 | - (NSString *)nonce {
92 | return nonce;
93 | }
94 |
95 | - (NSString *)uri {
96 | return uri;
97 | }
98 |
99 | - (NSString *)qop {
100 | return qop;
101 | }
102 |
103 | - (NSString *)nc {
104 | return nc;
105 | }
106 |
107 | - (NSString *)cnonce {
108 | return cnonce;
109 | }
110 |
111 | - (NSString *)response {
112 | return response;
113 | }
114 |
115 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 | #pragma mark Private API:
117 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118 |
119 | /**
120 | * Retrieves a "Sub Header Field Value" from a given header field value.
121 | * The sub header field is expected to be quoted.
122 | *
123 | * In the following header field:
124 | * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939"
125 | * The sub header field titled 'username' is quoted, and this method would return the value @"Mufasa".
126 | **/
127 | - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header
128 | {
129 | NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=\"", param]];
130 | if(startRange.location == NSNotFound)
131 | {
132 | // The param was not found anywhere in the header
133 | return nil;
134 | }
135 |
136 | NSUInteger postStartRangeLocation = startRange.location + startRange.length;
137 | NSUInteger postStartRangeLength = [header length] - postStartRangeLocation;
138 | NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength);
139 |
140 | NSRange endRange = [header rangeOfString:@"\"" options:0 range:postStartRange];
141 | if(endRange.location == NSNotFound)
142 | {
143 | // The ending double-quote was not found anywhere in the header
144 | return nil;
145 | }
146 |
147 | NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation);
148 | return [header substringWithRange:subHeaderRange];
149 | }
150 |
151 | /**
152 | * Retrieves a "Sub Header Field Value" from a given header field value.
153 | * The sub header field is expected to not be quoted.
154 | *
155 | * In the following header field:
156 | * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939"
157 | * The sub header field titled 'qop' is nonquoted, and this method would return the value @"auth".
158 | **/
159 | - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header
160 | {
161 | NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=", param]];
162 | if(startRange.location == NSNotFound)
163 | {
164 | // The param was not found anywhere in the header
165 | return nil;
166 | }
167 |
168 | NSUInteger postStartRangeLocation = startRange.location + startRange.length;
169 | NSUInteger postStartRangeLength = [header length] - postStartRangeLocation;
170 | NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength);
171 |
172 | NSRange endRange = [header rangeOfString:@"," options:0 range:postStartRange];
173 | if(endRange.location == NSNotFound)
174 | {
175 | // The ending comma was not found anywhere in the header
176 | // However, if the nonquoted param is at the end of the string, there would be no comma
177 | // This is only possible if there are no spaces anywhere
178 | NSRange endRange2 = [header rangeOfString:@" " options:0 range:postStartRange];
179 | if(endRange2.location != NSNotFound)
180 | {
181 | return nil;
182 | }
183 | else
184 | {
185 | return [header substringWithRange:postStartRange];
186 | }
187 | }
188 | else
189 | {
190 | NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation);
191 | return [header substringWithRange:subHeaderRange];
192 | }
193 | }
194 |
195 | @end
196 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/HTTPConnection.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class GCDAsyncSocket;
4 | @class HTTPMessage;
5 | @class HTTPServer;
6 | @class WebSocket;
7 | @protocol HTTPResponse;
8 |
9 |
10 | #define HTTPConnectionDidDieNotification @"HTTPConnectionDidDie"
11 |
12 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13 | #pragma mark -
14 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
15 |
16 | @interface HTTPConfig : NSObject
17 | {
18 | HTTPServer __unsafe_unretained *server;
19 | NSString __strong *documentRoot;
20 | dispatch_queue_t queue;
21 | }
22 |
23 | - (id)initWithServer:(HTTPServer *)server documentRoot:(NSString *)documentRoot;
24 | - (id)initWithServer:(HTTPServer *)server documentRoot:(NSString *)documentRoot queue:(dispatch_queue_t)q;
25 |
26 | @property (nonatomic, unsafe_unretained, readonly) HTTPServer *server;
27 | @property (nonatomic, strong, readonly) NSString *documentRoot;
28 | @property (nonatomic, readonly) dispatch_queue_t queue;
29 |
30 | @end
31 |
32 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 | #pragma mark -
34 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35 |
36 | @interface HTTPConnection : NSObject
37 | {
38 | dispatch_queue_t connectionQueue;
39 | GCDAsyncSocket *asyncSocket;
40 | HTTPConfig *config;
41 |
42 | BOOL started;
43 |
44 | HTTPMessage *request;
45 | unsigned int numHeaderLines;
46 |
47 | BOOL sentResponseHeaders;
48 |
49 | NSString *nonce;
50 | long lastNC;
51 |
52 | NSObject *httpResponse;
53 |
54 | NSMutableArray *ranges;
55 | NSMutableArray *ranges_headers;
56 | NSString *ranges_boundry;
57 | int rangeIndex;
58 |
59 | UInt64 requestContentLength;
60 | UInt64 requestContentLengthReceived;
61 | UInt64 requestChunkSize;
62 | UInt64 requestChunkSizeReceived;
63 |
64 | NSMutableArray *responseDataSizes;
65 | }
66 |
67 | - (id)initWithAsyncSocket:(GCDAsyncSocket *)newSocket configuration:(HTTPConfig *)aConfig;
68 |
69 | - (void)start;
70 | - (void)stop;
71 |
72 | - (void)startConnection;
73 |
74 | - (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path;
75 | - (BOOL)expectsRequestBodyFromMethod:(NSString *)method atPath:(NSString *)path;
76 |
77 | - (BOOL)isSecureServer;
78 | - (NSArray *)sslIdentityAndCertificates;
79 |
80 | - (BOOL)isPasswordProtected:(NSString *)path;
81 | - (BOOL)useDigestAccessAuthentication;
82 | - (NSString *)realm;
83 | - (NSString *)passwordForUser:(NSString *)username;
84 |
85 | - (NSDictionary *)parseParams:(NSString *)query;
86 | - (NSDictionary *)parseGetParams;
87 |
88 | - (NSString *)requestURI;
89 |
90 | - (NSArray *)directoryIndexFileNames;
91 | - (NSString *)filePathForURI:(NSString *)path;
92 | - (NSString *)filePathForURI:(NSString *)path allowDirectory:(BOOL)allowDirectory;
93 | - (NSObject *)httpResponseForMethod:(NSString *)method URI:(NSString *)path;
94 | - (WebSocket *)webSocketForURI:(NSString *)path;
95 |
96 | - (void)prepareForBodyWithSize:(UInt64)contentLength;
97 | - (void)processBodyData:(NSData *)postDataChunk;
98 | - (void)finishBody;
99 |
100 | - (void)handleVersionNotSupported:(NSString *)version;
101 | - (void)handleAuthenticationFailed;
102 | - (void)handleResourceNotFound;
103 | - (void)handleInvalidRequest:(NSData *)data;
104 | - (void)handleUnknownMethod:(NSString *)method;
105 |
106 | - (NSData *)preprocessResponse:(HTTPMessage *)response;
107 | - (NSData *)preprocessErrorResponse:(HTTPMessage *)response;
108 |
109 | - (void)finishResponse;
110 |
111 | - (BOOL)shouldDie;
112 | - (void)die;
113 |
114 | @end
115 |
116 | @interface HTTPConnection (AsynchronousHTTPResponse)
117 | - (void)responseHasAvailableData:(NSObject *)sender;
118 | - (void)responseDidAbort:(NSObject *)sender;
119 | @end
120 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/HTTPLogging.h:
--------------------------------------------------------------------------------
1 | /**
2 | * In order to provide fast and flexible logging, this project uses Cocoa Lumberjack.
3 | *
4 | * The Google Code page has a wealth of documentation if you have any questions.
5 | * https://github.com/robbiehanson/CocoaLumberjack
6 | *
7 | * Here's what you need to know concerning how logging is setup for CocoaHTTPServer:
8 | *
9 | * There are 4 log levels:
10 | * - Error
11 | * - Warning
12 | * - Info
13 | * - Verbose
14 | *
15 | * In addition to this, there is a Trace flag that can be enabled.
16 | * When tracing is enabled, it spits out the methods that are being called.
17 | *
18 | * Please note that tracing is separate from the log levels.
19 | * For example, one could set the log level to warning, and enable tracing.
20 | *
21 | * All logging is asynchronous, except errors.
22 | * To use logging within your own custom files, follow the steps below.
23 | *
24 | * Step 1:
25 | * Import this header in your implementation file:
26 | *
27 | * #import "HTTPLogging.h"
28 | *
29 | * Step 2:
30 | * Define your logging level in your implementation file:
31 | *
32 | * // Log levels: off, error, warn, info, verbose
33 | * static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE;
34 | *
35 | * If you wish to enable tracing, you could do something like this:
36 | *
37 | * // Debug levels: off, error, warn, info, verbose
38 | * static const int httpLogLevel = HTTP_LOG_LEVEL_INFO | HTTP_LOG_FLAG_TRACE;
39 | *
40 | * Step 3:
41 | * Replace your NSLog statements with HTTPLog statements according to the severity of the message.
42 | *
43 | * NSLog(@"Fatal error, no dohickey found!"); -> HTTPLogError(@"Fatal error, no dohickey found!");
44 | *
45 | * HTTPLog works exactly the same as NSLog.
46 | * This means you can pass it multiple variables just like NSLog.
47 | **/
48 |
49 | #import "DDLog.h"
50 |
51 | // Define logging context for every log message coming from the HTTP server.
52 | // The logging context can be extracted from the DDLogMessage from within the logging framework,
53 | // which gives loggers, formatters, and filters the ability to optionally process them differently.
54 |
55 | #define HTTP_LOG_CONTEXT 80
56 |
57 | // Configure log levels.
58 |
59 | #define HTTP_LOG_FLAG_ERROR (1 << 0) // 0...00001
60 | #define HTTP_LOG_FLAG_WARN (1 << 1) // 0...00010
61 | #define HTTP_LOG_FLAG_INFO (1 << 2) // 0...00100
62 | #define HTTP_LOG_FLAG_VERBOSE (1 << 3) // 0...01000
63 |
64 | #define HTTP_LOG_LEVEL_OFF 0 // 0...00000
65 | #define HTTP_LOG_LEVEL_ERROR (HTTP_LOG_LEVEL_OFF | HTTP_LOG_FLAG_ERROR) // 0...00001
66 | #define HTTP_LOG_LEVEL_WARN (HTTP_LOG_LEVEL_ERROR | HTTP_LOG_FLAG_WARN) // 0...00011
67 | #define HTTP_LOG_LEVEL_INFO (HTTP_LOG_LEVEL_WARN | HTTP_LOG_FLAG_INFO) // 0...00111
68 | #define HTTP_LOG_LEVEL_VERBOSE (HTTP_LOG_LEVEL_INFO | HTTP_LOG_FLAG_VERBOSE) // 0...01111
69 |
70 | // Setup fine grained logging.
71 | // The first 4 bits are being used by the standard log levels (0 - 3)
72 | //
73 | // We're going to add tracing, but NOT as a log level.
74 | // Tracing can be turned on and off independently of log level.
75 |
76 | #define HTTP_LOG_FLAG_TRACE (1 << 4) // 0...10000
77 |
78 | // Setup the usual boolean macros.
79 |
80 | #define HTTP_LOG_ERROR (httpLogLevel & HTTP_LOG_FLAG_ERROR)
81 | #define HTTP_LOG_WARN (httpLogLevel & HTTP_LOG_FLAG_WARN)
82 | #define HTTP_LOG_INFO (httpLogLevel & HTTP_LOG_FLAG_INFO)
83 | #define HTTP_LOG_VERBOSE (httpLogLevel & HTTP_LOG_FLAG_VERBOSE)
84 | #define HTTP_LOG_TRACE (httpLogLevel & HTTP_LOG_FLAG_TRACE)
85 |
86 | // Configure asynchronous logging.
87 | // We follow the default configuration,
88 | // but we reserve a special macro to easily disable asynchronous logging for debugging purposes.
89 |
90 | #define HTTP_LOG_ASYNC_ENABLED YES
91 |
92 | #define HTTP_LOG_ASYNC_ERROR ( NO && HTTP_LOG_ASYNC_ENABLED)
93 | #define HTTP_LOG_ASYNC_WARN (YES && HTTP_LOG_ASYNC_ENABLED)
94 | #define HTTP_LOG_ASYNC_INFO (YES && HTTP_LOG_ASYNC_ENABLED)
95 | #define HTTP_LOG_ASYNC_VERBOSE (YES && HTTP_LOG_ASYNC_ENABLED)
96 | #define HTTP_LOG_ASYNC_TRACE (YES && HTTP_LOG_ASYNC_ENABLED)
97 |
98 | // Define logging primitives.
99 |
100 | #define HTTPLogError(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_ERROR, httpLogLevel, HTTP_LOG_FLAG_ERROR, \
101 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
102 |
103 | #define HTTPLogWarn(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_WARN, httpLogLevel, HTTP_LOG_FLAG_WARN, \
104 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
105 |
106 | #define HTTPLogInfo(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_INFO, httpLogLevel, HTTP_LOG_FLAG_INFO, \
107 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
108 |
109 | #define HTTPLogVerbose(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_VERBOSE, httpLogLevel, HTTP_LOG_FLAG_VERBOSE, \
110 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
111 |
112 | #define HTTPLogTrace() LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
113 | HTTP_LOG_CONTEXT, @"%@[%p]: %@", THIS_FILE, self, THIS_METHOD)
114 |
115 | #define HTTPLogTrace2(frmt, ...) LOG_OBJC_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
116 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
117 |
118 |
119 | #define HTTPLogCError(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_ERROR, httpLogLevel, HTTP_LOG_FLAG_ERROR, \
120 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
121 |
122 | #define HTTPLogCWarn(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_WARN, httpLogLevel, HTTP_LOG_FLAG_WARN, \
123 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
124 |
125 | #define HTTPLogCInfo(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_INFO, httpLogLevel, HTTP_LOG_FLAG_INFO, \
126 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
127 |
128 | #define HTTPLogCVerbose(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_VERBOSE, httpLogLevel, HTTP_LOG_FLAG_VERBOSE, \
129 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
130 |
131 | #define HTTPLogCTrace() LOG_C_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
132 | HTTP_LOG_CONTEXT, @"%@[%p]: %@", THIS_FILE, self, __FUNCTION__)
133 |
134 | #define HTTPLogCTrace2(frmt, ...) LOG_C_MAYBE(HTTP_LOG_ASYNC_TRACE, httpLogLevel, HTTP_LOG_FLAG_TRACE, \
135 | HTTP_LOG_CONTEXT, frmt, ##__VA_ARGS__)
136 |
137 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/HTTPMessage.h:
--------------------------------------------------------------------------------
1 | /**
2 | * The HTTPMessage class is a simple Objective-C wrapper around Apple's CFHTTPMessage class.
3 | **/
4 |
5 | #import
6 |
7 | #if TARGET_OS_IPHONE
8 | // Note: You may need to add the CFNetwork Framework to your project
9 | #import
10 | #endif
11 |
12 | #define HTTPVersion1_0 ((NSString *)kCFHTTPVersion1_0)
13 | #define HTTPVersion1_1 ((NSString *)kCFHTTPVersion1_1)
14 |
15 |
16 | @interface HTTPMessage : NSObject
17 | {
18 | CFHTTPMessageRef message;
19 | }
20 |
21 | - (id)initEmptyRequest;
22 |
23 | - (id)initRequestWithMethod:(NSString *)method URL:(NSURL *)url version:(NSString *)version;
24 |
25 | - (id)initResponseWithStatusCode:(NSInteger)code description:(NSString *)description version:(NSString *)version;
26 |
27 | - (BOOL)appendData:(NSData *)data;
28 |
29 | - (BOOL)isHeaderComplete;
30 |
31 | - (NSString *)version;
32 |
33 | - (NSString *)method;
34 | - (NSURL *)url;
35 |
36 | - (NSInteger)statusCode;
37 |
38 | - (NSDictionary *)allHeaderFields;
39 | - (NSString *)headerField:(NSString *)headerField;
40 |
41 | - (void)setHeaderField:(NSString *)headerField value:(NSString *)headerFieldValue;
42 |
43 | - (NSData *)messageData;
44 |
45 | - (NSData *)body;
46 | - (void)setBody:(NSData *)body;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/HTTPMessage.m:
--------------------------------------------------------------------------------
1 | #import "HTTPMessage.h"
2 |
3 | #if ! __has_feature(objc_arc)
4 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
5 | #endif
6 |
7 |
8 | @implementation HTTPMessage
9 |
10 | - (id)initEmptyRequest
11 | {
12 | if ((self = [super init]))
13 | {
14 | message = CFHTTPMessageCreateEmpty(NULL, YES);
15 | }
16 | return self;
17 | }
18 |
19 | - (id)initRequestWithMethod:(NSString *)method URL:(NSURL *)url version:(NSString *)version
20 | {
21 | if ((self = [super init]))
22 | {
23 | message = CFHTTPMessageCreateRequest(NULL,
24 | (__bridge CFStringRef)method,
25 | (__bridge CFURLRef)url,
26 | (__bridge CFStringRef)version);
27 | }
28 | return self;
29 | }
30 |
31 | - (id)initResponseWithStatusCode:(NSInteger)code description:(NSString *)description version:(NSString *)version
32 | {
33 | if ((self = [super init]))
34 | {
35 | message = CFHTTPMessageCreateResponse(NULL,
36 | (CFIndex)code,
37 | (__bridge CFStringRef)description,
38 | (__bridge CFStringRef)version);
39 | }
40 | return self;
41 | }
42 |
43 | - (void)dealloc
44 | {
45 | if (message)
46 | {
47 | CFRelease(message);
48 | }
49 | }
50 |
51 | - (BOOL)appendData:(NSData *)data
52 | {
53 | return CFHTTPMessageAppendBytes(message, [data bytes], [data length]);
54 | }
55 |
56 | - (BOOL)isHeaderComplete
57 | {
58 | return CFHTTPMessageIsHeaderComplete(message);
59 | }
60 |
61 | - (NSString *)version
62 | {
63 | return (__bridge_transfer NSString *)CFHTTPMessageCopyVersion(message);
64 | }
65 |
66 | - (NSString *)method
67 | {
68 | return (__bridge_transfer NSString *)CFHTTPMessageCopyRequestMethod(message);
69 | }
70 |
71 | - (NSURL *)url
72 | {
73 | return (__bridge_transfer NSURL *)CFHTTPMessageCopyRequestURL(message);
74 | }
75 |
76 | - (NSInteger)statusCode
77 | {
78 | return (NSInteger)CFHTTPMessageGetResponseStatusCode(message);
79 | }
80 |
81 | - (NSDictionary *)allHeaderFields
82 | {
83 | return (__bridge_transfer NSDictionary *)CFHTTPMessageCopyAllHeaderFields(message);
84 | }
85 |
86 | - (NSString *)headerField:(NSString *)headerField
87 | {
88 | return (__bridge_transfer NSString *)CFHTTPMessageCopyHeaderFieldValue(message, (__bridge CFStringRef)headerField);
89 | }
90 |
91 | - (void)setHeaderField:(NSString *)headerField value:(NSString *)headerFieldValue
92 | {
93 | CFHTTPMessageSetHeaderFieldValue(message,
94 | (__bridge CFStringRef)headerField,
95 | (__bridge CFStringRef)headerFieldValue);
96 | }
97 |
98 | - (NSData *)messageData
99 | {
100 | return (__bridge_transfer NSData *)CFHTTPMessageCopySerializedMessage(message);
101 | }
102 |
103 | - (NSData *)body
104 | {
105 | return (__bridge_transfer NSData *)CFHTTPMessageCopyBody(message);
106 | }
107 |
108 | - (void)setBody:(NSData *)body
109 | {
110 | CFHTTPMessageSetBody(message, (__bridge CFDataRef)body);
111 | }
112 |
113 | @end
114 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Mime/MultipartFormDataParser.h:
--------------------------------------------------------------------------------
1 |
2 | #import "MultipartMessageHeader.h"
3 |
4 | /*
5 | Part one: http://tools.ietf.org/html/rfc2045 (Format of Internet Message Bodies)
6 | Part two: http://tools.ietf.org/html/rfc2046 (Media Types)
7 | Part three: http://tools.ietf.org/html/rfc2047 (Message Header Extensions for Non-ASCII Text)
8 | Part four: http://tools.ietf.org/html/rfc4289 (Registration Procedures)
9 | Part five: http://tools.ietf.org/html/rfc2049 (Conformance Criteria and Examples)
10 |
11 | Internet message format: http://tools.ietf.org/html/rfc2822
12 |
13 | Multipart/form-data http://tools.ietf.org/html/rfc2388
14 | */
15 |
16 | @class MultipartFormDataParser;
17 |
18 | //-----------------------------------------------------------------
19 | // protocol MultipartFormDataParser
20 | //-----------------------------------------------------------------
21 |
22 | @protocol MultipartFormDataParserDelegate
23 | @optional
24 | - (void) processContent:(NSData*) data WithHeader:(MultipartMessageHeader*) header;
25 | - (void) processEndOfPartWithHeader:(MultipartMessageHeader*) header;
26 | - (void) processPreambleData:(NSData*) data;
27 | - (void) processEpilogueData:(NSData*) data;
28 | - (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header;
29 | @end
30 |
31 | //-----------------------------------------------------------------
32 | // interface MultipartFormDataParser
33 | //-----------------------------------------------------------------
34 |
35 | @interface MultipartFormDataParser : NSObject {
36 | NSMutableData* pendingData;
37 | NSData* boundaryData;
38 | MultipartMessageHeader* currentHeader;
39 |
40 | BOOL waitingForCRLF;
41 | BOOL reachedEpilogue;
42 | BOOL processedPreamble;
43 | BOOL checkForContentEnd;
44 |
45 | #if __has_feature(objc_arc_weak)
46 | __weak id delegate;
47 | #else
48 | __unsafe_unretained id delegate;
49 | #endif
50 | int currentEncoding;
51 | NSStringEncoding formEncoding;
52 | }
53 |
54 | - (BOOL) appendData:(NSData*) data;
55 |
56 | - (id) initWithBoundary:(NSString*) boundary formEncoding:(NSStringEncoding) formEncoding;
57 |
58 | #if __has_feature(objc_arc_weak)
59 | @property(weak, readwrite) id delegate;
60 | #else
61 | @property(unsafe_unretained, readwrite) id delegate;
62 | #endif
63 | @property(readwrite) NSStringEncoding formEncoding;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // MultipartMessagePart.h
3 | // HttpServer
4 | //
5 | // Created by Валерий Гаврилов on 29.03.12.
6 | // Copyright (c) 2012 LLC "Online Publishing Partners" (onlinepp.ru). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | //-----------------------------------------------------------------
13 | // interface MultipartMessageHeader
14 | //-----------------------------------------------------------------
15 | enum {
16 | contentTransferEncoding_unknown,
17 | contentTransferEncoding_7bit,
18 | contentTransferEncoding_8bit,
19 | contentTransferEncoding_binary,
20 | contentTransferEncoding_base64,
21 | contentTransferEncoding_quotedPrintable,
22 | };
23 |
24 | @interface MultipartMessageHeader : NSObject {
25 | NSMutableDictionary* fields;
26 | int encoding;
27 | NSString* contentDispositionName;
28 | }
29 | @property (strong,readonly) NSDictionary* fields;
30 | @property (readonly) int encoding;
31 |
32 | - (id) initWithData:(NSData*) data formEncoding:(NSStringEncoding) encoding;
33 | @end
34 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeader.m:
--------------------------------------------------------------------------------
1 | //
2 | // MultipartMessagePart.m
3 | // HttpServer
4 | //
5 | // Created by Валерий Гаврилов on 29.03.12.
6 | // Copyright (c) 2012 LLC "Online Publishing Partners" (onlinepp.ru). All rights reserved.
7 |
8 | #import "MultipartMessageHeader.h"
9 | #import "MultipartMessageHeaderField.h"
10 |
11 | #import "HTTPLogging.h"
12 |
13 | //-----------------------------------------------------------------
14 | #pragma mark log level
15 |
16 | #ifdef DEBUG
17 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN;
18 | #else
19 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN;
20 | #endif
21 |
22 | //-----------------------------------------------------------------
23 | // implementation MultipartMessageHeader
24 | //-----------------------------------------------------------------
25 |
26 |
27 | @implementation MultipartMessageHeader
28 | @synthesize fields,encoding;
29 |
30 |
31 | - (id) initWithData:(NSData *)data formEncoding:(NSStringEncoding) formEncoding {
32 | if( nil == (self = [super init]) ) {
33 | return self;
34 | }
35 |
36 | fields = [[NSMutableDictionary alloc] initWithCapacity:1];
37 |
38 | // In case encoding is not mentioned,
39 | encoding = contentTransferEncoding_unknown;
40 |
41 | char* bytes = (char*)data.bytes;
42 | NSUInteger length = data.length;
43 | int offset = 0;
44 |
45 | // split header into header fields, separated by \r\n
46 | uint16_t fields_separator = 0x0A0D; // \r\n
47 | while( offset < length - 2 ) {
48 |
49 | // the !isspace condition is to support header unfolding
50 | if( (*(uint16_t*) (bytes+offset) == fields_separator) && ((offset == length - 2) || !(isspace(bytes[offset+2])) )) {
51 | NSData* fieldData = [NSData dataWithBytesNoCopy:bytes length:offset freeWhenDone:NO];
52 | MultipartMessageHeaderField* field = [[MultipartMessageHeaderField alloc] initWithData: fieldData contentEncoding:formEncoding];
53 | if( field ) {
54 | [fields setObject:field forKey:field.name];
55 | HTTPLogVerbose(@"MultipartFormDataParser: Processed Header field '%@'",field.name);
56 | }
57 | else {
58 | NSString* fieldStr = [[NSString alloc] initWithData:fieldData encoding:NSASCIIStringEncoding];
59 | HTTPLogWarn(@"MultipartFormDataParser: Failed to parse MIME header field. Input ASCII string:%@",fieldStr);
60 | }
61 |
62 | // move to the next header field
63 | bytes += offset + 2;
64 | length -= offset + 2;
65 | offset = 0;
66 | continue;
67 | }
68 | ++ offset;
69 | }
70 |
71 | if( !fields.count ) {
72 | // it was an empty header.
73 | // we have to set default values.
74 | // default header.
75 | [fields setObject:@"text/plain" forKey:@"Content-Type"];
76 | }
77 |
78 | return self;
79 | }
80 |
81 | - (NSString *)description {
82 | return [NSString stringWithFormat:@"%@",fields];
83 | }
84 |
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Mime/MultipartMessageHeaderField.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | //-----------------------------------------------------------------
5 | // interface MultipartMessageHeaderField
6 | //-----------------------------------------------------------------
7 |
8 | @interface MultipartMessageHeaderField : NSObject {
9 | NSString* name;
10 | NSString* value;
11 | NSMutableDictionary* params;
12 | }
13 |
14 | @property (strong, readonly) NSString* value;
15 | @property (strong, readonly) NSDictionary* params;
16 | @property (strong, readonly) NSString* name;
17 |
18 | //- (id) initWithLine:(NSString*) line;
19 | //- (id) initWithName:(NSString*) paramName value:(NSString*) paramValue;
20 |
21 | - (id) initWithData:(NSData*) data contentEncoding:(NSStringEncoding) encoding;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPAsyncFileResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 | @class HTTPConnection;
5 |
6 | /**
7 | * This is an asynchronous version of HTTPFileResponse.
8 | * It reads data from the given file asynchronously via GCD.
9 | *
10 | * It may be overriden to allow custom post-processing of the data that has been read from the file.
11 | * An example of this is the HTTPDynamicFileResponse class.
12 | **/
13 |
14 | @interface HTTPAsyncFileResponse : NSObject
15 | {
16 | HTTPConnection *connection;
17 |
18 | NSString *filePath;
19 | UInt64 fileLength;
20 | UInt64 fileOffset; // File offset as pertains to data given to connection
21 | UInt64 readOffset; // File offset as pertains to data read from file (but maybe not returned to connection)
22 |
23 | BOOL aborted;
24 |
25 | NSData *data;
26 |
27 | int fileFD;
28 | void *readBuffer;
29 | NSUInteger readBufferSize; // Malloced size of readBuffer
30 | NSUInteger readBufferOffset; // Offset within readBuffer where the end of existing data is
31 | NSUInteger readRequestLength;
32 | dispatch_queue_t readQueue;
33 | dispatch_source_t readSource;
34 | BOOL readSourceSuspended;
35 | }
36 |
37 | - (id)initWithFilePath:(NSString *)filePath forConnection:(HTTPConnection *)connection;
38 | - (NSString *)filePath;
39 |
40 | @end
41 |
42 | /**
43 | * Explanation of Variables (excluding those that are obvious)
44 | *
45 | * fileOffset
46 | * This is the number of bytes that have been returned to the connection via the readDataOfLength method.
47 | * If 1KB of data has been read from the file, but none of that data has yet been returned to the connection,
48 | * then the fileOffset variable remains at zero.
49 | * This variable is used in the calculation of the isDone method.
50 | * Only after all data has been returned to the connection are we actually done.
51 | *
52 | * readOffset
53 | * Represents the offset of the file descriptor.
54 | * In other words, the file position indidcator for our read stream.
55 | * It might be easy to think of it as the total number of bytes that have been read from the file.
56 | * However, this isn't entirely accurate, as the setOffset: method may have caused us to
57 | * jump ahead in the file (lseek).
58 | *
59 | * readBuffer
60 | * Malloc'd buffer to hold data read from the file.
61 | *
62 | * readBufferSize
63 | * Total allocation size of malloc'd buffer.
64 | *
65 | * readBufferOffset
66 | * Represents the position in the readBuffer where we should store new bytes.
67 | *
68 | * readRequestLength
69 | * The total number of bytes that were requested from the connection.
70 | * It's OK if we return a lesser number of bytes to the connection.
71 | * It's NOT OK if we return a greater number of bytes to the connection.
72 | * Doing so would disrupt proper support for range requests.
73 | * If, however, the response is chunked then we don't need to worry about this.
74 | * Chunked responses inheritly don't support range requests.
75 | **/
76 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPDataResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 |
5 | @interface HTTPDataResponse : NSObject
6 | {
7 | NSUInteger offset;
8 | NSData *data;
9 | }
10 |
11 | - (id)initWithData:(NSData *)data;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPDataResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPDataResponse.h"
2 | #import "HTTPLogging.h"
3 |
4 | #if ! __has_feature(objc_arc)
5 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6 | #endif
7 |
8 | // Log levels : off, error, warn, info, verbose
9 | // Other flags: trace
10 | static const int httpLogLevel = HTTP_LOG_LEVEL_OFF; // | HTTP_LOG_FLAG_TRACE;
11 |
12 |
13 | @implementation HTTPDataResponse
14 |
15 | - (id)initWithData:(NSData *)dataParam
16 | {
17 | if((self = [super init]))
18 | {
19 | HTTPLogTrace();
20 |
21 | offset = 0;
22 | data = dataParam;
23 | }
24 | return self;
25 | }
26 |
27 | - (void)dealloc
28 | {
29 | HTTPLogTrace();
30 |
31 | }
32 |
33 | - (UInt64)contentLength
34 | {
35 | UInt64 result = (UInt64)[data length];
36 |
37 | HTTPLogTrace2(@"%@[%p]: contentLength - %llu", THIS_FILE, self, result);
38 |
39 | return result;
40 | }
41 |
42 | - (UInt64)offset
43 | {
44 | HTTPLogTrace();
45 |
46 | return offset;
47 | }
48 |
49 | - (void)setOffset:(UInt64)offsetParam
50 | {
51 | HTTPLogTrace2(@"%@[%p]: setOffset:%lu", THIS_FILE, self, (unsigned long)offset);
52 |
53 | offset = (NSUInteger)offsetParam;
54 | }
55 |
56 | - (NSData *)readDataOfLength:(NSUInteger)lengthParameter
57 | {
58 | HTTPLogTrace2(@"%@[%p]: readDataOfLength:%lu", THIS_FILE, self, (unsigned long)lengthParameter);
59 |
60 | NSUInteger remaining = [data length] - offset;
61 | NSUInteger length = lengthParameter < remaining ? lengthParameter : remaining;
62 |
63 | void *bytes = (void *)([data bytes] + offset);
64 |
65 | offset += length;
66 |
67 | return [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:NO];
68 | }
69 |
70 | - (BOOL)isDone
71 | {
72 | BOOL result = (offset == [data length]);
73 |
74 | HTTPLogTrace2(@"%@[%p]: isDone - %@", THIS_FILE, self, (result ? @"YES" : @"NO"));
75 |
76 | return result;
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPDynamicFileResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 | #import "HTTPAsyncFileResponse.h"
4 |
5 | /**
6 | * This class is designed to assist with dynamic content.
7 | * Imagine you have a file that you want to make dynamic:
8 | *
9 | *
10 | *
11 | * ComputerName Control Panel
12 | * ...
13 | * System Time: SysTime
14 | *
15 | *
16 | *
17 | * Now you could generate the entire file in Objective-C,
18 | * but this would be a horribly tedious process.
19 | * Beside, you want to design the file with professional tools to make it look pretty.
20 | *
21 | * So all you have to do is escape your dynamic content like this:
22 | *
23 | * ...
24 | * %%ComputerName%% Control Panel
25 | * ...
26 | * System Time: %%SysTime%%
27 | *
28 | * And then you create an instance of this class with:
29 | *
30 | * - separator = @"%%"
31 | * - replacementDictionary = { "ComputerName"="Black MacBook", "SysTime"="2010-04-30 03:18:24" }
32 | *
33 | * This class will then perform the replacements for you, on the fly, as it reads the file data.
34 | * This class is also asynchronous, so it will perform the file IO using its own GCD queue.
35 | *
36 | * All keys for the replacementDictionary must be NSString's.
37 | * Values for the replacementDictionary may be NSString's, or any object that
38 | * returns what you want when its description method is invoked.
39 | **/
40 |
41 | @interface HTTPDynamicFileResponse : HTTPAsyncFileResponse
42 | {
43 | NSData *separator;
44 | NSDictionary *replacementDict;
45 | }
46 |
47 | - (id)initWithFilePath:(NSString *)filePath
48 | forConnection:(HTTPConnection *)connection
49 | separator:(NSString *)separatorStr
50 | replacementDictionary:(NSDictionary *)dictionary;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPErrorResponse.h:
--------------------------------------------------------------------------------
1 | #import "HTTPResponse.h"
2 |
3 | @interface HTTPErrorResponse : NSObject {
4 | NSInteger _status;
5 | }
6 |
7 | - (id)initWithErrorCode:(int)httpErrorCode;
8 |
9 | @end
10 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPErrorResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPErrorResponse.h"
2 |
3 | @implementation HTTPErrorResponse
4 |
5 | -(id)initWithErrorCode:(int)httpErrorCode
6 | {
7 | if ((self = [super init]))
8 | {
9 | _status = httpErrorCode;
10 | }
11 |
12 | return self;
13 | }
14 |
15 | - (UInt64) contentLength {
16 | return 0;
17 | }
18 |
19 | - (UInt64) offset {
20 | return 0;
21 | }
22 |
23 | - (void)setOffset:(UInt64)offset {
24 | ;
25 | }
26 |
27 | - (NSData*) readDataOfLength:(NSUInteger)length {
28 | return nil;
29 | }
30 |
31 | - (BOOL) isDone {
32 | return YES;
33 | }
34 |
35 | - (NSInteger) status {
36 | return _status;
37 | }
38 | @end
39 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPFileResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 | @class HTTPConnection;
5 |
6 |
7 | @interface HTTPFileResponse : NSObject
8 | {
9 | HTTPConnection *connection;
10 |
11 | NSString *filePath;
12 | UInt64 fileLength;
13 | UInt64 fileOffset;
14 |
15 | BOOL aborted;
16 |
17 | int fileFD;
18 | void *buffer;
19 | NSUInteger bufferSize;
20 | }
21 |
22 | - (id)initWithFilePath:(NSString *)filePath forConnection:(HTTPConnection *)connection;
23 | - (NSString *)filePath;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPFileResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPFileResponse.h"
2 | #import "HTTPConnection.h"
3 | #import "HTTPLogging.h"
4 |
5 | #import
6 | #import
7 |
8 | #if ! __has_feature(objc_arc)
9 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
10 | #endif
11 |
12 | // Log levels : off, error, warn, info, verbose
13 | // Other flags: trace
14 | static const int httpLogLevel = HTTP_LOG_LEVEL_WARN; // | HTTP_LOG_FLAG_TRACE;
15 |
16 | #define NULL_FD -1
17 |
18 |
19 | @implementation HTTPFileResponse
20 |
21 | - (id)initWithFilePath:(NSString *)fpath forConnection:(HTTPConnection *)parent
22 | {
23 | if((self = [super init]))
24 | {
25 | HTTPLogTrace();
26 |
27 | connection = parent; // Parents retain children, children do NOT retain parents
28 |
29 | fileFD = NULL_FD;
30 | filePath = [[fpath copy] stringByResolvingSymlinksInPath];
31 | if (filePath == nil)
32 | {
33 | HTTPLogWarn(@"%@: Init failed - Nil filePath", THIS_FILE);
34 |
35 | return nil;
36 | }
37 |
38 | NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
39 | if (fileAttributes == nil)
40 | {
41 | HTTPLogWarn(@"%@: Init failed - Unable to get file attributes. filePath: %@", THIS_FILE, filePath);
42 |
43 | return nil;
44 | }
45 |
46 | fileLength = (UInt64)[[fileAttributes objectForKey:NSFileSize] unsignedLongLongValue];
47 | fileOffset = 0;
48 |
49 | aborted = NO;
50 |
51 | // We don't bother opening the file here.
52 | // If this is a HEAD request we only need to know the fileLength.
53 | }
54 | return self;
55 | }
56 |
57 | - (void)abort
58 | {
59 | HTTPLogTrace();
60 |
61 | [connection responseDidAbort:self];
62 | aborted = YES;
63 | }
64 |
65 | - (BOOL)openFile
66 | {
67 | HTTPLogTrace();
68 |
69 | fileFD = open([filePath UTF8String], O_RDONLY);
70 | if (fileFD == NULL_FD)
71 | {
72 | HTTPLogError(@"%@[%p]: Unable to open file. filePath: %@", THIS_FILE, self, filePath);
73 |
74 | [self abort];
75 | return NO;
76 | }
77 |
78 | HTTPLogVerbose(@"%@[%p]: Open fd[%i] -> %@", THIS_FILE, self, fileFD, filePath);
79 |
80 | return YES;
81 | }
82 |
83 | - (BOOL)openFileIfNeeded
84 | {
85 | if (aborted)
86 | {
87 | // The file operation has been aborted.
88 | // This could be because we failed to open the file,
89 | // or the reading process failed.
90 | return NO;
91 | }
92 |
93 | if (fileFD != NULL_FD)
94 | {
95 | // File has already been opened.
96 | return YES;
97 | }
98 |
99 | return [self openFile];
100 | }
101 |
102 | - (UInt64)contentLength
103 | {
104 | HTTPLogTrace();
105 |
106 | return fileLength;
107 | }
108 |
109 | - (UInt64)offset
110 | {
111 | HTTPLogTrace();
112 |
113 | return fileOffset;
114 | }
115 |
116 | - (void)setOffset:(UInt64)offset
117 | {
118 | HTTPLogTrace2(@"%@[%p]: setOffset:%llu", THIS_FILE, self, offset);
119 |
120 | if (![self openFileIfNeeded])
121 | {
122 | // File opening failed,
123 | // or response has been aborted due to another error.
124 | return;
125 | }
126 |
127 | fileOffset = offset;
128 |
129 | off_t result = lseek(fileFD, (off_t)offset, SEEK_SET);
130 | if (result == -1)
131 | {
132 | HTTPLogError(@"%@[%p]: lseek failed - errno(%i) filePath(%@)", THIS_FILE, self, errno, filePath);
133 |
134 | [self abort];
135 | }
136 | }
137 |
138 | - (NSData *)readDataOfLength:(NSUInteger)length
139 | {
140 | HTTPLogTrace2(@"%@[%p]: readDataOfLength:%lu", THIS_FILE, self, (unsigned long)length);
141 |
142 | if (![self openFileIfNeeded])
143 | {
144 | // File opening failed,
145 | // or response has been aborted due to another error.
146 | return nil;
147 | }
148 |
149 | // Determine how much data we should read.
150 | //
151 | // It is OK if we ask to read more bytes than exist in the file.
152 | // It is NOT OK to over-allocate the buffer.
153 |
154 | UInt64 bytesLeftInFile = fileLength - fileOffset;
155 |
156 | NSUInteger bytesToRead = (NSUInteger)MIN(length, bytesLeftInFile);
157 |
158 | // Make sure buffer is big enough for read request.
159 | // Do not over-allocate.
160 |
161 | if (buffer == NULL || bufferSize < bytesToRead)
162 | {
163 | bufferSize = bytesToRead;
164 | buffer = reallocf(buffer, (size_t)bufferSize);
165 |
166 | if (buffer == NULL)
167 | {
168 | HTTPLogError(@"%@[%p]: Unable to allocate buffer", THIS_FILE, self);
169 |
170 | [self abort];
171 | return nil;
172 | }
173 | }
174 |
175 | // Perform the read
176 |
177 | HTTPLogVerbose(@"%@[%p]: Attempting to read %lu bytes from file", THIS_FILE, self, (unsigned long)bytesToRead);
178 |
179 | ssize_t result = read(fileFD, buffer, bytesToRead);
180 |
181 | // Check the results
182 |
183 | if (result < 0)
184 | {
185 | HTTPLogError(@"%@: Error(%i) reading file(%@)", THIS_FILE, errno, filePath);
186 |
187 | [self abort];
188 | return nil;
189 | }
190 | else if (result == 0)
191 | {
192 | HTTPLogError(@"%@: Read EOF on file(%@)", THIS_FILE, filePath);
193 |
194 | [self abort];
195 | return nil;
196 | }
197 | else // (result > 0)
198 | {
199 | HTTPLogVerbose(@"%@[%p]: Read %ld bytes from file", THIS_FILE, self, (long)result);
200 |
201 | fileOffset += result;
202 |
203 | return [NSData dataWithBytes:buffer length:result];
204 | }
205 | }
206 |
207 | - (BOOL)isDone
208 | {
209 | BOOL result = (fileOffset == fileLength);
210 |
211 | HTTPLogTrace2(@"%@[%p]: isDone - %@", THIS_FILE, self, (result ? @"YES" : @"NO"));
212 |
213 | return result;
214 | }
215 |
216 | - (NSString *)filePath
217 | {
218 | return filePath;
219 | }
220 |
221 | - (void)dealloc
222 | {
223 | HTTPLogTrace();
224 |
225 | if (fileFD != NULL_FD)
226 | {
227 | HTTPLogVerbose(@"%@[%p]: Close fd[%i]", THIS_FILE, self, fileFD);
228 |
229 | close(fileFD);
230 | }
231 |
232 | if (buffer)
233 | free(buffer);
234 |
235 | }
236 |
237 | @end
238 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPRedirectResponse.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "HTTPResponse.h"
3 |
4 |
5 | @interface HTTPRedirectResponse : NSObject
6 | {
7 | NSString *redirectPath;
8 | }
9 |
10 | - (id)initWithPath:(NSString *)redirectPath;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/Responses/HTTPRedirectResponse.m:
--------------------------------------------------------------------------------
1 | #import "HTTPRedirectResponse.h"
2 | #import "HTTPLogging.h"
3 |
4 | #if ! __has_feature(objc_arc)
5 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
6 | #endif
7 |
8 | // Log levels : off, error, warn, info, verbose
9 | // Other flags: trace
10 | static const int httpLogLevel = HTTP_LOG_LEVEL_OFF; // | HTTP_LOG_FLAG_TRACE;
11 |
12 |
13 | @implementation HTTPRedirectResponse
14 |
15 | - (id)initWithPath:(NSString *)path
16 | {
17 | if ((self = [super init]))
18 | {
19 | HTTPLogTrace();
20 |
21 | redirectPath = [path copy];
22 | }
23 | return self;
24 | }
25 |
26 | - (UInt64)contentLength
27 | {
28 | return 0;
29 | }
30 |
31 | - (UInt64)offset
32 | {
33 | return 0;
34 | }
35 |
36 | - (void)setOffset:(UInt64)offset
37 | {
38 | // Nothing to do
39 | }
40 |
41 | - (NSData *)readDataOfLength:(NSUInteger)length
42 | {
43 | HTTPLogTrace();
44 |
45 | return nil;
46 | }
47 |
48 | - (BOOL)isDone
49 | {
50 | return YES;
51 | }
52 |
53 | - (NSDictionary *)httpHeaders
54 | {
55 | HTTPLogTrace();
56 |
57 | return [NSDictionary dictionaryWithObject:redirectPath forKey:@"Location"];
58 | }
59 |
60 | - (NSInteger)status
61 | {
62 | HTTPLogTrace();
63 |
64 | return 302;
65 | }
66 |
67 | - (void)dealloc
68 | {
69 | HTTPLogTrace();
70 |
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/Vendor/CocoaHTTPServer/WebSocket.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class HTTPMessage;
4 | @class GCDAsyncSocket;
5 |
6 |
7 | #define WebSocketDidDieNotification @"WebSocketDidDie"
8 |
9 | @interface WebSocket : NSObject
10 | {
11 | dispatch_queue_t websocketQueue;
12 |
13 | HTTPMessage *request;
14 | GCDAsyncSocket *asyncSocket;
15 |
16 | NSData *term;
17 |
18 | BOOL isStarted;
19 | BOOL isOpen;
20 | BOOL isVersion76;
21 |
22 | id __unsafe_unretained delegate;
23 | }
24 |
25 | + (BOOL)isWebSocketRequest:(HTTPMessage *)request;
26 |
27 | - (id)initWithRequest:(HTTPMessage *)request socket:(GCDAsyncSocket *)socket;
28 |
29 | /**
30 | * Delegate option.
31 | *
32 | * In most cases it will be easier to subclass WebSocket,
33 | * but some circumstances may lead one to prefer standard delegate callbacks instead.
34 | **/
35 | @property (/* atomic */ unsafe_unretained) id delegate;
36 |
37 | /**
38 | * The WebSocket class is thread-safe, generally via it's GCD queue.
39 | * All public API methods are thread-safe,
40 | * and the subclass API methods are thread-safe as they are all invoked on the same GCD queue.
41 | **/
42 | @property (nonatomic, readonly) dispatch_queue_t websocketQueue;
43 |
44 | /**
45 | * Public API
46 | *
47 | * These methods are automatically called by the HTTPServer.
48 | * You may invoke the stop method yourself to close the WebSocket manually.
49 | **/
50 | - (void)start;
51 | - (void)stop;
52 |
53 | /**
54 | * Public API
55 | *
56 | * Sends a message over the WebSocket.
57 | * This method is thread-safe.
58 | **/
59 | - (void)sendMessage:(NSString *)msg;
60 |
61 | /**
62 | * Public API
63 | *
64 | * Sends a message over the WebSocket.
65 | * This method is thread-safe.
66 | **/
67 | - (void)sendData:(NSData *)msg;
68 |
69 | /**
70 | * Subclass API
71 | *
72 | * These methods are designed to be overriden by subclasses.
73 | **/
74 | - (void)didOpen;
75 | - (void)didReceiveMessage:(NSString *)msg;
76 | - (void)didClose;
77 |
78 | @end
79 |
80 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 | #pragma mark -
82 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
83 |
84 | /**
85 | * There are two ways to create your own custom WebSocket:
86 | *
87 | * - Subclass it and override the methods you're interested in.
88 | * - Use traditional delegate paradigm along with your own custom class.
89 | *
90 | * They both exist to allow for maximum flexibility.
91 | * In most cases it will be easier to subclass WebSocket.
92 | * However some circumstances may lead one to prefer standard delegate callbacks instead.
93 | * One such example, you're already subclassing another class, so subclassing WebSocket isn't an option.
94 | **/
95 |
96 | @protocol WebSocketDelegate
97 | @optional
98 |
99 | - (void)webSocketDidOpen:(WebSocket *)ws;
100 |
101 | - (void)webSocket:(WebSocket *)ws didReceiveMessage:(NSString *)msg;
102 |
103 | - (void)webSocketDidClose:(WebSocket *)ws;
104 |
105 | @end
106 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/DDASLLogger.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import "DDLog.h"
5 |
6 | /**
7 | * Welcome to Cocoa Lumberjack!
8 | *
9 | * The project page has a wealth of documentation if you have any questions.
10 | * https://github.com/robbiehanson/CocoaLumberjack
11 | *
12 | * If you're new to the project you may wish to read the "Getting Started" wiki.
13 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
14 | *
15 | *
16 | * This class provides a logger for the Apple System Log facility.
17 | *
18 | * As described in the "Getting Started" page,
19 | * the traditional NSLog() function directs it's output to two places:
20 | *
21 | * - Apple System Log
22 | * - StdErr (if stderr is a TTY) so log statements show up in Xcode console
23 | *
24 | * To duplicate NSLog() functionality you can simply add this logger and a tty logger.
25 | * However, if you instead choose to use file logging (for faster performance),
26 | * you may choose to use a file logger and a tty logger.
27 | **/
28 |
29 | @interface DDASLLogger : DDAbstractLogger
30 | {
31 | aslclient client;
32 | }
33 |
34 | + (DDASLLogger *)sharedInstance;
35 |
36 | // Inherited from DDAbstractLogger
37 |
38 | // - (id )logFormatter;
39 | // - (void)setLogFormatter:(id )formatter;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/DDASLLogger.m:
--------------------------------------------------------------------------------
1 | #import "DDASLLogger.h"
2 |
3 | #import
4 |
5 | /**
6 | * Welcome to Cocoa Lumberjack!
7 | *
8 | * The project page has a wealth of documentation if you have any questions.
9 | * https://github.com/robbiehanson/CocoaLumberjack
10 | *
11 | * If you're new to the project you may wish to read the "Getting Started" wiki.
12 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
13 | **/
14 |
15 | #if ! __has_feature(objc_arc)
16 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
17 | #endif
18 |
19 |
20 | @implementation DDASLLogger
21 |
22 | static DDASLLogger *sharedInstance;
23 |
24 | /**
25 | * The runtime sends initialize to each class in a program exactly one time just before the class,
26 | * or any class that inherits from it, is sent its first message from within the program. (Thus the
27 | * method may never be invoked if the class is not used.) The runtime sends the initialize message to
28 | * classes in a thread-safe manner. Superclasses receive this message before their subclasses.
29 | *
30 | * This method may also be called directly (assumably by accident), hence the safety mechanism.
31 | **/
32 | + (void)initialize
33 | {
34 | static BOOL initialized = NO;
35 | if (!initialized)
36 | {
37 | initialized = YES;
38 |
39 | sharedInstance = [[DDASLLogger alloc] init];
40 | }
41 | }
42 |
43 | + (DDASLLogger *)sharedInstance
44 | {
45 | return sharedInstance;
46 | }
47 |
48 | - (id)init
49 | {
50 | if (sharedInstance != nil)
51 | {
52 | return nil;
53 | }
54 |
55 | if ((self = [super init]))
56 | {
57 | // A default asl client is provided for the main thread,
58 | // but background threads need to create their own client.
59 |
60 | client = asl_open(NULL, "com.apple.console", 0);
61 | }
62 | return self;
63 | }
64 |
65 | - (void)logMessage:(DDLogMessage *)logMessage
66 | {
67 | NSString *logMsg = logMessage->logMsg;
68 |
69 | if (formatter)
70 | {
71 | logMsg = [formatter formatLogMessage:logMessage];
72 | }
73 |
74 | if (logMsg)
75 | {
76 | const char *msg = [logMsg UTF8String];
77 |
78 | int aslLogLevel;
79 | switch (logMessage->logFlag)
80 | {
81 | // Note: By default ASL will filter anything above level 5 (Notice).
82 | // So our mappings shouldn't go above that level.
83 |
84 | case LOG_FLAG_ERROR : aslLogLevel = ASL_LEVEL_CRIT; break;
85 | case LOG_FLAG_WARN : aslLogLevel = ASL_LEVEL_ERR; break;
86 | case LOG_FLAG_INFO : aslLogLevel = ASL_LEVEL_WARNING; break;
87 | default : aslLogLevel = ASL_LEVEL_NOTICE; break;
88 | }
89 |
90 | asl_log(client, NULL, aslLogLevel, "%s", msg);
91 | }
92 | }
93 |
94 | - (NSString *)loggerName
95 | {
96 | return @"cocoa.lumberjack.aslLogger";
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/DDAbstractDatabaseLogger.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "DDLog.h"
4 |
5 | /**
6 | * Welcome to Cocoa Lumberjack!
7 | *
8 | * The project page has a wealth of documentation if you have any questions.
9 | * https://github.com/robbiehanson/CocoaLumberjack
10 | *
11 | * If you're new to the project you may wish to read the "Getting Started" wiki.
12 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
13 | *
14 | *
15 | * This class provides an abstract implementation of a database logger.
16 | *
17 | * That is, it provides the base implementation for a database logger to build atop of.
18 | * All that is needed for a concrete database logger is to extend this class
19 | * and override the methods in the implementation file that are prefixed with "db_".
20 | **/
21 |
22 | @interface DDAbstractDatabaseLogger : DDAbstractLogger {
23 | @protected
24 | NSUInteger saveThreshold;
25 | NSTimeInterval saveInterval;
26 | NSTimeInterval maxAge;
27 | NSTimeInterval deleteInterval;
28 | BOOL deleteOnEverySave;
29 |
30 | BOOL saveTimerSuspended;
31 | NSUInteger unsavedCount;
32 | dispatch_time_t unsavedTime;
33 | dispatch_source_t saveTimer;
34 | dispatch_time_t lastDeleteTime;
35 | dispatch_source_t deleteTimer;
36 | }
37 |
38 | /**
39 | * Specifies how often to save the data to disk.
40 | * Since saving is an expensive operation (disk io) it is not done after every log statement.
41 | * These properties allow you to configure how/when the logger saves to disk.
42 | *
43 | * A save is done when either (whichever happens first):
44 | *
45 | * - The number of unsaved log entries reaches saveThreshold
46 | * - The amount of time since the oldest unsaved log entry was created reaches saveInterval
47 | *
48 | * You can optionally disable the saveThreshold by setting it to zero.
49 | * If you disable the saveThreshold you are entirely dependent on the saveInterval.
50 | *
51 | * You can optionally disable the saveInterval by setting it to zero (or a negative value).
52 | * If you disable the saveInterval you are entirely dependent on the saveThreshold.
53 | *
54 | * It's not wise to disable both saveThreshold and saveInterval.
55 | *
56 | * The default saveThreshold is 500.
57 | * The default saveInterval is 60 seconds.
58 | **/
59 | @property (assign, readwrite) NSUInteger saveThreshold;
60 | @property (assign, readwrite) NSTimeInterval saveInterval;
61 |
62 | /**
63 | * It is likely you don't want the log entries to persist forever.
64 | * Doing so would allow the database to grow infinitely large over time.
65 | *
66 | * The maxAge property provides a way to specify how old a log statement can get
67 | * before it should get deleted from the database.
68 | *
69 | * The deleteInterval specifies how often to sweep for old log entries.
70 | * Since deleting is an expensive operation (disk io) is is done on a fixed interval.
71 | *
72 | * An alternative to the deleteInterval is the deleteOnEverySave option.
73 | * This specifies that old log entries should be deleted during every save operation.
74 | *
75 | * You can optionally disable the maxAge by setting it to zero (or a negative value).
76 | * If you disable the maxAge then old log statements are not deleted.
77 | *
78 | * You can optionally disable the deleteInterval by setting it to zero (or a negative value).
79 | *
80 | * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted.
81 | *
82 | * It's not wise to enable both deleteInterval and deleteOnEverySave.
83 | *
84 | * The default maxAge is 7 days.
85 | * The default deleteInterval is 5 minutes.
86 | * The default deleteOnEverySave is NO.
87 | **/
88 | @property (assign, readwrite) NSTimeInterval maxAge;
89 | @property (assign, readwrite) NSTimeInterval deleteInterval;
90 | @property (assign, readwrite) BOOL deleteOnEverySave;
91 |
92 | /**
93 | * Forces a save of any pending log entries (flushes log entries to disk).
94 | **/
95 | - (void)savePendingLogEntries;
96 |
97 | /**
98 | * Removes any log entries that are older than maxAge.
99 | **/
100 | - (void)deleteOldLogEntries;
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/DDTTYLogger.h:
--------------------------------------------------------------------------------
1 | #import
2 | #if TARGET_OS_IPHONE
3 | #import
4 | #else
5 | #import
6 | #endif
7 |
8 | #import "DDLog.h"
9 |
10 | /**
11 | * Welcome to Cocoa Lumberjack!
12 | *
13 | * The project page has a wealth of documentation if you have any questions.
14 | * https://github.com/robbiehanson/CocoaLumberjack
15 | *
16 | * If you're new to the project you may wish to read the "Getting Started" wiki.
17 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
18 | *
19 | *
20 | * This class provides a logger for Terminal output or Xcode console output,
21 | * depending on where you are running your code.
22 | *
23 | * As described in the "Getting Started" page,
24 | * the traditional NSLog() function directs it's output to two places:
25 | *
26 | * - Apple System Log (so it shows up in Console.app)
27 | * - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
28 | *
29 | * To duplicate NSLog() functionality you can simply add this logger and an asl logger.
30 | * However, if you instead choose to use file logging (for faster performance),
31 | * you may choose to use only a file logger and a tty logger.
32 | **/
33 |
34 | @interface DDTTYLogger : DDAbstractLogger
35 | {
36 | NSCalendar *calendar;
37 | NSUInteger calendarUnitFlags;
38 |
39 | NSString *appName;
40 | char *app;
41 | size_t appLen;
42 |
43 | NSString *processID;
44 | char *pid;
45 | size_t pidLen;
46 |
47 | BOOL colorsEnabled;
48 | NSMutableArray *colorProfilesArray;
49 | NSMutableDictionary *colorProfilesDict;
50 | }
51 |
52 | + (DDTTYLogger *)sharedInstance;
53 |
54 | /* Inherited from the DDLogger protocol:
55 | *
56 | * Formatters may optionally be added to any logger.
57 | *
58 | * If no formatter is set, the logger simply logs the message as it is given in logMessage,
59 | * or it may use its own built in formatting style.
60 | *
61 | * More information about formatters can be found here:
62 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
63 | *
64 | * The actual implementation of these methods is inherited from DDAbstractLogger.
65 |
66 | - (id )logFormatter;
67 | - (void)setLogFormatter:(id )formatter;
68 |
69 | */
70 |
71 | /**
72 | * Want to use different colors for different log levels?
73 | * Enable this property.
74 | *
75 | * If you run the application via the Terminal (not Xcode),
76 | * the logger will map colors to xterm-256color or xterm-color (if available).
77 | *
78 | * Xcode does NOT natively support colors in the Xcode debugging console.
79 | * You'll need to install the XcodeColors plugin to see colors in the Xcode console.
80 | * https://github.com/robbiehanson/XcodeColors
81 | *
82 | * The default value if NO.
83 | **/
84 | @property (readwrite, assign) BOOL colorsEnabled;
85 |
86 | /**
87 | * The default color set (foregroundColor, backgroundColor) is:
88 | *
89 | * - LOG_FLAG_ERROR = (red, nil)
90 | * - LOG_FLAG_WARN = (orange, nil)
91 | *
92 | * You can customize the colors however you see fit.
93 | * Please note that you are passing a flag, NOT a level.
94 | *
95 | * GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :)
96 | * BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :(
97 | *
98 | * LOG_FLAG_INFO = 0...00100
99 | * LOG_LEVEL_INFO = 0...00111 <- Would match LOG_FLAG_INFO and LOG_FLAG_WARN and LOG_FLAG_ERROR
100 | *
101 | * If you run the application within Xcode, then the XcodeColors plugin is required.
102 | *
103 | * If you run the application from a shell, then DDTTYLogger will automatically map the given color to
104 | * the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
105 | *
106 | * This method invokes setForegroundColor:backgroundColor:forFlag:context: and passes the default context (0).
107 | **/
108 | #if TARGET_OS_IPHONE
109 | - (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask;
110 | #else
111 | - (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask;
112 | #endif
113 |
114 | /**
115 | * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
116 | *
117 | * A logging context is often used to identify log messages coming from a 3rd party framework,
118 | * although logging context's can be used for many different functions.
119 | *
120 | * Logging context's are explained in further detail here:
121 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext
122 | **/
123 | #if TARGET_OS_IPHONE
124 | - (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask context:(int)ctxt;
125 | #else
126 | - (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask context:(int)ctxt;
127 | #endif
128 |
129 | /**
130 | * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
131 | * For example, you could do something like this:
132 | *
133 | * static NSString *const PurpleTag = @"PurpleTag";
134 | *
135 | * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
136 | *
137 | * And then in your applicationDidFinishLaunching, or wherever you configure Lumberjack:
138 | *
139 | * #if TARGET_OS_IPHONE
140 | * UIColor *purple = [UIColor colorWithRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
141 | * #else
142 | * NSColor *purple = [NSColor colorWithCalibratedRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
143 | *
144 | * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
145 | * [DDLog addLogger:[DDTTYLogger sharedInstance]];
146 | *
147 | * This would essentially give you a straight NSLog replacement that prints in purple:
148 | *
149 | * DDLogPurple(@"I'm a purple log message!");
150 | **/
151 | #if TARGET_OS_IPHONE
152 | - (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forTag:(id )tag;
153 | #else
154 | - (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forTag:(id )tag;
155 | #endif
156 |
157 | /**
158 | * Clearing color profiles.
159 | **/
160 | - (void)clearColorsForFlag:(int)mask;
161 | - (void)clearColorsForFlag:(int)mask context:(int)context;
162 | - (void)clearColorsForTag:(id )tag;
163 | - (void)clearColorsForAllFlags;
164 | - (void)clearColorsForAllTags;
165 | - (void)clearAllColors;
166 |
167 | @end
168 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "DDLog.h"
3 |
4 | @class ContextFilterLogFormatter;
5 |
6 | /**
7 | * Welcome to Cocoa Lumberjack!
8 | *
9 | * The project page has a wealth of documentation if you have any questions.
10 | * https://github.com/robbiehanson/CocoaLumberjack
11 | *
12 | * If you're new to the project you may wish to read the "Getting Started" page.
13 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
14 | *
15 | *
16 | * This class provides a log formatter that filters log statements from a logging context not on the whitelist.
17 | *
18 | * A log formatter can be added to any logger to format and/or filter its output.
19 | * You can learn more about log formatters here:
20 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
21 | *
22 | * You can learn more about logging context's here:
23 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext
24 | *
25 | * But here's a quick overview / refresher:
26 | *
27 | * Every log statement has a logging context.
28 | * These come from the underlying logging macros defined in DDLog.h.
29 | * The default logging context is zero.
30 | * You can define multiple logging context's for use in your application.
31 | * For example, logically separate parts of your app each have a different logging context.
32 | * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context.
33 | **/
34 | @interface ContextWhitelistFilterLogFormatter : NSObject
35 |
36 | - (id)init;
37 |
38 | - (void)addToWhitelist:(int)loggingContext;
39 | - (void)removeFromWhitelist:(int)loggingContext;
40 |
41 | - (NSArray *)whitelist;
42 |
43 | - (BOOL)isOnWhitelist:(int)loggingContext;
44 |
45 | @end
46 |
47 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48 | #pragma mark -
49 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 |
51 | /**
52 | * This class provides a log formatter that filters log statements from a logging context on the blacklist.
53 | **/
54 | @interface ContextBlacklistFilterLogFormatter : NSObject
55 |
56 | - (id)init;
57 |
58 | - (void)addToBlacklist:(int)loggingContext;
59 | - (void)removeFromBlacklist:(int)loggingContext;
60 |
61 | - (NSArray *)blacklist;
62 |
63 | - (BOOL)isOnBlacklist:(int)loggingContext;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/Extensions/ContextFilterLogFormatter.m:
--------------------------------------------------------------------------------
1 | #import "ContextFilterLogFormatter.h"
2 | #import
3 |
4 | /**
5 | * Welcome to Cocoa Lumberjack!
6 | *
7 | * The project page has a wealth of documentation if you have any questions.
8 | * https://github.com/robbiehanson/CocoaLumberjack
9 | *
10 | * If you're new to the project you may wish to read the "Getting Started" wiki.
11 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
12 | **/
13 |
14 | #if ! __has_feature(objc_arc)
15 | #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
16 | #endif
17 |
18 | @interface LoggingContextSet : NSObject
19 |
20 | - (void)addToSet:(int)loggingContext;
21 | - (void)removeFromSet:(int)loggingContext;
22 |
23 | - (NSArray *)currentSet;
24 |
25 | - (BOOL)isInSet:(int)loggingContext;
26 |
27 | @end
28 |
29 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30 | #pragma mark -
31 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 |
33 | @implementation ContextWhitelistFilterLogFormatter
34 | {
35 | LoggingContextSet *contextSet;
36 | }
37 |
38 | - (id)init
39 | {
40 | if ((self = [super init]))
41 | {
42 | contextSet = [[LoggingContextSet alloc] init];
43 | }
44 | return self;
45 | }
46 |
47 |
48 | - (void)addToWhitelist:(int)loggingContext
49 | {
50 | [contextSet addToSet:loggingContext];
51 | }
52 |
53 | - (void)removeFromWhitelist:(int)loggingContext
54 | {
55 | [contextSet removeFromSet:loggingContext];
56 | }
57 |
58 | - (NSArray *)whitelist
59 | {
60 | return [contextSet currentSet];
61 | }
62 |
63 | - (BOOL)isOnWhitelist:(int)loggingContext
64 | {
65 | return [contextSet isInSet:loggingContext];
66 | }
67 |
68 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage
69 | {
70 | if ([self isOnWhitelist:logMessage->logContext])
71 | return logMessage->logMsg;
72 | else
73 | return nil;
74 | }
75 |
76 | @end
77 |
78 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79 | #pragma mark -
80 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 |
82 | @implementation ContextBlacklistFilterLogFormatter
83 | {
84 | LoggingContextSet *contextSet;
85 | }
86 |
87 | - (id)init
88 | {
89 | if ((self = [super init]))
90 | {
91 | contextSet = [[LoggingContextSet alloc] init];
92 | }
93 | return self;
94 | }
95 |
96 |
97 | - (void)addToBlacklist:(int)loggingContext
98 | {
99 | [contextSet addToSet:loggingContext];
100 | }
101 |
102 | - (void)removeFromBlacklist:(int)loggingContext
103 | {
104 | [contextSet removeFromSet:loggingContext];
105 | }
106 |
107 | - (NSArray *)blacklist
108 | {
109 | return [contextSet currentSet];
110 | }
111 |
112 | - (BOOL)isOnBlacklist:(int)loggingContext
113 | {
114 | return [contextSet isInSet:loggingContext];
115 | }
116 |
117 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage
118 | {
119 | if ([self isOnBlacklist:logMessage->logContext])
120 | return nil;
121 | else
122 | return logMessage->logMsg;
123 | }
124 |
125 | @end
126 |
127 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
128 | #pragma mark -
129 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130 |
131 | @implementation LoggingContextSet
132 | {
133 | OSSpinLock lock;
134 | NSMutableSet *set;
135 | }
136 |
137 | - (id)init
138 | {
139 | if ((self = [super init]))
140 | {
141 | set = [[NSMutableSet alloc] init];
142 | }
143 | return self;
144 | }
145 |
146 |
147 | - (void)addToSet:(int)loggingContext
148 | {
149 | OSSpinLockLock(&lock);
150 | {
151 | [set addObject:@(loggingContext)];
152 | }
153 | OSSpinLockUnlock(&lock);
154 | }
155 |
156 | - (void)removeFromSet:(int)loggingContext
157 | {
158 | OSSpinLockLock(&lock);
159 | {
160 | [set removeObject:@(loggingContext)];
161 | }
162 | OSSpinLockUnlock(&lock);
163 | }
164 |
165 | - (NSArray *)currentSet
166 | {
167 | NSArray *result = nil;
168 |
169 | OSSpinLockLock(&lock);
170 | {
171 | result = [set allObjects];
172 | }
173 | OSSpinLockUnlock(&lock);
174 |
175 | return result;
176 | }
177 |
178 | - (BOOL)isInSet:(int)loggingContext
179 | {
180 | BOOL result = NO;
181 |
182 | OSSpinLockLock(&lock);
183 | {
184 | result = [set containsObject:@(loggingContext)];
185 | }
186 | OSSpinLockUnlock(&lock);
187 |
188 | return result;
189 | }
190 |
191 | @end
192 |
--------------------------------------------------------------------------------
/Vendor/CocoaLumberjack/Extensions/DispatchQueueLogFormatter.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "DDLog.h"
4 |
5 |
6 | /**
7 | * Welcome to Cocoa Lumberjack!
8 | *
9 | * The project page has a wealth of documentation if you have any questions.
10 | * https://github.com/robbiehanson/CocoaLumberjack
11 | *
12 | * If you're new to the project you may wish to read the "Getting Started" page.
13 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
14 | *
15 | *
16 | * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id.
17 | *
18 | * A log formatter can be added to any logger to format and/or filter its output.
19 | * You can learn more about log formatters here:
20 | * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
21 | *
22 | * A typical NSLog (or DDTTYLogger) prints detailed info as [:].
23 | * For example:
24 | *
25 | * 2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here
26 | *
27 | * Where:
28 | * - 19928 = process id
29 | * - 5207 = thread id (mach_thread_id printed in hex)
30 | *
31 | * When using grand central dispatch (GCD), this information is less useful.
32 | * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool.
33 | * For example:
34 | *
35 | * 2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue
36 | * 2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue
37 | * 2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue
38 | *
39 | * This formatter allows you to replace the standard [box:info] with the dispatch_queue name.
40 | * For example:
41 | *
42 | * 2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue
43 | * 2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue
44 | * 2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue
45 | *
46 | * If the dispatch_queue doesn't have a set name, then it falls back to the thread name.
47 | * If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal).
48 | *
49 | * Note: If manually creating your own background threads (via NSThread/alloc/init or NSThread/detachNeThread),
50 | * you can use [[NSThread currentThread] setName:(NSString *)].
51 | **/
52 | @interface DispatchQueueLogFormatter : NSObject {
53 | @protected
54 |
55 | NSString *dateFormatString;
56 | }
57 |
58 | /**
59 | * Standard init method.
60 | * Configure using properties as desired.
61 | **/
62 | - (id)init;
63 |
64 | /**
65 | * The minQueueLength restricts the minimum size of the [detail box].
66 | * If the minQueueLength is set to 0, there is no restriction.
67 | *
68 | * For example, say a dispatch_queue has a label of "diskIO":
69 | *
70 | * If the minQueueLength is 0: [diskIO]
71 | * If the minQueueLength is 4: [diskIO]
72 | * If the minQueueLength is 5: [diskIO]
73 | * If the minQueueLength is 6: [diskIO]
74 | * If the minQueueLength is 7: [diskIO ]
75 | * If the minQueueLength is 8: [diskIO ]
76 | *
77 | * The default minQueueLength is 0 (no minimum, so [detail box] won't be padded).
78 | *
79 | * If you want every [detail box] to have the exact same width,
80 | * set both minQueueLength and maxQueueLength to the same value.
81 | **/
82 | @property (assign) NSUInteger minQueueLength;
83 |
84 | /**
85 | * The maxQueueLength restricts the number of characters that will be inside the [detail box].
86 | * If the maxQueueLength is 0, there is no restriction.
87 | *
88 | * For example, say a dispatch_queue has a label of "diskIO":
89 | *
90 | * If the maxQueueLength is 0: [diskIO]
91 | * If the maxQueueLength is 4: [disk]
92 | * If the maxQueueLength is 5: [diskI]
93 | * If the maxQueueLength is 6: [diskIO]
94 | * If the maxQueueLength is 7: [diskIO]
95 | * If the maxQueueLength is 8: [diskIO]
96 | *
97 | * The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated).
98 | *
99 | * If you want every [detail box] to have the exact same width,
100 | * set both minQueueLength and maxQueueLength to the same value.
101 | **/
102 | @property (assign) NSUInteger maxQueueLength;
103 |
104 | /**
105 | * Sometimes queue labels have long names like "com.apple.main-queue",
106 | * but you'd prefer something shorter like simply "main".
107 | *
108 | * This method allows you to set such preferred replacements.
109 | * The above example is set by default.
110 | *
111 | * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter.
112 | **/
113 | - (NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
114 | - (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
115 |
116 | @end
117 |
--------------------------------------------------------------------------------