/***************************************************************************** * Open LiteSpeed is an open source HTTP server. * * Copyright (C) 2013 - 2015 LiteSpeed Technologies, Inc. * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses/. * *****************************************************************************/ /** * HOW TO TEST * /testsuspend/..... to set to suspend, and ?11 to set to handle * */ #define _GNU_SOURCE #include "../../include/ls.h" #include #include #include #include #include #include #include #include #define MNAME testsuspend extern lsi_module_t MNAME; void timer_callback(const void *session) { int len; const char *qs = g_api->get_req_query_string((const lsi_session_t *)session, &len); if (len > 1 && strstr(qs, "11")) g_api->register_req_handler((const lsi_session_t *)session, &MNAME, 12); g_api->create_session_resume_event((const lsi_session_t *)session, &MNAME); } void *thread_callback(void *session) { sleep(5); timer_callback(session); pthread_exit(NULL); } int suspendFunc(lsi_param_t *rec) { const char *uri; int len; uri = g_api->get_req_uri(rec->session, &len); if (len >= 12 && strcasestr(uri, "/testsuspend")) { // //#define USE_TIMER_HERE // #ifdef USE_TIMER_HERE // g_api->set_timer(5000, timer_callback, (void *)rec->_session); // return LSI_SUSPEND; // #else // pthread_t mythread; // int rc = pthread_create(&mythread, NULL, thread_callback, (void *)rec->_session); // if (rc == 0) // { // return LSI_SUSPEND; //If ret LSI_SUSPEND, should set a timer or a thread to call hookResumeCallback() // } // #endif pthread_t mythread; int rc = pthread_create(&mythread, NULL, thread_callback, (void *)rec->session); if (rc == 0) { return LSI_SUSPEND; //If ret LSI_SUSPEND, should set a timer or a thread to call hookResumeCallback() } } return LSI_OK; } static lsi_serverhook_t serverHooks[] = { {LSI_HKPT_RCVD_REQ_HEADER, suspendFunc, LSI_HOOK_NORMAL, LSI_FLAG_ENABLED}, LSI_HOOK_END //Must put this at the end position }; static int init_module(lsi_module_t *pModule) { return 0; } //The first time the below function will be called, then onWriteEvent will be called next and next static int PsHandlerProcess(const lsi_session_t *session) { char tmBuf[30]; time_t t; struct tm *tmp; t = time(NULL); tmp = gmtime(&t); strftime(tmBuf, 30, "%a, %d %b %Y %H:%M:%S GMT", tmp); g_api->set_resp_header(session, LSI_RSPHDR_CONTENT_TYPE, NULL, 0, "text/html", sizeof("text/html") - 1, LSI_HEADEROP_SET); g_api->set_resp_header(session, LSI_RSPHDR_LAST_MODIFIED, NULL, 0, tmBuf, 29, LSI_HEADEROP_SET); char buf[1024]; sprintf(buf, "This test suspend for 5 seconds and resume, now time is %ld

", (long)(time(NULL))); g_api->append_resp_body(session, buf, strlen(buf)); g_api->end_resp(session); return 0; } lsi_reqhdlr_t myhandler = { PsHandlerProcess, NULL, NULL, NULL }; LSMODULE_EXPORT lsi_module_t MNAME = { LSI_MODULE_SIGNATURE, init_module, &myhandler, NULL, "", serverHooks};