aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mod/mod-build-result.cxx37
-rw-r--r--mod/mod-build-task.cxx6
2 files changed, 38 insertions, 5 deletions
diff --git a/mod/mod-build-result.cxx b/mod/mod-build-result.cxx
index be0075b..9f6455a 100644
--- a/mod/mod-build-result.cxx
+++ b/mod/mod-build-result.cxx
@@ -99,11 +99,12 @@ handle (request& rq, response&)
throw invalid_request (400, e.what ());
}
- // Parse the task response session to obtain the build configuration name,
- // and to make sure the session matches the result manifest's package name
- // and version.
+ // Parse the task response session to obtain the build configuration name and
+ // the timestamp, and to make sure the session matches the result manifest's
+ // package name and version.
//
build_id id;
+ timestamp session_timestamp;
try
{
@@ -144,10 +145,36 @@ handle (request& rq, response&)
if (version != rqm.result.version)
throw invalid_argument ("package version mismatch");
- id = build_id (package_id (move (name), version), string (s, p + 1));
+ b = p + 1; // Start of configuration name.
+ p = s.find ('/', b); // End of configuration name.
+
+ if (p == string::npos)
+ throw invalid_argument ("no timestamp");
+
+ id = build_id (package_id (move (name), version), string (s, b, p - b));
if (id.configuration.empty ())
throw invalid_argument ("empty configuration name");
+
+ try
+ {
+ size_t tsn;
+ string ts (s, p + 1);
+
+ session_timestamp = timestamp (
+ chrono::duration_cast<timestamp::duration> (
+ chrono::nanoseconds (stoull (ts, &tsn))));
+
+ if (tsn != ts.size ())
+ throw invalid_argument ("trailing junk");
+ }
+ // Handle invalid_argument or out_of_range (both derive from logic_error),
+ // that can be thrown by stoull().
+ //
+ catch (const logic_error& e)
+ {
+ throw invalid_argument (string ("invalid timestamp: ") + e.what ());
+ }
}
catch (const invalid_argument& e)
{
@@ -206,6 +233,8 @@ handle (request& rq, response&)
warn_expired ("no package configuration");
else if (b->state != build_state::testing)
warn_expired ("package configuration state is " + to_string (b->state));
+ else if (b->timestamp != session_timestamp)
+ warn_expired ("non-matching timestamp");
else
{
// Don's send email for the success-to-success status change, unless the
diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx
index 1466077..63ea327 100644
--- a/mod/mod-build-task.cxx
+++ b/mod/mod-build-task.cxx
@@ -149,8 +149,12 @@ handle (request& rq, response& rs)
shared_ptr<package>&& p,
const config_machine& cm) -> task_response_manifest
{
+ uint64_t ts (
+ chrono::duration_cast<std::chrono::nanoseconds> (
+ b->timestamp.time_since_epoch ()).count ());
+
string session (b->package_name + '/' + b->package_version.string () +
- '/' + b->configuration);
+ '/' + b->configuration + '/' + to_string (ts));
string result_url (options_->host () + options_->root ().string () +
"?build-result");