/* (c) 2009 Jerome Loyet */
#include "php.h"
+#include "SAPI.h"
#include <stdio.h>
#include "fpm_config.h"
struct fpm_shm_s *fpm_status_shm = NULL;
static char *fpm_status_pool = NULL;
static char *fpm_status_uri = NULL;
-static char *fpm_status_ping= NULL;
-static char *fpm_status_pong= NULL;
+static char *fpm_status_ping_uri = NULL;
+static char *fpm_status_ping_response = NULL;
int fpm_status_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
zlog(ZLOG_ERROR, "[pool %s] ping is set (%s) but pong is not set.", wp->config->name, wp->config->ping_path);
return -1;
}
- fpm_status_ping = strdup(wp->config->ping_path);
- fpm_status_pong = strdup(wp->config->ping_response);
+ fpm_status_ping_uri = strdup(wp->config->ping_path);
+ fpm_status_ping_response = strdup(wp->config->ping_response);
}
}
return 0;
}
/* }}} */
-static void fpm_status_handle_status_txt(struct fpm_status_s *status, char **output, char **content_type) /* {{{ */
+int fpm_status_handle_request() /* {{{ */
{
- if (!status || !output || !content_type) {
- return;
+ struct fpm_status_s status;
+ char *buffer, *syntax;
+
+ if (!SG(request_info).request_uri) {
+ return 0;
}
- spprintf(output, 0,
- "pool: %s\n"
- "process manager: %s\n"
- "accepted conn: %lu\n"
-#if HAVE_FPM_LQ
- "listen queue len: %u\n"
- "max listen queue len: %d\n"
-#endif
- "idle processes: %d\n"
- "active processes: %d\n"
- "total processes: %d\n"
- "max children reached: %u\n",
- fpm_status_pool,
- status->pm == PM_STYLE_STATIC ? "static" : "dynamic",
- status->accepted_conn,
-#if HAVE_FPM_LQ
- status->cur_lq,
- status->max_lq,
-#endif
- status->idle,
- status->active,
- status->total,
- status->max_children_reached);
+ /* PING */
+ if (fpm_status_ping_uri && fpm_status_ping_response && !strcmp(fpm_status_ping_uri, SG(request_info).request_uri)) {
+ sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1 TSRMLS_CC);
+ SG(sapi_headers).http_response_code = 200;
+ PUTS(fpm_status_ping_response);
+ return 1;
+ }
- spprintf(content_type, 0, "Content-Type: text/plain");
-}
-/* }}} */
+ /* STATUS */
+ if (fpm_status_uri && !strcmp(fpm_status_uri, SG(request_info).request_uri)) {
-static void fpm_status_handle_status_html(struct fpm_status_s *status, char **output, char **content_type) /* {{{ */
-{
- if (!status || !output || !content_type) {
- return;
- }
+ if (!fpm_status_shm || !fpm_status_shm->mem) {
+ zlog(ZLOG_ERROR, "[pool %s] unable to find or access status shared memory", fpm_status_pool);
+ SG(sapi_headers).http_response_code = 500;
+ sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1 TSRMLS_CC);
+ PUTS("Internal error. Please review log file for errors.");
+ return 1;
+ }
+
+ /* one shot operation */
+ status = *(struct fpm_status_s *)fpm_status_shm->mem;
- spprintf(output, 0,
- "<table>\n"
- "<tr><th>pool</th><td>%s</td></tr>\n"
- "<tr><th>process manager</th><td>%s</td></tr>\n"
- "<tr><th>accepted conn</th><td>%lu</td></tr>\n"
+ if (status.idle < 0 || status.active < 0 || status.total < 0) {
+ zlog(ZLOG_ERROR, "[pool %s] invalid status values", fpm_status_pool);
+ SG(sapi_headers).http_response_code = 500;
+ sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1 TSRMLS_CC);
+ PUTS("Internal error. Please review log file for errors.");
+ return 1;
+ }
+
+ /* HTML */
+ if (SG(request_info).query_string && strstr(SG(request_info).query_string, "html")) {
+ sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1 TSRMLS_CC);
+ syntax =
+ "<table>\n"
+ "<tr><th>pool</th><td>%s</td></tr>\n"
+ "<tr><th>process manager</th><td>%s</td></tr>\n"
+ "<tr><th>accepted conn</th><td>%lu</td></tr>\n"
#if HAVE_FPM_LQ
- "<tr><th>listen queue len</th><td>%u</td></tr>\n"
- "<tr><th>max listen queue len</th><td>%d</td></tr>\n"
+ "<tr><th>listen queue len</th><td>%u</td></tr>\n"
+ "<tr><th>max listen queue len</th><td>%d</td></tr>\n"
#endif
- "<tr><th>idle processes</th><td>%d</td></tr>\n"
- "<tr><th>active processes</th><td>%d</td></tr>\n"
- "<tr><th>total processes</th><td>%d</td></tr>\n"
- "<tr><th>max children reached</th><td>%u</td></tr>\n"
- "</table>",
- fpm_status_pool,
- status->pm == PM_STYLE_STATIC ? "static" : "dynamic",
- status->accepted_conn,
+ "<tr><th>idle processes</th><td>%d</td></tr>\n"
+ "<tr><th>active processes</th><td>%d</td></tr>\n"
+ "<tr><th>total processes</th><td>%d</td></tr>\n"
+ "<tr><th>max children reached</th><td>%u</td></tr>\n"
+ "</table>";
+
+ /* XML */
+ } else if (SG(request_info).request_uri && strstr(SG(request_info).query_string, "xml")) {
+ sapi_add_header_ex(ZEND_STRL("Content-Type: text/xml"), 1, 1 TSRMLS_CC);
+ syntax =
+ "<?xml version=\"1.0\" ?>\n"
+ "<status>\n"
+ "<pool>%s</pool>\n"
+ "<process-manager>%s</process-manager>\n"
+ "<accepted-conn>%lu</accepted-conn>\n"
#if HAVE_FPM_LQ
- status->cur_lq,
- status->max_lq,
+ "<listen-queue-len>%u</listen-queue-len>\n"
+ "<max-listen-queue-len>%d</max-listen-queue-len>\n"
#endif
- status->idle,
- status->active,
- status->total,
- status->max_children_reached);
-
- spprintf(content_type, 0, "Content-Type: text/html");
-}
-/* }}} */
-
-static void fpm_status_handle_status_json(struct fpm_status_s *status, char **output, char **content_type) /* {{{ */
-{
- if (!status || !output || !content_type) {
- return;
- }
-
- spprintf(output, 0,
- "{"
- "\"pool\":\"%s\","
- "\"process manager\":\"%s\","
- "\"accepted conn\":%lu,"
+ "<idle-processes>%d</idle-processes>\n"
+ "<active-processes>%d</active-processes>\n"
+ "<total-processes>%d</total-processes>\n"
+ "<max-children-reached>%u</max-children-reached>\n"
+ "</status>";
+
+ /* JSON */
+ } else if (SG(request_info).request_uri && strstr(SG(request_info).query_string, "json")) {
+ sapi_add_header_ex(ZEND_STRL("Content-Type: application/json"), 1, 1 TSRMLS_CC);
+
+ syntax =
+ "{"
+ "\"pool\":\"%s\","
+ "\"process manager\":\"%s\","
+ "\"accepted conn\":%lu,"
#if HAVE_FPM_LQ
- "\"listen queue len\":%u,"
- "\"max listen queue len\":%d,"
+ "\"listen queue len\":%u,"
+ "\"max listen queue len\":%d,"
#endif
- "\"idle processes\":%d,"
- "\"active processes\":%d,"
- "\"total processes\":%d,"
- "\"max children reached\":%u"
- "}",
- fpm_status_pool,
- status->pm == PM_STYLE_STATIC ? "static" : "dynamic",
- status->accepted_conn,
+ "\"idle processes\":%d,"
+ "\"active processes\":%d,"
+ "\"total processes\":%d,"
+ "\"max children reached\":%u"
+ "}";
+
+ /* TEXT */
+ } else {
+ sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1 TSRMLS_CC);
+ syntax =
+ "pool: %s\n"
+ "process manager: %s\n"
+ "accepted conn: %lu\n"
#if HAVE_FPM_LQ
- status->cur_lq,
- status->max_lq,
+ "listen queue len: %u\n"
+ "max listen queue len: %d\n"
#endif
- status->idle,
- status->active,
- status->total,
- status->max_children_reached);
-
- spprintf(content_type, 0, "Content-Type: application/json");
-}
-/* }}} */
-
-/* return 0 if it's not the request page
- * return 1 if ouput has been set)
- * *output unchanged: error (return 500)
- * *output changed: no error (return 200)
- */
-int fpm_status_handle_status(char *uri, char *query_string, char **output, char **content_type) /* {{{ */
-{
- struct fpm_status_s status;
-
- if (!fpm_status_uri || !uri) {
- return 0;
- }
-
- /* It's not the status page */
- if (strcmp(fpm_status_uri, uri)) {
- return 0;
- }
-
- if (!output || !content_type || !fpm_status_shm) {
- return 1;
- }
-
- if (!fpm_status_shm->mem) {
- return 1;
- }
-
- /* one shot operation */
- status = *(struct fpm_status_s *)fpm_status_shm->mem;
+ "idle processes: %d\n"
+ "active processes: %d\n"
+ "total processes: %d\n"
+ "max children reached: %u\n";
+ }
- if (status.idle < 0 || status.active < 0 || status.total < 0) {
- return 1;
- }
+ spprintf(&buffer, 0, syntax,
+ fpm_status_pool,
+ status.pm == PM_STYLE_STATIC ? "static" : "dynamic",
+ status.accepted_conn,
+#if HAVE_FPM_LQ
+ status.cur_lq,
+ status.max_lq,
+#endif
+ status.idle,
+ status.active,
+ status.total,
+ status.max_children_reached);
- if (query_string && strstr(query_string, "html")) {
- fpm_status_handle_status_html(&status, output, content_type);
- } else if (query_string && strstr(query_string, "json")) {
- fpm_status_handle_status_json(&status, output, content_type);
- } else {
- fpm_status_handle_status_txt(&status, output, content_type);
- }
+ SG(sapi_headers).http_response_code = 200;
+ PUTS(buffer);
+ efree(buffer);
- if (!*output || !content_type) {
- zlog(ZLOG_ERROR, "[pool %s] unable to allocate status ouput buffer", fpm_status_pool);
return 1;
}
- return 1;
-}
-/* }}} */
-
-char *fpm_status_handle_ping(char *uri) /* {{{ */
-{
- if (!fpm_status_ping || !fpm_status_pong || !uri) {
- return NULL;
- }
-
- /* It's not the status page */
- if (strcmp(fpm_status_ping, uri)) {
- return NULL;
- }
-
- return fpm_status_pong;
+ return 0;
}
/* }}} */