Merged silc_1_1_branch to trunk.
[silc.git] / apps / silcd / server_http.c
1 /*
2
3   server_http.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "serverincludes.h"
21 #include "server_internal.h"
22
23 /************************* Types and definitions ****************************/
24
25 #define HTTP_START1                                             \
26 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""           \
27 "\"http://www.w3.ohtml4/strict.dtd\">\n"                        \
28 "<html>\n"                                                      \
29 "<head>\n"                                                      \
30 "<meta http-equiv=\"Content-Type\" content=\"text/html; "       \
31 "charset=iso-8859-1\">\n"                                       \
32 "<title>\n"
33
34 #define HTTP_START2                             \
35 "</title>\n"                                    \
36 "</head>\n"                                     \
37 "<body>\n"
38
39 #define HTTP_END                                \
40 "</body>\n"                                     \
41 "</html>\n"
42
43 #define HTTP_404 "404 Not Found"
44 #define HTTP_404_B "<body><h1>404 Not Found</h1><p>The page you are looking for cannot be located</body>"
45
46 #define STAT_OUTPUT(fmt, stat)                                  \
47 do {                                                            \
48   silc_snprintf(buf, sizeof(buf), fmt "<br>", (int)stat);       \
49   silc_buffer_strformat(&page, buf, SILC_STRFMT_END);           \
50 } while(0)
51
52
53 /****************************** HTTP access *********************************/
54
55 /* HTTP server callback.  We serve pages here. */
56
57 static void silc_server_http_callback(SilcHttpServer httpd,
58                                       SilcHttpConnection conn,
59                                       const char *uri,
60                                       const char *method,
61                                       SilcBuffer data,
62                                       void *context)
63 {
64   SilcServer server = context;
65   SilcBufferStruct page;
66   unsigned char buf[128];
67
68   SILC_LOG_DEBUG(("HTTP callback: %s %s", method, uri));
69
70   memset(&page, 0, sizeof(page));
71
72   if (!strcasecmp(method, "GET")) {
73
74     /* Index page */
75     if (!strcmp(uri, "/") || !strcmp(uri, "/index.html")) {
76       SILC_LOG_DEBUG(("Index"));
77
78       silc_buffer_strformat(&page, HTTP_START1, SILC_STRFMT_END);
79       silc_buffer_strformat(&page, "SILC ",
80                             server->server_type == SILC_ROUTER ?
81                             "Router " : "Server ", server->server_name,
82                             SILC_STRFMT_END);
83       silc_buffer_strformat(&page, HTTP_START2, SILC_STRFMT_END);
84
85       silc_buffer_strformat(&page, "<h1>SILC ",
86                             server->server_type == SILC_ROUTER ?
87                             "Router " : "Server ", server->server_name,
88                             "</h1><hr><p>",
89                             SILC_STRFMT_END);
90
91       silc_buffer_strformat(&page, "<b>Statistics:</b><p>", SILC_STRFMT_END);
92
93       STAT_OUTPUT("Clients    : %d", server->stat.my_clients);
94       STAT_OUTPUT("Servers    : %d", server->stat.my_servers);
95       STAT_OUTPUT("Routers    : %d", server->stat.my_routers);
96       STAT_OUTPUT("Channels   : %d", server->stat.my_channels);
97       STAT_OUTPUT("Joined users   : %d", server->stat.my_chanclients);
98       STAT_OUTPUT("Aways      : %d", server->stat.my_aways);
99       STAT_OUTPUT("Detached clients : %d", server->stat.my_detached);
100       STAT_OUTPUT("Server operators : %d", server->stat.my_server_ops);
101       STAT_OUTPUT("Router operators : %d", server->stat.my_router_ops);
102
103       silc_buffer_strformat(&page, "<p><b>Global Statistics:</b><p>",
104                             SILC_STRFMT_END);
105       STAT_OUTPUT("Cell clients  : %d", server->stat.cell_clients);
106       STAT_OUTPUT("Cell servers  : %d", server->stat.cell_servers);
107       STAT_OUTPUT("Cell channels : %d", server->stat.cell_channels);
108       STAT_OUTPUT("Cell joined users : %d", server->stat.cell_chanclients);
109       STAT_OUTPUT("All clients   : %d", server->stat.clients);
110       STAT_OUTPUT("All servers   : %d", server->stat.servers);
111       STAT_OUTPUT("All routers   : %d", server->stat.routers);
112       STAT_OUTPUT("All channels  : %d", server->stat.channels);
113       STAT_OUTPUT("All joined users  : %d", server->stat.chanclients);
114       STAT_OUTPUT("All aways     : %d", server->stat.aways);
115       STAT_OUTPUT("All detached clients : %d", server->stat.detached);
116       STAT_OUTPUT("All server operators : %d", server->stat.server_ops);
117       STAT_OUTPUT("All router operators : %d", server->stat.router_ops);
118
119       silc_buffer_strformat(&page, "<p><b>Internal Statistics:</b><p>",
120                             SILC_STRFMT_END);
121       STAT_OUTPUT("Connection attempts : %d", server->stat.conn_attempts);
122       STAT_OUTPUT("Connection failures : %d", server->stat.conn_failures);
123       STAT_OUTPUT("Authentication attempts : %d", server->stat.auth_attempts);
124       STAT_OUTPUT("Authentication failures : %d", server->stat.auth_failures);
125       STAT_OUTPUT("Packets sent  : %d", server->stat.packets_sent);
126       STAT_OUTPUT("Packets received  : %d", server->stat.packets_received);
127       STAT_OUTPUT("Commands sent : %d", server->stat.commands_sent);
128       STAT_OUTPUT("Commands received : %d", server->stat.commands_received);
129       STAT_OUTPUT("Connections   : %d", server->stat.conn_num);
130
131       silc_buffer_strformat(&page, HTTP_END, SILC_STRFMT_END);
132
133       silc_http_server_send(httpd, conn, &page);
134       silc_buffer_purge(&page);
135       return;
136     }
137   }
138
139   silc_http_server_send_error(httpd, conn, HTTP_404, HTTP_404_B);
140 }
141
142 void silc_server_http_init(SilcServer server)
143 {
144   if (!server->config->httpd_ip)
145     return;
146
147   /* Allocate HTTP server */
148   server->httpd = silc_http_server_alloc(server->config->httpd_ip,
149                                          server->config->httpd_port,
150                                          server->schedule,
151                                          silc_server_http_callback,
152                                          server);
153 }
154
155 void silc_server_http_uninit(SilcServer server)
156 {
157   if (server->httpd)
158     silc_http_server_free(server->httpd);
159 }