A lot of file transfer updates
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user