Tiny HTTP Client http://mbed.org/users/okini3939/notebook/tinyhttp

Dependencies:   EthernetNetIf mbed

Files at this revision

API Documentation at this revision

Comitter:
okini3939
Date:
Wed Jul 27 16:08:54 2011 +0000
Child:
1:9f15e579d914
Commit message:

Changed in this revision

EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
TinyHTTP.cpp Show annotated file Show diff for this revision Revisions of this file
TinyHTTP.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Wed Jul 27 16:08:54 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TinyHTTP.cpp	Wed Jul 27 16:08:54 2011 +0000
@@ -0,0 +1,215 @@
+/*
+ * mbed Tiny HTTP Client
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Tiny HTTP Client
+ */
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+#include "DNSRequest.h"
+#include "TinyHTTP.h"
+
+#define STATUS_NONE 0
+#define STATUS_READABLE 1
+#define STATUS_CONNECTED 2
+#define STATUS_ERROR 3
+#define STATUS_DISCONNECTED 4
+
+
+TCPSocket *http;
+volatile int tcp_status = 0, dns_status = 0;
+
+// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+void base64enc(const char *input, unsigned int length, char *output) {
+  static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  unsigned int c, c1, c2, c3;
+  for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
+    c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
+    c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
+    c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
+
+    c = ((c1 & 0xFC) >> 2);
+    output[j+0] = base64[c];
+    c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
+    output[j+1] = base64[c];
+    c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
+    output[j+2] = (length>i+1)?base64[c]:'=';
+    c = (c3 & 0x3F);
+    output[j+3] = (length>i+2)?base64[c]:'=';
+  }
+  output[(((length-1)/3)+1)<<2] = '\0';
+}
+/*
+// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+int url_encode(char *str, char *buf, int len) {
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
+  if (len < strlen(str) * 3 + 1) return -1;
+  char *pstr = str, *pbuf = buf;
+  while (*pstr) {
+    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
+      *pbuf++ = *pstr;
+    else if (*pstr == ' ') 
+      *pbuf++ = '+';
+    else 
+      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+    pstr++;
+  }
+  *pbuf = '\0';
+  return 0;
+}
+*/
+
+void isr_http (TCPSocketEvent e) {
+
+#ifdef DEBUG
+    printf("tcp(%d)\r\n", e);
+#endif
+    switch(e) {
+    case TCPSOCKET_READABLE: //Incoming data
+        tcp_status = STATUS_READABLE;
+        break;
+
+    case TCPSOCKET_CONNECTED:
+    case TCPSOCKET_WRITEABLE: //We can send data
+        tcp_status = STATUS_CONNECTED;
+        break;
+
+    case TCPSOCKET_CONTIMEOUT:
+    case TCPSOCKET_CONRST:
+    case TCPSOCKET_CONABRT:
+    case TCPSOCKET_ERROR:
+        tcp_status = STATUS_ERROR;
+        break;
+
+    case TCPSOCKET_DISCONNECTED:
+        tcp_status = STATUS_DISCONNECTED;
+        break;
+    }
+}
+
+void createauth (char *user, char *pwd, char *buf) {
+    char tmp[80];
+
+    snprintf(tmp, sizeof(tmp), "Authorization: Basic %s:%s\n", user, pwd);
+    base64enc(tmp, strlen(tmp), buf);
+}
+
+void isr_dns (DNSReply r) {
+
+    if (DNS_FOUND) {
+        dns_status = 1;
+    } else {
+        dns_status = -1;
+    }
+}
+
+int httpRequest (int method, Host *host, char *uri, char *head, char *body) {
+    TCPSocketErr err;
+    char buf[500];
+    int i, ret = -1;
+
+    http = new TCPSocket;
+    tcp_status = STATUS_NONE;
+
+    http->setOnEvent(isr_http);
+
+    // connect
+    if (host->getIp().isNull()) {
+        DNSRequest dns;
+        dns_status = 0;
+        dns.setOnReply(isr_dns);
+        if (dns.resolve(host) != DNS_OK) goto exit;
+        for (i = 0; i < HTTP_TIMEOUT / 10; i ++) {
+            if (dns_status) break;
+            Net::poll();
+            wait_ms(10);
+        }
+        while (dns_status < 0) goto exit;
+    }
+    if (! host->getPort()) {
+        host->setPort(HTTP_PORT);
+    }
+    err = http->connect(*host);
+    if (err != TCPSOCKET_OK) goto exit;
+
+    // wait connect
+    for (i = 0; i < HTTP_TIMEOUT / 10; i ++) {
+        if (tcp_status != STATUS_NONE) break;
+        Net::poll();
+        wait_ms(10);
+    }
+    if (tcp_status != STATUS_CONNECTED) goto exit;
+
+    // send request
+    if (method == METHOD_POST) {
+        http->send("POST ", 5);
+    } else {
+        http->send("GET ", 4);
+    }
+    http->send(uri, strlen(uri));
+    http->send(" HTTP/1.1\r\nHost: ", 17);
+    http->send(host->getName(), strlen(host->getName()));
+    http->send("\r\n", 2);
+    if (head) {
+        http->send(head, strlen(head));
+    }
+    if (method == METHOD_POST) {
+        sprintf(buf, "Content-Length: %d\r\n", strlen(body));
+        http->send(buf, strlen(buf));
+    }
+    http->send("\r\n", 2);
+
+    // post method
+    if (method == METHOD_POST && body) {
+        http->send(body, strlen(body));
+    }
+
+    // wait responce
+    for (i = 0; i < 1500; i ++) {
+        if (tcp_status != STATUS_CONNECTED) break;
+        Net::poll();
+        wait_ms(10);
+    }
+    if (tcp_status != STATUS_READABLE) goto exit;
+
+    // recv responce
+    i = http->recv(buf, sizeof(buf));
+    buf[i] = 0;
+    if (strncmp(buf, "HTTP", 4) == 0) {
+        ret = atoi(&buf[9]);
+    }
+#ifdef DEBUG
+    printf(buf);
+#endif
+
+    // recv dummy
+    for (i = 0; i < HTTP_TIMEOUT / 10; i ++) {
+        switch (tcp_status) {
+        case STATUS_READABLE:
+            int n = http->recv(buf, sizeof(buf));
+            buf[n] = 0;
+            i = 0;
+#ifdef DEBUG
+            printf(buf);
+#endif
+            break;
+        case STATUS_DISCONNECTED:
+        case STATUS_ERROR:
+            goto exit;
+        }
+        Net::poll();
+        wait_ms(10);
+    }
+
+exit:
+    http->resetOnEvent();
+    http->close();
+    delete http;
+
+    return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TinyHTTP.h	Wed Jul 27 16:08:54 2011 +0000
@@ -0,0 +1,32 @@
+/*
+ * mbed Tiny HTTP Client
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Tiny HTTP Client
+ */
+
+#ifndef TinyHTTP_h
+#define TinyHTTP_h
+
+#define DEBUG
+
+#define HTTP_PORT 80
+#define HTTP_TIMEOUT 15000 // ms
+
+#define METHOD_GET 0
+#define METHOD_POST 1
+
+/** send http request
+ * @param method METHOD_GET or METHOD_POST
+ * @param host http server
+ * @param uri URI
+ * @param head http header (CR+LF) (or NULL)
+ * @param body POST body (or NULL)
+ * @return http code, -1:failue
+ */
+int httpRequest (int method, Host *host, char *uri, char *head, char *body);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 27 16:08:54 2011 +0000
@@ -0,0 +1,32 @@
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+#include "TinyHTTP.h"
+
+DigitalOut myled(LED1);
+Serial pc(USBTX, USBRX);
+EthernetNetIf eth;
+
+int main () {
+    EthernetErr ethErr;
+    Host host;
+    int r;
+
+    myled = 1;
+
+    ethErr = eth.setup();
+    if(ethErr) {
+        return -1;
+    }
+
+    host.setName("mbed.org");
+    r = httpRequest(METHOD_GET, &host, "/", NULL, NULL);
+/*
+    host.setName("www.domain.name");
+    r = httpRequest(METHOD_POST, &host, "/xxx.cgi", "Content-Type: application/x-www-form-urlencoded\r\n", "key=value&key2=value2");
+*/
+    printf("status %d\r\n", r);
+
+    myled = 0;
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Jul 27 16:08:54 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912