crashpad/handler/crash_report_upload_thread.h
Mark Mentovai 0c322ecc3f Use zlib to gzip-compress uploads
This adds zlib to Crashpad. By default in standalone Crashpad builds,
the system zlib will be used where available. A copy of Chromium’s zlib
(currently a slightly patched 1.2.11) is checked out via DEPS into
third_party for use on Windows, which does not have a system zlib.

zlib is used to produce gzip streams for HTTP upload request bodies sent
by crashpad_handler by default. The Content-Encoding: gzip header is set
for these compressed request bodies. Compression can be disabled for
upload to servers without corresponding decompression support by
starting crashpad_handler with the --no-upload-gzip option.

Most minidumps compress quite well with zlib. A size reduction of 90% is
not uncommon.

BUG=crashpad:157
TEST=crashpad_util_test GzipHTTPBodyStream.*:HTTPTransport.*

Change-Id: I99b86db3952c3685cd78f5dc858a60b54399c513
Reviewed-on: https://chromium-review.googlesource.com/438585
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-02-16 16:26:19 +00:00

152 lines
6.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_
#define CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "client/crash_report_database.h"
#include "util/thread/worker_thread.h"
namespace crashpad {
//! \brief A thread that processes pending crash reports in a
//! CrashReportDatabase by uploading them or marking them as completed
//! without upload, as desired.
//!
//! A producer of crash reports should notify an object of this class that a new
//! report has been added to the database by calling ReportPending().
//!
//! Independently of being triggered by ReportPending(), objects of this class
//! periodically examine the database for pending reports. This allows failed
//! upload attempts for reports left in the pending state to be retried. It also
//! catches reports that are added without a ReportPending() signal being
//! caught. This may happen if crash reports are added to the database by other
//! processes.
class CrashReportUploadThread : public WorkerThread::Delegate {
public:
//! \brief Constructs a new object.
//!
//! \param[in] database The database to upload crash reports from.
//! \param[in] url The URL of the server to upload crash reports to.
//! \param[in] rate_limit Whether uploads should be throttled to a (currently
//! hardcoded) rate.
//! \param[in] upload_gzip Whether uploads should use `gzip` compression.
CrashReportUploadThread(CrashReportDatabase* database,
const std::string& url,
bool rate_limit,
bool upload_gzip);
~CrashReportUploadThread();
//! \brief Starts a dedicated upload thread, which executes ThreadMain().
//!
//! This method may only be be called on a newly-constructed object or after
//! a call to Stop().
void Start();
//! \brief Stops the upload thread.
//!
//! The upload thread will terminate after completing whatever task it is
//! performing. If it is not performing any task, it will terminate
//! immediately. This method blocks while waiting for the upload thread to
//! terminate.
//!
//! This method must only be called after Start(). If Start() has been called,
//! this method must be called before destroying an object of this class.
//!
//! This method may be called from any thread other than the upload thread.
//! It is expected to only be called from the same thread that called Start().
void Stop();
//! \brief Informs the upload thread that a new pending report has been added
//! to the database.
//!
//! This method may be called from any thread.
void ReportPending();
private:
//! \brief The result code from UploadReport().
enum class UploadResult {
//! \brief The crash report was uploaded successfully.
kSuccess,
//! \brief The crash report upload failed in such a way that recovery is
//! impossible.
//!
//! No further upload attempts should be made for the report.
kPermanentFailure,
//! \brief The crash report upload failed, but it might succeed again if
//! retried in the future.
//!
//! If the report has not already been retried too many times, the caller
//! may arrange to call UploadReport() for the report again in the future,
//! after a suitable delay.
kRetry,
};
//! \brief Obtains all pending reports from the database, and calls
//! ProcessPendingReport() to process each one.
void ProcessPendingReports();
//! \brief Processes a single pending report from the database.
//!
//! \param[in] report The crash report to process.
//!
//! If report upload is enabled, this method attempts to upload \a report by
//! calling UplaodReport(). If the upload is successful, the report will be
//! marked as “completed” in the database. If the upload fails and more
//! retries are desired, the reports upload-attempt count and
//! last-upload-attempt time will be updated in the database and it will
//! remain in the “pending” state. If the upload fails and no more retries are
//! desired, or report upload is disabled, it will be marked as “completed” in
//! the database without ever having been uploaded.
void ProcessPendingReport(const CrashReportDatabase::Report& report);
//! \brief Attempts to upload a crash report.
//!
//! \param[in] report The report to upload. The caller is responsible for
//! calling CrashReportDatabase::GetReportForUploading() before calling
//! this method, and for calling
//! CrashReportDatabase::RecordUploadAttempt() after calling this method.
//! \param[out] response_body If the upload attempt is successful, this will
//! be set to the response body sent by the server. Breakpad-type servers
//! provide the crash ID assigned by the server in the response body.
//!
//! \return A member of UploadResult indicating the result of the upload
//! attempt.
UploadResult UploadReport(const CrashReportDatabase::Report* report,
std::string* response_body);
// WorkerThread::Delegate:
//! \brief Calls ProcessPendingReports() in response to ReportPending() having
//! been called on any thread, as well as periodically on a timer.
void DoWork(const WorkerThread* thread) override;
std::string url_;
WorkerThread thread_;
CrashReportDatabase* database_; // weak
bool rate_limit_;
bool upload_gzip_;
DISALLOW_COPY_AND_ASSIGN(CrashReportUploadThread);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_