summaryrefslogtreecommitdiffstats
path: root/src/http.c
blob: 3b271b9725fc78011e80de0b100f096241ab5df1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* Asterisk Manager Proxy
   Copyright (c) 2005 David C. Troy <dave@popvox.com>

   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;

    /* 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);
    memset(header, 0, sizeof header);

    /* for http, don't do get_input forever */
    for (;;) {
        memset(line, 0, sizeof line);
        res = get_input(s, line);
	debugmsg("res=%d, line: %s",res, line);

	if (res > 0) {
        	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);
                }

		if (*method && s->inlen==clength) {
                    if ( !strcasecmp(method, "POST") ) {
                        pthread_mutex_lock(&s->lock);
                        strncpy(formdata, s->inbuf, clength);
                        s->inlen = 0;
                        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;
                    ast_carefulwrite(s->fd, header, strlen(header), s->writetimeout);
                    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 if (res < 0)
		break;
    }

    return -1;
}

int _autodisconnect() {
    return 1;
}

/* We do not define a _write or _onconnect method */