X-Git-Url: https://git.saurik.com/apt-legacy.git/blobdiff_plain/910f26ec9bc823391d069d92b7943aeb653acd96..bfce9c8aff10d06b9660bd47401857111ad26cc4:/methods/http.cc.orig diff --git a/methods/http.cc.orig b/methods/http.cc.orig index b53b5da..3410a3e 100644 --- a/methods/http.cc.orig +++ b/methods/http.cc.orig @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -43,9 +44,11 @@ // Internet stuff #include +#include #include #include +#include #include "connect.h" #include "rfc2553emu.h" @@ -54,6 +57,50 @@ /*}}}*/ using namespace std; +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; @@ -1068,7 +1115,25 @@ 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; + +#if __ENVIRONMENT_ASPEN_VERSION_MIN_REQUIRED__ >= 10200 + struct hostent *he = gethostbyname(hs.c_str()); + if (he == NULL || he->h_addr_list[0] == NULL) { + _error->Error(hstrerror(h_errno)); + Fail(true); + free(url); + } + + uri.Host = inet_ntoa(* (struct in_addr *) he->h_addr_list[0]); +#endif + + 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); @@ -1089,32 +1154,51 @@ int HttpMethod::Loop() CFRelease(sr); } + 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")); + +#if __ENVIRONMENT_ASPEN_VERSION_MIN_REQUIRED__ >= 10200 + sr = CFStringCreateWithCString(kCFAllocatorDefault, hs.c_str(), se); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Host"), sr); + CFRelease(sr); +#endif + 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; } @@ -1122,7 +1206,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) { @@ -1131,7 +1235,7 @@ int HttpMethod::Loop() if (!CFStringGetCString(sr, cr, ln, se)) { Fail(); - goto done; + goto done_; } CFRelease(sr); @@ -1139,13 +1243,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")); @@ -1164,7 +1268,7 @@ int HttpMethod::Loop() if (!CFStringGetCString(sr, cr, ln, se)) { Fail(); - goto done; + goto done_; } CFRelease(sr); @@ -1172,7 +1276,7 @@ int HttpMethod::Loop() if (!StrToTime(cr, Res.LastModified)) { _error->Error(_("Unknown date format")); Fail(); - goto done; + goto done_; } } @@ -1220,7 +1324,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) @@ -1257,8 +1361,13 @@ int HttpMethod::Loop() } } + goto done; + done_: + CFRelease(hm); done: + CFReadStreamClose(rs); CFRelease(rs); + free(url); FailCounter = 0; } @@ -1272,6 +1381,22 @@ int main() 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; + + 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(); }