version 0.1.6
[fms.git] / src / http / ipagehandler.cpp
diff --git a/src/http/ipagehandler.cpp b/src/http/ipagehandler.cpp
new file mode 100644 (file)
index 0000000..230da65
--- /dev/null
@@ -0,0 +1,100 @@
+#include "../../include/http/ipagehandler.h"\r
+#include "../../include/http/httpdefs.h"\r
+#include "../../include/stringfunctions.h"\r
+\r
+#ifdef XMEM\r
+       #include <xmem.h>\r
+#endif\r
+\r
+const bool IPageHandler::Handle(shttpd_arg *arg)\r
+{\r
+       const char *uri=shttpd_get_env(arg,"REQUEST_URI");\r
+       const char *method=shttpd_get_env(arg,"REQUEST_METHOD");\r
+       std::string methodstr="";\r
+       if(method)\r
+       {\r
+               methodstr=method;\r
+       }\r
+\r
+       if(uri && WillHandleURI(std::string(uri)))\r
+       {\r
+               httpstate *mystate=(httpstate *)arg->state;\r
+               // this is a new request - create a new arg object\r
+               if(arg->state==NULL)\r
+               {\r
+                       arg->state=new httpstate;\r
+                       memset(arg->state,0,sizeof(httpstate));\r
+                       mystate=(httpstate *)arg->state;\r
+\r
+                       // if post then create input buffer\r
+                       if(methodstr=="POST")\r
+                       {\r
+                               const char *lenstr=shttpd_get_header(arg,"Content-Length");\r
+                               if(lenstr)\r
+                               {\r
+                                       long len;\r
+                                       StringFunctions::Convert(std::string(lenstr),len);\r
+                                       mystate->m_indata=new char[len];\r
+                                       mystate->m_indatalen=len;\r
+                                       mystate->m_indatapos=0;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // we have more POST data to get\r
+               if(arg->in.len>0)\r
+               {\r
+                       int pos=0;\r
+                       while(arg->in.num_bytes<arg->in.len)\r
+                       {\r
+                               mystate->m_indata[mystate->m_indatapos++]=arg->in.buf[pos++];\r
+                       }\r
+                       arg->in.num_bytes=arg->in.len;\r
+               }\r
+\r
+               // we have all POST data (or it was 0 to begin with) - generate the page\r
+               if(mystate->m_indatalen==mystate->m_indatapos && mystate->m_outdata==NULL)\r
+               {\r
+                       //TODO parse POST data and any QUERY_STRING before generating page\r
+                       std::string page=GeneratePage(methodstr,std::map<std::string,std::string>());\r
+                       mystate->m_outdata=new char[page.size()];\r
+                       memcpy(mystate->m_outdata,page.c_str(),page.size());\r
+                       mystate->m_outdatalen=page.size();\r
+                       mystate->m_outdatapos=0;\r
+               }\r
+\r
+               // if we have output data, push next block of data onto out buffer\r
+               if(mystate->m_outdata && mystate->m_outdatapos<mystate->m_outdatalen)\r
+               {\r
+                       int pos=0;\r
+                       while(mystate->m_outdatapos<mystate->m_outdatalen && pos<arg->out.len)\r
+                       {\r
+                               arg->out.buf[pos++]=mystate->m_outdata[mystate->m_outdatapos++];\r
+                       }\r
+                       arg->out.num_bytes=pos;\r
+               }\r
+\r
+               // if we have no more output data to send - delete the data pointers and set end of output flag\r
+               if(mystate->m_outdata && mystate->m_outdatapos==mystate->m_outdatalen)\r
+               {\r
+                       if(mystate->m_indata)\r
+                       {\r
+                               delete mystate->m_indata;\r
+                       }\r
+                       if(mystate->m_outdata)\r
+                       {\r
+                               delete mystate->m_outdata;\r
+                       }\r
+                       delete mystate;\r
+                       arg->state=NULL;\r
+\r
+                       arg->flags|=SHTTPD_END_OF_OUTPUT;\r
+               }\r
+\r
+               return true;\r
+       }\r
+       else\r
+       {\r
+               return false;\r
+       }\r
+}\r