Jun Furutani / libMiMic

Fork of libMiMic by Ryo Iizuka

Committer:
nyatla
Date:
Fri Apr 26 14:55:24 2013 +0000
Revision:
18:1970fec78229
Parent:
17:f29e1ca90e3d
Child:
19:33b9ba0859ee
update modLocalFileSystem; add simple directory index page

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 17:f29e1ca90e3d 1 #include "ModLocalFileSystem.h"
nyatla 17:f29e1ca90e3d 2 #include "HttpdConnection.h"
nyatla 18:1970fec78229 3 #include "UrlReader.h"
nyatla 18:1970fec78229 4 #include "Http.h"
nyatla 17:f29e1ca90e3d 5 #include "NyLPC_net.h"
nyatla 17:f29e1ca90e3d 6 #include <stdio.h>
nyatla 17:f29e1ca90e3d 7 #include <stdlib.h>
nyatla 17:f29e1ca90e3d 8 #include <typeinfo>
nyatla 17:f29e1ca90e3d 9 #include "mbed.h"
nyatla 17:f29e1ca90e3d 10 #include "FATDirHandle.h"
nyatla 17:f29e1ca90e3d 11 #define ModLocalFile_SIZE_OF_BUF 256
nyatla 17:f29e1ca90e3d 12 static char buf[ModLocalFile_SIZE_OF_BUF];
nyatla 17:f29e1ca90e3d 13
nyatla 18:1970fec78229 14 using namespace MiMic;
nyatla 18:1970fec78229 15 static void retDirJson(UrlReader& url,HttpdConnection& i_connection)
nyatla 18:1970fec78229 16 {
nyatla 18:1970fec78229 17 //assert(HEAD or GET)
nyatla 18:1970fec78229 18 //directory-list json
nyatla 18:1970fec78229 19 if(!NyLPC_cHttpdUtils_sendJsonHeader((i_connection._ref_inst))){
nyatla 18:1970fec78229 20 return;
nyatla 18:1970fec78229 21 }
nyatla 18:1970fec78229 22 if(!i_connection.isMethodType(Http::MT_GET)){
nyatla 18:1970fec78229 23 return;
nyatla 18:1970fec78229 24 }
nyatla 18:1970fec78229 25 const char* t;
nyatla 18:1970fec78229 26 int l;
nyatla 18:1970fec78229 27 url.getPath(t,l);
nyatla 18:1970fec78229 28 buf[l]='\0';//split path
nyatla 18:1970fec78229 29 //remove '/'
nyatla 18:1970fec78229 30 if(buf[l-1]=='/'){
nyatla 18:1970fec78229 31 buf[l-1]='\0';
nyatla 18:1970fec78229 32 }
nyatla 18:1970fec78229 33 DIR* d=opendir(buf);
nyatla 18:1970fec78229 34 if ( d == NULL )
nyatla 18:1970fec78229 35 {
nyatla 18:1970fec78229 36 i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":404,\"list\":[]}",buf);
nyatla 18:1970fec78229 37 return;
nyatla 18:1970fec78229 38 }
nyatla 18:1970fec78229 39 if(!i_connection.isMethodType(Http::MT_GET)){
nyatla 18:1970fec78229 40 //nothing to do
nyatla 18:1970fec78229 41 }else{
nyatla 18:1970fec78229 42 bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
nyatla 18:1970fec78229 43 struct dirent *p;
nyatla 18:1970fec78229 44 p = readdir(d);
nyatla 18:1970fec78229 45 i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":200,\"list\":[",buf);
nyatla 18:1970fec78229 46 for(;;)
nyatla 18:1970fec78229 47 {
nyatla 18:1970fec78229 48 if(is_fatfs){
nyatla 18:1970fec78229 49 bool isdir=(((struct direntFAT*)(p))->fattrib & AM_DIR)!=0;
nyatla 18:1970fec78229 50 i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":%u}",
nyatla 18:1970fec78229 51 p->d_name,isdir?"directory":NyLPC_cMiMeType_getFileName2MimeType(p->d_name),
nyatla 18:1970fec78229 52 isdir?0:((struct direntFAT*)(p))->fsize);
nyatla 18:1970fec78229 53 }else{
nyatla 18:1970fec78229 54 i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":undefined}",
nyatla 18:1970fec78229 55 p->d_name,NyLPC_cMiMeType_getFileName2MimeType(p->d_name));
nyatla 18:1970fec78229 56 }
nyatla 18:1970fec78229 57 p = readdir(d);
nyatla 18:1970fec78229 58 if(p==NULL){
nyatla 18:1970fec78229 59 break;
nyatla 18:1970fec78229 60 }
nyatla 18:1970fec78229 61 i_connection.sendBodyF(",");
nyatla 18:1970fec78229 62 }
nyatla 18:1970fec78229 63 i_connection.sendBodyF("]}");
nyatla 18:1970fec78229 64 }
nyatla 18:1970fec78229 65 closedir(d);
nyatla 18:1970fec78229 66 }
nyatla 18:1970fec78229 67 static void retDirHtml(UrlReader& url,HttpdConnection& i_connection)
nyatla 18:1970fec78229 68 {
nyatla 18:1970fec78229 69 //assert(HEAD or GET)
nyatla 18:1970fec78229 70 buf[strlen(buf)-1]='\0';//convert to dir path
nyatla 18:1970fec78229 71 DIR* d=opendir(buf);
nyatla 18:1970fec78229 72 if(d==NULL){
nyatla 18:1970fec78229 73 i_connection.sendHeader(403,"text/html",NULL);
nyatla 18:1970fec78229 74 if(!i_connection.isMethodType(Http::MT_GET)){
nyatla 18:1970fec78229 75 return;
nyatla 18:1970fec78229 76 }
nyatla 18:1970fec78229 77 i_connection.sendBodyF("<!DOCTYPE html><html><body><h1>403 Forbidden</h1><hr/>'%s'</body></html>",buf);
nyatla 18:1970fec78229 78 return;
nyatla 18:1970fec78229 79 }
nyatla 18:1970fec78229 80 if(!i_connection.sendHeader(200,"text/html",NULL)){
nyatla 18:1970fec78229 81 //nothing to do
nyatla 18:1970fec78229 82 }else{
nyatla 18:1970fec78229 83 if(!i_connection.isMethodType(Http::MT_GET)){
nyatla 18:1970fec78229 84 //nothing to do.
nyatla 18:1970fec78229 85 }else{
nyatla 18:1970fec78229 86 bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
nyatla 18:1970fec78229 87 struct dirent *p;
nyatla 18:1970fec78229 88 p = readdir(d);
nyatla 18:1970fec78229 89 i_connection.sendBodyF(
nyatla 18:1970fec78229 90 "<!DOCTYPE html><html><body><h1>Index of %s</h1><hr/>\n"
nyatla 18:1970fec78229 91 "<ul>\n"
nyatla 18:1970fec78229 92 ,buf);
nyatla 18:1970fec78229 93 for(;;)
nyatla 18:1970fec78229 94 {
nyatla 18:1970fec78229 95 if(is_fatfs){
nyatla 18:1970fec78229 96 if((((struct direntFAT*)(p))->fattrib & AM_DIR)!=0){
nyatla 18:1970fec78229 97 //dir
nyatla 18:1970fec78229 98 i_connection.sendBodyF("<li><a href=\"./%s/\">[DIR]%s</a></li>\n",p->d_name,p->d_name);
nyatla 18:1970fec78229 99 }else{
nyatla 18:1970fec78229 100 //file
nyatla 18:1970fec78229 101 i_connection.sendBodyF("<li><a href=\"./%s\">%s</a></li>\n",p->d_name,p->d_name);
nyatla 18:1970fec78229 102 }
nyatla 18:1970fec78229 103 }else{
nyatla 18:1970fec78229 104 i_connection.sendBodyF("<li><a href=\"./%s\">%s</a></li>\n",
nyatla 18:1970fec78229 105 p->d_name,p->d_name);
nyatla 18:1970fec78229 106 }
nyatla 18:1970fec78229 107 p = readdir(d);
nyatla 18:1970fec78229 108 if(p==NULL){
nyatla 18:1970fec78229 109 break;
nyatla 18:1970fec78229 110 }
nyatla 18:1970fec78229 111 }
nyatla 18:1970fec78229 112 i_connection.sendBodyF("</ul></body></html>",buf);
nyatla 18:1970fec78229 113 }
nyatla 18:1970fec78229 114 }
nyatla 18:1970fec78229 115 closedir(d);
nyatla 18:1970fec78229 116 }
nyatla 18:1970fec78229 117 static void retFile(UrlReader& url,HttpdConnection& i_connection)
nyatla 18:1970fec78229 118 {
nyatla 18:1970fec78229 119 //file contents
nyatla 18:1970fec78229 120 {//split URL path and query
nyatla 18:1970fec78229 121 const char* t;
nyatla 18:1970fec78229 122 int l;
nyatla 18:1970fec78229 123 url.getPath(t,l);
nyatla 18:1970fec78229 124 buf[l]='\0';
nyatla 18:1970fec78229 125 }
nyatla 18:1970fec78229 126 //return content
nyatla 18:1970fec78229 127 FILE *fp;
nyatla 18:1970fec78229 128 size_t sz;
nyatla 18:1970fec78229 129 //size
nyatla 18:1970fec78229 130 fp = fopen(buf, "r");
nyatla 18:1970fec78229 131 if(fp==NULL){
nyatla 18:1970fec78229 132 i_connection.sendHeader(404,"text/html",NULL);
nyatla 18:1970fec78229 133 if(!i_connection.isMethodType(Http::MT_GET)){
nyatla 18:1970fec78229 134 return;
nyatla 18:1970fec78229 135 }
nyatla 18:1970fec78229 136 i_connection.sendBodyF("<!DOCTYPE html><html><body>'%s' not found.</body></html>",buf);
nyatla 18:1970fec78229 137 return;
nyatla 18:1970fec78229 138 }
nyatla 18:1970fec78229 139
nyatla 18:1970fec78229 140 fseek(fp, 0, SEEK_END); // seek to end of file
nyatla 18:1970fec78229 141 sz = ftell(fp); // get current file pointer
nyatla 18:1970fec78229 142 fseek(fp, 0, SEEK_SET); // seek back to beginning of file
nyatla 18:1970fec78229 143 if(i_connection.sendHeader(200,NyLPC_cMiMeType_getFileName2MimeType(buf),NULL,sz)){
nyatla 18:1970fec78229 144 if(!i_connection.isMethodType(Http::MT_GET)){
nyatla 18:1970fec78229 145 //nothing to do
nyatla 18:1970fec78229 146 }else{
nyatla 18:1970fec78229 147 for(;;){
nyatla 18:1970fec78229 148 sz=fread(buf,1,ModLocalFile_SIZE_OF_BUF,fp);
nyatla 18:1970fec78229 149 if(sz<1){
nyatla 18:1970fec78229 150 break;
nyatla 18:1970fec78229 151 }
nyatla 18:1970fec78229 152 if(!i_connection.sendBody(buf,sz)){
nyatla 18:1970fec78229 153 break;
nyatla 18:1970fec78229 154 }
nyatla 18:1970fec78229 155 //switch transport thread
nyatla 18:1970fec78229 156 /*
nyatla 18:1970fec78229 157 i_connection.releaseHttpd();
nyatla 18:1970fec78229 158 NyLPC_cThread_yield();
nyatla 18:1970fec78229 159 i_connection.lockHttpd();
nyatla 18:1970fec78229 160 */
nyatla 18:1970fec78229 161 }
nyatla 18:1970fec78229 162 }
nyatla 18:1970fec78229 163 }
nyatla 18:1970fec78229 164 fclose(fp);
nyatla 18:1970fec78229 165 }
nyatla 18:1970fec78229 166
nyatla 17:f29e1ca90e3d 167
nyatla 17:f29e1ca90e3d 168 namespace MiMic
nyatla 17:f29e1ca90e3d 169 {
nyatla 17:f29e1ca90e3d 170 ModLocalFileSystem::ModLocalFileSystem(const char* i_path):ModBaseClass(i_path)
nyatla 17:f29e1ca90e3d 171 {
nyatla 17:f29e1ca90e3d 172 }
nyatla 17:f29e1ca90e3d 173 ModLocalFileSystem::ModLocalFileSystem():ModBaseClass()
nyatla 17:f29e1ca90e3d 174 {
nyatla 17:f29e1ca90e3d 175 }
nyatla 17:f29e1ca90e3d 176 ModLocalFileSystem::~ModLocalFileSystem()
nyatla 17:f29e1ca90e3d 177 {
nyatla 17:f29e1ca90e3d 178 }
nyatla 17:f29e1ca90e3d 179 void ModLocalFileSystem::setParam(const char* i_path)
nyatla 17:f29e1ca90e3d 180 {
nyatla 17:f29e1ca90e3d 181 ModBaseClass::setParam(i_path);
nyatla 17:f29e1ca90e3d 182 }
nyatla 18:1970fec78229 183
nyatla 17:f29e1ca90e3d 184 bool ModLocalFileSystem::execute(HttpdConnection& i_connection)
nyatla 17:f29e1ca90e3d 185 {
nyatla 17:f29e1ca90e3d 186 //check platform
nyatla 17:f29e1ca90e3d 187 //<write here! />
nyatla 17:f29e1ca90e3d 188
nyatla 17:f29e1ca90e3d 189 //check prefix
nyatla 17:f29e1ca90e3d 190 if(!this->canHandle(i_connection)){
nyatla 17:f29e1ca90e3d 191 return false;
nyatla 17:f29e1ca90e3d 192 }
nyatla 18:1970fec78229 193 //check Method type
nyatla 18:1970fec78229 194 {
nyatla 18:1970fec78229 195 int mt=i_connection.getMethodType();
nyatla 18:1970fec78229 196 if(mt!=Http::MT_GET && mt!=Http::MT_HEAD){
nyatla 18:1970fec78229 197 //method not allowed.
nyatla 18:1970fec78229 198 i_connection.sendHeader(405,"text/html",NULL);
nyatla 18:1970fec78229 199 return true;
nyatla 18:1970fec78229 200 }
nyatla 18:1970fec78229 201 }
nyatla 17:f29e1ca90e3d 202 //Httpd lock
nyatla 18:1970fec78229 203 i_connection.lockHttpd();
nyatla 17:f29e1ca90e3d 204 //set file path
nyatla 17:f29e1ca90e3d 205 {
nyatla 17:f29e1ca90e3d 206 //call ModUrl
nyatla 17:f29e1ca90e3d 207 NyLPC_TcModUrl_t mod;
nyatla 17:f29e1ca90e3d 208 NyLPC_cModUrl_initialize(&mod);
nyatla 17:f29e1ca90e3d 209 if(!NyLPC_cModUrl_execute2(&mod,i_connection._ref_inst,buf,ModLocalFile_SIZE_OF_BUF,0)){
nyatla 17:f29e1ca90e3d 210 NyLPC_cModUrl_finalize(&mod);
nyatla 17:f29e1ca90e3d 211 i_connection.releaseHttpd();
nyatla 17:f29e1ca90e3d 212 return true;
nyatla 17:f29e1ca90e3d 213 }
nyatla 17:f29e1ca90e3d 214 NyLPC_cModUrl_finalize(&mod);
nyatla 17:f29e1ca90e3d 215 }
nyatla 17:f29e1ca90e3d 216 UrlReader url(buf);
nyatla 17:f29e1ca90e3d 217 if(url.hasQueryKey("list")){
nyatla 18:1970fec78229 218 // if path has '/?list' query key,return directory information
nyatla 18:1970fec78229 219 retDirJson(url,i_connection);
nyatla 18:1970fec78229 220 }else if(strchr(buf,'?')==NULL && strchr(buf,'#')==NULL && buf[strlen(buf)-1]=='/'){
nyatla 18:1970fec78229 221 //return directory html when URL has not bookmark and URL query and terminated by '/'.
nyatla 18:1970fec78229 222 retDirHtml(url,i_connection);
nyatla 17:f29e1ca90e3d 223 }else{
nyatla 18:1970fec78229 224 retFile(url,i_connection);
nyatla 17:f29e1ca90e3d 225 }
nyatla 17:f29e1ca90e3d 226 //Httpd unlock
nyatla 17:f29e1ca90e3d 227 i_connection.releaseHttpd();
nyatla 17:f29e1ca90e3d 228 return true;
nyatla 17:f29e1ca90e3d 229
nyatla 17:f29e1ca90e3d 230 }
nyatla 17:f29e1ca90e3d 231 }