On Tue, Jan 12, 2016 at 01:56:10PM +0000, Robie Basak wrote:
> On Tue, Jan 12, 2016 at 02:36:28PM +0100, Julian Andres Klode wrote:
> > Well, yes, nobody really uses HTTP/1.0 servers, so it's not really tested 
> > much.
> 
> I just checked and a newer squid (3.1.19) that I have handy also
> responds with HTTP/1.0. I don't have a squid 3.4 deployment to check,
> but 3.1 shipped in wheezy (Debian LTS project EOL is 2018) and in Ubuntu
> 12.04, which is not EOL until 2019. I think apt needs to be able to work
> by default through squid proxies that are still commonly deployed.
> 
> > If we have hashes, we will try to do pipelining and then fall back if
> > the server messes up the response.
> > 
> > Maybe it helps to also disable pipelining if the server responds with
> > HTTP/1.0, like this:
> 
> I think this would help. You will reduce the number of pipelined
> requests, and thus the number of times the race is lost. But you won't
> eliminate the race completely. Really you need to only enable pipelining
> after you see an HTTP/1.1 or higher response, rather than the other way
> round. That is trickier to code correctly but is required by the
> standards, AIUI.
> 

Fixed in my branch in this commit:
  https://github.com/Debian/apt/commit/2caf777bf7badbc75e6503c4dcee71e51b0a43d8
just need to fix a failing test case that checks if pipelining is messed up,
as that now does no pipelining for the first package anymore.

And change the variable name to something nicer.

diff --git a/methods/server.cc b/methods/server.cc
index d5188d4..9f21eff 100644
--- a/methods/server.cc
+++ b/methods/server.cc
@@ -150,9 +150,15 @@ bool ServerState::HeaderLine(string Line)
       else
       {
         if (Major == 1 && Minor == 0)
+        {
            Persistent = false;
+        }
         else
+        {
            Persistent = true;
+           if (ServerIsDoingPipeliningWrong == false)
+              Pipeline = true;
+        }
       }
 
       return true;
@@ -240,7 +246,7 @@ bool ServerState::HeaderLine(string Line)
 }
                                                                        /*}}}*/
 // ServerState::ServerState - Constructor                              /*{{{*/
-ServerState::ServerState(URI Srv, ServerMethod *Owner) : ServerName(Srv), 
TimeOut(120), Owner(Owner)
+ServerState::ServerState(URI Srv, ServerMethod *Owner) : ServerName(Srv), 
TimeOut(120), Owner(Owner), ServerIsDoingPipeliningWrong(false)
 {
    Reset();
 }
@@ -532,6 +538,7 @@ int ServerMethod::Loop()
            _error->Discard();
            Server->Close();
            Server->Pipeline = false;
+           Server->ServerIsDoingPipeliningWrong = true;
            
            if (FailCounter >= 2)
            {
@@ -604,6 +611,7 @@ int ServerMethod::Loop()
                           strprintf(out, _("Automatically disabled %s due to 
incorrect response from server/proxy. (man 5 apt.conf)"), 
"Acquire::http::PipelineDepth");
                           std::cerr << "W: " << out << std::endl;
                           Server->Pipeline = false;
+                          Server->ServerIsDoingPipeliningWrong = true;
                           // we keep the PipelineDepth value so that the rest 
of the queue can be fixed up as well
                        }
                        Rename(Res.Filename, I->DestFile);
diff --git a/methods/server.h b/methods/server.h
index 365bc08..8f81090 100644
--- a/methods/server.h
+++ b/methods/server.h
@@ -51,6 +51,7 @@ struct ServerState
    enum {Chunked,Stream,Closes} Encoding;
    enum {Header, Data} State;
    bool Persistent;
+   bool ServerIsDoingPipeliningWrong;
    std::string Location;
 
    // This is a Persistent attribute of the server itself.
@@ -86,7 +87,7 @@ struct ServerState
    bool Comp(URI Other) const {return Other.Host == ServerName.Host && 
Other.Port == ServerName.Port;};
    virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; 
TotalFileSize = 0; JunkSize = 0;
                 StartPos = 0; Encoding = Closes; time(&Date); HaveContent = 
false;
-                State = Header; Persistent = false; Pipeline = true; 
MaximumSize = 0;};
+                State = Header; Persistent = false; Pipeline = false; 
MaximumSize = 0;};
    virtual bool WriteResponse(std::string const &Data) = 0;
 
    /** \brief Transfer the data from the socket */


-- 
Julian Andres Klode  - Debian Developer, Ubuntu Member

See http://wiki.debian.org/JulianAndresKlode and http://jak-linux.org/.

When replying, only quote what is necessary, and write each reply
directly below the part(s) it pertains to (`inline'). Thank you.

Reply via email to