Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
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);
};
MiMic Webservice library