package org.freertr.serv;
import java.util.ArrayList;
import java.util.List;
import org.freertr.cfg.cfgAll;
import org.freertr.cfg.cfgProxy;
import org.freertr.clnt.clntProxy;
import org.freertr.pipe.pipeLine;
import org.freertr.pipe.pipeSide;
import org.freertr.prt.prtGenConn;
import org.freertr.prt.prtServS;
import org.freertr.enc.encUrl;
import org.freertr.sec.secInfoUtl;
import org.freertr.tab.tabGen;
import org.freertr.user.userFilter;
import org.freertr.user.userFormat;
import org.freertr.user.userHelping;
import org.freertr.util.bits;
import org.freertr.util.cmds;
/**
* hypertext transfer protocol (rfc2616) server
*
* @author matecsaba
*/
public class servHttp extends servGeneric implements prtServS {
/**
* create instance
*/
public servHttp() {
}
/**
* port number
*/
public final static int clearPort = 80;
/**
* secure port
*/
public final static int securePort = 443;
/**
* html 401 transitive
*/
public final static String htmlHead = "
";
/**
* list of hosts
*/
protected tabGen hosts = new tabGen();
/**
* list of bots
*/
protected List bots = new ArrayList();
/**
* proxy to use
*/
protected clntProxy proxy;
/**
* second port to use
*/
protected int secondPort = -1;
/**
* error message
*/
protected String error;
/**
* single request
*/
protected boolean singleRequest;
/**
* default server path
*/
protected String defPath = defHostPat;
/**
* default subconnect
*/
protected int defSubcon;
/**
* buffer size
*/
protected int bufSiz = 65536;
/**
* default host path
*/
public final static String defHostPat = "/data/notfound/";
/**
* defaults text
*/
public final static String[] defaultL = {
"server http .*!" + cmds.tabulator + "port " + clearPort,
"server http .*!" + cmds.tabulator + "protocol " + proto2string(protoAllStrm),
"server http .*!" + cmds.tabulator + cmds.negated + cmds.tabulator + "proxy",
"server http .*!" + cmds.tabulator + cmds.negated + cmds.tabulator + "error",
"server http .*!" + cmds.tabulator + cmds.negated + cmds.tabulator + "single-request",
"server http .*!" + cmds.tabulator + "def-path " + defHostPat,
"server http .*!" + cmds.tabulator + "def-subconn",
"server http .*!" + cmds.tabulator + "buffer 65536",
"server http .*!" + cmds.tabulator + cmds.negated + cmds.tabulator + "second-port",};
/**
* defaults filter
*/
public static tabGen defaultF;
/**
* get defaults filter
*
* @return filter
*/
public tabGen srvDefFlt() {
return defaultF;
}
/**
* find one host
*
* @param s agent name
* @return true if found
*/
protected boolean findBot(String s) {
for (int i = 0; i < bots.size(); i++) {
String a = bots.get(i);
if (s.matches(a)) {
return true;
}
}
return false;
}
/**
* find one host
*
* @param s host name
* @return host descriptor, null if not found
*/
protected servHttpHost findHost(String s) {
servHttpHost ntry = new servHttpHost(this, s);
ntry = hosts.find(ntry);
if (ntry != null) {
return ntry;
}
for (int i = hosts.size() - 1; i >= 0; i--) {
ntry = hosts.get(i);
if (!ntry.host.startsWith("*")) {
continue;
}
if (!s.endsWith(ntry.host.substring(1, ntry.host.length()))) {
continue;
}
return ntry;
}
return null;
}
/**
* start connection
*
* @param pipe pipeline
* @param id connection
* @return false on success, true on error
*/
public boolean srvAccept(pipeSide pipe, prtGenConn id) {
pipe.setTime(120000);
new servHttpConn(this, pipe, id);
return false;
}
/**
* get config
*
* @param beg beginning
* @param l list
* @param filter default filter
*/
public void srvShRun(String beg, List l, int filter) {
if (proxy == null) {
l.add(beg + "no proxy");
} else {
l.add(beg + "proxy " + proxy.name);
}
if (error == null) {
l.add(beg + "no error");
} else {
l.add(beg + "error " + error);
}
cmds.cfgLine(l, secondPort < 0, beg, "second-port", "" + secondPort);
l.add(beg + "buffer " + bufSiz);
l.add(beg + "def-path " + defPath);
l.add(beg + "def-subconn" + servHttpUtil.subconn2string(defSubcon));
cmds.cfgLine(l, !singleRequest, beg, "single-request", "");
for (int i = 0; i < bots.size(); i++) {
l.add(beg + "bad-agent " + bots.get(i));
}
for (int hn = 0; hn < hosts.size(); hn++) {
servHttpHost ntry = hosts.get(hn);
if (ntry == null) {
continue;
}
ntry.getConfig(beg, l, filter);
}
}
/**
* configure
*
* @param cmd command
* @return false on success, true on error
*/
public boolean srvCfgStr(cmds cmd) {
String a = cmd.word();
boolean negated = false;
if (a.equals(cmds.negated)) {
negated = true;
a = cmd.word();
}
if (a.equals("bad-agent")) {
a = cmd.getRemaining();
if (negated) {
bots.remove(a);
return false;
}
if (bots.indexOf(a) >= 0) {
return false;
}
bots.add(a);
return false;
}
if (a.equals("second-port")) {
if (negated) {
secondPort = -1;
return false;
}
secondPort = bits.str2num(cmd.word());
return false;
}
if (a.equals("buffer")) {
bufSiz = bits.str2num(cmd.word());
return false;
}
if (a.equals("single-request")) {
singleRequest = !negated;
return false;
}
if (a.equals("def-path")) {
if (negated) {
defPath = defHostPat;
} else {
defPath = cmd.word();
}
return false;
}
if (a.equals("def-subconn")) {
defSubcon = servHttpUtil.string2subconn(negated, cmd);
return false;
}
if (a.equals("proxy")) {
if (negated) {
proxy = null;
return false;
}
cfgProxy prx = cfgAll.proxyFind(cmd.word(), false);
if (prx == null) {
cmd.error("no such proxy");
return false;
}
proxy = prx.proxy;
return false;
}
if (a.equals("error")) {
error = cmd.getRemaining();
if (negated) {
error = null;
return false;
}
return false;
}
if (!a.equals("host")) {
return true;
}
servHttpHost ntry = new servHttpHost(this, cmd.word());
servHttpHost old = hosts.add(ntry);
if (old != null) {
ntry = old;
}
a = cmd.word();
if (a.length() < 1) {
return false;
}
if (a.equals("path")) {
if (negated) {
hosts.del(ntry);
return false;
}
ntry.path = "/" + encUrl.normalizePath(cmd.word() + "/");
return false;
}
if (ntry.path == null) {
ntry.path = defPath;
ntry.subconn = defSubcon;
}
return ntry.doConfig(negated, a, cmd);
}
private final static void getSubconnHelp(String b, userHelping l) {
l.add(null, b + " strip-path strip path");
l.add(null, b + " strip-name strip filename");
l.add(null, b + " strip-ext strip extension");
l.add(null, b + " strip-param strip parameters");
l.add(null, b + " keep-cred keep credentinals");
l.add(null, b + " keep-host keep hostname");
l.add(null, b + " keep-path append path");
}
/**
* get help
*
* @param l list
*/
public void srvHelp(userHelping l) {
l.add(null, "1 . single-request one request per connection");
l.add(null, "1 2 buffer set buffer size on connection");
l.add(null, "2 . buffer in bytes");
l.add(null, "1 2 proxy enable proxy support");
l.add(null, "2 . proxy profile");
l.add(null, "1 2 second-port enable dual binding");
l.add(null, "2 . secure port");
l.add(null, "1 2 bad-agent set host default path");
l.add(null, "2 2,. user agent to deny");
l.add(null, "1 2 def-path set host default path");
l.add(null, "2 . path on the disk");
l.add(null, "1 2 def-subconn set host default subconnect");
getSubconnHelp("2 2,. ", l);
l.add(null, "1 2 error set error message");
l.add(null, "2 2,. error message");
l.add(null, "1 2 host define one virtual server");
List lst = new ArrayList();
for (int i = 0; i < hosts.size(); i++) {
lst.add(hosts.get(i).host);
}
l.add(lst, "2 3 name of server, * for any");
l.add(null, "3 4 path set server root");
l.add(null, "4 . root directory of server");
l.add(null, "3 4 redir set redirect path");
l.add(null, "4 . url to redirect to");
l.add(null, "3 4 webring set redirect file");
l.add(null, "4 . path to redirect list");
l.add(null, "3 . logging log to syslog");
l.add(null, "3 4 reconn reconnect to server");
l.add(null, "4 5 proxy profile");
l.add(null, "5 . server to redirect to");
l.add(null, "3 4 translate translate the url");
l.add(null, "4 4,. translation rule to use");
l.add(null, "3 4 subconn reconnect only to the url");
getSubconnHelp("4 4,. ", l);
l.add(null, "3 4 stream stream from server");
l.add(null, "4 5 content type");
l.add(null, "5 6 proxy profile");
l.add(null, "6 . server to stream from");
l.add(null, "3 4 multiacc access multiple servers");
l.add(null, "4 5 proxy profile");
l.add(null, "5 5,. server to access");
l.add(null, "3 . markdown allow markdown conversion");
l.add(null, "3 . noindex disallow index for directory");
l.add(null, "3 4 speed-limit limit download speeds");
l.add(null, "4 . bytes per second");
l.add(null, "3 4,. dirlist allow directory listing");
l.add(null, "4 4,. readme put readme in front of listing");
l.add(null, "4 4,. stats put statistics after listing");
l.add(null, "3 4,. script allow script running");
l.add(null, "4 4,. exec allow exec commands");
l.add(null, "4 4,. config allow config commands");
l.add(null, "3 4,. api allow api calls");
l.add(null, "4 4,. exec allow exec commands");
l.add(null, "4 4,. show allow show commands");
l.add(null, "4 4,. script allow script commands");
l.add(null, "4 4,. config allow config commands");
l.add(null, "4 4,. ipinfo allow ip info commands");
secInfoUtl.getHelp(l, 3, "ipinfo allow ipinfo api");
l.add(null, "3 4 search-script allow scripts defined in configuration");
l.add(null, "4 . prefix");
l.add(null, "3 . imagemap allow image map processing");
l.add(null, "3 . websock allow websocket processing");
l.add(null, "3 . webdav allow webdav processing");
l.add(null, "3 . mediastream allow media streaming");
l.add(null, "3 . class allow class running");
l.add(null, "3 . upload allow upload files");
l.add(null, "3 4 backup backup uploaded files");
l.add(null, "4 5 number of backups to keep");
l.add(null, "5 . root directory of backup");
l.add(null, "3 4 sstp allow sstp clients");
l.add(null, "4 . name of interface");
l.add(null, "3 4 anyconn allow anyconnect clients");
l.add(null, "4 . name of interface");
l.add(null, "3 4 forti allow fortinet clients");
l.add(null, "4 . name of interface");
l.add(null, "3 4 authentication require authentication to access");
l.add(null, "4 . authentication list");
l.add(null, "3 4 style set page style tags");
l.add(null, "4 4,. text to send");
secInfoUtl.getHelp(l, 2, "access-");
}
/**
* get name
*
* @return name
*/
public String srvName() {
return "http";
}
/**
* get port
*
* @return port
*/
public int srvPort() {
return clearPort;
}
/**
* get protocol
*
* @return protocol
*/
public int srvProto() {
return protoAllStrm;
}
/**
* initialize
*
* @return false on success, true on error
*/
public boolean srvInit() {
if (secondPort > 0) {
if (genStrmStart(this, new pipeLine(bufSiz, false), secondPort)) {
return true;
}
}
return genStrmStart(this, new pipeLine(bufSiz, false), 0);
}
/**
* deinitialize
*
* @return false on success, true on error
*/
public boolean srvDeinit() {
if (secondPort > 0) {
if (genericStop(secondPort)) {
return true;
}
}
return genericStop(0);
}
/**
* get show
*
* @return result
*/
public userFormat getShStat() {
userFormat res = new userFormat("|", "host|hit|last");
for (int i = 0; i < hosts.size(); i++) {
servHttpHost ntry = hosts.get(i);
res.add(ntry.host + "|" + ntry.askNum + "|" + bits.timePast(ntry.askTim));
}
return res;
}
/**
* get show
*
* @param s host to use
* @return result
*/
public List getShZone(String s) {
List res = new ArrayList();
for (int i = 0; i < hosts.size(); i++) {
servHttpHost ntry = hosts.get(i);
String a = ntry.host;
String b = "rr " + a + " cname " + s;
int o = a.indexOf(".");
if (o > 0) {
b = "zone " + a.substring(o + 1, a.length()) + " " + b;
}
res.add(b);
}
return res;
}
}