BastliBridge

git clone git://xatko.vsos.ethz.ch/BastliBridge.git
Log | Files | Refs | Submodules | README

proxy.d (2990B)


      1 import std.socket;
      2 import std.stdio;
      3 import std.conv:to;
      4 import std.typecons;
      5 import std.experimental.logger;
      6 import std.range;
      7 import bastlibridge.http;
      8 import bastlibridge.telegram;
      9 
     10 auto telegram=Nullable!Telegram.init;
     11 ubyte[] buf=new ubyte[1024];
     12 
     13 immutable string index=`
     14     ____  ___   _____________    ____
     15    / __ )/   | / ___/_  __/ /   /  _/
     16   / __  / /| | \__ \ / / / /    / /  
     17  / /_/ / ___ |___/ // / / /____/ /   
     18 /_____/_/  |_/____//_/ /_____/___/   
     19 `c;
     20 
     21 immutable string fof=`
     22  _  _    ___  _  _   
     23 | || |  / _ \| || |  
     24 | || |_| | | | || |_ 
     25 |__   _| |_| |__   _|
     26    |_|  \___/   |_|  
     27 `c;
     28 
     29 immutable string teapot=r"
     30             _
     31          _,(_)._
     32     ___,(_______).
     33   ,'__.           \    /\_
     34  /,' /             \  /  /
     35 | | |              |,'  /
     36  \`.|                  /
     37   `. :           :    /
     38     `.            :.,'
     39       `-.________,-'
     40 "c;
     41 
     42 void bridge(Socket ins, Socket outs, ubyte[] buf){
     43 	trace("Bridging between sockets");
     44 	size_t total=0;
     45 	size_t ret=0;
     46 	do{
     47 		ret=ins.receive(buf);
     48 		total+=ret;
     49 		outs.send(buf[0..ret]);
     50 	}while(ret==buf.length);
     51 	trace("Bridged a total of ", total, " bytes");
     52 }
     53 
     54 void handleClient(Socket newsock){
     55 	scope(exit){
     56 		newsock.close();
     57 	}
     58 	trace("Handling client "~newsock.remoteAddress.to!string);
     59 	static HttpResponse!void res;
     60 	auto req=receiveHttpRequest(newsock, buf);
     61 	if(req.isNull){
     62 		info("Socket gone");
     63 		return;
     64 	}
     65 	writeln(req);
     66 	void not_found(){
     67 		res.response(404, "Not Found");
     68 		res.header("Connection","close");
     69 		res.header("Content-Type","text/plain");
     70 		res.data(fof);
     71 		res.perform(newsock);
     72 	}
     73 	if(req.url=="/"){
     74 		res.response(200, "OK");
     75 		res.header("Content-Type","text/plain");
     76 		res.header("Connection","close");
     77 		res.data(index);
     78 		res.perform(newsock);
     79 	}
     80 	else if(req.url[1]!='?'){
     81 		not_found();
     82 	}
     83 	else{
     84 		JSONValue file;
     85 		try{
     86 			file=telegram.getFile(req.url[2..$]);
     87 		}
     88 		catch(TelegramException e){
     89 			not_found();
     90 			return;
     91 		}
     92 		catch(Exception e){
     93 			res.response(418, "I'm a teapot");
     94 			res.header("Connection", "close");
     95 			res.header("Content-Type", "text/plain");
     96 			res.data(teapot);
     97 			res.perform(newsock);
     98 			return;
     99 		}
    100 		string path=file["file_path"].str;
    101 		static HttpRequest!void r2;
    102 		r2.request("GET", chain("file/bot", telegram.token, "/", path));
    103 		r2.header("Host", telegram.ApiAddr);
    104 		r2.header("Connection", "close");
    105 		r2.perform(telegram.sock);
    106 		ubyte[1024] buffer;
    107 		bridge(telegram.sock, newsock, buffer);
    108 	}
    109 }
    110 
    111 void main(string[] args){
    112 	if(args.length!=4){
    113 		stderr.writeln("Usage: ", args[0], " <TELEGRAM_TOKEN> <IP> <PORT>");
    114 	}
    115 	
    116 	Address addr=parseAddress(args[2], args[3].to!ushort);
    117 	telegram=Telegram(args[1]);
    118 	telegram.connect();
    119 	scope(exit){
    120 		telegram.disconnect();
    121 	}
    122 	info("Listening on "~addr.toString);
    123 	
    124 	Socket server=new TcpSocket();
    125 	info("Binding to Address");
    126 	server.bind(addr);
    127 	scope(exit){
    128 		server.close();
    129 	}
    130 	info("Listening");
    131 	server.listen(10);
    132 	while(true){
    133 		auto newsock=server.accept();
    134 		handleClient(newsock);
    135 	}
    136 }