void session_closed_handler (void *cls, struct SPDY_Session * session, int by_client) { printf("session_closed_handler called\n"); if(strcmp(CLS,cls)!=0) { killchild(child,"wrong cls"); } if(SPDY_YES != by_client) { //killchild(child,"wrong by_client"); printf("session closed by server\n"); } else { printf("session closed by client\n"); } if(NULL == session) { killchild(child,"session is NULL"); } session_closed_called = 1; }
void standard_request_handler(void *cls, struct SPDY_Request * request, uint8_t priority, const char *method, const char *path, const char *version, const char *host, const char *scheme, struct SPDY_NameValue * headers, bool more) { (void)cls; (void)request; (void)priority; (void)host; (void)scheme; (void)headers; (void)method; (void)version; (void)more; struct SPDY_Response *response=NULL; struct SPDY_NameValue *resp_headers; printf("received request for '%s %s %s'\n", method, path, version); FILE *fd = fopen(DATA_DIR "spdy-draft.txt","r"); if(NULL == (resp_headers = SPDY_name_value_create())) { fprintf(stdout,"SPDY_name_value_create failed\n"); killchild(); } if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_TYPE,"text/plain")) { fprintf(stdout,"SPDY_name_value_add failed\n"); killchild(); } response = SPDY_build_response_with_callback(200,NULL, SPDY_HTTP_VERSION_1_1,resp_headers,&response_callback,fd,SPDY_MAX_SUPPORTED_FRAME_SIZE); SPDY_name_value_destroy(resp_headers); if(NULL==response){ fprintf(stdout,"no response obj\n"); killchild(); } void *clspath = strdup(path); if(SPDY_queue_response(request,response,true,false,&response_done_callback,clspath)!=SPDY_YES) { fprintf(stdout,"queue\n"); killchild(); } }
void new_session_callback (void *cls, struct SPDY_Session * session) { char ipstr[1024]; struct sockaddr *addr; socklen_t addr_len = SPDY_get_remote_addr(session, &addr); if(!addr_len) { printf("SPDY_get_remote_addr"); abort(); } if(strcmp(CLS,cls)!=0) { killchild(child,"wrong cls"); } if(AF_INET == addr->sa_family) { struct sockaddr_in * addr4 = (struct sockaddr_in *) addr; if(NULL == inet_ntop(AF_INET, &(addr4->sin_addr), ipstr, sizeof(ipstr))) { killchild(child,"inet_ntop"); } printf("New connection from: %s:%i\n", ipstr, ntohs(addr4->sin_port)); loop = 0; } #if HAVE_INET6 else if(AF_INET6 == addr->sa_family) { struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *) addr; if(NULL == inet_ntop(AF_INET6, &(addr6->sin6_addr), ipstr, sizeof(ipstr))) { killchild(child,"inet_ntop"); } printf("New connection from: %s:%i\n", ipstr, ntohs(addr6->sin6_port)); loop = 0; } #endif else { killchild(child,"wrong family"); } }
static void closed_session_cb (void *cls, struct SPDY_Session * session, int by_client) { (void)cls; (void)session; printf("closed_session_cb called\n"); if(SPDY_YES == by_client) { killchild("closed by the client"); } if(closed_session) { killchild("closed_session_cb called twice"); } closed_session = 1; }
void verifydir(char *cp) { struct stat stb; if (!stat(cp, &stb)) { if (S_ISDIR(stb.st_mode)) return; errno = ENOTDIR; } run_err("%s: %s", cp, strerror(errno)); killchild(0); }
bool Exec::Impl::createchild (const std::string & strCommand) { TRF; // If any previous child exist, kill it. killchild (); int handle [2]; if (pipe (handle) != 0) { TRDEB ("Error en pipe"); return false; } pid_t child= vfork (); switch (child) { case pid_t (0): // Child close (handle [0] ); dup2 (handle [1], STDOUT_FILENO); dup2 (handle [1], STDERR_FILENO); close (handle [1] ); { const char * strShell; strShell= getenv ("SHELL"); if (! strShell) strShell= "/bin/sh"; execlp (strShell, strShell, "-c", strCommand.c_str (), static_cast <const char *> (0) ); } TRDEB ("Error en execlp"); exit (1); return false; case pid_t (-1): // Error TRDEB ("Error en fork"); close (handle [0] ); close (handle [1] ); return false; default: hchild= handle [0]; close (handle [1] ); pidchild= child; return true; } }
void standard_request_handler(void *cls, struct SPDY_Request * request, uint8_t priority, const char *method, const char *path, const char *version, const char *host, const char *scheme, struct SPDY_NameValue * headers, bool more) { (void)cls; (void)request; (void)priority; (void)host; (void)scheme; (void)headers; (void)method; (void)version; struct SPDY_Response *response=NULL; if(strcmp(CLS,cls)!=0) { killchild(child,"wrong cls"); } if(false != more){ fprintf(stdout,"more has wrong value\n"); exit(5); } response = SPDY_build_response(200,NULL,SPDY_HTTP_VERSION_1_1,NULL,RESPONSE_BODY,strlen(RESPONSE_BODY)); if(NULL==response){ fprintf(stdout,"no response obj\n"); exit(3); } if(SPDY_queue_response(request,response,true,false,NULL,(void*)strdup(path))!=SPDY_YES) { fprintf(stdout,"queue\n"); exit(4); } }
//parent proc int parentproc( int port) { int childstatus; unsigned long long timeoutlong=0; struct timeval timeout; int ret; fd_set read_fd_set; fd_set write_fd_set; fd_set except_fd_set; int maxfd = -1; struct SPDY_Daemon *daemon; SPDY_init(); daemon = SPDY_start_daemon(port, DATA_DIR "cert-and-key.pem", DATA_DIR "cert-and-key.pem", NULL,&session_closed_handler,&standard_request_handler,NULL,CLS,SPDY_DAEMON_OPTION_END); if(NULL==daemon){ printf("no daemon\n"); return 1; } do { FD_ZERO(&read_fd_set); FD_ZERO(&write_fd_set); FD_ZERO(&except_fd_set); ret = SPDY_get_timeout(daemon, &timeoutlong); if(SPDY_NO == ret || timeoutlong > 1000) { timeout.tv_sec = 1; timeout.tv_usec = 0; } else { timeout.tv_sec = timeoutlong / 1000; timeout.tv_usec = (timeoutlong % 1000) * 1000; } maxfd = SPDY_get_fdset (daemon, &read_fd_set, &write_fd_set, &except_fd_set); ret = select(maxfd+1, &read_fd_set, &write_fd_set, &except_fd_set, &timeout); switch(ret) { case -1: printf("select error: %i\n", errno); killchild(child, "select error"); break; case 0: break; default: SPDY_run(daemon); break; } } while(waitpid(child,&childstatus,WNOHANG) != child); //give chance to the client to close socket and handle this in run usleep(100000); SPDY_run(daemon); SPDY_stop_daemon(daemon); SPDY_deinit(); return WEXITSTATUS(childstatus); }
static int parentproc() { int childstatus; unsigned long long timeoutlong=0; struct timeval timeout; int ret; fd_set read_fd_set; fd_set write_fd_set; fd_set except_fd_set; int maxfd = -1; struct SPDY_Daemon *daemon; unsigned long long beginning = 0; unsigned long long now; SPDY_init(); daemon = SPDY_start_daemon(port, DATA_DIR "cert-and-key.pem", DATA_DIR "cert-and-key.pem", &new_session_cb, &closed_session_cb, NULL, NULL, NULL, SPDY_DAEMON_OPTION_SESSION_TIMEOUT, TIMEOUT, SPDY_DAEMON_OPTION_END); if(NULL==daemon){ printf("no daemon\n"); return 1; } do { do_sleep=0; FD_ZERO(&read_fd_set); FD_ZERO(&write_fd_set); FD_ZERO(&except_fd_set); ret = SPDY_get_timeout(daemon, &timeoutlong); if(new_session && !closed_session) { if(SPDY_NO == ret) { killchild("SPDY_get_timeout returned wrong SPDY_NO"); } /*if(timeoutlong) { killchild("SPDY_get_timeout returned wrong timeout"); }*/ now = monotonic_time (); if(now - beginning > TIMEOUT*1000 + SELECT_MS_TIMEOUT) { printf("Started at: %llums\n",beginning); printf("Now is: %llums\n",now); printf("Timeout is: %i\n",TIMEOUT); printf("Select Timeout is: %ims\n",SELECT_MS_TIMEOUT); printf("SPDY_get_timeout gave: %llums\n",timeoutlong); killchild("Timeout passed but session was not closed"); } if(timeoutlong > beginning + TIMEOUT *1000) { printf("Started at: %llums\n",beginning); printf("Now is: %llums\n",now); printf("Timeout is: %i\n",TIMEOUT); printf("Select Timeout is: %ims\n",SELECT_MS_TIMEOUT); printf("SPDY_get_timeout gave: %llums\n",timeoutlong); killchild("SPDY_get_timeout returned wrong timeout"); } } else { if(SPDY_YES == ret) { killchild("SPDY_get_timeout returned wrong SPDY_YES"); } } if(SPDY_NO == ret || timeoutlong >= 1000) { timeout.tv_sec = 1; timeout.tv_usec = 0; } else { timeout.tv_sec = timeoutlong / 1000; timeout.tv_usec = (timeoutlong % 1000) * 1000; } //ignore values timeout.tv_sec = 0; timeout.tv_usec = SELECT_MS_TIMEOUT * 1000; maxfd = SPDY_get_fdset (daemon, &read_fd_set, &write_fd_set, &except_fd_set); ret = select(maxfd+1, &read_fd_set, &write_fd_set, &except_fd_set, &timeout); switch(ret) { case -1: printf("select error: %i\n", errno); break; case 0: /*if(new_session) { killchild("select returned wrong number"); }*/ break; default: SPDY_run(daemon); if(0 == beginning) { beginning = monotonic_time (); } /*if(do_sleep) { sleep(TIMEOUT); do_sleep = 0; }*/ break; } } while(waitpid(child,&childstatus,WNOHANG) != child); if(!new_session || !closed_session) { killchild("child is dead, callback wasn't called"); } ret = SPDY_get_timeout(daemon, &timeoutlong); if(SPDY_YES == ret) { killchild("SPDY_get_timeout returned wrong SPDY_YES after child died"); } SPDY_stop_daemon(daemon); SPDY_deinit(); return 0; }
//parent proc int parentproc(int child) { int childstatus = 0; unsigned long long timeoutlong=0; struct timeval timeout; int ret; fd_set read_fd_set; fd_set write_fd_set; fd_set except_fd_set; int maxfd = -1; struct SPDY_Daemon *daemon; SPDY_init(); daemon = SPDY_start_daemon(port, DATA_DIR "cert-and-key.pem", DATA_DIR "cert-and-key.pem", &new_session_callback,NULL,NULL,NULL,CLS,SPDY_DAEMON_OPTION_END); if(NULL==daemon){ printf("no daemon\n"); return 1; } do { FD_ZERO(&read_fd_set); FD_ZERO(&write_fd_set); FD_ZERO(&except_fd_set); ret = SPDY_get_timeout(daemon, &timeoutlong); if(SPDY_NO == ret || timeoutlong > 1000) { timeout.tv_sec = 1; timeout.tv_usec = 0; } else { timeout.tv_sec = timeoutlong / 1000; timeout.tv_usec = (timeoutlong % 1000) * 1000; } maxfd = SPDY_get_fdset (daemon, &read_fd_set, &write_fd_set, &except_fd_set); ret = select(maxfd+1, &read_fd_set, &write_fd_set, &except_fd_set, &timeout); switch(ret) { case -1: printf("select error: %i\n", errno); killchild(child, "select error"); break; case 0: break; default: SPDY_run(daemon); break; } } while(loop && waitpid(child,&childstatus,WNOHANG) != child); SPDY_stop_daemon(daemon); SPDY_deinit(); if(loop) return WEXITSTATUS(childstatus); if(waitpid(child,&childstatus,WNOHANG) == child) return WEXITSTATUS(childstatus); kill(child,SIGKILL); waitpid(child,&childstatus,0); return 0; }
Exec::Impl::~Impl () { killchild (); }