00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #ifdef HAVE_SYS_TIME_H
00029 #include <sys/time.h>
00030 #endif
00031
00032 #ifdef HAVE_STDIO_H
00033 #include <stdio.h>
00034 #endif
00035
00036 #ifdef HAVE_STRING_H
00037 #include <string.h>
00038 #endif
00039
00040 #ifdef HAVE_PTHREAD_H
00041 #include <pthread.h>
00042 #endif
00043
00044 #include "nanohttp-error.h"
00045 #include "nanohttp-common.h"
00046 #include "nanohttp-stream.h"
00047 #include "nanohttp-request.h"
00048 #include "nanohttp-server.h"
00049
00050 #include "nanohttp-admin.h"
00051
00052 static void
00053 _httpd_admin_send_title(httpd_conn_t *conn, const char *title)
00054 {
00055 httpd_send_header(conn, 200, HTTP_STATUS_200_REASON_PHRASE);
00056
00057 http_output_stream_write_string(conn->out,
00058 "<html>"
00059 "<head>");
00060 http_output_stream_write_string(conn->out,
00061 "<style>"
00062 ".logo {"
00063 " color: #005177;"
00064 " background-color: transparent;"
00065 " font-family: Calligraphic, arial, sans-serif;"
00066 " font-size: 36px;"
00067 "}"
00068 "</style>");
00069
00070 http_output_stream_write_string(conn->out,
00071 "</head>"
00072 "<body>"
00073 "<span class=\"logo\">nhttpd</span> ");
00074 http_output_stream_write_string(conn->out, title);
00075 http_output_stream_write_string(conn->out, "<hr />");
00076
00077 return;
00078 }
00079
00080 static inline void
00081 _httpd_admin_send_footer(httpd_conn_t *conn)
00082 {
00083 http_output_stream_write_string(conn->out,
00084 "</body>"
00085 "</html>");
00086
00087 return;
00088 }
00089
00090 static void
00091 _httpd_admin_list_services(httpd_conn_t *conn)
00092 {
00093 char buffer[1024];
00094 hservice_t *node;
00095
00096 _httpd_admin_send_title(conn, "Available services");
00097
00098 http_output_stream_write_string(conn->out, "<ul>");
00099 for (node = httpd_get_services(); node; node = node->next)
00100 {
00101 switch (node->status)
00102 {
00103 case NHTTPD_SERVICE_DOWN:
00104 sprintf(buffer,
00105 "<li>"
00106 "<a href=\"%s\">%s</a> "
00107 "<a href=\"?" NHTTPD_ADMIN_QUERY_ACTIVATE_SERVICE "=%s\">[Activate]</a> "
00108 "<a href=\"?" NHTTPD_ADMIN_QUERY_STATISTICS "=%s\">[Statistics]</a>"
00109 "</li>",
00110 node->context, node->context, node->context, node->context);
00111 break;
00112 case NHTTPD_SERVICE_UP:
00113 default:
00114 sprintf(buffer,
00115 "<li>"
00116 "<a href=\"%s\">%s</a> "
00117 "<a href=\"?" NHTTPD_ADMIN_QUERY_PASSIVATE_SERVICE "=%s\">[Passivate]</a> "
00118 "<a href=\"?" NHTTPD_ADMIN_QUERY_STATISTICS "=%s\">[Statistics]</a> "
00119 "</li>",
00120 node->context, node->context, node->context, node->context);
00121 break;
00122 }
00123 http_output_stream_write_string(conn->out, buffer);
00124 }
00125 http_output_stream_write_string(conn->out, "</ul>");
00126
00127 _httpd_admin_send_footer(conn);
00128
00129 return;
00130 }
00131
00132 static void
00133 _httpd_admin_list_statistics(httpd_conn_t *conn, const char *service_name)
00134 {
00135 char buffer[1024];
00136 hservice_t *service;
00137
00138 sprintf(buffer, "Listing statistics for service <b>%s</b>", service_name);
00139 _httpd_admin_send_title(conn, buffer);
00140
00141 if (!(service = httpd_find_service(service_name)))
00142 {
00143 http_output_stream_write_string(conn->out,
00144 "<p>"
00145 "Service not found!"
00146 "</p>");
00147 _httpd_admin_send_footer(conn);
00148 return;
00149 }
00150
00151 pthread_rwlock_rdlock(&(service->statistics->lock));
00152 sprintf(buffer, "<ul>"
00153 "<li>Requests served: %lu</li>"
00154 "<li>Bytes read: %lu</li>"
00155 "<li>Bytes sent: %lu</li>"
00156 "<li>Time used: %li.%li sec</li>"
00157 "<ul>",
00158 service->statistics->requests,
00159 service->statistics->bytes_received,
00160 service->statistics->bytes_transmitted,
00161 service->statistics->time.tv_sec,
00162 service->statistics->time.tv_usec);
00163 pthread_rwlock_unlock(&(service->statistics->lock));
00164
00165 http_output_stream_write_string(conn->out, buffer);
00166
00167 _httpd_admin_send_footer(conn);
00168
00169 return;
00170 }
00171
00172 static void
00173 _httpd_admin_enable_service(httpd_conn_t *conn, const char *service_name)
00174 {
00175 hservice_t *service;
00176 char buffer[1024];
00177
00178 sprintf(buffer, "Activating service <b>%s</b>", service_name);
00179 _httpd_admin_send_title(conn, buffer);
00180
00181 if (!(service = httpd_find_service(service_name)))
00182 {
00183 http_output_stream_write_string(conn->out,
00184 "<p>"
00185 "Service not found!"
00186 "</p>");
00187
00188 _httpd_admin_send_footer(conn);
00189 return;
00190 }
00191
00192 httpd_enable_service(service);
00193
00194 http_output_stream_write_string(conn->out,
00195 "<p>"
00196 "Service is up"
00197 "</p>");
00198
00199 _httpd_admin_send_footer(conn);
00200
00201 return;
00202 }
00203
00204 static void
00205 _httpd_admin_disable_service(httpd_conn_t *conn, const char *service_name)
00206 {
00207 hservice_t *service;
00208 char buffer[1024];
00209
00210 sprintf(buffer, "Passivating service <b>%s</b>", service_name);
00211 _httpd_admin_send_title(conn, buffer);
00212
00213 if (!(service = httpd_find_service(service_name)))
00214 {
00215 http_output_stream_write_string(conn->out,
00216 "<p>"
00217 "Service not found!"
00218 "</p>");
00219 _httpd_admin_send_footer(conn);
00220 return;
00221 }
00222
00223 httpd_disable_service(service);
00224
00225 http_output_stream_write_string(conn->out,
00226 "<p>"
00227 "Service is down"
00228 "</p>");
00229 _httpd_admin_send_footer(conn);
00230
00231 return;
00232 }
00233
00234 static void
00235 _httpd_admin_handle_get(httpd_conn_t * conn, struct hrequest_t *req)
00236 {
00237 char *param;
00238
00239 if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_SERVICES)))
00240 {
00241 _httpd_admin_list_services(conn);
00242 }
00243 else if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_STATISTICS)))
00244 {
00245 _httpd_admin_list_statistics(conn, param);
00246 }
00247 else if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_ACTIVATE_SERVICE)))
00248 {
00249 _httpd_admin_enable_service(conn, param);
00250 }
00251 else if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_PASSIVATE_SERVICE)))
00252 {
00253 _httpd_admin_disable_service(conn, param);
00254 }
00255 else
00256 {
00257 _httpd_admin_send_title(conn, "Welcome to the admin site");
00258
00259 http_output_stream_write_string(conn->out,
00260 "<ul>"
00261 "<li>"
00262 "<a href=\"?" NHTTPD_ADMIN_QUERY_SERVICES "\">Services</a>"
00263 "</li>"
00264 "<li>"
00265 "<a href=\"?" NHTTPD_ADMIN_QUERY_STATISTICS "\">Statistics</a>"
00266 "</li>"
00267 "</ul>");
00268
00269 _httpd_admin_send_footer(conn);
00270 }
00271
00272 return;
00273 }
00274
00275 static void
00276 _httpd_admin_entry(httpd_conn_t * conn, struct hrequest_t *req)
00277 {
00278 if (req->method == HTTP_REQUEST_GET)
00279 {
00280 _httpd_admin_handle_get(conn, req);
00281 }
00282 else
00283 {
00284 httpd_send_header(conn, 501, HTTP_STATUS_501_REASON_PHRASE);
00285 http_output_stream_write_string(conn->out,
00286 "<html>"
00287 "<head>"
00288 "</head>"
00289 "<body>"
00290 "<h1>Sorry!</h1>"
00291 "<hr />"
00292 "<div>POST Service is not implemented now. Use your browser.</div>"
00293 "</body>"
00294 "</html>");
00295 }
00296 return;
00297 }
00298
00299 herror_t
00300 httpd_admin_init_args(int argc, char **argv)
00301 {
00302 int i;
00303
00304 for (i=0; i<argc; i++)
00305 {
00306 if (!strcmp(argv[i], NHTTPD_ARG_ENABLE_ADMIN))
00307 {
00308 httpd_register("/nhttp", _httpd_admin_entry);
00309 break;
00310 }
00311 }
00312
00313 return H_OK;
00314 }