aboutsummaryrefslogtreecommitdiff
path: root/net/httpreq.c
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2011-01-13 18:54:34 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2011-01-13 18:54:34 +0000
commit7c6492599d64e3125af81e1c6442c1c1c43ad187 (patch)
tree3e47f7a9f2d218fca6f99c25aa4120ed38e7c947 /net/httpreq.c
parentec9960cb49988a010b76b537f7fd4f7391a208a5 (diff)
Two externals to process HTTP/1.1 requests and responses in conjunction with net exernals like [tcpclient] or
[slipenc]/[slipdec]. So far only GET requests work. svn path=/trunk/externals/mrpeach/; revision=14735
Diffstat (limited to 'net/httpreq.c')
-rw-r--r--net/httpreq.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/net/httpreq.c b/net/httpreq.c
new file mode 100644
index 0000000..e0b764a
--- /dev/null
+++ b/net/httpreq.c
@@ -0,0 +1,107 @@
+/* httptreq.c Started by Martin Peach 20110111 */
+/* httpreq will generate http 1.1 requests as lists of bytes suitable for input to tcpclient */
+/* See http://www.w3.org/Protocols/rfc2616/rfc2616.html */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <string.h>
+
+static t_class *httpreq_class;
+
+typedef struct _httpreq
+{
+ t_object x_obj;
+ t_outlet *x_reqout;
+} t_httpreq;
+
+#define MAX_GETSTRING 256
+
+void httpreq_bang(t_httpreq *x)
+{
+ post("httpreq_bang %p", x);
+}
+
+static void httpreq_get(t_httpreq *x, t_symbol *s)
+{
+ unsigned int i, j, len;
+ char buf[MAX_GETSTRING];
+ char request_line[1024];
+ t_atom request_atoms[1024];
+
+ len = strlen (s->s_name);
+ if (len > MAX_GETSTRING)
+ {
+ pd_error(x, "httpreq_get: string too long (%d), should be less than %d", len, MAX_GETSTRING);
+ return;
+ }
+ for (i = 0; i < strlen(s->s_name); ++i) buf[i] = s->s_name[i];
+ buf[i] = 0;
+// post("httpreq_get %s (%s)", s->s_name, buf);
+ if (0 != strncmp("http://", buf, 7))
+ {
+ pd_error(x, "httpreq_get: url doesn't begin with 'http://' (%d)", len);
+ return;
+ }
+/*
+5.1 Request-Line
+The Request-Line begins with a method token,
+followed by the Request-URI and the protocol version,
+and ending with CRLF.
+The elements are separated by SP characters.
+No CR or LF is allowed except in the final CRLF sequence.
+
+Request-Line = Method SP Request-URI SP HTTP-Version CRLF
+*/
+ j = sprintf(request_line, "GET ");
+ for (i = 7; i < len; ++i)
+ { /* skip "http://" and the host name */
+ if ('/' == buf[i]) break;
+ }
+ for (; i < len; ++i, ++j)
+ {
+ if (buf[i] <= 0x20) break;
+ request_line[j] = buf[i];
+ }
+ j += sprintf(&request_line[j], " HTTP/1.1");
+ request_line[j++] = 0xD; // <CR>
+ request_line[j++] = 0xA; // <LF>
+ j += sprintf(&request_line[j], "Host: ");
+ for (i = 7; i < len; ++i, ++j)
+ { /* copy the host name */
+ if ('/' == buf[i]) break;
+ request_line[j] = buf[i];
+ }
+ request_line[j++] = 0xD; // <CR>
+ request_line[j++] = 0xA; // <LF>
+ request_line[j++] = 0xD; // <CR>
+ request_line[j++] = 0xA; // <LF>
+ request_line[j] = 0; // terminate string
+
+// output the request line as a list of floats
+ for (i = 0; i < j; ++i)
+ {
+ SETFLOAT(&request_atoms[i], request_line[i]);
+// post("%f", request_atoms[i].a_w.w_float);
+ }
+ post ("j is %d", j);
+ post("httpreq_get: %s", request_line);
+ outlet_list(x->x_reqout, &s_list, j, &request_atoms[0]);
+}
+
+static void *httpreq_new (void)
+{
+ t_httpreq *x = (t_httpreq *)pd_new(httpreq_class);
+ if (NULL != x)
+ {
+ x->x_reqout = outlet_new(&x->x_obj, &s_anything);
+ }
+ return (void *)x;
+}
+
+void httpreq_setup(void)
+{
+ httpreq_class = class_new(gensym("httpreq"), (t_newmethod)httpreq_new, 0, sizeof(t_httpreq), CLASS_DEFAULT, 0);
+ class_addbang(httpreq_class, httpreq_bang);
+ class_addmethod (httpreq_class, (t_method)httpreq_get, gensym ("GET"), A_DEFSYM, 0);
+}
+/* fin httpreq.c */