diff -Nru apt-transport-debtorrent-0.1.1ubuntu2/debian/changelog apt-transport-debtorrent-0.2.0ubuntu1/debian/changelog --- apt-transport-debtorrent-0.1.1ubuntu2/debian/changelog 2007-12-14 12:06:40.000000000 +0100 +++ apt-transport-debtorrent-0.2.0ubuntu1/debian/changelog 2008-01-15 12:05:54.000000000 +0100 @@ -1,3 +1,28 @@ +apt-transport-debtorrent (0.2.0ubuntu1) hardy; urgency=low + + * Merge from Debian unstable (LP: #183143). Remaining Ubuntu changes: + - Build-dep on libapt-pkg-dev (>= 0.7.9). + - Add quilt support + - debian/patches/SetFailReason.patch: fix FTBFS + * Modify Maintainer value to match the DebianMaintainerField + specification. + + -- Andrea Colangelo Sat, 12 Jan 2008 10:10:56 +0100 + +apt-transport-debtorrent (0.2.0) unstable; urgency=low + + * Upgrade transport version to 0.2 + - Create sparse files based on status messages (102) from DebTorrent + - Send general status updates to apt (103) from DebTorrent + * Remove support for Range headers as they may confuse the + sparse file allocation + * Fix typo in long description + * Upgrade to standards version 3.7.3 (no changes) + * Changes the XS-Vcs-* headers to Vcs-* + * Moved Homepage from description to Source package fields + + -- Cameron Dale Wed, 09 Jan 2008 21:28:07 -0800 + apt-transport-debtorrent (0.1.1ubuntu2) hardy; urgency=low * Rebuild against libapt-pkg-libc6.6-6-4.6. diff -Nru apt-transport-debtorrent-0.1.1ubuntu2/debian/control apt-transport-debtorrent-0.2.0ubuntu1/debian/control --- apt-transport-debtorrent-0.1.1ubuntu2/debian/control 2007-12-14 12:06:48.000000000 +0100 +++ apt-transport-debtorrent-0.2.0ubuntu1/debian/control 2008-01-12 10:10:56.000000000 +0100 @@ -3,16 +3,17 @@ Priority: optional Maintainer: Ubuntu MOTU Developers XSBC-Original-Maintainer: Cameron Dale -Standards-Version: 3.7.2.2 +Homepage: http://debtorrent.alioth.debian.org/ +Standards-Version: 3.7.3 Build-Depends: debhelper (>= 5.0), libapt-pkg-dev (>= 0.7.9), quilt -XS-Vcs-Svn: svn://svn.debian.org/debtorrent/apt-transport-debtorrent/trunk -XS-Vcs-Browser: http://svn.debian.org/wsvn/debtorrent/apt-transport-debtorrent/trunk/ +Vcs-Svn: svn://svn.debian.org/debtorrent/apt-transport-debtorrent/trunk +Vcs-Browser: http://svn.debian.org/wsvn/debtorrent/apt-transport-debtorrent/trunk/ XS-Dm-Upload-Allowed: yes Package: apt-transport-debtorrent Architecture: any Depends: ${shlibs:Depends} -Recommends: debtorrent (>= 0.1.4) +Recommends: debtorrent (>= 0.1.5) Conflicts: debtorrent (<< 0.1.4) Description: an APT transport for communicating with DebTorrent This package contains the APT debtorrent transport. It makes it possible to @@ -26,11 +27,9 @@ . However, using this method has some advantages over HTTP. Unlike the traditional HTTP method, this transport will send all possible requests to - DebTorrent as soon as it receieves them, which will speed up the download + DebTorrent as soon as it recieves them, which will speed up the download as peers can be contacted in parallel. This method also allows the DebTorrent client to return files to APT in any order, which is important since BitTorrent downloads proceed in a random order. Additionally, this method uses a very similar protocol to HTTP, and so can easily be used to access a DebTorrent client running on another host. - . - Homepage: http://debtorrent.alioth.debian.org/ diff -Nru apt-transport-debtorrent-0.1.1ubuntu2/debtorrent.cc apt-transport-debtorrent-0.2.0ubuntu1/debtorrent.cc --- apt-transport-debtorrent-0.1.1ubuntu2/debtorrent.cc 2007-08-17 04:14:04.000000000 +0200 +++ apt-transport-debtorrent-0.2.0ubuntu1/debtorrent.cc 2007-11-07 01:07:31.000000000 +0100 @@ -353,7 +353,7 @@ { State = Header; - Owner->Status("Waiting for headers"); + // Owner->Status("Waiting for headers"); Major = 0; Minor = 0; @@ -363,6 +363,7 @@ Encoding = Closes; HaveContent = false; time(&Date); + Message[0] = '\0'; do { @@ -386,6 +387,20 @@ if (Result == 100) continue; + // 103 Status Update for apt + if (Result == 103) + { + Owner->Status(Message); + if (Debug == true) + { + char Buf[1000]; + sprintf(Buf,"StatusMessage: %s\n", Message); + string Req = Buf; + cerr << Req << endl; + } + continue; + } + // Tidy up the connection persistance state. if (Encoding == Closes && HaveContent == true) Persistent = false; @@ -530,7 +545,25 @@ return true; } - + + // The new Pieces-Downloaded header indicating how much of the file is available + if (stringcasecmp(Tag,"Pieces-Downloaded:") == 0) + { + if (sscanf(Val.c_str(),"bytes %lu/%lu",&StartPos,&Size) != 2) + return _error->Error("The DebTorrent client sent an invalid Pieces-Downloaded header"); + if ((unsigned)StartPos > Size) + return _error->Error("This DebTorrent client has broken Pieces-Downloaded support"); + return true; + } + + // The new Message header indicating the DebTorrent client's current status + if (stringcasecmp(Tag,"Message:") == 0) + { + if (sscanf(Val.c_str(),"%[^\n]",Message) != 1) + return _error->Error("The DebTorrent client sent an invalid Message header"); + return true; + } + if (stringcasecmp(Tag,"Content-Length:") == 0) { if (Encoding == Closes) @@ -556,10 +589,12 @@ { HaveContent = true; + /* Remove Range headers as DebTorrent doesn't support them and it could cause + * problems with sparse file writing. if (sscanf(Val.c_str(),"bytes %lu-%*u/%lu",&StartPos,&Size) != 2) return _error->Error("The DebTorrent client sent an invalid Content-Range header"); if ((unsigned)StartPos > Size) - return _error->Error("This DebTorrent client has broken range support"); + return _error->Error("This DebTorrent client has broken range support"); */ return true; } @@ -614,12 +649,14 @@ /* Build the request. We include a keep-alive header to tweak old http/1.0 servers that do support keep-alive but not HTTP/1.1 automatic keep-alive. */ - sprintf(Buf,"GET %s DEBTORRENT/0.1\r\nHost: %s\r\nConnection: keep-alive\r\n", + sprintf(Buf,"GET %s DEBTORRENT/0.2\r\nHost: %s\r\nConnection: keep-alive\r\n", QuoteString(Uri.Path,"~").c_str(),ProperHost.c_str()); string Req = Buf; // Check for a partial file + /* Remove Range headers as DebTorrent doesn't support them and it could cause + * problems with sparse file writing. struct stat SBuf; if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0) { @@ -629,19 +666,19 @@ Req += Buf; } else - { + { */ if (Itm->LastModified != 0) { sprintf(Buf,"If-Modified-Since: %s\r\n",TimeRFC1123(Itm->LastModified).c_str()); Req += Buf; } - } + /* } */ if (Uri.User.empty() == false || Uri.Password.empty() == false) Req += string("Authorization: Basic ") + Base64Encode(Uri.User + ":" + Uri.Password) + "\r\n"; - Req += "User-Agent: Debian APT-DEBTORRENT/0.1 ("VERSION")\r\n\r\n"; + Req += "User-Agent: Debian APT-DEBTORRENT/0.2 ("VERSION")\r\n\r\n"; if (Debug == true) cerr << Req << endl; @@ -871,6 +908,7 @@ // --------------------------------------------------------------------- /* We look at the header data we got back from the server and decide what to do. Returns + -1 - Piece downloaded update 0 - File is open, 1 - IMS hit 3 - Unrecoverable error @@ -878,6 +916,15 @@ 5 - Unrecoverable non-server error (close the connection) */ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) { + // Piece Downloaded update message + if (Srv->Result == 102) + { + // Hack: use ResumePoint to temporarily store the current size + Res.Size = Srv->Size; + Res.ResumePoint = Srv->StartPos; + return -1; + } + // Not Modified if (Srv->Result == 304) { @@ -903,7 +950,7 @@ // Open the file delete File; - File = new FileFd(Queue->DestFile,FileFd::WriteAny); + File = new FileFd(Queue->DestFile,FileFd::WriteEmpty); if (_error->PendingError() == true) return 5; @@ -940,6 +987,72 @@ SetNonBlock(File->Fd(),true); return 0; } + /*}}}*/ +// HttpMethod::UpdateFileSize - Update the output file's size /*{{{*/ +// --------------------------------------------------------------------- +/* Increase the output file's size (sparsely) to indicate the current + amount of the file that has been downloaded by DebTorrent. Returns + false if an error occurred. */ +bool HttpMethod::UpdateFileSize(FetchResult &Res, bool Started) +{ + // Open the file (reset to empty if not started) + if (Started) + File = new FileFd(Res.Filename, FileFd::WriteAny); + else + File = new FileFd(Res.Filename, FileFd::WriteEmpty); + if (_error->PendingError() == true) + { + delete File; + File = 0; + return false; + } + + // Get the old size of the file + unsigned long OldSize = File->Size(); + if (_error->PendingError() == true) + { + delete File; + File = 0; + return false; + } + + // Don't make files smaller (it will confuse apt) + if (OldSize >= Res.ResumePoint) + { + delete File; + File = 0; + return true; + } + + // Set the file to the new length + File->Truncate(Res.ResumePoint); + if (_error->PendingError() == true) + { + delete File; + File = 0; + return false; + } + + // Sync the file to disk and close it + File->Sync(); + delete File; + File = 0; + if (_error->PendingError() == true) + { + return false; + } + + if (Debug == true) + { + char Buf[1000]; + sprintf(Buf,"UpdateFileSize: %s was %ld, set to %ld/%ld\n", + Res.Filename.c_str(), OldSize, Res.ResumePoint, Res.Size); + string Req = Buf; + cerr << Req << endl; + } + + return true; +} /*}}}*/ // HttpMethod::SigTerm - Handle a fatal signal /*{{{*/ // --------------------------------------------------------------------- @@ -979,6 +1092,10 @@ if (QueueBack == I) { QueueBack = I->Next; + + // Initialize the unstarted flag + I->IndexFile = false; + SendReq(I,Server->Out); continue; } @@ -1101,10 +1218,39 @@ Res.Filename = Queue->DestFile; switch (DealWithHeaders(Res,Server)) { + // Got an informational file size message + case -1: + { + // Set the file to the new length + if (UpdateFileSize(Res, Queue->IndexFile) == false) + { + Fail(); + RotateDNS(); + Server->Close(); + } + // Hack: use the IndexFile flag to indicate if it's been started + else if (Queue->IndexFile == false) + { + // Make sure to unset the ResumePoint for the call to URIStart + Res.ResumePoint = 0; + + URIStart(Res); + + Queue->IndexFile = true; + } + + break; + } + // Ok, the file is Open case 0: { - URIStart(Res); + // Make sure to send the URIStart first + if (Queue->IndexFile == false) + { + URIStart(Res); + Queue->IndexFile = true; + } // Run the data bool Result = Server->RunData(); @@ -1201,10 +1347,14 @@ else { // The result could not be found in the requests + Fail("Data returned for an unrequested file"); + + // Send to content to dev/null + File = new FileFd("/dev/null",FileFd::WriteExists); + Server->RunData(); delete File; File = 0; - Fail("Data returned for an unrequested file"); RotateDNS(); Server->Close(); } diff -Nru apt-transport-debtorrent-0.1.1ubuntu2/debtorrent.h apt-transport-debtorrent-0.2.0ubuntu1/debtorrent.h --- apt-transport-debtorrent-0.1.1ubuntu2/debtorrent.h 2007-08-15 07:04:32.000000000 +0200 +++ apt-transport-debtorrent-0.2.0ubuntu1/debtorrent.h 2007-11-06 23:54:08.000000000 +0100 @@ -12,7 +12,7 @@ #define APT_DEBTORRENT_H #define MAXLEN 360 -#define VERSION "0.1" +#define VERSION "0.2" #include @@ -101,6 +101,7 @@ enum {Chunked,Stream,Closes} Encoding; enum {Header, Data} State; bool Persistent; + char Message[MAXLEN]; // This is a Persistent attribute of the server itself. bool Pipeline; @@ -136,6 +137,7 @@ bool ServerDie(ServerState *Srv); bool RearrangeQueue(ServerState *Srv); int DealWithHeaders(FetchResult &Res,ServerState *Srv); + bool UpdateFileSize(FetchResult &Res, bool Started); virtual bool Fetch(FetchItem *); virtual bool Configuration(string Message);