Skip to content

Instantly share code, notes, and snippets.

@dmthuc
Last active September 18, 2024 21:23
Show Gist options
  • Save dmthuc/afaf01c4948c6a3bb51304926e3f00ca to your computer and use it in GitHub Desktop.
Save dmthuc/afaf01c4948c6a3bb51304926e3f00ca to your computer and use it in GitHub Desktop.
Fast CGI example in C++ using official fcgi library
/*
using official fcgi++ library
Reference to fcgi protocol at https://tools.ietf.org/html/rfc3875#section-6.2.1
Build: g++ main.cpp -lfcgi++ -lfcgi -o main
Spawn: spawn-fcgi -a 127.0.0.1 -p 9105 -n -- main
*/
#include <iostream>
#include <string>
#include <thread>
#include <string_view>
#include <fstream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <fcgio.h>
#include <fcgiapp.h>
#include <unistd.h>
using namespace std;
enum class Request_method{GET, HEAD ,POST, PUT, DELETE};
Request_method to_Request_method(string_view method) {
if (method == "GET")
return Request_method::GET;
else if(method == "POST")
return Request_method::POST;
else
throw runtime_error{"not support method"};
}
void on_load() {
}
void on_unload() {
}
void handle_request(FCGX_Request& request)
{
fcgi_streambuf cin_fcgi_streambuf(request.in);
fcgi_streambuf cout_fcgi_streambuf(request.out);
fcgi_streambuf cerr_fcgi_streambuf(request.err);
ostream os{&cout_fcgi_streambuf};
ostream errs{&cerr_fcgi_streambuf};
istream is{&cin_fcgi_streambuf};
char *query_string = FCGX_GetParam("QUERY_STRING", request.envp);
string script_name{FCGX_GetParam("SCRIPT_NAME", request.envp)};
Request_method method = to_Request_method({FCGX_GetParam("REQUEST_METHOD", request.envp)});
switch (method) {
case Request_method::GET:
if (script_name == "/")
os << "Location:https://www.youtube.com/user/skylargrey\r\n\r\n";
else {
sleep(10);
os << "Content-type: application/json\r\n"
<< "\r\n"
<< "{\"hi\":\"hehe\",\"hi\":\"hehe\"}\n";
}
break;
case Request_method::POST:
long int body_length = atoi(FCGX_GetParam("CONTENT_LENGTH", request.envp));
cout<< "body length:"<< body_length << '\n';
string body{};
char c;
int i = 0;
while(is.get(c)) {
body +=c;
}
std::cout<<body<<endl;
os << "Content-type: application/json\r\n"
<< "\r\n"
<< "{\"hi\":\"hehe\",\"hi\":\"hehe\"}\n";
break;
}
}
int main()
{
FCGX_Request request;
FCGX_Init();
FCGX_InitRequest(&request, 0, 0);
while (FCGX_Accept_r(&request) == 0) {
handle_request(request);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment