2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【C++】httplib.hを使ったwebサーバの作成

Last updated at Posted at 2023-06-13

はじめに

以前にhttplib.hを使ったHTTPサーバ/クライアントを作成した。
 ※以前の記事:C++ HTTPサーバー/クライアントを作る

今回はhttplib.hを使ってブラウザ表示できるwebサーバを作ってみた。

httplib.hのダウンロード/コピー

以下のgithubからダウンロードしてくる。
https://github.com/yhirose/cpp-httplib

もしくは、Googleがyhiroseさんの実装を取り込んだGoogle gitからダウンロードする。
chromium.googlesource.com/httplib.h

※補足 (2023/8/25追記) g++のバージョンによっては起動すると、
terminate called after throwing an instance of 'std::regex_error'

となり、regexでエラーとなってしまうようです。
@hiroaki_yamadaさんから教えていただきました。

regexはC++ 11から追加された機能になるため、バージョン4.9以上にすれば、動作すると思います。
以下は参考ページになります。

今回の動作環境は9.4.0でした。

ディレクトリ構成

httplib.h と同じ階層にserverSample.cppを置く。
htmlディレクトリはブラウザで表示させるファイル置き場。

├── CMakeLists.txt
├── html
│   ├── index.html
│   └── page1
│       └── page.html
├── httplib.h
└── serverSample.cpp

実装

Readme.mdのServer Exampleを参考にwebサーバアプリを作成する。

実装は以下になる。(ここをクリック)
serverSample.cpp
#include "httplib.h"
#include <iostream>

class FileReader {
public:
    int Read(std::string file_path) {
        std::ifstream ifs(file_path);
        std::string str = "";
        record_data = "";

        if (ifs.fail()) {
            std::cerr << "Failed to open file." << std::endl;
            return -1;
        }
        while (getline(ifs, str)) {
            record_data += str;
        }
        return 0;
    }
    std::string GetRecord() { return record_data; }
private:
    std::string record_data;
};

int main(void)
{
    using namespace httplib;
    Server svr;
    FileReader reader;

    std::cout << "start Server" << std::endl;

    std::string file_path = "../html";

    svr.Get("/", [&](const Request& req, Response& res) {
        reader.Read(file_path + "/index.html");
        std::string html = reader.GetRecord();
        res.set_content(html, "text/html");
    });

    svr.Get(R"(/(.+))", [&](const Request& req, Response& res) {
        reader.Read(file_path + req.target);
        std::string html = reader.GetRecord();
        res.set_content(html, "text/html");
    });

    svr.listen("127.0.0.1", 8080);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# set the project name and version
project(httpSample CXX)

# find package
find_package(Threads REQUIRED)

# compile executable file
add_executable(serverSample serverSample.cpp)

# module, library, target link
target_link_libraries(serverSample PUBLIC "-pthread")

実装解説

  • class FileReader
    • htmlファイルを読み込むためのクラス
  • int main(void)関数のstd::string file_path = "../html";
    • html置き場のディレクトリパスを指定する。
    • 以下のコマンドでbuildディレクトリに実行ファイルを生成する。
      cmake -Bbuild -H.
      cmake --build build
      
    • buildディレクトリからアプリを実行したため"../html"を指定している。
  • res.set_content(html, "text/html");
    • text/htmlを指定する。
    • ※ここの値は状況に応じてcssやjavascriptに変える必要がある。
  • svr.Get("/", [&](const Request& req, Response& res) {
    • Get methodで/を要求された時はhtml/index.htmlをブラウザに表示させる。
  • svr.Get(R"(/(.+))", [&](const Request& req, Response& res) {
    • R"(/(.+))"は正規表現。
    • /以降のパスを要求された時はhtml配下のhtmlファイルをブラウザに表示させる。

※補足 (2023/8/25追記)

@yhiroseさんから教えていただきました。 > まさかの作者さんからでした。
今回のhtmlのディレクトリにアクセスさせるため、

serverSample.cpp
std::string file_path = "../html";

svr.Get(R"(/(.+))"内の

serverSample.cpp
reader.Read(file_path + req.target);

に設定していました。

頂いたコメントによると、以下のcpp-httplibのStatic File Server機能を使用できるようです。

svr.set_mount_point("/", "../html")

これについて、再度実装してみました。

物凄く実装が綺麗になりました。

serverSample.cpp
#include "httplib.h"
#include <iostream>

int main(void)
{
    using namespace httplib;
    Server svr;

    std::cout << "start Server" << std::endl;
    svr.set_mount_point("/", "../html");
    svr.listen("127.0.0.1", 8080);
}

これだけでWebサーバを作成できました。
簡単で驚きました。

Googleがアップしていたのが、2017年の更新。
この時はまだStatic File Server機能は追加されてませんでした。
※ご本人様のGithubを確認せずに、こちらを使ってました。。

ご本人様のGithubを確認したら、2023年の更新。
set_mount_pointすごぃ。。。
改めて記事にしてまとめます。

余談

PCスペックによってはレスポンスが遅く、htmlにリンクしたjavascriptがブラウザに表示できないことがある。

さいごに

以上で終了です。
メモ程度ですが、ご参考になれば幸いです。

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?