/* Asterisk Manager Proxy Copyright (c) 2005 David C. Troy This program is free software, distributed under the terms of the GNU General Public License. HTTP Input Handler */ #include "astmanproxy.h" int ParseHTTPInput(char *buf, struct message *m) { char *n, *v; /* just an empty block; go home if ( !(*buf) ) return 0; */ /* initialize message block */ memset(m, 0, sizeof (struct message) ); n = buf; while ( (v = strstr(n, "=")) ) { v += 1; debugmsg("n: %s, v: %s", n, v); strncat(m->headers[m->hdrcount], n, v-n-1); strcat(m->headers[m->hdrcount], ": "); if ( (n = strstr(v, "&")) ) { n += 1; } else { n = (v + strlen(v) + 1); } strncat(m->headers[m->hdrcount], v, n-v-1); debugmsg("got hdr: %s", m->headers[m->hdrcount]); m->hdrcount++; } return (m->hdrcount > 0); } int BuildHTTPHeader(char *hdr) { time_t t; struct tm tm; char date[80]; time(&t); localtime_r(&t, &tm); strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm); sprintf(hdr, "HTTP/1.1 200 OK\r\n" "Date: %s\r\n" "Content-Type: text/xml\r\n" "Connection: close\r\n" "Server: %s/%s\r\n\r\n", date, PROXY_BANNER, PROXY_VERSION); return 0; } int _read(struct mansession *s, struct message *m) { /* Note: No single line may be longer than MAX_LEN/s->inbuf, as per get_input */ /* No HTTP Input may be longer than BUFSIZE */ char line[MAX_LEN], method[10], formdata[MAX_LEN], header[MAX_LEN]; int res, clength = 0; if (s->inputcomplete) return 0; memset(method, 0, sizeof method); memset(formdata, 0, sizeof formdata); /* for http, don't do get_input forever */ for (;;) { memset(line, 0, sizeof line); res = get_input(s, line); if (res > 0) { if (*line == '\0' ) { if (*method == '\0') break; else { if ( !strcasecmp(method, "POST") ) { pthread_mutex_lock(&s->lock); strncpy(formdata, s->inbuf, clength); /* Move remaining data back to the front */ memmove(s->inbuf, s->inbuf + clength+1, s->inlen - clength); s->inlen -= clength; pthread_mutex_unlock(&s->lock); } debugmsg("method: %s", method); debugmsg("clength: %d", clength); debugmsg("formdata: %s", formdata); debugmsg("s->inbuf: %s", s->inbuf); debugmsg("s->inlen: %d", s->inlen); BuildHTTPHeader(header); pthread_mutex_lock(&s->lock); s->inputcomplete = 1; write(s->fd, header, strlen(header)); pthread_mutex_unlock(&s->lock); debugmsg("header: %s", header); /* now, let's transform and copy into a standard message block */ res = ParseHTTPInput(formdata, m); return res; } } else { debugmsg("Got http: %s", line); /* Do meaningful things here */ if ( !strncmp(line,"POST",4) ) { strncpy(method, line, 4); } else if ( !strncmp(line,"GET",3) ) { /* GET /?Action=Ping&ActionID=Foo HTTP/1.1 */ strncpy(method, line, 3); memcpy(formdata, line+6, strstr(line, " HTTP")-line-6); } else if ( !strncasecmp(line, "Content-Length: ", 16) ) { clength = atoi(line+16); } } } else if (res < 0) return res; } return -1; } int _autodisconnect() { return 1; } /* We do not define a _write or _onconnect method */