A lot of file transfer updates

This commit is contained in:
WolverinDEV
2020-05-13 11:32:08 +02:00
parent 1a2dd4a008
commit 90b1646876
45 changed files with 1989 additions and 2806 deletions
+28 -39
View File
@@ -452,6 +452,7 @@ void LocalFileTransfer::callback_transfer_network_read(int fd, short events, voi
const auto max_read_buffer = transfer->networking.throttle.bytes_left();
if(!max_read_buffer) break; /* network throttle */
errno = 0;
auto read = ::recv(fd, buffer, std::min(buffer_size, std::min(max_read_buffer, transfer->networking.max_read_buffer_size)), MSG_NOSIGNAL | MSG_DONTWAIT);
//logTrace(0, "Read {}, max {} | {}", read, std::min(buffer_size, std::min(max_read_buffer, transfer->networking.max_read_buffer_size)), max_read_buffer);
if(read <= 0) {
@@ -471,10 +472,10 @@ void LocalFileTransfer::callback_transfer_network_read(int fd, short events, voi
/* since we're counting the bytes directly on read, a disconnect would mean that not all data has been transferred */
if(transfer->transfer->direction == Transfer::DIRECTION_UPLOAD) {
logMessage(LOG_FT, "{} Disconnected while receiving file. Received {} out of {} bytes",
transfer->log_prefix(), transfer->statistics.file_bytes_transferred, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
transfer->log_prefix(), transfer->statistics.file_transferred.total_bytes, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
} else if(transfer->transfer->direction == Transfer::DIRECTION_DOWNLOAD) {
logMessage(LOG_FT, "{} Disconnected while sending file. Send {} out of {} bytes",
transfer->log_prefix(), transfer->statistics.file_bytes_transferred, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
transfer->log_prefix(), transfer->statistics.file_transferred.total_bytes, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
}
transfer->handle->report_transfer_statistics(transfer->shared_from_this());
@@ -482,6 +483,8 @@ void LocalFileTransfer::callback_transfer_network_read(int fd, short events, voi
callback(transfer->transfer, { TransferError::UNEXPECTED_CLIENT_DISCONNECT, "" });
break;
}
case FileClient::STATE_DISCONNECTING:
case FileClient::STATE_DISCONNECTED:
default:
break;
}
@@ -506,16 +509,18 @@ void LocalFileTransfer::callback_transfer_network_read(int fd, short events, voi
/* since we're counting the bytes directly on read, a disconnect would mean that not all data has been transferred */
if(transfer->transfer->direction == Transfer::DIRECTION_UPLOAD) {
logMessage(LOG_FT, "{} Received read error while receiving file. Received {} out of {} bytes: {}/{}",
transfer->log_prefix(), transfer->statistics.file_bytes_transferred, transfer->transfer->expected_file_size - transfer->transfer->file_offset, errno, strerror(errno));
transfer->log_prefix(), transfer->statistics.file_transferred.total_bytes, transfer->transfer->expected_file_size - transfer->transfer->file_offset, errno, strerror(errno));
} else if(transfer->transfer->direction == Transfer::DIRECTION_DOWNLOAD) {
logMessage(LOG_FT, "{} Received read error while sending file. Send {} out of {} bytes: {}/{}",
transfer->log_prefix(), transfer->statistics.file_bytes_transferred, transfer->transfer->expected_file_size - transfer->transfer->file_offset, errno, strerror(errno));
transfer->log_prefix(), transfer->statistics.file_transferred.total_bytes, transfer->transfer->expected_file_size - transfer->transfer->file_offset, errno, strerror(errno));
}
transfer->handle->report_transfer_statistics(transfer->shared_from_this());
if(auto callback{transfer->handle->callback_transfer_aborted}; callback)
callback(transfer->transfer, { TransferError::NETWORK_IO_ERROR, strerror(errno) });
break;
case FileClient::STATE_DISCONNECTING:
case FileClient::STATE_DISCONNECTED:
default:
break;
}
@@ -524,7 +529,7 @@ void LocalFileTransfer::callback_transfer_network_read(int fd, short events, voi
return;
} else {
transfer->timings.last_read = std::chrono::system_clock::now();
transfer->statistics.network_bytes_received += read;
transfer->statistics.network_received.increase_bytes(read);
bool throttle_read = transfer->networking.throttle.increase_bytes(read);
if(transfer->state != FileClient::STATE_AWAITING_KEY && !(transfer->state == FileClient::STATE_TRANSFERRING && transfer->transfer->direction == Transfer::DIRECTION_UPLOAD)) {
@@ -616,7 +621,7 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
if(written == 0) {
/* EOF, how the hell is this event possible?! (Read should already catch it) */
logError(LOG_FT, "{} Client disconnected unexpectedly on write. Send {} bytes out of {}.",
transfer->log_prefix(), transfer->statistics.file_bytes_transferred, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
transfer->log_prefix(), transfer->statistics.file_transferred.total_bytes, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
transfer->handle->report_transfer_statistics(transfer->shared_from_this());
if(auto callback{transfer->handle->callback_transfer_aborted}; callback)
@@ -633,7 +638,7 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
}
logError(LOG_FT, "{} Received network write error. Send {} bytes out of {}. Closing transfer.",
transfer->log_prefix(), transfer->statistics.file_bytes_transferred, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
transfer->log_prefix(), transfer->statistics.file_transferred.total_bytes, transfer->transfer->expected_file_size - transfer->transfer->file_offset);
transfer->handle->report_transfer_statistics(transfer->shared_from_this());
if(auto callback{transfer->handle->callback_transfer_aborted}; callback)
@@ -668,7 +673,7 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
}
transfer->timings.last_write = std::chrono::system_clock::now();
transfer->statistics.network_bytes_send += written;
transfer->statistics.network_send.increase_bytes(written);
if(transfer->networking.throttle.increase_bytes(written))
break; /* we've to slow down */
@@ -678,7 +683,7 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
if(buffer_left_size > 0)
transfer->add_network_write_event(false);
else if(transfer->state == FileClient::STATE_DISCONNECTING) {
if(transfer->transfer && transfer->statistics.file_bytes_transferred + transfer->transfer->file_offset == transfer->transfer->expected_file_size) {
if(transfer->transfer && transfer->statistics.file_transferred.total_bytes + transfer->transfer->file_offset == transfer->transfer->expected_file_size) {
logMessage(LOG_FT, "{} Finished file transfer within {}. Closing connection.", transfer->log_prefix(), duration_to_string(std::chrono::system_clock::now() - transfer->timings.key_received));
transfer->handle->report_transfer_statistics(transfer->shared_from_this());
if(auto callback{transfer->handle->callback_transfer_finished}; callback)
@@ -783,6 +788,7 @@ size_t LocalFileTransfer::handle_transfer_read_raw(const std::shared_ptr<FileCli
logMessage(LOG_FT, "{} Disconnecting client because we failed to open the target file.", client->log_prefix());
break;
case TransferKeyApplyResult::INTERNAL_ERROR:
default:
this->report_transfer_statistics(client);
if(auto callback{this->callback_transfer_aborted}; client->transfer && callback)
@@ -881,6 +887,7 @@ size_t LocalFileTransfer::handle_transfer_read(const std::shared_ptr<FileClient>
response.setHeader("x-error-message", { "unknown key" });
goto send_response_exit;
case TransferKeyApplyResult::INTERNAL_ERROR:
default:
this->report_transfer_statistics(client);
if(auto callback{this->callback_transfer_aborted}; client->transfer && callback)
@@ -1044,37 +1051,19 @@ TransferKeyApplyResult LocalFileTransfer::handle_transfer_key_provided(const std
if(!client->transfer)
return TransferKeyApplyResult::UNKNOWN_KEY;
{
std::string absolute_path{};
auto transfer = client->transfer;
switch (transfer->target_type) {
case Transfer::TARGET_TYPE_AVATAR:
absolute_path = this->file_system_.absolute_avatar_path(transfer->server_id, transfer->target_file_path);
logMessage(LOG_FT, "{} Initialized avatar transfer for avatar \"{}\" ({} bytes, transferring {} bytes).",
client->log_prefix(), transfer->target_file_path, transfer->expected_file_size, transfer->expected_file_size - transfer->file_offset);
break;
case Transfer::TARGET_TYPE_ICON:
absolute_path = this->file_system_.absolute_icon_path(transfer->server_id, transfer->target_file_path);
logMessage(LOG_FT, "{} Initialized icon transfer for icon \"{}\" ({} bytes, transferring {} bytes).",
client->log_prefix(), transfer->target_file_path, transfer->expected_file_size, transfer->expected_file_size - transfer->file_offset);
break;
case Transfer::TARGET_TYPE_CHANNEL_FILE:
absolute_path = this->file_system_.absolute_channel_path(transfer->server_id, transfer->channel_id, transfer->target_file_path);
logMessage(LOG_FT, "{} Initialized channel transfer for file \"{}/{}\" ({} bytes, transferring {} bytes).",
client->log_prefix(), transfer->channel_id, transfer->target_file_path, transfer->expected_file_size, transfer->expected_file_size - transfer->file_offset);
break;
default:
logError(LOG_FT, "{} Tried to initialize client with unknown file target type ({}). Dropping transfer.", client->log_prefix(), (int) transfer->target_type);
error_detail = "invalid transfer target type";
return TransferKeyApplyResult::INTERNAL_ERROR;
}
debugMessage(LOG_FT, "{} Absolute file path: {}", client->log_prefix(), absolute_path);
client->file.absolute_path = absolute_path;
if(client->transfer->direction == Transfer::DIRECTION_UPLOAD) {
auto server = dynamic_pointer_cast<LocalVirtualFileServer>(client->transfer->server);
assert(server);
client->networking.throttle.right = &server->upload_throttle;
} else if(client->transfer->direction == Transfer::DIRECTION_DOWNLOAD) {
auto server = dynamic_pointer_cast<LocalVirtualFileServer>(client->transfer->server);
assert(server);
client->networking.throttle.right = &server->download_throttle;
}
if(client->transfer->max_bandwidth > 0) {
debugMessage(LOG_FT, "{} Limit network bandwidth to {} bytes/second", client->log_prefix(), client->transfer->max_bandwidth);
client->networking.throttle.set_max_bandwidth(client->transfer->max_bandwidth);
debugMessage(LOG_FT, "{} Limit network bandwidth especially for the client to {} bytes/second", client->log_prefix(), client->transfer->max_bandwidth);
client->networking.client_throttle.set_max_bandwidth(client->transfer->max_bandwidth);
}
client->networking.max_read_buffer_size = (size_t) -1; /* limit max bandwidth via throttle */
@@ -1102,10 +1091,10 @@ TransferKeyApplyResult LocalFileTransfer::handle_transfer_key_provided(const std
}
TransferUploadRawResult LocalFileTransfer::handle_transfer_upload_raw(const std::shared_ptr<FileClient> &client, const char *buffer, size_t length) {
client->statistics.file_bytes_transferred += length;
client->statistics.file_transferred.increase_bytes(length);
bool transfer_finished{false};
auto writte_offset = client->statistics.file_bytes_transferred + client->transfer->file_offset;
auto writte_offset = client->statistics.file_transferred.total_bytes + client->transfer->file_offset;
if(writte_offset > client->transfer->expected_file_size) {
logMessage(LOG_FT, "{} Client send {} too many bytes (Transfer length was {}). Dropping them, flushing the disk IO and closing the transfer.", client->log_prefix(), writte_offset - client->transfer->expected_file_size, duration_to_string(std::chrono::system_clock::now() - client->timings.key_received));
length -= writte_offset - client->transfer->expected_file_size;