一个简单的基于microhttpd的httpd,有目录遍历问题。
#include <stdio.h>
#include <stdlib.h>
#include <microhttpd.h>
#include <cstring>
#include <string>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
/**
* Simple HTTP Server
* 编译: g++ -std=c++11 -o tt tt.cpp -lmicrohttpd
*/
class SimpleHttpServer {
public:
SimpleHttpServer(const std::string& rootDir, const std::string& defaultDoc, int port)
: root_dir_(rootDir), default_doc_(defaultDoc), port_(port), daemon_(nullptr) {}
~SimpleHttpServer() {
Stop();
}
bool Start() {
daemon_ = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, port_,
nullptr, nullptr,
&requestHandler, this,
MHD_OPTION_END);
if (daemon_ == nullptr) {
std::cerr << "Failed to start the HTTP server." << std::endl;
return false;
}
return true;
}
void Stop() {
if (daemon_ != nullptr) {
MHD_stop_daemon(daemon_);
daemon_ = nullptr;
}
}
private:
static MHD_Result requestHandler(void* cls, struct MHD_Connection* connection,
const char* url, const char* method,
const char* version, const char* upload_data,
size_t* upload_data_size, void** con_cls) {
SimpleHttpServer* self = static_cast<SimpleHttpServer*>(cls);
std::string full_path;
if (url[strlen(self->root_dir_.c_str()) - 1] == '/') {
full_path = self->root_dir_ + url;
} else {
full_path = self->root_dir_ + "/" + url;
}
struct stat file_stat;
if (stat(full_path.c_str(), &file_stat) != 0) {
return MHD_NO;
}
if (S_ISDIR(file_stat.st_mode)) {
if (url[strlen(url) - 1] == '/') {
full_path += self->default_doc_;
} else {
full_path += "/" + self->default_doc_;
}
if (stat(full_path.c_str(), &file_stat) != 0) {
return MHD_NO;
}
}
struct MHD_Response *response;
MHD_Result ret;
if (strcmp(method, "GET") == 0) {
response = MHD_create_response_from_fd(file_stat.st_size, open(full_path.c_str(), O_RDONLY));
if (response != nullptr) {
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
} else {
ret = MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, nullptr);
}
} else {
ret = MHD_queue_response(connection, MHD_HTTP_METHOD_NOT_ALLOWED, nullptr);
}
return ret;
}
std::string root_dir_;
std::string default_doc_;
int port_;
struct MHD_Daemon* daemon_;
};
int main() {
int port = 8701;
SimpleHttpServer server("~/publish/www", "index.html", port);
if (server.Start()) {
printf("Server started on port %d\n", port);
while (true) {
sleep(1);
}
}
return 0;
}