1/* 2 * cgGet.cpp - simplified interface to use CFNetwork to do one 3 * HTTP or HTTPS GET transaction. 4 */ 5 6#include "cfSimpleGet.h" 7#include <CoreServices/CoreServices.h> 8 9#define BUFSIZE 1024 10 11#define DEBUG_PRINT 0 12#if DEBUG_PRINT 13#define dprintf(args...) printf(args) 14#else 15#define dprintf(args...) 16#endif 17 18CFDataRef cfSimpleGet( 19 const char *url) 20{ 21 CFURLRef cfUrl = NULL; 22 CFMutableDataRef rtnData = NULL; 23 CFReadStreamRef rdStrm = NULL; 24 CFHTTPMessageRef myReq = NULL; 25 Boolean brtn; 26 UInt8 rbuf[BUFSIZE]; 27 CFIndex irtn; 28 bool isOpen = false; 29 CFStreamStatus rsStat; 30 31 cfUrl = CFURLCreateWithBytes(kCFAllocatorDefault, 32 (UInt8 *)url, strlen(url), kCFStringEncodingASCII, NULL); 33 if(cfUrl == NULL) { 34 printf("***Error creating URL for %s.\n", url); 35 return NULL; 36 } 37 myReq = CFHTTPMessageCreateRequest(kCFAllocatorDefault, 38 CFSTR("GET"), cfUrl, kCFHTTPVersion1_0); 39 if(myReq == NULL) { 40 printf("***Error creating HTTP msg for %s.\n", url); 41 goto errOut; 42 } 43 /* no msg body, no headers */ 44 45 rdStrm = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myReq); 46 if(rdStrm == NULL) { 47 printf("***Error creating CFReadStream for %s.\n", url); 48 goto errOut; 49 } 50 dprintf("...opening rd stream for %s\n", url); 51 brtn = CFReadStreamOpen(rdStrm); 52 if(!brtn) { 53 printf("***Error (1) opening CFReadStream for %s.\n", url); 54 goto errOut; 55 } 56 57 /* wait for open */ 58 do { 59 rsStat = CFReadStreamGetStatus(rdStrm); 60 switch(rsStat) { 61 case kCFStreamStatusError: 62 printf("***Error (2) opening CFReadStream for %s.\n", url); 63 goto errOut; 64 case kCFStreamStatusAtEnd: 65 printf("***Unexpected EOF while opening %s\n", url); 66 goto errOut; 67 case kCFStreamStatusClosed: 68 printf("***Unexpected close while opening %s\n", url); 69 goto errOut; 70 case kCFStreamStatusNotOpen: 71 case kCFStreamStatusOpening: 72 /* wait some more */ 73 break; 74 case kCFStreamStatusOpen: 75 case kCFStreamStatusReading: 76 case kCFStreamStatusWriting: 77 isOpen = true; 78 break; 79 default: 80 printf("***Unexpected status while opening %s\n", url); 81 goto errOut; 82 } 83 } while(!isOpen); 84 dprintf("...rd stream for %s open for business\n", url); 85 86 /* go */ 87 rtnData = CFDataCreateMutable(kCFAllocatorDefault, 0); 88 do { 89 irtn = CFReadStreamRead(rdStrm, rbuf, BUFSIZE); 90 if(irtn == 0) { 91 /* end of stream, normal exit */ 92 isOpen = false; 93 dprintf("...EOF on rd stream for %s\n", url); 94 } 95 else if(irtn < 0) { 96 /* FIXME - how to tell caller? */ 97 printf("***Error reading %s\n", url); 98 isOpen = false; 99 } 100 else { 101 dprintf(" ...read %d bytes from %s\n", (int)irtn, url); 102 CFDataAppendBytes(rtnData, rbuf, irtn); 103 } 104 } while(isOpen); 105errOut: 106 if(myReq) { 107 CFRelease(myReq); 108 } 109 if(rdStrm) { 110 CFRelease(rdStrm); 111 } 112 if(cfUrl) { 113 CFRelease(cfUrl); 114 } 115 if(rtnData) { 116 /* error on zero bytes read */ 117 if(CFDataGetLength(rtnData) == 0) { 118 printf("***No data read from %s\n", url); 119 CFRelease(rtnData); 120 rtnData = NULL; 121 } 122 } 123 return rtnData; 124} 125 126 127