Fix leakage of a too big temporary file in HttpReader.
GitOrigin-RevId: b9bc7646013206fb30490cfb24e939eadb15e9c3
This commit is contained in:
parent
d8f66f8a8e
commit
692bc1f26d
@ -70,6 +70,7 @@ Result<size_t> HttpReader::read_next(HttpQuery *query) {
|
|||||||
if (state_ != ReadHeaders) {
|
if (state_ != ReadHeaders) {
|
||||||
flow_source_.wakeup();
|
flow_source_.wakeup();
|
||||||
if (flow_sink_.is_ready() && flow_sink_.status().is_error()) {
|
if (flow_sink_.is_ready() && flow_sink_.status().is_error()) {
|
||||||
|
clean_temporary_file();
|
||||||
return Status::Error(400, PSLICE() << "Bad Request: " << flow_sink_.status().message());
|
return Status::Error(400, PSLICE() << "Bad Request: " << flow_sink_.status().message());
|
||||||
}
|
}
|
||||||
need_size = flow_source_.get_need_size();
|
need_size = flow_source_.get_need_size();
|
||||||
@ -772,24 +773,26 @@ Status HttpReader::try_open_temp_file(Slice directory_name, CSlice desired_file_
|
|||||||
Status HttpReader::save_file_part(BufferSlice &&file_part) {
|
Status HttpReader::save_file_part(BufferSlice &&file_part) {
|
||||||
file_size_ += narrow_cast<int64>(file_part.size());
|
file_size_ += narrow_cast<int64>(file_part.size());
|
||||||
if (file_size_ > MAX_FILE_SIZE) {
|
if (file_size_ > MAX_FILE_SIZE) {
|
||||||
string file_name = temp_file_name_;
|
clean_temporary_file();
|
||||||
close_temp_file();
|
|
||||||
delete_temp_file(file_name);
|
|
||||||
return Status::Error(
|
return Status::Error(
|
||||||
413, PSLICE() << "Request Entity Too Large: file is too big to be uploaded " << tag("size", file_size_));
|
413, PSLICE() << "Request Entity Too Large: file of size " << file_size_ << " is too big to be uploaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(DEBUG) << "Save file part of size " << file_part.size() << " to file " << temp_file_name_;
|
LOG(DEBUG) << "Save file part of size " << file_part.size() << " to file " << temp_file_name_;
|
||||||
auto result_written = temp_file_.write(file_part.as_slice());
|
auto result_written = temp_file_.write(file_part.as_slice());
|
||||||
if (result_written.is_error() || result_written.ok() != file_part.size()) {
|
if (result_written.is_error() || result_written.ok() != file_part.size()) {
|
||||||
string file_name = temp_file_name_;
|
clean_temporary_file();
|
||||||
close_temp_file();
|
|
||||||
delete_temp_file(file_name);
|
|
||||||
return Status::Error(500, "Internal server error: can't upload the file");
|
return Status::Error(500, "Internal server error: can't upload the file");
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpReader::clean_temporary_file() {
|
||||||
|
string file_name = temp_file_name_;
|
||||||
|
close_temp_file();
|
||||||
|
delete_temp_file(file_name);
|
||||||
|
}
|
||||||
|
|
||||||
void HttpReader::close_temp_file() {
|
void HttpReader::close_temp_file() {
|
||||||
LOG(DEBUG) << "Close temporary file " << temp_file_name_;
|
LOG(DEBUG) << "Close temporary file " << temp_file_name_;
|
||||||
CHECK(!temp_file_.empty());
|
CHECK(!temp_file_.empty());
|
||||||
|
@ -96,6 +96,7 @@ class HttpReader {
|
|||||||
Status try_open_temp_file(Slice directory_name, CSlice desired_file_name) TD_WARN_UNUSED_RESULT;
|
Status try_open_temp_file(Slice directory_name, CSlice desired_file_name) TD_WARN_UNUSED_RESULT;
|
||||||
Status save_file_part(BufferSlice &&file_part) TD_WARN_UNUSED_RESULT;
|
Status save_file_part(BufferSlice &&file_part) TD_WARN_UNUSED_RESULT;
|
||||||
void close_temp_file();
|
void close_temp_file();
|
||||||
|
void clean_temporary_file();
|
||||||
|
|
||||||
static constexpr size_t MAX_CONTENT_SIZE = 150 << 20; // Some reasonable limit
|
static constexpr size_t MAX_CONTENT_SIZE = 150 << 20; // Some reasonable limit
|
||||||
static constexpr size_t MAX_TOTAL_PARAMETERS_LENGTH = 1 << 16; // Some reasonable limit
|
static constexpr size_t MAX_TOTAL_PARAMETERS_LENGTH = 1 << 16; // Some reasonable limit
|
||||||
|
Loading…
Reference in New Issue
Block a user