X-Git-Url: https://git.saurik.com/apt-legacy.git/blobdiff_plain/910f26ec9bc823391d069d92b7943aeb653acd96..f23a31abf292fafa4e46772d15cf65e98042e6c9:/methods/http.cc?ds=sidebyside diff --git a/methods/http.cc b/methods/http.cc index 012d450..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,48 @@ 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); - CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); + CFDictionaryRef dr = SCDynamicStoreCopyProxies(NULL); + CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPProxy, dr); + CFRelease(dr); - URI uri = Queue->Uri; + //CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); + CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); 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)) { - _error->Error("Unable to open stream"); + CfrsError("Open", rs); Fail(true); goto done; } - CFIndex rd = CFReadStreamRead(rs, data, sizeof(data)); + rd = CFReadStreamRead(rs, data, sizeof(data)); if (rd == -1) { - _error->Error("Stream read failure"); + CfrsError(uri.Host.c_str(), rs); Fail(true); goto done; } @@ -1126,7 +1197,27 @@ int HttpMethod::Loop() Res.Filename = Queue->DestFile; hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader); - UInt32 sc = CFHTTPMessageGetResponseStatusCode(hm); + sc = CFHTTPMessageGetResponseStatusCode(hm); + + 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) { @@ -1135,7 +1226,7 @@ int HttpMethod::Loop() if (!CFStringGetCString(sr, cr, ln, se)) { Fail(); - goto done; + goto done_; } CFRelease(sr); @@ -1143,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")); @@ -1168,7 +1259,7 @@ int HttpMethod::Loop() if (!CFStringGetCString(sr, cr, ln, se)) { Fail(); - goto done; + goto done_; } CFRelease(sr); @@ -1176,7 +1267,7 @@ int HttpMethod::Loop() if (!StrToTime(cr, Res.LastModified)) { _error->Error(_("Unknown date format")); Fail(); - goto done; + goto done_; } } @@ -1224,7 +1315,7 @@ int HttpMethod::Loop() URIStart(Res); read: if (rd == -1) { - _error->Error("Stream read failure"); + CfrsError("rd", rs); Fail(true); } else if (rd == 0) { if (Res.Size == 0) @@ -1261,8 +1352,13 @@ int HttpMethod::Loop() } } + goto done; + done_: + CFRelease(hm); done: + CFReadStreamClose(rs); CFRelease(rs); + free(url); FailCounter = 0; } @@ -1273,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(); }