#ifndef nullptr #define nullptr NULL #endif #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; // http://www.fastcgi.com #include #include // http://www.postgresql.org //#include #include // http://uriparser.sourceforge.net #include // https://github.com/open-source-parsers/jsoncpp //#include 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 upf_map_t; static upf_map_t g_url_processors; typedef map 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:
\n
\n", label);
	for ( ; *envp != NULL; envp++)
	{
		FCGI_printf("%s\n", *envp);
	}
	FCGI_printf("

\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" "FastCGI echo" "

FastCGI echo

\n" "Request number %d, Process ID: %d

\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.

\n"); } else { int i, ch; FCGI_printf("Standard input:
\n

\n");
		for (i = 0; i < len; i++)
		{
			if ((ch = getchar()) < 0)
			{
				FCGI_printf("Error: Not enough bytes received on standard input

\n"); break; } putchar(ch); } FCGI_printf("\n

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