【问题标题】:Serving static files in uWebSockets HTTP server (C++)在 uWebSockets HTTP 服务器 (C++) 中提供静态文件
【发布时间】:2022-09-26 11:18:54
【问题描述】:

我正在使用 uWebSockets 库在 C++ 中设置 HTTP 服务器,并且我想添加一个中间件来提供静态文件,类似于 app.use(express.static(path.join(__dirname, \'public\'))); 在 Express.js 中所做的。

静态文件位于public 文件夹中。中间件应该使服务器加载路径http://localhost:8087/css/bootstrap.min.css下的文件,而不是http://localhost:8087/public/css/bootstrap.min.css,从而将root重新路由到public。

如何使用 uWebSockets 库在 C++ 中做到这一点?我已经检查了uWS::App 结构,但是我发现没有与路径或提供静态文件相关的任何内容。

这是一个 HTTP 服务器的示例:

#include <uWebSockets/App.h>
#include <rapidjson/rapidjson.h>

#include \"util/AsyncFileReader.h\"
#include \"util/AsyncFileStreamer.h\"

#include <iostream>
#include <string>



void get_home(uWS::HttpResponse<false> *res, uWS::HttpRequest *req) {
  res->writeHeader(\"Content-Type\", \"text/html; charset=utf8\");
  // res->writeStatus(uWS::HTTP_200_OK);
  // res->end(\"Hello! This is <b>Sergei\'s C++ web server</b>.\");
  AsyncFileReader page_contents(\"./public/home.html\");
  res->end(page_contents.peek(0));
}

int main() {
  int port{8087};

  // HTTP
  uWS::App app = uWS::App();
  app.get(\"/\", get_home);


  app.listen(port, [&port](auto *token) {
    if (token) {
      std::cout << \"Listening on port \" << port << std::endl;
    }
  })
  .run();

  return 0;
}

    标签: c++ webserver httpserver uwebsockets


    【解决方案1】:

    正好有一个例子 https://github.com/uNetworking/uWebSockets/blob/master/examples/HttpServer.cpp 我最终添加了一个目录监视并更新了保存的 html 文件(代码库中的一些更改)但我想那是另一回事

    #include "helpers/AsyncFileReader.h"
    #include "helpers/AsyncFileStreamer.h"
    #include "helpers/Middleware.h"
    
    AsyncFileStreamer asyncFileStreamer("htmls"); // htmls is a relative folder path to static files
    
    
    app.get("/*", gethome); // note the *
    
    void get_home(auto *res, auto *req) {
    //void get_home(uWS::HttpResponse<false> *res, uWS::HttpRequest *req) {
      
      serveFile(res, req); // essentially res->writeStatus(uWS::HTTP_200_OK);
      asyncFileStreamer.streamFile(res, req->getUrl());
    }
    

    请注意,serveFile() 函数还需要处理图像的不同 Content-Type 标头设置

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
    【解决方案2】:

    为了扩展@amit.user105387 的答案,下面是一个可行的解决方案的样子:

    #include <uWebSockets/App.h>
    #include <rapidjson/rapidjson.h>
    
    #include "util/AsyncFileReader.h"
    #include "util/AsyncFileStreamer.h"
    #include "util/Middleware.h"
    
    #include <iostream>
    #include <string>
    
    void get_home(uWS::HttpResponse<false> *res, uWS::HttpRequest *req) {
      // res->writeHeader("Alt-Svc", "h2=\"localhost:8087\"public\"");
      res->writeHeader("Content-Type", "text/html; charset=utf8");
      AsyncFileReader page_contents("./public/html/home.html");
      res->end(page_contents.peek(0));
    }
    
    void PrintCachedFiles(std::map<std::string_view, AsyncFileReader *> dict) {
      for (auto it = dict.begin(); it != dict.end(); it++) {
        std::cout << it->first << std::endl;
      }
    }
    
    int main() {
      const int port{8087};
      const std::string public_folder{"./public"};
      AsyncFileStreamer public_files("./public");
    
      // HTTP
      uWS::App app = uWS::App();
    
      app.get("/", [&public_files](auto res, auto req){
        std::cout << "root folder = "<< public_files.root << std::endl;
        PrintCachedFiles(public_files.asyncFileReaders);
        res->writeHeader("Content-Type", "text/html; charset=utf8");
        public_files.streamFile(res, "/html/home.html");
        res->writeStatus(uWS::HTTP_200_OK)->end();
      });
    
      app.get("/css/:path", [&public_files](auto res, auto req){
        public_files.streamFile(res, req->getUrl());
        res->writeStatus(uWS::HTTP_200_OK)->end();
      });
    
      app.get("/js/:path", [&public_files](auto res, auto req){
        public_files.streamFile(res, req->getUrl());
        res->writeStatus(uWS::HTTP_200_OK)->end();
      });
    
      app.get("/img/:path/*", [&public_files](auto res, auto req){
        serveFile(res, req);
        public_files.streamFile(res, req->getUrl());
        res->writeStatus(uWS::HTTP_200_OK)->end();
      });
    
      app.get("/*", [&public_files](auto res, auto req){    
        res->writeStatus(uWS::HTTP_200_OK)->end("404: Page not found.");
      });
    
    
      app.listen(port, [&port](auto *token) {
        if (token) {
          std::cout << "Listening on port " << port << std::endl;
        }
      })
      .run();
    
      return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-21
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 2013-09-27
      相关资源
      最近更新 更多