From a0ae11d92d5174c55556b471b5037337f1e8cc9c Mon Sep 17 00:00:00 2001 From: Jay Freeman Date: Wed, 21 Jan 2009 11:17:34 +0000 Subject: Fixed Dl-Limit (long standing APT bug that they won't acknowledge), specified error messages for HTTP status codes, and added support for download timeouts. git-svn-id: http://svn.telesphoreo.org/trunk@534 514c082c-b64e-11dc-b46d-3d985efe055d --- data/apt/cfnetwork.diff | 144 +++++++++++++++++++++++++++++++++++++++++++----- data/apt/dllimit.diff | 12 ++++ data/apt/parallel.diff | 33 +++++++++++ 3 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 data/apt/dllimit.diff create mode 100644 data/apt/parallel.diff diff --git a/data/apt/cfnetwork.diff b/data/apt/cfnetwork.diff index 03d5edcbd..525a559d5 100644 --- a/data/apt/cfnetwork.diff +++ b/data/apt/cfnetwork.diff @@ -1,7 +1,7 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc --- apt-0.6.46.4.1/methods/http.cc 2006-12-04 14:37:36.000000000 +0000 -+++ apt-0.6.46.4.1+iPhone/methods/http.cc 2008-05-11 06:33:29.000000000 +0000 -@@ -30,6 +34,7 @@ ++++ apt-0.6.46.4.1+iPhone/methods/http.cc 2009-01-21 10:11:37.000000000 +0000 +@@ -30,6 +36,7 @@ #include #include @@ -9,7 +9,11 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc #include #include #include -@@ -43,6 +48,12 @@ +@@ -40,9 +47,16 @@ + #include + #include + #include ++#include // Internet stuff #include @@ -22,7 +26,7 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc #include "connect.h" #include "rfc2553emu.h" -@@ -51,6 +61,51 @@ +@@ -51,6 +65,51 @@ /*}}}*/ using namespace std; @@ -74,7 +78,68 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc string HttpMethod::FailFile; int HttpMethod::FailFd = -1; time_t HttpMethod::FailTime = 0; -@@ -1062,159 +1117,261 @@ +@@ -630,6 +689,51 @@ + } + /*}}}*/ + ++static const CFOptionFlags kNetworkEvents = ++ kCFStreamEventOpenCompleted | ++ kCFStreamEventHasBytesAvailable | ++ kCFStreamEventEndEncountered | ++ kCFStreamEventErrorOccurred | ++0; ++ ++static void CFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType event, void *arg) { ++ switch (event) { ++ case kCFStreamEventOpenCompleted: ++ break; ++ ++ case kCFStreamEventHasBytesAvailable: ++ case kCFStreamEventEndEncountered: ++ *reinterpret_cast(arg) = 1; ++ CFRunLoopStop(CFRunLoopGetCurrent()); ++ break; ++ ++ case kCFStreamEventErrorOccurred: ++ *reinterpret_cast(arg) = -1; ++ CFRunLoopStop(CFRunLoopGetCurrent()); ++ break; ++ } ++} ++ ++/* http://lists.apple.com/archives/Macnetworkprog/2006/Apr/msg00014.html */ ++int CFReadStreamOpen(CFReadStreamRef stream, double timeout) { ++ CFStreamClientContext context; ++ int value(0); ++ ++ memset(&context, 0, sizeof(context)); ++ context.info = &value; ++ ++ if (CFReadStreamSetClient(stream, kNetworkEvents, CFReadStreamCallback, &context)) { ++ CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); ++ if (CFReadStreamOpen(stream)) ++ CFRunLoopRunInMode(kCFRunLoopDefaultMode, timeout, false); ++ else ++ value = -1; ++ CFReadStreamSetClient(stream, kCFStreamEventNone, NULL, NULL); ++ } ++ ++ return value; ++} ++ + // HttpMethod::SendReq - Send the HTTP request /*{{{*/ + // --------------------------------------------------------------------- + /* This places the http request in the outbound buffer */ +@@ -1043,6 +1147,8 @@ + signal(SIGINT,SigTerm); + + Server = 0; ++ ++ std::set cached; + + int FailCounter = 0; + while (1) +@@ -1062,159 +1168,314 @@ if (Queue == 0) continue; @@ -151,6 +216,14 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc + URI uri = std::string(url); + std::string hs = uri.Host; + ++ if (cached.find(hs) != cached.end()) { ++ _error->Error("Cached Failure"); ++ Fail(true); ++ free(url); ++ FailCounter = 0; ++ continue; ++ } ++ + std::string urs = uri; + + for (;;) { @@ -197,11 +270,25 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc + if (UniqueID_ != NULL) + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Unique-ID"), UniqueID_); + -+ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.484")); ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.534")); + + CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, hm); + CFRelease(hm); + ++#define _kCFStreamPropertyReadTimeout CFSTR("_kCFStreamPropertyReadTimeout") ++#define _kCFStreamPropertyWriteTimeout CFSTR("_kCFStreamPropertyWriteTimeout") ++#define _kCFStreamPropertySocketImmediateBufferTimeOut CFSTR("_kCFStreamPropertySocketImmediateBufferTimeOut") ++ ++ /*SInt32 to(TimeOut); ++ CFNumberRef nm(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &to));*/ ++ double to(TimeOut); ++ CFNumberRef nm(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &to)); ++ ++ CFReadStreamSetProperty(rs, _kCFStreamPropertyReadTimeout, nm); ++ CFReadStreamSetProperty(rs, _kCFStreamPropertyWriteTimeout, nm); ++ CFReadStreamSetProperty(rs, _kCFStreamPropertySocketImmediateBufferTimeOut, nm); ++ CFRelease(nm); ++ + CFDictionaryRef dr = SCDynamicStoreCopyProxies(NULL); + CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPProxy, dr); + CFRelease(dr); @@ -219,9 +306,22 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc + + Status("Connecting to %s", hs.c_str()); + -+ if (!CFReadStreamOpen(rs)) { -+ CfrsError("Open", rs); -+ Fail(true); ++ switch (CFReadStreamOpen(rs, to)) { ++ case -1: ++ CfrsError("Open", rs); ++ goto fail; ++ ++ case 0: ++ _error->Error("Host Unreachable"); ++ cached.insert(hs); ++ goto fail; ++ ++ case 1: ++ /* success */ ++ break; ++ ++ fail: ++ Fail(true); + goto done; + } + @@ -229,6 +329,7 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc + + if (rd == -1) { + CfrsError(uri.Host.c_str(), rs); ++ cached.insert(hs); + Fail(true); + goto done; + } @@ -320,6 +421,25 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc + } + } + ++ if (sc < 200 || sc >= 300 && sc != 304) { ++ sr = CFHTTPMessageCopyResponseStatusLine(hm); ++ ++ size_t ln = CFStringGetLength(sr) + 1; ++ char cr[ln]; ++ ++ if (!CFStringGetCString(sr, cr, ln, se)) { ++ Fail(); ++ goto done; ++ } ++ ++ CFRelease(sr); ++ ++ _error->Error("%s", cr); ++ ++ Fail(); ++ goto done_; ++ } ++ + CFRelease(hm); + + if (sc == 304) { @@ -327,9 +447,7 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc + Res.IMSHit = true; + Res.LastModified = Queue->LastModified; + URIDone(Res); -+ } else if (sc < 200 || sc >= 300) -+ Fail(); -+ else { ++ } else { + Hashes hash; + + File = new FileFd(Queue->DestFile, FileFd::WriteAny); @@ -475,7 +593,7 @@ diff -ru apt-0.6.46.4.1/methods/http.cc apt-0.6.46.4.1+iPhone/methods/http.cc FailCounter = 0; } -@@ -1224,6 +1386,34 @@ +@@ -1224,6 +1484,34 @@ setlocale(LC_ALL, ""); HttpMethod Mth; diff --git a/data/apt/dllimit.diff b/data/apt/dllimit.diff new file mode 100644 index 000000000..367c73006 --- /dev/null +++ b/data/apt/dllimit.diff @@ -0,0 +1,12 @@ +diff -ru apt-0.6.46.4.1/apt-pkg/acquire.cc apt-0.6.46.4.1+iPhone/apt-pkg/acquire.cc +--- apt-0.6.46.4.1/apt-pkg/acquire.cc 2006-12-04 14:37:34.000000000 +0000 ++++ apt-0.6.46.4.1+iPhone/apt-pkg/acquire.cc 2009-01-21 10:47:16.000000000 +0000 +@@ -268,7 +286,7 @@ + return 0; + + /* if a method uses DownloadLimit, we switch to SingleInstance mode */ +- if(_config->FindI("Acquire::"+Access+"::DlLimit",0) > 0) ++ if(_config->FindI("Acquire::"+Access+"::Dl-Limit",0) > 0) + Conf->SingleInstance = true; + + return Conf; diff --git a/data/apt/parallel.diff b/data/apt/parallel.diff new file mode 100644 index 000000000..1643fd2c7 --- /dev/null +++ b/data/apt/parallel.diff @@ -0,0 +1,33 @@ +diff -ru apt-0.6.46.4.1/apt-pkg/acquire.cc apt-0.6.46.4.1+iPhone/apt-pkg/acquire.cc +--- apt-0.6.46.4.1/apt-pkg/acquire.cc 2006-12-04 14:37:34.000000000 +0000 ++++ apt-0.6.46.4.1+iPhone/apt-pkg/acquire.cc 2009-01-21 10:47:16.000000000 +0000 +@@ -238,9 +238,27 @@ + /* Single-Instance methods get exactly one queue per URI. This is + also used for the Access queue method */ + if (Config->SingleInstance == true || QueueMode == QueueAccess) +- return U.Access; ++ return U.Access; ++ string name(U.Access + ':' + U.Host); + +- return U.Access + ':' + U.Host; ++ int parallel(_config->FindI("Acquire::"+U.Access+"::MaxParallel",0)); ++ if (parallel <= 0) ++ return name; ++ ++ typedef map indexmap; ++ static indexmap indices; ++ ++ pair cache(indices.insert(indexmap::value_type(name, -1))); ++ if (cache.second || cache.first->second == -1) { ++ int &index(indices[U.Access]); ++ if (index >= parallel) ++ index = 0; ++ cache.first->second = index++; ++ } ++ ++ ostringstream value; ++ value << U.Access << "::" << cache.first->second; ++ return value.str(); + } + /*}}}*/ + // Acquire::GetConfig - Fetch the configuration information /*{{{*/ -- cgit v1.2.3