C++のライブラリ,POCOの紹介キャンペーンの続きです.
POCOで簡単SMTPプレーンテキストメール - なぜか数学者にはワイン好きが多い
POCOで簡単SMTPアクセス - なぜか数学者にはワイン好きが多い
POCOで簡単POPアクセス - なぜか数学者にはワイン好きが多い
POCOで簡単Webアクセス - なぜか数学者にはワイン好きが多い
ApacheみたいなWebサーバの簡単バージョンを書いてみます.静的なページだけが対象.
今回はデーモンにするので,ヘッダ部分だけでこれくらいになります.
*#include "Poco/Net/HTTPServer.h" #include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPRequestHandlerFactory.h" #include "Poco/Net/HTTPServerParams.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Net/HTTPServerResponse.h" #include "Poco/Net/HTTPServerParams.h" #include "Poco/Net/ServerSocket.h" #include "Poco/ThreadPool.h" #include "Poco/Thread.h" #include "Poco/Util/ServerApplication.h" #include "Poco/Util/Option.h" #include "Poco/Util/OptionSet.h" #include "Poco/RunnableAdapter.h" #include "iostream" using Poco::Net::ServerSocket; using Poco::Net::HTTPRequestHandler; using Poco::Net::HTTPRequestHandlerFactory; using Poco::Net::HTTPServer; using Poco::Net::HTTPServerRequest; using Poco::Net::HTTPServerResponse; using Poco::Net::HTTPServerParams; using Poco::ThreadPool; using Poco::Thread; using Poco::Util::ServerApplication; using Poco::Util::Application; using Poco::Util::Option; using Poco::Util::OptionSet; using Poco::RunnableAdapter; using namespace std;
手抜きして,ヘッダファイルのクラス宣言部分に定義も全部書いてしまいます.
class WWWRequestHandler: public HTTPRequestHandler
{
public:
WWWRequestHandler() { } // なんもしない
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
{
// 適当な表示内容を...
response.setChunkedTransferEncoding(true);
response.setContentType("text/html");
std::ostream& ostr = response.send();
ostr << "<html><head><title>WWW Server</title>";
ostr << "<body><p style=\"text-align: center; font-size: 48px;\">";
ostr << "WWW Server by POCO C++ Libraries"<<"<BR />";
ostr << "YOUR REQUEST="<<request.getURI()<<"<BR />";
ostr << "YOUR ADDRESS="<<request.clientAddress().toString()<<"<BR />";
ostr << "</p></body></html>";
}
};
class WWWRequestHandlerFactory: public HTTPRequestHandlerFactory
{
public:
WWWRequestHandlerFactory() { }
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
return new WWWRequestHandler();
}
};
class WWWServer: public Poco::Util::ServerApplication
{
public:
WWWServer() { }
~WWWServer() { }
protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
ServerApplication::initialize(self);
}
void uninitialize()
{
ServerApplication::uninitialize();
}
void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);
}
void handleOption(const std::string& name, const std::string& value)
{
ServerApplication::handleOption(name, value);
}
int main(const std::vector<std::string>& args)
{
unsigned short port = (unsigned short) config().getInt("WWWServer.port", 8888);
int maxQueued = config().getInt("WWWServer.maxQueued", 100);
int maxThreads = config().getInt("WWWServer.maxThreads", 16);
ThreadPool::defaultPool().addCapacity(maxThreads);
HTTPServerParams* pParams = new HTTPServerParams;
pParams->setMaxQueued(maxQueued);
pParams->setMaxThreads(maxThreads);
ServerSocket svs(port);
HTTPServer srv(new WWWRequestHandlerFactory(), svs, pParams);
srv.start();
waitForTerminationRequest(); // CTRL-Cが押されるか,killでシグナルを送られるまで待つ
srv.stop();
return Application::EXIT_OK;
}
};
このプログラムをコンパイルします.
> c++ -o httpd httpd.cc -I/usr/local/include -L/usr/local/lib -lPocoNet -lPocoUtil
実行します.
./httpd
ローカルでアクセスしてみます.
> w3m http://localhost:8888/
Ok.
ポートを8888にしているのは,ポート80にしてコンパイル&実行するとエラーが出たからです.
> ./httpd I/O error: Permission denied
これはよく分かんなかったので,また調べます.
(全部rootで作業するとエラーは出ないのですが...)