1 #include <lib/network/http_file.h>
11 eHTTPFile::eHTTPFile(eHTTPConnection *c, int _fd, int method, const char *mime): eHTTPDataSource(c), method(method)
14 if (method == methodGET)
16 c->local_header["Content-Type"]=std::string(mime);
17 size=lseek(fd, 0, SEEK_END);
19 snprintf(asize, 10, "%d", size);
20 lseek(fd, 0, SEEK_SET);
21 c->local_header["Content-Length"]=std::string(asize);
23 connection->code_descr="OK";
27 int eHTTPFile::doWrite(int bytes)
29 if (method == methodGET)
37 len=read(fd, buff, len);
40 size-=connection->writeBlock(buff, len);
49 void eHTTPFile::haveData(void *data, int len)
51 if (method != methodPUT)
53 ::write(fd, data, len);
56 eHTTPFile::~eHTTPFile()
61 eHTTPFilePathResolver::eHTTPFilePathResolver()
66 static char _base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
68 static int unbase64(std::string &dst, const std::string string)
77 if (i == string.size())
79 char *ch=strchr(_base64, string[i++]);
107 int CheckUnixPassword(const char *user, const char *pass)
109 passwd *pwd=getpwnam(user);
112 char *cpwd=pwd->pw_passwd;
113 if (pwd && (!strcmp(pwd->pw_passwd, "x")))
115 spwd *sp=getspnam(user);
116 if (!sp) // no shadow password defined.
122 if ((*cpwd=='!')||(*cpwd=='*')) // disabled user
124 char *cres=crypt(pass, cpwd);
125 return !!strcmp(cres, cpwd);
128 static int checkAuth(const std::string cauth)
131 if (cauth.substr(0, 6) != "Basic ")
133 if (unbase64(auth, cauth.substr(6)))
135 std::string username=auth.substr(0, auth.find(":"));
136 std::string password=auth.substr(auth.find(":")+1);
137 if (CheckUnixPassword(username.c_str(), password.c_str()))
142 DEFINE_REF(eHTTPFilePathResolver);
144 RESULT eHTTPFilePathResolver::getDataSource(eHTTPDataSourcePtr &ptr, std::string request, std::string path, eHTTPConnection *conn)
147 eDebug("request = %s, path = %s", request.c_str(), path.c_str());
148 if (request == "GET")
149 method=eHTTPFile::methodGET;
150 else if (request == "PUT")
151 method=eHTTPFile::methodPUT;
154 ptr = new eHTTPError(conn, 405); // method not allowed
157 if (path.find("../")!=std::string::npos) // evil hax0r
159 ptr = new eHTTPError(conn, 403);
162 if (path[0] != '/') // prepend '/'
164 if (path[path.length()-1]=='/')
167 eHTTPDataSource *data=0;
168 for (ePtrList<eHTTPFilePath>::iterator i(translate); i != translate.end(); ++i)
170 if (i->root==path.substr(0, i->root.length()))
172 std::string newpath=i->path+path.substr(i->root.length());
173 if (newpath.find('?'))
174 newpath=newpath.substr(0, newpath.find('?'));
175 eDebug("translated %s to %s", path.c_str(), newpath.c_str());
177 if (i->authorized & ((method==eHTTPFile::methodGET)?1:2))
179 std::map<std::string, std::string>::iterator i=conn->remote_header.find("Authorization");
180 if ((i == conn->remote_header.end()) || checkAuth(i->second))
182 conn->local_header["WWW-Authenticate"]="Basic realm=\"dreambox\"";
183 ptr = new eHTTPError(conn, 401); // auth req'ed
188 int fd=open(newpath.c_str(), (method==eHTTPFile::methodGET)?O_RDONLY:(O_WRONLY|O_CREAT|O_TRUNC), 0644);
195 data=new eHTTPError(conn, 404);
198 data=new eHTTPError(conn, 403);
201 data=new eHTTPError(conn, 403); // k.a.
207 std::string ext=path.substr(path.rfind('.'));
208 const char *mime="text/unknown";
209 if ((ext==".html") || (ext==".htm"))
211 else if ((ext==".jpeg") || (ext==".jpg"))
213 else if (ext==".gif")
215 else if (ext==".css")
217 else if (ext==".png")
219 else if (ext==".xml")
221 else if (ext==".xsl")
224 data=new eHTTPFile(conn, fd, method, mime);
234 void eHTTPFilePathResolver::addTranslation(std::string path, std::string root, int authorized)
236 if (path[path.length()-1]!='/')
238 if (root[root.length()-1]!='/')
240 translate.push_back(new eHTTPFilePath(path, root, authorized));