My fork of the HTTPServer (working)

Dependents:   DGWWebServer LAN2

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     
00028   private:
00029     /**
00030      * If you need some Headerfeelds you have tor register the feelds here.
00031      */
00032 //    virtual void reg(HTTPServer *svr) {
00033 //      svr->registerField("Content-Length");
00034 //    }
00035 
00036     /**
00037      * If a new RPCRequest Header is complete received the server will call this function.
00038      * This is the right place for preparing our datastructures.
00039      * Furthermore we will execute the rpc call and store the anwere.
00040      * But we will not send a response. This will be hapen in the send method.
00041      */
00042     virtual HTTPStatus init(HTTPConnection *con) const {
00043       HTTPRPCData *data = new HTTPRPCData();
00044       con->data = data;
00045       char *query = con->getURL()+strlen(_prefix);
00046       clean(query);
00047       rpc(query, data->result);
00048 
00049       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";
00050       char *old = (char *)con->getHeaderFields();
00051       int oldlen = strlen(old);
00052       int atrlen = strlen(nfields);
00053       char *fields = new char[atrlen+oldlen+3];
00054       strcpy(fields,old);
00055       fields[oldlen+0] = '\r';
00056       fields[oldlen+1] = '\n';
00057       strcpy(&fields[oldlen+2], nfields);
00058       fields[atrlen+2+oldlen] = '\0';
00059       con->setHeaderFields(fields);
00060       if(*old) {
00061         delete old;
00062       }
00063 
00064       con->setLength(strlen(data->result));
00065       return HTTP_OK;
00066     }
00067 
00068     /**
00069      * If we got an POST request the send method will not be executed.
00070      * If we want to send data we have to trigger it the first time by ourself.
00071      * So we execute the send method.
00072      *
00073      * If the rpc call is the content of the POST body we would not be able to execute it.
00074      * Were parsing only the URL.
00075      */
00076     virtual HTTPHandle data(HTTPConnection *con, void *, int) const {
00077       return send(con, con->sndbuf());
00078     }
00079 
00080     /**
00081      * Send the result back to the client.
00082      * If we have not enought space wait for next time.
00083      */
00084     virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
00085       HTTPRPCData *data = static_cast<HTTPRPCData *>(con->data);    
00086       if(maximum>64) {
00087         con->write(data->result, con->getLength());
00088         return HTTP_SuccessEnded;
00089       } else {
00090         // To less memory.
00091         return HTTP_SenderMemory;
00092       }
00093     }
00094 
00095     /**
00096      * To reduce memory usage we sodify the URL directly 
00097      * and replace '%20',',','+','=' with spaces.
00098      */
00099     inline void clean(char *str) const {
00100       while(*str++) {
00101         if(*str=='%'&&*(str+1)=='2'&&*(str+2)=='0') {
00102           *str = ' ';
00103           *(str+1) = ' ';
00104           *(str+2) = ' ';
00105         }
00106         if(*str==','||*str=='+'||*str=='=') {
00107           *str = ' ';
00108         }
00109       }
00110     }
00111 };
00112 #endif
00113 
00114 #endif