c++webserverhttpserveruwebsockets

Serving static files in uWebSockets HTTP server (C++)


I am setting up an HTTP server in C++ using the uWebSockets library and I would like to add a middleware to serve static files, similar to what app.use(express.static(path.join(__dirname, 'public'))); does in Express.js.

The static files reside in the public folder. The middleware should make the server load files under the path http://localhost:8087/css/bootstrap.min.css, not http://localhost:8087/public/css/bootstrap.min.css, thus re-routing root to public.

How could one do this in C++ using the uWebSockets library? I already inspected the uWS::App struct, however I find there nothing related to the path or to serving static files.

Here is an example an HTTP server:

#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;
}

Solution

  • There is an example with this exactly

    I eventually ended up adding a directory watch and updating the html files if saved (a few changes in codebase) but i guess thats a different thing

    #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());
    }
    

    Please note serveFile() function also needs to take care of different Content-Type header setting for images

    example mentioned: https://github.com/uNetworking/uWebSockets/blob/master/examples/HttpServer.cpp