summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Troy <dave@popvox.com>2006-04-04 23:01:38 +0000
committerDavid Troy <dave@popvox.com>2006-04-04 23:01:38 +0000
commit8c5e24cab7e89f74bbc363223fe00dd45edb28e2 (patch)
tree603cc498ad7a59338e200a453328987e452cdc38
parent8c46813c678ff0ca734e7b2866623a61109f26aa (diff)
downloadastmanproxy-8c5e24cab7e89f74bbc363223fe00dd45edb28e2.tar.gz
astmanproxy-8c5e24cab7e89f74bbc363223fe00dd45edb28e2.tar.xz
astmanproxy-8c5e24cab7e89f74bbc363223fe00dd45edb28e2.zip
git-svn-id: http://svncommunity.digium.com/svn/astmanproxy/branches/1.20pre@86 f02b47b9-160a-0410-81a6-dc3441afb0ec
-rw-r--r--TODO2
-rwxr-xr-xperl/soapclient.pl6
-rw-r--r--src/soap.c157
3 files changed, 161 insertions, 4 deletions
diff --git a/TODO b/TODO
index bb0f233..8083f1c 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,6 @@
fix non-blocking in ast_connect
kill autodisconnect concept; this would be managed by inputcomplete/outputcomplete in drivers?
+finish SOAP handler
'connected' flag; do not set until we get "authentication accepted' back from server
Check for module versions; do not run without modules installed
@@ -12,4 +13,3 @@ SetInputFormat proxyaction?
clean up autodisconnect vs. inputcomplete/outputcomplete
deal with http non-conformity better
-SOAP handler?
diff --git a/perl/soapclient.pl b/perl/soapclient.pl
index 2ab9c2f..4fb4d0f 100755
--- a/perl/soapclient.pl
+++ b/perl/soapclient.pl
@@ -3,9 +3,9 @@
use SOAP::Lite;
print SOAP::Lite
- -> uri('http://www.soaplite.com/Demo')
- -> proxy('http://services.soaplite.com/hibye.cgi')
- -> hi()
+ -> uri('http://localhost:1234/astmanproxy')
+ -> proxy('http://localhost:1234/')
+ -> astman('Action: Ping')
-> result . "\n";
exit(0);
diff --git a/src/soap.c b/src/soap.c
new file mode 100644
index 0000000..8a8d245
--- /dev/null
+++ b/src/soap.c
@@ -0,0 +1,157 @@
+/* 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;
+
+ 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 HTTPHeader(struct mansession *s, char *status) {
+
+
+ time_t t;
+ struct tm tm;
+ char date[80];
+ char ctype[15], hdr[MAX_LEN];
+
+ time(&t);
+ localtime_r(&t, &tm);
+ strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
+
+ if ( !strcasecmp("xml", s->output->formatname) )
+ sprintf(ctype, "text/xml");
+ else
+ sprintf(ctype, "text/plain");
+
+ if (!strcmp("200 OK", status) )
+ sprintf(hdr,
+ "HTTP/1.1 %s\r\n"
+ "Date: %s\r\n"
+ "Content-Type: %s\r\n"
+ "Connection: close\r\n"
+ "Server: %s/%s\r\n\r\n", status,
+ date, ctype, PROXY_BANNER, PROXY_VERSION);
+ else
+ sprintf(hdr,
+ "HTTP/1.1 %s\r\n"
+ "Date: %s\r\n"
+ "Status: %s\r\n"
+ "Server: %s/%s\r\n\r\n", status, date, status, PROXY_BANNER, PROXY_VERSION);
+
+ pthread_mutex_lock(&s->lock);
+ s->inputcomplete = 1;
+ ast_carefulwrite(s->fd, hdr, strlen(hdr), s->writetimeout);
+ pthread_mutex_unlock(&s->lock);
+ debugmsg("http header: %s", hdr);
+
+ 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], status[15];
+ int res, clength = 0;
+
+ memset(method, 0, sizeof method);
+ memset(formdata, 0, sizeof formdata);
+ memset(status, 0, sizeof status);
+
+ /* for http, don't do get_input forever */
+ for (;;) {
+
+ if (s->inputcomplete && !s->outputcomplete)
+ continue;
+ else if (s->inputcomplete && s->outputcomplete)
+ return -1;
+
+ 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);
+
+ if ( !clength && !strncasecmp(line, "Content-Length: ", 16) )
+ clength = atoi(line+16);
+
+ if (!*method) {
+ if ( !strncmp(line,"POST",4) ) {
+ strncpy(method, line, 4);
+ } else if ( !strncmp(line,"GET",3)) {
+ if ( strlen(line) > 14 ) {
+ /* GET / HTTP/1.1 ---- this is bad */
+ /* GET /?Action=Ping&ActionID=Foo HTTP/1.1 */
+ strncpy(method, line, 3);
+ memcpy(formdata, line+6, strstr(line, " HTTP")-line-6);
+ sprintf(status, "200 OK");
+ } else
+ sprintf(status, "501 Not Implemented");
+ }
+ }
+ } else if (res == 0) {
+ if (*method && !*formdata) {
+ if ( !strcasecmp(method, "POST") && clength && s->inlen==clength) {
+ pthread_mutex_lock(&s->lock);
+ strncpy(formdata, s->inbuf, clength);
+ s->inlen = 0;
+ pthread_mutex_unlock(&s->lock);
+ sprintf(status, "200 OK");
+ }
+ }
+ }
+
+ if (res < 0)
+ break;
+
+ if (*status) {
+ HTTPHeader(s, status);
+
+ /* now, let's transform and copy into a standard message block */
+ if (!strcmp("200 OK", status) ) {
+ res = ParseHTTPInput(formdata, m);
+ return res;
+ } else {
+ pthread_mutex_lock(&s->lock);
+ s->outputcomplete = 1;
+ pthread_mutex_unlock(&s->lock);
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
+int _autodisconnect() {
+ return 1;
+}
+
+/* We do not define a _write or _onconnect method */