优化文件上传速度,增加请求头预校验功能
This commit is contained in:
+106
-99
@@ -16,138 +16,145 @@
|
||||
#include "webcc/router.h"
|
||||
#include "webcc/url.h"
|
||||
|
||||
namespace webcc {
|
||||
namespace webcc
|
||||
{
|
||||
|
||||
class Server : public Router {
|
||||
public:
|
||||
Server(boost::asio::ip::tcp protocol, std::uint16_t port,
|
||||
const fs::path& doc_root = {});
|
||||
using HeaderValidator = std::function<bool(const RequestPtr&)>;
|
||||
|
||||
Server(const Server&) = delete;
|
||||
Server& operator=(const Server&) = delete;
|
||||
class Server : public Router
|
||||
{
|
||||
public:
|
||||
Server(boost::asio::ip::tcp protocol, std::uint16_t port,
|
||||
const fs::path& doc_root = {});
|
||||
|
||||
~Server() = default;
|
||||
Server(const Server&) = delete;
|
||||
Server& operator=(const Server&) = delete;
|
||||
|
||||
void set_buffer_size(std::size_t buffer_size) {
|
||||
if (buffer_size > 0) {
|
||||
buffer_size_ = buffer_size;
|
||||
}
|
||||
}
|
||||
~Server() = default;
|
||||
|
||||
void set_file_chunk_size(std::size_t file_chunk_size) {
|
||||
assert(file_chunk_size > 0);
|
||||
file_chunk_size_ = file_chunk_size;
|
||||
}
|
||||
void set_buffer_size(std::size_t buffer_size)
|
||||
{
|
||||
if (buffer_size > 0)
|
||||
{
|
||||
buffer_size_ = buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Start and run the server.
|
||||
// This method is blocking so will not return until Stop() is called (from
|
||||
// another thread) or a signal like SIGINT is caught.
|
||||
// When the request of a connection has been read, the connection is put into
|
||||
// a queue waiting for some worker thread to process. Normally, the more
|
||||
// |workers| you have, the more concurrency you gain (the concurrency also
|
||||
// depends on the number of CPU cores). The worker thread pops connections
|
||||
// from the queue one by one, prepares the response by the user provided View,
|
||||
// then sends it back to the client.
|
||||
// Meanwhile, the (event) loop, i.e., io_context, is also running in a number
|
||||
// (|loops|) of threads. Normally, one thread for the loop is good enough, but
|
||||
// it could be more than that.
|
||||
void Run(std::size_t workers = 1, std::size_t loops = 1);
|
||||
void set_file_chunk_size(std::size_t file_chunk_size)
|
||||
{
|
||||
assert(file_chunk_size > 0);
|
||||
file_chunk_size_ = file_chunk_size;
|
||||
}
|
||||
|
||||
// Stop the server.
|
||||
// This should be called from another thread since the Run() is blocking.
|
||||
void Stop();
|
||||
// Start and run the server.
|
||||
// This method is blocking so will not return until Stop() is called (from
|
||||
// another thread) or a signal like SIGINT is caught.
|
||||
// When the request of a connection has been read, the connection is put into
|
||||
// a queue waiting for some worker thread to process. Normally, the more
|
||||
// |workers| you have, the more concurrency you gain (the concurrency also
|
||||
// depends on the number of CPU cores). The worker thread pops connections
|
||||
// from the queue one by one, prepares the response by the user provided View,
|
||||
// then sends it back to the client.
|
||||
// Meanwhile, the (event) loop, i.e., io_context, is also running in a number
|
||||
// (|loops|) of threads. Normally, one thread for the loop is good enough, but
|
||||
// it could be more than that.
|
||||
void Run(std::size_t workers = 1, std::size_t loops = 1);
|
||||
|
||||
// Is the server running?
|
||||
bool IsRunning() const;
|
||||
// Stop the server.
|
||||
// This should be called from another thread since the Run() is blocking.
|
||||
void Stop();
|
||||
|
||||
// For High-Level api deleloper: to set the default server name insteaed of
|
||||
// webcc Added by UnknownObject at 2022-09-04
|
||||
void SetDefaultServerName(std::string server_name);
|
||||
// Is the server running?
|
||||
bool IsRunning() const;
|
||||
|
||||
private:
|
||||
// Register signals which indicate when the server should exit.
|
||||
void AddSignals();
|
||||
// For High-Level api deleloper: to set the default server name insteaed of
|
||||
// webcc Added by UnknownObject at 2022-09-04
|
||||
void SetDefaultServerName(std::string server_name);
|
||||
|
||||
// Wait for a signal to stop the server.
|
||||
void AsyncWaitSignals();
|
||||
private:
|
||||
// Register signals which indicate when the server should exit.
|
||||
void AddSignals();
|
||||
|
||||
// Listen on the given port.
|
||||
bool Listen(std::uint16_t port);
|
||||
// Wait for a signal to stop the server.
|
||||
void AsyncWaitSignals();
|
||||
|
||||
// Accept connections asynchronously.
|
||||
void AsyncAccept();
|
||||
// Listen on the given port.
|
||||
bool Listen(std::uint16_t port);
|
||||
|
||||
// Stop acceptor and worker threads, close all pending connections, and
|
||||
// finally stop the event loop.
|
||||
void DoStop();
|
||||
// Accept connections asynchronously.
|
||||
void AsyncAccept();
|
||||
|
||||
// Worker thread routine.
|
||||
void WorkerRoutine();
|
||||
// Stop acceptor and worker threads, close all pending connections, and
|
||||
// finally stop the event loop.
|
||||
void DoStop();
|
||||
|
||||
// Clear pending connections from the queue and stop worker threads.
|
||||
void StopWorkers();
|
||||
// Worker thread routine.
|
||||
void WorkerRoutine();
|
||||
|
||||
// Handle a connection (or more precisely, the request inside it).
|
||||
// Get the request from the connection, process it, prepare the response,
|
||||
// then send the response back to the client.
|
||||
// The connection will keep alive if it's a persistent connection. When next
|
||||
// request comes, this connection will be put back to the queue again.
|
||||
virtual void Handle(ConnectionPtr connection);
|
||||
// Clear pending connections from the queue and stop worker threads.
|
||||
void StopWorkers();
|
||||
|
||||
// Match the view by HTTP method and URL (path).
|
||||
// Return if a view or static file is matched or not.
|
||||
// If the view asks for data streaming, |stream| will be set to true.
|
||||
bool MatchViewOrStatic(const std::string& method, const std::string& url,
|
||||
bool* stream);
|
||||
// Handle a connection (or more precisely, the request inside it).
|
||||
// Get the request from the connection, process it, prepare the response,
|
||||
// then send the response back to the client.
|
||||
// The connection will keep alive if it's a persistent connection. When next
|
||||
// request comes, this connection will be put back to the queue again.
|
||||
virtual void Handle(ConnectionPtr connection);
|
||||
|
||||
// Serve static files from the doc root.
|
||||
ResponsePtr ServeStatic(RequestPtr request);
|
||||
// Match the view by HTTP method and URL (path).
|
||||
// Return if a view or static file is matched or not.
|
||||
// If the view asks for data streaming, |stream| will be set to true.
|
||||
bool MatchViewOrStatic(const std::string& method, const std::string& url,
|
||||
bool* stream, ViewPtr* out_view = nullptr);
|
||||
|
||||
private:
|
||||
// tcp::v4() or tcp::v6()
|
||||
boost::asio::ip::tcp protocol_;
|
||||
// Serve static files from the doc root.
|
||||
ResponsePtr ServeStatic(RequestPtr request);
|
||||
|
||||
// Port number.
|
||||
std::uint16_t port_ = 0;
|
||||
private:
|
||||
// tcp::v4() or tcp::v6()
|
||||
boost::asio::ip::tcp protocol_;
|
||||
|
||||
// The directory with the static files to be served.
|
||||
fs::path doc_root_;
|
||||
// Port number.
|
||||
std::uint16_t port_ = 0;
|
||||
|
||||
// The size of the buffer for reading request.
|
||||
std::size_t buffer_size_ = kBufferSize;
|
||||
// The directory with the static files to be served.
|
||||
fs::path doc_root_;
|
||||
|
||||
// The size of the chunk loaded into memory each time when serving a
|
||||
// static file.
|
||||
std::size_t file_chunk_size_ = 1024;
|
||||
// The size of the buffer for reading request.
|
||||
std::size_t buffer_size_ = kBufferSize;
|
||||
|
||||
// Is the server running?
|
||||
bool running_ = false;
|
||||
// The size of the chunk loaded into memory each time when serving a
|
||||
// static file.
|
||||
std::size_t file_chunk_size_ = 1024;
|
||||
|
||||
// The mutex for guarding the state of the server.
|
||||
std::mutex state_mutex_;
|
||||
// Is the server running?
|
||||
bool running_ = false;
|
||||
|
||||
// The io_context used to perform asynchronous operations.
|
||||
boost::asio::io_context io_context_;
|
||||
// The mutex for guarding the state of the server.
|
||||
std::mutex state_mutex_;
|
||||
|
||||
// Acceptor used to listen for incoming connections.
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
// The io_context used to perform asynchronous operations.
|
||||
boost::asio::io_context io_context_;
|
||||
|
||||
// The connection pool which owns all live connections.
|
||||
ConnectionPool pool_;
|
||||
// Acceptor used to listen for incoming connections.
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
|
||||
// The signals for processing termination notifications.
|
||||
boost::asio::signal_set signals_;
|
||||
// The connection pool which owns all live connections.
|
||||
ConnectionPool pool_;
|
||||
|
||||
// Worker threads.
|
||||
std::vector<std::thread> worker_threads_;
|
||||
// The signals for processing termination notifications.
|
||||
boost::asio::signal_set signals_;
|
||||
|
||||
// The queue with connection waiting for the workers to process.
|
||||
Queue<ConnectionPtr> queue_;
|
||||
// Worker threads.
|
||||
std::vector<std::thread> worker_threads_;
|
||||
|
||||
// For High-Level api deleloper: to set the default server name insteaed of webcc
|
||||
// Added by UnknownObject at 2022-09-04
|
||||
std::string server_name__;
|
||||
};
|
||||
// The queue with connection waiting for the workers to process.
|
||||
Queue<ConnectionPtr> queue_;
|
||||
|
||||
// For High-Level api deleloper: to set the default server name insteaed of webcc
|
||||
// Added by UnknownObject at 2022-09-04
|
||||
std::string server_name__;
|
||||
};
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user