Jun Furutani / libMiMic

Fork of libMiMic by Ryo Iizuka

Revision:
18:1970fec78229
Parent:
17:f29e1ca90e3d
Child:
19:33b9ba0859ee
--- a/mbed/ModLocalFileSystem.cpp	Fri Apr 26 05:26:34 2013 +0000
+++ b/mbed/ModLocalFileSystem.cpp	Fri Apr 26 14:55:24 2013 +0000
@@ -1,7 +1,8 @@
 #include "ModLocalFileSystem.h"
 #include "HttpdConnection.h"
+#include "UrlReader.h"
+#include "Http.h"
 #include "NyLPC_net.h"
-#include "UrlReader.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <typeinfo>
@@ -10,6 +11,159 @@
 #define ModLocalFile_SIZE_OF_BUF 256
 static char buf[ModLocalFile_SIZE_OF_BUF];
 
+using namespace MiMic;
+static void retDirJson(UrlReader& url,HttpdConnection& i_connection)
+{
+   //assert(HEAD or GET)
+   //directory-list json
+    if(!NyLPC_cHttpdUtils_sendJsonHeader((i_connection._ref_inst))){
+        return;
+    }
+    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);
+    if ( d == NULL )
+    {
+        i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":404,\"list\":[]}",buf);
+        return;
+    }
+    if(!i_connection.isMethodType(Http::MT_GET)){
+        //nothing to do
+    }else{
+        bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
+        struct dirent *p;
+        p = readdir(d);
+        i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":200,\"list\":[",buf);
+        for(;;)
+        {
+            if(is_fatfs){
+                bool isdir=(((struct direntFAT*)(p))->fattrib & AM_DIR)!=0;
+                i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":%u}",
+                p->d_name,isdir?"directory":NyLPC_cMiMeType_getFileName2MimeType(p->d_name),
+                isdir?0:((struct direntFAT*)(p))->fsize);
+            }else{
+                i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":undefined}",
+                p->d_name,NyLPC_cMiMeType_getFileName2MimeType(p->d_name));
+            }
+            p = readdir(d);
+            if(p==NULL){
+                break;
+            }
+            i_connection.sendBodyF(",");                        
+        }
+        i_connection.sendBodyF("]}");
+    }
+    closedir(d);
+}
+static void retDirHtml(UrlReader& url,HttpdConnection& i_connection)
+{
+    //assert(HEAD or GET)
+    buf[strlen(buf)-1]='\0';//convert to dir path
+    DIR* d=opendir(buf);
+    if(d==NULL){
+        i_connection.sendHeader(403,"text/html",NULL);
+        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)){
+        //nothing to do
+    }else{
+        if(!i_connection.isMethodType(Http::MT_GET)){
+            //nothing to do.
+        }else{
+            bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
+            struct dirent *p;
+            p = readdir(d);
+            i_connection.sendBodyF(
+                "<!DOCTYPE html><html><body><h1>Index of %s</h1><hr/>\n"
+                "<ul>\n"
+                ,buf);
+            for(;;)
+            {
+                if(is_fatfs){
+                    if((((struct direntFAT*)(p))->fattrib & AM_DIR)!=0){
+                        //dir
+                        i_connection.sendBodyF("<li><a href=\"./%s/\">[DIR]%s</a></li>\n",p->d_name,p->d_name);
+                    }else{
+                        //file
+                        i_connection.sendBodyF("<li><a href=\"./%s\">%s</a></li>\n",p->d_name,p->d_name);
+                    }
+                }else{
+                    i_connection.sendBodyF("<li><a href=\"./%s\">%s</a></li>\n",
+                    p->d_name,p->d_name);
+                }
+                p = readdir(d);
+                if(p==NULL){
+                    break;
+                }
+            }
+            i_connection.sendBodyF("</ul></body></html>",buf);
+        }
+    }
+    closedir(d);
+}
+static void retFile(UrlReader& url,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"); 
+    if(fp==NULL){
+        i_connection.sendHeader(404,"text/html",NULL);
+        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
+    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.isMethodType(Http::MT_GET)){
+            //nothing to do
+        }else{
+            for(;;){
+                sz=fread(buf,1,ModLocalFile_SIZE_OF_BUF,fp);
+                if(sz<1){
+                    break;
+                }
+                if(!i_connection.sendBody(buf,sz)){
+                    break;
+                }
+                //switch transport thread
+                /*
+                i_connection.releaseHttpd();
+                NyLPC_cThread_yield();
+                i_connection.lockHttpd();
+                */
+            }
+        }
+    }
+    fclose(fp);
+}    
+
 
 namespace MiMic
 {
@@ -26,8 +180,7 @@
     {
         ModBaseClass::setParam(i_path);
     }
-
-   
+  
     bool ModLocalFileSystem::execute(HttpdConnection& i_connection)
     {
         //check platform
@@ -37,9 +190,17 @@
         if(!this->canHandle(i_connection)){
             return false;
         }
+        //check Method type
+        {
+            int mt=i_connection.getMethodType();
+            if(mt!=Http::MT_GET && mt!=Http::MT_HEAD){
+                //method not allowed.
+                i_connection.sendHeader(405,"text/html",NULL);
+                return true;
+            }
+        }
         //Httpd lock
-        i_connection.lockHttpd();            
-
+        i_connection.lockHttpd();
         //set file path
         {
             //call ModUrl
@@ -52,87 +213,15 @@
             }
             NyLPC_cModUrl_finalize(&mod);
         }
-        // if path has '/?list' query key,return directory information
-        //otherwise FILE.
         UrlReader url(buf);
         if(url.hasQueryKey("list")){
-            //directory-list
-            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);
-            if(NyLPC_cHttpdUtils_sendJsonHeader((i_connection._ref_inst))){
-                if ( d != NULL )
-                {
-                    bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
-                    struct dirent *p;
-                    p = readdir(d);
-                    i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":200,\"list\":[",buf);
-                    for(;;)
-                    {
-                        if(is_fatfs){
-                            bool isdir=(((struct direntFAT*)(p))->fattrib & AM_DIR)!=0;
-                            i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":%u}",
-                            p->d_name,isdir?"directory":NyLPC_cMiMeType_getFileName2MimeType(p->d_name),
-                            isdir?0:((struct direntFAT*)(p))->fsize);
-                        }else{
-                            i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":undefined}",
-                            p->d_name,NyLPC_cMiMeType_getFileName2MimeType(p->d_name));
-                        }
-                        p = readdir(d);
-                        if(p==NULL){
-                            break;
-                        }
-                        i_connection.sendBodyF(",");                        
-                    }
-                    closedir(d);
-                    i_connection.sendBodyF("]}");
-                }else{
-                    i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":404,\"list\":[]}",buf);
-                }
-            }
+            // if path has '/?list' query key,return directory information
+            retDirJson(url,i_connection);
+        }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,i_connection);
         }else{
-            {//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"); 
-            if(fp!=NULL){
-                fseek(fp, 0, SEEK_END); // seek to end of file
-                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)){
-                    for(;;){
-                        sz=fread(buf,1,ModLocalFile_SIZE_OF_BUF,fp);
-                        if(sz<1){
-                            break;
-                        }
-                        if(!i_connection.sendBody(buf,sz)){
-                            break;
-                        }
-//                        //switch transport thread
-/*                        i_connection.releaseHttpd();
-                        NyLPC_cThread_yield();
-                        i_connection.lockHttpd();                        
-*/                    }
-                }
-                fclose(fp);
-            }else{
-                i_connection.sendHeader(404,"text/html",NULL);
-                i_connection.sendBodyF("<html><body>'%s' not found.</body></html>",buf);
-            }            
+            retFile(url,i_connection);
         }
         //Httpd unlock
         i_connection.releaseHttpd();