This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
Revision 111:f525c6e5e27b, committed 2015-03-16
- Comitter:
- nyatla
- Date:
- Mon Mar 16 14:19:16 2015 +0000
- Parent:
- 110:257739f9b31e
- Child:
- 112:1853d747fcdf
- Commit message:
- ModLocalfilesystem; ; Add virtual directory option.
Changed in this revision
--- a/mbed/mod/ModBaseClass.cpp Sun Mar 15 09:33:38 2015 +0000 +++ b/mbed/mod/ModBaseClass.cpp Mon Mar 16 14:19:16 2015 +0000 @@ -52,5 +52,5 @@ return false; } return true; - } + } }
--- a/mbed/mod/ModBaseClass.h Sun Mar 15 09:33:38 2015 +0000 +++ b/mbed/mod/ModBaseClass.h Mon Mar 16 14:19:16 2015 +0000 @@ -34,6 +34,10 @@ * </pre> */ void setParam(const char* i_path); + /** + * URLとパスプレフィクスi_pathを比較して、処理対象のURLかを計算します。 + * URLに'/i_path/'を含むパスを処理対象とみなします。 + */ virtual bool canHandle(HttpdConnection& i_connection); }; } \ No newline at end of file
--- a/mbed/mod/ModLocalFileSystem.cpp Sun Mar 15 09:33:38 2015 +0000 +++ b/mbed/mod/ModLocalFileSystem.cpp Mon Mar 16 14:19:16 2015 +0000 @@ -12,7 +12,17 @@ using namespace MiMic; -static void retDirJson(UrlReader& url,char* buf,HttpdConnection& i_connection,unsigned char i_fs_type) + +static void write_path(HttpdConnection& i_connection,const char* i_buf,const char* i_root_alias,const char* i_f_path) +{ + if(i_root_alias==NULL){ + i_connection.sendBodyF("%s",i_buf); + }else{ + i_connection.sendBodyF("%.*s%s",strlen(i_root_alias)-1,i_root_alias,i_buf+strlen(i_f_path)+1); + } +} + +void ModLocalFileSystem::retDirJson(const char* i_buf,HttpdConnection& i_connection,unsigned char i_fs_type) { //assert(HEAD or GET) //directory-list json @@ -22,24 +32,21 @@ if(!i_connection.isMethodType(Http::MT_GET)){ return; } - const char* t; - int l; - url.getPath(t,l); - buf[l]='\0';//split path - //remove '/' - if(buf[l-1]=='/'){ - buf[l-1]='\0'; - } - DIR* d=opendir(buf); + + DIR* d=opendir(i_buf); if ( d == NULL ) { - i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":404,\"list\":[]}",buf); + i_connection.sendBodyF("{\"dir\":\""); + write_path(i_connection,i_buf,this->_root_alias,this->_path); + i_connection.sendBodyF("\",\"status\":404,\"list\":[]}"); return; } if(!i_connection.isMethodType(Http::MT_GET)){ //nothing to do }else{ - i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":200,\"list\":[",buf); + i_connection.sendBodyF("{\"dir\":\""); + write_path(i_connection,i_buf,this->_root_alias,this->_path); + i_connection.sendBodyF("\",\"status\":200,\"list\":["); switch(i_fs_type){ case ModLocalFileSystem::FST_DEFAULT: for(struct dirent *p= readdir(d);;) @@ -74,17 +81,12 @@ } closedir(d); } -static void retDirHtml(UrlReader& url,char* buf,HttpdConnection& i_connection,unsigned char i_fs_type) +void ModLocalFileSystem::retDirHtml(const char* i_buf,HttpdConnection& i_connection,unsigned char i_fs_type) { //assert(HEAD or GET) - buf[strlen(buf)-1]='\0';//convert to dir path - DIR* d=opendir(buf); + DIR* d=opendir(i_buf); if(d==NULL){ i_connection.sendError(403); - if(!i_connection.isMethodType(Http::MT_GET)){ - return; - } - i_connection.sendBodyF("<!DOCTYPE html><html><body><h1>403 Forbidden</h1><hr/>'%s'</body></html>",buf); return; } if(!i_connection.sendHeader(200,"text/html",NULL)){ @@ -94,9 +96,10 @@ //nothing to do. }else{ i_connection.sendBodyF( - "<!DOCTYPE html><html><body><h1>Index of %s</h1><hr/>\n" - "<ul>\n" - ,buf); + "<!DOCTYPE html><html><body><h1>Index of "); + write_path(i_connection,i_buf,this->_root_alias,this->_path); + i_connection.sendBodyF("</h1><hr/>\n" + "<ul>\n"); switch(i_fs_type){ case ModLocalFileSystem::FST_DEFAULT: for(struct dirent *p = readdir(d);p!=NULL;p = readdir(d)) @@ -120,49 +123,39 @@ default: break; } - i_connection.sendBodyF("</ul></body></html>",buf); + i_connection.sendBodyF("</ul></body></html>"); } } closedir(d); } -static void retFile(UrlReader& url,char* buf,HttpdConnection& i_connection) +/** + * @param i_path + * i_pathにはnull終端ファイルパスを入れてください。 + */ +void ModLocalFileSystem::retFile(char* i_buf,HttpdConnection& i_connection) { - //file contents - {//split URL path and query - const char* t; - int l; - url.getPath(t,l); - buf[l]='\0'; - } //return content - FILE *fp; - size_t sz; - //size - fp = fopen(buf, "r"); + FILE *fp = fopen(i_buf, "r"); if(fp==NULL){ i_connection.sendError(404); - if(!i_connection.isMethodType(Http::MT_GET)){ - return; - } - i_connection.sendBodyF("<!DOCTYPE html><html><body>'%s' not found.</body></html>",buf); return; } fseek(fp, 0, SEEK_END); // seek to end of file - sz = ftell(fp); // get current file pointer + size_t sz = ftell(fp); // get current file pointer fseek(fp, 0, SEEK_SET); // seek back to beginning of file - if(i_connection.sendHeader(200,NyLPC_cMiMeType_getFileName2MimeType(buf),NULL,sz)){ + if(i_connection.sendHeader(200,NyLPC_cMiMeType_getFileName2MimeType(i_buf),NULL,sz)){ if(!i_connection.isMethodType(Http::MT_GET)){ //nothing to do }else{ Timer t; t.start(); for(;;){ - sz=fread(buf,1,Httpd::SIZE_OF_HTTP_BUF,fp); + sz=fread(i_buf,1,Httpd::SIZE_OF_HTTP_BUF,fp); if(sz<1){ break; } - if(!i_connection.sendBody(buf,sz)){ + if(!i_connection.sendBody(i_buf,sz)){ break; } //switch other session @@ -179,25 +172,67 @@ fclose(fp); } +NyLPC_TBool flip_url_prefix(char* buf, int buf_len, const char* url_prefix, const char* file_path) +{ + size_t bl = strlen(url_prefix); + size_t al = strlen(file_path)+2; + if (al - bl + strlen(buf) + 1 > buf_len){ + return NyLPC_TBool_FALSE; + } + if (strncmp(buf, url_prefix, bl) == 0){ + memmove(buf + al, buf + bl, strlen(buf) - bl + 1); + memcpy(buf + 1, file_path, al - 1); + *(buf + al - 1) = '/'; + } + return NyLPC_TBool_TRUE; +} namespace MiMic { - ModLocalFileSystem::ModLocalFileSystem(const char* i_path,unsigned char i_fs_type):ModBaseClass(i_path) + ModLocalFileSystem::ModLocalFileSystem(const char* i_path,const char* i_root_alias,unsigned char i_fs_type):ModBaseClass() { - this->_fs_type=i_fs_type; + this->setParam(i_path,i_root_alias,i_fs_type); + } + ModLocalFileSystem::ModLocalFileSystem(const char* i_path,unsigned char i_fs_type):ModBaseClass() + { + this->setParam(i_path,NULL,i_fs_type); } ModLocalFileSystem::ModLocalFileSystem():ModBaseClass() { + this->_root_alias=NULL; } ModLocalFileSystem::~ModLocalFileSystem() { } + void ModLocalFileSystem::setParam(const char* i_path,const char* i_root_alias,unsigned char i_fs_type) + { + NyLPC_Assert(strlen(i_root_alias)>0); + ModBaseClass::setParam(i_path); + this->_root_alias=i_root_alias; + this->_fs_type=i_fs_type; + } void ModLocalFileSystem::setParam(const char* i_path,unsigned char i_fs_type) { - ModBaseClass::setParam(i_path); - this->_fs_type=i_fs_type; + this->setParam(i_path,NULL,i_fs_type); } - + bool ModLocalFileSystem::canHandle(HttpdConnection& i_connection) + { + if(this->_root_alias==NULL){ + return ModBaseClass::canHandle(i_connection); + } + //root alias指定がある場合 + if(!NyLPC_cHttpdConnection_getReqStatus(i_connection._ref_inst)==NyLPC_cHttpdConnection_ReqStatus_REQPARSE) + { + return NyLPC_TBool_FALSE; + } + const NyLPC_TChar* in_url; + in_url=NyLPC_cHttpdConnection_getUrlPrefix(i_connection._ref_inst); + size_t base_url_len=strlen(this->_root_alias); + if(strncmp(this->_root_alias,in_url,base_url_len)!=0){ + return false; + } + return true; + } bool ModLocalFileSystem::execute(HttpdConnection& i_connection) { //check platform @@ -233,15 +268,33 @@ } NyLPC_cModUrl_finalize(&mod); } + //パスのエイリアスがあるときはここで編集 + if(this->_root_alias!=NULL){ + flip_url_prefix(buf,Httpd::SIZE_OF_HTTP_BUF,this->_root_alias,this->_path); + } UrlReader url(buf); if(url.hasQueryKey("list")){ // if path has '/?list' query key,return directory information - retDirJson(url,buf,i_connection,this->_fs_type); + const char* t; + int l; + url.getPath(t,l); + buf[l]='\0';//split path + //remove '/' + if(buf[l-1]=='/'){ + buf[l-1]='\0'; + } + retDirJson(buf,i_connection,this->_fs_type); }else if(strchr(buf,'?')==NULL && strchr(buf,'#')==NULL && buf[strlen(buf)-1]=='/'){ //return directory html when URL has not bookmark and URL query and terminated by '/'. - retDirHtml(url,buf,i_connection,this->_fs_type); + buf[strlen(buf)-1]='\0';//convert to dir path + retDirHtml(buf,i_connection,this->_fs_type); }else{ - retFile(url,buf,i_connection); + //split URL path and query + const char* t; + int l; + url.getPath(t,l); + buf[l]='\0'; + retFile(buf,i_connection); } //Httpd unlock i_connection.unlockHttpd();
--- a/mbed/mod/ModLocalFileSystem.h Sun Mar 15 09:33:38 2015 +0000 +++ b/mbed/mod/ModLocalFileSystem.h Mon Mar 16 14:19:16 2015 +0000 @@ -28,11 +28,19 @@ private: /** file system type*/ unsigned char _fs_type; + /** ルートディレクトリのプレフィクス "/pathname/" 表記*/ + const char* _root_alias; + private: + void retFile(char* i_buf,HttpdConnection& i_connection); + void retDirHtml(const char* i_buf,HttpdConnection& i_connection,unsigned char i_fs_type); + void retDirJson(const char* buf,HttpdConnection& i_connection,unsigned char i_fs_type); + public: const static unsigned char FST_DEFAULT=0x00; const static unsigned char FST_SDFATFS=0x01; public: /** + * Create filesistem responder. * @param i_fs_type * Filesystem type. * This value should match the file system type of mount point. @@ -42,9 +50,23 @@ * </ul> */ ModLocalFileSystem(const char* i_path,unsigned char i_fs_type=FST_DEFAULT); + /** + * 2nd constructor. + * @param i_root_alias + * Root path string. Handler replaces the accepted URL prefix in the root path. + * ex. '/' or '/virtual_path/', + */ + ModLocalFileSystem(const char* i_path,const char* i_root_alias,unsigned char i_fs_type=FST_DEFAULT); + /** + * 3rd donstructor. + * Must be call setParam method before call execute. + */ ModLocalFileSystem(); virtual ~ModLocalFileSystem(); void setParam(const char* i_path,unsigned char i_fs_type=FST_DEFAULT); + void setParam(const char* i_path,const char* i_root_alias,unsigned char i_fs_type=FST_DEFAULT); + virtual bool canHandle(HttpdConnection& i_connection); + bool execute(HttpdConnection& i_connection); };