mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
Use a FileReaderInterface for file attachments instead of a FilePath
This is a step towards a database which gives out FileReaders in Report objects instead of FilePaths. Change-Id: I59704da65fc5521e5d47019416bf962c215d13bc Reviewed-on: https://chromium-review.googlesource.com/721978 Commit-Queue: Joshua Peraza <jperaza@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
4d7a07f684
commit
68a0e736c6
@ -70,7 +70,7 @@ void InsertOrReplaceMapEntry(std::map<std::string, std::string>* map,
|
|||||||
//
|
//
|
||||||
// In the event of an error reading the minidump file, a message will be logged.
|
// In the event of an error reading the minidump file, a message will be logged.
|
||||||
std::map<std::string, std::string> BreakpadHTTPFormParametersFromMinidump(
|
std::map<std::string, std::string> BreakpadHTTPFormParametersFromMinidump(
|
||||||
FileReader* minidump_file_reader) {
|
FileReaderInterface* minidump_file_reader) {
|
||||||
ProcessSnapshotMinidump minidump_process_snapshot;
|
ProcessSnapshotMinidump minidump_process_snapshot;
|
||||||
if (!minidump_process_snapshot.Initialize(minidump_file_reader)) {
|
if (!minidump_process_snapshot.Initialize(minidump_file_reader)) {
|
||||||
return std::map<std::string, std::string>();
|
return std::map<std::string, std::string>();
|
||||||
@ -344,18 +344,25 @@ CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport(
|
|||||||
std::string* response_body) {
|
std::string* response_body) {
|
||||||
std::map<std::string, std::string> parameters;
|
std::map<std::string, std::string> parameters;
|
||||||
|
|
||||||
{
|
FileReader minidump_file_reader;
|
||||||
FileReader minidump_file_reader;
|
if (!minidump_file_reader.Open(report->file_path)) {
|
||||||
if (!minidump_file_reader.Open(report->file_path)) {
|
// If the minidump file can’t be opened, all hope is lost.
|
||||||
// If the minidump file can’t be opened, all hope is lost.
|
return UploadResult::kPermanentFailure;
|
||||||
return UploadResult::kPermanentFailure;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the minidump file could be opened, ignore any errors that might occur
|
FileOffset start_offset = minidump_file_reader.SeekGet();
|
||||||
// when attempting to interpret it. This may result in its being uploaded
|
if (start_offset < 0) {
|
||||||
// with few or no parameters, but as long as there’s a dump file, the server
|
return UploadResult::kPermanentFailure;
|
||||||
// can decide what to do with it.
|
}
|
||||||
parameters = BreakpadHTTPFormParametersFromMinidump(&minidump_file_reader);
|
|
||||||
|
// Ignore any errors that might occur when attempting to interpret the
|
||||||
|
// minidump file. This may result in its being uploaded with few or no
|
||||||
|
// parameters, but as long as there’s a dump file, the server can decide what
|
||||||
|
// to do with it.
|
||||||
|
parameters = BreakpadHTTPFormParametersFromMinidump(&minidump_file_reader);
|
||||||
|
|
||||||
|
if (!minidump_file_reader.SeekSet(start_offset)) {
|
||||||
|
return UploadResult::kPermanentFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPMultipartBuilder http_multipart_builder;
|
HTTPMultipartBuilder http_multipart_builder;
|
||||||
@ -379,7 +386,7 @@ CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport(
|
|||||||
#else
|
#else
|
||||||
report->file_path.BaseName().value(),
|
report->file_path.BaseName().value(),
|
||||||
#endif
|
#endif
|
||||||
report->file_path,
|
&minidump_file_reader,
|
||||||
"application/octet-stream");
|
"application/octet-stream");
|
||||||
|
|
||||||
std::unique_ptr<HTTPTransport> http_transport(HTTPTransport::Create());
|
std::unique_ptr<HTTPTransport> http_transport(HTTPTransport::Create());
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "tools/tool_support.h"
|
#include "tools/tool_support.h"
|
||||||
|
#include "util/file/file_reader.h"
|
||||||
#include "util/file/file_writer.h"
|
#include "util/file/file_writer.h"
|
||||||
#include "util/net/http_body.h"
|
#include "util/net/http_body.h"
|
||||||
#include "util/net/http_multipart_builder.h"
|
#include "util/net/http_multipart_builder.h"
|
||||||
@ -85,6 +87,7 @@ int HTTPUploadMain(int argc, char* argv[]) {
|
|||||||
{nullptr, 0, nullptr, 0},
|
{nullptr, 0, nullptr, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<FileReader>> readers;
|
||||||
HTTPMultipartBuilder http_multipart_builder;
|
HTTPMultipartBuilder http_multipart_builder;
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
@ -102,8 +105,14 @@ int HTTPUploadMain(int argc, char* argv[]) {
|
|||||||
ToolSupport::CommandLineArgumentToFilePathStringType(path));
|
ToolSupport::CommandLineArgumentToFilePathStringType(path));
|
||||||
std::string file_name(
|
std::string file_name(
|
||||||
ToolSupport::FilePathToCommandLineArgument(file_path.BaseName()));
|
ToolSupport::FilePathToCommandLineArgument(file_path.BaseName()));
|
||||||
|
|
||||||
|
readers.push_back(std::make_unique<FileReader>());
|
||||||
|
FileReader* upload_file_reader = readers.back().get();
|
||||||
|
if (!upload_file_reader->Open(file_path)) {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
http_multipart_builder.SetFileAttachment(
|
http_multipart_builder.SetFileAttachment(
|
||||||
key, file_name, file_path, "application/octet-stream");
|
key, file_name, upload_file_reader, "application/octet-stream");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kOptionNoUploadGzip: {
|
case kOptionNoUploadGzip: {
|
||||||
|
@ -46,38 +46,22 @@ FileOperationResult StringHTTPBodyStream::GetBytesBuffer(uint8_t* buffer,
|
|||||||
return num_bytes_returned;
|
return num_bytes_returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHTTPBodyStream::FileHTTPBodyStream(const base::FilePath& path)
|
FileReaderHTTPBodyStream::FileReaderHTTPBodyStream(FileReaderInterface* reader)
|
||||||
: HTTPBodyStream(), path_(path), file_(), file_state_(kUnopenedFile) {
|
: HTTPBodyStream(), reader_(reader), reached_eof_(false) {
|
||||||
|
DCHECK(reader_);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHTTPBodyStream::~FileHTTPBodyStream() {
|
FileReaderHTTPBodyStream::~FileReaderHTTPBodyStream() {}
|
||||||
}
|
|
||||||
|
|
||||||
FileOperationResult FileHTTPBodyStream::GetBytesBuffer(uint8_t* buffer,
|
FileOperationResult FileReaderHTTPBodyStream::GetBytesBuffer(uint8_t* buffer,
|
||||||
size_t max_len) {
|
size_t max_len) {
|
||||||
switch (file_state_) {
|
if (reached_eof_) {
|
||||||
case kUnopenedFile:
|
return 0;
|
||||||
file_.reset(LoggingOpenFileForRead(path_));
|
|
||||||
if (!file_.is_valid()) {
|
|
||||||
file_state_ = kFileOpenError;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
file_state_ = kReading;
|
|
||||||
break;
|
|
||||||
case kFileOpenError:
|
|
||||||
return -1;
|
|
||||||
case kClosedAtEOF:
|
|
||||||
return 0;
|
|
||||||
case kReading:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOperationResult rv = ReadFile(file_.get(), buffer, max_len);
|
FileOperationResult rv = reader_->Read(buffer, max_len);
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
file_.reset();
|
reached_eof_ = true;
|
||||||
file_state_ = kClosedAtEOF;
|
|
||||||
} else if (rv < 0) {
|
|
||||||
PLOG(ERROR) << "read";
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "util/file/file_io.h"
|
#include "util/file/file_io.h"
|
||||||
|
#include "util/file/file_reader.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
@ -70,33 +71,26 @@ class StringHTTPBodyStream : public HTTPBodyStream {
|
|||||||
DISALLOW_COPY_AND_ASSIGN(StringHTTPBodyStream);
|
DISALLOW_COPY_AND_ASSIGN(StringHTTPBodyStream);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief An implementation of HTTPBodyStream that reads from the specified
|
//! \brief An implementation of HTTPBodyStream that reads from a
|
||||||
//! file and provides its contents for an HTTP body.
|
//! FileReaderInterface and provides its contents for an HTTP body.
|
||||||
class FileHTTPBodyStream : public HTTPBodyStream {
|
class FileReaderHTTPBodyStream : public HTTPBodyStream {
|
||||||
public:
|
public:
|
||||||
//! \brief Creates a stream for reading the file at the specified \a path.
|
//! \brief Creates a stream for reading from a FileReaderInterface.
|
||||||
//!
|
//!
|
||||||
//! \param[in] path The file from which this HTTPBodyStream will read.
|
//! \param[in] reader A FileReaderInterface from which this HTTPBodyStream
|
||||||
explicit FileHTTPBodyStream(const base::FilePath& path);
|
//! will read.
|
||||||
|
explicit FileReaderHTTPBodyStream(FileReaderInterface* reader);
|
||||||
|
|
||||||
~FileHTTPBodyStream() override;
|
~FileReaderHTTPBodyStream() override;
|
||||||
|
|
||||||
// HTTPBodyStream:
|
// HTTPBodyStream:
|
||||||
FileOperationResult GetBytesBuffer(uint8_t* buffer, size_t max_len) override;
|
FileOperationResult GetBytesBuffer(uint8_t* buffer, size_t max_len) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum FileState {
|
FileReaderInterface* reader_; // weak
|
||||||
kUnopenedFile,
|
bool reached_eof_;
|
||||||
kFileOpenError,
|
|
||||||
kClosedAtEOF,
|
|
||||||
kReading,
|
|
||||||
};
|
|
||||||
|
|
||||||
base::FilePath path_;
|
DISALLOW_COPY_AND_ASSIGN(FileReaderHTTPBodyStream);
|
||||||
ScopedFileHandle file_;
|
|
||||||
FileState file_state_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(FileHTTPBodyStream);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief An implementation of HTTPBodyStream that combines an array of
|
//! \brief An implementation of HTTPBodyStream that combines an array of
|
||||||
|
@ -96,10 +96,13 @@ TEST(StringHTTPBodyStream, MultipleReads) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FileHTTPBodyStream, ReadASCIIFile) {
|
TEST(FileReaderHTTPBodyStream, ReadASCIIFile) {
|
||||||
base::FilePath path = TestPaths::TestDataRoot().Append(
|
base::FilePath path = TestPaths::TestDataRoot().Append(
|
||||||
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
||||||
FileHTTPBodyStream stream(path);
|
|
||||||
|
FileReader reader;
|
||||||
|
ASSERT_TRUE(reader.Open(path));
|
||||||
|
FileReaderHTTPBodyStream stream(&reader);
|
||||||
std::string contents = ReadStreamToString(&stream, 32);
|
std::string contents = ReadStreamToString(&stream, 32);
|
||||||
EXPECT_EQ(contents, "This is a test.\n");
|
EXPECT_EQ(contents, "This is a test.\n");
|
||||||
|
|
||||||
@ -113,14 +116,16 @@ TEST(FileHTTPBodyStream, ReadASCIIFile) {
|
|||||||
ExpectBufferSet(buf, '!', sizeof(buf));
|
ExpectBufferSet(buf, '!', sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FileHTTPBodyStream, ReadBinaryFile) {
|
TEST(FileReaderHTTPBodyStream, ReadBinaryFile) {
|
||||||
// HEX contents of file: |FEEDFACE A11A15|.
|
// HEX contents of file: |FEEDFACE A11A15|.
|
||||||
base::FilePath path = TestPaths::TestDataRoot().Append(
|
base::FilePath path = TestPaths::TestDataRoot().Append(
|
||||||
FILE_PATH_LITERAL("util/net/testdata/binary_http_body.dat"));
|
FILE_PATH_LITERAL("util/net/testdata/binary_http_body.dat"));
|
||||||
// This buffer size was chosen so that reading the file takes multiple reads.
|
// This buffer size was chosen so that reading the file takes multiple reads.
|
||||||
uint8_t buf[4];
|
uint8_t buf[4];
|
||||||
|
|
||||||
FileHTTPBodyStream stream(path);
|
FileReader reader;
|
||||||
|
ASSERT_TRUE(reader.Open(path));
|
||||||
|
FileReaderHTTPBodyStream stream(&reader);
|
||||||
|
|
||||||
memset(buf, '!', sizeof(buf));
|
memset(buf, '!', sizeof(buf));
|
||||||
EXPECT_EQ(stream.GetBytesBuffer(buf, sizeof(buf)), 4);
|
EXPECT_EQ(stream.GetBytesBuffer(buf, sizeof(buf)), 4);
|
||||||
@ -143,18 +148,6 @@ TEST(FileHTTPBodyStream, ReadBinaryFile) {
|
|||||||
ExpectBufferSet(buf, '!', sizeof(buf));
|
ExpectBufferSet(buf, '!', sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FileHTTPBodyStream, NonExistentFile) {
|
|
||||||
base::FilePath path = base::FilePath(
|
|
||||||
FILE_PATH_LITERAL("/var/empty/crashpad/util/net/http_body/null"));
|
|
||||||
FileHTTPBodyStream stream(path);
|
|
||||||
|
|
||||||
uint8_t buf = 0xff;
|
|
||||||
EXPECT_LT(stream.GetBytesBuffer(&buf, 1), 0);
|
|
||||||
EXPECT_EQ(buf, 0xff);
|
|
||||||
EXPECT_LT(stream.GetBytesBuffer(&buf, 1), 0);
|
|
||||||
EXPECT_EQ(buf, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(CompositeHTTPBodyStream, TwoEmptyStrings) {
|
TEST(CompositeHTTPBodyStream, TwoEmptyStrings) {
|
||||||
std::vector<HTTPBodyStream*> parts;
|
std::vector<HTTPBodyStream*> parts;
|
||||||
parts.push_back(new StringHTTPBodyStream(std::string()));
|
parts.push_back(new StringHTTPBodyStream(std::string()));
|
||||||
@ -201,7 +194,10 @@ TEST_P(CompositeHTTPBodyStreamBufferSize, StringsAndFile) {
|
|||||||
parts.push_back(new StringHTTPBodyStream(string1));
|
parts.push_back(new StringHTTPBodyStream(string1));
|
||||||
base::FilePath path = TestPaths::TestDataRoot().Append(
|
base::FilePath path = TestPaths::TestDataRoot().Append(
|
||||||
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
||||||
parts.push_back(new FileHTTPBodyStream(path));
|
|
||||||
|
FileReader reader;
|
||||||
|
ASSERT_TRUE(reader.Open(path));
|
||||||
|
parts.push_back(new FileReaderHTTPBodyStream(&reader));
|
||||||
parts.push_back(new StringHTTPBodyStream(string2));
|
parts.push_back(new StringHTTPBodyStream(string2));
|
||||||
|
|
||||||
CompositeHTTPBodyStream stream(parts);
|
CompositeHTTPBodyStream stream(parts);
|
||||||
|
@ -133,13 +133,13 @@ void HTTPMultipartBuilder::SetFormData(const std::string& key,
|
|||||||
void HTTPMultipartBuilder::SetFileAttachment(
|
void HTTPMultipartBuilder::SetFileAttachment(
|
||||||
const std::string& key,
|
const std::string& key,
|
||||||
const std::string& upload_file_name,
|
const std::string& upload_file_name,
|
||||||
const base::FilePath& path,
|
FileReaderInterface* reader,
|
||||||
const std::string& content_type) {
|
const std::string& content_type) {
|
||||||
EraseKey(upload_file_name);
|
EraseKey(upload_file_name);
|
||||||
|
|
||||||
FileAttachment attachment;
|
FileAttachment attachment;
|
||||||
attachment.filename = EncodeMIMEField(upload_file_name);
|
attachment.filename = EncodeMIMEField(upload_file_name);
|
||||||
attachment.path = path;
|
attachment.reader = reader;
|
||||||
|
|
||||||
if (content_type.empty()) {
|
if (content_type.empty()) {
|
||||||
attachment.content_type = "application/octet-stream";
|
attachment.content_type = "application/octet-stream";
|
||||||
@ -174,7 +174,7 @@ std::unique_ptr<HTTPBodyStream> HTTPMultipartBuilder::GetBodyStream() {
|
|||||||
attachment.content_type.c_str(), kBoundaryCRLF);
|
attachment.content_type.c_str(), kBoundaryCRLF);
|
||||||
|
|
||||||
streams.push_back(new StringHTTPBodyStream(header));
|
streams.push_back(new StringHTTPBodyStream(header));
|
||||||
streams.push_back(new FileHTTPBodyStream(attachment.path));
|
streams.push_back(new FileReaderHTTPBodyStream(attachment.reader));
|
||||||
streams.push_back(new StringHTTPBodyStream(kCRLF));
|
streams.push_back(new StringHTTPBodyStream(kCRLF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/files/file_path.h"
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "util/file/file_reader.h"
|
||||||
#include "util/net/http_headers.h"
|
#include "util/net/http_headers.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
@ -51,7 +51,7 @@ class HTTPMultipartBuilder {
|
|||||||
//! \param[in] value The value to set at the \a key.
|
//! \param[in] value The value to set at the \a key.
|
||||||
void SetFormData(const std::string& key, const std::string& value);
|
void SetFormData(const std::string& key, const std::string& value);
|
||||||
|
|
||||||
//! \brief Specifies the file at \a path to have its contents uploaded as
|
//! \brief Specifies the contents read from \a reader to be uploaded as
|
||||||
//! multipart data, available at `name` of \a upload_file_name.
|
//! multipart data, available at `name` of \a upload_file_name.
|
||||||
//!
|
//!
|
||||||
//! \param[in] key The key of the form data, specified as the `name` in the
|
//! \param[in] key The key of the form data, specified as the `name` in the
|
||||||
@ -59,12 +59,13 @@ class HTTPMultipartBuilder {
|
|||||||
//! key will be overwritten.
|
//! key will be overwritten.
|
||||||
//! \param[in] upload_file_name The `filename` to specify for this multipart
|
//! \param[in] upload_file_name The `filename` to specify for this multipart
|
||||||
//! data attachment.
|
//! data attachment.
|
||||||
//! \param[in] path The path of the file whose contents will be uploaded.
|
//! \param[in] reader A FileReaderInterface from which to read the content to
|
||||||
|
//! upload.
|
||||||
//! \param[in] content_type The `Content-Type` to specify for the attachment.
|
//! \param[in] content_type The `Content-Type` to specify for the attachment.
|
||||||
//! If this is empty, `"application/octet-stream"` will be used.
|
//! If this is empty, `"application/octet-stream"` will be used.
|
||||||
void SetFileAttachment(const std::string& key,
|
void SetFileAttachment(const std::string& key,
|
||||||
const std::string& upload_file_name,
|
const std::string& upload_file_name,
|
||||||
const base::FilePath& path,
|
FileReaderInterface* reader,
|
||||||
const std::string& content_type);
|
const std::string& content_type);
|
||||||
|
|
||||||
//! \brief Generates the HTTPBodyStream for the data currently supplied to
|
//! \brief Generates the HTTPBodyStream for the data currently supplied to
|
||||||
@ -83,7 +84,7 @@ class HTTPMultipartBuilder {
|
|||||||
struct FileAttachment {
|
struct FileAttachment {
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string content_type;
|
std::string content_type;
|
||||||
base::FilePath path;
|
FileReaderInterface* reader;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Removes elements from both data maps at the specified |key|, to ensure
|
// Removes elements from both data maps at the specified |key|, to ensure
|
||||||
|
@ -102,18 +102,19 @@ TEST(HTTPMultipartBuilder, ThreeFileAttachments) {
|
|||||||
HTTPMultipartBuilder builder;
|
HTTPMultipartBuilder builder;
|
||||||
base::FilePath ascii_http_body_path = TestPaths::TestDataRoot().Append(
|
base::FilePath ascii_http_body_path = TestPaths::TestDataRoot().Append(
|
||||||
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
||||||
builder.SetFileAttachment("first",
|
|
||||||
"minidump.dmp",
|
FileReader reader1;
|
||||||
ascii_http_body_path,
|
ASSERT_TRUE(reader1.Open(ascii_http_body_path));
|
||||||
"");
|
builder.SetFileAttachment("first", "minidump.dmp", &reader1, "");
|
||||||
builder.SetFileAttachment("second",
|
|
||||||
"minidump.dmp",
|
FileReader reader2;
|
||||||
ascii_http_body_path,
|
ASSERT_TRUE(reader2.Open(ascii_http_body_path));
|
||||||
"text/plain");
|
builder.SetFileAttachment("second", "minidump.dmp", &reader2, "text/plain");
|
||||||
builder.SetFileAttachment("\"third 50% silly\"",
|
|
||||||
"test%foo.txt",
|
FileReader reader3;
|
||||||
ascii_http_body_path,
|
ASSERT_TRUE(reader3.Open(ascii_http_body_path));
|
||||||
"text/plain");
|
builder.SetFileAttachment(
|
||||||
|
"\"third 50% silly\"", "test%foo.txt", &reader3, "text/plain");
|
||||||
|
|
||||||
static constexpr char kFileContents[] = "This is a test.\n";
|
static constexpr char kFileContents[] = "This is a test.\n";
|
||||||
|
|
||||||
@ -187,21 +188,22 @@ TEST(HTTPMultipartBuilder, OverwriteFileAttachment) {
|
|||||||
builder.SetFormData("a key", kValue);
|
builder.SetFormData("a key", kValue);
|
||||||
base::FilePath testdata_path =
|
base::FilePath testdata_path =
|
||||||
TestPaths::TestDataRoot().Append(FILE_PATH_LITERAL("util/net/testdata"));
|
TestPaths::TestDataRoot().Append(FILE_PATH_LITERAL("util/net/testdata"));
|
||||||
builder.SetFileAttachment("minidump",
|
|
||||||
"minidump.dmp",
|
FileReader reader1;
|
||||||
testdata_path.Append(FILE_PATH_LITERAL(
|
ASSERT_TRUE(reader1.Open(
|
||||||
"binary_http_body.dat")),
|
testdata_path.Append(FILE_PATH_LITERAL("binary_http_body.dat"))));
|
||||||
"");
|
builder.SetFileAttachment("minidump", "minidump.dmp", &reader1, "");
|
||||||
builder.SetFileAttachment("minidump2",
|
|
||||||
"minidump.dmp",
|
FileReader reader2;
|
||||||
testdata_path.Append(FILE_PATH_LITERAL(
|
ASSERT_TRUE(reader2.Open(
|
||||||
"binary_http_body.dat")),
|
testdata_path.Append(FILE_PATH_LITERAL("binary_http_body.dat"))));
|
||||||
"");
|
builder.SetFileAttachment("minidump2", "minidump.dmp", &reader2, "");
|
||||||
builder.SetFileAttachment("minidump",
|
|
||||||
"minidump.dmp",
|
FileReader reader3;
|
||||||
testdata_path.Append(FILE_PATH_LITERAL(
|
ASSERT_TRUE(reader3.Open(
|
||||||
"ascii_http_body.txt")),
|
testdata_path.Append(FILE_PATH_LITERAL("ascii_http_body.txt"))));
|
||||||
"text/plain");
|
builder.SetFileAttachment("minidump", "minidump.dmp", &reader3, "text/plain");
|
||||||
|
|
||||||
std::unique_ptr<HTTPBodyStream> body(builder.GetBodyStream());
|
std::unique_ptr<HTTPBodyStream> body(builder.GetBodyStream());
|
||||||
ASSERT_TRUE(body.get());
|
ASSERT_TRUE(body.get());
|
||||||
std::string contents = ReadStreamToString(body.get());
|
std::string contents = ReadStreamToString(body.get());
|
||||||
@ -244,10 +246,10 @@ TEST(HTTPMultipartBuilder, SharedFormDataAndAttachmentKeyNamespace) {
|
|||||||
builder.SetFormData("one", kValue1);
|
builder.SetFormData("one", kValue1);
|
||||||
base::FilePath ascii_http_body_path = TestPaths::TestDataRoot().Append(
|
base::FilePath ascii_http_body_path = TestPaths::TestDataRoot().Append(
|
||||||
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
|
||||||
builder.SetFileAttachment("minidump",
|
|
||||||
"minidump.dmp",
|
FileReader reader;
|
||||||
ascii_http_body_path,
|
ASSERT_TRUE(reader.Open(ascii_http_body_path));
|
||||||
"");
|
builder.SetFileAttachment("minidump", "minidump.dmp", &reader, "");
|
||||||
static constexpr char kValue2[] = "this is not a file";
|
static constexpr char kValue2[] = "this is not a file";
|
||||||
builder.SetFormData("minidump", kValue2);
|
builder.SetFormData("minidump", kValue2);
|
||||||
|
|
||||||
@ -278,19 +280,16 @@ TEST(HTTPMultipartBuilder, SharedFormDataAndAttachmentKeyNamespace) {
|
|||||||
|
|
||||||
TEST(HTTPMultipartBuilderDeathTest, AssertUnsafeMIMEType) {
|
TEST(HTTPMultipartBuilderDeathTest, AssertUnsafeMIMEType) {
|
||||||
HTTPMultipartBuilder builder;
|
HTTPMultipartBuilder builder;
|
||||||
|
FileReader reader;
|
||||||
// Invalid and potentially dangerous:
|
// Invalid and potentially dangerous:
|
||||||
ASSERT_DEATH_CHECK(
|
ASSERT_DEATH_CHECK(builder.SetFileAttachment("", "", &reader, "\r\n"), "");
|
||||||
builder.SetFileAttachment("", "", base::FilePath(), "\r\n"), "");
|
ASSERT_DEATH_CHECK(builder.SetFileAttachment("", "", &reader, "\""), "");
|
||||||
ASSERT_DEATH_CHECK(
|
ASSERT_DEATH_CHECK(builder.SetFileAttachment("", "", &reader, "\x12"), "");
|
||||||
builder.SetFileAttachment("", "", base::FilePath(), "\""), "");
|
ASSERT_DEATH_CHECK(builder.SetFileAttachment("", "", &reader, "<>"), "");
|
||||||
ASSERT_DEATH_CHECK(
|
|
||||||
builder.SetFileAttachment("", "", base::FilePath(), "\x12"), "");
|
|
||||||
ASSERT_DEATH_CHECK(
|
|
||||||
builder.SetFileAttachment("", "", base::FilePath(), "<>"), "");
|
|
||||||
// Invalid but safe:
|
// Invalid but safe:
|
||||||
builder.SetFileAttachment("", "", base::FilePath(), "0/totally/-invalid.pdf");
|
builder.SetFileAttachment("", "", &reader, "0/totally/-invalid.pdf");
|
||||||
// Valid and safe:
|
// Valid and safe:
|
||||||
builder.SetFileAttachment("", "", base::FilePath(), "application/xml+xhtml");
|
builder.SetFileAttachment("", "", &reader, "application/xml+xhtml");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user