diff options
Diffstat (limited to 'mod')
-rw-r--r-- | mod/mod-build-result.cxx | 37 | ||||
-rw-r--r-- | mod/mod-build-task.cxx | 6 |
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"); |