Embedded WebSockets Experiment

Dependencies:   mbed MD5

Committer:
nandgate
Date:
Tue Jul 26 05:30:53 2011 +0000
Revision:
0:6dee052a3fa4

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nandgate 0:6dee052a3fa4 1 #ifndef HTTPRPC_H
nandgate 0:6dee052a3fa4 2 #define HTTPRPC_H
nandgate 0:6dee052a3fa4 3
nandgate 0:6dee052a3fa4 4 #include "HTTPServer.h"
nandgate 0:6dee052a3fa4 5 #include "platform.h"
nandgate 0:6dee052a3fa4 6 #ifdef MBED_RPC
nandgate 0:6dee052a3fa4 7 #include "rpc.h"
nandgate 0:6dee052a3fa4 8
nandgate 0:6dee052a3fa4 9 /**
nandgate 0:6dee052a3fa4 10 * A datastorage helper for the HTTPRPC class
nandgate 0:6dee052a3fa4 11 */
nandgate 0:6dee052a3fa4 12 class HTTPRPCData : public HTTPData {
nandgate 0:6dee052a3fa4 13 public: char result[255];
nandgate 0:6dee052a3fa4 14 };
nandgate 0:6dee052a3fa4 15
nandgate 0:6dee052a3fa4 16 /**
nandgate 0:6dee052a3fa4 17 * Thsi class enables you to make rpc calls to your mbed.
nandgate 0:6dee052a3fa4 18 * Furthermore it is a good example how to write a HTTPHandler for small data chunks.
nandgate 0:6dee052a3fa4 19 */
nandgate 0:6dee052a3fa4 20 class HTTPRPC : public HTTPHandler {
nandgate 0:6dee052a3fa4 21 public:
nandgate 0:6dee052a3fa4 22 /**
nandgate 0:6dee052a3fa4 23 * We have to know the prefix for the RPCHandler.
nandgate 0:6dee052a3fa4 24 * A good default choice is /rpc so we made this default.
nandgate 0:6dee052a3fa4 25 */
nandgate 0:6dee052a3fa4 26 HTTPRPC(const char *path = "/rpc") : HTTPHandler(path) {}
nandgate 0:6dee052a3fa4 27 HTTPRPC(HTTPServer *server, const char *path = "/rpc") : HTTPHandler(path) { server->addHandler(this); }
nandgate 0:6dee052a3fa4 28
nandgate 0:6dee052a3fa4 29 private:
nandgate 0:6dee052a3fa4 30 /**
nandgate 0:6dee052a3fa4 31 * If you need some Headerfeelds you have tor register the feelds here.
nandgate 0:6dee052a3fa4 32 */
nandgate 0:6dee052a3fa4 33 // virtual void reg(HTTPServer *svr) {
nandgate 0:6dee052a3fa4 34 // svr->registerField("Content-Length");
nandgate 0:6dee052a3fa4 35 // }
nandgate 0:6dee052a3fa4 36
nandgate 0:6dee052a3fa4 37 /**
nandgate 0:6dee052a3fa4 38 * If a new RPCRequest Header is complete received the server will call this function.
nandgate 0:6dee052a3fa4 39 * This is the right place for preparing our datastructures.
nandgate 0:6dee052a3fa4 40 * Furthermore we will execute the rpc call and store the anwere.
nandgate 0:6dee052a3fa4 41 * But we will not send a response. This will be hapen in the send method.
nandgate 0:6dee052a3fa4 42 */
nandgate 0:6dee052a3fa4 43 virtual HTTPStatus init(HTTPConnection *con) const {
nandgate 0:6dee052a3fa4 44 HTTPRPCData *data = new HTTPRPCData();
nandgate 0:6dee052a3fa4 45 con->data = data;
nandgate 0:6dee052a3fa4 46 char *query = con->getURL()+strlen(_prefix);
nandgate 0:6dee052a3fa4 47 clean(query);
nandgate 0:6dee052a3fa4 48 rpc(query, data->result);
nandgate 0:6dee052a3fa4 49
nandgate 0:6dee052a3fa4 50 const char *nfields = "Cache-Control: no-cache, no-store, must-revalidate\r\nPragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GM";
nandgate 0:6dee052a3fa4 51 char *old = (char *)con->getHeaderFields();
nandgate 0:6dee052a3fa4 52 int oldlen = strlen(old);
nandgate 0:6dee052a3fa4 53 int atrlen = strlen(nfields);
nandgate 0:6dee052a3fa4 54 char *fields = new char[atrlen+oldlen+3];
nandgate 0:6dee052a3fa4 55 strcpy(fields,old);
nandgate 0:6dee052a3fa4 56 fields[oldlen+0] = '\r';
nandgate 0:6dee052a3fa4 57 fields[oldlen+1] = '\n';
nandgate 0:6dee052a3fa4 58 strcpy(&fields[oldlen+2], nfields);
nandgate 0:6dee052a3fa4 59 fields[atrlen+2+oldlen] = '\0';
nandgate 0:6dee052a3fa4 60 con->setHeaderFields(fields);
nandgate 0:6dee052a3fa4 61 if(*old) {
nandgate 0:6dee052a3fa4 62 delete old;
nandgate 0:6dee052a3fa4 63 }
nandgate 0:6dee052a3fa4 64
nandgate 0:6dee052a3fa4 65 con->setLength(strlen(data->result));
nandgate 0:6dee052a3fa4 66 return HTTP_OK;
nandgate 0:6dee052a3fa4 67 }
nandgate 0:6dee052a3fa4 68
nandgate 0:6dee052a3fa4 69 /**
nandgate 0:6dee052a3fa4 70 * If we got an POST request the send method will not be executed.
nandgate 0:6dee052a3fa4 71 * If we want to send data we have to trigger it the first time by ourself.
nandgate 0:6dee052a3fa4 72 * So we execute the send method.
nandgate 0:6dee052a3fa4 73 *
nandgate 0:6dee052a3fa4 74 * If the rpc call is the content of the POST body we would not be able to execute it.
nandgate 0:6dee052a3fa4 75 * Were parsing only the URL.
nandgate 0:6dee052a3fa4 76 */
nandgate 0:6dee052a3fa4 77 virtual HTTPHandle data(HTTPConnection *con, void *, int) const {
nandgate 0:6dee052a3fa4 78 return send(con, con->sndbuf());
nandgate 0:6dee052a3fa4 79 }
nandgate 0:6dee052a3fa4 80
nandgate 0:6dee052a3fa4 81 /**
nandgate 0:6dee052a3fa4 82 * Send the result back to the client.
nandgate 0:6dee052a3fa4 83 * If we have not enought space wait for next time.
nandgate 0:6dee052a3fa4 84 */
nandgate 0:6dee052a3fa4 85 virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
nandgate 0:6dee052a3fa4 86 HTTPRPCData *data = static_cast<HTTPRPCData *>(con->data);
nandgate 0:6dee052a3fa4 87 if(maximum>64) {
nandgate 0:6dee052a3fa4 88 con->write(data->result, con->getLength());
nandgate 0:6dee052a3fa4 89 return HTTP_SuccessEnded;
nandgate 0:6dee052a3fa4 90 } else {
nandgate 0:6dee052a3fa4 91 // To less memory.
nandgate 0:6dee052a3fa4 92 return HTTP_SenderMemory;
nandgate 0:6dee052a3fa4 93 }
nandgate 0:6dee052a3fa4 94 }
nandgate 0:6dee052a3fa4 95
nandgate 0:6dee052a3fa4 96 /**
nandgate 0:6dee052a3fa4 97 * To reduce memory usage we sodify the URL directly
nandgate 0:6dee052a3fa4 98 * and replace '%20',',','+','=' with spaces.
nandgate 0:6dee052a3fa4 99 */
nandgate 0:6dee052a3fa4 100 inline void clean(char *str) const {
nandgate 0:6dee052a3fa4 101 while(*str++) {
nandgate 0:6dee052a3fa4 102 if(*str=='%'&&*(str+1)=='2'&&*(str+2)=='0') {
nandgate 0:6dee052a3fa4 103 *str = ' ';
nandgate 0:6dee052a3fa4 104 *(str+1) = ' ';
nandgate 0:6dee052a3fa4 105 *(str+2) = ' ';
nandgate 0:6dee052a3fa4 106 }
nandgate 0:6dee052a3fa4 107 if(*str==','||*str=='+'||*str=='=') {
nandgate 0:6dee052a3fa4 108 *str = ' ';
nandgate 0:6dee052a3fa4 109 }
nandgate 0:6dee052a3fa4 110 }
nandgate 0:6dee052a3fa4 111 }
nandgate 0:6dee052a3fa4 112 };
nandgate 0:6dee052a3fa4 113 #endif
nandgate 0:6dee052a3fa4 114
nandgate 0:6dee052a3fa4 115 #endif