├── .appledoc.plist ├── .gitignore ├── .gitmodules ├── CURLHandle.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── WorkspaceSettings.xcsettings ├── CURLHandleSource ├── CURLHTTPParsing.h ├── CURLHTTPParsing.m ├── CURLHandle.h ├── CURLHandle.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ ├── CURLHandle.xcscheme │ │ ├── Libraries.xcscheme │ │ └── Standalone Test.xcscheme ├── CURLHandle_Prefix.pch ├── CURLList.h ├── CURLList.m ├── CURLMultiHandle.h ├── CURLMultiHandle.m ├── CURLProtocol.h ├── CURLProtocol.m ├── CURLRequest.h ├── CURLRequest.m ├── CURLResponse.h ├── CURLResponse.m ├── CURLSocketRegistration.h ├── CURLSocketRegistration.m ├── CURLTransfer+MultiSupport.h ├── CURLTransfer+TestingSupport.h ├── CURLTransfer.h ├── CURLTransfer.m ├── Info.plist ├── NSDictionary+CURLHandle.h ├── NSDictionary+CURLHandle.m ├── Tests │ ├── CURLHandleBasedTest.h │ ├── CURLHandleBasedTest.m │ ├── CURLHandleTests-Info.plist │ ├── CURLHandleTests-Prefix.pch │ ├── CURLMultiTests.m │ ├── CURLProtocolTests.m │ ├── CURLTransferTests.m │ ├── StandaloneGcdTest.m │ ├── StandaloneGcdWaitTest.m │ ├── StandaloneNoGcdTest.m │ ├── TestContent.txt │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── multi-gcd-crashtest-wait.c │ ├── multi-gcd-crashtest.c │ ├── multi-gcd-wait.c │ ├── multi-gcd.c │ ├── multi-nogcd-crashtest.c │ └── upload-root.c ├── built │ ├── include │ │ ├── cares-i386 │ │ │ └── ares_build.h │ │ ├── cares-x86_64 │ │ │ └── ares_build.h │ │ ├── curl-i386 │ │ │ └── curl │ │ │ │ ├── curl.h │ │ │ │ ├── curlbuild.h │ │ │ │ ├── curlrules.h │ │ │ │ ├── curlver.h │ │ │ │ ├── easy.h │ │ │ │ ├── mprintf.h │ │ │ │ ├── multi.h │ │ │ │ ├── stdcheaders.h │ │ │ │ └── typecheck-gcc.h │ │ └── curl-x86_64 │ │ │ └── curl │ │ │ ├── curl.h │ │ │ ├── curlbuild.h │ │ │ ├── curlrules.h │ │ │ ├── curlver.h │ │ │ ├── easy.h │ │ │ ├── mprintf.h │ │ │ ├── multi.h │ │ │ ├── stdcheaders.h │ │ │ └── typecheck-gcc.h │ ├── libcares.dylib │ ├── libcares.dylib.dSYM │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ └── DWARF │ │ │ └── libcares.dylib │ ├── libcurl.dylib │ └── libcurl.dylib.dSYM │ │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── DWARF │ │ └── libcurl.dylib ├── libcares-README.txt └── libcurl-README.txt ├── CURLHandleTesterSource ├── CURLHandleTester.xcodeproj │ └── project.pbxproj ├── CURLHandleTester_Prefix.pch ├── English.lproj │ ├── FindPanel.nib │ │ ├── classes.nib │ │ ├── info.nib │ │ ├── keyedobjects.nib │ │ └── objects.nib │ ├── MainMenu-preQuentin.nib │ │ ├── classes.nib │ │ ├── info.nib │ │ ├── keyedobjects.nib │ │ └── objects.nib │ └── MainMenu.nib │ │ ├── classes.nib │ │ ├── info.nib │ │ └── objects.nib ├── Info.plist ├── NSData+plist.h ├── NSData+plist.m ├── TestController.h ├── TestController.m ├── TextFinder.h ├── TextFinder.m ├── curl.icns └── main.m ├── Documentation ├── Building Libraries-template.md ├── CURLHandle+extras.html ├── CURLHandle.html ├── NSArray+CurlHTTPExtensions.html ├── NSDictionary+CurlHTTPExtensions.html ├── NSString+CurlHTTPExtensions.html ├── Release Notes-template.md └── Submodule organisation notes.graffle ├── README.md └── Scripts ├── build-libs.sh ├── c-ares-clean.sh ├── c-ares-combine.sh ├── c-ares-config.sh ├── c-ares-copy-built.sh ├── c-ares-make.sh ├── curl-clean.sh ├── curl-combine.sh ├── curl-config.sh ├── curl-make.sh ├── install-tools.sh ├── rename-install.sh ├── setup ├── test-libs.sh ├── test.sh ├── useftpserver.sh └── usemockserver.sh /.appledoc.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --include 6 | 7 | Documentation 8 | 9 | --ignore 10 | 11 | curl 12 | c-ares 13 | SFTP/libssh2 14 | SFTP/openssl 15 | SFTP/build 16 | CURLHandleSource/Tests/MockServer 17 | CURLHandleTesterSource 18 | test-build 19 | .git 20 | .gitmodules 21 | .gitignore 22 | 23 | --index-desc 24 | 25 | README.md 26 | 27 | --logformat 28 | xcode 29 | --exit-threshold 30 | 2 31 | --explicit-crossref 32 | 33 | --project-company 34 | Karelia Systems 35 | --company-id 36 | com.karelia 37 | --keep-undocumented-members 38 | 39 | --keep-undocumented-objects 40 | 41 | --merge-categories 42 | 43 | --keep-merged-sections 44 | 45 | --prefix-merged-sections 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | *.DS_Store 3 | 4 | # Xcode 5 | build 6 | profile 7 | *.pbxuser 8 | *.mode1v3 9 | *.mode2v3 10 | *.perspectivev3 11 | *.xcuserstate 12 | xcuserdata/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "curl"] 2 | path = curl 3 | url = https://github.com/karelia/curl.git 4 | [submodule "c-ares"] 5 | path = c-ares 6 | url = https://github.com/bagder/c-ares.git 7 | [submodule "SFTP"] 8 | path = SFTP 9 | url = https://github.com/karelia/libssh2_sftp-Cocoa-wrapper.git 10 | [submodule "CURLHandleSource/Tests/MockServer"] 11 | path = CURLHandleSource/Tests/MockServer 12 | url = https://github.com/karelia/MockServer.git 13 | -------------------------------------------------------------------------------- /CURLHandle.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CURLHandle.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHTTPParsing.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+CURLHandle.h 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import 9 | 10 | @interface NSString (CURLHandle) 11 | 12 | - (NSString *) headerHTTPVersion; 13 | - (NSDictionary *) allHTTPHeaderFields; 14 | - (NSString *) headerKey; 15 | - (NSString *) headerValue; 16 | - (NSArray *) componentsSeparatedByLineSeparators; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHTTPParsing.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+CURLHandle.m 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import "CURLHTTPParsing.h" 9 | 10 | @implementation NSString (CURLHandle) 11 | 12 | - (NSString *) headerHTTPVersion 13 | { 14 | NSString *result = nil; 15 | // Get the first "word" of the first line of the headers 16 | NSRange whereSpace = [self rangeOfString:@" "]; 17 | if (NSNotFound != whereSpace.location) 18 | { 19 | result = [self substringToIndex:whereSpace.location]; 20 | } 21 | return result; 22 | } 23 | 24 | /*" Create a dictionary from the HTTP headers. "*/ 25 | 26 | - (NSDictionary *) allHTTPHeaderFields; 27 | { 28 | NSArray *components = [self componentsSeparatedByLineSeparators]; 29 | NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:[components count] - 1]; 30 | 31 | NSEnumerator *theEnum = [components objectEnumerator]; 32 | NSString *theLine = [theEnum nextObject]; // result code -- ignore 33 | (void)theLine; 34 | while (nil != (theLine = [theEnum nextObject]) ) 35 | { 36 | NSString *key = [theLine headerKey]; 37 | NSString *value = [theLine headerValue]; 38 | if (nil != key && nil != value) 39 | { 40 | // Add a single dictionary for this header name/value 41 | [result setObject:value forKey:key]; 42 | } 43 | } 44 | return result; 45 | } 46 | 47 | /*" Given a line of a header, e.g. "Foo: Bar" "*/ 48 | 49 | - (NSString *) headerKey 50 | { 51 | NSString *result = nil; 52 | NSRange whereColon = [self rangeOfString:@": "]; 53 | if (NSNotFound != whereColon.location) 54 | { 55 | result = [self substringToIndex:whereColon.location]; 56 | } 57 | return result; 58 | } 59 | 60 | /*" Given a line of a header, e.g. "Foo: Bar", return the value in lowercase form, e.g. "bar". "*/ 61 | 62 | - (NSString *) headerValue 63 | { 64 | NSString *result = nil; 65 | NSRange whereColon = [self rangeOfString:@": "]; 66 | if (NSNotFound != whereColon.location) 67 | { 68 | result = [self substringFromIndex:whereColon.location + 2]; 69 | } 70 | return result; 71 | } 72 | 73 | 74 | /*" Split a string into lines separated by any of the various newline characters. Equivalent to componentsSeparatedByString:@"\n" but it works with the different line separators: \r, \n, \r\n, 0x2028, 0x2029 "*/ 75 | 76 | - (NSArray *) componentsSeparatedByLineSeparators 77 | { 78 | NSMutableArray *result = [NSMutableArray array]; 79 | NSRange range = NSMakeRange(0,0); 80 | NSUInteger start, end; 81 | NSUInteger contentsEnd = 0; 82 | 83 | while (contentsEnd < [self length]) 84 | { 85 | [self getLineStart:&start end:&end contentsEnd:&contentsEnd forRange:range]; 86 | [result addObject:[self substringWithRange:NSMakeRange(start,contentsEnd-start)]]; 87 | range.location = end; 88 | range.length = 0; 89 | } 90 | return result; 91 | } 92 | @end 93 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLHandle.h 3 | // CURLHandle 4 | // 5 | // Created by Mike on 19/06/2013. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import 12 | #import 13 | #import 14 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle.xcodeproj/xcshareddata/xcschemes/CURLHandle.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 44 | 46 | 47 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | 57 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 85 | 87 | 88 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle.xcodeproj/xcshareddata/xcschemes/Libraries.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 56 | 57 | 58 | 59 | 65 | 66 | 68 | 69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle.xcodeproj/xcshareddata/xcschemes/Standalone Test.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 64 | 65 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLHandle_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // CURLHandle 3 | // 4 | // Prefix header for all source files of the 'CURLHandle' target in the 'CURLHandle' project. 5 | // Copyright (c) 2013 Karelia Software. All rights reserved. 6 | // 7 | 8 | #ifdef __OBJC__ 9 | #import 10 | #endif 11 | 12 | // Comment/uncomment these to control logging for various aspects of CurlHandle. 13 | 14 | //#define CURLHandleLog(...) NSLog(@"%@: %@", self, [NSString stringWithFormat:__VA_ARGS__]) 15 | //#define CURLMultiLog(...) NSLog(@"%@: %@", self, [NSString stringWithFormat:__VA_ARGS__]) 16 | //#define CURLMultiLogError(...) NSLog(@"%@: %@", self, [NSString stringWithFormat:__VA_ARGS__]) 17 | //#define CURLProtocolLog(...) NSLog(@"%@: %@", self, [NSString stringWithFormat:__VA_ARGS__]) 18 | //#define CURLProtocolError(...) NSLog(@"%@: %@", self, [NSString stringWithFormat:__VA_ARGS__]) 19 | 20 | 21 | // Comment this definition out to have CURLMultiLogDetail do the same as CURLMultiLog (which will result in more output assuming that CURLMultiLog is enabled) 22 | 23 | #define CURLMultiLogDetail(...) 24 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLList.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLList.h 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 28/03/2013. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | Wrapper for the curl_slist structure. 13 | 14 | You can make a list from an array or a single object, using listWithContentsOrArray: or listWithString:. 15 | You can then append items to it with appendObject: 16 | 17 | There is no way to remove or re-order items, and the only way to empty it is to release it. 18 | 19 | The curl_slist type is only designed to contain strings. When you add something to CURLList, 20 | it calls description on it to get a textual representation. 21 | */ 22 | 23 | @interface CURLList : NSObject 24 | { 25 | struct curl_slist* _list; 26 | } 27 | 28 | /** 29 | The underlying curl_slist structure. 30 | */ 31 | 32 | @property (readonly, nonatomic) struct curl_slist* list; 33 | 34 | /** 35 | Create a list from an array of objects. 36 | 37 | We will call [NSObject description] on each object to obtain a textual representation, which is what will actually be added to the list. 38 | 39 | @param array The items for the list - must contain only NSString objects. 40 | @return The new list. 41 | */ 42 | 43 | + (CURLList*)listWithArray:(NSArray*)array; 44 | 45 | /** 46 | Create a list with a single object. 47 | 48 | We will call [NSObject description] on the object to obtain a textual representation, which is what will actually be added to the list. 49 | 50 | @param object An object to add to the new list. 51 | @return The new list. 52 | */ 53 | 54 | + (CURLList*)listWithObject:(id)object; 55 | 56 | /** 57 | Add an object to the list. 58 | 59 | We will call [NSObject description] on the object to obtain a textual representation, which is what will actually be added to the list. 60 | 61 | @param object The object to add. 62 | */ 63 | 64 | - (void)addObject:(id)object; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLList.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLList.m 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 28/03/2013. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLList.h" 10 | 11 | #import 12 | 13 | @implementation CURLList 14 | 15 | @synthesize list = _list; 16 | 17 | + (CURLList*)listWithArray:(NSArray *)array 18 | { 19 | CURLList* list = [[CURLList alloc] init]; 20 | for (id object in array) 21 | { 22 | [list addObject:object]; 23 | } 24 | 25 | return [list autorelease]; 26 | } 27 | 28 | + (CURLList*)listWithObject:(id)object 29 | { 30 | CURLList* list = [[CURLList alloc] init]; 31 | [list addObject:object]; 32 | 33 | return [list autorelease]; 34 | } 35 | 36 | - (void)addObject:(id)object 37 | { 38 | _list = curl_slist_append(_list, [[object description] UTF8String]); 39 | } 40 | 41 | - (void)dealloc 42 | { 43 | if (_list) 44 | { 45 | curl_slist_free_all(_list); 46 | } 47 | 48 | [super dealloc]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLMultiHandle.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLMultiHandle.h 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 20/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | #ifndef CURLMultiLog 14 | #define CURLMultiLog(...) // no logging by default - to enable it, add something like this to the prefix: #define CURLMultiLog NSLog 15 | #endif 16 | 17 | #ifndef CURLMultiLogError 18 | #define CURLMultiLogError NSLog 19 | #endif 20 | 21 | #ifndef CURLMultiLogDetail 22 | #define CURLMultiLogDetail CURLMultiLog 23 | #endif 24 | 25 | @class CURLTransfer; 26 | @class CURLSocketRegistration; 27 | 28 | /** 29 | * Wrapper for a curl_multi handle. 30 | * In general you shouldn't use this class directly - use the extensions in NSURLRequest+CURLHandle 31 | * instead, and work with normal NSURLConnections. 32 | * 33 | * CURLProtocol uses the global sharedInstance to implement the NSURLRequest/NSURLConnection 34 | * integration. 35 | * 36 | * There's nothing to stop you making other instances if you want to - it's just not really necessary, particularly 37 | * as we don't expose the curl multi externally. 38 | * 39 | * This class works by setting up a serial GCD queue to process all events associated with the multi. We add 40 | * gcd dispatch sources for each socket that the multi makes, and use them to notify curl when something 41 | * happens that needs attention. 42 | */ 43 | 44 | @interface CURLMultiHandle : NSObject 45 | { 46 | CURLM *_multi; 47 | NSMutableArray* _transfers; 48 | BOOL _isRunningProcessingLoop; 49 | NSMutableArray* _sockets; 50 | dispatch_queue_t _queue; 51 | 52 | dispatch_source_t _timer; 53 | BOOL _timerIsSuspended; 54 | } 55 | 56 | /** 57 | * Return a default instance. 58 | * Don't call startup or shutdown on this instance - startup will already have been called, and shutting it down 59 | * will be terminal since it's shared by everything. 60 | * 61 | * @return The shared instance. 62 | */ 63 | 64 | + (CURLMultiHandle*)sharedInstance; 65 | 66 | 67 | /** 68 | * Shut down the multi and clean up all resources that it was using. 69 | */ 70 | 71 | - (void)shutdown; 72 | 73 | /** 74 | * Assign a CURLTransfer to the multi to manage. 75 | * CURLTransfer uses this method internally when you call loadRequest:withMulti: on a transfer, 76 | * so generally you don't need to call it directly. 77 | * The multi will retain the transfer for as long as it needs it, but will silently release it once 78 | * the transfer has completed or failed. 79 | * 80 | * @param transfer The transfer to manage. Will be retained by the multi until removed (completion automatically performs removal). 81 | */ 82 | 83 | - (void)beginTransfer:(CURLTransfer*)transfer __attribute((nonnull)); 84 | 85 | /** 86 | * This removes the transfer from the multi. * 87 | * It is safe to call this method for a transfer that has already been cancelled, or has completed, 88 | * (or indeed was never managed by the multi). Doing so will simply do nothing. 89 | * 90 | * @warning ONLY call this on the receiver's queue 91 | * 92 | * To cancel the transfer, call [transfer cancel] instead - it will end up calling this method too, 93 | * if the transfer was being managed by a multi. 94 | * 95 | * @param transfer The transfer to cancel. Should have previously been added with beginTransfer:. 96 | */ 97 | 98 | - (void)suspendTransfer:(CURLTransfer*)transfer __attribute((nonnull)); 99 | 100 | /** 101 | Update the dispatch source for a given socket and type. 102 | 103 | @warning The routine is used internally by / , and shouldn't be called from your code. 104 | 105 | @param source The current dispatch source for the given type 106 | @param type Is this the source for reading or writing? 107 | @param socket The raw system socket that the dispatch source should be monitoring. 108 | @param registration The object that owns the source. 109 | @param required Is the source required? If not, an existing source will be cancelled. If required and the source parameter is nil, and new one will be created. 110 | @return The new/updated dispatch source. 111 | */ 112 | 113 | - (dispatch_source_t)updateSource:(dispatch_source_t)source type:(dispatch_source_type_t)type socket:(int)socket registration:(CURLSocketRegistration *)registration required:(BOOL)required; 114 | 115 | /** 116 | The serial queue the instance schedules sources on 117 | */ 118 | @property (readonly, assign, nonatomic) dispatch_queue_t queue; 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLProtocol.h 3 | // CURLHandle 4 | // 5 | // Created by Mike Abdullah on 19/01/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLTransfer.h" 10 | 11 | #ifndef CURLProtocolLog 12 | #define CURLProtocolLog(...) // no logging by default - to enable it, add something like this to the prefix: #define CURLHandleLog NSLog 13 | #endif 14 | 15 | /** 16 | An NSURLProtocol subclass implemented by handing off requests to libcurl via CURLTransfer. 17 | 18 | This allows you to use the Cocoa URL Loading System's APIs, but have it work 19 | using CURLHandle behind the scenes. 20 | */ 21 | 22 | @interface CURLProtocol : NSURLProtocol 23 | { 24 | BOOL _gotResponse; 25 | CURLTransfer* _transfer; 26 | BOOL _uploaded; 27 | } 28 | 29 | @end 30 | 31 | 32 | @interface NSURLRequest (CURLProtocol) 33 | 34 | /** 35 | @return Whether the Cocoa URL Loading System should attempt to use CURLHandle for this request. 36 | */ 37 | - (BOOL)shouldUseCurlHandle; 38 | 39 | @end 40 | 41 | 42 | @interface NSMutableURLRequest (CURLProtocol) 43 | 44 | /** 45 | libcurl supports a wide variety of protocols, but you probably don't want the 46 | Cocoa URL Loading System to hand off to it for everything. Thus this method 47 | must be used to explicitly mark a request as wanting to use CURLHandle. 48 | 49 | Note that the URL Loading System will ignore this property **unless** you've 50 | already registered `CURLProtocol` appropriately. 51 | 52 | @param useCurl Whether the Cocoa URL Loading System should attempt to use CURLHandle for this request. 53 | */ 54 | - (void)setShouldUseCurlHandle:(BOOL)useCurl; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLProtocol.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLProtocol.m 3 | // CURLHandle 4 | // 5 | // Created by Mike Abdullah on 19/01/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLProtocol.h" 10 | #import "CURLMultiHandle.h" 11 | #import "CURLTransfer+MultiSupport.h" 12 | #import "CURLRequest.h" 13 | 14 | @interface CURLProtocol() 15 | 16 | @property (assign, nonatomic) BOOL gotResponse; 17 | @property (strong, nonatomic) CURLTransfer* transfer; 18 | @property (assign, nonatomic) BOOL uploaded; 19 | 20 | @end 21 | 22 | @implementation CURLProtocol 23 | 24 | @synthesize gotResponse = _gotResponse; 25 | @synthesize transfer = _transfer; 26 | @synthesize uploaded = _uploaded; 27 | 28 | #pragma mark - Object Lifecycle 29 | 30 | - (void)dealloc 31 | { 32 | NSAssert((_transfer == nil) || [_transfer hasCompleted], @"transfer should be done by the time we are destroyed"); 33 | 34 | [_transfer release]; 35 | 36 | CURLProtocolLog(@"dealloced"); 37 | 38 | [super dealloc]; 39 | } 40 | 41 | #pragma mark - NSURLProtocol Support 42 | 43 | + (BOOL)canInitWithRequest:(NSURLRequest *)request; 44 | { 45 | BOOL result = [request shouldUseCurlHandle]; 46 | return result; 47 | } 48 | 49 | + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request 50 | { 51 | return request; 52 | } 53 | 54 | - (void)startLoading; 55 | { 56 | CURLProtocolLog(@"starting"); 57 | 58 | // Request auth before trying FTP connection 59 | NSURL *url = [[self request] URL]; 60 | NSString *scheme = [url scheme]; 61 | 62 | if ([@"ftp" caseInsensitiveCompare:scheme] == NSOrderedSame || [@"ftps" caseInsensitiveCompare:scheme] == NSOrderedSame) 63 | { 64 | NSString *protocol = ([@"ftps" caseInsensitiveCompare:scheme] == NSOrderedSame ? @"ftps" : NSURLProtectionSpaceFTP); 65 | 66 | NSURLProtectionSpace *space = [[NSURLProtectionSpace alloc] initWithHost:[url host] 67 | port:[[url port] integerValue] 68 | protocol:protocol 69 | realm:nil 70 | authenticationMethod:NSURLAuthenticationMethodDefault]; 71 | 72 | NSURLCredential *credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:space]; 73 | 74 | NSURLAuthenticationChallenge *challenge = [[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:space 75 | proposedCredential:credential 76 | previousFailureCount:0 77 | failureResponse:nil 78 | error:nil 79 | sender:self]; 80 | 81 | [space release]; 82 | 83 | [[self client] URLProtocol:self didReceiveAuthenticationChallenge:challenge]; 84 | [challenge release]; 85 | 86 | return; 87 | } 88 | 89 | [self startLoadingWithCredential:nil]; 90 | } 91 | 92 | - (void)startLoadingWithCredential:(NSURLCredential *)credential; 93 | { 94 | CURLTransfer *transfer = [[CURLTransfer alloc] initWithRequest:[self request] credential:credential delegate:self delegateQueue:nil]; 95 | self.transfer = transfer; 96 | [transfer release]; 97 | } 98 | 99 | - (void)stopLoading; 100 | { 101 | CURLProtocolLog(@"stopping"); 102 | 103 | // this protocol object is going away 104 | // if our associated transfer hasn't completed yet, we need to cancel it, to stop 105 | // it from trying to send us delegate messages after we've been disposed 106 | [self.transfer cancel]; 107 | self.transfer = nil; 108 | } 109 | 110 | #pragma mark - Utilities 111 | 112 | - (NSString*)description 113 | { 114 | return [NSString stringWithFormat:@"", self, self.request.URL]; 115 | } 116 | 117 | #pragma mark - CURLTransferDelegate 118 | 119 | - (void)transfer:(CURLTransfer *)transfer didReceiveResponse:(NSURLResponse *)response; 120 | { 121 | if (!self.gotResponse) 122 | { 123 | id client = [self client]; 124 | CURLProtocolLog(@"got didReceiveResponse %ld from %@ for %@", (long)[(NSHTTPURLResponse*)response statusCode], transfer, client); 125 | [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed]; 126 | self.gotResponse = YES; 127 | } 128 | } 129 | 130 | - (void)transfer:(CURLTransfer *)transfer didReceiveData:(NSData *)data; 131 | { 132 | id client = [self client]; 133 | CURLProtocolLog(@"got didReceiveData from %@ for %@", transfer, client); 134 | [client URLProtocol:self didLoadData:data]; 135 | } 136 | 137 | - (void)transfer:(CURLTransfer*)transfer didCompleteWithError:(NSError *)error 138 | { 139 | id client = [self client]; 140 | if (error) 141 | { 142 | CURLProtocolLog(@"got didFailWithError %@ from %@ for %@", error, transfer, client); 143 | [client URLProtocol:self didFailWithError:error]; 144 | } 145 | else 146 | { 147 | CURLProtocolLog(@"got didFinish from %@ for %@", transfer, client); 148 | [client URLProtocolDidFinishLoading:self]; 149 | } 150 | } 151 | 152 | - (void)transfer:(CURLTransfer *)transfer willSendBodyDataOfLength:(NSUInteger)bytesWritten 153 | { 154 | // TODO: improve this if we're ever given acess 155 | // ideally we'd be able to generate a connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: call here 156 | // but NSURLProtocol doesn't give us a way to do it 157 | 158 | // is the upload finished? 159 | if (bytesWritten == 0) 160 | { 161 | // set a flag so that when stopLoading is called, we don't cancel incorrectly 162 | self.uploaded = YES; 163 | } 164 | } 165 | 166 | #pragma mark NSURLAuthenticationChallengeSender 167 | 168 | - (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; 169 | { 170 | [self startLoadingWithCredential:credential]; 171 | } 172 | 173 | - (void)continueWithoutCredentialForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; 174 | { 175 | [self startLoadingWithCredential:nil]; 176 | } 177 | 178 | - (void)cancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; 179 | { 180 | [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain 181 | code:NSURLErrorUserAuthenticationRequired 182 | userInfo:nil]]; 183 | } 184 | 185 | @end 186 | 187 | 188 | #pragma mark - 189 | 190 | 191 | static NSString *const UseCurlHandleKey = @"useCurlHandle"; 192 | 193 | @implementation NSURLRequest (CURLProtocol) 194 | 195 | - (BOOL)shouldUseCurlHandle; 196 | { 197 | return [[NSURLProtocol propertyForKey:UseCurlHandleKey inRequest:self] boolValue]; 198 | } 199 | 200 | @end 201 | 202 | 203 | @implementation NSMutableURLRequest (CURLProtocol) 204 | 205 | - (void)setShouldUseCurlHandle:(BOOL)useCurl; 206 | { 207 | [NSURLProtocol setProperty:[NSNumber numberWithBool:useCurl] forKey:UseCurlHandleKey inRequest:self]; 208 | } 209 | 210 | @end 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLRequest.h 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import 9 | #import 10 | 11 | @interface NSURLRequest (CURLOptionsFTP) 12 | 13 | // CURLUSESSL_NONE, CURLUSESSL_TRY, CURLUSESSL_CONTROL, or CURLUSESSL_ALL 14 | @property(nonatomic, readonly) curl_usessl curl_desiredSSLLevel; 15 | 16 | @property(nonatomic, readonly) BOOL curl_shouldVerifySSLCertificate; // CURLOPT_SSL_VERIFYPEER 17 | @property(nonatomic, readonly) BOOL curl_shouldVerifySSLHost; // CURLOPT_SSL_VERIFYHOST 18 | 19 | // An array of strings. Executed in turn before/after the main request is done 20 | // NOTE: We have seen crashes (mishandling of buffers) when using post-transfer commands for a request that doesn't actually do a transfer. This may be a bug in libcurl; we don't know yet! 21 | @property(nonatomic, copy, readonly) NSArray *curl_postTransferCommands; 22 | @property(nonatomic, copy, readonly) NSArray *curl_preTransferCommands; 23 | 24 | // A value greater than 0 will cause Curl to create missing directories. I'm pretty certain this only applies when uploading 25 | // Default is 0 26 | // See CURLOPT_FTP_CREATE_MISSING_DIRS docs for full details 27 | @property(nonatomic, readonly) NSUInteger curl_createIntermediateDirectories; 28 | 29 | // Default is nil, which tells libcurl in turn to use its own defaults, which are currently documented to be 0644 and 0755 respectively 30 | // Only supported by SFTP, SCP and file protocols at present apparently 31 | @property(nonatomic, readonly) NSNumber *curl_newFilePermissions; 32 | @property(nonatomic, readonly) NSNumber *curl_newDirectoryPermissions; 33 | 34 | /** 35 | The location of an OpenSSH file of known hosts to check the server against. 36 | 37 | Default is `nil`, which means no checking. 38 | */ 39 | @property(nonatomic, readonly) NSURL *curl_SSHKnownHostsFileURL; 40 | 41 | @end 42 | 43 | @interface NSMutableURLRequest (CURLOptionsFTP) 44 | 45 | - (void)curl_setDesiredSSLLevel:(curl_usessl)level; 46 | - (void)curl_setShouldVerifySSLCertificate:(BOOL)verify; 47 | - (void)curl_setShouldVerifySSLHost:(BOOL)verify; 48 | - (void)curl_setCreateIntermediateDirectories:(NSUInteger)createIntermediateDirectories; 49 | 50 | - (void)curl_setPreTransferCommands:(NSArray *)commands; 51 | - (void)curl_setPostTransferCommands:(NSArray *)commands; 52 | 53 | - (void)curl_setNewFilePermissions:(NSNumber *)permissions; 54 | - (void)curl_setNewDirectoryPermissions:(NSNumber *)permissions; 55 | 56 | - (void)curl_setSSHKnownHostsFileURL:(NSURL *)url; 57 | 58 | @end 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLRequest.m 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import "CURLRequest.h" 9 | #import "CURLProtocol.h" 10 | 11 | @implementation NSURLRequest (CURLOptionsFTP) 12 | 13 | - (curl_usessl)curl_desiredSSLLevel; 14 | { 15 | return (curl_usessl)[[NSURLProtocol propertyForKey:@"curl_desiredSSLLevel" inRequest:self] longValue]; 16 | } 17 | 18 | - (BOOL)curl_shouldVerifySSLCertificate; 19 | { 20 | NSNumber *result = [NSURLProtocol propertyForKey:@"curl_shouldVerifySSLCertificate" inRequest:self]; 21 | return (result ? [result boolValue] : YES); 22 | } 23 | 24 | - (BOOL)curl_shouldVerifySSLHost; 25 | { 26 | NSNumber *result = [NSURLProtocol propertyForKey:@"curl_shouldVerifySSLHost" inRequest:self]; 27 | return (result ? [result boolValue] : YES); 28 | } 29 | 30 | - (NSArray *)curl_preTransferCommands; 31 | { 32 | return [NSURLProtocol propertyForKey:@"curl_preTransferCommands" inRequest:self]; 33 | } 34 | 35 | - (NSArray *)curl_postTransferCommands; 36 | { 37 | return [NSURLProtocol propertyForKey:@"curl_postTransferCommands" inRequest:self]; 38 | } 39 | 40 | - (NSUInteger)curl_createIntermediateDirectories; 41 | { 42 | return [[NSURLProtocol propertyForKey:@"curl_createIntermediateDirectories" inRequest:self] unsignedIntegerValue]; 43 | } 44 | 45 | - (NSNumber *)curl_newFilePermissions; { return [NSURLProtocol propertyForKey:@"curl_newFilePermissions" inRequest:self]; } 46 | - (NSNumber *)curl_newDirectoryPermissions; { return [NSURLProtocol propertyForKey:@"curl_newDirectoryPermissions" inRequest:self]; } 47 | 48 | - (NSURL *)curl_SSHKnownHostsFileURL; { return [NSURLProtocol propertyForKey:@"curl_SSHKnownHostsFileURL" inRequest:self]; } 49 | 50 | @end 51 | 52 | @implementation NSMutableURLRequest (CURLOptionsFTP) 53 | 54 | - (void)curl_setDesiredSSLLevel:(curl_usessl)level; 55 | { 56 | [NSURLProtocol setProperty:[NSNumber numberWithLong:level] forKey:@"curl_desiredSSLLevel" inRequest:self]; 57 | } 58 | 59 | - (void)curl_setShouldVerifySSLCertificate:(BOOL)verify; 60 | { 61 | [NSURLProtocol setProperty:@(verify) forKey:@"curl_shouldVerifySSLCertificate" inRequest:self]; 62 | } 63 | 64 | - (void)curl_setShouldVerifySSLHost:(BOOL)verify; 65 | { 66 | [NSURLProtocol setProperty:@(verify) forKey:@"curl_shouldVerifySSLHost" inRequest:self]; 67 | } 68 | 69 | - (void)curl_setCreateIntermediateDirectories:(NSUInteger)value; 70 | { 71 | [NSURLProtocol setProperty:[NSNumber numberWithUnsignedInteger:value] forKey:@"curl_createIntermediateDirectories" inRequest:self]; 72 | } 73 | 74 | - (void)curl_setPreTransferCommands:(NSArray *)commands; 75 | { 76 | if (commands) 77 | { 78 | commands = [commands copy]; 79 | [NSURLProtocol setProperty:commands forKey:@"curl_preTransferCommands" inRequest:self]; 80 | [commands release]; 81 | } 82 | else 83 | { 84 | [NSURLProtocol removePropertyForKey:@"curl_preTransferCommands" inRequest:self]; 85 | } 86 | } 87 | 88 | - (void)curl_setPostTransferCommands:(NSArray *)commands; 89 | { 90 | if (commands) 91 | { 92 | commands = [commands copy]; 93 | [NSURLProtocol setProperty:commands forKey:@"curl_postTransferCommands" inRequest:self]; 94 | [commands release]; 95 | } 96 | else 97 | { 98 | [NSURLProtocol removePropertyForKey:@"curl_postTransferCommands" inRequest:self]; 99 | } 100 | } 101 | 102 | - (void)curl_setNewFilePermissions:(NSNumber *)permissions; 103 | { 104 | [NSURLProtocol setProperty:permissions forKey:@"curl_newFilePermissions" inRequest:self]; 105 | } 106 | 107 | - (void)curl_setNewDirectoryPermissions:(NSNumber *)permissions; 108 | { 109 | [NSURLProtocol setProperty:permissions forKey:@"curl_newDirectoryPermissions" inRequest:self]; 110 | } 111 | 112 | - (void)curl_setSSHKnownHostsFileURL:(NSURL *)url; 113 | { 114 | if (url) 115 | { 116 | [NSURLProtocol setProperty:url forKey:@"curl_SSHKnownHostsFileURL" inRequest:self]; 117 | } 118 | else 119 | { 120 | [NSURLProtocol removePropertyForKey:@"curl_SSHKnownHostsFileURL" inRequest:self]; 121 | } 122 | } 123 | 124 | @end 125 | 126 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLResponse.h 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import 9 | 10 | @interface CURLResponse : NSURLResponse 11 | { 12 | @private 13 | NSInteger _code; 14 | NSString *_header; 15 | } 16 | 17 | // For HTTP URLs, returns an NSHTTPURLResponse. For others, a CURLResponse 18 | + (NSURLResponse *)responseWithURL:(NSURL *)url statusCode:(NSInteger)statusCode headerString:(NSString *)header; 19 | 20 | @property(readonly) NSInteger statusCode; 21 | @property(readonly) NSString *headerString; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLResponse.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLResponse.m 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import "CURLResponse.h" 9 | #import "CURLHTTPParsing.h" 10 | 11 | 12 | @interface CURLHTTPResponse : NSHTTPURLResponse 13 | { 14 | NSInteger _statusCode; 15 | NSDictionary *_headerFields; 16 | } 17 | @end 18 | 19 | 20 | @implementation CURLResponse 21 | 22 | + (NSURLResponse *)responseWithURL:(NSURL *)url statusCode:(NSInteger)statusCode headerString:(NSString *)header; 23 | { 24 | NSString *scheme = url.scheme; 25 | if ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame || [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) 26 | { 27 | Class responseClass = ([NSHTTPURLResponse instancesRespondToSelector:@selector(initWithURL:statusCode:HTTPVersion:headerFields:)] ? [NSHTTPURLResponse class] : [CURLResponse class]); 28 | 29 | return [[[responseClass alloc] initWithURL:url 30 | statusCode:statusCode 31 | HTTPVersion:[header headerHTTPVersion] 32 | headerFields:[header allHTTPHeaderFields]] 33 | autorelease]; 34 | } 35 | else 36 | { 37 | CURLResponse *result = [[self alloc] initWithURL:url MIMEType:nil expectedContentLength:NSURLResponseUnknownLength textEncodingName:nil]; 38 | result->_code = statusCode; 39 | result->_header = [header copy]; 40 | return [result autorelease]; 41 | } 42 | } 43 | 44 | - (void)dealloc 45 | { 46 | [_header release]; 47 | [super dealloc]; 48 | } 49 | 50 | @synthesize headerString = _header; 51 | @synthesize statusCode = _code; 52 | 53 | @end 54 | 55 | @implementation CURLHTTPResponse 56 | 57 | - (id)initWithURL:(NSURL *)URL statusCode:(NSInteger)statusCode HTTPVersion:(NSString *)HTTPVersion headerFields:(NSDictionary *)fields; 58 | { 59 | if (self = [self initWithURL:URL 60 | MIMEType:[fields objectForKey:@"Content-Type"] 61 | expectedContentLength:[[fields objectForKey:@"Content-Length"] integerValue] 62 | textEncodingName:[fields objectForKey:@"Content-Encoding"]]) 63 | { 64 | _statusCode = statusCode; 65 | _headerFields = [fields copy]; 66 | } 67 | return self; 68 | } 69 | 70 | - (NSInteger)statusCode; { return _statusCode; } 71 | 72 | - (NSDictionary *)allHeaderFields; { return _headerFields; } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLSocketRegistration.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLSocketRegistration.h 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 26/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CURLMultiHandle; 12 | 13 | /** 14 | * Internal wrapper for dispatch sources that monitor each of the curl sockets. 15 | * CURLMulti uses this internally - not intended for public consumption. 16 | */ 17 | 18 | @interface CURLSocketRegistration : NSObject 19 | { 20 | dispatch_source_t _reader; 21 | dispatch_source_t _writer; 22 | } 23 | 24 | /** 25 | * Create/destroy the dispatch sources, based on the values in the mode parameter. 26 | * CURLMulti uses this internally - not intended for public consumption. 27 | * 28 | * @param socket The socket . 29 | * @param mode Whether we are interested in reads, writes, or both. 30 | * @param multi The multi that this object is working with. 31 | */ 32 | 33 | - (void)updateSourcesForSocket:(int)socket mode:(int)mode multi:(CURLMultiHandle*)multi; 34 | 35 | /** 36 | Indicates whether a given source is owned by this socket. 37 | 38 | @param source The source to check. 39 | @return Returns YES if the source is owned by this socket. 40 | */ 41 | 42 | - (BOOL)ownsSource:(dispatch_source_t)source; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLSocketRegistration.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLSocketRegistration.m 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 26/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLSocketRegistration.h" 10 | #import "CURLMultiHandle.h" 11 | 12 | #import 13 | 14 | @interface CURLSocketRegistration() 15 | 16 | #pragma mark - Private Properties 17 | 18 | @property (assign, nonatomic) dispatch_source_t reader; 19 | @property (assign, nonatomic) dispatch_source_t writer; 20 | 21 | @end 22 | 23 | @implementation CURLSocketRegistration 24 | 25 | #pragma mark - Synthesized Properties 26 | 27 | @synthesize reader = _reader; 28 | @synthesize writer = _writer; 29 | 30 | #pragma mark - Implementation 31 | 32 | - (void)dealloc 33 | { 34 | if (self.reader) 35 | { 36 | dispatch_source_cancel(self.reader); // the cancel handler will release the source 37 | } 38 | 39 | if (self.writer) 40 | { 41 | dispatch_source_cancel(self.writer); // the cancel handler will release the source 42 | } 43 | 44 | [super dealloc]; 45 | } 46 | 47 | - (void)updateSourcesForSocket:(int)socket mode:(int)mode multi:(CURLMultiHandle*)multi 48 | { 49 | // We call back to the multi to do the actual work - this class really just exists as 50 | // a place to group together the reader and writer sources corresponding to a socket. 51 | 52 | BOOL readerRequired = (mode == CURL_POLL_IN) || (mode == CURL_POLL_INOUT); 53 | self.reader = [multi updateSource:self.reader type:DISPATCH_SOURCE_TYPE_READ socket:socket registration:self required:readerRequired]; 54 | 55 | BOOL writerRequired = (mode == CURL_POLL_OUT) || (mode == CURL_POLL_INOUT); 56 | self.writer = [multi updateSource:self.writer type:DISPATCH_SOURCE_TYPE_WRITE socket:socket registration:self required:writerRequired]; 57 | } 58 | 59 | - (NSString*)description 60 | { 61 | NSString* mode; 62 | if (self.reader) 63 | { 64 | if (self.writer) 65 | { 66 | mode = [NSString stringWithFormat:@"read, write sources for %lu", dispatch_source_get_handle(self.reader)]; 67 | } 68 | else 69 | { 70 | mode = [NSString stringWithFormat:@"read source for %lu", dispatch_source_get_handle(self.reader)]; 71 | } 72 | } 73 | else if (self.writer) 74 | { 75 | mode = [NSString stringWithFormat:@"write source for %lu", dispatch_source_get_handle(self.writer)]; 76 | } 77 | else 78 | { 79 | mode = @"no sources"; 80 | } 81 | 82 | return [NSString stringWithFormat:@"", self, mode]; 83 | } 84 | 85 | - (BOOL)ownsSource:(dispatch_source_t)source 86 | { 87 | return (self.reader == source) || (self.writer == source); 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLTransfer+MultiSupport.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLTransfer+MultiSupport.h 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 27/03/2013. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import "CURLTransfer.h" 9 | 10 | 11 | /** 12 | Private API used by CURLMulti. 13 | Not exported in the framework, and not recommended for general use. 14 | */ 15 | 16 | @interface CURLTransfer(MultiSupport) 17 | 18 | /** @name Internal Methods */ 19 | 20 | /** 21 | The CURL handle managed by this object. 22 | 23 | @warning Not intended for general use. 24 | 25 | @return The curl handle. 26 | 27 | */ 28 | 29 | - (CURL*)curlHandle; 30 | 31 | /** 32 | Called by to tell the transfer that it has completed. 33 | 34 | @param code The completion code. 35 | 36 | @warning Not intended for general use. 37 | 38 | */ 39 | 40 | - (void)completeWithCode:(CURLcode)code; 41 | 42 | /** 43 | Called by to tell the transfer that it has completed. 44 | 45 | @param error The failure error if there was one. 46 | 47 | @warning Not intended for general use. 48 | 49 | */ 50 | 51 | - (void)completeWithError:(NSError *)error; 52 | 53 | /** 54 | Has the transfer completed? 55 | 56 | @return YES if the transfer has completed. 57 | 58 | @warning Not intended for general use. 59 | 60 | */ 61 | 62 | - (BOOL)hasCompleted; 63 | 64 | @end 65 | 66 | -------------------------------------------------------------------------------- /CURLHandleSource/CURLTransfer+TestingSupport.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLTransfer+TestingSupport.h 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 27/03/2013. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import "CURLTransfer.h" 9 | 10 | 11 | /** 12 | This functionality is only provided for unit tests, and isn't intended for general use. 13 | It is included in the framework, so that frameworks that build on this one (eg ConnectionKit) can 14 | use these functions in their unit tests. 15 | */ 16 | 17 | @interface CURLTransfer(TestingSupport) 18 | 19 | /** @name Testing Methods */ 20 | 21 | /** 22 | Creates a CURLTransfer instance tied to a specific multi handle 23 | 24 | @warning Not intended for general use. 25 | 26 | @return A new CURLTransfer object. 27 | */ 28 | - (id)initWithRequest:(NSURLRequest *)request credential:(NSURLCredential *)credential delegate:(id )delegate delegateQueue:(NSOperationQueue *)queue multi:(CURLMultiHandle*)multi __attribute((nonnull(1,5))); 29 | 30 | /** 31 | Returns a new CURLMulti, for use in testing. 32 | 33 | Generally multi's are an internal implementation detail, 34 | but it's useful to be able to make new ones for unit tests 35 | since sharing multis between tests can create dependencies. 36 | 37 | @warning Not intended for general use. 38 | 39 | @return A new CURLMulti object. 40 | */ 41 | 42 | + (CURLMultiHandle*)standaloneMultiForTestPurposes; 43 | 44 | /** 45 | Clean up a multi that was created by standaloneMultiForTestPurposes. 46 | 47 | @warning Not intended for general use. 48 | 49 | @param multi The multi to clean up. 50 | */ 51 | 52 | + (void)cleanupStandaloneMulti:(CURLMultiHandle*)multi; 53 | @end 54 | 55 | -------------------------------------------------------------------------------- /CURLHandleSource/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleName 10 | ${PRODUCT_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | com.karelia.CURLHandle 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CURLHandleSource/NSDictionary+CURLHandle.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+CURLHandle.h 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import 9 | 10 | @interface NSDictionary(CURLHandle) 11 | 12 | - (NSString *) formatForHTTP; 13 | - (NSString *) formatForHTTPUsingEncoding:(NSStringEncoding)inEncoding; 14 | - (NSString *) formatForHTTPUsingEncoding:(NSStringEncoding)inEncoding ordering:(NSArray *)inOrdering; 15 | 16 | @end 17 | 18 | 19 | -------------------------------------------------------------------------------- /CURLHandleSource/NSDictionary+CURLHandle.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+CURLHandle.m 3 | // CURLHandle 4 | // 5 | // Created by Dan Wood on Fri Jun 22 2001. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | 8 | #import "NSDictionary+CURLHandle.h" 9 | 10 | @implementation NSDictionary ( CurlHTTPExtensions ) 11 | 12 | /*" This category adds methods for dealing with HTTP input and output to an #NSDictionary. 13 | "*/ 14 | 15 | /*" Convert a dictionary to an HTTP-formatted string with 7-bit ASCII encoding; 16 | see #formatForHTTPUsingEncoding. 17 | "*/ 18 | 19 | - (NSString *) formatForHTTP 20 | { 21 | return [self formatForHTTPUsingEncoding:NSASCIIStringEncoding]; 22 | // default to dumb ASCII only 23 | } 24 | 25 | /*" Convert a dictionary to an HTTP-formatted string with the given encoding. 26 | Spaces are turned into !{+}; other special characters are escaped with !{%}; 27 | keys and values are output as %{key}=%{value}; in between arguments is !{&}. 28 | "*/ 29 | 30 | - (NSString *) formatForHTTPUsingEncoding:(NSStringEncoding)inEncoding 31 | { 32 | return [self formatForHTTPUsingEncoding:inEncoding ordering:nil]; 33 | } 34 | 35 | /*" Convert a dictionary to an HTTP-formatted string with the given encoding, as above. The inOrdering parameter specifies the order to place the inputs, for servers that care about this. (Note that keys in the dictionary that aren't in inOrdering will not be included.) If inOrdering is nil, all keys and values will be output in an unspecified order. 36 | "*/ 37 | 38 | - (NSString *) formatForHTTPUsingEncoding:(NSStringEncoding)inEncoding ordering:(NSArray *)inOrdering 39 | { 40 | NSMutableString *s = [NSMutableString stringWithCapacity:256]; 41 | NSEnumerator *e = (nil == inOrdering) ? [self keyEnumerator] : [inOrdering objectEnumerator]; 42 | id key; 43 | CFStringEncoding cfStrEnc = CFStringConvertNSStringEncodingToEncoding(inEncoding); 44 | 45 | while ((key = [e nextObject])) 46 | { 47 | id keyObject = [self objectForKey: key]; 48 | // conform with rfc 1738 3.3, also escape URL-like characters that might be in the parameters 49 | NSString *escapedKey 50 | = (NSString *) CFURLCreateStringByAddingPercentEscapes( 51 | NULL, (CFStringRef) key, NULL, (CFStringRef) @";:@&=/+", cfStrEnc); 52 | if ([keyObject respondsToSelector: @selector(objectEnumerator)]) 53 | { 54 | NSEnumerator *multipleValueEnum = [keyObject objectEnumerator]; 55 | id aValue; 56 | 57 | while ((aValue = [multipleValueEnum nextObject])) 58 | { 59 | NSString *escapedObject 60 | = (NSString *) CFURLCreateStringByAddingPercentEscapes( 61 | NULL, (CFStringRef) [aValue description], NULL, (CFStringRef) @";:@&=/+", cfStrEnc); 62 | [s appendFormat:@"%@=%@&", escapedKey, escapedObject]; 63 | [escapedObject release]; 64 | } 65 | } 66 | else 67 | { 68 | NSString *escapedObject 69 | = (NSString *) CFURLCreateStringByAddingPercentEscapes( 70 | NULL, (CFStringRef) [keyObject description], NULL, (CFStringRef) @";:@&=/+", cfStrEnc); 71 | [s appendFormat:@"%@=%@&", escapedKey, escapedObject]; 72 | [escapedObject release]; 73 | } 74 | [escapedKey release]; 75 | } 76 | // Delete final & from the string 77 | if (![s isEqualToString:@""]) 78 | { 79 | [s deleteCharactersInRange:NSMakeRange([s length]-1, 1)]; 80 | } 81 | return s; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/CURLHandleBasedTest.h: -------------------------------------------------------------------------------- 1 | // 2 | // CURLHandleBasedTest 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 20/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "KMSTestCase.h" 10 | 11 | #import "CURLTransfer.h" 12 | 13 | @interface CURLHandleBasedTest : KMSTestCase 14 | 15 | @property (strong, nonatomic) NSMutableData* buffer; 16 | @property (strong, nonatomic) NSError* error; 17 | @property (assign, nonatomic) NSUInteger expected; 18 | @property (assign, atomic) BOOL exitRunLoop; 19 | @property (assign, atomic) NSUInteger finishedCount; 20 | @property (strong, nonatomic) NSURLResponse* response; 21 | @property (assign, nonatomic) BOOL sending; 22 | @property (strong, nonatomic) NSMutableString* transcript; 23 | 24 | - (BOOL)checkDownloadedBufferWasCorrect; 25 | - (void)runUntilPaused; 26 | - (void)stopServer; 27 | - (void)cleanup; 28 | 29 | - (NSURL*)ftpTestServer; 30 | - (BOOL)usingMockServer; 31 | - (NSURL*)testFileURL; 32 | - (NSURL*)testFileRemoteURL; 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/CURLHandleBasedTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLHandleBasedTest 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 20/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLHandleBasedTest.h" 10 | #import "KMSServer.h" 11 | 12 | @implementation CURLHandleBasedTest 13 | 14 | - (NSURL*)testFileURL 15 | { 16 | NSURL* testFileURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestContent" withExtension:@"txt"]; 17 | 18 | return testFileURL; 19 | } 20 | 21 | - (NSURL*)testFileRemoteURL 22 | { 23 | NSURL* testFileURL = [NSURL URLWithString:@"https://raw.github.com/karelia/CurlHandle/v4.x-beta/CURLHandleSource/Tests/TestContent.txt"]; 24 | 25 | return testFileURL; 26 | } 27 | 28 | - (void)transfer:(CURLTransfer *)transfer didReceiveData:(NSData *)data 29 | { 30 | NSMutableData* buffer = self.buffer; 31 | if (!buffer) 32 | { 33 | buffer = [NSMutableData dataWithCapacity:self.expected]; 34 | self.buffer = buffer; 35 | } 36 | 37 | [buffer appendData:data]; 38 | } 39 | 40 | - (void)transfer:(CURLTransfer *)transfer didReceiveResponse:(NSURLResponse *)response 41 | { 42 | self.response = response; 43 | if (response.expectedContentLength > 0) 44 | { 45 | self.expected = response.expectedContentLength; 46 | } 47 | } 48 | 49 | - (void)transfer:(CURLTransfer *)transfer willSendBodyDataOfLength:(NSUInteger)bytesWritten 50 | { 51 | self.sending = YES; 52 | if (bytesWritten == 0) 53 | { 54 | NSLog(@"test: upload done"); 55 | } 56 | } 57 | 58 | - (void)transfer:(CURLTransfer *)transfer didReceiveDebugInformation:(NSString *)string ofType:(curl_infotype)type 59 | { 60 | NSString* typeName = [transfer.class nameForType:type]; 61 | if (!self.transcript) 62 | { 63 | self.transcript = [NSMutableString stringWithString:@""]; 64 | } 65 | 66 | @synchronized(self.transcript) 67 | { 68 | [self.transcript appendFormat:@"%@: %@", typeName, string]; 69 | } 70 | } 71 | 72 | - (void)transfer:(CURLTransfer*)transfer didCompleteWithError:(NSError *)error 73 | { 74 | if (error) 75 | { 76 | NSLog(@"test: transfer failed with error %@", error); 77 | self.error = error; 78 | } 79 | else 80 | { 81 | NSLog(@"test: transfer %@ finished", transfer); 82 | self.finishedCount++; 83 | } 84 | 85 | [self pause]; 86 | } 87 | 88 | - (void)pause 89 | { 90 | NSLog(@"test: pause requested"); 91 | if (self.server) 92 | { 93 | [self.server pause]; 94 | } 95 | else 96 | { 97 | self.exitRunLoop = YES; 98 | } 99 | } 100 | 101 | - (void)runUntilPaused 102 | { 103 | if (self.server) 104 | { 105 | [self.server runUntilPaused]; 106 | } 107 | else 108 | { 109 | while (!self.exitRunLoop) 110 | { 111 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]]; 112 | } 113 | self.exitRunLoop = NO; 114 | } 115 | NSLog(@"test: paused"); 116 | } 117 | 118 | - (void)stopServer 119 | { 120 | if (self.server) 121 | { 122 | [self.server stop]; 123 | while (self.server.state != KMSStopped) 124 | { 125 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]]; 126 | } 127 | } 128 | } 129 | 130 | - (BOOL)checkDownloadedBufferWasCorrect 131 | { 132 | STAssertNotNil(self.response, @"got no response"); 133 | STAssertTrue([self.buffer length] > 0, @"got no data, expected %ld", self.expected); 134 | STAssertNil(self.error, @"got error %@", self.error); 135 | 136 | NSError* error = nil; 137 | NSURL* testFileURL = [self testFileURL]; 138 | NSString* testNotes = [NSString stringWithContentsOfURL:testFileURL encoding:NSUTF8StringEncoding error:&error]; 139 | NSString* receivedNotes = [[NSString alloc] initWithData:self.buffer encoding:NSUTF8StringEncoding]; 140 | 141 | BOOL result = [receivedNotes isEqualToString:testNotes]; 142 | STAssertTrue(result, @"received notes didn't match: was:\n'%@'\n\nshould have been:\n'%@'", receivedNotes, testNotes); 143 | 144 | // clear the buffer 145 | [self.buffer setLength:0]; 146 | 147 | return result; 148 | } 149 | 150 | - (BOOL)usingMockServer 151 | { 152 | NSString* ftpTest = [[NSUserDefaults standardUserDefaults] objectForKey:@"CURLHandleFTPTestURL"]; 153 | return [ftpTest isEqualToString:@"MockServer"]; 154 | } 155 | 156 | - (NSURL*)ftpTestServer 157 | { 158 | NSURL* result = nil; 159 | NSString* ftpTest = [[NSUserDefaults standardUserDefaults] objectForKey:@"CURLHandleFTPTestURL"]; 160 | if ([ftpTest isEqualToString:@"MockServer"]) 161 | { 162 | [self setupServerWithResponseFileNamed:@"ftp"]; 163 | 164 | NSURL* testFileURL = [self testFileURL]; 165 | self.server.data = [NSData dataWithContentsOfURL:testFileURL]; 166 | 167 | result = [self URLForPath:@"/"]; 168 | } 169 | else 170 | { 171 | STAssertNotNil(ftpTest, @"need to set a test server address using defaults, e.g: defaults write otest CURLHandleFTPTestURL \"ftp://user:password@ftp.test.com\""); 172 | result = [NSURL URLWithString:ftpTest]; 173 | } 174 | 175 | return result; 176 | } 177 | 178 | - (void)cleanup 179 | { 180 | if (self.transcript) 181 | { 182 | NSLog(@"Transcript:\n\n%@", self.transcript); 183 | } 184 | else 185 | { 186 | NSLog(@"No transcript."); 187 | } 188 | 189 | self.buffer = nil; 190 | self.transcript = nil; 191 | self.response = nil; 192 | self.error = nil; 193 | self.exitRunLoop = NO; 194 | } 195 | 196 | - (void)tearDown 197 | { 198 | [self cleanup]; 199 | [super tearDown]; 200 | } 201 | 202 | @end 203 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/CURLHandleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.karelia.${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 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/CURLHandleTests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CURLHandleTests' target in the 'CURLHandleTests' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/CURLMultiTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLMultiTests.m 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 20/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLMultiHandle.h" 10 | #import "CURLHandleBasedTest.h" 11 | #import "CURLTransfer+TestingSupport.h" 12 | 13 | #import "CURLRequest.h" 14 | #import "KMSServer.h" 15 | 16 | 17 | @interface CURLMultiTests : CURLHandleBasedTest 18 | 19 | @property (assign, nonatomic) BOOL pauseOnResponse; 20 | @property (assign, nonatomic) BOOL finished; 21 | @end 22 | 23 | @implementation CURLMultiTests 24 | 25 | 26 | - (void)transfer:(CURLTransfer *)transfer didReceiveResponse:(NSURLResponse *)response 27 | { 28 | if (self.pauseOnResponse) 29 | { 30 | [self pause]; 31 | } 32 | [super transfer:transfer didReceiveResponse:response]; 33 | } 34 | 35 | - (void)transfer:(CURLTransfer *)transfer didCompleteWithError:(NSError *)error; 36 | { 37 | if (!error) self.finished = YES; 38 | [super transfer:transfer didCompleteWithError:error]; 39 | } 40 | 41 | #pragma mark - Tests 42 | 43 | - (void)testStartupShutdown 44 | { 45 | CURLMultiHandle* multi = [[CURLMultiHandle alloc] init]; 46 | 47 | [multi shutdown]; 48 | 49 | [multi release]; 50 | } 51 | 52 | - (void)testHTTPDownload 53 | { 54 | CURLMultiHandle* multi = [[CURLMultiHandle alloc] init]; 55 | 56 | NSURLRequest* request = [NSURLRequest requestWithURL:[self testFileRemoteURL]]; 57 | CURLTransfer* transfer = [[CURLTransfer alloc] initWithRequest:request credential:nil delegate:self delegateQueue:[NSOperationQueue mainQueue] multi:multi]; 58 | 59 | [self runUntilPaused]; 60 | 61 | [self checkDownloadedBufferWasCorrect]; 62 | 63 | [transfer release]; 64 | 65 | [multi shutdown]; 66 | 67 | [multi release]; 68 | 69 | } 70 | 71 | - (void)testFTPDownload 72 | { 73 | CURLMultiHandle* multi = [[CURLMultiHandle alloc] init]; 74 | 75 | NSURL* ftpRoot = [self ftpTestServer]; 76 | if (ftpRoot) 77 | { 78 | NSURL* ftpDownload = [[ftpRoot URLByAppendingPathComponent:@"CURLHandleTests"] URLByAppendingPathComponent:@"TestContent.txt"]; 79 | 80 | NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:ftpDownload]; 81 | CURLTransfer* transfer = [[CURLTransfer alloc] initWithRequest:request credential:nil delegate:self delegateQueue:[NSOperationQueue mainQueue] multi:multi]; 82 | 83 | [self runUntilPaused]; 84 | 85 | [self checkDownloadedBufferWasCorrect]; 86 | 87 | [transfer release]; 88 | } 89 | 90 | [multi shutdown]; 91 | 92 | [multi release]; 93 | } 94 | 95 | - (void)testFTPUpload 96 | { 97 | CURLMultiHandle* multi = [[CURLMultiHandle alloc] init]; 98 | 99 | NSURL* ftpRoot = [self ftpTestServer]; 100 | if (ftpRoot) 101 | { 102 | NSURL* ftpUpload = [[ftpRoot URLByAppendingPathComponent:@"CURLHandleTests"] URLByAppendingPathComponent:@"Upload.txt"]; 103 | 104 | NSError* error = nil; 105 | NSURL* devNotesURL = [self testFileURL]; 106 | NSString* devNotes = [NSString stringWithContentsOfURL:devNotesURL encoding:NSUTF8StringEncoding error:&error]; 107 | 108 | NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:ftpUpload]; 109 | [request curl_setCreateIntermediateDirectories:1]; 110 | [request setHTTPBody:[devNotes dataUsingEncoding:NSUTF8StringEncoding]]; 111 | CURLTransfer* transfer = [[CURLTransfer alloc] initWithRequest:request credential:nil delegate:self delegateQueue:[NSOperationQueue mainQueue] multi:multi]; 112 | 113 | [self runUntilPaused]; 114 | 115 | STAssertTrue(self.sending, @"should have set sending flag"); 116 | STAssertNil(self.error, @"got error %@", self.error); 117 | STAssertNotNil(self.response, @"expected response"); 118 | STAssertTrue([self.buffer length] == 0, @"got unexpected data %@", self.buffer); 119 | 120 | [transfer release]; 121 | } 122 | 123 | [multi shutdown]; 124 | 125 | [multi release]; 126 | 127 | } 128 | 129 | - (void)testCancelling 130 | { 131 | CURLMultiHandle* multi = [[CURLMultiHandle alloc] init]; 132 | 133 | NSURL* largeFile = [NSURL URLWithString:@"https://github.com/karelia/CurlHandle/archive/master.zip"]; 134 | NSURLRequest* request = [NSURLRequest requestWithURL:largeFile]; 135 | CURLTransfer* transfer = [[CURLTransfer alloc] initWithRequest:request credential:nil delegate:self delegateQueue:[NSOperationQueue mainQueue] multi:multi]; 136 | 137 | [transfer cancel]; 138 | STAssertTrue(transfer.state >= CURLTransferStateCanceling, @"should have been cancelled"); 139 | 140 | [self runUntilPaused]; 141 | 142 | STAssertFalse(self.finished, @"shouldn't have finished by the time we get here"); 143 | 144 | [transfer release]; 145 | 146 | [multi shutdown]; 147 | 148 | [multi release]; 149 | } 150 | 151 | 152 | @end 153 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/CURLProtocolTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLProtocolTests.m 3 | // CURLHandle 4 | // 5 | // Created by Sam Deane on 20/09/2012. 6 | // Copyright (c) 2013 Karelia Software. All rights reserved. 7 | // 8 | 9 | #import "CURLProtocol.h" 10 | #import "CURLRequest.h" 11 | 12 | #import "CURLHandleBasedTest.h" 13 | 14 | @interface CURLProtocolTests : CURLHandleBasedTest 15 | 16 | @property (assign, nonatomic) BOOL pauseOnResponse; 17 | 18 | @end 19 | 20 | @implementation CURLProtocolTests 21 | 22 | - (void)setUp; 23 | { 24 | [super setUp]; 25 | [NSURLProtocol registerClass:[CURLProtocol class]]; 26 | } 27 | 28 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 29 | { 30 | NSLog(@"failed with error %@", error); 31 | 32 | self.error = error; 33 | [self pause]; 34 | } 35 | 36 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 37 | { 38 | NSLog(@"got response %@", response); 39 | 40 | self.response = response; 41 | self.buffer = [NSMutableData data]; 42 | if (self.pauseOnResponse) 43 | { 44 | [self pause]; 45 | } 46 | } 47 | 48 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)dataIn 49 | { 50 | NSLog(@"got data %ld bytes", [dataIn length]); 51 | 52 | [self.buffer appendData:dataIn]; 53 | } 54 | 55 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 56 | { 57 | NSLog(@"finished"); 58 | 59 | [self pause]; 60 | } 61 | 62 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite; 63 | { 64 | self.sending = YES; 65 | } 66 | 67 | - (void)testHTTPDownload 68 | { 69 | NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[self testFileRemoteURL]]; 70 | request.shouldUseCurlHandle = YES; 71 | 72 | NSURLConnection* connection = [NSURLConnection connectionWithRequest:request delegate:self]; 73 | 74 | STAssertNotNil(connection, @"failed to get connection for request %@", request); 75 | 76 | [self runUntilPaused]; 77 | 78 | [self checkDownloadedBufferWasCorrect]; 79 | } 80 | 81 | - (void)testCancelling 82 | { 83 | self.pauseOnResponse = YES; 84 | NSURL* largeFile = [NSURL URLWithString:@"https://github.com/karelia/CurlHandle/archive/master.zip"]; 85 | NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:largeFile]; 86 | request.shouldUseCurlHandle = YES; 87 | 88 | NSURLConnection* connection = [NSURLConnection connectionWithRequest:request delegate:self]; 89 | STAssertNotNil(connection, @"failed to get connection for request %@", request); 90 | 91 | [self runUntilPaused]; 92 | 93 | [connection cancel]; 94 | 95 | // we don't get any delegate message to say that we've been cancelled, so we just have to finish 96 | // the test here without checking anything else 97 | } 98 | 99 | - (void)testFTPDownload 100 | { 101 | NSURL* ftpRoot = [self ftpTestServer]; 102 | if (ftpRoot) 103 | { 104 | NSURL* ftpDownload = [[ftpRoot URLByAppendingPathComponent:@"CURLHandleTests"] URLByAppendingPathComponent:@"TestContent.txt"]; 105 | 106 | NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:ftpDownload]; 107 | request.shouldUseCurlHandle = YES; 108 | 109 | NSURLConnection* connection = [NSURLConnection connectionWithRequest:request delegate:self]; 110 | STAssertNotNil(connection, @"failed to get connection for request %@", request); 111 | 112 | [self runUntilPaused]; 113 | 114 | [self checkDownloadedBufferWasCorrect]; 115 | } 116 | } 117 | 118 | - (void)testFTPUpload 119 | { 120 | NSURL* ftpRoot = [self ftpTestServer]; 121 | if (ftpRoot) 122 | { 123 | NSURL* ftpUpload = [[ftpRoot URLByAppendingPathComponent:@"CURLHandleTests"] URLByAppendingPathComponent:@"Upload.txt"]; 124 | 125 | NSError* error = nil; 126 | NSURL* testNotesURL = [self testFileURL]; 127 | NSString* testNotes = [NSString stringWithContentsOfURL:testNotesURL encoding:NSUTF8StringEncoding error:&error]; 128 | 129 | NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:ftpUpload]; 130 | request.shouldUseCurlHandle = YES; 131 | [request curl_setCreateIntermediateDirectories:1]; 132 | [request setHTTPBody:[testNotes dataUsingEncoding:NSUTF8StringEncoding]]; 133 | 134 | NSURLConnection* connection = [NSURLConnection connectionWithRequest:request delegate:self]; 135 | STAssertNotNil(connection, @"failed to get connection for request %@", request); 136 | 137 | [self runUntilPaused]; 138 | 139 | NSURLResponse* response = self.response; 140 | if ([response respondsToSelector:@selector(statusCode)]) 141 | { 142 | NSUInteger code = [(id)response statusCode]; 143 | STAssertEquals(code, (NSInteger) 226, @"got unexpected code %ld", code); 144 | STAssertNil(self.error, @"got error %@", self.error); 145 | STAssertTrue([self.buffer length] == 0, @"got unexpected data %@", self.buffer); 146 | } 147 | } 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/StandaloneGcdWaitTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLMultiTests.m 3 | // 4 | // Created by Sam Deane on 20/09/2012. 5 | // Copyright (c) 2013 Karelia Software. All rights reserved. 6 | // 7 | 8 | #import "CURLHandleBasedTest.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | @interface StandaloneGCDWaitTest : CURLHandleBasedTest 18 | 19 | @end 20 | 21 | @implementation StandaloneGCDWaitTest 22 | 23 | #define log_message(...) fprintf(stderr, __VA_ARGS__) 24 | #define log_error(...) fprintf(stderr, "ERROR: " __VA_ARGS__) 25 | 26 | static void add_download(const char *url); 27 | 28 | static dispatch_queue_t queue; 29 | static int remaining = 0; 30 | static int repeats = 20; 31 | static CURLM *curl_handle; 32 | 33 | 34 | #pragma mark - Socket Action 35 | 36 | static void curl_perform_wait(StandaloneGCDWaitTest* test) 37 | { 38 | long timeout_ms = -1; 39 | CURLMcode result = curl_multi_timeout(curl_handle, &timeout_ms); 40 | if (result != CURLM_OK) log_error("curl_multi_timeout error %d", result); 41 | 42 | if (timeout_ms < 1) timeout_ms = 1; 43 | 44 | int numfds = 0; 45 | result = curl_multi_wait(curl_handle, NULL, 0, (int)timeout_ms, &numfds); 46 | if (result != CURLM_OK) log_error("curl_multi_wait error %d", result); 47 | 48 | int numrunning = 0; 49 | result = curl_multi_perform(curl_handle, &numrunning); 50 | if (result != CURLM_OK) log_error("curl_multi_perform error %d", result); 51 | 52 | int pending = 0; 53 | CURLMsg *message; 54 | while ((message = curl_multi_info_read(curl_handle, &pending))) { 55 | switch (message->msg) { 56 | case CURLMSG_DONE: 57 | { 58 | const char* done_url; 59 | CURL* easy = message->easy_handle; 60 | curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url); 61 | CURLcode code = message->data.result; 62 | printf("%s DONE\ncode:%d - %s\n", done_url, code, curl_easy_strerror(code)); 63 | 64 | struct curl_slist* list; 65 | curl_easy_getinfo(easy, CURLINFO_PRIVATE, &list); 66 | 67 | --remaining; 68 | 69 | if (--repeats) 70 | { 71 | add_download(done_url); 72 | } 73 | 74 | curl_multi_remove_handle(curl_handle, message->easy_handle); 75 | curl_easy_cleanup(message->easy_handle); 76 | curl_slist_free_all(list); 77 | 78 | break; 79 | } 80 | default: 81 | log_error("CURLMSG default\n"); 82 | abort(); 83 | } 84 | } 85 | 86 | if (remaining == 0) 87 | { 88 | log_message("cleaning up"); 89 | curl_multi_cleanup(curl_handle); 90 | [test pause]; 91 | } 92 | else 93 | { 94 | dispatch_async(queue, ^{ 95 | curl_perform_wait(test); 96 | }); 97 | } 98 | } 99 | 100 | 101 | static int debug_func(CURL *curl, curl_infotype infoType, char *info, size_t infoLength, void *userp) 102 | { 103 | char* string = strndup(info, infoLength); 104 | fprintf(stderr, "debug %d: %s", infoType, string); 105 | free(string); 106 | return 0; 107 | } 108 | 109 | 110 | #pragma mark - Top Level 111 | 112 | static void add_download(const char *url) 113 | { 114 | CURL *handle = curl_easy_init(); 115 | curl_easy_setopt(handle, CURLOPT_URL, url); 116 | curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, debug_func); 117 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 118 | 119 | curl_easy_setopt(handle, CURLOPT_URL, url); 120 | 121 | 122 | char randomname[CURL_ERROR_SIZE]; 123 | char makecmd[CURL_ERROR_SIZE]; 124 | char chmodcmd[CURL_ERROR_SIZE]; 125 | char delcmd[CURL_ERROR_SIZE]; 126 | 127 | sprintf(randomname, "test-%d", rand()); 128 | 129 | 130 | sprintf(makecmd, "*MKD %s", randomname); 131 | sprintf(chmodcmd, "SITE CHMOD 0744 %s", randomname); 132 | sprintf(delcmd, "DELE %s", randomname); 133 | 134 | struct curl_slist* list = curl_slist_append(NULL, makecmd); 135 | list = curl_slist_append(list, chmodcmd); 136 | list = curl_slist_append(list, "*DELE file1.txt"); 137 | list = curl_slist_append(list, "*DELE file2.txt"); 138 | list = curl_slist_append(list, delcmd); 139 | curl_easy_setopt(handle, CURLOPT_PRIVATE, list); 140 | curl_easy_setopt(handle, CURLOPT_POSTQUOTE, list); 141 | 142 | long timeout = 60; 143 | curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, timeout); 144 | 145 | curl_easy_setopt(handle, CURLOPT_NOBODY, 1); 146 | 147 | ++remaining; 148 | dispatch_async(queue, ^{ 149 | curl_multi_add_handle(curl_handle, handle); 150 | log_message("Added download %s\n", url); 151 | }); 152 | } 153 | 154 | 155 | - (void)test_multi_gcd_wait 156 | { 157 | if ([self setupServerWithResponseFileNamed:@"ftp"]) 158 | { 159 | queue = dispatch_queue_create("curl queue", 0); 160 | 161 | curl_handle = curl_multi_init(); 162 | 163 | NSURL* url = [[self ftpTestServer] URLByAppendingPathComponent:@"multigcdwait"]; 164 | add_download([[url absoluteString] UTF8String]); 165 | 166 | dispatch_async(queue, ^{ 167 | int numrunning = 0; 168 | curl_multi_perform(curl_handle, &numrunning); 169 | curl_perform_wait(self); 170 | }); 171 | 172 | [self runUntilPaused]; 173 | 174 | log_message("cleaned up"); 175 | } 176 | } 177 | 178 | @end 179 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/StandaloneNoGcdTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // CURLMultiTests.m 3 | // 4 | // Created by Sam Deane on 20/09/2012. 5 | // Copyright (c) 2013 Karelia Software. All rights reserved. 6 | // 7 | 8 | #import "CURLHandleBasedTest.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | @interface StandaloneNoGCDTest : CURLHandleBasedTest 18 | 19 | @end 20 | 21 | @implementation StandaloneNoGCDTest 22 | 23 | #define log_message(...) fprintf(stderr, __VA_ARGS__) 24 | #define log_error(...) fprintf(stderr, "ERROR: " __VA_ARGS__) 25 | 26 | static void add_download(const char *url); 27 | 28 | 29 | static int remaining = 0; 30 | static int repeats = 20; 31 | static CURLM *curl_handle; 32 | 33 | static void curl_perform_wait() 34 | { 35 | long timeout_ms = -1; 36 | CURLMcode result = curl_multi_timeout(curl_handle, &timeout_ms); 37 | if (result != CURLM_OK) log_error("curl_multi_timeout error %d", result); 38 | 39 | if (timeout_ms < 1) timeout_ms = 1; 40 | if (timeout_ms > 100) timeout_ms = 100; // for the purposes of the test, keep the timeout time to a minimum 41 | 42 | int numfds = 0; 43 | result = curl_multi_wait(curl_handle, NULL, 0, (int)timeout_ms, &numfds); 44 | if (result != CURLM_OK) log_error("curl_multi_wait error %d", result); 45 | 46 | int numrunning = 0; 47 | result = curl_multi_perform(curl_handle, &numrunning); 48 | if (result != CURLM_OK) log_error("curl_multi_perform error %d", result); 49 | 50 | int pending = 0; 51 | CURLMsg *message; 52 | while ((message = curl_multi_info_read(curl_handle, &pending))) { 53 | switch (message->msg) { 54 | case CURLMSG_DONE: 55 | { 56 | const char* done_url; 57 | CURL* easy = message->easy_handle; 58 | curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url); 59 | CURLcode code = message->data.result; 60 | printf("%s DONE\ncode:%d - %s\n", done_url, code, 61 | curl_easy_strerror(code)); 62 | 63 | struct curl_slist* list; 64 | curl_easy_getinfo(easy, CURLINFO_PRIVATE, &list); 65 | 66 | --remaining; 67 | 68 | if (--repeats) 69 | { 70 | add_download(done_url); 71 | } 72 | 73 | curl_multi_remove_handle(curl_handle, easy); 74 | curl_easy_cleanup(easy); 75 | curl_slist_free_all(list); 76 | 77 | break; 78 | } 79 | default: 80 | log_error("CURLMSG default\n"); 81 | abort(); 82 | } 83 | } 84 | } 85 | 86 | 87 | static int debug_func(CURL *curl, curl_infotype infoType, char *info, size_t infoLength, void *userp) 88 | { 89 | char* string = strndup(info, infoLength); 90 | fprintf(stderr, "debug %d: %s", infoType, string); 91 | free(string); 92 | return 0; 93 | } 94 | 95 | static void add_download(const char *url) 96 | { 97 | CURL *handle = curl_easy_init(); 98 | curl_easy_setopt(handle, CURLOPT_URL, url); 99 | curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, debug_func); 100 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 101 | 102 | curl_easy_setopt(handle, CURLOPT_URL, url); 103 | 104 | 105 | char randomname[CURL_ERROR_SIZE]; 106 | char makecmd[CURL_ERROR_SIZE]; 107 | char chmodcmd[CURL_ERROR_SIZE]; 108 | char delcmd[CURL_ERROR_SIZE]; 109 | 110 | sprintf(randomname, "test-%d", rand()); 111 | 112 | 113 | sprintf(makecmd, "*MKD %s", randomname); 114 | sprintf(chmodcmd, "SITE CHMOD 0744 %s", randomname); 115 | sprintf(delcmd, "DELE %s", randomname); 116 | 117 | struct curl_slist* list = curl_slist_append(NULL, makecmd); 118 | list = curl_slist_append(list, chmodcmd); 119 | list = curl_slist_append(list, "*DELE file1.txt"); 120 | list = curl_slist_append(list, "*DELE file2.txt"); 121 | list = curl_slist_append(list, delcmd); 122 | curl_easy_setopt(handle, CURLOPT_PRIVATE, list); 123 | curl_easy_setopt(handle, CURLOPT_POSTQUOTE, list); 124 | 125 | long timeout = 60; 126 | curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, timeout); 127 | 128 | curl_easy_setopt(handle, CURLOPT_NOBODY, 1); 129 | 130 | ++remaining; 131 | curl_multi_add_handle(curl_handle, handle); 132 | log_message("Added download %s\n", url); 133 | } 134 | 135 | - (void)test_multi_no_gcd 136 | { 137 | if (!self.usingMockServer) 138 | { 139 | // can't run this test with MockServer. It will deadlock, since everything is happening on the main loop. 140 | if ([self setupServerWithResponseFileNamed:@"ftp"]) 141 | { 142 | curl_handle = curl_multi_init(); 143 | 144 | NSURL* url = [[self ftpTestServer] URLByAppendingPathComponent:@"multinogcd"]; 145 | add_download([[url absoluteString] UTF8String]); 146 | 147 | while(remaining > 0) 148 | { 149 | curl_perform_wait(self); 150 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]]; 151 | } 152 | 153 | log_message("cleaning up"); 154 | curl_multi_cleanup(curl_handle); 155 | } 156 | } 157 | } 158 | 159 | @end 160 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/TestContent.txt: -------------------------------------------------------------------------------- 1 | *|*|* Some test content. Blah blah... *|*|* -------------------------------------------------------------------------------- /CURLHandleSource/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/multi-gcd-crashtest-wait.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * _ _ ____ _ 3 | * Project ___| | | | _ \| | 4 | * / __| | | | |_) | | 5 | * | (__| |_| | _ <| |___ 6 | * \___|\___/|_| \_\_____| 7 | * 8 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 9 | * 10 | * This software is licensed as described in the file COPYING, which 11 | * you should have received as part of this distribution. The terms 12 | * are also available at http://curl.haxx.se/docs/copyright.html. 13 | * 14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 | * copies of the Software, and permit persons to whom the Software is 16 | * furnished to do so, under the terms of the COPYING file. 17 | * 18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 | * KIND, either express or implied. 20 | * 21 | ***************************************************************************/ 22 | 23 | /* Example application code using the multi socket interface to download 24 | multiple files at once, but instead of using curl_multi_perform and 25 | curl_multi_wait, which uses select(), we use gcd. 26 | 27 | Written by Sam Deane, based on the multi-uv.c example. 28 | 29 | Requires gcd and (of course) libcurl. 30 | 31 | See http://en.wikipedia.org/wiki/Grand_Central_Dispatch for more information on gcd. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #define log_message(...) fprintf(stderr, __VA_ARGS__) 42 | #define log_error(...) fprintf(stderr, "ERROR: " __VA_ARGS__) 43 | 44 | void add_download(const char *url); 45 | 46 | dispatch_queue_t queue; 47 | int remaining = 0; 48 | int repeats = 20; 49 | CURLM *curl_handle; 50 | dispatch_source_t timeout; 51 | 52 | 53 | 54 | #pragma mark - Socket Action 55 | 56 | void curl_perform_wait() 57 | { 58 | long timeout_ms = -1; 59 | CURLMcode result = curl_multi_timeout(curl_handle, &timeout_ms); 60 | if (result != CURLM_OK) log_error("curl_multi_timeout error %d", result); 61 | 62 | if (timeout_ms < 1) timeout_ms = 1; 63 | 64 | int numfds = 0; 65 | result = curl_multi_wait(curl_handle, NULL, 0, (int)timeout_ms, &numfds); 66 | if (result != CURLM_OK) log_error("curl_multi_wait error %d", result); 67 | 68 | int numrunning = 0; 69 | result = curl_multi_perform(curl_handle, &numrunning); 70 | if (result != CURLM_OK) log_error("curl_multi_perform error %d", result); 71 | 72 | int pending = 0; 73 | CURLMsg *message; 74 | while ((message = curl_multi_info_read(curl_handle, &pending))) { 75 | switch (message->msg) { 76 | case CURLMSG_DONE: 77 | { 78 | const char* done_url; 79 | CURL* easy = message->easy_handle; 80 | curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url); 81 | CURLcode code = message->data.result; 82 | printf("%s DONE\ncode:%d - %s\n", done_url, code, curl_easy_strerror(code)); 83 | 84 | struct curl_slist* list; 85 | curl_easy_getinfo(easy, CURLINFO_PRIVATE, &list); 86 | 87 | --remaining; 88 | 89 | if (--repeats) 90 | { 91 | add_download(done_url); 92 | } 93 | 94 | curl_multi_remove_handle(curl_handle, message->easy_handle); 95 | curl_easy_cleanup(message->easy_handle); 96 | curl_slist_free_all(list); 97 | 98 | break; 99 | } 100 | default: 101 | log_error("CURLMSG default\n"); 102 | abort(); 103 | } 104 | } 105 | 106 | if (remaining == 0) 107 | { 108 | curl_multi_cleanup(curl_handle); 109 | exit(0); 110 | } 111 | 112 | dispatch_async(queue, ^{ 113 | curl_perform_wait(); 114 | }); 115 | } 116 | 117 | 118 | int debug_func(CURL *curl, curl_infotype infoType, char *info, size_t infoLength, void *userp) 119 | { 120 | char* string = strndup(info, infoLength); 121 | fprintf(stderr, "debug %d: %s", infoType, string); 122 | free(string); 123 | return 0; 124 | } 125 | 126 | 127 | #pragma mark - Top Level 128 | 129 | void add_download(const char *url) 130 | { 131 | CURL *handle = curl_easy_init(); 132 | curl_easy_setopt(handle, CURLOPT_URL, url); 133 | curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, debug_func); 134 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 135 | 136 | curl_easy_setopt(handle, CURLOPT_URL, url); 137 | 138 | 139 | char randomname[CURL_ERROR_SIZE]; 140 | char makecmd[CURL_ERROR_SIZE]; 141 | char chmodcmd[CURL_ERROR_SIZE]; 142 | char delcmd[CURL_ERROR_SIZE]; 143 | 144 | sprintf(randomname, "test-%d", rand()); 145 | 146 | 147 | sprintf(makecmd, "*MKD %s", randomname); 148 | sprintf(chmodcmd, "SITE CHMOD 0744 %s", randomname); 149 | sprintf(delcmd, "DELE %s", randomname); 150 | 151 | struct curl_slist* list = curl_slist_append(NULL, makecmd); 152 | list = curl_slist_append(list, chmodcmd); 153 | list = curl_slist_append(list, "*DELE file1.txt"); 154 | list = curl_slist_append(list, "*DELE file2.txt"); 155 | list = curl_slist_append(list, delcmd); 156 | curl_easy_setopt(handle, CURLOPT_PRIVATE, list); 157 | curl_easy_setopt(handle, CURLOPT_POSTQUOTE, list); 158 | 159 | long timeout = 60; 160 | curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, timeout); 161 | 162 | curl_easy_setopt(handle, CURLOPT_NOBODY, 1); 163 | 164 | ++remaining; 165 | dispatch_async(queue, ^{ 166 | curl_multi_add_handle(curl_handle, handle); 167 | log_message("Added download %s\n", url); 168 | }); 169 | } 170 | 171 | 172 | int main(int argc, char **argv) 173 | { 174 | queue = dispatch_queue_create("curl queue", 0); 175 | 176 | if (argc <= 1) 177 | return 0; 178 | 179 | if (curl_global_init(CURL_GLOBAL_ALL)) { 180 | log_error("Could not init cURL\n"); 181 | return 1; 182 | } 183 | 184 | curl_handle = curl_multi_init(); 185 | 186 | while (argc-- > 1) { 187 | add_download(argv[argc]); 188 | } 189 | 190 | dispatch_async(queue, ^{ 191 | int numrunning = 0; 192 | curl_multi_perform(curl_handle, &numrunning); 193 | curl_perform_wait(); 194 | }); 195 | 196 | dispatch_main(); 197 | 198 | return 0; 199 | } -------------------------------------------------------------------------------- /CURLHandleSource/Tests/multi-gcd-wait.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * _ _ ____ _ 3 | * Project ___| | | | _ \| | 4 | * / __| | | | |_) | | 5 | * | (__| |_| | _ <| |___ 6 | * \___|\___/|_| \_\_____| 7 | * 8 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 9 | * 10 | * This software is licensed as described in the file COPYING, which 11 | * you should have received as part of this distribution. The terms 12 | * are also available at http://curl.haxx.se/docs/copyright.html. 13 | * 14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 | * copies of the Software, and permit persons to whom the Software is 16 | * furnished to do so, under the terms of the COPYING file. 17 | * 18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 | * KIND, either express or implied. 20 | * 21 | ***************************************************************************/ 22 | 23 | /* Example application code using the multi socket interface to download 24 | multiple files at once, but instead of using curl_multi_perform and 25 | curl_multi_wait, which uses select(), we use gcd. 26 | 27 | Written by Sam Deane, based on the multi-uv.c example. 28 | 29 | Requires gcd and (of course) libcurl. 30 | 31 | See http://en.wikipedia.org/wiki/Grand_Central_Dispatch for more information on gcd. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #define log_message(...) fprintf(stderr, __VA_ARGS__) 42 | #define log_error(...) fprintf(stderr, "ERROR: " __VA_ARGS__) 43 | 44 | dispatch_queue_t queue; 45 | int remaining = 0; 46 | CURLM *curl_handle; 47 | dispatch_source_t timeout; 48 | 49 | 50 | 51 | #pragma mark - Socket Action 52 | 53 | void curl_perform_wait() 54 | { 55 | long timeout_ms = -1; 56 | CURLMcode result = curl_multi_timeout(curl_handle, &timeout_ms); 57 | if (result != CURLM_OK) log_error("curl_multi_timeout error %d", result); 58 | 59 | if (timeout_ms < 1) timeout_ms = 1; 60 | 61 | int numfds = 0; 62 | result = curl_multi_wait(curl_handle, NULL, 0, (int)timeout_ms, &numfds); 63 | if (result != CURLM_OK) log_error("curl_multi_wait error %d", result); 64 | 65 | int numrunning = 0; 66 | result = curl_multi_perform(curl_handle, &numrunning); 67 | if (result != CURLM_OK) log_error("curl_multi_perform error %d", result); 68 | 69 | int pending = 0; 70 | CURLMsg *message; 71 | while ((message = curl_multi_info_read(curl_handle, &pending))) { 72 | switch (message->msg) { 73 | case CURLMSG_DONE: 74 | { 75 | const char* done_url; 76 | CURL* easy = message->easy_handle; 77 | curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url); 78 | CURLcode code = message->data.result; 79 | printf("%s DONE\ncode:%d - %s\n", done_url, code, curl_easy_strerror(code)); 80 | 81 | curl_multi_remove_handle(curl_handle, message->easy_handle); 82 | curl_easy_cleanup(message->easy_handle); 83 | --remaining; 84 | 85 | break; 86 | } 87 | default: 88 | log_error("CURLMSG default\n"); 89 | abort(); 90 | } 91 | } 92 | 93 | if (numrunning == 0) 94 | { 95 | curl_multi_cleanup(curl_handle); 96 | exit(0); 97 | } 98 | 99 | dispatch_async(queue, ^{ 100 | curl_perform_wait(); 101 | }); 102 | } 103 | 104 | 105 | int debug_func(CURL *curl, curl_infotype infoType, char *info, size_t infoLength, void *userp) 106 | { 107 | char* string = strndup(info, infoLength); 108 | fprintf(stderr, "debug %d: %s", infoType, string); 109 | free(string); 110 | return 0; 111 | } 112 | 113 | 114 | #pragma mark - Top Level 115 | 116 | void add_download(const char *url, int num) 117 | { 118 | char filename[50]; 119 | FILE *file; 120 | CURL *handle; 121 | 122 | sprintf(filename, "%d.download.txt", num); 123 | 124 | file = fopen(filename, "w"); 125 | if (file == NULL) { 126 | log_error("Error opening %s\n", filename); 127 | return; 128 | } 129 | 130 | handle = curl_easy_init(); 131 | curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL); 132 | curl_easy_setopt(handle, CURLOPT_WRITEDATA, file); 133 | curl_easy_setopt(handle, CURLOPT_URL, url); 134 | curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, debug_func); 135 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 136 | 137 | dispatch_async(queue, ^{ 138 | curl_multi_add_handle(curl_handle, handle); 139 | log_message("Added download %s\n", url); 140 | ++remaining; 141 | }); 142 | } 143 | 144 | 145 | int main(int argc, char **argv) 146 | { 147 | queue = dispatch_queue_create("curl queue", 0); 148 | 149 | if (argc <= 1) 150 | return 0; 151 | 152 | if (curl_global_init(CURL_GLOBAL_ALL)) { 153 | log_error("Could not init cURL\n"); 154 | return 1; 155 | } 156 | 157 | curl_handle = curl_multi_init(); 158 | 159 | while (argc-- > 1) { 160 | add_download(argv[argc], argc); 161 | } 162 | 163 | dispatch_async(queue, ^{ 164 | int numrunning = 0; 165 | curl_multi_perform(curl_handle, &numrunning); 166 | curl_perform_wait(); 167 | }); 168 | 169 | dispatch_main(); 170 | 171 | return 0; 172 | } -------------------------------------------------------------------------------- /CURLHandleSource/Tests/multi-gcd.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * _ _ ____ _ 3 | * Project ___| | | | _ \| | 4 | * / __| | | | |_) | | 5 | * | (__| |_| | _ <| |___ 6 | * \___|\___/|_| \_\_____| 7 | * 8 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 9 | * 10 | * This software is licensed as described in the file COPYING, which 11 | * you should have received as part of this distribution. The terms 12 | * are also available at http://curl.haxx.se/docs/copyright.html. 13 | * 14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 | * copies of the Software, and permit persons to whom the Software is 16 | * furnished to do so, under the terms of the COPYING file. 17 | * 18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 | * KIND, either express or implied. 20 | * 21 | ***************************************************************************/ 22 | 23 | /* Example application code using the multi socket interface to download 24 | multiple files at once, but instead of using curl_multi_perform and 25 | curl_multi_wait, which uses select(), we use gcd. 26 | 27 | Written by Sam Deane, based on the multi-uv.c example. 28 | 29 | Requires gcd and (of course) libcurl. 30 | 31 | See http://en.wikipedia.org/wiki/Grand_Central_Dispatch for more information on gcd. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #define log_message(...) fprintf(stderr, __VA_ARGS__) 42 | #define log_error(...) fprintf(stderr, "ERROR: " __VA_ARGS__) 43 | 44 | dispatch_queue_t queue; 45 | int remaining = 0; 46 | CURLM *curl_handle; 47 | dispatch_source_t timeout; 48 | 49 | #pragma mark - Socket context 50 | 51 | typedef struct socket_context_s { 52 | dispatch_source_t read_source; 53 | dispatch_source_t write_source; 54 | } socket_context_t; 55 | 56 | socket_context_t* create_socket_context_s() 57 | { 58 | socket_context_t *context = (socket_context_t *) malloc(sizeof *context); 59 | memset(context, 0, sizeof(socket_context_t)); 60 | 61 | return context; 62 | } 63 | 64 | void destroy_socket_context_s(socket_context_t *context) 65 | { 66 | if (context->read_source) 67 | dispatch_source_cancel(context->read_source); 68 | 69 | if (context->write_source) 70 | dispatch_source_cancel(context->write_source); 71 | 72 | free(context); 73 | } 74 | 75 | #pragma mark - Socket Action 76 | 77 | void curl_perform_action(int socket, int actions) 78 | { 79 | int running_handles; 80 | char *done_url; 81 | CURLMsg *message; 82 | int pending; 83 | 84 | curl_multi_socket_action(curl_handle, socket, actions, &running_handles); 85 | 86 | while ((message = curl_multi_info_read(curl_handle, &pending))) { 87 | switch (message->msg) { 88 | case CURLMSG_DONE: 89 | { 90 | CURL* easy = message->easy_handle; 91 | curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url); 92 | CURLcode code = message->data.result; 93 | printf("%s DONE\ncode:%d - %s\n", done_url, code, curl_easy_strerror(code)); 94 | 95 | curl_multi_remove_handle(curl_handle, message->easy_handle); 96 | curl_easy_cleanup(message->easy_handle); 97 | --remaining; 98 | 99 | break; 100 | } 101 | default: 102 | log_error("CURLMSG default\n"); 103 | abort(); 104 | } 105 | } 106 | } 107 | 108 | #pragma mark - GCD utilities 109 | 110 | 111 | dispatch_source_t create_source(dispatch_source_type_t type, int socket, int action) 112 | { 113 | dispatch_source_t source = dispatch_source_create(type, socket, 0, queue); 114 | dispatch_source_set_event_handler(source, ^{ 115 | curl_perform_action(socket, action); 116 | }); 117 | dispatch_source_set_cancel_handler(source, ^{ 118 | dispatch_release(source); 119 | }); 120 | 121 | dispatch_resume(source); 122 | return source; 123 | } 124 | 125 | void create_timeout() 126 | { 127 | timeout = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 128 | dispatch_source_set_event_handler(timeout, ^{ 129 | curl_perform_action(CURL_SOCKET_TIMEOUT, 0); 130 | if (remaining == 0) 131 | { 132 | curl_multi_cleanup(curl_handle); 133 | exit(0); 134 | } 135 | }); 136 | 137 | dispatch_resume(timeout); 138 | } 139 | 140 | 141 | #pragma mark - MULTI callbacks 142 | 143 | void timeout_func(CURLM *multi, long timeout_ms, void *userp) 144 | { 145 | if (timeout_ms <= 0) 146 | timeout_ms = 1; /* 0 means directly call socket_action, but we'll do it in 147 | a bit */ 148 | 149 | int64_t timeout_ns = timeout_ms * NSEC_PER_MSEC; 150 | dispatch_source_set_timer(timeout, DISPATCH_TIME_NOW, timeout_ns, timeout_ns / 100); 151 | } 152 | 153 | int multi_socket_func(CURL *easy, curl_socket_t s, int action, void *userp, void *socketp) 154 | { 155 | socket_context_t *curl_context = (socket_context_t*) socketp; 156 | 157 | if (action == CURL_POLL_IN || action == CURL_POLL_OUT) { 158 | if (!curl_context) { 159 | curl_context = create_socket_context_s(); 160 | curl_multi_assign(curl_handle, s, (void *) curl_context); 161 | } 162 | } 163 | 164 | switch (action) { 165 | case CURL_POLL_IN: 166 | curl_context->read_source = create_source(DISPATCH_SOURCE_TYPE_READ, s, CURL_CSELECT_IN); 167 | break; 168 | 169 | case CURL_POLL_OUT: 170 | curl_context->write_source = create_source(DISPATCH_SOURCE_TYPE_WRITE, s, CURL_CSELECT_OUT); 171 | break; 172 | 173 | case CURL_POLL_REMOVE: 174 | if (curl_context) { 175 | destroy_socket_context_s(curl_context); 176 | curl_multi_assign(curl_handle, s, NULL); 177 | } 178 | break; 179 | default: 180 | abort(); 181 | } 182 | 183 | return 0; 184 | } 185 | 186 | #pragma mark - Top Level 187 | 188 | void add_download(const char *url, int num) 189 | { 190 | char filename[50]; 191 | FILE *file; 192 | CURL *handle; 193 | 194 | sprintf(filename, "%d.download.txt", num); 195 | 196 | file = fopen(filename, "w"); 197 | if (file == NULL) { 198 | log_error("Error opening %s\n", filename); 199 | return; 200 | } 201 | 202 | handle = curl_easy_init(); 203 | curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL); 204 | curl_easy_setopt(handle, CURLOPT_WRITEDATA, file); 205 | curl_easy_setopt(handle, CURLOPT_URL, url); 206 | 207 | dispatch_async(queue, ^{ 208 | curl_multi_add_handle(curl_handle, handle); 209 | log_message("Added download %s\n", url); 210 | ++remaining; 211 | }); 212 | } 213 | 214 | 215 | int main(int argc, char **argv) 216 | { 217 | queue = dispatch_queue_create("curl queue", 0); 218 | 219 | if (argc <= 1) 220 | return 0; 221 | 222 | if (curl_global_init(CURL_GLOBAL_ALL)) { 223 | log_error("Could not init cURL\n"); 224 | return 1; 225 | } 226 | 227 | create_timeout(); 228 | 229 | curl_handle = curl_multi_init(); 230 | curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, multi_socket_func); 231 | curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, timeout_func); 232 | 233 | while (argc-- > 1) { 234 | add_download(argv[argc], argc); 235 | } 236 | 237 | dispatch_main(); 238 | 239 | return 0; 240 | } -------------------------------------------------------------------------------- /CURLHandleSource/Tests/multi-nogcd-crashtest.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * _ _ ____ _ 3 | * Project ___| | | | _ \| | 4 | * / __| | | | |_) | | 5 | * | (__| |_| | _ <| |___ 6 | * \___|\___/|_| \_\_____| 7 | * 8 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 9 | * 10 | * This software is licensed as described in the file COPYING, which 11 | * you should have received as part of this distribution. The terms 12 | * are also available at http://curl.haxx.se/docs/copyright.html. 13 | * 14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 | * copies of the Software, and permit persons to whom the Software is 16 | * furnished to do so, under the terms of the COPYING file. 17 | * 18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 | * KIND, either express or implied. 20 | * 21 | ***************************************************************************/ 22 | 23 | /* Example application code using the multi socket interface to download 24 | multiple files at once. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define log_message(...) fprintf(stderr, __VA_ARGS__) 33 | #define log_error(...) fprintf(stderr, "ERROR: " __VA_ARGS__) 34 | 35 | void add_download(const char *url); 36 | 37 | 38 | int remaining = 0; 39 | int repeats = 20; 40 | CURLM *curl_handle; 41 | 42 | void curl_perform_wait() 43 | { 44 | long timeout_ms = -1; 45 | CURLMcode result = curl_multi_timeout(curl_handle, &timeout_ms); 46 | if (result != CURLM_OK) log_error("curl_multi_timeout error %d", result); 47 | 48 | if (timeout_ms < 1) timeout_ms = 1; 49 | 50 | int numfds = 0; 51 | result = curl_multi_wait(curl_handle, NULL, 0, (int)timeout_ms, &numfds); 52 | if (result != CURLM_OK) log_error("curl_multi_wait error %d", result); 53 | 54 | int numrunning = 0; 55 | result = curl_multi_perform(curl_handle, &numrunning); 56 | if (result != CURLM_OK) log_error("curl_multi_perform error %d", result); 57 | 58 | int pending = 0; 59 | CURLMsg *message; 60 | while ((message = curl_multi_info_read(curl_handle, &pending))) { 61 | switch (message->msg) { 62 | case CURLMSG_DONE: 63 | { 64 | const char* done_url; 65 | CURL* easy = message->easy_handle; 66 | curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &done_url); 67 | CURLcode code = message->data.result; 68 | printf("%s DONE\ncode:%d - %s\n", done_url, code, 69 | curl_easy_strerror(code)); 70 | 71 | struct curl_slist* list; 72 | curl_easy_getinfo(easy, CURLINFO_PRIVATE, &list); 73 | 74 | --remaining; 75 | 76 | if (--repeats) 77 | { 78 | add_download(done_url); 79 | } 80 | 81 | curl_multi_remove_handle(curl_handle, easy); 82 | curl_easy_cleanup(easy); 83 | curl_slist_free_all(list); 84 | 85 | break; 86 | } 87 | default: 88 | log_error("CURLMSG default\n"); 89 | abort(); 90 | } 91 | } 92 | 93 | if (remaining == 0) 94 | { 95 | curl_multi_cleanup(curl_handle); 96 | exit(0); 97 | } 98 | } 99 | 100 | 101 | int debug_func(CURL *curl, curl_infotype infoType, char *info, size_t infoLength, void *userp) 102 | { 103 | char* string = strndup(info, infoLength); 104 | fprintf(stderr, "debug %d: %s", infoType, string); 105 | free(string); 106 | return 0; 107 | } 108 | 109 | void add_download(const char *url) 110 | { 111 | CURL *handle = curl_easy_init(); 112 | curl_easy_setopt(handle, CURLOPT_URL, url); 113 | curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, debug_func); 114 | curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 115 | 116 | curl_easy_setopt(handle, CURLOPT_URL, url); 117 | 118 | 119 | char randomname[CURL_ERROR_SIZE]; 120 | char makecmd[CURL_ERROR_SIZE]; 121 | char chmodcmd[CURL_ERROR_SIZE]; 122 | char delcmd[CURL_ERROR_SIZE]; 123 | 124 | sprintf(randomname, "test-%d", rand()); 125 | 126 | 127 | sprintf(makecmd, "*MKD %s", randomname); 128 | sprintf(chmodcmd, "SITE CHMOD 0744 %s", randomname); 129 | sprintf(delcmd, "DELE %s", randomname); 130 | 131 | struct curl_slist* list = curl_slist_append(NULL, makecmd); 132 | list = curl_slist_append(list, chmodcmd); 133 | list = curl_slist_append(list, "*DELE file1.txt"); 134 | list = curl_slist_append(list, "*DELE file2.txt"); 135 | list = curl_slist_append(list, delcmd); 136 | curl_easy_setopt(handle, CURLOPT_PRIVATE, list); 137 | curl_easy_setopt(handle, CURLOPT_POSTQUOTE, list); 138 | 139 | long timeout = 60; 140 | curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, timeout); 141 | 142 | curl_easy_setopt(handle, CURLOPT_NOBODY, 1); 143 | 144 | ++remaining; 145 | curl_multi_add_handle(curl_handle, handle); 146 | log_message("Added download %s\n", url); 147 | } 148 | 149 | 150 | int main(int argc, char **argv) 151 | { 152 | if (argc <= 1) 153 | return 0; 154 | 155 | if (curl_global_init(CURL_GLOBAL_ALL)) { 156 | log_error("Could not init cURL\n"); 157 | return 1; 158 | } 159 | 160 | curl_handle = curl_multi_init(); 161 | 162 | while (argc-- > 1) { 163 | add_download(argv[argc]); 164 | } 165 | 166 | while(1) 167 | curl_perform_wait(); 168 | 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /CURLHandleSource/Tests/upload-root.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #ifdef WIN32 10 | #include 11 | #else 12 | #include 13 | #endif 14 | 15 | /* 16 | * This example shows an FTP upload to an absolute path at the root of the server, 17 | * e.g: /test.txt 18 | * 19 | * If the server's root and the user's home directories are different (ie, the result of 20 | * PWD is not "/"), the file is incorrectly uploaded to the root of the home directory, 21 | * instead of the root of the server. 22 | */ 23 | 24 | /* NOTE: if you want this example to work on Windows with libcurl as a 25 | DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION. 26 | Failing to do so will give you a crash since a DLL may not use the 27 | variable's memory when passed in to it from an app like this. */ 28 | static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) 29 | { 30 | curl_off_t nread; 31 | /* in real-world cases, this would probably get this data differently 32 | as this fread() stuff is exactly what the library already would do 33 | by default internally */ 34 | size_t retcode = fread(ptr, size, nmemb, stream); 35 | 36 | nread = (curl_off_t)retcode; 37 | 38 | fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T 39 | " bytes from file\n", nread); 40 | return retcode; 41 | } 42 | 43 | extern int upload_root(const char* url) 44 | { 45 | CURL *curl; 46 | CURLcode res; 47 | FILE *hd_src; 48 | struct stat file_info; 49 | curl_off_t fsize; 50 | 51 | /* make test content */ 52 | char* temp_path = tmpnam(NULL); 53 | FILE* f = fopen(temp_path, "w"); 54 | fprintf(f, "some test content"); 55 | fclose(f); 56 | 57 | /* get the file size of the local file */ 58 | if(stat(temp_path, &file_info)) { 59 | printf("Couldnt open '%s': %s\n", temp_path, strerror(errno)); 60 | return 1; 61 | } 62 | fsize = (curl_off_t)file_info.st_size; 63 | 64 | printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize); 65 | 66 | /* get a FILE * of the same file */ 67 | hd_src = fopen(temp_path, "rb"); 68 | 69 | /* In windows, this will init the winsock stuff */ 70 | curl_global_init(CURL_GLOBAL_ALL); 71 | 72 | /* get a curl handle */ 73 | curl = curl_easy_init(); 74 | if(curl) { 75 | /* we want to use our own read function */ 76 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); 77 | 78 | /* enable uploading */ 79 | curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); 80 | 81 | /* specify target */ 82 | curl_easy_setopt(curl,CURLOPT_URL, url); 83 | 84 | /* now specify which file to upload */ 85 | curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); 86 | 87 | /* Set the size of the file to upload (optional). If you give a *_LARGE 88 | option you MUST make sure that the type of the passed-in argument is a 89 | curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must 90 | make sure that to pass in a type 'long' argument. */ 91 | curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, 92 | (curl_off_t)fsize); 93 | 94 | /* Now run off and do what you've been told! */ 95 | res = curl_easy_perform(curl); 96 | /* Check for errors */ 97 | if(res != CURLE_OK) 98 | fprintf(stderr, "curl_easy_perform() failed: %s\n", 99 | curl_easy_strerror(res)); 100 | 101 | /* always cleanup */ 102 | curl_easy_cleanup(curl); 103 | } 104 | fclose(hd_src); /* close the local file */ 105 | 106 | curl_global_cleanup(); 107 | 108 | unlink(temp_path); 109 | 110 | return 0; 111 | } 112 | 113 | #ifndef SUPPRESS_MAIN 114 | int main(int argc, char **argv) 115 | { 116 | /* this should upload to the server root, but doesn't */ 117 | upload_root("ftp://ftptest:ftptest@10.0.1.32//libcurl_upload_test1.txt"); 118 | 119 | /* this does */ 120 | upload_root("ftp://ftptest:ftptest@10.0.1.32/%2Flibcurl_upload_test2.txt"); 121 | } 122 | #endif -------------------------------------------------------------------------------- /CURLHandleSource/built/include/cares-i386/ares_build.h: -------------------------------------------------------------------------------- 1 | /* ares_build.h. Generated from ares_build.h.in by configure. */ 2 | #ifndef __CARES_BUILD_H 3 | #define __CARES_BUILD_H 4 | 5 | 6 | /* Copyright (C) 2009 by Daniel Stenberg et al 7 | * 8 | * Permission to use, copy, modify, and distribute this software and its 9 | * documentation for any purpose and without fee is hereby granted, provided 10 | * that the above copyright notice appear in all copies and that both that 11 | * copyright notice and this permission notice appear in supporting 12 | * documentation, and that the name of M.I.T. not be used in advertising or 13 | * publicity pertaining to distribution of the software without specific, 14 | * written prior permission. M.I.T. makes no representations about the 15 | * suitability of this software for any purpose. It is provided "as is" 16 | * without express or implied warranty. 17 | */ 18 | 19 | /* ================================================================ */ 20 | /* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ 21 | /* ================================================================ */ 22 | 23 | /* 24 | * NOTE 1: 25 | * ------- 26 | * 27 | * Nothing in this file is intended to be modified or adjusted by the 28 | * c-ares library user nor by the c-ares library builder. 29 | * 30 | * If you think that something actually needs to be changed, adjusted 31 | * or fixed in this file, then, report it on the c-ares development 32 | * mailing list: http://cool.haxx.se/mailman/listinfo/c-ares/ 33 | * 34 | * This header file shall only export symbols which are 'cares' or 'CARES' 35 | * prefixed, otherwise public name space would be polluted. 36 | * 37 | * NOTE 2: 38 | * ------- 39 | * 40 | * Right now you might be staring at file ares_build.h.in or ares_build.h, 41 | * this is due to the following reason: 42 | * 43 | * On systems capable of running the configure script, the configure process 44 | * will overwrite the distributed ares_build.h file with one that is suitable 45 | * and specific to the library being configured and built, which is generated 46 | * from the ares_build.h.in template file. 47 | * 48 | */ 49 | 50 | /* ================================================================ */ 51 | /* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ 52 | /* ================================================================ */ 53 | 54 | #ifdef CARES_SIZEOF_LONG 55 | # error "CARES_SIZEOF_LONG shall not be defined except in ares_build.h" 56 | Error Compilation_aborted_CARES_SIZEOF_LONG_already_defined 57 | #endif 58 | 59 | #ifdef CARES_TYPEOF_ARES_SOCKLEN_T 60 | # error "CARES_TYPEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h" 61 | Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_already_defined 62 | #endif 63 | 64 | #ifdef CARES_SIZEOF_ARES_SOCKLEN_T 65 | # error "CARES_SIZEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h" 66 | Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_already_defined 67 | #endif 68 | 69 | /* ================================================================ */ 70 | /* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ 71 | /* ================================================================ */ 72 | 73 | /* Configure process defines this to 1 when it finds out that system */ 74 | /* header file ws2tcpip.h must be included by the external interface. */ 75 | /* #undef CARES_PULL_WS2TCPIP_H */ 76 | #ifdef CARES_PULL_WS2TCPIP_H 77 | # ifndef WIN32_LEAN_AND_MEAN 78 | # define WIN32_LEAN_AND_MEAN 79 | # endif 80 | # include 81 | # include 82 | # include 83 | #endif 84 | 85 | /* Configure process defines this to 1 when it finds out that system */ 86 | /* header file sys/types.h must be included by the external interface. */ 87 | #define CARES_PULL_SYS_TYPES_H 1 88 | #ifdef CARES_PULL_SYS_TYPES_H 89 | # include 90 | #endif 91 | 92 | /* Configure process defines this to 1 when it finds out that system */ 93 | /* header file sys/socket.h must be included by the external interface. */ 94 | #define CARES_PULL_SYS_SOCKET_H 1 95 | #ifdef CARES_PULL_SYS_SOCKET_H 96 | # include 97 | #endif 98 | 99 | /* The size of `long', as computed by sizeof. */ 100 | #define CARES_SIZEOF_LONG 4 101 | 102 | /* Integral data type used for ares_socklen_t. */ 103 | #define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t 104 | 105 | /* The size of `ares_socklen_t', as computed by sizeof. */ 106 | #define CARES_SIZEOF_ARES_SOCKLEN_T 4 107 | 108 | /* Data type definition of ares_socklen_t. */ 109 | typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; 110 | 111 | #endif /* __CARES_BUILD_H */ 112 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/cares-x86_64/ares_build.h: -------------------------------------------------------------------------------- 1 | /* ares_build.h. Generated from ares_build.h.in by configure. */ 2 | #ifndef __CARES_BUILD_H 3 | #define __CARES_BUILD_H 4 | 5 | 6 | /* Copyright (C) 2009 by Daniel Stenberg et al 7 | * 8 | * Permission to use, copy, modify, and distribute this software and its 9 | * documentation for any purpose and without fee is hereby granted, provided 10 | * that the above copyright notice appear in all copies and that both that 11 | * copyright notice and this permission notice appear in supporting 12 | * documentation, and that the name of M.I.T. not be used in advertising or 13 | * publicity pertaining to distribution of the software without specific, 14 | * written prior permission. M.I.T. makes no representations about the 15 | * suitability of this software for any purpose. It is provided "as is" 16 | * without express or implied warranty. 17 | */ 18 | 19 | /* ================================================================ */ 20 | /* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ 21 | /* ================================================================ */ 22 | 23 | /* 24 | * NOTE 1: 25 | * ------- 26 | * 27 | * Nothing in this file is intended to be modified or adjusted by the 28 | * c-ares library user nor by the c-ares library builder. 29 | * 30 | * If you think that something actually needs to be changed, adjusted 31 | * or fixed in this file, then, report it on the c-ares development 32 | * mailing list: http://cool.haxx.se/mailman/listinfo/c-ares/ 33 | * 34 | * This header file shall only export symbols which are 'cares' or 'CARES' 35 | * prefixed, otherwise public name space would be polluted. 36 | * 37 | * NOTE 2: 38 | * ------- 39 | * 40 | * Right now you might be staring at file ares_build.h.in or ares_build.h, 41 | * this is due to the following reason: 42 | * 43 | * On systems capable of running the configure script, the configure process 44 | * will overwrite the distributed ares_build.h file with one that is suitable 45 | * and specific to the library being configured and built, which is generated 46 | * from the ares_build.h.in template file. 47 | * 48 | */ 49 | 50 | /* ================================================================ */ 51 | /* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ 52 | /* ================================================================ */ 53 | 54 | #ifdef CARES_SIZEOF_LONG 55 | # error "CARES_SIZEOF_LONG shall not be defined except in ares_build.h" 56 | Error Compilation_aborted_CARES_SIZEOF_LONG_already_defined 57 | #endif 58 | 59 | #ifdef CARES_TYPEOF_ARES_SOCKLEN_T 60 | # error "CARES_TYPEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h" 61 | Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_already_defined 62 | #endif 63 | 64 | #ifdef CARES_SIZEOF_ARES_SOCKLEN_T 65 | # error "CARES_SIZEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h" 66 | Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_already_defined 67 | #endif 68 | 69 | /* ================================================================ */ 70 | /* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ 71 | /* ================================================================ */ 72 | 73 | /* Configure process defines this to 1 when it finds out that system */ 74 | /* header file ws2tcpip.h must be included by the external interface. */ 75 | /* #undef CARES_PULL_WS2TCPIP_H */ 76 | #ifdef CARES_PULL_WS2TCPIP_H 77 | # ifndef WIN32_LEAN_AND_MEAN 78 | # define WIN32_LEAN_AND_MEAN 79 | # endif 80 | # include 81 | # include 82 | # include 83 | #endif 84 | 85 | /* Configure process defines this to 1 when it finds out that system */ 86 | /* header file sys/types.h must be included by the external interface. */ 87 | #define CARES_PULL_SYS_TYPES_H 1 88 | #ifdef CARES_PULL_SYS_TYPES_H 89 | # include 90 | #endif 91 | 92 | /* Configure process defines this to 1 when it finds out that system */ 93 | /* header file sys/socket.h must be included by the external interface. */ 94 | #define CARES_PULL_SYS_SOCKET_H 1 95 | #ifdef CARES_PULL_SYS_SOCKET_H 96 | # include 97 | #endif 98 | 99 | /* The size of `long', as computed by sizeof. */ 100 | #define CARES_SIZEOF_LONG 8 101 | 102 | /* Integral data type used for ares_socklen_t. */ 103 | #define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t 104 | 105 | /* The size of `ares_socklen_t', as computed by sizeof. */ 106 | #define CARES_SIZEOF_ARES_SOCKLEN_T 4 107 | 108 | /* Data type definition of ares_socklen_t. */ 109 | typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; 110 | 111 | #endif /* __CARES_BUILD_H */ 112 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-i386/curl/curlbuild.h: -------------------------------------------------------------------------------- 1 | /* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ 2 | #ifndef __CURL_CURLBUILD_H 3 | #define __CURL_CURLBUILD_H 4 | /*************************************************************************** 5 | * _ _ ____ _ 6 | * Project ___| | | | _ \| | 7 | * / __| | | | |_) | | 8 | * | (__| |_| | _ <| |___ 9 | * \___|\___/|_| \_\_____| 10 | * 11 | * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. 12 | * 13 | * This software is licensed as described in the file COPYING, which 14 | * you should have received as part of this distribution. The terms 15 | * are also available at http://curl.haxx.se/docs/copyright.html. 16 | * 17 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 18 | * copies of the Software, and permit persons to whom the Software is 19 | * furnished to do so, under the terms of the COPYING file. 20 | * 21 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 22 | * KIND, either express or implied. 23 | * 24 | ***************************************************************************/ 25 | 26 | /* ================================================================ */ 27 | /* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ 28 | /* ================================================================ */ 29 | 30 | /* 31 | * NOTE 1: 32 | * ------- 33 | * 34 | * Nothing in this file is intended to be modified or adjusted by the 35 | * curl library user nor by the curl library builder. 36 | * 37 | * If you think that something actually needs to be changed, adjusted 38 | * or fixed in this file, then, report it on the libcurl development 39 | * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ 40 | * 41 | * This header file shall only export symbols which are 'curl' or 'CURL' 42 | * prefixed, otherwise public name space would be polluted. 43 | * 44 | * NOTE 2: 45 | * ------- 46 | * 47 | * Right now you might be staring at file include/curl/curlbuild.h.in or 48 | * at file include/curl/curlbuild.h, this is due to the following reason: 49 | * 50 | * On systems capable of running the configure script, the configure process 51 | * will overwrite the distributed include/curl/curlbuild.h file with one that 52 | * is suitable and specific to the library being configured and built, which 53 | * is generated from the include/curl/curlbuild.h.in template file. 54 | * 55 | */ 56 | 57 | /* ================================================================ */ 58 | /* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ 59 | /* ================================================================ */ 60 | 61 | #ifdef CURL_SIZEOF_LONG 62 | #error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" 63 | Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined 64 | #endif 65 | 66 | #ifdef CURL_TYPEOF_CURL_SOCKLEN_T 67 | #error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" 68 | Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined 69 | #endif 70 | 71 | #ifdef CURL_SIZEOF_CURL_SOCKLEN_T 72 | #error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" 73 | Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined 74 | #endif 75 | 76 | #ifdef CURL_TYPEOF_CURL_OFF_T 77 | #error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" 78 | Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined 79 | #endif 80 | 81 | #ifdef CURL_FORMAT_CURL_OFF_T 82 | #error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" 83 | Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined 84 | #endif 85 | 86 | #ifdef CURL_FORMAT_CURL_OFF_TU 87 | #error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" 88 | Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined 89 | #endif 90 | 91 | #ifdef CURL_FORMAT_OFF_T 92 | #error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" 93 | Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined 94 | #endif 95 | 96 | #ifdef CURL_SIZEOF_CURL_OFF_T 97 | #error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" 98 | Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined 99 | #endif 100 | 101 | #ifdef CURL_SUFFIX_CURL_OFF_T 102 | #error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" 103 | Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined 104 | #endif 105 | 106 | #ifdef CURL_SUFFIX_CURL_OFF_TU 107 | #error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" 108 | Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined 109 | #endif 110 | 111 | /* ================================================================ */ 112 | /* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ 113 | /* ================================================================ */ 114 | 115 | /* Configure process defines this to 1 when it finds out that system */ 116 | /* header file ws2tcpip.h must be included by the external interface. */ 117 | /* #undef CURL_PULL_WS2TCPIP_H */ 118 | #ifdef CURL_PULL_WS2TCPIP_H 119 | # ifndef WIN32_LEAN_AND_MEAN 120 | # define WIN32_LEAN_AND_MEAN 121 | # endif 122 | # include 123 | # include 124 | # include 125 | #endif 126 | 127 | /* Configure process defines this to 1 when it finds out that system */ 128 | /* header file sys/types.h must be included by the external interface. */ 129 | #define CURL_PULL_SYS_TYPES_H 1 130 | #ifdef CURL_PULL_SYS_TYPES_H 131 | # include 132 | #endif 133 | 134 | /* Configure process defines this to 1 when it finds out that system */ 135 | /* header file stdint.h must be included by the external interface. */ 136 | #define CURL_PULL_STDINT_H 1 137 | #ifdef CURL_PULL_STDINT_H 138 | # include 139 | #endif 140 | 141 | /* Configure process defines this to 1 when it finds out that system */ 142 | /* header file inttypes.h must be included by the external interface. */ 143 | #define CURL_PULL_INTTYPES_H 1 144 | #ifdef CURL_PULL_INTTYPES_H 145 | # include 146 | #endif 147 | 148 | /* Configure process defines this to 1 when it finds out that system */ 149 | /* header file sys/socket.h must be included by the external interface. */ 150 | #define CURL_PULL_SYS_SOCKET_H 1 151 | #ifdef CURL_PULL_SYS_SOCKET_H 152 | # include 153 | #endif 154 | 155 | /* Configure process defines this to 1 when it finds out that system */ 156 | /* header file sys/poll.h must be included by the external interface. */ 157 | /* #undef CURL_PULL_SYS_POLL_H */ 158 | #ifdef CURL_PULL_SYS_POLL_H 159 | # include 160 | #endif 161 | 162 | /* The size of `long', as computed by sizeof. */ 163 | #define CURL_SIZEOF_LONG 4 164 | 165 | /* Integral data type used for curl_socklen_t. */ 166 | #define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t 167 | 168 | /* The size of `curl_socklen_t', as computed by sizeof. */ 169 | #define CURL_SIZEOF_CURL_SOCKLEN_T 4 170 | 171 | /* Data type definition of curl_socklen_t. */ 172 | typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; 173 | 174 | /* Signed integral data type used for curl_off_t. */ 175 | #define CURL_TYPEOF_CURL_OFF_T int64_t 176 | 177 | /* Data type definition of curl_off_t. */ 178 | typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; 179 | 180 | /* curl_off_t formatting string directive without "%" conversion specifier. */ 181 | #define CURL_FORMAT_CURL_OFF_T "lld" 182 | 183 | /* unsigned curl_off_t formatting string without "%" conversion specifier. */ 184 | #define CURL_FORMAT_CURL_OFF_TU "llu" 185 | 186 | /* curl_off_t formatting string directive with "%" conversion specifier. */ 187 | #define CURL_FORMAT_OFF_T "%lld" 188 | 189 | /* The size of `curl_off_t', as computed by sizeof. */ 190 | #define CURL_SIZEOF_CURL_OFF_T 8 191 | 192 | /* curl_off_t constant suffix. */ 193 | #define CURL_SUFFIX_CURL_OFF_T LL 194 | 195 | /* unsigned curl_off_t constant suffix. */ 196 | #define CURL_SUFFIX_CURL_OFF_TU ULL 197 | 198 | #endif /* __CURL_CURLBUILD_H */ 199 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-i386/curl/curlver.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_CURLVER_H 2 | #define __CURL_CURLVER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | /* This header file contains nothing but libcurl version info, generated by 26 | a script at release-time. This was made its own header file in 7.11.2 */ 27 | 28 | /* This is the global package copyright */ 29 | #define LIBCURL_COPYRIGHT "1996 - 2013 Daniel Stenberg, ." 30 | 31 | /* This is the version number of the libcurl package from which this header 32 | file origins: */ 33 | #define LIBCURL_VERSION "7.31.0-DEV" 34 | 35 | /* The numeric version number is also available "in parts" by using these 36 | defines: */ 37 | #define LIBCURL_VERSION_MAJOR 7 38 | #define LIBCURL_VERSION_MINOR 31 39 | #define LIBCURL_VERSION_PATCH 0 40 | 41 | /* This is the numeric version of the libcurl version number, meant for easier 42 | parsing and comparions by programs. The LIBCURL_VERSION_NUM define will 43 | always follow this syntax: 44 | 45 | 0xXXYYZZ 46 | 47 | Where XX, YY and ZZ are the main version, release and patch numbers in 48 | hexadecimal (using 8 bits each). All three numbers are always represented 49 | using two digits. 1.2 would appear as "0x010200" while version 9.11.7 50 | appears as "0x090b07". 51 | 52 | This 6-digit (24 bits) hexadecimal number does not show pre-release number, 53 | and it is always a greater number in a more recent release. It makes 54 | comparisons with greater than and less than work. 55 | */ 56 | #define LIBCURL_VERSION_NUM 0x071f00 57 | 58 | /* 59 | * This is the date and time when the full source package was created. The 60 | * timestamp is not stored in git, as the timestamp is properly set in the 61 | * tarballs by the maketgz script. 62 | * 63 | * The format of the date should follow this template: 64 | * 65 | * "Mon Feb 12 11:35:33 UTC 2007" 66 | */ 67 | #define LIBCURL_TIMESTAMP "DEV" 68 | 69 | #endif /* __CURL_CURLVER_H */ 70 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-i386/curl/easy.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_EASY_H 2 | #define __CURL_EASY_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | CURL_EXTERN CURL *curl_easy_init(void); 29 | CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); 30 | CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); 31 | CURL_EXTERN void curl_easy_cleanup(CURL *curl); 32 | 33 | /* 34 | * NAME curl_easy_getinfo() 35 | * 36 | * DESCRIPTION 37 | * 38 | * Request internal information from the curl session with this function. The 39 | * third argument MUST be a pointer to a long, a pointer to a char * or a 40 | * pointer to a double (as the documentation describes elsewhere). The data 41 | * pointed to will be filled in accordingly and can be relied upon only if the 42 | * function returns CURLE_OK. This function is intended to get used *AFTER* a 43 | * performed transfer, all results from this function are undefined until the 44 | * transfer is completed. 45 | */ 46 | CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); 47 | 48 | 49 | /* 50 | * NAME curl_easy_duphandle() 51 | * 52 | * DESCRIPTION 53 | * 54 | * Creates a new curl session handle with the same options set for the handle 55 | * passed in. Duplicating a handle could only be a matter of cloning data and 56 | * options, internal state info and things like persistent connections cannot 57 | * be transferred. It is useful in multithreaded applications when you can run 58 | * curl_easy_duphandle() for each new thread to avoid a series of identical 59 | * curl_easy_setopt() invokes in every thread. 60 | */ 61 | CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); 62 | 63 | /* 64 | * NAME curl_easy_reset() 65 | * 66 | * DESCRIPTION 67 | * 68 | * Re-initializes a CURL handle to the default values. This puts back the 69 | * handle to the same state as it was in when it was just created. 70 | * 71 | * It does keep: live connections, the Session ID cache, the DNS cache and the 72 | * cookies. 73 | */ 74 | CURL_EXTERN void curl_easy_reset(CURL *curl); 75 | 76 | /* 77 | * NAME curl_easy_recv() 78 | * 79 | * DESCRIPTION 80 | * 81 | * Receives data from the connected socket. Use after successful 82 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 83 | */ 84 | CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, 85 | size_t *n); 86 | 87 | /* 88 | * NAME curl_easy_send() 89 | * 90 | * DESCRIPTION 91 | * 92 | * Sends data over the connected socket. Use after successful 93 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 94 | */ 95 | CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, 96 | size_t buflen, size_t *n); 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-i386/curl/mprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_MPRINTF_H 2 | #define __CURL_MPRINTF_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | #include 26 | #include /* needed for FILE */ 27 | 28 | #include "curl.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | CURL_EXTERN int curl_mprintf(const char *format, ...); 35 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); 36 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); 37 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, 38 | const char *format, ...); 39 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args); 40 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); 41 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); 42 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, 43 | const char *format, va_list args); 44 | CURL_EXTERN char *curl_maprintf(const char *format, ...); 45 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); 46 | 47 | #ifdef _MPRINTF_REPLACE 48 | # undef printf 49 | # undef fprintf 50 | # undef sprintf 51 | # undef vsprintf 52 | # undef snprintf 53 | # undef vprintf 54 | # undef vfprintf 55 | # undef vsnprintf 56 | # undef aprintf 57 | # undef vaprintf 58 | # define printf curl_mprintf 59 | # define fprintf curl_mfprintf 60 | #ifdef CURLDEBUG 61 | /* When built with CURLDEBUG we define away the sprintf functions since we 62 | don't want internal code to be using them */ 63 | # define sprintf sprintf_was_used 64 | # define vsprintf vsprintf_was_used 65 | #else 66 | # define sprintf curl_msprintf 67 | # define vsprintf curl_mvsprintf 68 | #endif 69 | # define snprintf curl_msnprintf 70 | # define vprintf curl_mvprintf 71 | # define vfprintf curl_mvfprintf 72 | # define vsnprintf curl_mvsnprintf 73 | # define aprintf curl_maprintf 74 | # define vaprintf curl_mvaprintf 75 | #endif 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* __CURL_MPRINTF_H */ 82 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-i386/curl/stdcheaders.h: -------------------------------------------------------------------------------- 1 | #ifndef __STDC_HEADERS_H 2 | #define __STDC_HEADERS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | #include 26 | 27 | size_t fread (void *, size_t, size_t, FILE *); 28 | size_t fwrite (const void *, size_t, size_t, FILE *); 29 | 30 | int strcasecmp(const char *, const char *); 31 | int strncasecmp(const char *, const char *, size_t); 32 | 33 | #endif /* __STDC_HEADERS_H */ 34 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-x86_64/curl/curlbuild.h: -------------------------------------------------------------------------------- 1 | /* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ 2 | #ifndef __CURL_CURLBUILD_H 3 | #define __CURL_CURLBUILD_H 4 | /*************************************************************************** 5 | * _ _ ____ _ 6 | * Project ___| | | | _ \| | 7 | * / __| | | | |_) | | 8 | * | (__| |_| | _ <| |___ 9 | * \___|\___/|_| \_\_____| 10 | * 11 | * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. 12 | * 13 | * This software is licensed as described in the file COPYING, which 14 | * you should have received as part of this distribution. The terms 15 | * are also available at http://curl.haxx.se/docs/copyright.html. 16 | * 17 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 18 | * copies of the Software, and permit persons to whom the Software is 19 | * furnished to do so, under the terms of the COPYING file. 20 | * 21 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 22 | * KIND, either express or implied. 23 | * 24 | ***************************************************************************/ 25 | 26 | /* ================================================================ */ 27 | /* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ 28 | /* ================================================================ */ 29 | 30 | /* 31 | * NOTE 1: 32 | * ------- 33 | * 34 | * Nothing in this file is intended to be modified or adjusted by the 35 | * curl library user nor by the curl library builder. 36 | * 37 | * If you think that something actually needs to be changed, adjusted 38 | * or fixed in this file, then, report it on the libcurl development 39 | * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ 40 | * 41 | * This header file shall only export symbols which are 'curl' or 'CURL' 42 | * prefixed, otherwise public name space would be polluted. 43 | * 44 | * NOTE 2: 45 | * ------- 46 | * 47 | * Right now you might be staring at file include/curl/curlbuild.h.in or 48 | * at file include/curl/curlbuild.h, this is due to the following reason: 49 | * 50 | * On systems capable of running the configure script, the configure process 51 | * will overwrite the distributed include/curl/curlbuild.h file with one that 52 | * is suitable and specific to the library being configured and built, which 53 | * is generated from the include/curl/curlbuild.h.in template file. 54 | * 55 | */ 56 | 57 | /* ================================================================ */ 58 | /* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ 59 | /* ================================================================ */ 60 | 61 | #ifdef CURL_SIZEOF_LONG 62 | #error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" 63 | Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined 64 | #endif 65 | 66 | #ifdef CURL_TYPEOF_CURL_SOCKLEN_T 67 | #error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" 68 | Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined 69 | #endif 70 | 71 | #ifdef CURL_SIZEOF_CURL_SOCKLEN_T 72 | #error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" 73 | Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined 74 | #endif 75 | 76 | #ifdef CURL_TYPEOF_CURL_OFF_T 77 | #error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" 78 | Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined 79 | #endif 80 | 81 | #ifdef CURL_FORMAT_CURL_OFF_T 82 | #error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" 83 | Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined 84 | #endif 85 | 86 | #ifdef CURL_FORMAT_CURL_OFF_TU 87 | #error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" 88 | Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined 89 | #endif 90 | 91 | #ifdef CURL_FORMAT_OFF_T 92 | #error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" 93 | Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined 94 | #endif 95 | 96 | #ifdef CURL_SIZEOF_CURL_OFF_T 97 | #error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" 98 | Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined 99 | #endif 100 | 101 | #ifdef CURL_SUFFIX_CURL_OFF_T 102 | #error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" 103 | Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined 104 | #endif 105 | 106 | #ifdef CURL_SUFFIX_CURL_OFF_TU 107 | #error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" 108 | Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined 109 | #endif 110 | 111 | /* ================================================================ */ 112 | /* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ 113 | /* ================================================================ */ 114 | 115 | /* Configure process defines this to 1 when it finds out that system */ 116 | /* header file ws2tcpip.h must be included by the external interface. */ 117 | /* #undef CURL_PULL_WS2TCPIP_H */ 118 | #ifdef CURL_PULL_WS2TCPIP_H 119 | # ifndef WIN32_LEAN_AND_MEAN 120 | # define WIN32_LEAN_AND_MEAN 121 | # endif 122 | # include 123 | # include 124 | # include 125 | #endif 126 | 127 | /* Configure process defines this to 1 when it finds out that system */ 128 | /* header file sys/types.h must be included by the external interface. */ 129 | #define CURL_PULL_SYS_TYPES_H 1 130 | #ifdef CURL_PULL_SYS_TYPES_H 131 | # include 132 | #endif 133 | 134 | /* Configure process defines this to 1 when it finds out that system */ 135 | /* header file stdint.h must be included by the external interface. */ 136 | /* #undef CURL_PULL_STDINT_H */ 137 | #ifdef CURL_PULL_STDINT_H 138 | # include 139 | #endif 140 | 141 | /* Configure process defines this to 1 when it finds out that system */ 142 | /* header file inttypes.h must be included by the external interface. */ 143 | /* #undef CURL_PULL_INTTYPES_H */ 144 | #ifdef CURL_PULL_INTTYPES_H 145 | # include 146 | #endif 147 | 148 | /* Configure process defines this to 1 when it finds out that system */ 149 | /* header file sys/socket.h must be included by the external interface. */ 150 | #define CURL_PULL_SYS_SOCKET_H 1 151 | #ifdef CURL_PULL_SYS_SOCKET_H 152 | # include 153 | #endif 154 | 155 | /* Configure process defines this to 1 when it finds out that system */ 156 | /* header file sys/poll.h must be included by the external interface. */ 157 | /* #undef CURL_PULL_SYS_POLL_H */ 158 | #ifdef CURL_PULL_SYS_POLL_H 159 | # include 160 | #endif 161 | 162 | /* The size of `long', as computed by sizeof. */ 163 | #define CURL_SIZEOF_LONG 8 164 | 165 | /* Integral data type used for curl_socklen_t. */ 166 | #define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t 167 | 168 | /* The size of `curl_socklen_t', as computed by sizeof. */ 169 | #define CURL_SIZEOF_CURL_SOCKLEN_T 4 170 | 171 | /* Data type definition of curl_socklen_t. */ 172 | typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; 173 | 174 | /* Signed integral data type used for curl_off_t. */ 175 | #define CURL_TYPEOF_CURL_OFF_T long 176 | 177 | /* Data type definition of curl_off_t. */ 178 | typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; 179 | 180 | /* curl_off_t formatting string directive without "%" conversion specifier. */ 181 | #define CURL_FORMAT_CURL_OFF_T "ld" 182 | 183 | /* unsigned curl_off_t formatting string without "%" conversion specifier. */ 184 | #define CURL_FORMAT_CURL_OFF_TU "lu" 185 | 186 | /* curl_off_t formatting string directive with "%" conversion specifier. */ 187 | #define CURL_FORMAT_OFF_T "%ld" 188 | 189 | /* The size of `curl_off_t', as computed by sizeof. */ 190 | #define CURL_SIZEOF_CURL_OFF_T 8 191 | 192 | /* curl_off_t constant suffix. */ 193 | #define CURL_SUFFIX_CURL_OFF_T L 194 | 195 | /* unsigned curl_off_t constant suffix. */ 196 | #define CURL_SUFFIX_CURL_OFF_TU UL 197 | 198 | #endif /* __CURL_CURLBUILD_H */ 199 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-x86_64/curl/curlver.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_CURLVER_H 2 | #define __CURL_CURLVER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | /* This header file contains nothing but libcurl version info, generated by 26 | a script at release-time. This was made its own header file in 7.11.2 */ 27 | 28 | /* This is the global package copyright */ 29 | #define LIBCURL_COPYRIGHT "1996 - 2013 Daniel Stenberg, ." 30 | 31 | /* This is the version number of the libcurl package from which this header 32 | file origins: */ 33 | #define LIBCURL_VERSION "7.31.0-DEV" 34 | 35 | /* The numeric version number is also available "in parts" by using these 36 | defines: */ 37 | #define LIBCURL_VERSION_MAJOR 7 38 | #define LIBCURL_VERSION_MINOR 31 39 | #define LIBCURL_VERSION_PATCH 0 40 | 41 | /* This is the numeric version of the libcurl version number, meant for easier 42 | parsing and comparions by programs. The LIBCURL_VERSION_NUM define will 43 | always follow this syntax: 44 | 45 | 0xXXYYZZ 46 | 47 | Where XX, YY and ZZ are the main version, release and patch numbers in 48 | hexadecimal (using 8 bits each). All three numbers are always represented 49 | using two digits. 1.2 would appear as "0x010200" while version 9.11.7 50 | appears as "0x090b07". 51 | 52 | This 6-digit (24 bits) hexadecimal number does not show pre-release number, 53 | and it is always a greater number in a more recent release. It makes 54 | comparisons with greater than and less than work. 55 | */ 56 | #define LIBCURL_VERSION_NUM 0x071f00 57 | 58 | /* 59 | * This is the date and time when the full source package was created. The 60 | * timestamp is not stored in git, as the timestamp is properly set in the 61 | * tarballs by the maketgz script. 62 | * 63 | * The format of the date should follow this template: 64 | * 65 | * "Mon Feb 12 11:35:33 UTC 2007" 66 | */ 67 | #define LIBCURL_TIMESTAMP "DEV" 68 | 69 | #endif /* __CURL_CURLVER_H */ 70 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-x86_64/curl/easy.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_EASY_H 2 | #define __CURL_EASY_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | CURL_EXTERN CURL *curl_easy_init(void); 29 | CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); 30 | CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); 31 | CURL_EXTERN void curl_easy_cleanup(CURL *curl); 32 | 33 | /* 34 | * NAME curl_easy_getinfo() 35 | * 36 | * DESCRIPTION 37 | * 38 | * Request internal information from the curl session with this function. The 39 | * third argument MUST be a pointer to a long, a pointer to a char * or a 40 | * pointer to a double (as the documentation describes elsewhere). The data 41 | * pointed to will be filled in accordingly and can be relied upon only if the 42 | * function returns CURLE_OK. This function is intended to get used *AFTER* a 43 | * performed transfer, all results from this function are undefined until the 44 | * transfer is completed. 45 | */ 46 | CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); 47 | 48 | 49 | /* 50 | * NAME curl_easy_duphandle() 51 | * 52 | * DESCRIPTION 53 | * 54 | * Creates a new curl session handle with the same options set for the handle 55 | * passed in. Duplicating a handle could only be a matter of cloning data and 56 | * options, internal state info and things like persistent connections cannot 57 | * be transferred. It is useful in multithreaded applications when you can run 58 | * curl_easy_duphandle() for each new thread to avoid a series of identical 59 | * curl_easy_setopt() invokes in every thread. 60 | */ 61 | CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); 62 | 63 | /* 64 | * NAME curl_easy_reset() 65 | * 66 | * DESCRIPTION 67 | * 68 | * Re-initializes a CURL handle to the default values. This puts back the 69 | * handle to the same state as it was in when it was just created. 70 | * 71 | * It does keep: live connections, the Session ID cache, the DNS cache and the 72 | * cookies. 73 | */ 74 | CURL_EXTERN void curl_easy_reset(CURL *curl); 75 | 76 | /* 77 | * NAME curl_easy_recv() 78 | * 79 | * DESCRIPTION 80 | * 81 | * Receives data from the connected socket. Use after successful 82 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 83 | */ 84 | CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, 85 | size_t *n); 86 | 87 | /* 88 | * NAME curl_easy_send() 89 | * 90 | * DESCRIPTION 91 | * 92 | * Sends data over the connected socket. Use after successful 93 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 94 | */ 95 | CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, 96 | size_t buflen, size_t *n); 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-x86_64/curl/mprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_MPRINTF_H 2 | #define __CURL_MPRINTF_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | #include 26 | #include /* needed for FILE */ 27 | 28 | #include "curl.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | CURL_EXTERN int curl_mprintf(const char *format, ...); 35 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); 36 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); 37 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, 38 | const char *format, ...); 39 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args); 40 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); 41 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); 42 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, 43 | const char *format, va_list args); 44 | CURL_EXTERN char *curl_maprintf(const char *format, ...); 45 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); 46 | 47 | #ifdef _MPRINTF_REPLACE 48 | # undef printf 49 | # undef fprintf 50 | # undef sprintf 51 | # undef vsprintf 52 | # undef snprintf 53 | # undef vprintf 54 | # undef vfprintf 55 | # undef vsnprintf 56 | # undef aprintf 57 | # undef vaprintf 58 | # define printf curl_mprintf 59 | # define fprintf curl_mfprintf 60 | #ifdef CURLDEBUG 61 | /* When built with CURLDEBUG we define away the sprintf functions since we 62 | don't want internal code to be using them */ 63 | # define sprintf sprintf_was_used 64 | # define vsprintf vsprintf_was_used 65 | #else 66 | # define sprintf curl_msprintf 67 | # define vsprintf curl_mvsprintf 68 | #endif 69 | # define snprintf curl_msnprintf 70 | # define vprintf curl_mvprintf 71 | # define vfprintf curl_mvfprintf 72 | # define vsnprintf curl_mvsnprintf 73 | # define aprintf curl_maprintf 74 | # define vaprintf curl_mvaprintf 75 | #endif 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* __CURL_MPRINTF_H */ 82 | -------------------------------------------------------------------------------- /CURLHandleSource/built/include/curl-x86_64/curl/stdcheaders.h: -------------------------------------------------------------------------------- 1 | #ifndef __STDC_HEADERS_H 2 | #define __STDC_HEADERS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at http://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | #include 26 | 27 | size_t fread (void *, size_t, size_t, FILE *); 28 | size_t fwrite (const void *, size_t, size_t, FILE *); 29 | 30 | int strcasecmp(const char *, const char *); 31 | int strncasecmp(const char *, const char *, size_t); 32 | 33 | #endif /* __STDC_HEADERS_H */ 34 | -------------------------------------------------------------------------------- /CURLHandleSource/built/libcares.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleSource/built/libcares.dylib -------------------------------------------------------------------------------- /CURLHandleSource/built/libcares.dylib.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.libcares.dylib 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /CURLHandleSource/built/libcares.dylib.dSYM/Contents/Resources/DWARF/libcares.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleSource/built/libcares.dylib.dSYM/Contents/Resources/DWARF/libcares.dylib -------------------------------------------------------------------------------- /CURLHandleSource/built/libcurl.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleSource/built/libcurl.dylib -------------------------------------------------------------------------------- /CURLHandleSource/built/libcurl.dylib.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.libcurl.dylib 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /CURLHandleSource/built/libcurl.dylib.dSYM/Contents/Resources/DWARF/libcurl.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleSource/built/libcurl.dylib.dSYM/Contents/Resources/DWARF/libcurl.dylib -------------------------------------------------------------------------------- /CURLHandleSource/libcares-README.txt: -------------------------------------------------------------------------------- 1 | libcares is a git submodule - be sure to update it via git 2 | 3 | How to build libcares: 4 | 1. Update the source to a new version if desired. 5 | 2. Select the target "libcares" in the Scheme popup (32- or 64-bit doesn't matter). 6 | 3. Build. Just a regular Cmd-B build. No archiving or anything. 7 | Because the builds are controlled by scripts, not Xcode, they always build for "release", but also with debug info. 8 | Note also that the build outputs are: 9 | libcares.dylib & libcares.dylib.dSYM 10 | 4. Make a new git commit in CurlHandle if needed. Git is tracking the built dylib & dSYM as well as the source. 11 | 12 | After updating/rebuilding libcares, you should update/rebuild any libraries, frameworks, or apps that depend on it, such as libcurl & CURLHandle.framework. 13 | 14 | NOTE: Building libcurl will automatically build libcares, too. -------------------------------------------------------------------------------- /CURLHandleSource/libcurl-README.txt: -------------------------------------------------------------------------------- 1 | libcurl is a git submodule - be sure to update it via git 2 | 3 | How to build libcurl: 4 | 1. Update the source to a new version if desired. 5 | 2. Select the target "libcurl" in the Scheme popup (32- or 64-bit doesn't matter). 6 | 3. Build. Just a regular Cmd-B build. No archiving or anything. 7 | Because the builds are controlled by scripts, not Xcode, they always build for "release", but also with debug info. 8 | Note also that the build outputs are: 9 | libcurl.dylib & libcurl.dylib.dSYM 10 | 4. Make a new git commit if needed. Git is tracking the built dylib & dSYM as well as the source. 11 | 12 | After updating/rebuilding libcurl, you should update/rebuild any libraries, frameworks, or apps that depend on it, such as CURLHandle.framework. 13 | 14 | Building CURLHandle.framework (the CURLHandle target) uses the current build of libcurl.dylib -- it does not rebuild it. That's a decision we made for performance during CURLHandle builds. 15 | 16 | Dependencies: 17 | libcurl depends on 18 | libcares 19 | libssh2 20 | 21 | libcares is built automatically by building the libcurl target, 22 | libssh2 is buit separately in another project. 23 | 24 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/CURLHandleTester_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CURLHandleTester' target in the 'CURLHandleTester' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/FindPanel.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | { 5 | ACTIONS = { 6 | findNext = id; 7 | findNextAndOrderFindPanelOut = id; 8 | findPrevious = id; 9 | replace = id; 10 | replaceAll = id; 11 | replaceAndFind = id; 12 | }; 13 | CLASS = TextFinder; 14 | LANGUAGE = ObjC; 15 | OUTLETS = { 16 | findNextButton = id; 17 | findTextField = id; 18 | ignoreCaseButton = id; 19 | replaceAllScopeMatrix = id; 20 | replaceTextField = id; 21 | statusField = id; 22 | }; 23 | SUPERCLASS = NSObject; 24 | } 25 | ); 26 | IBVersion = 1; 27 | } -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/FindPanel.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 65 594 356 240 0 0 1920 1178 7 | IBFramework Version 8 | 291.0 9 | IBOpenObjects 10 | 11 | 8 12 | 13 | IBSystem Version 14 | 6I32 15 | 16 | 17 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/FindPanel.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleTesterSource/English.lproj/FindPanel.nib/keyedobjects.nib -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/FindPanel.nib/objects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleTesterSource/English.lproj/FindPanel.nib/objects.nib -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu-preQuentin.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | { 5 | ACTIONS = {go = id; stop = id; useBigFile = id; useSSLTest = id; useSnoop = id; }; 6 | CLASS = TestController; 7 | LANGUAGE = ObjC; 8 | OUTLETS = { 9 | oBackground = id; 10 | oBody = id; 11 | oCookieDictionary = id; 12 | oCookieFileString = id; 13 | oCookieParseCheckbox = id; 14 | oCookieResult = id; 15 | oFollow = id; 16 | oGoButton = id; 17 | oHeader = id; 18 | oHeaderParseCheckbox = id; 19 | oPassword = id; 20 | oPostCheckbox = id; 21 | oPostDictionary = id; 22 | oProgress = NSProgressIndicator; 23 | oRenderHTMLCheckbox = id; 24 | oResultCode = id; 25 | oSSL = id; 26 | oStatus = id; 27 | oStopButton = id; 28 | oURL = id; 29 | oUserID = id; 30 | }; 31 | SUPERCLASS = NSObject; 32 | }, 33 | { 34 | ACTIONS = { 35 | findNext = id; 36 | findNextAndOrderFindPanelOut = id; 37 | findPrevious = id; 38 | jumpToSelection = id; 39 | orderFrontFindPanel = id; 40 | replace = id; 41 | replaceAll = id; 42 | replaceAndFind = id; 43 | takeFindStringFromSelection = id; 44 | }; 45 | CLASS = TextFinder; 46 | LANGUAGE = ObjC; 47 | OUTLETS = { 48 | findNextButton = id; 49 | findTextField = id; 50 | ignoreCaseButton = id; 51 | replaceAllScopeMatrix = id; 52 | replaceTextField = id; 53 | statusField = id; 54 | }; 55 | SUPERCLASS = NSObject; 56 | } 57 | ); 58 | IBVersion = 1; 59 | } -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu-preQuentin.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 210 872 356 240 0 0 1920 1178 7 | IBEditorPositions 8 | 9 | 29 10 | 164 491 292 44 0 0 1920 1178 11 | 12 | IBFramework Version 13 | 291.0 14 | IBOpenObjects 15 | 16 | 21 17 | 29 18 | 19 | IBSystem Version 20 | 6I32 21 | 22 | 23 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu-preQuentin.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleTesterSource/English.lproj/MainMenu-preQuentin.nib/keyedobjects.nib -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu-preQuentin.nib/objects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleTesterSource/English.lproj/MainMenu-preQuentin.nib/objects.nib -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | { 5 | ACTIONS = {go = id; stop = id; useBigFile = id; useSSLTest = id; useSnoop = id; }; 6 | CLASS = TestController; 7 | LANGUAGE = ObjC; 8 | OUTLETS = { 9 | oBackground = id; 10 | oBody = id; 11 | oCookieDictionary = id; 12 | oCookieFileString = id; 13 | oCookieParseCheckbox = id; 14 | oCookieResult = id; 15 | oFollow = id; 16 | oGoButton = id; 17 | oHeader = id; 18 | oHeaderParseCheckbox = id; 19 | oPassword = id; 20 | oPostCheckbox = id; 21 | oPostDictionary = id; 22 | oProgress = NSProgressIndicator; 23 | oRenderHTMLCheckbox = id; 24 | oResultCode = id; 25 | oResultLocation = id; 26 | oResultReason = id; 27 | oResultVers = id; 28 | oSSL = id; 29 | oStatus = id; 30 | oStopButton = id; 31 | oURL = id; 32 | oUserID = id; 33 | }; 34 | SUPERCLASS = NSObject; 35 | } 36 | ); 37 | IBVersion = 1; 38 | } -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 72 268 356 240 0 0 1920 1178 7 | IBEditorPositions 8 | 9 | 29 10 | 300 484 292 44 0 0 1920 1178 11 | 12 | IBFramework Version 13 | 291.0 14 | IBOpenObjects 15 | 16 | 21 17 | 18 | IBSystem Version 19 | 6G37 20 | 21 | 22 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/English.lproj/MainMenu.nib/objects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleTesterSource/English.lproj/MainMenu.nib/objects.nib -------------------------------------------------------------------------------- /CURLHandleTesterSource/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | curl 11 | CFBundleIdentifier 12 | com.karelia.CURLHandleTester 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | NSMainNibFile 24 | MainMenu 25 | NSPrincipalClass 26 | NSApplication 27 | 28 | 29 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/NSData+plist.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | // Courtesy of Ken Dyke. 4 | // See "What is the easiest way to get an XML Plist into an NSDictionary?" on macosx-dev@omnigroup.com 5 | 6 | @interface NSData(nsObjectNSDataExtensions) 7 | 8 | // Go from XML to property list 9 | - (id)propertyListFromXMLWithOptions:(CFPropertyListMutabilityOptions)options; 10 | - (id)propertyListFromXML; 11 | - (id)mutablePropertyListFromXML; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/NSData+plist.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // NSData+plist.m 4 | // 5 | // 6 | 7 | // Courtesy of Ken Dyke. 8 | // See "What is the easiest way to get an XML Plist into an NSDictionary?" on macosx-dev@omnigroup.com 9 | // 10 | // Similar to [NSDictionary dictionaryWithContentsOfFile:path] but uses text as the input. 11 | 12 | #import "NSData+plist.h" 13 | 14 | @implementation NSData(nsObjectNSDataExtensions) 15 | 16 | - (id)propertyListFromXMLWithOptions:(CFPropertyListMutabilityOptions)options 17 | { 18 | CFPropertyListRef pList; 19 | CFStringRef errorString = nil; 20 | 21 | pList = CFPropertyListCreateFromXMLData(NULL, (CFDataRef)self, options, &errorString); 22 | 23 | // Error if string, or if the pList is actually NOT a dictionary, but is instead a STRING! 24 | if(errorString) 25 | { 26 | NSLog(@"Error loading from Property List:%@",(NSString*)errorString); 27 | CFRelease(errorString); 28 | } 29 | if (![(id)pList isKindOfClass:[NSDictionary class]]) 30 | { 31 | NSLog(@"Error loading from Property List -- result is not a dictionary"); 32 | [(id)pList release]; 33 | return nil; 34 | } 35 | return [(id)pList autorelease]; 36 | } 37 | 38 | - (id)propertyListFromXML 39 | { 40 | return [self propertyListFromXMLWithOptions:kCFPropertyListImmutable]; 41 | } 42 | 43 | - (id)mutablePropertyListFromXML 44 | { 45 | return [self propertyListFromXMLWithOptions:kCFPropertyListMutableContainersAndLeaves]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/TestController.h: -------------------------------------------------------------------------------- 1 | // Created by Dan Wood on Mon Oct 01 2001. 2 | // This is in the public domain, but please report any improvements back to the author. 3 | 4 | #import 5 | #import 6 | #import 7 | #import "NSData+plist.h" 8 | 9 | @class CURLHandle; 10 | 11 | @interface TestController : NSObject 12 | { 13 | IBOutlet id oBackground; 14 | IBOutlet id oFollow; 15 | IBOutlet id oPassword; 16 | IBOutlet id oPostCheckbox; 17 | IBOutlet id oHeaderParseCheckbox; 18 | IBOutlet id oCookieParseCheckbox; 19 | IBOutlet NSProgressIndicator *oProgress; 20 | IBOutlet id oSSL; 21 | IBOutlet id oURL; 22 | IBOutlet id oUserID; 23 | IBOutlet id oCookieFileString; 24 | IBOutlet id oCookieDictionary; 25 | IBOutlet id oPostDictionary; 26 | IBOutlet id oCookieResult; 27 | 28 | IBOutlet id oResultCode; 29 | IBOutlet id oResultReason; 30 | IBOutlet id oResultLocation; 31 | IBOutlet id oResultVers; 32 | IBOutlet id oHeader; 33 | IBOutlet id oBody; 34 | 35 | IBOutlet id oGoButton; 36 | IBOutlet id oStopButton; 37 | 38 | IBOutlet id oRenderHTMLCheckbox; 39 | IBOutlet id oStatus; 40 | 41 | NSURLConnection *_connection; 42 | NSMutableData *_dataReceived; 43 | NSURLHandleStatus _theStatus; 44 | } 45 | 46 | - (IBAction)go:(id)sender; 47 | - (IBAction)stop:(id)sender; 48 | - (IBAction)useSnoop:(id)sender; 49 | - (IBAction) useBigFile:(id)sender; 50 | - (IBAction) useSSLTest:(id)sender; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/TextFinder.h: -------------------------------------------------------------------------------- 1 | /* 2 | Reusable find panel functionality (find, replace). 3 | Need one shared instance of TextFinder to which the menu items and widgets in the find panel are connected. 4 | Loads UI lazily. 5 | Works on first responder, assumed to be an NSTextView. 6 | */ 7 | 8 | #import 9 | 10 | #define Forward YES 11 | #define Backward NO 12 | 13 | @interface TextFinder : NSObject { 14 | NSString *findString; 15 | id findTextField; 16 | id replaceTextField; 17 | id ignoreCaseButton; 18 | id findNextButton; 19 | id replaceAllScopeMatrix; 20 | id statusField; 21 | BOOL lastFindWasSuccessful; 22 | } 23 | 24 | /* Common way to get a text finder. One instance of TextFinder per app is good enough. */ 25 | + (id)sharedInstance; 26 | 27 | /* Main method for external users; does a find in the first responder. Selects found range or beeps. */ 28 | - (BOOL)find:(BOOL)direction; 29 | 30 | /* Loads UI lazily */ 31 | - (NSPanel *)findPanel; 32 | 33 | /* Gets the first responder and returns it if it's an NSTextView */ 34 | - (NSTextView *)textObjectToSearchIn; 35 | 36 | /* Get/set the current find string. Will update UI if UI is loaded */ 37 | - (NSString *)findString; 38 | - (void)setFindString:(NSString *)string; 39 | - (void)setFindString:(NSString *)string writeToPasteboard:(BOOL)flag; 40 | 41 | /* Misc internal methods */ 42 | - (void)appDidActivate:(NSNotification *)notification; 43 | - (void)loadFindStringFromPasteboard; 44 | - (void)loadFindStringToPasteboard; 45 | 46 | /* Action methods, sent from the find panel UI; can also be connected to menu items */ 47 | - (void)findNext:(id)sender; 48 | - (void)findPrevious:(id)sender; 49 | - (void)findNextAndOrderFindPanelOut:(id)sender; 50 | - (void)replace:(id)sender; 51 | - (void)replaceAndFind:(id)sender; 52 | - (void)replaceAll:(id)sender; 53 | - (void)orderFrontFindPanel:(id)sender; 54 | - (void)takeFindStringFromSelection:(id)sender; 55 | - (void)jumpToSelection:(id)sender; 56 | 57 | @end 58 | 59 | -------------------------------------------------------------------------------- /CURLHandleTesterSource/curl.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karelia/CurlHandle/82d036fa7e453b71a01a8a6ba2d7e31560490009/CURLHandleTesterSource/curl.icns -------------------------------------------------------------------------------- /CURLHandleTesterSource/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | return NSApplicationMain(argc, (const char **) argv); 6 | } 7 | -------------------------------------------------------------------------------- /Documentation/Building Libraries-template.md: -------------------------------------------------------------------------------- 1 | Building libraries 2 | 3 | CURLHandle uses its own builds of libcurl, libcares, libcrypto, libssl and libssh2. 4 | 5 | The good news is that we commit built versions of these to either this git repo or one of the submodule repos. 6 | 7 | So in normal use, you shouldn't need to worry about this, and can stop reading now. 8 | 9 | However, should you find yourself needing to rebuild these libraries for some reason, this is how you do it. 10 | 11 | 12 | ## Install Tools 13 | 14 | Homebrew 15 | brew update 16 | brew install automake (if it's not already installed) 17 | brew versions automake (we want to use ver. 1.12.6) 18 | cd /usr/local/Library/Formula/ 19 | git checkout 3a7567c /usr/local/Library/Formula/automake.rb 20 | brew unlink automake 21 | brew install automake (should show ver 1.12.6 installing) 22 | (also note the cool beer mug emoji when brew is done :-P ) 23 | 24 | brew install pkg-config 25 | brew install libtool 26 | 27 | There is now a script {{Scripts/install-tools.sh}} which you can run to perform these steps. 28 | 29 | 30 | ## Fetch Code 31 | 32 | git 33 | git checkout "v4.x-beta" 34 | git submodule update --recursive 35 | (new commits in CurlHandle and SFTP leave the library build dirs in place to allow debugging) 36 | 37 | ## Build 38 | 39 | ### Using Xcode 40 | OpenSSL - libcrypto, libssl 41 | open SFTP/OpenSSL.xcodeproj 42 | build target openssl (with Product / Build For / Archiving) 43 | libssh2 44 | open SFTP/libssh2.xcodeproj 45 | build target libssh2 (for archiving) 46 | libcurl, libcares 47 | open CURLHandleSource/CURLHandle.xcodeproj 48 | build target libcurl (for archiving) 49 | 50 | ### From the command line 51 | 52 | cd 53 | Scripts/build-libs.sh 54 | 55 | ## Debugging 56 | 57 | Because of the vaguaries of the way these libraries are built, Xcode has trouble locating the source files when you're debugging, even though we do commit the dSYM files. 58 | 59 | This is one reason why you might find yourself wanting to build the libraries locally - as long as the built objects etc are hanging around on your machine, Xcode should find the source ok. 60 | 61 | Ideally we'll figure out how to fix things so that this isn't necessary. 62 | 63 | On the other hand, ideally you won't need to debug the internals of these libraries. 64 | 65 | ## Running libcurl's Test Suite 66 | 67 | There is an extensive test suite that comes with libcurl. 68 | 69 | You can attempt to run this suite using the following script: 70 | 71 | Scripts/test-libs.sh 72 | 73 | The tests are run for the x86_64 variant of the built library, which is created as part of the build process, and thus buried away in an object folder somewhere. 74 | 75 | The tests *aren't* run directly from the curl/ folder, since this hasn't been ./configure'd etc. 76 | 77 | The libcurl test script itself requires some details that the user inputs when the script is first run, and which are then stored in a 'setup' file inside the curl/ folder. These details include a user name, email address, and a description of the machine the tests are running on. 78 | 79 | Since we're running the scripts on a copy of the curl/ folder, we need to copy this 'setup' file in from somewhere. Currently, it's copied in from Scripts/setup. This means that it's got my details in it! You may wish to change these before running... 80 | 81 | Ideally we should probably build this setup file on the fly, pulling out the relevant information from elsewhere. 82 | -------------------------------------------------------------------------------- /Documentation/NSArray+CurlHTTPExtensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

