133 lines
4.4 KiB
C++
133 lines
4.4 KiB
C++
#pragma once
|
|
|
|
#include <protocol/buffers.h>
|
|
#include <poll.h>
|
|
#include <fstream>
|
|
#include <src/server/file/FileServer.h>
|
|
#include <event.h>
|
|
#include <pipes/ws.h>
|
|
#include <pipes/ssl.h>
|
|
#include "../../TSServer.h"
|
|
|
|
namespace ts {
|
|
namespace server {
|
|
class ConnectedClient;
|
|
|
|
class ConnectedClient;
|
|
class FileServer;
|
|
|
|
enum FTType {
|
|
Unknown,
|
|
TeamSpeak,
|
|
|
|
TeaWeb_SSL, /* not yet decided if the protocol is HTTP or WebSocket */
|
|
TeaWeb_SSL_WS,
|
|
TeaWeb_SSL_HTTP,
|
|
|
|
TeaWeb_HTTP
|
|
};
|
|
|
|
class FileClient {
|
|
friend class FileServer;
|
|
public:
|
|
enum TransferState {
|
|
T_INITIALIZE,
|
|
T_TRANSFER,
|
|
T_DONE
|
|
};
|
|
enum ConnectionState {
|
|
C_CONNECTED,
|
|
C_DISCONNECTING,
|
|
C_DISCONNECTED
|
|
};
|
|
struct BandwidthEntry {
|
|
std::chrono::system_clock::time_point timestamp;
|
|
uint16_t length = 0;
|
|
};
|
|
|
|
FileClient(FileServer* handle, int socketFd);
|
|
~FileClient();
|
|
|
|
void disconnect(std::chrono::milliseconds = std::chrono::milliseconds(5000));
|
|
FTType getFTType(){ return this->ftType; }
|
|
|
|
size_t used_bandwidth();
|
|
|
|
std::string client_prefix();
|
|
|
|
size_t transferred_bytes();
|
|
size_t remaining_bytes();
|
|
protected:
|
|
void disconnectFinal(std::unique_lock<threads::Mutex>& /* tick lock */, bool /* handle flush thread */);
|
|
|
|
bool tick();
|
|
|
|
bool uploadWriteBytes(const pipes::buffer_view&);
|
|
void close_file_handle();
|
|
|
|
bool applyKey(const std::string &);
|
|
void sendMessage(const pipes::buffer_view&);
|
|
|
|
//Direct methods & IO stuff
|
|
void sendRawMessage(const pipes::buffer_view&);
|
|
void handleMessageRead(int, short, void*);
|
|
void handleMessageWrite(int, short, void*);
|
|
|
|
void handle_ssl_message(const pipes::buffer_view&); /* handeles all decoded SSL messages */
|
|
|
|
/* http header parser. header must be stored with read buffer! */
|
|
void handle_http_header();
|
|
|
|
/* Final protocol handlers */
|
|
void handle_http_message(const pipes::buffer_view&);
|
|
void handle_ws_message(const pipes::WSMessage&);
|
|
bool handle_ts_message();
|
|
private:
|
|
FileServer* handle;
|
|
std::weak_ptr<FileClient> _this;
|
|
|
|
std::recursive_mutex bandwidth_lock;
|
|
std::deque<std::unique_ptr<BandwidthEntry>> bandwidth;
|
|
|
|
sockaddr_storage remote_address;
|
|
int clientFd;
|
|
|
|
bool event_read_hold = false;
|
|
::event* readEvent = nullptr;
|
|
|
|
bool event_write_hold = false;
|
|
::event* writeEvent = nullptr;
|
|
threads::Mutex tickLock;
|
|
|
|
std::recursive_timed_mutex bufferLock;
|
|
std::deque<pipes::buffer> write_queue;
|
|
std::deque<pipes::buffer> read_queue;
|
|
pipes::buffer read_buffer; /* buffer which contains fragments of decoded data, e.g. HTTP request. Access only within tickLock locked */
|
|
FTType ftType = FTType::Unknown;
|
|
|
|
pipes::WebSocket ws_handler;
|
|
pipes::SSL ssl_handler;
|
|
bool https_upload_init = false;
|
|
bool http_init = false; /* general flag if the HTTP header has been parsed */
|
|
|
|
std::shared_ptr<ConnectedClient> client;
|
|
std::shared_ptr<file::FileTransfereKey> pendingKey = nullptr;
|
|
std::chrono::time_point<std::chrono::system_clock> last_io_action;
|
|
std::chrono::time_point<std::chrono::system_clock> connect_timestamp;
|
|
std::chrono::time_point<std::chrono::system_clock> finished_timestamp;
|
|
|
|
std::fstream* fstream = nullptr;
|
|
size_t bytesHandled = 0;
|
|
|
|
ConnectionState state_connection = ConnectionState::C_CONNECTED;
|
|
TransferState state_transfer = TransferState::T_INITIALIZE;
|
|
|
|
size_t availableBytes();
|
|
std::string getBytes(size_t);
|
|
std::string peekBytes(size_t);
|
|
|
|
std::mutex thread_flush_lock;
|
|
std::thread thread_flush;
|
|
};
|
|
}
|
|
} |