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
lwip/HTTPServer/HTTPRPC.h
- Committer:
- mitesh2patel
- Date:
- 2010-12-15
- Revision:
- 0:e1a0471e5ffb
File content as of revision 0:e1a0471e5ffb:
// HTTPRPC.h // Modified by iva2k // Improved URL string handling // #ifndef HTTPRPC_H #define HTTPRPC_H #include "HTTPServer.h" #include "platform.h" #ifdef MBED_RPC #include "rpc.h" #ifndef HTTPRPC_USE_URI_FIELDS #define HTTPRPC_USE_URI_FIELDS 1 #endif /** * A datastorage helper for the HTTPRPC class */ class HTTPRPCData : public HTTPData { public: char result[255]; }; /** * Thsi class enables you to make rpc calls to your mbed. * Furthermore it is a good example how to write a HTTPHandler for small data chunks. */ class HTTPRPC : public HTTPHandler { public: /** * We have to know the prefix for the RPCHandler. * A good default choice is /rpc so we made this default. */ HTTPRPC(const char *path = "/rpc") : HTTPHandler(path) {} HTTPRPC(HTTPServer *server, const char *path = "/rpc") : HTTPHandler(path) { server->addHandler(this); } private: /** * If you need some Headerfeelds you have tor register the feelds here. */ // virtual void reg(HTTPServer *svr) { // svr->registerField("Content-Length"); // } /** * If a new RPCRequest Header is complete received the server will call this function. * This is the right place for preparing our datastructures. * Furthermore we will execute the rpc call and store the anwere. * But we will not send a response. This will be hapen in the send method. */ virtual HTTPStatus init(HTTPConnection *con) const { HTTPRPCData *data = new HTTPRPCData(); con->data = data; char *query = con->getURL()+strlen(_prefix); query = clean(query); rpc(query, data->result); 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"; char *old = (char *)con->getHeaderFields(); int oldlen = strlen(old); int atrlen = strlen(nfields); char *fields = new char[atrlen+oldlen+3]; strcpy(fields,old); fields[oldlen+0] = '\r'; fields[oldlen+1] = '\n'; strcpy(&fields[oldlen+2], nfields); fields[atrlen+2+oldlen] = '\0'; con->setHeaderFields(fields); if(*old) { delete old; } con->setLength(strlen(data->result)); return HTTP_OK; } /** * If we got an POST request the send method will not be executed. * If we want to send data we have to trigger it the first time by ourself. * So we execute the send method. * * If the rpc call is the content of the POST body we would not be able to execute it. * Were parsing only the URL. */ virtual HTTPHandle data(HTTPConnection *con, void *, int) const { return send(con, con->sndbuf()); } /** * Send the result back to the client. * If we have not enought space wait for next time. */ virtual HTTPHandle send(HTTPConnection *con, int maximum) const { HTTPRPCData *data = static_cast<HTTPRPCData *>(con->data); if(maximum>64) { con->write(data->result, con->getLength()); return HTTP_SuccessEnded; } else { // To less memory. return HTTP_SenderMemory; } } inline bool is_hex(const char a) const { return (a>='0' && a<='9') || (a>='A' && a<='F') || (a>='a' && a<='f'); } inline char hex_nib(const char a) const { return 0xf & ( (a>='0' && a<='9') ? (a-'0' ) : (a>='A' && a<='F') ? (a-'A'+10) : (a>='a' && a<='f') ? (a-'a'+10) : 0 ); } inline char hex_byte(const char *str) const { return (hex_nib(*str) << 4) | hex_nib(*(str+1)); } /** * To reduce memory usage we sodify the URL directly * and replace '%20',',','+','=' with spaces. */ // mutable char _buf[1024]; inline char *clean(char *str) const { char *in = str; // char *out = _buf; char *out = str; // this will do conversions in-place. bool inquotes=false; bool backslash=false; bool hasquery=false; bool cantquery=false; // cantquery=true will indicate that the URI already has symbols // incompatible with query, so it disables checking for query. #if HTTPRPC_USE_URI_FIELDS bool infield=false; // bool rpcquery=false; char *field=out; #endif printf("\r\nDEBUG HTTPRPC::clean() IN=:%s:\r\n",str); while (*in) { #if HTTPRPC_USE_URI_FIELDS // Check if URI has query part // in form "/rpc/obj/method?arg1=val1&arg2=val2&arg3=val3" if (!inquotes && !cantquery && !hasquery && *in == '?') { hasquery = true; *out = ' '; out++; // delimit base URI part infield = true; in++; field=in; continue; // New field started. Do nothing yet } // Check if URI with query part is delimited if (!inquotes && !infield && hasquery && *in == '&') { *out = ' '; out++; // delimit current arg infield = true; in++; field=in; continue; // New field started } if (infield) { // Process the query - skip till '=' // Also check if it is in form "/rpc/obj/method?val1&val2&val3" if (!inquotes && *in == '&') { // modified query - catch up while (field<in) { *out = *field; if (*field=='%' && is_hex(*(field+1)) && is_hex(*(field+2)) ) { *out = hex_byte(++field); field++; // field is incremented by 2 total } if (!backslash && *out == '"') { inquotes = !inquotes; } backslash = inquotes && !backslash && (*out == '\\'); out++; field++; } *out = ' '; out++; // delimit current arg infield = true; in++; field=in; continue; // New field started } else if (!inquotes && *in == '=') { infield = false; *in = '\0'; // this will mark the field name printf(" - field: %s\r\n", field); // FIXME: here we have a field/arg name. Can we use it to reorder the arguments for the rpc? } else { // Keep tracking quotes char tmp = *in; if (*in=='%' && is_hex(*(in+1)) && is_hex(*(in+2)) ) { tmp = hex_byte(++in); in++; // in is incremented by 2 total } if (!backslash && tmp == '"') { inquotes = !inquotes; } backslash = inquotes && !backslash && (tmp == '\\'); } } else #endif // HTTPRPC_USE_URI_FIELDS { // Keep processing the stream *out = *in; if (*in=='%' && is_hex(*(in+1)) && is_hex(*(in+2)) ) { *out = hex_byte(++in); in++; // in is incremented by 2 total cantquery = !hasquery; // any %-encoded before '?' means it can't be a query } else if (!inquotes && !hasquery && (*in==',' || *in=='+' || *in=='=')) { *out = ' '; // cantquery = !hasquery; // any non-query delimiter disallows URI query } if (!backslash && *out == '"') { inquotes = !inquotes; } backslash = inquotes && !backslash && (*out == '\\'); out++; } in++; } // while #if HTTPRPC_USE_URI_FIELDS if (infield) { // modified query last arg - catch up while (field < in) { *out = *field; if (*field=='%' && is_hex(*(field+1)) && is_hex(*(field+2)) ) { *out = hex_byte(++field); field++; // field is incremented by 2 total } if (!backslash && *out == '"') { inquotes = !inquotes; } backslash = inquotes && !backslash && (*out == '\\'); out++; field++; } } #endif // HTTPRPC_USE_URI_FIELDS hasquery = cantquery; // only removes compiler warning *out = '\0'; // out = _buf; out = str; printf("DEBUG HTTPRPC::clean() OUT=:%s:\r\n", out); return out; } }; #endif #endif