appjam 0.1.8.8 → 0.1.8.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +22 -62
- data/lib/appjam/generators/gist.yml +1 -1
- data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.pbxproj +1166 -482
- data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.xcworkspace/xcuserdata/eiffel.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/EiffelApplication-Prefix.pch.tt +26 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenu.h +52 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenu.m +412 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenuItem.h +44 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenuItem.m +97 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton-highlighted.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton-highlighted@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem-highlighted.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem-highlighted@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus-highlighted.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus-highlighted@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-star.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-star@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/CMPopTipView/CMPopTipView.h +167 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/CMPopTipView/CMPopTipView.m +639 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/FXLabel/FXLabel.h +97 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/FXLabel/FXLabel.m +1080 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MBProgressHUD/MBProgressHUD.h +451 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MBProgressHUD/MBProgressHUD.m +865 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FacingView.h +42 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FacingView.m +56 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FoldView.h +90 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FoldView.m +316 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/MultiFoldView.h +104 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/MultiFoldView.m +516 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldConstants.h +49 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldNavigationController.h +18 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldNavigationController.m +88 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_left.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_left@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_right.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_right@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldSwipeHintView.h +25 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldSwipeHintView.m +76 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldView.h +131 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldView.m +941 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/Resources/swipe_guide.psd +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/Resources/swipe_guide2.psd +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/ShadowView.h +46 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/ShadowView.m +82 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/TouchThroughUIView.h +39 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/TouchThroughUIView.m +72 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/UIView+Screenshot.h +42 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/UIView+Screenshot.m +100 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/NSBubbleData.h +34 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/NSBubbleData.m +140 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleHeaderTableViewCell.h +17 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleHeaderTableViewCell.m +57 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableView.h +30 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableView.m +233 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewCell.h +19 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewCell.m +122 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewDataSource.h +24 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTypingTableViewCell.h +20 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTypingTableViewCell.m +56 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleMine.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleMine@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleSomeone.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleSomeone@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/missingAvatar.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/missingAvatar@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingMine.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingMine@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingSomeone.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingSomeone@2x.png +0 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIGlossyButton.h +124 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIGlossyButton.m +545 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIView+LayerEffects.h +22 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIView+LayerEffects.m +32 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFIncrementalStore.h +344 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFIncrementalStore.m +848 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFRESTClient.h +135 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFRESTClient.m +441 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/NSString+InflectorKit.h +40 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/NSString+InflectorKit.m +36 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/TTTStringInflector.h +76 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/TTTStringInflector.m +270 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/MKAnnotationView+WebCache.h +95 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/MKAnnotationView+WebCache.m +78 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDImageCache.h +144 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDImageCache.m +311 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageCompat.h +40 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageCompat.m +54 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDecoder.h +18 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDecoder.m +70 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloader.h +102 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloader.m +226 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloaderOperation.h +25 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloaderOperation.m +339 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageManager.h +167 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageManager.m +244 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageOperation.h +15 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImagePrefetcher.h +58 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImagePrefetcher.m +127 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIButton+WebCache.h +173 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIButton+WebCache.m +129 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIImageView+WebCache.h +140 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIImageView+WebCache.m +84 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationProgram.h +28 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationSequence.h +28 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationStep.h +49 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationProgram.m +100 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationSequence.m +85 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationStep.m +122 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaAsyncSocket/GCDAsyncSocket.h +1074 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaAsyncSocket/GCDAsyncSocket.m +7430 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDData.h +14 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDData.m +158 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDNumber.h +12 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDNumber.m +88 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDRange.h +56 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDRange.m +104 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPAuthenticationRequest.h +45 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPAuthenticationRequest.m +195 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPConnection.h +119 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPConnection.m +2708 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPLogging.h +136 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPMessage.h +48 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPMessage.m +113 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPResponse.h +149 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPServer.h +205 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPServer.m +772 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartFormDataParser.h +65 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartFormDataParser.m +529 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeader.h +33 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeader.m +86 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeaderField.h +23 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeaderField.m +211 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPAsyncFileResponse.h +75 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPAsyncFileResponse.m +405 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDataResponse.h +13 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDataResponse.m +79 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDynamicFileResponse.h +52 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDynamicFileResponse.m +292 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPErrorResponse.h +9 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPErrorResponse.m +38 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPFileResponse.h +25 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPFileResponse.m +237 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPRedirectResponse.h +12 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPRedirectResponse.m +73 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/WebSocket.h +105 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/WebSocket.m +791 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVConnection.h +7 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVConnection.m +160 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVResponse.h +11 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVResponse.m +372 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DELETEResponse.h +7 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DELETEResponse.m +49 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/PUTResponse.h +8 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/PUTResponse.m +69 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHpple.h +54 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHpple.m +102 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHppleElement.h +103 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHppleElement.m +200 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/XPathQuery.h +10 -0
- data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/XPathQuery.m +197 -0
- data/lib/appjam/version.rb +1 -1
- metadata +164 -3
@@ -0,0 +1,136 @@
|
|
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
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/**
|
2
|
+
* The HTTPMessage class is a simple Objective-C wrapper around Apple's CFHTTPMessage class.
|
3
|
+
**/
|
4
|
+
|
5
|
+
#import <Foundation/Foundation.h>
|
6
|
+
|
7
|
+
#if TARGET_OS_IPHONE
|
8
|
+
// Note: You may need to add the CFNetwork Framework to your project
|
9
|
+
#import <CFNetwork/CFNetwork.h>
|
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
|
@@ -0,0 +1,113 @@
|
|
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
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#import <Foundation/Foundation.h>
|
2
|
+
|
3
|
+
|
4
|
+
@protocol HTTPResponse
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Returns the length of the data in bytes.
|
8
|
+
* If you don't know the length in advance, implement the isChunked method and have it return YES.
|
9
|
+
**/
|
10
|
+
- (UInt64)contentLength;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* The HTTP server supports range requests in order to allow things like
|
14
|
+
* file download resumption and optimized streaming on mobile devices.
|
15
|
+
**/
|
16
|
+
- (UInt64)offset;
|
17
|
+
- (void)setOffset:(UInt64)offset;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Returns the data for the response.
|
21
|
+
* You do not have to return data of the exact length that is given.
|
22
|
+
* You may optionally return data of a lesser length.
|
23
|
+
* However, you must never return data of a greater length than requested.
|
24
|
+
* Doing so could disrupt proper support for range requests.
|
25
|
+
*
|
26
|
+
* To support asynchronous responses, read the discussion at the bottom of this header.
|
27
|
+
**/
|
28
|
+
- (NSData *)readDataOfLength:(NSUInteger)length;
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Should only return YES after the HTTPConnection has read all available data.
|
32
|
+
* That is, all data for the response has been returned to the HTTPConnection via the readDataOfLength method.
|
33
|
+
**/
|
34
|
+
- (BOOL)isDone;
|
35
|
+
|
36
|
+
@optional
|
37
|
+
|
38
|
+
/**
|
39
|
+
* If you need time to calculate any part of the HTTP response headers (status code or header fields),
|
40
|
+
* this method allows you to delay sending the headers so that you may asynchronously execute the calculations.
|
41
|
+
* Simply implement this method and return YES until you have everything you need concerning the headers.
|
42
|
+
*
|
43
|
+
* This method ties into the asynchronous response architecture of the HTTPConnection.
|
44
|
+
* You should read the full discussion at the bottom of this header.
|
45
|
+
*
|
46
|
+
* If you return YES from this method,
|
47
|
+
* the HTTPConnection will wait for you to invoke the responseHasAvailableData method.
|
48
|
+
* After you do, the HTTPConnection will again invoke this method to see if the response is ready to send the headers.
|
49
|
+
*
|
50
|
+
* You should only delay sending the headers until you have everything you need concerning just the headers.
|
51
|
+
* Asynchronously generating the body of the response is not an excuse to delay sending the headers.
|
52
|
+
* Instead you should tie into the asynchronous response architecture, and use techniques such as the isChunked method.
|
53
|
+
*
|
54
|
+
* Important: You should read the discussion at the bottom of this header.
|
55
|
+
**/
|
56
|
+
- (BOOL)delayResponseHeaders;
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Status code for response.
|
60
|
+
* Allows for responses such as redirect (301), etc.
|
61
|
+
**/
|
62
|
+
- (NSInteger)status;
|
63
|
+
|
64
|
+
/**
|
65
|
+
* If you want to add any extra HTTP headers to the response,
|
66
|
+
* simply return them in a dictionary in this method.
|
67
|
+
**/
|
68
|
+
- (NSDictionary *)httpHeaders;
|
69
|
+
|
70
|
+
/**
|
71
|
+
* If you don't know the content-length in advance,
|
72
|
+
* implement this method in your custom response class and return YES.
|
73
|
+
*
|
74
|
+
* Important: You should read the discussion at the bottom of this header.
|
75
|
+
**/
|
76
|
+
- (BOOL)isChunked;
|
77
|
+
|
78
|
+
/**
|
79
|
+
* This method is called from the HTTPConnection class when the connection is closed,
|
80
|
+
* or when the connection is finished with the response.
|
81
|
+
* If your response is asynchronous, you should implement this method so you know not to
|
82
|
+
* invoke any methods on the HTTPConnection after this method is called (as the connection may be deallocated).
|
83
|
+
**/
|
84
|
+
- (void)connectionDidClose;
|
85
|
+
|
86
|
+
@end
|
87
|
+
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Important notice to those implementing custom asynchronous and/or chunked responses:
|
91
|
+
*
|
92
|
+
* HTTPConnection supports asynchronous responses. All you have to do in your custom response class is
|
93
|
+
* asynchronously generate the response, and invoke HTTPConnection's responseHasAvailableData method.
|
94
|
+
* You don't have to wait until you have all of the response ready to invoke this method. For example, if you
|
95
|
+
* generate the response in incremental chunks, you could call responseHasAvailableData after generating
|
96
|
+
* each chunk. Please see the HTTPAsyncFileResponse class for an example of how to do this.
|
97
|
+
*
|
98
|
+
* The normal flow of events for an HTTPConnection while responding to a request is like this:
|
99
|
+
* - Send http resopnse headers
|
100
|
+
* - Get data from response via readDataOfLength method.
|
101
|
+
* - Add data to asyncSocket's write queue.
|
102
|
+
* - Wait for asyncSocket to notify it that the data has been sent.
|
103
|
+
* - Get more data from response via readDataOfLength method.
|
104
|
+
* - ... continue this cycle until the entire response has been sent.
|
105
|
+
*
|
106
|
+
* With an asynchronous response, the flow is a little different.
|
107
|
+
*
|
108
|
+
* First the HTTPResponse is given the opportunity to postpone sending the HTTP response headers.
|
109
|
+
* This allows the response to asynchronously execute any code needed to calculate a part of the header.
|
110
|
+
* An example might be the response needs to generate some custom header fields,
|
111
|
+
* or perhaps the response needs to look for a resource on network-attached storage.
|
112
|
+
* Since the network-attached storage may be slow, the response doesn't know whether to send a 200 or 404 yet.
|
113
|
+
* In situations such as this, the HTTPResponse simply implements the delayResponseHeaders method and returns YES.
|
114
|
+
* After returning YES from this method, the HTTPConnection will wait until the response invokes its
|
115
|
+
* responseHasAvailableData method. After this occurs, the HTTPConnection will again query the delayResponseHeaders
|
116
|
+
* method to see if the response is ready to send the headers.
|
117
|
+
* This cycle will continue until the delayResponseHeaders method returns NO.
|
118
|
+
*
|
119
|
+
* You should only delay sending the response headers until you have everything you need concerning just the headers.
|
120
|
+
* Asynchronously generating the body of the response is not an excuse to delay sending the headers.
|
121
|
+
*
|
122
|
+
* After the response headers have been sent, the HTTPConnection calls your readDataOfLength method.
|
123
|
+
* You may or may not have any available data at this point. If you don't, then simply return nil.
|
124
|
+
* You should later invoke HTTPConnection's responseHasAvailableData when you have data to send.
|
125
|
+
*
|
126
|
+
* You don't have to keep track of when you return nil in the readDataOfLength method, or how many times you've invoked
|
127
|
+
* responseHasAvailableData. Just simply call responseHasAvailableData whenever you've generated new data, and
|
128
|
+
* return nil in your readDataOfLength whenever you don't have any available data in the requested range.
|
129
|
+
* HTTPConnection will automatically detect when it should be requesting new data and will act appropriately.
|
130
|
+
*
|
131
|
+
* It's important that you also keep in mind that the HTTP server supports range requests.
|
132
|
+
* The setOffset method is mandatory, and should not be ignored.
|
133
|
+
* Make sure you take into account the offset within the readDataOfLength method.
|
134
|
+
* You should also be aware that the HTTPConnection automatically sorts any range requests.
|
135
|
+
* So if your setOffset method is called with a value of 100, then you can safely release bytes 0-99.
|
136
|
+
*
|
137
|
+
* HTTPConnection can also help you keep your memory footprint small.
|
138
|
+
* Imagine you're dynamically generating a 10 MB response. You probably don't want to load all this data into
|
139
|
+
* RAM, and sit around waiting for HTTPConnection to slowly send it out over the network. All you need to do
|
140
|
+
* is pay attention to when HTTPConnection requests more data via readDataOfLength. This is because HTTPConnection
|
141
|
+
* will never allow asyncSocket's write queue to get much bigger than READ_CHUNKSIZE bytes. You should
|
142
|
+
* consider how you might be able to take advantage of this fact to generate your asynchronous response on demand,
|
143
|
+
* while at the same time keeping your memory footprint small, and your application lightning fast.
|
144
|
+
*
|
145
|
+
* If you don't know the content-length in advanced, you should also implement the isChunked method.
|
146
|
+
* This means the response will not include a Content-Length header, and will instead use "Transfer-Encoding: chunked".
|
147
|
+
* There's a good chance that if your response is asynchronous and dynamic, it's also chunked.
|
148
|
+
* If your response is chunked, you don't need to worry about range requests.
|
149
|
+
**/
|
@@ -0,0 +1,205 @@
|
|
1
|
+
#import <Foundation/Foundation.h>
|
2
|
+
|
3
|
+
@class GCDAsyncSocket;
|
4
|
+
@class WebSocket;
|
5
|
+
|
6
|
+
#if TARGET_OS_IPHONE
|
7
|
+
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 40000 // iPhone 4.0
|
8
|
+
#define IMPLEMENTED_PROTOCOLS <NSNetServiceDelegate>
|
9
|
+
#else
|
10
|
+
#define IMPLEMENTED_PROTOCOLS
|
11
|
+
#endif
|
12
|
+
#else
|
13
|
+
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 // Mac OS X 10.6
|
14
|
+
#define IMPLEMENTED_PROTOCOLS <NSNetServiceDelegate>
|
15
|
+
#else
|
16
|
+
#define IMPLEMENTED_PROTOCOLS
|
17
|
+
#endif
|
18
|
+
#endif
|
19
|
+
|
20
|
+
|
21
|
+
@interface HTTPServer : NSObject IMPLEMENTED_PROTOCOLS
|
22
|
+
{
|
23
|
+
// Underlying asynchronous TCP/IP socket
|
24
|
+
GCDAsyncSocket *asyncSocket;
|
25
|
+
|
26
|
+
// Dispatch queues
|
27
|
+
dispatch_queue_t serverQueue;
|
28
|
+
dispatch_queue_t connectionQueue;
|
29
|
+
void *IsOnServerQueueKey;
|
30
|
+
void *IsOnConnectionQueueKey;
|
31
|
+
|
32
|
+
// HTTP server configuration
|
33
|
+
NSString *documentRoot;
|
34
|
+
Class connectionClass;
|
35
|
+
NSString *interface;
|
36
|
+
UInt16 port;
|
37
|
+
|
38
|
+
// NSNetService and related variables
|
39
|
+
NSNetService *netService;
|
40
|
+
NSString *domain;
|
41
|
+
NSString *type;
|
42
|
+
NSString *name;
|
43
|
+
NSString *publishedName;
|
44
|
+
NSDictionary *txtRecordDictionary;
|
45
|
+
|
46
|
+
// Connection management
|
47
|
+
NSMutableArray *connections;
|
48
|
+
NSMutableArray *webSockets;
|
49
|
+
NSLock *connectionsLock;
|
50
|
+
NSLock *webSocketsLock;
|
51
|
+
|
52
|
+
BOOL isRunning;
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Specifies the document root to serve files from.
|
57
|
+
* For example, if you set this to "/Users/<your_username>/Sites",
|
58
|
+
* then it will serve files out of the local Sites directory (including subdirectories).
|
59
|
+
*
|
60
|
+
* The default value is nil.
|
61
|
+
* The default server configuration will not serve any files until this is set.
|
62
|
+
*
|
63
|
+
* If you change the documentRoot while the server is running,
|
64
|
+
* the change will affect future incoming http connections.
|
65
|
+
**/
|
66
|
+
- (NSString *)documentRoot;
|
67
|
+
- (void)setDocumentRoot:(NSString *)value;
|
68
|
+
|
69
|
+
/**
|
70
|
+
* The connection class is the class used to handle incoming HTTP connections.
|
71
|
+
*
|
72
|
+
* The default value is [HTTPConnection class].
|
73
|
+
* You can override HTTPConnection, and then set this to [MyHTTPConnection class].
|
74
|
+
*
|
75
|
+
* If you change the connectionClass while the server is running,
|
76
|
+
* the change will affect future incoming http connections.
|
77
|
+
**/
|
78
|
+
- (Class)connectionClass;
|
79
|
+
- (void)setConnectionClass:(Class)value;
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Set what interface you'd like the server to listen on.
|
83
|
+
* By default this is nil, which causes the server to listen on all available interfaces like en1, wifi etc.
|
84
|
+
*
|
85
|
+
* The interface may be specified by name (e.g. "en1" or "lo0") or by IP address (e.g. "192.168.4.34").
|
86
|
+
* You may also use the special strings "localhost" or "loopback" to specify that
|
87
|
+
* the socket only accept connections from the local machine.
|
88
|
+
**/
|
89
|
+
- (NSString *)interface;
|
90
|
+
- (void)setInterface:(NSString *)value;
|
91
|
+
|
92
|
+
/**
|
93
|
+
* The port number to run the HTTP server on.
|
94
|
+
*
|
95
|
+
* The default port number is zero, meaning the server will automatically use any available port.
|
96
|
+
* This is the recommended port value, as it avoids possible port conflicts with other applications.
|
97
|
+
* Technologies such as Bonjour can be used to allow other applications to automatically discover the port number.
|
98
|
+
*
|
99
|
+
* Note: As is common on most OS's, you need root privledges to bind to port numbers below 1024.
|
100
|
+
*
|
101
|
+
* You can change the port property while the server is running, but it won't affect the running server.
|
102
|
+
* To actually change the port the server is listening for connections on you'll need to restart the server.
|
103
|
+
*
|
104
|
+
* The listeningPort method will always return the port number the running server is listening for connections on.
|
105
|
+
* If the server is not running this method returns 0.
|
106
|
+
**/
|
107
|
+
- (UInt16)port;
|
108
|
+
- (UInt16)listeningPort;
|
109
|
+
- (void)setPort:(UInt16)value;
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Bonjour domain for publishing the service.
|
113
|
+
* The default value is "local.".
|
114
|
+
*
|
115
|
+
* Note: Bonjour publishing requires you set a type.
|
116
|
+
*
|
117
|
+
* If you change the domain property after the bonjour service has already been published (server already started),
|
118
|
+
* you'll need to invoke the republishBonjour method to update the broadcasted bonjour service.
|
119
|
+
**/
|
120
|
+
- (NSString *)domain;
|
121
|
+
- (void)setDomain:(NSString *)value;
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Bonjour name for publishing the service.
|
125
|
+
* The default value is "".
|
126
|
+
*
|
127
|
+
* If using an empty string ("") for the service name when registering,
|
128
|
+
* the system will automatically use the "Computer Name".
|
129
|
+
* Using an empty string will also handle name conflicts
|
130
|
+
* by automatically appending a digit to the end of the name.
|
131
|
+
*
|
132
|
+
* Note: Bonjour publishing requires you set a type.
|
133
|
+
*
|
134
|
+
* If you change the name after the bonjour service has already been published (server already started),
|
135
|
+
* you'll need to invoke the republishBonjour method to update the broadcasted bonjour service.
|
136
|
+
*
|
137
|
+
* The publishedName method will always return the actual name that was published via the bonjour service.
|
138
|
+
* If the service is not running this method returns nil.
|
139
|
+
**/
|
140
|
+
- (NSString *)name;
|
141
|
+
- (NSString *)publishedName;
|
142
|
+
- (void)setName:(NSString *)value;
|
143
|
+
|
144
|
+
/**
|
145
|
+
* Bonjour type for publishing the service.
|
146
|
+
* The default value is nil.
|
147
|
+
* The service will not be published via bonjour unless the type is set.
|
148
|
+
*
|
149
|
+
* If you wish to publish the service as a traditional HTTP server, you should set the type to be "_http._tcp.".
|
150
|
+
*
|
151
|
+
* If you change the type after the bonjour service has already been published (server already started),
|
152
|
+
* you'll need to invoke the republishBonjour method to update the broadcasted bonjour service.
|
153
|
+
**/
|
154
|
+
- (NSString *)type;
|
155
|
+
- (void)setType:(NSString *)value;
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Republishes the service via bonjour if the server is running.
|
159
|
+
* If the service was not previously published, this method will publish it (if the server is running).
|
160
|
+
**/
|
161
|
+
- (void)republishBonjour;
|
162
|
+
|
163
|
+
/**
|
164
|
+
*
|
165
|
+
**/
|
166
|
+
- (NSDictionary *)TXTRecordDictionary;
|
167
|
+
- (void)setTXTRecordDictionary:(NSDictionary *)dict;
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Attempts to starts the server on the configured port, interface, etc.
|
171
|
+
*
|
172
|
+
* If an error occurs, this method returns NO and sets the errPtr (if given).
|
173
|
+
* Otherwise returns YES on success.
|
174
|
+
*
|
175
|
+
* Some examples of errors that might occur:
|
176
|
+
* - You specified the server listen on a port which is already in use by another application.
|
177
|
+
* - You specified the server listen on a port number below 1024, which requires root priviledges.
|
178
|
+
*
|
179
|
+
* Code Example:
|
180
|
+
*
|
181
|
+
* NSError *err = nil;
|
182
|
+
* if (![httpServer start:&err])
|
183
|
+
* {
|
184
|
+
* NSLog(@"Error starting http server: %@", err);
|
185
|
+
* }
|
186
|
+
**/
|
187
|
+
- (BOOL)start:(NSError **)errPtr;
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Stops the server, preventing it from accepting any new connections.
|
191
|
+
* You may specify whether or not you want to close the existing client connections.
|
192
|
+
*
|
193
|
+
* The default stop method (with no arguments) will close any existing connections. (It invokes [self stop:NO])
|
194
|
+
**/
|
195
|
+
- (void)stop;
|
196
|
+
- (void)stop:(BOOL)keepExistingConnections;
|
197
|
+
|
198
|
+
- (BOOL)isRunning;
|
199
|
+
|
200
|
+
- (void)addWebSocket:(WebSocket *)ws;
|
201
|
+
|
202
|
+
- (NSUInteger)numberOfHTTPConnections;
|
203
|
+
- (NSUInteger)numberOfWebSocketConnections;
|
204
|
+
|
205
|
+
@end
|