#ifndef nullptr
|
#define nullptr NULL
|
#endif
|
|
#include <unistd.h>
|
#include <time.h>
|
#include <errno.h>
|
|
#include <stdlib.h>
|
#include <iostream>
|
#include <map>
|
#include <vector>
|
#include <string>
|
#include <sstream>
|
#include <algorithm>
|
#include <iterator>
|
#include <cctype>
|
|
using namespace std;
|
|
// http://www.fastcgi.com
|
#include <fcgi_stdio.h>
|
#include <fcgi_config.h>
|
|
|
// http://www.postgresql.org
|
//#include <pgsql/libpq-fe.h>
|
#include <libpq-fe.h>
|
// http://uriparser.sourceforge.net
|
#include <uriparser/Uri.h>
|
|
|
// https://github.com/open-source-parsers/jsoncpp
|
//#include <json/json.h>
|
|
|
extern char **environ;
|
static char **g_initial_nv = nullptr;
|
static size_t g_req_count = 0;
|
|
stringstream g_log_msg;
|
stringstream g_http_res;
|
|
typedef void (*url_process_func_t)();
|
typedef map<string, url_process_func_t> upf_map_t;
|
static upf_map_t g_url_processors;
|
|
typedef map<string, string> str_map_t;
|
|
//=======错误提示=======
|
static void http_res_200(const char* msg)
|
{
|
FCGI_printf("Status: 20 OK\r\n" "Content-type: text/html\r\n" "\r\n" "%s", msg);
|
}
|
static void http_res_400()
|
{
|
FCGI_printf("Status: 400 Bad Request\r\n" "Content-type: text/html\r\n" "\r\n");
|
}
|
static void http_res_401()
|
{
|
FCGI_printf("Status: 401 Unauthorized\r\n" "Content-type: text/html\r\n" "\r\n");
|
}
|
static void http_res_404()
|
{
|
FCGI_printf("Status: 404 Not Found\r\n" "\r\n");
|
}
|
static void http_res_500()
|
{
|
FCGI_printf("Status: 500 test Internal Server Error \r\n" "\r\n");
|
}
|
static void http_res_500(int problem_code = 0)
|
{
|
FCGI_printf("Status: 500 Internal Server Error\r\n" "Content-type: text/html\r\n" "\r\n" "Problem code = %d", problem_code);
|
}
|
static void http_res_500(const char* msg)
|
{
|
FCGI_printf("Status: 500 Internal Server Error\r\n" "Content-type: text/html\r\n" "\r\n" "Message = %s", msg);
|
}
|
//=======错误提示==end=====
|
|
size_t read_shell(const char* cmd, char* buffer, size_t buffer_size, int* exit_status = nullptr, int* exit_code = nullptr)
|
{
|
if (cmd == nullptr)
|
return 0;
|
|
FCGI_FILE* fcmd = FCGI_popen(cmd, "r");
|
if (fcmd == nullptr)
|
return 0;
|
|
size_t red = FCGI_fread(buffer, sizeof(char), buffer_size - 1, fcmd);
|
|
int es = FCGI_pclose(fcmd);
|
|
if (exit_status != nullptr)
|
*exit_status = es;
|
if (exit_code != nullptr)
|
*exit_code = WEXITSTATUS(es);
|
|
return red;
|
}
|
|
void run_in_bash(const char* cmd, int* exit_status = nullptr, int* exit_code = nullptr)
|
{
|
#define BASH_WRAPPER "su -s /bin/bash -c '%s' http"
|
|
char buffer[512];
|
snprintf(buffer, sizeof(buffer) - 1, BASH_WRAPPER, cmd);
|
|
int es = system(buffer);
|
|
if (exit_status != nullptr)
|
*exit_status = es;
|
if (exit_code != nullptr)
|
*exit_code = WEXITSTATUS(es);
|
}
|
|
static void print_env(const char *label, char **envp)
|
{
|
FCGI_printf("%s:<br>\n<pre>\n", label);
|
for ( ; *envp != NULL; envp++)
|
{
|
FCGI_printf("%s\n", *envp);
|
}
|
FCGI_printf("</pre><p>\n");
|
}
|
|
static void hpf_echo()
|
{
|
g_log_msg.flush();
|
|
char *contentLength = getenv("CONTENT_LENGTH");
|
int len;
|
|
FCGI_printf("Content-type: text/html\r\n"
|
"\r\n"
|
"<title>FastCGI echo</title>"
|
"<h1>FastCGI echo</h1>\n"
|
"Request number %d, Process ID: %d<p>\n", g_req_count, getpid());
|
|
if (contentLength != NULL)
|
len = strtol(contentLength, NULL, 10);
|
else
|
len = 0;
|
|
if (len <= 0)
|
{
|
FCGI_printf("No data from standard input.<p>\n");
|
}
|
else
|
{
|
int i, ch;
|
|
FCGI_printf("Standard input:<br>\n<pre>\n");
|
for (i = 0; i < len; i++)
|
{
|
if ((ch = getchar()) < 0)
|
{
|
FCGI_printf("Error: Not enough bytes received on standard input<p>\n");
|
break;
|
}
|
putchar(ch);
|
}
|
FCGI_printf("\n</pre><p>\n");
|
}
|
|
print_env("Request environment", environ);
|
print_env("Initial environment", g_initial_nv);
|
}
|
|
bool parse_query_items(str_map_t& query_items)
|
{
|
return true;
|
}
|
|
size_t get_post_content(char* buffer, size_t max_size, size_t offset_content = 0)
|
{
|
if (buffer == NULL || max_size == 0)
|
return 0;
|
|
const char* contentLength = getenv("CONTENT_LENGTH");
|
size_t len = 0;
|
if (contentLength != NULL)
|
len = strtol(contentLength, NULL, 10);
|
|
if (len == 0)
|
return 0;
|
|
if (offset_content > 0)
|
fseek(stdin, offset_content, SEEK_SET);
|
|
return fread(buffer, sizeof(char), min(max_size, len), stdin);
|
}
|
|
const string* try_get_str_from_map(const str_map_t& str_map, const string& key, const string* default_value = nullptr)
|
{
|
str_map_t::const_iterator iter = str_map.find(key);
|
if (iter == str_map.end())
|
return default_value;
|
else
|
return &(iter->second);
|
}
|
|
|
|
|
|
static void hpf_fishbowl_fish_count()
|
{
|
|
}
|
|
static void hpf_fishbowl_load_v4l2grab()
|
{
|
|
}
|
|
int main ()
|
{
|
g_initial_nv = environ;
|
|
|
|
cerr << "begin accept access" << endl;
|
|
int fcgi_accept_status;
|
|
while ((fcgi_accept_status = FCGI_Accept()) >= 0)
|
{
|
g_req_count++;
|
g_log_msg.flush();
|
|
char* req_PATH_INFO = getenv("PATH_INFO");
|
if(req_PATH_INFO == nullptr)
|
{
|
cerr << "PATH_INFO is null" << endl;
|
exit(EXIT_FAILURE);
|
}
|
|
upf_map_t::iterator iter_upf = g_url_processors.find(req_PATH_INFO);
|
if (iter_upf == g_url_processors.end())
|
{
|
http_res_404();
|
}
|
else
|
{
|
url_process_func_t proc = iter_upf->second;
|
proc();
|
}
|
}
|
|
|
cerr << "exit gracefully, fcgi_accept_status=" << fcgi_accept_status << endl;
|
|
return 0;
|
}
|