diff -ru apt-0.7.20.2/methods/http.cc apt-0.7.20.2+iPhone/methods/http.cc
--- apt-0.7.20.2/methods/http.cc	2009-02-07 15:09:35.000000000 +0000
+++ apt-0.7.20.2+iPhone/methods/http.cc	2009-04-14 16:34:31.000000000 +0000
@@ -30,6 +30,7 @@
 #include <apt-pkg/error.h>
 #include <apt-pkg/hashes.h>
 
+#include <sys/sysctl.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <utime.h>
@@ -40,9 +41,16 @@
 #include <string.h>
 #include <iostream>
 #include <apti18n.h>
+#include <set>
 
 // Internet stuff
 #include <netdb.h>
+#include <arpa/inet.h>
+
+#include <lockdown.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h>
+#include <SystemConfiguration/SystemConfiguration.h>
 
 #include "config.h"
 #include "connect.h"
@@ -52,6 +60,51 @@
 									/*}}}*/
 using namespace std;
 
+CFStringRef Firmware_;
+const char *Machine_;
+CFStringRef UniqueID_;
+
+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;
@@ -632,6 +685,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<int *>(arg) = 1;
+            CFRunLoopStop(CFRunLoopGetCurrent());
+        break;
+
+        case kCFStreamEventErrorOccurred:
+            *reinterpret_cast<int *>(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 +1141,8 @@
    signal(SIGINT,SigTerm);
    
    Server = 0;
+
+   std::set<std::string> cached;
    
    int FailCounter = 0;
    while (1)
@@ -1063,173 +1163,313 @@
       if (Queue == 0)
 	 continue;
       
-      // Connect to the server
-      if (Server == 0 || Server->Comp(Queue->Uri) == false)
-      {
-	 delete Server;
-	 Server = new ServerState(Queue->Uri,this);
-      }
-      /* If the server has explicitly said this is the last connection
-         then we pre-emptively shut down the pipeline and tear down 
-	 the connection. This will speed up HTTP/1.0 servers a tad
-	 since we don't have to wait for the close sequence to
-         complete */
-      if (Server->Persistent == false)
-	 Server->Close();
-      
-      // Reset the pipeline
-      if (Server->ServerFd == -1)
-	 QueueBack = Queue;	 
-	 
-      // Connnect to the host
-      if (Server->Open() == false)
-      {
-	 Fail(true);
-	 delete Server;
-	 Server = 0;
-	 continue;
-      }
+      CFStringEncoding se = kCFStringEncodingUTF8;
 
-      // Fill the pipeline.
-      Fetch(0);
-      
-      // Fetch the next URL header data from the server.
-      switch (Server->RunHeaders())
-      {
-	 case 0:
-	 break;
-	 
-	 // The header data is bad
-	 case 2:
-	 {
-	    _error->Error(_("Bad header data"));
-	    Fail(true);
-	    RotateDNS();
-	    continue;
-	 }
-	 
-	 // The server closed a connection during the header get..
-	 default:
-	 case 1:
-	 {
-	    FailCounter++;
-	    _error->Discard();
-	    Server->Close();
-	    Server->Pipeline = false;
-	    
-	    if (FailCounter >= 2)
-	    {
-	       Fail(_("Connection failed"),true);
-	       FailCounter = 0;
-	    }
-	    
-	    RotateDNS();
-	    continue;
-	 }
-      };
+      char *url = strdup(Queue->Uri.c_str());
+    url:
+      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 (;;) {
+         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);
+      CFRelease(ur);
+
+      struct stat SBuf;
+      if (stat(Queue->DestFile.c_str(), &SBuf) >= 0 && SBuf.st_size > 0) {
+         sr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("bytes=%li-"), (long) SBuf.st_size - 1);
+         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Range"), sr);
+         CFRelease(sr);
+
+         sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(SBuf.st_mtime).c_str(), se);
+         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Range"), sr);
+         CFRelease(sr);
+
+         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Cache-Control"), CFSTR("no-cache"));
+      } else if (Queue->LastModified != 0) {
+         sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(Queue->LastModified).c_str(), se);
+         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Modified-Since"), sr);
+         CFRelease(sr);
+
+         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Cache-Control"), CFSTR("no-cache"));
+      } else
+         CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Cache-Control"), CFSTR("max-age=0"));
+
+      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.592"));
+
+      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);
+
+      //CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue);
+      CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue);
 
-      // Decide what to do.
       FetchResult Res;
+      CFIndex rd;
+      UInt32 sc;
+
+      uint8_t data[10240];
+      size_t offset = 0;
+
+      Status("Connecting to %s", hs.c_str());
+
+      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;
+      }
+
+      rd = CFReadStreamRead(rs, data, sizeof(data));
+
+      if (rd == -1) {
+         CfrsError(uri.Host.c_str(), rs);
+         cached.insert(hs);
+         Fail(true);
+         goto done;
+      }
+
       Res.Filename = Queue->DestFile;
-      switch (DealWithHeaders(Res,Server))
-      {
-	 // Ok, the file is Open
-	 case 0:
-	 {
-	    URIStart(Res);
 
-	    // Run the data
-	    bool Result =  Server->RunData();
+      hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader);
+      sc = CFHTTPMessageGetResponseStatusCode(hm);
 
-	    /* If the server is sending back sizeless responses then fill in
-	       the size now */
+      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<char *>(malloc(ln));
+
+            if (!CFStringGetCString(sr, url, ln, se)) {
+               Fail();
+               goto done_;
+            }
+
+            CFRelease(sr);
+            goto url;
+         }
+      }
+
+      sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Range"));
+      if (sr != NULL) {
+         size_t ln = CFStringGetLength(sr) + 1;
+         char cr[ln];
+
+         if (!CFStringGetCString(sr, cr, ln, se)) {
+            Fail();
+            goto done_;
+         }
+
+         CFRelease(sr);
+
+         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_;
+         }
+
+         if (offset > Res.Size) {
+	    _error->Error(_("This HTTP server has broken range support"));
+            Fail();
+            goto done_;
+         }
+      } else {
+         sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Length"));
+         if (sr != NULL) {
+            Res.Size = CFStringGetIntValue(sr);
+            CFRelease(sr);
+         }
+      }
+
+      time(&Res.LastModified);
+
+      sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Last-Modified"));
+      if (sr != NULL) {
+         size_t ln = CFStringGetLength(sr) + 1;
+         char cr[ln];
+
+         if (!CFStringGetCString(sr, cr, ln, se)) {
+            Fail();
+            goto done_;
+         }
+
+         CFRelease(sr);
+
+         if (!StrToTime(cr, Res.LastModified)) {
+	    _error->Error(_("Unknown date format"));
+            Fail();
+            goto done_;
+         }
+      }
+
+      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) {
+         unlink(Queue->DestFile.c_str());
+         Res.IMSHit = true;
+         Res.LastModified = Queue->LastModified;
+	 URIDone(Res);
+      } else {
+         Hashes hash;
+
+         File = new FileFd(Queue->DestFile, FileFd::WriteAny);
+         if (_error->PendingError() == true) {
+            delete File;
+            File = NULL;
+            Fail();
+            goto done;
+         }
+
+         FailFile = Queue->DestFile;
+         FailFile.c_str();   // Make sure we dont do a malloc in the signal handler
+         FailFd = File->Fd();
+         FailTime = Res.LastModified;
+
+         Res.ResumePoint = offset;
+         ftruncate(File->Fd(), offset);
+
+         if (offset != 0) {
+            lseek(File->Fd(), 0, SEEK_SET);
+            if (!hash.AddFD(File->Fd(), offset)) {
+	       _error->Errno("read", _("Problem hashing file"));
+               delete File;
+               File = NULL;
+               Fail();
+               goto done;
+            }
+         }
+
+         lseek(File->Fd(), 0, SEEK_END);
+
+	 URIStart(Res);
+
+         read: if (rd == -1) {
+            CfrsError("rd", rs);
+            Fail(true);
+         } else if (rd == 0) {
 	    if (Res.Size == 0)
 	       Res.Size = File->Size();
-	    
-	    // Close the file, destroy the FD object and timestamp it
-	    FailFd = -1;
-	    delete File;
-	    File = 0;
-	    
-	    // Timestamp
+
 	    struct utimbuf UBuf;
 	    time(&UBuf.actime);
-	    UBuf.actime = Server->Date;
-	    UBuf.modtime = Server->Date;
-	    utime(Queue->DestFile.c_str(),&UBuf);
+	    UBuf.actime = Res.LastModified;
+	    UBuf.modtime = Res.LastModified;
+	    utime(Queue->DestFile.c_str(), &UBuf);
 
-	    // Send status to APT
-	    if (Result == true)
-	    {
-	       Res.TakeHashes(*Server->In.Hash);
-	       URIDone(Res);
-	    }
-	    else
-	    {
-	       if (Server->ServerFd == -1)
-	       {
-		  FailCounter++;
-		  _error->Discard();
-		  Server->Close();
-		  
-		  if (FailCounter >= 2)
-		  {
-		     Fail(_("Connection failed"),true);
-		     FailCounter = 0;
-		  }
-		  
-		  QueueBack = Queue;
-	       }
-	       else
-		  Fail(true);
-	    }
-	    break;
-	 }
-	 
-	 // IMS hit
-	 case 1:
-	 {
+	    Res.TakeHashes(hash);
 	    URIDone(Res);
-	    break;
-	 }
-	 
-	 // Hard server error, not found or something
-	 case 3:
-	 {
-	    Fail();
-	    break;
-	 }
-	  
-	 // Hard internal error, kill the connection and fail
-	 case 5:
-	 {
-	    delete File;
-	    File = 0;
+         } else {
+	    hash.Add(data, rd);
 
-	    Fail();
-	    RotateDNS();
-	    Server->Close();
-	    break;
-	 }
+            uint8_t *dt = data;
+            while (rd != 0) {
+               int sz = write(File->Fd(), dt, rd);
+
+               if (sz == -1) {
+                   delete File;
+                   File = NULL;
+                   Fail();
+                   goto done;
+               }
+
+               dt += sz;
+               rd -= sz;
+            }
+
+            rd = CFReadStreamRead(rs, data, sizeof(data));
+            goto read;
+         }
+      }
+
+     goto done;
+    done_:
+      CFRelease(hm);
+    done:
+      CFReadStreamClose(rs);
+      CFRelease(rs);
+      free(url);
 
