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.
Fork of libMiMic by
Diff: mbed/mod/ModLocalFileSystem.cpp
- Revision:
- 111:f525c6e5e27b
- Parent:
- 48:00d211aac2ec
diff -r 257739f9b31e -r f525c6e5e27b mbed/mod/ModLocalFileSystem.cpp
--- 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();
