/* * demo3.c: sample event-driven module showing how to * handle postponed requests. */ #include #include "tuxmodule.h" #ifdef TUXAPI_declare TUXAPI_declare; #endif #define REPLY_HEADER "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" #define REPLY_HEADER_LEN (sizeof(REPLY_HEADER)-1) #define QUERY_ERROR "no query string.\n" #define QUERY_ERROR_LEN (sizeof(QUERY_ERROR)-1) #define ERROR "GET_OBJECT error.\n" #define ERROR_LEN (sizeof(ERROR)-1) int TUXAPI_handle_events (user_req_t *req) { int ret = TUX_RETURN_USERSPACE_REQUEST; switch (req->event) { /* * A new request starts with event code 0. */ case 0: write (req->sock, REPLY_HEADER, REPLY_HEADER_LEN); req->http_status = 200; if (!req->query[0]) { write (req->sock, QUERY_ERROR, QUERY_ERROR_LEN); goto abort; } /* * set req->objectname is to the requested object * in the query string. This simulates * simple static GETs. */ strcpy(req->objectname, req->query); req->event = 1; ret = tux(TUX_ACTION_GET_OBJECT, req); if (ret < 0 || req->error) { write (req->sock, ERROR, ERROR_LEN); goto abort; } break; case 1: { int pid; if (req->error) { write (req->sock, ERROR, ERROR_LEN); goto abort; } req->event = 2; ret = tux(TUX_ACTION_POSTPONE_REQ, req); pid = fork(); if (!pid) { sleep(3); ret = tux(TUX_ACTION_CONTINUE_REQ, (user_req_t *)req->sock); exit(0); } ret = tux(TUX_ACTION_EVENTLOOP, req); break; } case 2: req->event = 3; ret = tux(TUX_ACTION_SEND_OBJECT, req); break; case 3: abort: ret = tux(TUX_ACTION_FINISH_CLOSE_REQ, req); break; } return ret; }