<feed xmlns='http://www.w3.org/2005/Atom'>
<title>apt/methods/http.cc, branch 2.2.1</title>
<subtitle>Debians commandline package manager</subtitle>
<id>https://git.kalnischkies.de/apt/atom?h=2.2.1</id>
<link rel='self' href='https://git.kalnischkies.de/apt/atom?h=2.2.1'/>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/'/>
<updated>2020-12-18T18:31:19Z</updated>
<entry>
<title>Implement encoded URI handling in all methods</title>
<updated>2020-12-18T18:31:19Z</updated>
<author>
<name>David Kalnischkies</name>
<email>david@kalnischkies.de</email>
</author>
<published>2020-07-09T22:02:25Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=97d6c3b2d05fe0d965657197adf56cc78f9edf81'/>
<id>urn:sha1:97d6c3b2d05fe0d965657197adf56cc78f9edf81</id>
<content type='text'>
Every method opts in to getting the encoded URI passed along while
keeping compat in case we are operated by an older acquire system.

Effectively this is just a change for the http-based methods as the
others just decode the URI as they work with files directly.
</content>
</entry>
<entry>
<title>Rewrite HttpServerState::Die()</title>
<updated>2020-08-11T11:42:41Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-08-11T11:09:14Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=8b35e2a3dd7b863639a8909fa2361ed4fd217bc3'/>
<id>urn:sha1:8b35e2a3dd7b863639a8909fa2361ed4fd217bc3</id>
<content type='text'>
The old code was fairly confusing, and contradictory. Notably, the
second `if` also only applied to the Data state, whereas we already
terminated the Data state earlier. This was bad.

The else fallback applied in three cases:

(1) We reached our limit
(2) We are Persistent
(3) We are headers

Now, it always failed as a transient error if it had
nothing left in the buffer. BUT: Nothing left in the buffer
is the correct thing to happen if we were fetching content.

Checking all combinations for the flags, we can compare the results
of Die() between 2.1.7 - the last "known-acceptable-ish" version
and this version:
                                2.1.7           this
Data !Persist !Space !Limit     OK (A)           OK
Data !Persist !Space Limit      OK (A)           OK
Data !Persist Space !Limit      OK (C)           OK
Data !Persist Space Limit       OK               OK

Data Persist !Space !Limit      ERR              ERR          *
Data Persist !Space Limit       OK (B)           OK
Data Persist Space !Limit       ERR              ERR
Data Persist Space Limit        OK               OK

