CFHTTPCookieStorage.c
1 // 2 // CFHTTPCookieStorage.c 3 // CFNetwork 4 // 5 // Copyright (c) 2014 Apportable. All rights reserved. 6 // 7 8 #include "CFBase.h" 9 #include "CFRuntime.h" 10 #include "CFHTTPCookieStorage.h" 11 #include "CFHTTPCookie.h" 12 #include "CFArray.h" 13 #include <dispatch/dispatch.h> 14 15 struct __CFHTTPCookieStorage { 16 CFRuntimeBase _base; 17 CFMutableArrayRef _cookies; 18 }; 19 20 static void __CFHTTPCookieStorageDeallocate(CFTypeRef cf) { 21 struct __CFHTTPCookieStorage *item = (struct __CFHTTPCookieStorage *)cf; 22 CFRelease(item->_cookies); 23 } 24 25 static CFTypeID __kCFHTTPCookieStorageTypeID = _kCFRuntimeNotATypeID; 26 27 static const CFRuntimeClass __CFHTTPCookieStorageClass = { 28 _kCFRuntimeScannedObject, 29 "CFHTTPCookieStorage", 30 NULL, // init 31 NULL, // copy 32 __CFHTTPCookieStorageDeallocate, 33 NULL, 34 NULL, 35 NULL, 36 NULL 37 }; 38 39 static void __CFHTTPCookieStorageInitialize(void) { 40 __kCFHTTPCookieStorageTypeID = _CFRuntimeRegisterClass(&__CFHTTPCookieStorageClass); 41 } 42 43 CFTypeID CFHTTPCookieStorageGetTypeID(void) { 44 if (__kCFHTTPCookieStorageTypeID == _kCFRuntimeNotATypeID) { 45 __CFHTTPCookieStorageInitialize(); 46 } 47 return __kCFHTTPCookieStorageTypeID; 48 } 49 50 static struct __CFHTTPCookieStorage *_CFHTTPCookieStorageCreate(CFAllocatorRef allocator) { 51 CFIndex size = sizeof(struct __CFHTTPCookieStorage) - sizeof(CFRuntimeBase); 52 struct __CFHTTPCookieStorage *cookieStorage = (struct __CFHTTPCookieStorage *)_CFRuntimeCreateInstance(allocator, CFHTTPCookieStorageGetTypeID(), size, NULL); 53 54 cookieStorage->_cookies = (CFMutableArrayRef)CFRetain(CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks)); 55 56 57 return cookieStorage; 58 } 59 60 61 62 CFHTTPCookieStorageRef CFHTTPCookieStorageGetDefault() { 63 static struct __CFHTTPCookieStorage *sharedStorage = NULL; 64 static dispatch_once_t once = 0L; 65 dispatch_once(&once, ^{ 66 sharedStorage = _CFHTTPCookieStorageCreate(kCFAllocatorDefault); 67 }); 68 return (CFHTTPCookieStorageRef)sharedStorage; 69 70 } 71 72 void CFHTTPCookieStorageDeleteCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie) { 73 CFMutableArrayRef cookies = storage->_cookies; 74 CFIndex i = CFArrayGetFirstIndexOfValue(cookies, 75 CFRangeMake(0, CFArrayGetCount(cookies)), 76 cookie); 77 if (i != kCFNotFound) 78 CFArrayRemoveValueAtIndex(cookies, i); 79 } 80 81 void CFHTTPCookieStorageSetCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie) { 82 CFIndex existingCookieIndex = kCFNotFound; 83 for (int j=0; j<CFArrayGetCount(storage->_cookies); j++) { 84 CFHTTPCookieRef existingCookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(storage->_cookies, j); 85 if (CFStringCompare(CFHTTPCookieGetName(existingCookie), CFHTTPCookieGetName(cookie), kCFCompareCaseInsensitive)==kCFCompareEqualTo) { 86 existingCookieIndex = j; 87 break; 88 } 89 } 90 if (existingCookieIndex == kCFNotFound) { 91 CFArrayAppendValue(storage->_cookies, cookie); 92 } else { 93 CFArrayReplaceValues(storage->_cookies, CFRangeMake(existingCookieIndex, 1), (CFTypeRef*)&cookie, 1); 94 } 95 } 96 97 CFArrayRef CFHTTPCookieStorageCopyCookies(CFHTTPCookieStorageRef storage) { 98 return CFArrayCreateCopy(kCFAllocatorDefault, storage->_cookies); 99 } 100 101 CFArrayRef CFHTTPCookieStorageCopyCookiesForURL(CFHTTPCookieStorageRef storage, CFURLRef url) { 102 //fixme respect the url 103 return CFHTTPCookieStorageCopyCookies(storage); 104 } 105 106 107 void CFHTTPCookieStorageSetCookies(CFHTTPCookieStorageRef storage, CFArrayRef cookies) { 108 //fixme bad big O. 109 for (int i=0; i<CFArrayGetCount(cookies); i++) { 110 CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookies, i); 111 CFHTTPCookieStorageSetCookie(storage, cookie); 112 } 113 } 114 115 116 void CFHTTPCookieStorageSetCookiesWithResponseHeaderFields(CFHTTPCookieStorageRef storage, CFDictionaryRef headerFields, CFURLRef url) { 117 CFArrayRef cookies = CFHTTPCookieCreateWithResponseHeaderFields(headerFields, url); 118 if (cookies != NULL) { 119 CFHTTPCookieStorageSetCookies(storage, cookies); 120 CFRelease(cookies); 121 } 122 } 123 CFDictionaryRef CFHTTPCookieStorageCopyRequestHeaderFieldsForURL(CFHTTPCookieStorageRef storage, CFURLRef url) { 124 return CFHTTPCookieCopyRequestHeaderFields(storage->_cookies); 125 } 126 127 128