Minor typos.
[ntk/apt.git] / methods / http.cc
index dbf2d1b..3c2d8a3 100644 (file)
@@ -3,7 +3,7 @@
 // $Id: http.cc,v 1.59 2004/05/08 19:42:35 mdz Exp $
 /* ######################################################################
 
-   HTTP Aquire Method - This is the HTTP aquire method for APT.
+   HTTP Acquire Method - This is the HTTP aquire method for APT.
    
    It uses HTTP/1.1 and many of the fancy options there-in, such as
    pipelining, range, if-range and so on. 
@@ -44,6 +44,7 @@
 // Internet stuff
 #include <netdb.h>
 
+#include "config.h"
 #include "connect.h"
 #include "rfc2553emu.h"
 #include "http.h"
@@ -57,8 +58,13 @@ time_t HttpMethod::FailTime = 0;
 unsigned long PipelineDepth = 10;
 unsigned long TimeOut = 120;
 bool Debug = false;
+URI Proxy;
 
-
+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                                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -66,6 +72,8 @@ CircleBuf::CircleBuf(unsigned long Size) : Size(Size), Hash(0)
 {
    Buf = new unsigned char[Size];
    Reset();
+
+   CircleBuf::BwReadLimit = _config->FindI("Acquire::http::Dl-Limit",0)*1024;
 }
                                                                        /*}}}*/
 // CircleBuf::Reset - Reset to the default state                       /*{{{*/
@@ -91,16 +99,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)
@@ -621,7 +658,7 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
       will glitch HTTP/1.0 proxies because they do not filter it out and 
       pass it on, HTTP/1.1 says the connection should default to keep alive
       and we expect the proxy to do this */
-   if (Proxy.empty() == true)
+   if (Proxy.empty() == true || Proxy.Host.empty())
       sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\n",
              QuoteString(Uri.Path,"~").c_str(),ProperHost.c_str());
    else
@@ -678,7 +715,7 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out)
       Req += string("Authorization: Basic ") + 
           Base64Encode(Uri.User + ":" + Uri.Password) + "\r\n";
    
-   Req += "User-Agent: Debian APT-HTTP/1.3\r\n\r\n";
+   Req += "User-Agent: Debian APT-HTTP/1.3 ("VERSION")\r\n\r\n";
    
    if (Debug == true)
       cerr << Req << endl;
@@ -783,7 +820,10 @@ bool HttpMethod::Flush(ServerState *Srv)
 {
    if (File != 0)
    {
-      SetNonBlock(File->Fd(),false);
+      // on GNU/kFreeBSD, apt dies on /dev/null because non-blocking
+      // can't be set
+      if (File->Name() != "/dev/null")
+        SetNonBlock(File->Fd(),false);
       if (Srv->In.WriteSpace() == false)
         return true;
       
@@ -811,7 +851,10 @@ bool HttpMethod::ServerDie(ServerState *Srv)
    // Dump the buffer to the file
    if (Srv->State == ServerState::Data)
    {
-      SetNonBlock(File->Fd(),false);
+      // on GNU/kFreeBSD, apt dies on /dev/null because non-blocking
+      // can't be set
+      if (File->Name() != "/dev/null")
+        SetNonBlock(File->Fd(),false);
       while (Srv->In.WriteSpace() == true)
       {
         if (Srv->In.Write(File->Fd()) == false)