NSArray (CurlHTTPExtensions)


6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
Declared In:
14 |
CURLHandle.h
15 |
16 | 17 |

18 | 19 | 20 |

Category Description

21 | This category on NSArray adds methods for header and cookie access. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |


43 |

Method Types

44 |
45 | 46 | 47 |
48 | 49 |
- parsedCookies
50 | 51 |
52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 |

Instance Methods

62 | 63 | 64 | 65 |

parsedCookies

66 | - (NSDictionary *)parsedCookies 67 |

68 | Parse the array of cookie lines, turning it into a dictionary of key/values 69 | (suitable for passing to setRequestCookies:).

70 | 71 | For instance, this will turn

72 | 73 | ( "B=96lr6csucjt99&b=2; expires=Thu, 15 Apr 2010 20:00:00 GMT; path=/; domain=.yahoo.com"; )

74 | 75 | into

76 | 77 | { 78 | B = { 79 | value = "96lr6csucjt99&b=2"; 80 | expires = "Thu, 15 Apr 2010 20:00:00 GMT"; 81 | path = "/"; 82 | domain = ".yahoo.com"; 83 | } 84 | } 85 | 86 | 87 | 88 | 89 | 90 |

91 | 92 | -------------------------------------------------------------------------------- /Documentation/NSDictionary+CurlHTTPExtensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

