root / trunk / data / apt / cfnetwork.diff
| Revision 475, 14.3 kB (checked in by saurik, 2 months ago) |
|---|
-
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 30 34 #include <apt-pkg/error.h> 31 35 #include <apt-pkg/hashes.h> 32 36 37 #include <sys/sysctl.h> 33 38 #include <sys/stat.h> 34 39 #include <sys/time.h> 35 40 #include <utime.h> … … 43 48 44 49 // Internet stuff 45 50 #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> 46 57 47 58 #include "connect.h" 48 59 #include "rfc2553emu.h" … … 51 61 /*}}}*/ 52 62 using namespace std; 53 63 64 CFStringRef Firmware_; 65 const char *Machine_; 66 CFStringRef UniqueID_; 67 68 void 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 54 109 string HttpMethod::FailFile; 55 110 int HttpMethod::FailFd = -1; 56 111 time_t HttpMethod::FailTime = 0; … … 1062 1117 1063 1118 if (Queue == 0) 1064 1119 continue; 1065 1066 // Connect to the server1067 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 connection1074 then we pre-emptively shut down the pipeline and tear down1075 the connection. This will speed up HTTP/1.0 servers a tad1076 since we don't have to wait for the close sequence to1077 complete */1078 if (Server->Persistent == false)1079 Server->Close();1080 1081 // Reset the pipeline1082 if (Server->ServerFd == -1)1083 QueueBack = Queue;1084 1085 // Connnect to the host1086 if (Server->Open() == false)1087 {1088 Fail(true);1089 delete Server;1090 Server = 0;1091 continue;1092 }1093 1120 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); 1131 1180 1132 // Decide what to do.1133 1181 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 1134 1204 Res.Filename = Queue->DestFile; 1135 switch (DealWithHeaders(Res,Server))1136 {1137 // Ok, the file is Open1138 case 0:1139 {1140 URIStart(Res);1141 1205 1142 // Run the data 1143 bool Result = Server->RunData();1206 hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader); 1207 sc = CFHTTPMessageGetResponseStatusCode(hm); 1144 1208 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) { 1147 1328 if (Res.Size == 0) 1148 1329 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 1156 1331 struct utimbuf UBuf; 1157 1332 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); 1161 1336 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); 1177 1338 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); 1193 1341 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); 1199 1369 1200 // We need to flush the data, the header is like a 404 w/ error text1201 case 4:1202 {1203 Fail();1204 1205 // Send to content to dev/null1206 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 1218 1370 FailCounter = 0; 1219 1371 } 1220 1372 … … 1224 1386 setlocale(LC_ALL, ""); 1225 1387 1226 1388 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 } 1227 1417 1228 1418 return Mth.Loop(); 1229 1419 } -
methods/makefile
diff -ru apt-0.6.46.4.1/methods/makefile apt-0.6.46.4.1+iPhone/methods/makefile
old new 47 47 48 48 # The http method 49 49 PROGRAM=http 50 SLIBS = -lapt-pkg $(SOCKETLIBS) 50 SLIBS = -lapt-pkg $(SOCKETLIBS) -framework CoreFoundation -framework CFNetwork -framework SystemConfiguration -framework IOKit -llockdown 51 51 LIB_MAKES = apt-pkg/makefile 52 52 SOURCE = http.cc rfc2553emu.cc connect.cc 53 53 include $(PROGRAM_H)
Note: See TracBrowser
for help on using the browser.
