X-Git-Url: https://git.saurik.com/apt-legacy.git/blobdiff_plain/b7a89731f51f1a64423d67c80f8406cea49e1366..4db9327121d7ec181af05bd587175a77ce255e4e:/methods/http.cc diff --git a/methods/http.cc b/methods/http.cc index 578e4e2..aa6f516 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -34,6 +34,7 @@ extern "C" { #include #include +#include #include #include #include @@ -47,7 +48,9 @@ extern "C" { // Internet stuff #include +#include +#include #include #include #include @@ -59,7 +62,11 @@ extern "C" { /*}}}*/ using namespace std; -void CfrsError(CFReadStreamRef rs) { +CFStringRef Firmware_; +const char *Machine_; +CFStringRef UniqueID_; + +void CfrsError(const char *name, CFReadStreamRef rs) { CFStreamError se = CFReadStreamGetError(rs); if (se.domain == kCFStreamErrorDomainCustom) { @@ -68,7 +75,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) { @@ -1116,7 +1123,20 @@ int HttpMethod::Loop() char *url = strdup(Queue->Uri.c_str()); url: - CFStringRef sr = CFStringCreateWithCString(kCFAllocatorDefault, url, se); + URI uri = std::string(url); + std::string hs = uri.Host; + + std::string urs = uri; + + for (;;) { + size_t bad = urs.find_first_of("+"); + if (bad == std::string::npos) + break; + // XXX: generalize + urs = urs.substr(0, bad) + "%2b" + urs.substr(bad + 1); + } + + 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); @@ -1132,12 +1152,23 @@ int HttpMethod::Loop() CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Range"), sr); CFRelease(sr); } else if (Queue->LastModified != 0) { - sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(SBuf.st_mtime).c_str(), se); + sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(Queue->LastModified).c_str(), se); CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Modified-Since"), sr); CFRelease(sr); } + if (Firmware_ != NULL) + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Firmware"), Firmware_); + + sr = CFStringCreateWithCString(kCFAllocatorDefault, Machine_, se); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Machine"), sr); + CFRelease(sr); + + if (UniqueID_ != NULL) + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Unique-ID"), UniqueID_); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.98")); + CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, hm); CFRelease(hm); @@ -1148,8 +1179,6 @@ int HttpMethod::Loop() //CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); - URI uri = Queue->Uri; - FetchResult Res; CFIndex rd; UInt32 sc; @@ -1157,10 +1186,10 @@ int HttpMethod::Loop() 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; } @@ -1168,7 +1197,7 @@ int HttpMethod::Loop() rd = CFReadStreamRead(rs, data, sizeof(data)); if (rd == -1) { - CfrsError(rs); + CfrsError(uri.Host.c_str(), rs); Fail(true); goto done; } @@ -1178,7 +1207,7 @@ int HttpMethod::Loop() hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader); sc = CFHTTPMessageGetResponseStatusCode(hm); - if (sc == 302) { + if (sc == 301 || sc == 302) { sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Location")); if (sr == NULL) { Fail(); @@ -1294,7 +1323,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) @@ -1348,16 +1377,46 @@ 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 (void *lockdown = lockdown_connect()) { + UniqueID_ = lockdown_copy_value(lockdown, NULL, kLockdownUniqueDeviceIDKey); + lockdown_disconnect(lockdown); + } return Mth.Loop(); }