X-Git-Url: https://git.saurik.com/apt-legacy.git/blobdiff_plain/253ba34a3c06ebbc2523ae67009d9fd4aff0fff1..17d2e7dddaa70d7485933d57860da0faf3a1c59f:/methods/http.cc diff --git a/methods/http.cc b/methods/http.cc index 7e5bbc9..1a7e7c9 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -34,6 +34,7 @@ extern "C" { #include #include +#include #include #include #include @@ -47,9 +48,11 @@ extern "C" { // Internet stuff #include +#include #include #include +#include #include "connect.h" #include "rfc2553emu.h" @@ -58,6 +61,51 @@ extern "C" { /*}}}*/ using namespace std; +CFStringRef Firmware_; +const char *Machine_; +const char *SerialNumber_; + +void CfrsError(const char *name, CFReadStreamRef rs) { + CFStreamError se = CFReadStreamGetError(rs); + + if (se.domain == kCFStreamErrorDomainCustom) { + } else if (se.domain == kCFStreamErrorDomainPOSIX) { + _error->Error("POSIX: %s", strerror(se.error)); + } else if (se.domain == kCFStreamErrorDomainMacOSStatus) { + _error->Error("MacOSStatus: %ld", se.error); + } else if (se.domain == kCFStreamErrorDomainNetDB) { + _error->Error("NetDB: %s %s", name, gai_strerror(se.error)); + } else if (se.domain == kCFStreamErrorDomainMach) { + _error->Error("Mach: %ld", se.error); + } else if (se.domain == kCFStreamErrorDomainHTTP) { + switch (se.error) { + case kCFStreamErrorHTTPParseFailure: + _error->Error("Parse failure"); + break; + + case kCFStreamErrorHTTPRedirectionLoop: + _error->Error("Redirection loop"); + break; + + case kCFStreamErrorHTTPBadURL: + _error->Error("Bad URL"); + break; + + default: + _error->Error("Unknown HTTP error: %ld", se.error); + break; + } + } else if (se.domain == kCFStreamErrorDomainSOCKS) { + _error->Error("SOCKS: %ld", se.error); + } else if (se.domain == kCFStreamErrorDomainSystemConfiguration) { + _error->Error("SystemConfiguration: %ld", se.error); + } else if (se.domain == kCFStreamErrorDomainSSL) { + _error->Error("SSL: %ld", se.error); + } else { + _error->Error("Domain #%ld: %ld", se.domain, se.error); + } +} + string HttpMethod::FailFile; int HttpMethod::FailFd = -1; time_t HttpMethod::FailTime = 0; @@ -1072,7 +1120,14 @@ int HttpMethod::Loop() CFStringEncoding se = kCFStringEncodingUTF8; - CFStringRef sr = CFStringCreateWithCString(kCFAllocatorDefault, Queue->Uri.c_str(), se); + char *url = strdup(Queue->Uri.c_str()); + url: + URI uri = std::string(url); + std::string hs = uri.Host; + + std::string urs = uri; + + CFStringRef sr = CFStringCreateWithCString(kCFAllocatorDefault, urs.c_str(), se); CFURLRef ur = CFURLCreateWithString(kCFAllocatorDefault, sr, NULL); CFRelease(sr); CFHTTPMessageRef hm = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), ur, kCFHTTPVersion1_1); @@ -1093,32 +1148,76 @@ int HttpMethod::Loop() CFRelease(sr); } + if (Firmware_ != NULL) + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Firmware"), Firmware_); + + sr = CFStringCreateWithCString(kCFAllocatorDefault, Machine_, se); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Machine"), sr); + CFRelease(sr); + + sr = CFStringCreateWithCString(kCFAllocatorDefault, SerialNumber_, se); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Serial-Number"), sr); + CFRelease(sr); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.98")); + CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, hm); CFRelease(hm); - CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); + CFDictionaryRef dr = SCDynamicStoreCopyProxies(NULL); + CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPProxy, dr); + CFRelease(dr); + + //CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); - URI uri = Queue->Uri; + FetchResult Res; + CFIndex rd; + UInt32 sc; + + uint8_t data[10240]; + size_t offset = 0; - Status("Connecting to %s", uri.Host.c_str()); + Status("Connecting to %s", hs.c_str()); if (!CFReadStreamOpen(rs)) { + CfrsError("Open", rs); Fail(true); - continue; + goto done; } - uint8_t data[10240]; - CFIndex rd = CFReadStreamRead(rs, data, sizeof(data)); + rd = CFReadStreamRead(rs, data, sizeof(data)); + + if (rd == -1) { + CfrsError(uri.Host.c_str(), rs); + Fail(true); + goto done; + } - FetchResult Res; Res.Filename = Queue->DestFile; hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader); - UInt32 sc = CFHTTPMessageGetResponseStatusCode(hm); + sc = CFHTTPMessageGetResponseStatusCode(hm); - size_t offset = 0; + if (sc == 301 || sc == 302) { + sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Location")); + if (sr == NULL) { + Fail(); + goto done_; + } else { + size_t ln = CFStringGetLength(sr) + 1; + free(url); + url = static_cast(malloc(ln)); + + if (!CFStringGetCString(sr, url, ln, se)) { + Fail(); + goto done_; + } + + CFRelease(sr); + goto url; + } + } sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Range")); if (sr != NULL) { @@ -1127,7 +1226,7 @@ int HttpMethod::Loop() if (!CFStringGetCString(sr, cr, ln, se)) { Fail(); - goto done; + goto done_; } CFRelease(sr); @@ -1135,13 +1234,13 @@ int HttpMethod::Loop() if (sscanf(cr, "bytes %lu-%*u/%lu", &offset, &Res.Size) != 2) { _error->Error(_("The HTTP server sent an invalid Content-Range header")); Fail(); - goto done; + goto done_; } if (offset > Res.Size) { _error->Error(_("This HTTP server has broken range support")); Fail(); - goto done; + goto done_; } } else { sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Length")); @@ -1160,7 +1259,7 @@ int HttpMethod::Loop() if (!CFStringGetCString(sr, cr, ln, se)) { Fail(); - goto done; + goto done_; } CFRelease(sr); @@ -1168,7 +1267,7 @@ int HttpMethod::Loop() if (!StrToTime(cr, Res.LastModified)) { _error->Error(_("Unknown date format")); Fail(); - goto done; + goto done_; } } @@ -1215,9 +1314,10 @@ int HttpMethod::Loop() URIStart(Res); - read: if (rd == -1) + read: if (rd == -1) { + CfrsError("rd", rs); Fail(true); - else if (rd == 0) { + } else if (rd == 0) { if (Res.Size == 0) Res.Size = File->Size(); @@ -1252,8 +1352,13 @@ int HttpMethod::Loop() } } + goto done; + done_: + CFRelease(hm); done: + CFReadStreamClose(rs); CFRelease(rs); + free(url); FailCounter = 0; } @@ -1264,16 +1369,51 @@ int HttpMethod::Loop() int main() { +#if !defined(__ENVIRONMENT_ASPEN_VERSION_MIN_REQUIRED__) || __ENVIRONMENT_ASPEN_VERSION_MIN_REQUIRED__ < 10200 struct nlist nl[2]; memset(nl, 0, sizeof(nl)); - nl[0].n_un.n_name = "_useMDNSResponder"; + nl[0].n_un.n_name = (char *) "_useMDNSResponder"; nlist("/usr/lib/libc.dylib", nl); if (nl[0].n_type != N_UNDF) *(int *) nl[0].n_value = 0; +#endif setlocale(LC_ALL, ""); HttpMethod Mth; + + size_t size; + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + char *machine = new char[size]; + sysctlbyname("hw.machine", machine, &size, NULL, 0); + Machine_ = machine; + + const char *path = "/System/Library/CoreServices/SystemVersion.plist"; + CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (uint8_t *) path, strlen(path), false); + + CFPropertyListRef plist; { + CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); + CFReadStreamOpen(stream); + plist = CFPropertyListCreateFromStream(kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, NULL); + CFReadStreamClose(stream); + } + + CFRelease(url); + + if (plist != NULL) { + Firmware_ = (CFStringRef) CFRetain(CFDictionaryGetValue((CFDictionaryRef) plist, CFSTR("ProductVersion"))); + CFRelease(plist); + } + + if (CFMutableDictionaryRef dict = IOServiceMatching("IOPlatformExpertDevice")) + if (io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, dict)) { + if (CFTypeRef serial = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0)) { + SerialNumber_ = strdup(CFStringGetCStringPtr((CFStringRef) serial, CFStringGetSystemEncoding())); + CFRelease(serial); + } + + IOObjectRelease(service); + } return Mth.Loop(); }