this will take a image from C328 serial camera and store those images in mbed flash as html and this html page is uploaded into the server at ip:192.168.1.2

Dependencies:   mbed

Committer:
mitesh2patel
Date:
Wed Dec 15 15:01:56 2010 +0000
Revision:
0:e1a0471e5ffb

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mitesh2patel 0:e1a0471e5ffb 1 // HTTPRPC.h
mitesh2patel 0:e1a0471e5ffb 2 // Modified by iva2k
mitesh2patel 0:e1a0471e5ffb 3 // Improved URL string handling
mitesh2patel 0:e1a0471e5ffb 4 //
mitesh2patel 0:e1a0471e5ffb 5
mitesh2patel 0:e1a0471e5ffb 6 #ifndef HTTPRPC_H
mitesh2patel 0:e1a0471e5ffb 7 #define HTTPRPC_H
mitesh2patel 0:e1a0471e5ffb 8
mitesh2patel 0:e1a0471e5ffb 9 #include "HTTPServer.h"
mitesh2patel 0:e1a0471e5ffb 10 #include "platform.h"
mitesh2patel 0:e1a0471e5ffb 11 #ifdef MBED_RPC
mitesh2patel 0:e1a0471e5ffb 12 #include "rpc.h"
mitesh2patel 0:e1a0471e5ffb 13
mitesh2patel 0:e1a0471e5ffb 14 #ifndef HTTPRPC_USE_URI_FIELDS
mitesh2patel 0:e1a0471e5ffb 15 #define HTTPRPC_USE_URI_FIELDS 1
mitesh2patel 0:e1a0471e5ffb 16 #endif
mitesh2patel 0:e1a0471e5ffb 17
mitesh2patel 0:e1a0471e5ffb 18 /**
mitesh2patel 0:e1a0471e5ffb 19 * A datastorage helper for the HTTPRPC class
mitesh2patel 0:e1a0471e5ffb 20 */
mitesh2patel 0:e1a0471e5ffb 21 class HTTPRPCData : public HTTPData {
mitesh2patel 0:e1a0471e5ffb 22 public: char result[255];
mitesh2patel 0:e1a0471e5ffb 23 };
mitesh2patel 0:e1a0471e5ffb 24
mitesh2patel 0:e1a0471e5ffb 25 /**
mitesh2patel 0:e1a0471e5ffb 26 * Thsi class enables you to make rpc calls to your mbed.
mitesh2patel 0:e1a0471e5ffb 27 * Furthermore it is a good example how to write a HTTPHandler for small data chunks.
mitesh2patel 0:e1a0471e5ffb 28 */
mitesh2patel 0:e1a0471e5ffb 29 class HTTPRPC : public HTTPHandler {
mitesh2patel 0:e1a0471e5ffb 30 public:
mitesh2patel 0:e1a0471e5ffb 31 /**
mitesh2patel 0:e1a0471e5ffb 32 * We have to know the prefix for the RPCHandler.
mitesh2patel 0:e1a0471e5ffb 33 * A good default choice is /rpc so we made this default.
mitesh2patel 0:e1a0471e5ffb 34 */
mitesh2patel 0:e1a0471e5ffb 35 HTTPRPC(const char *path = "/rpc") : HTTPHandler(path) {}
mitesh2patel 0:e1a0471e5ffb 36 HTTPRPC(HTTPServer *server, const char *path = "/rpc") : HTTPHandler(path) { server->addHandler(this); }
mitesh2patel 0:e1a0471e5ffb 37
mitesh2patel 0:e1a0471e5ffb 38 private:
mitesh2patel 0:e1a0471e5ffb 39 /**
mitesh2patel 0:e1a0471e5ffb 40 * If you need some Headerfeelds you have tor register the feelds here.
mitesh2patel 0:e1a0471e5ffb 41 */
mitesh2patel 0:e1a0471e5ffb 42 // virtual void reg(HTTPServer *svr) {
mitesh2patel 0:e1a0471e5ffb 43 // svr->registerField("Content-Length");
mitesh2patel 0:e1a0471e5ffb 44 // }
mitesh2patel 0:e1a0471e5ffb 45
mitesh2patel 0:e1a0471e5ffb 46 /**
mitesh2patel 0:e1a0471e5ffb 47 * If a new RPCRequest Header is complete received the server will call this function.
mitesh2patel 0:e1a0471e5ffb 48 * This is the right place for preparing our datastructures.
mitesh2patel 0:e1a0471e5ffb 49 * Furthermore we will execute the rpc call and store the anwere.
mitesh2patel 0:e1a0471e5ffb 50 * But we will not send a response. This will be hapen in the send method.
mitesh2patel 0:e1a0471e5ffb 51 */
mitesh2patel 0:e1a0471e5ffb 52 virtual HTTPStatus init(HTTPConnection *con) const {
mitesh2patel 0:e1a0471e5ffb 53 HTTPRPCData *data = new HTTPRPCData();
mitesh2patel 0:e1a0471e5ffb 54 con->data = data;
mitesh2patel 0:e1a0471e5ffb 55 char *query = con->getURL()+strlen(_prefix);
mitesh2patel 0:e1a0471e5ffb 56 query = clean(query);
mitesh2patel 0:e1a0471e5ffb 57 rpc(query, data->result);
mitesh2patel 0:e1a0471e5ffb 58
mitesh2patel 0:e1a0471e5ffb 59 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";
mitesh2patel 0:e1a0471e5ffb 60 char *old = (char *)con->getHeaderFields();
mitesh2patel 0:e1a0471e5ffb 61 int oldlen = strlen(old);
mitesh2patel 0:e1a0471e5ffb 62 int atrlen = strlen(nfields);
mitesh2patel 0:e1a0471e5ffb 63 char *fields = new char[atrlen+oldlen+3];
mitesh2patel 0:e1a0471e5ffb 64 strcpy(fields,old);
mitesh2patel 0:e1a0471e5ffb 65 fields[oldlen+0] = '\r';
mitesh2patel 0:e1a0471e5ffb 66 fields[oldlen+1] = '\n';
mitesh2patel 0:e1a0471e5ffb 67 strcpy(&fields[oldlen+2], nfields);
mitesh2patel 0:e1a0471e5ffb 68 fields[atrlen+2+oldlen] = '\0';
mitesh2patel 0:e1a0471e5ffb 69 con->setHeaderFields(fields);
mitesh2patel 0:e1a0471e5ffb 70 if(*old) {
mitesh2patel 0:e1a0471e5ffb 71 delete old;
mitesh2patel 0:e1a0471e5ffb 72 }
mitesh2patel 0:e1a0471e5ffb 73
mitesh2patel 0:e1a0471e5ffb 74 con->setLength(strlen(data->result));
mitesh2patel 0:e1a0471e5ffb 75 return HTTP_OK;
mitesh2patel 0:e1a0471e5ffb 76 }
mitesh2patel 0:e1a0471e5ffb 77
mitesh2patel 0:e1a0471e5ffb 78 /**
mitesh2patel 0:e1a0471e5ffb 79 * If we got an POST request the send method will not be executed.
mitesh2patel 0:e1a0471e5ffb 80 * If we want to send data we have to trigger it the first time by ourself.
mitesh2patel 0:e1a0471e5ffb 81 * So we execute the send method.
mitesh2patel 0:e1a0471e5ffb 82 *
mitesh2patel 0:e1a0471e5ffb 83 * If the rpc call is the content of the POST body we would not be able to execute it.
mitesh2patel 0:e1a0471e5ffb 84 * Were parsing only the URL.
mitesh2patel 0:e1a0471e5ffb 85 */
mitesh2patel 0:e1a0471e5ffb 86 virtual HTTPHandle data(HTTPConnection *con, void *, int) const {
mitesh2patel 0:e1a0471e5ffb 87 return send(con, con->sndbuf());
mitesh2patel 0:e1a0471e5ffb 88 }
mitesh2patel 0:e1a0471e5ffb 89
mitesh2patel 0:e1a0471e5ffb 90 /**
mitesh2patel 0:e1a0471e5ffb 91 * Send the result back to the client.
mitesh2patel 0:e1a0471e5ffb 92 * If we have not enought space wait for next time.
mitesh2patel 0:e1a0471e5ffb 93 */
mitesh2patel 0:e1a0471e5ffb 94 virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
mitesh2patel 0:e1a0471e5ffb 95 HTTPRPCData *data = static_cast<HTTPRPCData *>(con->data);
mitesh2patel 0:e1a0471e5ffb 96 if(maximum>64) {
mitesh2patel 0:e1a0471e5ffb 97 con->write(data->result, con->getLength());
mitesh2patel 0:e1a0471e5ffb 98 return HTTP_SuccessEnded;
mitesh2patel 0:e1a0471e5ffb 99 } else {
mitesh2patel 0:e1a0471e5ffb 100 // To less memory.
mitesh2patel 0:e1a0471e5ffb 101 return HTTP_SenderMemory;
mitesh2patel 0:e1a0471e5ffb 102 }
mitesh2patel 0:e1a0471e5ffb 103 }
mitesh2patel 0:e1a0471e5ffb 104
mitesh2patel 0:e1a0471e5ffb 105 inline bool is_hex(const char a) const {
mitesh2patel 0:e1a0471e5ffb 106 return (a>='0' && a<='9') || (a>='A' && a<='F') || (a>='a' && a<='f');
mitesh2patel 0:e1a0471e5ffb 107 }
mitesh2patel 0:e1a0471e5ffb 108 inline char hex_nib(const char a) const {
mitesh2patel 0:e1a0471e5ffb 109 return 0xf & (
mitesh2patel 0:e1a0471e5ffb 110 (a>='0' && a<='9') ? (a-'0' ) :
mitesh2patel 0:e1a0471e5ffb 111 (a>='A' && a<='F') ? (a-'A'+10) :
mitesh2patel 0:e1a0471e5ffb 112 (a>='a' && a<='f') ? (a-'a'+10) : 0
mitesh2patel 0:e1a0471e5ffb 113 );
mitesh2patel 0:e1a0471e5ffb 114 }
mitesh2patel 0:e1a0471e5ffb 115 inline char hex_byte(const char *str) const {
mitesh2patel 0:e1a0471e5ffb 116 return (hex_nib(*str) << 4) | hex_nib(*(str+1));
mitesh2patel 0:e1a0471e5ffb 117 }
mitesh2patel 0:e1a0471e5ffb 118 /**
mitesh2patel 0:e1a0471e5ffb 119 * To reduce memory usage we sodify the URL directly
mitesh2patel 0:e1a0471e5ffb 120 * and replace '%20',',','+','=' with spaces.
mitesh2patel 0:e1a0471e5ffb 121 */
mitesh2patel 0:e1a0471e5ffb 122 // mutable char _buf[1024];
mitesh2patel 0:e1a0471e5ffb 123 inline char *clean(char *str) const {
mitesh2patel 0:e1a0471e5ffb 124 char *in = str;
mitesh2patel 0:e1a0471e5ffb 125 // char *out = _buf;
mitesh2patel 0:e1a0471e5ffb 126 char *out = str; // this will do conversions in-place.
mitesh2patel 0:e1a0471e5ffb 127 bool inquotes=false;
mitesh2patel 0:e1a0471e5ffb 128 bool backslash=false;
mitesh2patel 0:e1a0471e5ffb 129 bool hasquery=false;
mitesh2patel 0:e1a0471e5ffb 130 bool cantquery=false;
mitesh2patel 0:e1a0471e5ffb 131 // cantquery=true will indicate that the URI already has symbols
mitesh2patel 0:e1a0471e5ffb 132 // incompatible with query, so it disables checking for query.
mitesh2patel 0:e1a0471e5ffb 133 #if HTTPRPC_USE_URI_FIELDS
mitesh2patel 0:e1a0471e5ffb 134 bool infield=false;
mitesh2patel 0:e1a0471e5ffb 135 // bool rpcquery=false;
mitesh2patel 0:e1a0471e5ffb 136 char *field=out;
mitesh2patel 0:e1a0471e5ffb 137 #endif
mitesh2patel 0:e1a0471e5ffb 138
mitesh2patel 0:e1a0471e5ffb 139 printf("\r\nDEBUG HTTPRPC::clean() IN=:%s:\r\n",str);
mitesh2patel 0:e1a0471e5ffb 140 while (*in) {
mitesh2patel 0:e1a0471e5ffb 141 #if HTTPRPC_USE_URI_FIELDS
mitesh2patel 0:e1a0471e5ffb 142 // Check if URI has query part
mitesh2patel 0:e1a0471e5ffb 143 // in form "/rpc/obj/method?arg1=val1&arg2=val2&arg3=val3"
mitesh2patel 0:e1a0471e5ffb 144 if (!inquotes && !cantquery && !hasquery && *in == '?') {
mitesh2patel 0:e1a0471e5ffb 145 hasquery = true;
mitesh2patel 0:e1a0471e5ffb 146 *out = ' '; out++; // delimit base URI part
mitesh2patel 0:e1a0471e5ffb 147 infield = true; in++; field=in; continue;
mitesh2patel 0:e1a0471e5ffb 148 // New field started. Do nothing yet
mitesh2patel 0:e1a0471e5ffb 149 }
mitesh2patel 0:e1a0471e5ffb 150 // Check if URI with query part is delimited
mitesh2patel 0:e1a0471e5ffb 151 if (!inquotes && !infield && hasquery && *in == '&') {
mitesh2patel 0:e1a0471e5ffb 152 *out = ' '; out++; // delimit current arg
mitesh2patel 0:e1a0471e5ffb 153 infield = true; in++; field=in; continue;
mitesh2patel 0:e1a0471e5ffb 154 // New field started
mitesh2patel 0:e1a0471e5ffb 155 }
mitesh2patel 0:e1a0471e5ffb 156 if (infield) {
mitesh2patel 0:e1a0471e5ffb 157 // Process the query - skip till '='
mitesh2patel 0:e1a0471e5ffb 158 // Also check if it is in form "/rpc/obj/method?val1&val2&val3"
mitesh2patel 0:e1a0471e5ffb 159 if (!inquotes && *in == '&') {
mitesh2patel 0:e1a0471e5ffb 160 // modified query - catch up
mitesh2patel 0:e1a0471e5ffb 161 while (field<in) {
mitesh2patel 0:e1a0471e5ffb 162 *out = *field;
mitesh2patel 0:e1a0471e5ffb 163 if (*field=='%' && is_hex(*(field+1)) && is_hex(*(field+2)) ) {
mitesh2patel 0:e1a0471e5ffb 164 *out = hex_byte(++field);
mitesh2patel 0:e1a0471e5ffb 165 field++; // field is incremented by 2 total
mitesh2patel 0:e1a0471e5ffb 166 }
mitesh2patel 0:e1a0471e5ffb 167 if (!backslash && *out == '"') { inquotes = !inquotes; }
mitesh2patel 0:e1a0471e5ffb 168 backslash = inquotes && !backslash && (*out == '\\');
mitesh2patel 0:e1a0471e5ffb 169
mitesh2patel 0:e1a0471e5ffb 170 out++;
mitesh2patel 0:e1a0471e5ffb 171 field++;
mitesh2patel 0:e1a0471e5ffb 172 }
mitesh2patel 0:e1a0471e5ffb 173
mitesh2patel 0:e1a0471e5ffb 174 *out = ' '; out++; // delimit current arg
mitesh2patel 0:e1a0471e5ffb 175 infield = true; in++; field=in; continue;
mitesh2patel 0:e1a0471e5ffb 176 // New field started
mitesh2patel 0:e1a0471e5ffb 177 } else
mitesh2patel 0:e1a0471e5ffb 178 if (!inquotes && *in == '=') {
mitesh2patel 0:e1a0471e5ffb 179 infield = false;
mitesh2patel 0:e1a0471e5ffb 180 *in = '\0'; // this will mark the field name
mitesh2patel 0:e1a0471e5ffb 181 printf(" - field: %s\r\n", field);
mitesh2patel 0:e1a0471e5ffb 182 // FIXME: here we have a field/arg name. Can we use it to reorder the arguments for the rpc?
mitesh2patel 0:e1a0471e5ffb 183
mitesh2patel 0:e1a0471e5ffb 184 } else {
mitesh2patel 0:e1a0471e5ffb 185 // Keep tracking quotes
mitesh2patel 0:e1a0471e5ffb 186 char tmp = *in;
mitesh2patel 0:e1a0471e5ffb 187 if (*in=='%' && is_hex(*(in+1)) && is_hex(*(in+2)) ) {
mitesh2patel 0:e1a0471e5ffb 188 tmp = hex_byte(++in);
mitesh2patel 0:e1a0471e5ffb 189 in++; // in is incremented by 2 total
mitesh2patel 0:e1a0471e5ffb 190 }
mitesh2patel 0:e1a0471e5ffb 191 if (!backslash && tmp == '"') { inquotes = !inquotes; }
mitesh2patel 0:e1a0471e5ffb 192 backslash = inquotes && !backslash && (tmp == '\\');
mitesh2patel 0:e1a0471e5ffb 193 }
mitesh2patel 0:e1a0471e5ffb 194 } else
mitesh2patel 0:e1a0471e5ffb 195 #endif // HTTPRPC_USE_URI_FIELDS
mitesh2patel 0:e1a0471e5ffb 196 {
mitesh2patel 0:e1a0471e5ffb 197 // Keep processing the stream
mitesh2patel 0:e1a0471e5ffb 198 *out = *in;
mitesh2patel 0:e1a0471e5ffb 199
mitesh2patel 0:e1a0471e5ffb 200 if (*in=='%' && is_hex(*(in+1)) && is_hex(*(in+2)) ) {
mitesh2patel 0:e1a0471e5ffb 201 *out = hex_byte(++in);
mitesh2patel 0:e1a0471e5ffb 202 in++; // in is incremented by 2 total
mitesh2patel 0:e1a0471e5ffb 203 cantquery = !hasquery; // any %-encoded before '?' means it can't be a query
mitesh2patel 0:e1a0471e5ffb 204 } else
mitesh2patel 0:e1a0471e5ffb 205 if (!inquotes && !hasquery && (*in==',' || *in=='+' || *in=='=')) {
mitesh2patel 0:e1a0471e5ffb 206 *out = ' ';
mitesh2patel 0:e1a0471e5ffb 207 // cantquery = !hasquery; // any non-query delimiter disallows URI query
mitesh2patel 0:e1a0471e5ffb 208 }
mitesh2patel 0:e1a0471e5ffb 209 if (!backslash && *out == '"') { inquotes = !inquotes; }
mitesh2patel 0:e1a0471e5ffb 210 backslash = inquotes && !backslash && (*out == '\\');
mitesh2patel 0:e1a0471e5ffb 211
mitesh2patel 0:e1a0471e5ffb 212 out++;
mitesh2patel 0:e1a0471e5ffb 213 }
mitesh2patel 0:e1a0471e5ffb 214
mitesh2patel 0:e1a0471e5ffb 215 in++;
mitesh2patel 0:e1a0471e5ffb 216 } // while
mitesh2patel 0:e1a0471e5ffb 217
mitesh2patel 0:e1a0471e5ffb 218 #if HTTPRPC_USE_URI_FIELDS
mitesh2patel 0:e1a0471e5ffb 219 if (infield) {
mitesh2patel 0:e1a0471e5ffb 220 // modified query last arg - catch up
mitesh2patel 0:e1a0471e5ffb 221 while (field < in) {
mitesh2patel 0:e1a0471e5ffb 222 *out = *field;
mitesh2patel 0:e1a0471e5ffb 223 if (*field=='%' && is_hex(*(field+1)) && is_hex(*(field+2)) ) {
mitesh2patel 0:e1a0471e5ffb 224 *out = hex_byte(++field);
mitesh2patel 0:e1a0471e5ffb 225 field++; // field is incremented by 2 total
mitesh2patel 0:e1a0471e5ffb 226 }
mitesh2patel 0:e1a0471e5ffb 227 if (!backslash && *out == '"') { inquotes = !inquotes; }
mitesh2patel 0:e1a0471e5ffb 228 backslash = inquotes && !backslash && (*out == '\\');
mitesh2patel 0:e1a0471e5ffb 229
mitesh2patel 0:e1a0471e5ffb 230 out++;
mitesh2patel 0:e1a0471e5ffb 231 field++;
mitesh2patel 0:e1a0471e5ffb 232 }
mitesh2patel 0:e1a0471e5ffb 233 }
mitesh2patel 0:e1a0471e5ffb 234 #endif // HTTPRPC_USE_URI_FIELDS
mitesh2patel 0:e1a0471e5ffb 235
mitesh2patel 0:e1a0471e5ffb 236 hasquery = cantquery; // only removes compiler warning
mitesh2patel 0:e1a0471e5ffb 237 *out = '\0';
mitesh2patel 0:e1a0471e5ffb 238
mitesh2patel 0:e1a0471e5ffb 239 // out = _buf;
mitesh2patel 0:e1a0471e5ffb 240 out = str;
mitesh2patel 0:e1a0471e5ffb 241 printf("DEBUG HTTPRPC::clean() OUT=:%s:\r\n", out);
mitesh2patel 0:e1a0471e5ffb 242 return out;
mitesh2patel 0:e1a0471e5ffb 243 }
mitesh2patel 0:e1a0471e5ffb 244 };
mitesh2patel 0:e1a0471e5ffb 245 #endif
mitesh2patel 0:e1a0471e5ffb 246
mitesh2patel 0:e1a0471e5ffb 247 #endif