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