root/src/stratcon_realtime_http.c

Revision 7e4ba07cef41176c62aec06ace775294d183bc2d, 19.8 kB (checked in by Thom May <thom@digital-science.com>, 4 years ago)

selectively disable -Wuninitialized for stratcon_realtime_http

GCC 4.5.2 appears to incorrectly detect part of FULLREAD as
uninitialized when it clearly isn't

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34 #include "eventer/eventer.h"
35 #include "noit_conf.h"
36 #include "utils/noit_hash.h"
37 #include "utils/noit_log.h"
38 #include "utils/noit_str.h"
39 #include "jlog/jlog.h"
40 #include "noit_jlog_listener.h"
41 #include "noit_listener.h"
42 #include "noit_http.h"
43 #include "noit_rest.h"
44 #include "noit_check.h"
45 #include "noit_livestream_listener.h"
46 #include "stratcon_realtime_http.h"
47 #include "stratcon_jlog_streamer.h"
48 #include "stratcon_datastore.h"
49
50 #include <ctype.h>
51 #include <unistd.h>
52 #include <assert.h>
53 #include <errno.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #ifdef HAVE_SYS_FILIO_H
57 #include <sys/filio.h>
58 #endif
59 #include <netinet/in.h>
60 #include <sys/un.h>
61 #include <arpa/inet.h>
62
63 /*
64  * it appears that GCC 4.5.2 incorrectly thinks that FULLREAD uses "mask"
65  * without initializing it, so disable that specific warning for this file
66  * for now
67  */
68
69 #pragma GCC diagnostic ignored "-Wuninitialized"
70
71 typedef struct realtime_recv_ctx_t {
72   int bytes_expected;
73   int bytes_read;
74   int bytes_written;
75   int body_len;
76   char *buffer;         /* These guys are for doing partial reads */
77
78   enum {
79     REALTIME_HTTP_WANT_INITIATE = 0,
80     REALTIME_HTTP_WANT_SEND_INTERVAL = 1,
81     REALTIME_HTTP_WANT_SEND_UUID = 2,
82     REALTIME_HTTP_WANT_HEADER = 3,
83     REALTIME_HTTP_WANT_BODY = 4,
84   } state;
85   int count;            /* Number of jlog messages we need to read */
86   u_int32_t hack_inc_id;
87   noit_http_session_ctx *ctx;
88   struct realtime_tracker *rt;
89 } realtime_recv_ctx_t;
90
91 typedef struct realtime_context {
92   enum { RC_INITIAL = 0, RC_REQ_RECV, RC_INTERESTS_RESOLVED, RC_FEEDING } setup;
93   struct realtime_tracker *checklist;
94   char *document_domain;
95 } realtime_context;
96
97 static realtime_context *alloc_realtime_context(const char *domain) {
98   realtime_context *ctx;
99   ctx = calloc(sizeof(*ctx), 1);
100   ctx->document_domain = strdup(domain);
101   return ctx;
102 }
103 static void free_realtime_tracker(struct realtime_tracker *rt) {
104   if(rt->noit) free(rt->noit);
105   free(rt);
106 }
107 static void clear_realtime_context(realtime_context *rc) {
108  rc->setup = RC_INITIAL;
109   while(rc->checklist) {
110     struct realtime_tracker *tofree;
111     tofree = rc->checklist;
112     rc->checklist = tofree->next;
113     free_realtime_tracker(tofree);
114   }
115   if(rc->document_domain) free(rc->document_domain);
116   rc->document_domain = NULL;
117 }
118 int
119 stratcon_line_to_javascript(noit_http_session_ctx *ctx, char *buff,
120                             u_int32_t inc_id) {
121   char buffer[1024];
122   char *scp, *ecp, *token;
123   int len;
124   const char *v, *cb = NULL;
125   noit_hash_table json = NOIT_HASH_EMPTY;
126   noit_http_request *req = noit_http_session_request(ctx);
127   char s_inc_id[42];
128
129   snprintf(s_inc_id, sizeof(s_inc_id), "script-%08x", inc_id);
130  
131   cb = noit_http_request_querystring(req, "cb");
132   for(v = cb; v && *v; v++)
133     if(!((*v >= '0' && *v <= '9') ||
134          (*v >= 'a' && *v <= 'z') ||
135          (*v >= 'A' && *v <= 'Z') ||
136          (*v == '_') || (*v == '.'))) {
137       cb = NULL;
138       break;
139     }
140   if(!cb) cb = "window.parent.plot_iframe_data";
141
142 #define BAIL_HTTP_WRITE do { \
143   noit_hash_destroy(&json, NULL, free); \
144   noitL(noit_error, "javascript emit failed: %s:%s:%d\n", \
145         __FILE__, __FUNCTION__, __LINE__); \
146   return -1; \
147 } while(0)
148
149 #define PROCESS_NEXT_FIELD(t,l) do { \
150   if(!*scp) goto bad_row; \
151   ecp = strchr(scp, '\t'); \
152   if(!ecp) goto bad_row; \
153   t = scp; \
154   l = (ecp-scp); \
155   scp = ecp + 1; \
156 } while(0)
157 #define PROCESS_LAST_FIELD(t,l) do { \
158   if(!*scp) ecp = scp; \
159   else { \
160     ecp = scp + strlen(scp); /* Puts us at the '\0' */ \
161     if(*(ecp-1) == '\n') ecp--; /* We back up on letter if we ended in \n */ \
162   } \
163   t = scp; \
164   l = (ecp-scp); \
165 } while(0)
166
167   scp = buff;
168   PROCESS_NEXT_FIELD(token,len); /* Skip the leader */
169   if(buff[1] == '\t' && (buff[0] == 'M' || buff[0] == 'S')) {
170     char target[256], module[256], name[256], uuid_str[UUID_STR_LEN+1];
171     noit_http_request *req = noit_http_session_request(ctx);
172     noit_hash_table *qs;
173     noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
174     const char *key;
175     int klen, i=0;
176     void *vval;
177     char type[2] = { '\0', '\0' };
178     type[0] = buff[0];
179
180 #define ra_write(a,b) if(noit_http_response_append(ctx, a, b) == noit_false) BAIL_HTTP_WRITE
181
182     snprintf(buffer, sizeof(buffer), "<script id=\"%s\">%s({", s_inc_id, cb);
183     ra_write(buffer, strlen(buffer));
184
185     qs = noit_http_request_querystring_table(req);
186     while(noit_hash_next(qs, &iter, &key, &klen, &vval)) {
187       if(!strcmp(key, "cb")) continue;
188       noit_hash_store(&json, key, klen, strdup(vval ?(char *)vval : "true"));
189     }
190     /* Time */
191     noit_hash_store(&json, "script_id", 9, strdup(s_inc_id));
192     noit_hash_store(&json, "type", 4, strdup(type));
193     PROCESS_NEXT_FIELD(token,len);
194     noit_hash_store(&json, "time", 4, noit__strndup(token, len));
195     /* UUID */
196     PROCESS_NEXT_FIELD(token,len);
197     noit_check_extended_id_split(token, len, target, sizeof(target),
198                                  module, sizeof(module), name, sizeof(name),
199                                  uuid_str, sizeof(uuid_str));
200     if(*uuid_str)
201       noit_hash_store(&json, "id", 2,
202                       noit__strndup(uuid_str, strlen(uuid_str)));
203     if(*target)
204       noit_hash_store(&json, "check_target", 12,
205                       noit__strndup(target, strlen(target)));
206     if(*module)
207       noit_hash_store(&json, "check_module", 12,
208                       noit__strndup(module, strlen(module)));
209     if(*name)
210       noit_hash_store(&json, "check_name", 10,
211                       noit__strndup(name, strlen(name)));
212     if(buff[0] == 'M') {
213       /* name */
214       PROCESS_NEXT_FIELD(token,len);
215       noit_hash_store(&json, "metric_name", 11, noit__strndup(token, len));
216       /* type */
217       PROCESS_NEXT_FIELD(token,len);
218       noit_hash_store(&json, "metric_type", 11, noit__strndup(token, len));
219       /* value */
220       PROCESS_LAST_FIELD(token,len); /* value */
221       noit_hash_store(&json, "value", 5, noit__strndup(token, len));
222     }
223     else if(buff[0] == 'S') {
224       /* state */
225       PROCESS_NEXT_FIELD(token,len);
226       noit_hash_store(&json, "check_state", 11, noit__strndup(token, len));
227       /* availability */
228       PROCESS_NEXT_FIELD(token,len);
229       noit_hash_store(&json, "check_availability", 18, noit__strndup(token, len));
230       /* duration */
231       PROCESS_NEXT_FIELD(token,len);
232       noit_hash_store(&json, "check_duration_ms", 17, noit__strndup(token, len));
233       /* status */
234       PROCESS_LAST_FIELD(token,len);
235       noit_hash_store(&json, "status_message", 14, noit__strndup(token, len));
236     }
237
238     memset(&iter, 0, sizeof(iter));
239     while(noit_hash_next(&json, &iter, &key, &klen, &vval)) {
240       char *val = (char *)vval;
241       if(i++) ra_write(",", 1);
242       ra_write("\"", 1);
243       ra_write(key, klen);
244       ra_write("\":\"", 3);
245       while(*val) {
246         if(*val == '\"' || *val == '\\') {
247           ra_write((char *)"\\", 1);
248         }
249         if(isprint(*val)) {
250           ra_write((char *)val, 1);
251         }
252         else {
253           char od[5];
254           snprintf(od, sizeof(od), "\\%03o", *((unsigned char *)val));
255           ra_write(od, strlen(od));
256         }
257         val++;
258       }
259       ra_write("\"", 1);
260     }
261     snprintf(buffer, sizeof(buffer), "});</script>\n");
262     ra_write(buffer, strlen(buffer));
263
264     if(noit_http_response_flush(ctx, noit_false) == noit_false) BAIL_HTTP_WRITE;
265   }
266
267   noit_hash_destroy(&json, NULL, free);
268   return 0;
269
270  bad_row:
271   BAIL_HTTP_WRITE;
272 }
273 int
274 stratcon_realtime_uri_parse(realtime_context *rc, const char *uri) {
275   int len, cnt = 0;
276   const char *cp, *interest;
277   char *copy, *brk;
278   if(strncmp(uri, "/data/", 6)) return 0;
279   cp = uri + 6;
280   len = strlen(cp);
281   copy = alloca(len + 1);
282   if(!copy) return 0;
283   memcpy(copy, cp, len);
284   copy[len] = '\0';
285
286   for (interest = strtok_r(copy, "/", &brk);
287        interest;
288        interest = strtok_r(NULL, "/", &brk)) {
289     uuid_t in_uuid;
290     struct realtime_tracker *node;
291     char *interval;
292
293     interval = strchr(interest, '@');
294     if(!interval)
295       interval = "5000";
296     else
297       *interval++ = '\0';
298     if(uuid_parse((char *)interest, in_uuid)) continue;
299     node = calloc(1, sizeof(*node));
300     node->rc = rc;
301     uuid_copy(node->checkid, in_uuid);
302     node->interval = atoi(interval);
303     node->next = rc->checklist;
304     rc->checklist = node;
305     cnt++;
306   }
307   return cnt;
308 }
309 static void
310 free_realtime_recv_ctx(void *vctx) {
311   realtime_recv_ctx_t *rrctx = vctx;
312   noit_http_session_ctx *ctx = rrctx->ctx;
313   realtime_context *rc = noit_http_session_dispatcher_closure(ctx);
314
315   if(noit_http_session_ref_dec(ctx) == 1) {
316     noit_http_response_end(ctx);
317     clear_realtime_context(rc);
318     noit_http_session_trigger(ctx, EVENTER_WRITE | EVENTER_EXCEPTION);
319   }
320   free(rrctx);
321 }
322 #define Eread(a,b) e->opset->read(e->fd, (a), (b), &mask, e)
323 static int
324 __read_on_ctx(eventer_t e, realtime_recv_ctx_t *ctx, int *newmask) {
325   int len, mask;
326   while(ctx->bytes_read < ctx->bytes_expected) {
327     len = Eread(ctx->buffer + ctx->bytes_read,
328                 ctx->bytes_expected - ctx->bytes_read);
329     if(len < 0) {
330       *newmask = mask;
331       return -1;
332     }
333     /* if we get 0 inside SSL, and there was a real error, we
334      * will actually get a -1 here.
335      * if(len == 0) return ctx->bytes_read;
336      */
337     ctx->bytes_read += len;
338   }
339   assert(ctx->bytes_read == ctx->bytes_expected);
340   return ctx->bytes_read;
341 }
342 #define FULLREAD(e,ctx,size) do { \
343   int mask, len; \
344   if(!ctx->bytes_expected) { \
345     ctx->bytes_expected = size; \
346     if(ctx->buffer) free(ctx->buffer); \
347     ctx->buffer = malloc(size + 1); \
348     if(ctx->buffer == NULL) { \
349       noitL(noit_error, "malloc(%lu) failed.\n", (unsigned long)size + 1); \
350       goto socket_error; \
351     } \
352     ctx->buffer[size] = '\0'; \
353   } \
354   len = __read_on_ctx(e, ctx, &mask); \
355   if(len < 0) { \
356     if(errno == EAGAIN) return mask | EVENTER_EXCEPTION; \
357     noitL(noit_error, "SSL read error: %s\n", strerror(errno)); \
358     goto socket_error; \
359   } \
360   ctx->bytes_read = 0; \
361   ctx->bytes_expected = 0; \
362   if(len != size) { \
363     noitL(noit_error, "SSL short read [%d] (%d/%lu).  Reseting connection.\n", \
364           ctx->state, len, (unsigned long)size); \
365     goto socket_error; \
366   } \
367 } while(0)
368
369 int
370 stratcon_realtime_recv_handler(eventer_t e, int mask, void *closure,
371                                struct timeval *now) {
372   static u_int32_t livestream_cmd = 0;
373   noit_connection_ctx_t *nctx = closure;
374   realtime_recv_ctx_t *ctx = nctx->consumer_ctx;
375   int len;
376   u_int32_t nint;
377   char uuid_str[37];
378
379   if(!livestream_cmd) livestream_cmd = htonl(NOIT_LIVESTREAM_DATA_FEED);
380
381   if(mask & EVENTER_EXCEPTION || nctx->wants_shutdown) {
382  socket_error:
383     ctx->state = REALTIME_HTTP_WANT_INITIATE;
384     ctx->count = 0;
385     ctx->bytes_read = 0;
386     ctx->bytes_written = 0;
387     ctx->bytes_expected = 0;
388     if(ctx->buffer) free(ctx->buffer);
389     ctx->buffer = NULL;
390     noit_connection_ctx_dealloc(nctx);
391     eventer_remove_fd(e->fd);
392     e->opset->close(e->fd, &mask, e);
393     return 0;
394   }
395
396 #define full_nb_write(data, wlen) do { \
397   if(!ctx->bytes_expected) { \
398     ctx->bytes_written = 0; \
399     ctx->bytes_expected = wlen; \
400   } \
401   while(ctx->bytes_written < ctx->bytes_expected) { \
402     while(-1 == (len = e->opset->write(e->fd, ((char *)data) + ctx->bytes_written, \
403                                        ctx->bytes_expected - ctx->bytes_written, \
404                                        &mask, e)) && errno == EINTR); \
405     if(len < 0) { \
406       if(errno == EAGAIN) return mask | EVENTER_EXCEPTION; \
407       goto socket_error; \
408     } \
409     ctx->bytes_written += len; \
410   } \
411   if(ctx->bytes_written != ctx->bytes_expected) { \
412     noitL(noit_error, "short write on initiating stream [%d != %d].\n", \
413           ctx->bytes_written, ctx->bytes_expected); \
414     goto socket_error; \
415   } \
416   ctx->bytes_expected = 0; \
417 } while(0)
418
419   noit_connection_update_timeout(nctx);
420   while(1) {
421     u_int32_t net_body_len;
422
423     switch(ctx->state) {
424       case REALTIME_HTTP_WANT_INITIATE:
425         full_nb_write(&livestream_cmd, sizeof(livestream_cmd));
426         ctx->state = REALTIME_HTTP_WANT_SEND_INTERVAL;
427       case REALTIME_HTTP_WANT_SEND_INTERVAL:
428         nint = htonl(ctx->rt->interval);
429         full_nb_write(&nint, sizeof(nint));
430         ctx->state = REALTIME_HTTP_WANT_SEND_UUID;
431       case REALTIME_HTTP_WANT_SEND_UUID:
432         uuid_unparse_lower(ctx->rt->checkid, uuid_str);
433         full_nb_write(uuid_str, 36);
434         ctx->state = REALTIME_HTTP_WANT_HEADER;
435       case REALTIME_HTTP_WANT_HEADER:
436         FULLREAD(e, ctx, sizeof(u_int32_t));
437         memcpy(&net_body_len, ctx->buffer, sizeof(u_int32_t));
438         ctx->body_len = ntohl(net_body_len);
439         free(ctx->buffer); ctx->buffer = NULL;
440         ctx->state = REALTIME_HTTP_WANT_BODY;
441         break;
442       case REALTIME_HTTP_WANT_BODY:
443         FULLREAD(e, ctx, ctx->body_len);
444         if(stratcon_line_to_javascript(ctx->ctx, ctx->buffer, ctx->hack_inc_id++)) goto socket_error;
445         free(ctx->buffer); ctx->buffer = NULL;
446         ctx->state = REALTIME_HTTP_WANT_HEADER;
447         break;
448     }
449   }
450
451 }
452
453 int
454 stratcon_realtime_http_postresolve(eventer_t e, int mask, void *closure,
455                                    struct timeval *now) {
456   noit_http_session_ctx *ctx = closure;
457   realtime_context *rc = noit_http_session_dispatcher_closure(ctx);
458   struct realtime_tracker *node;
459
460   for(node = rc->checklist; node; node = node->next) {
461     if(node->noit) {
462       realtime_recv_ctx_t *rrctx;
463       rrctx = calloc(1, sizeof(*rrctx));
464       rrctx->ctx = ctx;
465       rrctx->rt = node;
466       stratcon_streamer_connection(NULL, node->noit,
467                                    stratcon_realtime_recv_handler,
468                                    NULL, rrctx,
469                                    free_realtime_recv_ctx);
470     }
471     else
472       noit_http_session_ref_dec(ctx);
473   }
474   if(noit_http_session_ref_cnt(ctx) == 1) {
475     noit_http_response_end(ctx);
476     clear_realtime_context(rc);
477     noit_http_session_trigger(ctx, EVENTER_WRITE);
478   }
479   return 0;
480 }
481 int
482 stratcon_request_dispatcher(noit_http_session_ctx *ctx) {
483   const char *key, *value;
484   realtime_context *rc = noit_http_session_dispatcher_closure(ctx);
485   int klen;
486   noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
487   noit_http_request *req = noit_http_session_request(ctx);
488
489   if(rc->setup == RC_INITIAL) {
490     eventer_t completion;
491     struct realtime_tracker *node;
492     char c[1024];
493     int num_interests;
494     const char *uri_str = noit_http_request_uri_str(req);
495     noit_hash_table *headers = noit_http_request_headers_table(req);
496
497     num_interests = stratcon_realtime_uri_parse(rc, uri_str);
498     if(num_interests == 0) {
499       noit_http_response_status_set(ctx, 404, "OK");
500       noit_http_response_option_set(ctx, NOIT_HTTP_CLOSE);
501       noit_http_response_end(ctx);
502       return 0;
503     }
504
505     noitL(noit_error, "http: %s %s %s\n",
506           noit_http_request_method_str(req), uri_str,
507           noit_http_request_protocol_str(req));
508     while(noit_hash_next_str(headers, &iter, &key, &klen, &value)) {
509       noitL(noit_error, "http: [%s: %s]\n", key, value);
510     }
511     noit_http_response_status_set(ctx, 200, "OK");
512     noit_http_response_option_set(ctx, NOIT_HTTP_CHUNKED);
513     /*noit_http_response_option_set(ctx, NOIT_HTTP_GZIP);*/
514     /*noit_http_response_option_set(ctx, NOIT_HTTP_DEFLATE);*/
515     noit_http_response_header_set(ctx, "Content-Type", "text/html");
516
517     snprintf(c, sizeof(c),
518              "<html><head><script>document.domain='%s';</script></head><body>\n",
519              rc->document_domain);
520     noit_http_response_append(ctx, c, strlen(c));
521
522     /* this dumb crap is to make some browsers happy (Safari) */
523     memset(c, ' ', sizeof(c));
524     noit_http_response_append(ctx, c, sizeof(c));
525     noit_http_response_flush(ctx, noit_false);
526
527     rc->setup = RC_REQ_RECV;
528     /* Each interest references the ctx */
529     for(node = rc->checklist; node; node = node->next) {
530       char uuid_str[UUID_STR_LEN+1];
531       noit_http_session_ref_inc(ctx);
532       uuid_unparse_lower(node->checkid, uuid_str);
533       noitL(noit_error, "Resolving uuid: %s\n", uuid_str);
534     }
535     completion = eventer_alloc();
536     completion->mask = EVENTER_TIMER;
537     completion->callback = stratcon_realtime_http_postresolve;
538     completion->closure = ctx;
539     gettimeofday(&completion->whence, NULL);
540     stratcon_datastore_push(DS_OP_FIND_COMPLETE, NULL, NULL,
541                             rc->checklist, completion);
542   }
543   return EVENTER_EXCEPTION;
544 }
545 int
546 stratcon_realtime_http_handler(eventer_t e, int mask, void *closure,
547                                struct timeval *now) {
548   int done = 0, rv;
549   acceptor_closure_t *ac = closure;
550   noit_http_session_ctx *http_ctx = ac->service_ctx;
551   rv = noit_http_session_drive(e, mask, http_ctx, now, &done);
552   if(done) acceptor_closure_free(ac);
553   return rv;
554 }
555 static int
556 rest_stream_data(noit_http_rest_closure_t *restc,
557                  int npats, char **pats) {
558   /* We're here and want to subvert the rest system */
559   const char *document_domain = NULL;
560   noit_http_session_ctx *ctx = restc->http_ctx;
561   noit_http_connection *conn = noit_http_session_connection(ctx);
562   eventer_t e;
563   acceptor_closure_t *ac = restc->ac;
564
565   /* Rewire the handler */
566   if(ac->service_ctx_free)
567     ac->service_ctx_free(ac->service_ctx);
568   ac->service_ctx = ctx;
569   ac->service_ctx_free = noit_http_ctx_acceptor_free;
570
571   if(!noit_hash_retr_str(ac->config,
572                          "document_domain", strlen("document_domain"),
573                          &document_domain)) {
574     noitL(noit_error, "Document domain not set!  Realtime streaming will be broken\n");
575     document_domain = "";
576   }
577
578   noit_http_process_querystring(noit_http_session_request(ctx));
579   /* Rewire the http context */
580   e = noit_http_connection_event(conn);
581   e->callback = stratcon_realtime_http_handler;
582   noit_http_session_set_dispatcher(ctx, stratcon_request_dispatcher,
583                                    alloc_realtime_context(document_domain));
584   return stratcon_request_dispatcher(ctx);
585 }
586
587 void
588 stratcon_realtime_http_init(const char *toplevel) {
589   eventer_name_callback("stratcon_realtime_http",
590                         stratcon_realtime_http_handler);
591   eventer_name_callback("stratcon_realtime_recv",
592                         stratcon_realtime_recv_handler);
593   assert(noit_http_rest_register_auth(
594     "GET", "/data/",
595            "^((?:" UUID_REGEX "(?:@\\d+)?)(?:/" UUID_REGEX "(?:@\\d+)?)*)$",
596     rest_stream_data, noit_http_rest_access
597   ) == 0);
598   assert(noit_http_rest_register_auth(
599     "GET", "/", "^(.*)$", noit_rest_simple_file_handler, noit_http_rest_access
600   ) == 0);
601 }
Note: See TracBrowser for help on using the browser.