Jun Furutani / libMiMic

Fork of libMiMic by Ryo Iizuka

Committer:
nyatla
Date:
Mon Apr 29 08:24:07 2013 +0000
Revision:
26:1a13899a5a1c
Parent:
21:f2a70f15301f
update ModLocalFileSystem task switch

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 19:33b9ba0859ee 5 #include "Httpd.h"
nyatla 17:f29e1ca90e3d 6 #include "NyLPC_net.h"
nyatla 17:f29e1ca90e3d 7 #include <stdio.h>
nyatla 17:f29e1ca90e3d 8 #include <stdlib.h>
nyatla 17:f29e1ca90e3d 9 #include <typeinfo>
nyatla 17:f29e1ca90e3d 10 #include "mbed.h"
nyatla 17:f29e1ca90e3d 11 #include "FATDirHandle.h"
nyatla 19:33b9ba0859ee 12
nyatla 17:f29e1ca90e3d 13
nyatla 18:1970fec78229 14 using namespace MiMic;
nyatla 19:33b9ba0859ee 15 static void retDirJson(UrlReader& url,char* buf,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 19:33b9ba0859ee 67 static void retDirHtml(UrlReader& url,char* buf,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 19:33b9ba0859ee 117 static void retFile(UrlReader& url,char* buf,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 26:1a13899a5a1c 147 Timer t;
nyatla 26:1a13899a5a1c 148 t.start();
nyatla 18:1970fec78229 149 for(;;){
nyatla 19:33b9ba0859ee 150 sz=fread(buf,1,Httpd::SIZE_OF_HTTP_BUF,fp);
nyatla 18:1970fec78229 151 if(sz<1){
nyatla 18:1970fec78229 152 break;
nyatla 18:1970fec78229 153 }
nyatla 18:1970fec78229 154 if(!i_connection.sendBody(buf,sz)){
nyatla 18:1970fec78229 155 break;
nyatla 18:1970fec78229 156 }
nyatla 26:1a13899a5a1c 157 if(t.read_ms()>500){
nyatla 26:1a13899a5a1c 158 //switch transport thread
nyatla 21:f2a70f15301f 159 i_connection.unlockHttpd();
nyatla 21:f2a70f15301f 160 NyLPC_cThread_sleep(50);
nyatla 21:f2a70f15301f 161 i_connection.lockHttpd();
nyatla 26:1a13899a5a1c 162 t.reset();
nyatla 21:f2a70f15301f 163 }
nyatla 18:1970fec78229 164 }
nyatla 18:1970fec78229 165 }
nyatla 18:1970fec78229 166 }
nyatla 18:1970fec78229 167 fclose(fp);
nyatla 18:1970fec78229 168 }
nyatla 18:1970fec78229 169
nyatla 17:f29e1ca90e3d 170
nyatla 17:f29e1ca90e3d 171 namespace MiMic
nyatla 17:f29e1ca90e3d 172 {
nyatla 17:f29e1ca90e3d 173 ModLocalFileSystem::ModLocalFileSystem(const char* i_path):ModBaseClass(i_path)
nyatla 17:f29e1ca90e3d 174 {
nyatla 17:f29e1ca90e3d 175 }
nyatla 17:f29e1ca90e3d 176 ModLocalFileSystem::ModLocalFileSystem():ModBaseClass()
nyatla 17:f29e1ca90e3d 177 {
nyatla 17:f29e1ca90e3d 178 }
nyatla 17:f29e1ca90e3d 179 ModLocalFileSystem::~ModLocalFileSystem()
nyatla 17:f29e1ca90e3d 180 {
nyatla 17:f29e1ca90e3d 181 }
nyatla 17:f29e1ca90e3d 182 void ModLocalFileSystem::setParam(const char* i_path)
nyatla 17:f29e1ca90e3d 183 {
nyatla 17:f29e1ca90e3d 184 ModBaseClass::setParam(i_path);
nyatla 17:f29e1ca90e3d 185 }
nyatla 18:1970fec78229 186
nyatla 17:f29e1ca90e3d 187 bool ModLocalFileSystem::execute(HttpdConnection& i_connection)
nyatla 17:f29e1ca90e3d 188 {
nyatla 17:f29e1ca90e3d 189 //check platform
nyatla 17:f29e1ca90e3d 190 //<write here! />
nyatla 17:f29e1ca90e3d 191
nyatla 17:f29e1ca90e3d 192 //check prefix
nyatla 17:f29e1ca90e3d 193 if(!this->canHandle(i_connection)){
nyatla 17:f29e1ca90e3d 194 return false;
nyatla 17:f29e1ca90e3d 195 }
nyatla 18:1970fec78229 196 //check Method type
nyatla 18:1970fec78229 197 {
nyatla 18:1970fec78229 198 int mt=i_connection.getMethodType();
nyatla 18:1970fec78229 199 if(mt!=Http::MT_GET && mt!=Http::MT_HEAD){
nyatla 18:1970fec78229 200 //method not allowed.
nyatla 18:1970fec78229 201 i_connection.sendHeader(405,"text/html",NULL);
nyatla 18:1970fec78229 202 return true;
nyatla 18:1970fec78229 203 }
nyatla 18:1970fec78229 204 }
nyatla 17:f29e1ca90e3d 205 //Httpd lock
nyatla 18:1970fec78229 206 i_connection.lockHttpd();
nyatla 19:33b9ba0859ee 207 char* buf=Httpd::_shared_buf;
nyatla 19:33b9ba0859ee 208
nyatla 17:f29e1ca90e3d 209 //set file path
nyatla 17:f29e1ca90e3d 210 {
nyatla 17:f29e1ca90e3d 211 //call ModUrl
nyatla 17:f29e1ca90e3d 212 NyLPC_TcModUrl_t mod;
nyatla 17:f29e1ca90e3d 213 NyLPC_cModUrl_initialize(&mod);
nyatla 19:33b9ba0859ee 214 if(!NyLPC_cModUrl_execute2(&mod,i_connection._ref_inst,buf,Httpd::SIZE_OF_HTTP_BUF,0,NyLPC_cModUrl_ParseMode_ALL)){
nyatla 17:f29e1ca90e3d 215 NyLPC_cModUrl_finalize(&mod);
nyatla 19:33b9ba0859ee 216 i_connection.unlockHttpd();
nyatla 17:f29e1ca90e3d 217 return true;
nyatla 17:f29e1ca90e3d 218 }
nyatla 17:f29e1ca90e3d 219 NyLPC_cModUrl_finalize(&mod);
nyatla 17:f29e1ca90e3d 220 }
nyatla 17:f29e1ca90e3d 221 UrlReader url(buf);
nyatla 17:f29e1ca90e3d 222 if(url.hasQueryKey("list")){
nyatla 18:1970fec78229 223 // if path has '/?list' query key,return directory information
nyatla 19:33b9ba0859ee 224 retDirJson(url,buf,i_connection);
nyatla 18:1970fec78229 225 }else if(strchr(buf,'?')==NULL && strchr(buf,'#')==NULL && buf[strlen(buf)-1]=='/'){
nyatla 18:1970fec78229 226 //return directory html when URL has not bookmark and URL query and terminated by '/'.
nyatla 19:33b9ba0859ee 227 retDirHtml(url,buf,i_connection);
nyatla 17:f29e1ca90e3d 228 }else{
nyatla 19:33b9ba0859ee 229 retFile(url,buf,i_connection);
nyatla 17:f29e1ca90e3d 230 }
nyatla 17:f29e1ca90e3d 231 //Httpd unlock
nyatla 19:33b9ba0859ee 232 i_connection.unlockHttpd();
nyatla 17:f29e1ca90e3d 233 return true;
nyatla 17:f29e1ca90e3d 234
nyatla 17:f29e1ca90e3d 235 }
nyatla 17:f29e1ca90e3d 236 }