1 #include <lib/network/http_file.h>
9 eHTTPFile::eHTTPFile(eHTTPConnection *c, int _fd, int method, const char *mime): eHTTPDataSource(c), method(method)
12 if (method == methodGET)
14 c->local_header["Content-Type"]=std::string(mime);
15 size=lseek(fd, 0, SEEK_END);
17 snprintf(asize, 10, "%d", size);
18 lseek(fd, 0, SEEK_SET);
19 c->local_header["Content-Length"]=std::string(asize);
21 connection->code_descr="OK";
25 int eHTTPFile::doWrite(int bytes)
27 if (method == methodGET)
35 len=read(fd, buff, len);
38 size-=connection->writeBlock(buff, len);
47 void eHTTPFile::haveData(void *data, int len)
49 if (method != methodPUT)
51 ::write(fd, data, len);
54 eHTTPFile::~eHTTPFile()
59 eHTTPFilePathResolver::eHTTPFilePathResolver()
61 #warning autodelete removed
65 static char _base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
67 static int unbase64(std::string &dst, const std::string string)
76 if (i == string.size())
78 char *ch=strchr(_base64, string[i++]);
106 int CheckUnixPassword(const char *user, const char *pass)
108 passwd *pwd=getpwnam(user);
111 char *cpwd=pwd->pw_passwd;
112 if (pwd && (!strcmp(pwd->pw_passwd, "x")))
114 spwd *sp=getspnam(user);
115 if (!sp) // no shadow password defined.
121 if ((*cpwd=='!')||(*cpwd=='*')) // disabled user
123 char *cres=crypt(pass, cpwd);
124 return !!strcmp(cres, cpwd);
127 static int checkAuth(const std::string cauth)
130 if (cauth.substr(0, 6) != "Basic ")
132 if (unbase64(auth, cauth.substr(6)))
134 std::string username=auth.substr(0, auth.find(":"));
135 std::string password=auth.substr(auth.find(":")+1);
136 if (CheckUnixPassword(username.c_str(), password.c_str()))
141 eHTTPDataSource *eHTTPFilePathResolver::getDataSource(std::string request, std::string path, eHTTPConnection *conn)
144 eDebug("request = %s, path = %s", request.c_str(), path.c_str());
145 if (request == "GET")
146 method=eHTTPFile::methodGET;
147 else if (request == "PUT")
148 method=eHTTPFile::methodPUT;
150 return new eHTTPError(conn, 405); // method not allowed
151 if (path.find("../")!=std::string::npos) // evil hax0r
152 return new eHTTPError(conn, 403);
153 if (path[0] != '/') // prepend '/'
155 if (path[path.length()-1]=='/')
158 eHTTPDataSource *data=0;
159 for (ePtrList<eHTTPFilePath>::iterator i(translate); i != translate.end(); ++i)
161 if (i->root==path.substr(0, i->root.length()))
163 std::string newpath=i->path+path.substr(i->root.length());
164 if (newpath.find('?'))
165 newpath=newpath.substr(0, newpath.find('?'));
166 eDebug("translated %s to %s", path.c_str(), newpath.c_str());
168 if (i->authorized & ((method==eHTTPFile::methodGET)?1:2))
170 std::map<std::string, std::string>::iterator i=conn->remote_header.find("Authorization");
171 if ((i == conn->remote_header.end()) || checkAuth(i->second))
173 conn->local_header["WWW-Authenticate"]="Basic realm=\"dreambox\"";
174 return new eHTTPError(conn, 401); // auth req'ed
178 int fd=open(newpath.c_str(), (method==eHTTPFile::methodGET)?O_RDONLY:(O_WRONLY|O_CREAT|O_TRUNC), 0644);
185 data=new eHTTPError(conn, 404);
188 data=new eHTTPError(conn, 403);
191 data=new eHTTPError(conn, 403); // k.a.
197 std::string ext=path.substr(path.rfind('.'));
198 const char *mime="text/unknown";
199 if ((ext==".html") || (ext==".htm"))
201 else if ((ext==".jpeg") || (ext==".jpg"))
203 else if (ext==".gif")
205 else if (ext==".css")
207 else if (ext==".png")
209 else if (ext==".xml")
211 else if (ext==".xsl")
214 data=new eHTTPFile(conn, fd, method, mime);
221 void eHTTPFilePathResolver::addTranslation(std::string path, std::string root, int authorized)
223 if (path[path.length()-1]!='/')
225 if (root[root.length()-1]!='/')
227 translate.push_back(new eHTTPFilePath(path, root, authorized));