static bool fcgi_pass_request(struct fcgi_context *fc) { char buf[FCGI_BUF_SIZE]; ssize_t nread; /* eat the whole request and pass it to CGI */ while ((nread = FCGI_fread(buf, 1, sizeof(buf), FCGI_stdin)) > 0) { if (write_all(fc->fd_stdin, buf, nread) <= 0) { fcgi_finish(fc, "reading the request"); return false; } } close(fc->fd_stdin); fc->fd_stdin = -1; return true; }
int PUBReadPostBuffer() { char *p = NULL ; int post_len ; int read_remain_len ; int read_len ; int len ; int nret = 0 ; p = getenv("CONTENT_LENGTH") ; if( p == NULL ) { PUBFreePostBuffer(); return -1; } post_len = atoi(p) ; nret = PUBReallocPostBuffer( post_len ) ; if( nret ) return nret; read_remain_len = post_len ; read_len = 0 ; while( read_remain_len > 0 ) { len = FCGI_fread( g_post_buffer + read_len , 1 , read_remain_len , FCGI_stdin ) ; if( len == 0 ) break; read_remain_len -= len ; read_len += len ; } g_post_buffer_len = read_len ; return 0; }
static int msIO_fcgiRead( void *cbData, void *data, int byteCount ) { return FCGI_fread( data, 1, byteCount, (FCGI_FILE *) cbData ); }
int main (void) { char *ptr; json_t *responseJSON, *jsonFinal; RESTdispatchClass* root; logREST* log = logREST::instance(); // initialize the dispatch hierarchy root = initRESTDispatch(); while (FCGI_Accept() >= 0) { RESTdispatchClass::httpMethod method; std::string uri, query, body; std::vector<std::string> tokens; size_t bodyLen; size_t tokenPos; // read in the critical environment variables and go to next iteration if any fail ptr = getenv("PATH_INFO"); if (ptr) { uri.assign(ptr); } else continue; method = RESTdispatchClass::methodFromString(getenv("REQUEST_METHOD")); ptr = getenv("QUERY_STRING"); if (ptr) { query.assign(ptr); } else continue; ptr = getenv("CONTENT_LENGTH"); if (ptr) { bodyLen = ::atoi(ptr); } else { // For GET requests, etc., we don't get a CONTENT_LENGTH, which is OK. bodyLen = 0; } // if there is post data, read it in if (bodyLen > 0) { char *bodyBuf = (char *)calloc(bodyLen, sizeof(char)); if (bodyBuf == NULL) continue; FCGI_fread(bodyBuf, 1, bodyLen, FCGI_stdin); body.assign(bodyBuf, bodyLen); free(bodyBuf); } // chop up the URI and move the elements into a vector of strings tokens.clear(); tokenPos = 0; while (tokenPos < uri.length() && uri.at(tokenPos) == '/') tokenPos ++; while (tokenPos != std::string::npos) { size_t nextTokenPos = uri.find_first_of("/\\", tokenPos+1); size_t tokenLen; if (nextTokenPos == std::string::npos) { tokenLen = uri.length() - tokenPos; } else { tokenLen = (nextTokenPos - tokenPos); nextTokenPos ++; } tokens.push_back(uri.substr(tokenPos, tokenLen)); tokenPos = nextTokenPos; } // dispatch on the URI try { responseJSON = root->dispatch(tokens, 0, query, method, body); } catch (const std::exception& exc) { const char *mangled = typeid(exc).name(); int status = -1; char *demangled = abi::__cxa_demangle(mangled, NULL, NULL, &status); FCGI_printf("Status: 500\r\nContent-type: text/plain\r\n\r\n" "Uncaught exception while processing request:\n" "Exception: %s\n" "What: %s\n\n", (status == 0 && demangled != 0)? demangled : mangled, exc.what()); if (demangled != 0) free(demangled); continue; } if (responseJSON == NULL) { FCGI_printf("Status: 404\r\nContent-Type: text/plain\r\n\r\n" "Dispatch method returned NULL.\r\n"); continue; } // add some things to the JSON response... jsonFinal = json_pack("{sOsissss}", "response", responseJSON, "id", REST_ID, "name", REST_NAME, "connected", "true"); // print the result back to the client writeJSONResponse(jsonFinal, JSON_COMPACT); // log everything log->open(REST_LOGFILE); char *response = jsonFinal? json_dumps(jsonFinal, JSON_COMPACT) : NULL; log->write(tokens, query, body, to_string(method), response); if (response) ::free(response); log->close(); // clean up tokens.clear(); json_decref(jsonFinal); tokenPos = 0; } }
int ewf_fastcgi_read_cb( void *ptr, char *data, int size ) { NBU_UNUSED(ptr); return FCGI_fread( data, sizeof( char ), size, FCGI_stdin ); }