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