Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 156 lines (128 sloc) 4.324 kB
eeebb66 @jayridge initial import of pubsub
jayridge authored
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "queue.h"
5b0770f @nathanfolkman Fixed args.
nathanfolkman authored
5 #include "simplehttp.h"
6 #include "json/json.h"
eeebb66 @jayridge initial import of pubsub
jayridge authored
7
9eca153 @nathanfolkman Added BUFSIZE.
nathanfolkman authored
8 #define BUFSZ 1024
09802dd @nathanfolkman Adding support for multipart.
nathanfolkman authored
9 #define BOUNDARY "xXPubSubXx"
9eca153 @nathanfolkman Added BUFSIZE.
nathanfolkman authored
10
eeebb66 @jayridge initial import of pubsub
jayridge authored
11 typedef struct cli {
12 struct evbuffer *buf;
13 struct evhttp_request *req;
14 TAILQ_ENTRY(cli) entries;
15 } cli;
16 TAILQ_HEAD(, cli) clients;
17
b1d1329 @nathanfolkman Trying to fix new stats command.
nathanfolkman authored
18 void argtoi(struct evkeyvalq *args, char *key, int *val, int def);
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
19 void finalize_json(struct evhttp_request *req, struct evbuffer *evb,
20 struct evkeyvalq *args, struct json_object *jsobj);
21
22 uint32_t totalConns = 0;
23 uint32_t currentConns = 0;
24 uint32_t msgRecv = 0;
25 uint32_t msgSent = 0;
26
27 void finalize_json(struct evhttp_request *req, struct evbuffer *evb,
28 struct evkeyvalq *args, struct json_object *jsobj)
29 {
30 char *json, *jsonp;
31
32 jsonp = (char *)evhttp_find_header(args, "jsonp");
33 json = json_object_to_json_string(jsobj);
34 if (jsonp) {
35 evbuffer_add_printf(evb, "%s(%s)\n", jsonp, json);
36 } else {
37 evbuffer_add_printf(evb, "%s\n", json);
38 }
39 json_object_put(jsobj); // Odd free function
40
41 evhttp_send_reply(req, HTTP_OK, "OK", evb);
42 evhttp_clear_headers(args);
43 }
44
45 void argtoi(struct evkeyvalq *args, char *key, int *val, int def)
46 {
47 char *tmp;
48
49 *val = def;
50 tmp = (char *)evhttp_find_header(args, (const char *)key);
51 if (tmp) {
52 *val = atoi(tmp);
53 }
54 }
55
56 void
57 stats(struct evhttp_request *req, struct evbuffer *evb, void *ctx)
58 {
5b0770f @nathanfolkman Fixed args.
nathanfolkman authored
59 struct evkeyvalq args;
b1d1329 @nathanfolkman Trying to fix new stats command.
nathanfolkman authored
60 struct json_object *jsobj;
61 int reset;
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
62 char *uri, *queue, *total_gets, *total_puts, *total;
63 char kbuf[BUFSZ];
64
65 uri = evhttp_decode_uri(req->uri);
66 evhttp_parse_query(uri, &args);
67 free(uri);
68
b1d1329 @nathanfolkman Trying to fix new stats command.
nathanfolkman authored
69 argtoi(&args, "reset", &reset, 0);
70 jsobj = json_object_new_object();
71 json_object_object_add(jsobj, "totalConnections", json_object_new_int(totalConns));
72 json_object_object_add(jsobj, "currentConnections", json_object_new_int(currentConns));
73 json_object_object_add(jsobj, "messagesReceived", json_object_new_int(msgRecv));
74 json_object_object_add(jsobj, "messagesSent", json_object_new_int(msgSent));
75
76 if (reset) {
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
77 totalConns = 0;
78 currentConns = 0;
79 msgRecv = 0;
80 msgSent = 0;
81 }
82
b1d1329 @nathanfolkman Trying to fix new stats command.
nathanfolkman authored
83 finalize_json(req, evb, &args, jsobj);
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
84 }
eeebb66 @jayridge initial import of pubsub
jayridge authored
85
86 void on_close(struct evhttp_connection *evcon, void *ctx)
87 {
88 struct cli *client = (struct cli *)ctx;
89
90 if (client) {
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
91 currentConns--;
eeebb66 @jayridge initial import of pubsub
jayridge authored
92 TAILQ_REMOVE(&clients, client, entries);
93 evbuffer_free(client->buf);
94 free(client);
95 }
96 }
97
98 void pub_cb(struct evhttp_request *req, struct evbuffer *evb, void *ctx)
99 {
100 int i = 0;
101 struct cli *client;
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
102
103 msgRecv++;
5b0770f @nathanfolkman Fixed args.
nathanfolkman authored
104 totalConns++;
eeebb66 @jayridge initial import of pubsub
jayridge authored
105
106 TAILQ_FOREACH(client, &clients, entries) {
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
107 msgSent++;
eeebb66 @jayridge initial import of pubsub
jayridge authored
108 evbuffer_drain(client->buf, EVBUFFER_LENGTH(client->buf));
09802dd @nathanfolkman Adding support for multipart.
nathanfolkman authored
109
110 evbuffer_add_printf(client->buf, "Content-Type: %s\n\n", "text/html");
eeebb66 @jayridge initial import of pubsub
jayridge authored
111 evbuffer_add(client->buf, req->input_buffer->buffer, EVBUFFER_LENGTH(req->input_buffer));
09802dd @nathanfolkman Adding support for multipart.
nathanfolkman authored
112 evbuffer_add_printf(client->buf, "--%s\n", BOUNDARY);
113
114 /* evbuffer_add(client->buf, "\r\n", 2); */
115
eeebb66 @jayridge initial import of pubsub
jayridge authored
116 printf("sending to client\n");
117 evhttp_send_reply_chunk(client->req, client->buf);
118 i++;
119 }
5b0770f @nathanfolkman Fixed args.
nathanfolkman authored
120
eeebb66 @jayridge initial import of pubsub
jayridge authored
121 evbuffer_add_printf(evb, "Published to %d clients.\n", i);
122 evhttp_send_reply(req, HTTP_OK, "OK", evb);
123 }
124
125 void sub_cb(struct evhttp_request *req, struct evbuffer *evb, void *ctx)
126 {
127 struct cli *client;
128
129 printf("sub_cb\n");
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
130 currentConns++;
131 totalConns++;
eeebb66 @jayridge initial import of pubsub
jayridge authored
132 client = calloc(1, sizeof(*client));
133 client->req = req;
134 client->buf = evbuffer_new();
09802dd @nathanfolkman Adding support for multipart.
nathanfolkman authored
135 evhttp_add_header(client->req->output_headers, "Content-Type",
136 "multipart/x-mixed-replace; boundary=" BOUNDARY);
137 evbuffer_add_printf(client->buf, "--%s\n", BOUNDARY);
138 evhttp_send_reply_start(client->req, HTTP_OK, "OK");
139 evhttp_send_reply_chunk(client->req, client->buf);
eeebb66 @jayridge initial import of pubsub
jayridge authored
140 TAILQ_INSERT_TAIL(&clients, client, entries);
141 evhttp_connection_set_closecb(req->evcon, on_close, (void *)client);
142 }
143
144 int
145 main(int argc, char **argv)
146 {
147 TAILQ_INIT(&clients);
148 simplehttp_init();
149 simplehttp_set_cb("/pub*", pub_cb, NULL);
150 simplehttp_set_cb("/sub*", sub_cb, NULL);
1604d50 @nathanfolkman Added stats.
nathanfolkman authored
151 simplehttp_set_cb("/stats*", stats, NULL);
eeebb66 @jayridge initial import of pubsub
jayridge authored
152 simplehttp_main(argc, argv);
153
154 return 0;
155 }
Something went wrong with that request. Please try again.