root / trunk / data / apt / cfnetwork.diff

Revision 475, 14.3 kB (checked in by saurik, 2 months ago)

Finalized 2.1 Cydia.

  • methods/http.cc

    diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc
    old new  
    3034#include <apt-pkg/error.h> 
    3135#include <apt-pkg/hashes.h> 
    3236 
     37#include <sys/sysctl.h> 
    3338#include <sys/stat.h> 
    3439#include <sys/time.h> 
    3540#include <utime.h> 
     
    4348 
    4449// Internet stuff 
    4550#include <netdb.h> 
     51#include <arpa/inet.h> 
     52 
     53#include <lockdown.h> 
     54#include <CoreFoundation/CoreFoundation.h> 
     55#include <CoreServices/CoreServices.h> 
     56#include <SystemConfiguration/SystemConfiguration.h> 
    4657 
    4758#include "connect.h" 
    4859#include "rfc2553emu.h" 
     
    5161                                                                        /*}}}*/ 
    5262using namespace std; 
    5363 
     64CFStringRef Firmware_; 
     65const char *Machine_; 
     66CFStringRef UniqueID_; 
     67 
     68void CfrsError(const char *name, CFReadStreamRef rs) { 
     69    CFStreamError se = CFReadStreamGetError(rs); 
     70 
     71    if (se.domain == kCFStreamErrorDomainCustom) { 
     72    } else if (se.domain == kCFStreamErrorDomainPOSIX) { 
     73        _error->Error("POSIX: %s", strerror(se.error)); 
     74    } else if (se.domain == kCFStreamErrorDomainMacOSStatus) { 
     75        _error->Error("MacOSStatus: %ld", se.error); 
     76    } else if (se.domain == kCFStreamErrorDomainNetDB) { 
     77        _error->Error("NetDB: %s %s", name, gai_strerror(se.error)); 
     78    } else if (se.domain == kCFStreamErrorDomainMach) { 
     79        _error->Error("Mach: %ld", se.error); 
     80    } else if (se.domain == kCFStreamErrorDomainHTTP) { 
     81        switch (se.error) { 
     82            case kCFStreamErrorHTTPParseFailure: 
     83                _error->Error("Parse failure"); 
     84            break; 
     85 
     86            case kCFStreamErrorHTTPRedirectionLoop: 
     87                _error->Error("Redirection loop"); 
     88            break; 
     89 
     90            case kCFStreamErrorHTTPBadURL: 
     91                _error->Error("Bad URL"); 
     92            break; 
     93 
     94            default: 
     95                _error->Error("Unknown HTTP error: %ld", se.error); 
     96            break; 
     97        } 
     98    } else if (se.domain == kCFStreamErrorDomainSOCKS) { 
     99        _error->Error("SOCKS: %ld", se.error); 
     100    } else if (se.domain == kCFStreamErrorDomainSystemConfiguration) { 
     101        _error->Error("SystemConfiguration: %ld", se.error); 
     102    } else if (se.domain == kCFStreamErrorDomainSSL) { 
     103        _error->Error("SSL: %ld", se.error); 
     104    } else { 
     105        _error->Error("Domain #%ld: %ld", se.domain, se.error); 
     106    } 
     107} 
     108 
    54109string HttpMethod::FailFile; 
    55110int HttpMethod::FailFd = -1; 
    56111time_t HttpMethod::FailTime = 0; 
     
    10621117 
    10631118      if (Queue == 0) 
    10641119         continue; 
    1065        
    1066       // Connect to the server 
    1067       if (Server == 0 || Server->Comp(Queue->Uri) == false) 
    1068       { 
    1069          delete Server; 
    1070          Server = new ServerState(Queue->Uri,this); 
    1071       } 
    1072        
    1073       /* If the server has explicitly said this is the last connection 
    1074          then we pre-emptively shut down the pipeline and tear down  
    1075          the connection. This will speed up HTTP/1.0 servers a tad 
    1076          since we don't have to wait for the close sequence to 
    1077          complete */ 
    1078       if (Server->Persistent == false) 
    1079          Server->Close(); 
    1080        
    1081       // Reset the pipeline 
    1082       if (Server->ServerFd == -1) 
    1083          QueueBack = Queue;       
    1084           
    1085       // Connnect to the host 
    1086       if (Server->Open() == false) 
    1087       { 
    1088          Fail(true); 
    1089          delete Server; 
    1090          Server = 0; 
    1091          continue; 
    1092       } 
    10931120 
    1094       // Fill the pipeline. 
    1095       Fetch(0); 
    1096        
    1097       // Fetch the next URL header data from the server. 
    1098       switch (Server->RunHeaders()) 
    1099       { 
    1100          case 0: 
    1101          break; 
    1102           
    1103          // The header data is bad 
    1104          case 2: 
    1105          { 
    1106             _error->Error(_("Bad header data")); 
    1107             Fail(true); 
    1108             RotateDNS(); 
    1109             continue; 
    1110          } 
    1111           
    1112          // The server closed a connection during the header get.. 
    1113          default: 
    1114          case 1: 
    1115          { 
    1116             FailCounter++; 
    1117             _error->Discard(); 
    1118             Server->Close(); 
    1119             Server->Pipeline = false; 
    1120              
    1121             if (FailCounter >= 2) 
    1122             { 
    1123                Fail(_("Connection failed"),true); 
    1124                FailCounter = 0; 
    1125             } 
    1126              
    1127             RotateDNS(); 
    1128             continue; 
    1129          } 
    1130       }; 
     1121      CFStringEncoding se = kCFStringEncodingUTF8; 
     1122 
     1123      char *url = strdup(Queue->Uri.c_str()); 
     1124    url: 
     1125      URI uri = std::string(url); 
     1126      std::string hs = uri.Host; 
     1127 
     1128      std::string urs = uri; 
     1129 
     1130      for (;;) { 
     1131         size_t bad = urs.find_first_of("+"); 
     1132         if (bad == std::string::npos) 
     1133            break; 
     1134         // XXX: generalize 
     1135         urs = urs.substr(0, bad) + "%2b" + urs.substr(bad + 1); 
     1136      } 
     1137 
     1138      CFStringRef sr = CFStringCreateWithCString(kCFAllocatorDefault, urs.c_str(), se); 
     1139      CFURLRef ur = CFURLCreateWithString(kCFAllocatorDefault, sr, NULL); 
     1140      CFRelease(sr); 
     1141      CFHTTPMessageRef hm = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), ur, kCFHTTPVersion1_1); 
     1142      CFRelease(ur); 
     1143 
     1144      struct stat SBuf; 
     1145      if (stat(Queue->DestFile.c_str(), &SBuf) >= 0 && SBuf.st_size > 0) { 
     1146         sr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("bytes=%li-"), (long) SBuf.st_size - 1); 
     1147         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Range"), sr); 
     1148         CFRelease(sr); 
     1149 
     1150         sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(SBuf.st_mtime).c_str(), se); 
     1151         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Range"), sr); 
     1152         CFRelease(sr); 
     1153      } else if (Queue->LastModified != 0) { 
     1154         sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(Queue->LastModified).c_str(), se); 
     1155         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Modified-Since"), sr); 
     1156         CFRelease(sr); 
     1157      } 
     1158 
     1159      if (Firmware_ != NULL) 
     1160         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Firmware"), Firmware_); 
     1161 
     1162      sr = CFStringCreateWithCString(kCFAllocatorDefault, Machine_, se); 
     1163      CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Machine"), sr); 
     1164      CFRelease(sr); 
     1165 
     1166      if (UniqueID_ != NULL) 
     1167         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Unique-ID"), UniqueID_); 
     1168 
     1169      CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.98")); 
     1170 
     1171      CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, hm); 
     1172      CFRelease(hm); 
     1173 
     1174      CFDictionaryRef dr = SCDynamicStoreCopyProxies(NULL); 
     1175      CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPProxy, dr); 
     1176      CFRelease(dr); 
     1177 
     1178      //CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); 
     1179      CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); 
    11311180 
    1132       // Decide what to do. 
    11331181      FetchResult Res; 
     1182      CFIndex rd; 
     1183      UInt32 sc; 
     1184 
     1185      uint8_t data[10240]; 
     1186      size_t offset = 0; 
     1187 
     1188      Status("Connecting to %s", hs.c_str()); 
     1189 
     1190      if (!CFReadStreamOpen(rs)) { 
     1191         CfrsError("Open", rs); 
     1192         Fail(true); 
     1193         goto done; 
     1194      } 
     1195 
     1196      rd = CFReadStreamRead(rs, data, sizeof(data)); 
     1197 
     1198      if (rd == -1) { 
     1199         CfrsError(uri.Host.c_str(), rs); 
     1200         Fail(true); 
     1201         goto done; 
     1202      } 
     1203 
    11341204      Res.Filename = Queue->DestFile; 
    1135       switch (DealWithHeaders(Res,Server)) 
    1136       { 
    1137          // Ok, the file is Open 
    1138          case 0: 
    1139          { 
    1140             URIStart(Res); 
    11411205 
    1142             // Run the data 
    1143             bool Result =  Server->RunData(); 
     1206      hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader); 
     1207      sc = CFHTTPMessageGetResponseStatusCode(hm); 
    11441208 
    1145             /* If the server is sending back sizeless responses then fill in 
    1146                the size now */ 
     1209      if (sc == 301 || sc == 302) { 
     1210         sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Location")); 
     1211         if (sr == NULL) { 
     1212            Fail(); 
     1213            goto done_; 
     1214         } else { 
     1215            size_t ln = CFStringGetLength(sr) + 1; 
     1216            free(url); 
     1217            url = static_cast<char *>(malloc(ln)); 
     1218 
     1219            if (!CFStringGetCString(sr, url, ln, se)) { 
     1220               Fail(); 
     1221               goto done_; 
     1222            } 
     1223 
     1224            CFRelease(sr); 
     1225            goto url; 
     1226         } 
     1227      } 
     1228 
     1229      sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Range")); 
     1230      if (sr != NULL) { 
     1231         size_t ln = CFStringGetLength(sr) + 1; 
     1232         char cr[ln]; 
     1233 
     1234         if (!CFStringGetCString(sr, cr, ln, se)) { 
     1235            Fail(); 
     1236            goto done_; 
     1237         } 
     1238 
     1239         CFRelease(sr); 
     1240 
     1241         if (sscanf(cr, "bytes %lu-%*u/%lu", &offset, &Res.Size) != 2) { 
     1242            _error->Error(_("The HTTP server sent an invalid Content-Range header")); 
     1243            Fail(); 
     1244            goto done_; 
     1245         } 
     1246 
     1247         if (offset > Res.Size) { 
     1248            _error->Error(_("This HTTP server has broken range support")); 
     1249            Fail(); 
     1250            goto done_; 
     1251         } 
     1252      } else { 
     1253         sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Length")); 
     1254         if (sr != NULL) { 
     1255            Res.Size = CFStringGetIntValue(sr); 
     1256            CFRelease(sr); 
     1257         } 
     1258      } 
     1259 
     1260      time(&Res.LastModified); 
     1261 
     1262      sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Last-Modified")); 
     1263      if (sr != NULL) { 
     1264         size_t ln = CFStringGetLength(sr) + 1; 
     1265         char cr[ln]; 
     1266 
     1267         if (!CFStringGetCString(sr, cr, ln, se)) { 
     1268            Fail(); 
     1269            goto done_; 
     1270         } 
     1271 
     1272         CFRelease(sr); 
     1273 
     1274         if (!StrToTime(cr, Res.LastModified)) { 
     1275            _error->Error(_("Unknown date format")); 
     1276            Fail(); 
     1277            goto done_; 
     1278         } 
     1279      } 
     1280 
     1281      CFRelease(hm); 
     1282 
     1283      if (sc == 304) { 
     1284         unlink(Queue->DestFile.c_str()); 
     1285         Res.IMSHit = true; 
     1286         Res.LastModified = Queue->LastModified; 
     1287         URIDone(Res); 
     1288      } else if (sc < 200 || sc >= 300) 
     1289         Fail(); 
     1290      else { 
     1291         Hashes hash; 
     1292 
     1293         File = new FileFd(Queue->DestFile, FileFd::WriteAny); 
     1294         if (_error->PendingError() == true) { 
     1295            delete File; 
     1296            File = NULL; 
     1297            Fail(); 
     1298            goto done; 
     1299         } 
     1300 
     1301         FailFile = Queue->DestFile; 
     1302         FailFile.c_str();   // Make sure we dont do a malloc in the signal handler 
     1303         FailFd = File->Fd(); 
     1304         FailTime = Res.LastModified; 
     1305 
     1306         Res.ResumePoint = offset; 
     1307         ftruncate(File->Fd(), offset); 
     1308 
     1309         if (offset != 0) { 
     1310            lseek(File->Fd(), 0, SEEK_SET); 
     1311            if (!hash.AddFD(File->Fd(), offset)) { 
     1312               _error->Errno("read", _("Problem hashing file")); 
     1313               delete File; 
     1314               File = NULL; 
     1315               Fail(); 
     1316               goto done; 
     1317            } 
     1318         } 
     1319 
     1320         lseek(File->Fd(), 0, SEEK_END); 
     1321 
     1322         URIStart(Res); 
     1323 
     1324         read: if (rd == -1) { 
     1325            CfrsError("rd", rs); 
     1326            Fail(true); 
     1327         } else if (rd == 0) { 
    11471328            if (Res.Size == 0) 
    11481329               Res.Size = File->Size(); 
    1149              
    1150             // Close the file, destroy the FD object and timestamp it 
    1151             FailFd = -1; 
    1152             delete File; 
    1153             File = 0; 
    1154              
    1155             // Timestamp 
     1330 
    11561331            struct utimbuf UBuf; 
    11571332            time(&UBuf.actime); 
    1158             UBuf.actime = Server->Date; 
    1159             UBuf.modtime = Server->Date; 
    1160             utime(Queue->DestFile.c_str(),&UBuf); 
     1333            UBuf.actime = Res.LastModified; 
     1334            UBuf.modtime = Res.LastModified; 
     1335            utime(Queue->DestFile.c_str(), &UBuf); 
    11611336 
    1162             // Send status to APT 
    1163             if (Result == true) 
    1164             { 
    1165                Res.TakeHashes(*Server->In.Hash); 
    1166                URIDone(Res); 
    1167             } 
    1168             else 
    1169                Fail(true); 
    1170              
    1171             break; 
    1172          } 
    1173           
    1174          // IMS hit 
    1175          case 1: 
    1176          { 
     1337            Res.TakeHashes(hash); 
    11771338            URIDone(Res); 
    1178             break; 
    1179          } 
    1180           
    1181          // Hard server error, not found or something 
    1182          case 3: 
    1183          { 
    1184             Fail(); 
    1185             break; 
    1186          } 
    1187            
    1188          // Hard internal error, kill the connection and fail 
    1189          case 5: 
    1190          { 
    1191             delete File; 
    1192             File = 0; 
     1339         } else { 
     1340            hash.Add(data, rd); 
    11931341 
    1194             Fail(); 
    1195             RotateDNS(); 
    1196             Server->Close(); 
    1197             break; 
    1198          } 
     1342            uint8_t *dt = data; 
     1343            while (rd != 0) { 
     1344               int sz = write(File->Fd(), dt, rd); 
     1345 
     1346               if (sz == -1) { 
     1347                   delete File; 
     1348                   File = NULL; 
     1349                   Fail(); 
     1350                   goto done; 
     1351               } 
     1352 
     1353               dt += sz; 
     1354               rd -= sz; 
     1355            } 
     1356 
     1357            rd = CFReadStreamRead(rs, data, sizeof(data)); 
     1358            goto read; 
     1359         } 
     1360      } 
     1361 
     1362     goto done; 
     1363    done_: 
     1364      CFRelease(hm); 
     1365    done: 
     1366      CFReadStreamClose(rs); 
     1367      CFRelease(rs); 
     1368      free(url); 
    11991369 
    1200          // We need to flush the data, the header is like a 404 w/ error text 
    1201          case 4: 
    1202          { 
    1203             Fail(); 
    1204              
    1205             // Send to content to dev/null 
    1206             File = new FileFd("/dev/null",FileFd::WriteExists); 
    1207             Server->RunData(); 
    1208             delete File; 
    1209             File = 0; 
    1210             break; 
    1211          } 
    1212           
    1213          default: 
    1214          Fail(_("Internal error")); 
    1215          break; 
    1216       } 
    1217        
    12181370      FailCounter = 0; 
    12191371   } 
    12201372    
     
    12241386   setlocale(LC_ALL, ""); 
    12251387 
    12261388   HttpMethod Mth; 
     1389 
     1390    size_t size; 
     1391    sysctlbyname("hw.machine", NULL, &size, NULL, 0); 
     1392    char *machine = new char[size]; 
     1393    sysctlbyname("hw.machine", machine, &size, NULL, 0); 
     1394    Machine_ = machine; 
     1395 
     1396    const char *path = "/System/Library/CoreServices/SystemVersion.plist"; 
     1397    CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (uint8_t *) path, strlen(path), false); 
     1398 
     1399    CFPropertyListRef plist; { 
     1400        CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); 
     1401        CFReadStreamOpen(stream); 
     1402        plist = CFPropertyListCreateFromStream(kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, NULL); 
     1403        CFReadStreamClose(stream); 
     1404    } 
     1405 
     1406    CFRelease(url); 
     1407 
     1408    if (plist != NULL) { 
     1409        Firmware_ = (CFStringRef) CFRetain(CFDictionaryGetValue((CFDictionaryRef) plist, CFSTR("ProductVersion"))); 
     1410        CFRelease(plist); 
     1411    } 
     1412 
     1413    if (void *lockdown = lockdown_connect()) { 
     1414        UniqueID_ = lockdown_copy_value(lockdown, NULL, kLockdownUniqueDeviceIDKey); 
     1415        lockdown_disconnect(lockdown); 
     1416    } 
    12271417    
    12281418   return Mth.Loop(); 
    12291419} 
  • methods/makefile

    diff -ru apt-0.6.46.4.1/methods/makefile apt-0.6.46.4.1+iPhone/methods/makefile
    old new  
    4747 
    4848# The http method 
    4949PROGRAM=http 
    50 SLIBS = -lapt-pkg $(SOCKETLIBS) 
     50SLIBS = -lapt-pkg $(SOCKETLIBS) -framework CoreFoundation -framework CFNetwork -framework SystemConfiguration -framework IOKit -llockdown 
    5151LIB_MAKES = apt-pkg/makefile 
    5252SOURCE = http.cc rfc2553emu.cc connect.cc 
    5353include $(PROGRAM_H) 
Note: See TracBrowser for help on using the browser.