-	 // We need to flush the data, the header is like a 404 w/ error text
-	 case 4:
-	 {
-	    Fail();
-	    
-	    // Send to content to dev/null
-	    File = new FileFd("/dev/null",FileFd::WriteExists);
-	    Server->RunData();
-	    delete File;
-	    File = 0;
-	    break;
-	 }
-	 
-	 default:
-	 Fail(_("Internal error"));
-	 break;
-      }
-      
       FailCounter = 0;
    }
    
@@ -1242,6 +1482,34 @@
    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();
 }
diff -ru apt-0.7.20.2/methods/makefile apt-0.7.20.2+iPhone/methods/makefile
--- apt-0.7.20.2/methods/makefile	2009-02-07 15:09:35.000000000 +0000
+++ apt-0.7.20.2+iPhone/methods/makefile	2009-04-14 16:18:18.000000000 +0000
@@ -47,7 +47,7 @@
 
 # The http method
 PROGRAM=http
-SLIBS = -lapt-pkg $(SOCKETLIBS) $(INTLLIBS)
+SLIBS = -lapt-pkg $(SOCKETLIBS) $(INTLLIBS) -framework CoreFoundation -framework CFNetwork -framework SystemConfiguration -framework IOKit -llockdown
 LIB_MAKES = apt-pkg/makefile
 SOURCE = http.cc rfc2553emu.cc connect.cc
 include $(PROGRAM_H)