NSDictionary (CurlHTTPExtensions)


6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
Declared In:
14 |
CURLHandle.h
15 |
16 | 17 |

18 | 19 | 20 |

Category Description

21 | This category adds methods for dealing with HTTP input and output to an NSDictionary. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |


43 |

Method Types

44 |
45 | 46 | 47 |
48 | 49 |
- formatForHTTP
50 | 51 |
- formatForHTTPUsingEncoding:
52 | 53 |
- formatForHTTPUsingEncoding:ordering:
54 | 55 |
56 | 57 |
58 | 59 | 60 | 61 | 62 | 63 | 64 |
65 |

Instance Methods

66 | 67 | 68 | 69 |

formatForHTTP

70 | - (NSString *)formatForHTTP 71 |

72 | Convert a dictionary to an HTTP-formatted string with 7-bit ASCII encoding; 73 | see formatForHTTPUsingEncoding. 74 | 75 |


76 |

formatForHTTPUsingEncoding:

77 | - (NSString *)formatForHTTPUsingEncoding:(NSStringEncoding)inEncoding 78 | 79 |

80 | Convert a dictionary to an HTTP-formatted string with the given encoding. 81 | Spaces are turned into +; other special characters are escaped with %; 82 | keys and values are output as key=value; in between arguments is &. 83 | 84 |


