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
Diff: lwip/HTTPServer/HTTPRPC.h
- Revision:
- 0:e1a0471e5ffb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwip/HTTPServer/HTTPRPC.h Wed Dec 15 15:01:56 2010 +0000 @@ -0,0 +1,247 @@ +// 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