<%# /* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . * */ //cppsp module to enable directory listing #include #define TO_C_STR(in,inLen,out) char out[inLen+1];\ memcpy(out,in,inLen);\ out[inLen]=0; bool compareString(String s1, String s2) { return s1.alphabeticalCompare(s2)<0; } struct DirListModule: public RGC::Object { DelegateChain(String)>::item* it; Server* server; String filePath; struct redirectHandler: public RGC::Object { Delegate cb; void handleRequest(Request& req, Response& resp, Delegate cb) { this->cb=cb; resp.headersExtraSpace+=req.path.len+32; resp.addDefaultHeaders(req.server->host->curRFCTime,req.server->defaultMime); resp.appendHeaders("Location: "); resp.appendHeaders(req.path); resp.appendHeaders("/\r\n"); resp.statusName="Moved permanently"; resp.statusCode=301; resp.finalize({&redirectHandler::flushCB,this}); } void flushCB(Response& resp) { auto Cb=cb; destruct(); Cb(); } }; void handleRedirect(Request& req, Response& resp, Delegate cb) { req.sp->New()->handleRequest(req,resp,cb); } AsyncValue routeRequest(String path) { struct stat st; string s=server->mapPath(path.toSTDString()); if(::stat(s.c_str(),&st)>=0 && S_ISDIR(st.st_mode)) { if(path.length()>0 && path.data()[path.length()-1]!='/') { Handler h({&DirListModule::handleRedirect,this}); return h; } //redirect to self return server->routeDynamicRequestFromFile(filePath); } return (*it->prev)(path); } DirListModule(ModuleParams& p) { server=p.server; filePath=p.filePath; it=server->routeRequest.attach({&DirListModule::routeRequest,this}); } ~DirListModule() { server->routeRequest.detach(it); } }; extern "C" void* initModule(ModuleParams& p) { return new DirListModule(p); } extern "C" void deinitModule(void* mod) { delete (DirListModule*)mod; } %><% string path=server->mapPath(request->path.toSTDString()); %> Index of <% htmlEscape(request->path,output); %>

Index of <% htmlEscape(request->path,output); %>

<% vector list; auto tmp=[&](const char* name) { list.push_back(sp->addString(name)); }; listDirectory(path.c_str(), &tmp); std::sort(list.begin(),list.end(),compareString); for(int i=0;i <% } %>
Name Last modified Size

<% htmlEscape(name,output); %><%if(S_ISDIR(st.st_mode)){%>/<%}%> <%=buffer%> <%=(int64_t)st.st_size%>