=&gt; Data connections are OK if they have not reached their limit,
   or are persistent (in which case they'll probably be chunked)

Header !Persist !Space !Limit   ERR              ERR
Header !Persist !Space Limit    ERR              ERR
Header !Persist Space !Limit    OK               OK
Header !Persist Space Limit     OK               OK
Header Persist !Space !Limit    ERR              ERR
Header Persist !Space Limit     ERR              ERR
Header Persist Space !Limit     OK               OK
Header Persist Space Limit      OK               OK

=&gt; Common scheme here is that header connections are fine if they have
   read something into the input buffer (Space). The rest does not matter.

(A) Non-persistent connections with !space always enter the else clause, hence  success
(B) no Space means we enter the if/else, we go with else because IsLimit(), and we succeed because we don't have space
(C) Having space we do enter the while (WriteSpace()) loop, but we never reach IsLimit(),
    hence we fall through. Given that our connection is not persistent, we fall through to the
    else case, and there we win because we have data left to write.
</content>
</entry>
<entry>
<title>http: Fully flush local file both before/after server read</title>
<updated>2020-08-11T11:09:04Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-08-11T08:55:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=73780d7f664a4ea1da55527d726b4c9c7753f1fb'/>
<id>urn:sha1:73780d7f664a4ea1da55527d726b4c9c7753f1fb</id>
<content type='text'>
We do not want to end up in a code path while reading content
from the server where we have local data left to write, which
can happen if a previous read included both headers and content.

Restructure Flush() to accept a new argument to allow incomplete
flushs (which do not match our limit), so that it can flush as
far as possible, and modify Go() and use that before and after
reading from the server.
</content>
</entry>
<entry>
<title>http: Do not use non-blocking local I/O</title>
<updated>2020-08-11T11:09:04Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-08-11T09:42:15Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=13ab2317451931f055855f1aeaec6c8b28b14ce2'/>
<id>urn:sha1:13ab2317451931f055855f1aeaec6c8b28b14ce2</id>
<content type='text'>
This causes some more issues, really.
</content>
</entry>
<entry>
<title>http: Restore successful exits from Die()</title>
<updated>2020-08-11T11:09:04Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-08-11T09:40:14Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=af7ab7c0002ef2cdfb1a4c0a468c5dbbda3d5dd0'/>
<id>urn:sha1:af7ab7c0002ef2cdfb1a4c0a468c5dbbda3d5dd0</id>
<content type='text'>
We have successfully finished reading data if our buffer is empty,
so we don't need to do any further checks.
</content>
</entry>
<entry>
<title>http: Always write to the file if there's something to write</title>
<updated>2020-08-04T09:46:39Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-08-04T09:37:45Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=27d36318b98f3a070fb24557ce691718ef4eec34'/>
<id>urn:sha1:27d36318b98f3a070fb24557ce691718ef4eec34</id>
<content type='text'>
We only add the file to the select() call if we have data to
write to it prior to the select() call. This is problematic:

Assuming we enter Go() with no data to write to the file,
but we read some from the server as well as an EOF, we end
up not writing it to the file because we did not add the file
to the select.

We can't always add the file to the select(), because it's
basically always ready and we don't want to wake up if we
don't have anything to read or write.

So for a solution, let's just always write data to the file
if there's data to write to it. If some gets leftover, or if
some was already present when we started Go(), it will still
be added to the select() call and unblock it.

Closes: #959518
</content>
</entry>
<entry>
<title>http: Redesign reading of pending data</title>
<updated>2020-07-24T14:30:43Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-06-29T12:03:21Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=08f05aa8beb58fa32485e2087eb21a9f3cb267bb'/>
<id>urn:sha1:08f05aa8beb58fa32485e2087eb21a9f3cb267bb</id>
<content type='text'>
Instead of reading the data early, disable the timeout for the
select() call and read the data later. Also, change Read() to
call only once to drain the buffer in such instances.

We could optimize this to call read() multiple times if there
is also pending stuff on the socket, but that it slightly more
complex and should not provide any benefits.
</content>
</entry>
<entry>
<title>http: On select timeout, error out directly, do not call Die()</title>
<updated>2020-07-24T14:30:43Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-06-29T10:31:55Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=c2cb8abbf5d8a49b25071ffffca93a083fe725fc'/>
<id>urn:sha1:c2cb8abbf5d8a49b25071ffffca93a083fe725fc</id>
<content type='text'>
The error handling in Die() that's supposed to add useful error
messages is not super useful here.
</content>
</entry>
<entry>
<title>http: Finish copying data from server to file before sending stuff to server</title>
<updated>2020-07-24T14:30:43Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-06-29T10:23:02Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=9742032dcdc0e72c117ae0c589fbb59452d6d33c'/>
<id>urn:sha1:9742032dcdc0e72c117ae0c589fbb59452d6d33c</id>
<content type='text'>
This avoids a case where we read data, then write to the server
and only then realize the connection was closed. It is somewhat
slower, though.
</content>
</entry>
<entry>
<title>http: Die(): Do not flush the buffer, error out instead</title>
<updated>2020-07-24T14:30:43Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2020-06-29T09:48:28Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=24d308455a5f8751f57219f211a5672af340099e'/>
<id>urn:sha1:24d308455a5f8751f57219f211a5672af340099e</id>
<content type='text'>
By changing the buffer implementation to return true if it
read or wrote something, even on EOF, we should not have a
need to flush the buffer in Die() anymore - we should only
be calling Die() if the buffer is empty now.
</content>
</entry>
</feed>
