diff --git a/native/serverconnection/exports/exports.d.ts b/native/serverconnection/exports/exports.d.ts index b2f6310..86a49f7 100644 --- a/native/serverconnection/exports/exports.d.ts +++ b/native/serverconnection/exports/exports.d.ts @@ -106,7 +106,11 @@ declare module "teaclient_connection" { callback_progress: (current: number, max: number) => any; callback_failed: (message: string) => any; - start(); + /** + * @return true if the connect method has been executed successfully + * false if the connect fails, callback_failed will be called with the exact reason + */ + start() : boolean; } export interface TransferOptions { diff --git a/native/serverconnection/src/connection/ft/FileTransferManager.cpp b/native/serverconnection/src/connection/ft/FileTransferManager.cpp index 58b5adf..9ca385f 100644 --- a/native/serverconnection/src/connection/ft/FileTransferManager.cpp +++ b/native/serverconnection/src/connection/ft/FileTransferManager.cpp @@ -1,6 +1,7 @@ #include "FileTransferManager.h" #include "FileTransferObject.h" +#include #include #include #include @@ -8,6 +9,7 @@ #ifndef WIN32 #include #include + #define IPPROTO_TCP (0) #else #include #define SOCK_NONBLOCK (0) @@ -56,14 +58,17 @@ bool Transfer::initialize(std::string &error) { switch(this->remote_address.ss_family) { case AF_INET: ((sockaddr_in*) &this->remote_address)->sin_port = htons(this->_options->remote_port); + break; case AF_INET6: ((sockaddr_in6*) &this->remote_address)->sin6_port = htons(this->_options->remote_port); + break; default: + log_warn(category::file_transfer, tr("getaddrinfo() returns unknown address family ({})"), this->remote_address.ss_family); break; } - log_info(category::file_transfer, tr("Setting remote port to {}"), this->_options->remote_port); - this->_socket = (int) ::socket(this->remote_address.ss_family, SOCK_STREAM | SOCK_NONBLOCK, 0); + log_info(category::file_transfer, tr("Setting remote port to {}"), net::to_string(this->remote_address)); + this->_socket = (int) ::socket(this->remote_address.ss_family, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); if(this->_socket < 0) { this->finalize(); error = tr("failed to spawn socket"); @@ -106,13 +111,20 @@ bool Transfer::connect() { 0, nullptr ); - fprintf(stdout, "Connect failed with code %d. Error: %ld/%S\n", result, error, s); + auto r = wcschr(s, L'\r'); + if(r) *r = L'\0'; + + this->call_callback_failed(to_string(error) + "/" + std::string{s, s + wcslen(s)}); + log_trace(category::file_transfer, tr("Failed to connect with code: {} => {}/{}"), result, error, std::string{s, s + wcslen(s)}.c_str()); LocalFree(s); + + this->finalize(); return false; } #else if(errno != EINPROGRESS) { log_error(category::file_transfer, tr("Failed to connect with code: {} => {}/{}"), result, errno, strerror(errno)); + this->call_callback_failed(to_string(errno) + "/" + strerror(errno)); this->finalize(); return false; } @@ -709,11 +721,14 @@ NAN_METHOD(JSTransfer::_start) { } NAN_METHOD(JSTransfer::start) { if(!this->_transfer->connect()) { - Nan::ThrowError("failed to connect"); + log_debug(category::file_transfer, tr("Failed to start file transfer. Error callback should be called!")); + info.GetReturnValue().Set(Nan::New(false)); return; } log_info(category::file_transfer, tr("Connecting to {}:{}"), this->_transfer->options().remote_address, this->_transfer->options().remote_port); + info.GetReturnValue().Set(Nan::New(true)); + return; } NAN_METHOD(JSTransfer::_abort) { @@ -721,6 +736,7 @@ NAN_METHOD(JSTransfer::_abort) { } NAN_METHOD(JSTransfer::abort) { //TODO! + Nan::ThrowError("Not implemented"); } void JSTransfer::callback_finished(bool flag) { diff --git a/native/serverconnection/src/connection/ft/FileTransferObject.cpp b/native/serverconnection/src/connection/ft/FileTransferObject.cpp index 3aea0e1..2923ea9 100644 --- a/native/serverconnection/src/connection/ft/FileTransferObject.cpp +++ b/native/serverconnection/src/connection/ft/FileTransferObject.cpp @@ -189,10 +189,6 @@ TransferFileSource::TransferFileSource(std::string path, std::string name) : _pa } } -#ifdef WIN32 - #define u8path path -#endif - uint64_t TransferFileSource::byte_length() const { if(file_size.has_value()) return file_size.value(); diff --git a/native/serverconnection/test/js/ft.ts b/native/serverconnection/test/js/ft.ts index a16b336..cac0c54 100644 --- a/native/serverconnection/test/js/ft.ts +++ b/native/serverconnection/test/js/ft.ts @@ -4,15 +4,17 @@ module.paths.push("../../build/win32_64"); import * as fs from "fs"; import * as net from "net"; +import * as os from "os"; +import * as path from "path"; const original_require = require; -require = (module => original_require("/home/wolverindev/TeaSpeak-Client/client/native/build/linux_x64/" + module + ".node")) as any; +require = (module => original_require(path.join(__dirname, "..", "..", "..", "build", os.platform() + "_" + os.arch(), module + ".node"))) as any; import * as handle from "teaclient_connection"; require = original_require; const buffer_size = 24; const start_server = async () => { - const server = net.createServer(); + const server: net.Server = net.createServer(); await new Promise(resolve => server.listen(30303, "localhost", resolve)); server.on('connection', socket => { @@ -40,6 +42,10 @@ const start_server = async () => { //console.log("[SERVER] Received data: %s", buffer.toString()); }); }); + + const address = server.address(); + console.log("[SERVER] Listening on %o", address); + return typeof address === "string" ? address : address.address; }; function str2ab(str) { @@ -53,13 +59,14 @@ function str2ab(str) { start_server().catch(error => { console.error("Failed to start FT server (%o)", error); -}).then(() => { +}).then(address => { const target_buffer = new Uint8Array(buffer_size); const destination = handle.ft.download_transfer_object_from_buffer(target_buffer.buffer); //const source = handle.ft.upload_transfer_object_from_buffer(str2ab("Hello World")); //console.log(source); //const source = handle.ft.upload_transfer_object_from_file(__dirname, "test_upload.txt"); - const source = handle.ft.upload_transfer_object_from_file("/home/wolverindev/Downloads", "xxx.iso"); + //const source = handle.ft.upload_transfer_object_from_file("/home/wolverindev/Downloads", "xxx.iso"); + const source = handle.ft.upload_transfer_object_from_file("C:\\Users\\WolverinDEV\\Downloads", "ütest.txt"); console.log(source); const upload = true; @@ -71,7 +78,7 @@ start_server().catch(error => { object: upload ? source : destination, transfer_key: upload ? "ft_upload_data__" : "ft_download_data", - remote_address: "localhost", + remote_address: address, remote_port: 30303 });