bool BZFSHTTP::handleRequest(const HTTPRequest &request, HTTPReply &reply) { if (serviceMimeResources && resourceRootPath.size() && mimeTypes.size()) { // parse out the resource and see if we know what it is std::string ext; tolower(getFileExtension(request.resource),ext); if (ext.size()) { if ( mimeTypes.find(ext) != mimeTypes.end() ) { // it's one we do, try and find it std::string filepath = concatPaths(resourceRootPath.c_str(),request.resource.c_str()); FILE *fp = fopen(filepath.c_str(),"rb"); if (fp) { char buffer[1024]; bool done = false; while (!done) { size_t read = fread(buffer,1,1024,fp); if (read) reply.addBody(buffer,read); if (read != 1024) done = true; } fclose(fp); reply.docType = HTTPReply::eOther; reply.otherMimeType = mimeTypes[ext]; reply.returnCode = HTTPReply::e200OK; return true; } } } } return generatePage(request,reply); }
bool StaticFileServer::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) { int fd = open((template_base + "/" + this->file_name).c_str(), O_RDONLY); if (fd < 0) { Log(LOG_NORMAL, "httpd") << "Error serving file " << page_name << " (" << (template_base + "/" + this->file_name) << "): " << strerror(errno); client->SendError(HTTP_PAGE_NOT_FOUND, "Page not found"); return true; } reply.content_type = this->GetContentType(); reply.headers["Cache-Control"] = "public"; int i; char buffer[BUFSIZE]; while ((i = read(fd, buffer, sizeof(buffer))) > 0) reply.Write(buffer, i); close(fd); return true; }
bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) override { Anope::string content = message.content, tname, data; XMLRPCRequest request(reply); while (GetData(content, tname, data)) { Log(LOG_DEBUG) << "m_xmlrpc: Tag name: " << tname << ", data: " << data; if (tname == "methodName") request.name = data; else if (tname == "name" && data == "id") { GetData(content, tname, data); request.id = data; } else if (tname == "string") request.data.push_back(data); } for (unsigned i = 0; i < this->events.size(); ++i) { XMLRPCEvent *e = this->events[i]; if (!e->Run(this, client, request)) return false; else if (!request.get_replies().empty()) { this->Reply(request); return true; } } reply.error = HTTP_PAGE_NOT_FOUND; reply.Write("Unrecognized query"); return true; }
void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Replacements &r) { int fd = open((template_base + "/" + this->file_name).c_str(), O_RDONLY); if (fd < 0) { Log(LOG_NORMAL, "httpd") << "Error serving file " << page_name << " (" << (template_base + "/" + this->file_name) << "): " << strerror(errno); client->SendError(HTTP_PAGE_NOT_FOUND, "Page not found"); return; } Anope::string buf; int i; char buffer[BUFSIZE]; while ((i = read(fd, buffer, sizeof(buffer) - 1)) > 0) { buffer[i] = 0; buf += buffer; } close(fd); Anope::string finished; bool escaped = false; for (unsigned j = 0; j < buf.length(); ++j) { if (buf[j] == '\\' && j + 1 < buf.length() && (buf[j + 1] == '{' || buf[j + 1] == '}')) escaped = true; else if (buf[j] == '{' && !escaped) { size_t f = buf.substr(j).find('}'); if (f == Anope::string::npos) break; const Anope::string &content = buf.substr(j + 1, f - 1); if (content.find("IF ") == 0) { std::vector<Anope::string> tokens; spacesepstream(content).GetTokens(tokens); if (tokens.size() == 4 && tokens[1] == "EQ") { Anope::string first = FindReplacement(r, tokens[2]), second = FindReplacement(r, tokens[3]); if (first.empty()) first = tokens[2]; if (second.empty()) second = tokens[3]; bool stackok = IfStack.empty() || IfStack.top(); IfStack.push(stackok && first == second); } else if (tokens.size() == 3 && tokens[1] == "EXISTS") { bool stackok = IfStack.empty() || IfStack.top(); IfStack.push(stackok && r.count(tokens[2]) > 0); } else Log() << "Invalid IF in web template " << this->file_name; } else if (content == "ELSE") { if (IfStack.empty()) Log() << "Invalid ELSE with no stack in web template" << this->file_name; else { bool old = IfStack.top(); IfStack.pop(); // Pop off previous if() bool stackok = IfStack.empty() || IfStack.top(); IfStack.push(stackok && !old); // Push back the opposite of what was popped } } else if (content == "END IF") { if (IfStack.empty()) Log() << "END IF with empty stack?"; else IfStack.pop(); } else if (content.find("FOR ") == 0) { std::vector<Anope::string> tokens; spacesepstream(content).GetTokens(tokens); if (tokens.size() != 4 || tokens[2] != "IN") Log() << "Invalid FOR in web template " << this->file_name; else { std::vector<Anope::string> temp_variables, real_variables; commasepstream(tokens[1]).GetTokens(temp_variables); commasepstream(tokens[3]).GetTokens(real_variables); if (temp_variables.size() != real_variables.size()) Log() << "Invalid FOR in web template " << this->file_name << " variable mismatch"; else ForLoop::Stack.push_back(ForLoop(j + f, r, temp_variables, real_variables)); } } else if (content == "END FOR") { if (ForLoop::Stack.empty()) Log() << "END FOR with empty stack?"; else { ForLoop &fl = ForLoop::Stack.back(); if (fl.finished(r)) ForLoop::Stack.pop_back(); else { fl.increment(r); if (fl.finished(r)) ForLoop::Stack.pop_back(); else { j = fl.start; // Move pointer back to start of the loop continue; // To prevent skipping over this block which doesn't exist anymore } } } } else if (content.find("INCLUDE ") == 0) { std::vector<Anope::string> tokens; spacesepstream(content).GetTokens(tokens); if (tokens.size() != 2) Log() << "Invalid INCLUDE in web template " << this->file_name; else { if (!finished.empty()) { reply.Write(finished); // Write out what we have currently so we insert this files contents here finished.clear(); } TemplateFileServer tfs(tokens[1]); tfs.Serve(server, page_name, client, message, reply, r); } } else { // If the if stack is empty or we are in a true statement bool ifok = IfStack.empty() || IfStack.top(); bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r); if (ifok && forok) { const Anope::string &replacement = FindReplacement(r, content.substr(0, f - 1)); finished += replacement; } } j += f; // Skip over this whole block } else { escaped = false; // If the if stack is empty or we are in a true statement bool ifok = IfStack.empty() || IfStack.top(); bool forok = ForLoop::Stack.empty() || !ForLoop::Stack.back().finished(r); if (ifok && forok) finished += buf[j]; } } if (!finished.empty()) reply.Write(finished); }