X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/049c0171c286bbce536c2732ac17605fdea78410..16176b647e76f316ec98f31f6dd806a49d7b8a77:/methods/http.cc?ds=sidebyside diff --git a/methods/http.cc b/methods/http.cc index 68653fbb3..2ec1fe631 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -58,6 +58,12 @@ unsigned long PipelineDepth = 10; unsigned long TimeOut = 120; bool Debug = false; + +unsigned long CircleBuf::BwReadLimit=0; +unsigned long CircleBuf::BwTickReadData=0; +struct timeval CircleBuf::BwReadTick={0,0}; +const unsigned int CircleBuf::BW_HZ=10; + // CircleBuf::CircleBuf - Circular input buffer /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -65,6 +71,8 @@ CircleBuf::CircleBuf(unsigned long Size) : Size(Size), Hash(0) { Buf = new unsigned char[Size]; Reset(); + + CircleBuf::BwReadLimit = _config->FindI("Acquire::http::DlLimit",0)*1024; } /*}}}*/ // CircleBuf::Reset - Reset to the default state /*{{{*/ @@ -90,16 +98,45 @@ void CircleBuf::Reset() is non-blocking.. */ bool CircleBuf::Read(int Fd) { + unsigned long BwReadMax; + while (1) { // Woops, buffer is full if (InP - OutP == Size) return true; - + + // what's left to read in this tick + BwReadMax = CircleBuf::BwReadLimit/BW_HZ; + + if(CircleBuf::BwReadLimit) { + struct timeval now; + gettimeofday(&now,0); + + unsigned long d = (now.tv_sec-CircleBuf::BwReadTick.tv_sec)*1000000 + + now.tv_usec-CircleBuf::BwReadTick.tv_usec; + if(d > 1000000/BW_HZ) { + CircleBuf::BwReadTick = now; + CircleBuf::BwTickReadData = 0; + } + + if(CircleBuf::BwTickReadData >= BwReadMax) { + usleep(1000000/BW_HZ); + return true; + } + } + // Write the buffer segment int Res; - Res = read(Fd,Buf + (InP%Size),LeftRead()); + if(CircleBuf::BwReadLimit) { + Res = read(Fd,Buf + (InP%Size), + BwReadMax > LeftRead() ? LeftRead() : BwReadMax); + } else + Res = read(Fd,Buf + (InP%Size),LeftRead()); + if(Res > 0 && BwReadLimit > 0) + CircleBuf::BwTickReadData += Res; + if (Res == 0) return false; if (Res < 0) @@ -514,14 +551,14 @@ bool ServerState::HeaderLine(string Line) { if (sscanf(Line.c_str(),"HTTP/%u.%u %u %[^\n]",&Major,&Minor, &Result,Code) != 4) - return _error->Error(_("The http server sent an invalid reply header")); + return _error->Error(_("The HTTP server sent an invalid reply header")); } else { Major = 0; Minor = 9; if (sscanf(Line.c_str(),"HTTP %u %[^\n]",&Result,Code) != 2) - return _error->Error(_("The http server sent an invalid reply header")); + return _error->Error(_("The HTTP server sent an invalid reply header")); } /* Check the HTTP response header to get the default persistance @@ -550,7 +587,7 @@ bool ServerState::HeaderLine(string Line) return true; if (sscanf(Val.c_str(),"%lu",&Size) != 1) - return _error->Error(_("The http server sent an invalid Content-Length header")); + return _error->Error(_("The HTTP server sent an invalid Content-Length header")); return true; } @@ -565,9 +602,9 @@ bool ServerState::HeaderLine(string Line) HaveContent = true; if (sscanf(Val.c_str(),"bytes %lu-%*u/%lu",&StartPos,&Size) != 2) - return _error->Error(_("The http server sent an invalid Content-Range header")); + return _error->Error(_("The HTTP server sent an invalid Content-Range header")); if ((unsigned)StartPos > Size) - return _error->Error(_("This http server has broken range support")); + return _error->Error(_("This HTTP server has broken range support")); return true; } @@ -635,9 +672,9 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) and a no-store directive for archives. */ sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n", Itm->Uri.c_str(),ProperHost.c_str()); - if (_config->FindB("Acquire::http::No-Cache",false) == true) - strcat(Buf,"Cache-Control: no-cache\r\nPragma: no-cache\r\n"); - else + // only generate a cache control header if we actually want to + // use a cache + if (_config->FindB("Acquire::http::No-Cache",false) == false) { if (Itm->IndexFile == true) sprintf(Buf+strlen(Buf),"Cache-Control: max-age=%u\r\n", @@ -649,6 +686,10 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) } } } + // generate a no-cache header if needed + if (_config->FindB("Acquire::http::No-Cache",false) == true) + strcat(Buf,"Cache-Control: no-cache\r\nPragma: no-cache\r\n"); + string Req = Buf; @@ -829,7 +870,7 @@ bool HttpMethod::ServerDie(ServerState *Srv) { Srv->Close(); if (LErrno == 0) - return _error->Error(_("Error reading from server Remote end closed connection")); + return _error->Error(_("Error reading from server. Remote end closed connection")); errno = LErrno; return _error->Errno("read",_("Error reading from server")); } @@ -1062,7 +1103,7 @@ int HttpMethod::Loop() // The header data is bad case 2: { - _error->Error(_("Bad header Data")); + _error->Error(_("Bad header data")); Fail(true); RotateDNS(); continue; @@ -1184,7 +1225,6 @@ int HttpMethod::Loop() int main() { setlocale(LC_ALL, ""); - bindtextdomain(APT_DOMAIN, Cnf.FindDir("Dir::Locale").c_str()); HttpMethod Mth;