X-Git-Url: https://git.saurik.com/apt-legacy.git/blobdiff_plain/3d6f1076e59c8a808e88a7d90dfe7f587faf1c22..17d2e7dddaa70d7485933d57860da0faf3a1c59f:/methods/http.cc?ds=sidebyside diff --git a/methods/http.cc b/methods/http.cc index b3cea13..1a7e7c9 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -34,6 +34,7 @@ extern "C" { #include #include +#include #include #include #include @@ -47,6 +48,7 @@ extern "C" { // Internet stuff #include +#include #include #include @@ -59,7 +61,11 @@ extern "C" { /*}}}*/ using namespace std; -void CfrsError(CFReadStreamRef rs) { +CFStringRef Firmware_; +const char *Machine_; +const char *SerialNumber_; + +void CfrsError(const char *name, CFReadStreamRef rs) { CFStreamError se = CFReadStreamGetError(rs); if (se.domain == kCFStreamErrorDomainCustom) { @@ -68,7 +74,7 @@ void CfrsError(CFReadStreamRef rs) { } else if (se.domain == kCFStreamErrorDomainMacOSStatus) { _error->Error("MacOSStatus: %ld", se.error); } else if (se.domain == kCFStreamErrorDomainNetDB) { - _error->Error("NetDB: %s", gai_strerror(se.error)); + _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) { @@ -96,7 +102,7 @@ void CfrsError(CFReadStreamRef rs) { } else if (se.domain == kCFStreamErrorDomainSSL) { _error->Error("SSL: %ld", se.error); } else { - _error->Error("Domain #%d: %ld", se.domain, se.error); + _error->Error("Domain #%ld: %ld", se.domain, se.error); } } @@ -1114,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); @@ -1135,7 +1148,19 @@ 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); @@ -1143,28 +1168,28 @@ int HttpMethod::Loop() CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPProxy, dr); CFRelease(dr); - CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); + //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(rs); + CfrsError("Open", rs); Fail(true); goto done; } - CFIndex rd = CFReadStreamRead(rs, data, sizeof(data)); + rd = CFReadStreamRead(rs, data, sizeof(data)); if (rd == -1) { - CfrsError(rs); + CfrsError(uri.Host.c_str(), rs); Fail(true); goto done; } @@ -1172,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) { @@ -1270,7 +1315,7 @@ int HttpMethod::Loop() URIStart(Res); read: if (rd == -1) { - CfrsError(rs); + CfrsError("rd", rs); Fail(true); } else if (rd == 0) { if (Res.Size == 0) @@ -1313,6 +1358,7 @@ int HttpMethod::Loop() done: CFReadStreamClose(rs); CFRelease(rs); + free(url); FailCounter = 0; } @@ -1323,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 = (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(); }