85 |

formatForHTTPUsingEncoding:ordering:

86 | - (NSString *)formatForHTTPUsingEncoding:(NSStringEncoding)inEncoding ordering:(NSArray *)inOrdering 87 | 88 |

89 | Convert a dictionary to an HTTP-formatted string with the given encoding, as above. The inOrdering parameter specifies the order to place the inputs, for servers that care about this. (Note that keys in the dictionary that aren't in inOrdering will not be included.) If inOrdering is nil, all keys and values will be output in an unspecified order. 90 | 91 | 92 | 93 | 94 | 95 |

96 | 97 | -------------------------------------------------------------------------------- /Documentation/NSString+CurlHTTPExtensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

NSString (CurlHTTPExtensions)


6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
Declared In:
14 |
CURLHandle.h
15 |
16 | 17 |

18 | 19 | 20 |

Category Description

21 | No category description. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |


43 |

Method Types

44 |
45 | 46 | 47 |
48 | 49 |
- headerStatus
50 | 51 |
- headerHTTPVersion
52 | 53 |
- headerMatchingKey:
54 | 55 |
- headersMatchingKey:
56 | 57 |
- allHTTPHeaderDicts
58 | 59 |
- headerKey
60 | 61 |
- headerValue
62 | 63 |
- componentsSeparatedByLineSeparators
64 | 65 |
66 | 67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 |
75 |

Instance Methods

76 | 77 | 78 | 79 |

allHTTPHeaderDicts

80 | - (NSArray *)allHTTPHeaderDicts 81 |

82 | No method description. 83 | 84 |


85 |

componentsSeparatedByLineSeparators

86 | - (NSArray *)componentsSeparatedByLineSeparators 87 |

88 | No method description. 89 | 90 |


91 |

headerHTTPVersion

92 | - (NSString *)headerHTTPVersion 93 |

94 | No method description. 95 | 96 |


97 |

headerKey

98 | - (NSString *)headerKey 99 |

100 | No method description. 101 | 102 |


103 |

headerMatchingKey:

104 | - (NSString *)headerMatchingKey:(NSString *)inKey 105 | 106 |

107 | No method description. 108 | 109 |


110 |

headerStatus

111 | - (NSString *)headerStatus 112 |

113 | No method description. 114 | 115 |


116 |

headerValue

117 | - (NSString *)headerValue 118 |

119 | No method description. 120 | 121 |


122 |

headersMatchingKey:

123 | - (NSArray *)headersMatchingKey:(NSString *)inKey 124 | 125 |

126 | No method description. 127 | 128 | 129 | 130 | 131 | 132 |

133 | 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CURLHandle is a high level Objective-C interface to the libcurl library. 2 | 3 | It was originally created by Dan Wood of [Karelia Software](http://karelia.com), way back in the mists of time, when dinosaurs still roamed the earth (ok, sometime around 2001). 4 | 5 | It is now mostly maintained by [Mike Abdullah](http://twitter.com/mikeabdullah) (also of Karelia), with guest appearances by [Sam Deane](http://bornsleepy.com/sam) of [Elegant Chaos](http://elegantchaos.com). 6 | 7 | ## Documentation 8 | 9 | This documentation is under development. 10 | 11 | Eventually, full documentation will be found on the [github pages](http://karelia.github.io/CurlHandle/Documentation). 12 | 13 | ## License 14 | 15 | Blah. 16 | 17 | ## Manifest 18 | 19 | This package contains the following top-level items: 20 | 21 | - CURLHandleSource -- folder containing project that makes CURLHandle.framework. 22 | - CURLHandleTesterSource -- folder containing project that makes CURLHandleTester.app; a useful "template" for making sure your own projects properly include CURLHandle framework. 23 | - curl -- git submodule containing the libcurl source 24 | - c-ares -- git submodule containing the libcares source 25 | - SFTP -- git submodule containing libssh2 and associated support files 26 | - Scripts -- miscellaneous scripts 27 | - Documentation -- source files for the [documentation](http://karelia.github.io/CurlHandle/Documentation), including the [release notes](http://karelia.github.io/CurlHandle/Documentation/docs/Documentation/Release%20Notes.html) 28 | -------------------------------------------------------------------------------- /Scripts/build-libs.sh: -------------------------------------------------------------------------------- 1 | build() { 2 | 3 | echo "Building $2" 4 | 5 | obj="$HOME/Library/Caches/CurlHandle/$2/obj" 6 | sym="$HOME/Library/Caches/CurlHandle/$2/sym" 7 | rm -rf "$obj" 8 | rm -rf "$sym" 9 | xcodebuild -project $1.xcodeproj -target $2 -configuration Debug OBJROOT="$obj" SYMROOT="$sym" > /tmp/build.log 10 | res=$? 11 | 12 | if [ $res -ne 0 ]; 13 | then 14 | cat /tmp/build.log 15 | echo "$1 build failed" 16 | exit $res 17 | fi 18 | 19 | } 20 | 21 | # remove old versions 22 | rm -rf CURLHandleSource/built 23 | 24 | # build SFTP libraries too? 25 | 26 | if [ "$1" == "--all" ]; 27 | then 28 | cd SFTP 29 | build OpenSSL openssl 30 | build libssh2 libssh2 31 | cd .. 32 | 33 | elif [ "$1" == "--curl-only" ]; 34 | then 35 | echo "Skipping SFTP libraries" 36 | 37 | else 38 | echo "Usage: build-libs.sh { --all | --curl-only }" 39 | exit 0 40 | fi 41 | 42 | # build libcurl and libcares 43 | cd CURLHandleSource 44 | build CURLHandle libcurl 45 | 46 | echo "Done" 47 | open "built" -------------------------------------------------------------------------------- /Scripts/c-ares-clean.sh: -------------------------------------------------------------------------------- 1 | # glibtoolize (and maybe other tools) are not supplied with OS X. 2 | # Add default macports & homebrew paths in attempt to find them. 3 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 4 | 5 | # Clean original source dir, just in case. 6 | cd "${SRCROOT}/../c-ares" 7 | echo "Please ignore any messages about \"No rule to make target distclean.\" That just means the build dir is already clean." 8 | make distclean 9 | 10 | # Remove final output files from previous run. 11 | OUTDIR="${SRCROOT}/built" 12 | rm -Rf "${OUTDIR}/include/cares-i386" 13 | rm -Rf "${OUTDIR}/include/cares-x86_64" 14 | rm -f "${OUTDIR}/libcares.dylib" 15 | rm -Rf "${OUTDIR}/libcares.dylib.dSYM" 16 | 17 | # Remove intermediate output files from previous run. 18 | open "${OBJROOT}" 19 | rm -f "${OBJROOT}/libcares.dylib" 20 | rm -Rf "${OBJROOT}/libcares.dylib.dSYM" 21 | 22 | # Remove build dirs from previous run. 23 | rm -Rf "${OBJROOT}/cares-i386" 24 | rm -Rf "${OBJROOT}/cares-x86_64" 25 | -------------------------------------------------------------------------------- /Scripts/c-ares-combine.sh: -------------------------------------------------------------------------------- 1 | # glibtoolize (and maybe other tools) are not supplied with OS X. 2 | # Add default macports & homebrew paths in attempt to find them. 3 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 4 | 5 | # Create final dylibs. 6 | cd "${OBJROOT}" 7 | lipo -create -arch i386 cares-i386/.libs/libcares-i386.dylib -arch x86_64 cares-x86_64/.libs/libcares-x86_64.dylib -output libcares.dylib 8 | 9 | # Create dSYMs 10 | dsymutil libcares.dylib 11 | 12 | # Strip dylibs 13 | strip -x libcares.dylib 14 | 15 | # Final output to project dir, not build dir. 16 | OUTDIR="${SRCROOT}/built" 17 | mkdir -p "${OUTDIR}/include/cares-i386" 18 | mkdir -p "${OUTDIR}/include/cares-x86_64" 19 | cp -f libcares.dylib "${OUTDIR}" 20 | cp -Rf libcares.dylib.dSYM "${OUTDIR}" 21 | cp -f cares-i386/ares_build.h "${OUTDIR}/include/cares-i386" 22 | cp -f cares-x86_64/ares_build.h "${OUTDIR}/include/cares-x86_64" 23 | 24 | # Display results. 25 | lipo -detailed_info "${OUTDIR}/libcares.dylib" 26 | exit 0 27 | -------------------------------------------------------------------------------- /Scripts/c-ares-config.sh: -------------------------------------------------------------------------------- 1 | # First parameter should be "i386" or "x86_64" 2 | MODE=$1 3 | 4 | # glibtoolize (and maybe other tools) are not supplied with OS X. 5 | # Add default macports & homebrew paths in attempt to find them. 6 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 7 | 8 | # Copy source to a new location to build. 9 | cd "${SRCROOT}/.." 10 | mkdir -p "${OBJROOT}" 11 | cp -af c-ares "${OBJROOT}/cares-$MODE" 12 | 13 | # Buildconf 14 | cd "${OBJROOT}/cares-$MODE" 15 | echo "Please ignore any messages about \"No rule to make target distclean.\" That just means the build dir is already clean." 16 | make distclean 17 | echo "***" 18 | echo "***" 19 | echo "*** NOTE: Error messages about installing files are not errors. Please ignore. ***" 20 | echo "***" 21 | echo "***" 22 | ./buildconf 23 | 24 | # Configure 25 | ./configure \ 26 | CC="clang" \ 27 | CFLAGS="-isysroot ${SDKROOT} -arch $MODE -g -w -mmacosx-version-min=10.6" \ 28 | --host=$MODE-apple-darwin10 \ 29 | --with-sysroot="${SDKROOT}" \ 30 | --enable-debug \ 31 | --enable-optimize \ 32 | --disable-warnings \ 33 | --disable-werror \ 34 | --disable-curldebug \ 35 | --disable-symbol-hiding \ 36 | --enable-nonblocking \ 37 | --enable-shared \ 38 | --disable-static 39 | -------------------------------------------------------------------------------- /Scripts/c-ares-copy-built.sh: -------------------------------------------------------------------------------- 1 | # First parameter should be "i386" or "x86_64" 2 | MODE=$1 3 | 4 | # Copy ares_build.h for use by libcurl compile. 5 | cd "${OBJROOT}/cares-$MODE" 6 | cp -f ares_build.h ares_build-$MODE.h 7 | -------------------------------------------------------------------------------- /Scripts/c-ares-make.sh: -------------------------------------------------------------------------------- 1 | # First parameter should be "i386" or "x86_64" 2 | MODE=$1 3 | 4 | # glibtoolize (and maybe other tools) are not supplied with OS X. 5 | # Add default macports & homebrew paths in attempt to find them. 6 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 7 | 8 | cd "${OBJROOT}/cares-$MODE" 9 | make 10 | -------------------------------------------------------------------------------- /Scripts/curl-clean.sh: -------------------------------------------------------------------------------- 1 | # glibtoolize (and maybe other tools) are not supplied with OS X. 2 | # Add default macports & homebrew paths in attempt to find them. 3 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 4 | 5 | # Remove final output files from previous run. 6 | OUTDIR="${SRCROOT}/built" 7 | rm -f "${OUTDIR}/libcurl.dylib" 8 | rm -Rf "${OUTDIR}/libcurl.dylib.dSYM" 9 | 10 | # Remove intermediate output files from previous run. 11 | rm -f "${OBJROOT}/libcurl.dylib" 12 | rm -Rf "${OBJROOT}/libcurl.dylib.dSYM" 13 | 14 | # Remove build dirs from previous run. 15 | rm -Rf "${OBJROOT}/curl-i386" 16 | rm -Rf "${OBJROOT}/curl-x86_64" 17 | rm -Rf "${OBJROOT}/libssh2" 18 | rm -Rf "${OBJROOT}/c-ares-i386" 19 | rm -Rf "${OBJROOT}/c-ares-x86_64" 20 | -------------------------------------------------------------------------------- /Scripts/curl-combine.sh: -------------------------------------------------------------------------------- 1 | # glibtoolize (and maybe other tools) are not supplied with OS X. 2 | # Add default macports & homebrew paths in attempt to find them. 3 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 4 | 5 | # Create final dylibs. 6 | cd "${OBJROOT}" 7 | lipo -create -arch i386 curl-i386/lib/.libs/libcurl-i386.dylib -arch x86_64 curl-x86_64/lib/.libs/libcurl-x86_64.dylib -output libcurl.dylib 8 | 9 | # Create dSYMs 10 | dsymutil libcurl.dylib 11 | 12 | # Strip dylibs 13 | strip -x libcurl.dylib 14 | 15 | # Final output to project dir, not source/build dir. 16 | OUTDIR="${SRCROOT}/built" 17 | mkdir -p "${OUTDIR}/include/curl-i386/curl" 18 | mkdir -p "${OUTDIR}/include/curl-x86_64/curl" 19 | cp -f libcurl.dylib "${OUTDIR}" 20 | cp -Rf libcurl.dylib.dSYM "${OUTDIR}" 21 | cp -Rf curl-i386/include/curl/*.h "${OUTDIR}/include/curl-i386/curl/" 22 | cp -Rf curl-x86_64/include/curl/*.h "${OUTDIR}/include/curl-x86_64/curl/" 23 | 24 | # Display results. 25 | lipo -detailed_info "${OUTDIR}/libcurl.dylib" 26 | exit 0 27 | -------------------------------------------------------------------------------- /Scripts/curl-config.sh: -------------------------------------------------------------------------------- 1 | # First parameter should be "i386" or "x86_64" 2 | MODE=$1 3 | 4 | # glibtoolize (and maybe other tools) are not supplied with OS X. 5 | # Add default macports & homebrew paths in attempt to find them. 6 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 7 | 8 | # Copy source to a new location to build. 9 | cd "${SRCROOT}/.." 10 | mkdir -p "${OBJROOT}" 11 | cp -af curl "${OBJROOT}/curl-$MODE" 12 | 13 | # Copy libssh2 (we depend on it) headers & dylibs. 14 | cd "${SRCROOT}/../SFTP" 15 | mkdir -p "${OBJROOT}/libssh2/lib" 16 | cp -af libssh2/include "${OBJROOT}/libssh2" 17 | cp -f libssh2.dylib "${OBJROOT}/libssh2/lib" 18 | 19 | # Freaking unbelievably, we also have to copy the libs that libssh2 depends on to the proper relative runtime location, so that the ./configure script can load libssh2 at *configure* time. 20 | cd "${SRCROOT}/../SFTP" 21 | mkdir -p "${OBJROOT}/libssh2/Frameworks" 22 | cp -f libcrypto.dylib "${OBJROOT}/libssh2/Frameworks" 23 | cp -f libssl.dylib "${OBJROOT}/libssh2/Frameworks" 24 | 25 | # Copy libcares (we depend on it) headers & dylibs. 26 | cd "${SRCROOT}" 27 | mkdir -p "${OBJROOT}/c-ares-$MODE/include" 28 | mkdir -p "${OBJROOT}/c-ares-$MODE/lib" 29 | cp -f ../c-ares/ares*.h "${OBJROOT}/c-ares-$MODE/include" 30 | # Overwrite generic ares_build.h with the one from our actual build. 31 | cp -f built/include/cares-$MODE/ares_build.h "${OBJROOT}/c-ares-$MODE/include/ares_build.h" 32 | cp -f built/libcares.dylib "${OBJROOT}/c-ares-$MODE/lib" 33 | 34 | # Buildconf 35 | cd "${OBJROOT}/curl-$MODE" 36 | echo "Please ignore any messages about \"No rule to make target distclean.\" That just means the build dir is already clean." 37 | make distclean 38 | echo "***" 39 | echo "***" 40 | echo "*** NOTE: Error messages about installing files are not errors. Please ignore. ***" 41 | echo "***" 42 | echo "***" 43 | ./buildconf 44 | 45 | # Configure 46 | ./configure \ 47 | CC="clang" \ 48 | CFLAGS="-isysroot ${SDKROOT} -arch $MODE -g -w -mmacosx-version-min=10.6" \ 49 | --host=$MODE-apple-darwin10 \ 50 | --with-sysroot="${SDKROOT}" \ 51 | --with-darwinssl \ 52 | --with-libssh2="${OBJROOT}/libssh2" \ 53 | --enable-ares="${OBJROOT}/c-ares-$MODE" \ 54 | --without-libidn \ 55 | --enable-debug \ 56 | --enable-optimize \ 57 | --disable-warnings \ 58 | --disable-werror \ 59 | --disable-curldebug \ 60 | --disable-symbol-hiding \ 61 | --enable-shared \ 62 | --disable-static \ 63 | --enable-proxy 64 | ##--enable-threaded-resolver [either this or c-ares, this is heavy-uses a thread for every resolve call] 65 | -------------------------------------------------------------------------------- /Scripts/curl-make.sh: -------------------------------------------------------------------------------- 1 | # First parameter should be "i386" or "x86_64" 2 | MODE=$1 3 | 4 | # glibtoolize (and maybe other tools) are not supplied with OS X. 5 | # Add default macports & homebrew paths in attempt to find them. 6 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 7 | 8 | cd "${OBJROOT}/curl-$MODE" 9 | make 10 | -------------------------------------------------------------------------------- /Scripts/install-tools.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | brew update 4 | brew install automake 5 | brew versions automake 6 | cd /usr/local/Library/Formula/ 7 | git checkout 3a7567c /usr/local/Library/Formula/automake.rb 8 | brew unlink automake 9 | brew install automake 10 | 11 | brew install pkg-config 12 | brew install libtool 13 | 14 | -------------------------------------------------------------------------------- /Scripts/rename-install.sh: -------------------------------------------------------------------------------- 1 | # First parameter should be "i386" or "x86_64" 2 | MODE=$1 3 | 4 | # Second parameter should be the lib name, eg "curl" or "cares" 5 | NAME=$2 6 | 7 | # Third parameter is the location of the libs - eg ".libs" for c-ares, or "lib/.libs" for curl 8 | LIBSLOC=$3 9 | 10 | # glibtoolize (and maybe other tools) are not supplied with OS X. 11 | # Add default macports & homebrew paths in attempt to find them. 12 | export PATH=${PATH}:/opt/local/bin:/usr/local/bin 13 | 14 | # Correct the load commands of the dylibs. 15 | cd "${OBJROOT}/$NAME-$MODE/$LIBSLOC" 16 | 17 | # Get the full filenames of the dylibs from the symlinks. 18 | # E.g.: dylib:"libcrypto.1.0.0.dylib" symlink:"libcrypto.dylib" 19 | LONG_DYLIB=`readlink -n lib$NAME.dylib` 20 | 21 | # Fix ID. 22 | install_name_tool -id @rpath/lib$NAME.dylib ${LONG_DYLIB} 23 | 24 | # Correct load path of libs that we load (libssh2). 25 | # [already correct] install_name_tool -change /usr/local/lib/${LONG_DYLIB} @rpath/lib$NAME.dylib ${LONG_DYLIB} 26 | # Add rpath search paths. 27 | install_name_tool -add_rpath @loader_path/../Frameworks ${LONG_DYLIB} 28 | 29 | # Copy dylibs to have arch in name. 30 | cp -f ${LONG_DYLIB} lib$NAME-$MODE.dylib 31 | -------------------------------------------------------------------------------- /Scripts/setup: -------------------------------------------------------------------------------- 1 | name='Sam Deane' 2 | email='sam@elegantchaos.com' 3 | desc='Macbook Pro 15-inch, Mid 2010 2.66 GHz Intel Core i7' 4 | confopts='--with-ssl --enable-debug' 5 | notes='' 6 | fixed='4' 7 | -------------------------------------------------------------------------------- /Scripts/test-libs.sh: -------------------------------------------------------------------------------- 1 | build() { 2 | 3 | echo "Building $2" 4 | 5 | obj="$HOME/Library/Caches/CurlHandle/obj" 6 | sym="$HOME/Library/Caches/CurlHandle/sym" 7 | xcodebuild -project $1.xcodeproj -target $2 -configuration Debug OBJROOT="$obj" SYMROOT="$sym" > /tmp/build.log 8 | res=$? 9 | 10 | if [ $res -ne 0 ]; 11 | then 12 | cat /tmp/build.log 13 | echo "$1 build failed" 14 | exit $res 15 | fi 16 | 17 | } 18 | 19 | 20 | 21 | cd CURLHandleSource 22 | 23 | # if necessary, build everything first 24 | # this will leave the various object files knocking around that the tests will need 25 | # in theory we only require this step if we've not already built on this machine 26 | # (of if something has changed since then, of course) 27 | # since building is quite slow, it's helpful to be able to skip it 28 | 29 | if [ "$1" == "--build-and-test" ]; 30 | then 31 | build CURLHandle libcurl 32 | 33 | elif [ "$1" == "--test-only" ]; 34 | then 35 | echo "Skipping rebuilding libraries" 36 | 37 | else 38 | echo "Usage: test-libs.sh { --build-and-test | --test-only }" 39 | exit 0 40 | fi 41 | 42 | # buidling this target attempts to copy the 64 bit versions of the build libraries into 43 | # the right places, then invokes 'make test' to build and run the tests 44 | 45 | build CURLHandle libcurl-tests-x86_64 46 | 47 | echo "Tests done" 48 | 49 | cat /tmp/build.log 50 | -------------------------------------------------------------------------------- /Scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script builds and runs the unit tests and produces output in a format that is compatible with Jenkins. 4 | 5 | base=`dirname $0` 6 | pushd "$base/.." > /dev/null 7 | build="$PWD/test-build" 8 | ocunit2junit="$PWD/CURLHandleSource/Tests/MockServer/UnitTests/OCUnit2JUnit/bin/ocunit2junit" 9 | popd > /dev/null 10 | 11 | echo "Building and running tests into $build" 12 | 13 | sym="$build/sym" 14 | obj="$build/obj" 15 | 16 | testout="$build/output.log" 17 | testerr="$build/error.log" 18 | 19 | rm -rf "$build" 20 | mkdir -p "$build" 21 | 22 | xcodebuild -workspace "CURLHandle.xcworkspace" -scheme "CURLHandle" -sdk "macosx" -config "Debug" test OBJROOT="$obj" SYMROOT="$sym" > "$testout" 2> "$testerr" 23 | cd "$build" 24 | "$ocunit2junit" < "$testout" 25 | -------------------------------------------------------------------------------- /Scripts/useftpserver.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | defaults write otest CURLHandleFTPTestURL $1 4 | -------------------------------------------------------------------------------- /Scripts/usemockserver.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | defaults write otest CURLHandleFTPTestURL "MockServer" 4 | --------------------------------------------------------------------------------