Embedded WebSockets Experiment

Dependencies:   mbed MD5

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPRPC.h Source File

HTTPRPC.h

00001 #ifndef HTTPRPC_H
00002 #define HTTPRPC_H
00003 
00004 #include "HTTPServer.h"
00005 #include "platform.h"
00006 #ifdef MBED_RPC
00007 #include "rpc.h"
00008 
00009 /**
00010  * A datastorage helper for the HTTPRPC class
00011  */
00012 class HTTPRPCData : public HTTPData {
00013   public: char result[255];
00014 };
00015 
00016 /**
00017  * Thsi class enables you to make rpc calls to your mbed.
00018  * Furthermore it is a good example how to write a HTTPHandler for small data chunks.
00019  */
00020 class HTTPRPC : public HTTPHandler {
00021   public:
00022     /**
00023      * We have to know the prefix for the RPCHandler.
00024      * A good default choice is /rpc so we made this default.
00025      */
00026     HTTPRPC(const char *path = "/rpc") : HTTPHandler(path) {}
00027     HTTPRPC(HTTPServer *server, const char *path = "/rpc") : HTTPHandler(path) { server->addHandler(this); }
00028     
00029   private:
00030     /**
00031      * If you need some Headerfeelds you have tor register the feelds here.
00032      */
00033 //    virtual void reg(HTTPServer *svr) {
00034 //      svr->registerField("Content-Length");
00035 //    }
00036 
00037     /**
00038      * If a new RPCRequest Header is complete received the server will call this function.
00039      * This is the right place for preparing our datastructures.
00040      * Furthermore we will execute the rpc call and store the anwere.
00041      * But we will not send a response. This will be hapen in the send method.
00042      */
00043     virtual HTTPStatus init(HTTPConnection *con) const {
00044       HTTPRPCData *data = new HTTPRPCData();
00045       con->data = data;
00046       char *query = con->getURL()+strlen(_prefix);
00047       clean(query);
00048       rpc(query, data->result);
00049 
00050       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";
00051       char *old = (char *)con->getHeaderFields();
00052       int oldlen = strlen(old);
00053       int atrlen = strlen(nfields);
00054       char *fields = new char[atrlen+oldlen+3];
00055       strcpy(fields,old);
00056       fields[oldlen+0] = '\r';
00057       fields[oldlen+1] = '\n';
00058       strcpy(&fields[oldlen+2], nfields);
00059       fields[atrlen+2+oldlen] = '\0';
00060       con->setHeaderFields(fields);
00061       if(*old) {
00062         delete old;
00063       }
00064 
00065       con->setLength(strlen(data->result));
00066       return HTTP_OK;
00067     }
00068 
00069     /**
00070      * If we got an POST request the send method will not be executed.
00071      * If we want to send data we have to trigger it the first time by ourself.
00072      * So we execute the send method.
00073      *
00074      * If the rpc call is the content of the POST body we would not be able to execute it.
00075      * Were parsing only the URL.
00076      */
00077     virtual HTTPHandle data(HTTPConnection *con, void *, int) const {
00078       return send(con, con->sndbuf());
00079     }
00080 
00081     /**
00082      * Send the result back to the client.
00083      * If we have not enought space wait for next time.
00084      */
00085     virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
00086       HTTPRPCData *data = static_cast<HTTPRPCData *>(con->data);    
00087       if(maximum>64) {
00088         con->write(data->result, con->getLength());
00089         return HTTP_SuccessEnded;
00090       } else {
00091         // To less memory.
00092         return HTTP_SenderMemory;
00093       }
00094     }
00095 
00096     /**
00097      * To reduce memory usage we sodify the URL directly 
00098      * and replace '%20',',','+','=' with spaces.
00099      */
00100     inline void clean(char *str) const {
00101       while(*str++) {
00102         if(*str=='%'&&*(str+1)=='2'&&*(str+2)=='0') {
00103           *str = ' ';
00104           *(str+1) = ' ';
00105           *(str+2) = ' ';
00106         }
00107         if(*str==','||*str=='+'||*str=='=') {
00108           *str = ' ';
00109         }
00110       }
00111     }
00112 };
00113 #endif
00114 
00115 #endif