summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
Diffstat (limited to 'methods')
-rw-r--r--methods/basehttp.cc24
-rw-r--r--methods/basehttp.h3
-rw-r--r--methods/gpgv.cc59
3 files changed, 45 insertions, 41 deletions
diff --git a/methods/basehttp.cc b/methods/basehttp.cc
index 3d95ba7df..f8dd7c020 100644
--- a/methods/basehttp.cc
+++ b/methods/basehttp.cc
@@ -39,6 +39,10 @@ string BaseHttpMethod::FailFile;
int BaseHttpMethod::FailFd = -1;
time_t BaseHttpMethod::FailTime = 0;
+// Number of successful requests in a pipeline needed to continue
+// pipelining after a connection reset.
+constexpr int PIPELINE_MIN_SUCCESSFUL_ANSWERS_TO_CONTINUE = 3;
+
// ServerState::RunHeaders - Get the headers before the data /*{{{*/
// ---------------------------------------------------------------------
/* Returns 0 if things are OK, 1 if an IO error occurred and 2 if a header
@@ -215,8 +219,11 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/
/* Some servers send error pages (as they are dynamically generated)
for simplicity via a connection close instead of e.g. chunked,
so assuming an always closing server only if we get a file + close */
- if (Result >= 200 && Result < 300)
+ if (Result >= 200 && Result < 300 && Server->PipelineAnswersReceived < PIPELINE_MIN_SUCCESSFUL_ANSWERS_TO_CONTINUE)
+ {
Server->PipelineAllowed = false;
+ Server->PipelineAnswersReceived = 0;
+ }
}
else if (stringcasecmp(Val,"keep-alive") == 0)
Server->Persistent = true;
@@ -267,6 +274,7 @@ void ServerState::Reset() /*{{{*/
Pipeline = false;
PipelineAllowed = true;
RangesAllowed = true;
+ PipelineAnswersReceived = 0;
}
/*}}}*/
@@ -593,8 +601,10 @@ int BaseHttpMethod::Loop()
Server->Close();
// Reset the pipeline
- if (Server->IsOpen() == false)
+ if (Server->IsOpen() == false) {
QueueBack = Queue;
+ Server->PipelineAnswersReceived = 0;
+ }
// Connect to the host
switch (Server->Open())
@@ -752,6 +762,10 @@ int BaseHttpMethod::Loop()
BeforeI = I;
}
}
+ if (Server->Pipeline == true)
+ {
+ Server->PipelineAnswersReceived++;
+ }
Res.TakeHashes(*resultHashes);
URIDone(Res);
}
@@ -861,9 +875,9 @@ unsigned long long BaseHttpMethod::FindMaximumObjectSizeInQueue() const /*{{{*/
return MaxSizeInQueue;
}
/*}}}*/
-BaseHttpMethod::BaseHttpMethod(std::string &&Binary, char const * const Ver,unsigned long const Flags) :/*{{{*/
- aptAuthConfMethod(std::move(Binary), Ver, Flags), Server(nullptr), PipelineDepth(10),
- AllowRedirect(false), Debug(false)
+BaseHttpMethod::BaseHttpMethod(std::string &&Binary, char const *const Ver, unsigned long const Flags) /*{{{*/
+ : aptAuthConfMethod(std::move(Binary), Ver, Flags), Server(nullptr),
+ AllowRedirect(false), Debug(false), PipelineDepth(10)
{
}
/*}}}*/
diff --git a/methods/basehttp.h b/methods/basehttp.h
index 8220c1b3c..5fdff69e0 100644
--- a/methods/basehttp.h
+++ b/methods/basehttp.h
@@ -67,6 +67,7 @@ struct ServerState
bool Persistent;
bool PipelineAllowed;
bool RangesAllowed;
+ unsigned long PipelineAnswersReceived;
bool Pipeline;
URI ServerName;
@@ -122,7 +123,6 @@ class BaseHttpMethod : public aptAuthConfMethod
std::unique_ptr<ServerState> Server;
std::string NextURI;
- unsigned long PipelineDepth;
bool AllowRedirect;
// Find the biggest item in the fetch queue for the checking of the maximum
@@ -131,6 +131,7 @@ class BaseHttpMethod : public aptAuthConfMethod
public:
bool Debug;
+ unsigned long PipelineDepth;
/** \brief Result of the header parsing */
enum DealWithHeadersResult {
diff --git a/methods/gpgv.cc b/methods/gpgv.cc
index 8de15c48a..84b8c3e59 100644
--- a/methods/gpgv.cc
+++ b/methods/gpgv.cc
@@ -94,7 +94,10 @@ struct Signer {
std::string note;
};
static bool IsTheSameKey(std::string const &validsig, std::string const &goodsig) {
- // VALIDSIG reports a keyid (40 = 24 + 16), GOODSIG is a longid (16) only
+ // VALIDSIG reports a fingerprint (40 = 24 + 16), GOODSIG can be longid (16) or
+ // fingerprint according to documentation in DETAILS.gz
+ if (goodsig.length() == 40 + strlen("GOODSIG "))
+ return validsig.compare(0, 40, goodsig, strlen("GOODSIG "), 40) == 0;
return validsig.compare(24, 16, goodsig, strlen("GOODSIG "), 16) == 0;
}
@@ -254,46 +257,32 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile,
if (keyIsID == true)
{
if (Debug == true)
- std::clog << "GoodSigs needs to be limited to keyid " << key << std::endl;
- bool foundGood = false;
- for (auto const &k: VectorizeString(key, ','))
+ std::clog << "GoodSigs needs to be limited to keyid(s) " << key << std::endl;
+ auto const limitedTo = VectorizeString(key, ',');
+ std::vector<std::string> filteredGood;
+ for (auto &&good: GoodSigners)
{
- if (std::find(ValidSigners.begin(), ValidSigners.end(), k) == ValidSigners.end())
- continue;
- // we look for GOODSIG here as well as an expired sig is a valid sig as well (but not a good one)
- std::string const goodfingerprint = "GOODSIG " + k;
- std::string const goodlongkeyid = "GOODSIG " + k.substr(24, 16);
- foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodfingerprint) != GoodSigners.end();
if (Debug == true)
- std::clog << "Key " << k << " is valid sig, is " << goodfingerprint << " also a good one? " << (foundGood ? "yes" : "no") << std::endl;
- std::string goodsig;
- if (foundGood == false)
+ std::clog << "Key " << good << " is good sig, is it also a valid and allowed one? ";
+ bool found = false;
+ for (auto const &l : limitedTo)
{
- foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodlongkeyid) != GoodSigners.end();
- if (Debug == true)
- std::clog << "Key " << k << " is valid sig, is " << goodlongkeyid << " also a good one? " << (foundGood ? "yes" : "no") << std::endl;
- goodsig = goodlongkeyid;
+ if (IsTheSameKey(l, good) == false)
+ continue;
+ // GOODSIG might be "just" a longid, so we check VALIDSIG which is always a fingerprint
+ if (std::find(ValidSigners.begin(), ValidSigners.end(), l) == ValidSigners.end())
+ continue;
+ found = true;
+ break;
}
+ if (Debug)
+ std::clog << (found ? "yes" : "no") << "\n";
+ if (found)
+ filteredGood.emplace_back(std::move(good));
else
- goodsig = goodfingerprint;
- if (foundGood == false)
- continue;
- std::copy(GoodSigners.begin(), GoodSigners.end(), std::back_insert_iterator<std::vector<std::string> >(NoPubKeySigners));
- GoodSigners.clear();
- GoodSigners.push_back(goodsig);
- NoPubKeySigners.erase(
- std::remove(NoPubKeySigners.begin(),
- std::remove(NoPubKeySigners.begin(), NoPubKeySigners.end(), goodfingerprint),
- goodlongkeyid),
- NoPubKeySigners.end()
- );
- break;
- }
- if (foundGood == false)
- {
- std::copy(GoodSigners.begin(), GoodSigners.end(), std::back_insert_iterator<std::vector<std::string> >(NoPubKeySigners));
- GoodSigners.clear();
+ NoPubKeySigners.emplace_back(std::move(good));
}
+ GoodSigners = std::move(filteredGood);
}
int status;