143 lines
3.7 KiB
Haxe
143 lines
3.7 KiB
Haxe
|
/*
|
||
|
SAGITTA -- the arrow
|
||
|
gemini fetcher
|
||
|
|
||
|
named so because it requires some "bow" code to shoot it well
|
||
|
but it can be rebound off of redirects,
|
||
|
shot through tls,
|
||
|
and find any links in its path,
|
||
|
for easier management by the archer
|
||
|
*/
|
||
|
|
||
|
import Sys.getChar;
|
||
|
import Sys.systemName;
|
||
|
#if Windows
|
||
|
import Sys.command;
|
||
|
#end
|
||
|
|
||
|
import Sys.print;
|
||
|
import Sys.println;
|
||
|
import sys.net.Socket;
|
||
|
import sys.ssl.Socket as SSL_Socket;
|
||
|
import sys.net.Host;
|
||
|
import JanBug.pbug;
|
||
|
//import Std.string;
|
||
|
|
||
|
class Sagitta {
|
||
|
static final timeout_short=0.5; //in seconds, time before first attempt fails
|
||
|
static final timeout_long=1; //in seconds, time before second attempt fails
|
||
|
static final nl="\n"; //newline
|
||
|
|
||
|
static public function main(){
|
||
|
/*
|
||
|
* if the result isn't intended to run on windows,
|
||
|
* then assume it works with ansi escapes
|
||
|
* adding windows flag just allows
|
||
|
*/
|
||
|
#if Windows
|
||
|
if(systemName()=="Windows"){
|
||
|
command("%userprofile%\\documents\\C\\fixcon10.exe");
|
||
|
};
|
||
|
#end
|
||
|
stuff("gemini://tilde.pink/~jan6");
|
||
|
pbug("press any key to continue","info");
|
||
|
getChar(false);
|
||
|
};
|
||
|
// static public function stuff(url:String,?redirect:Bool=false) {
|
||
|
static public function stuff(url:String) {
|
||
|
var redirect:Bool=false;
|
||
|
//convenience variables to avoid quotes
|
||
|
final error="error";
|
||
|
final warn ="warn";
|
||
|
final info="info";
|
||
|
final debug="debug";
|
||
|
|
||
|
pbug("requesting: "+url,debug,true);
|
||
|
var text=false;
|
||
|
var nl=Sagitta.nl; //newline
|
||
|
var buf=new haxe.io.BytesBuffer();
|
||
|
var timeout_short=Sagitta.timeout_short;
|
||
|
var timeout_long =Sagitta.timeout_long;
|
||
|
|
||
|
//don't verify now, since want self-signed and whatnot to be accepted
|
||
|
SSL_Socket.DEFAULT_VERIFY_CERT=false;
|
||
|
var socket = new SSL_Socket();
|
||
|
socket.connect(new Host(url.split("/")[2]), 1965);
|
||
|
|
||
|
socket.setTimeout(timeout_short); //timeout in seconds
|
||
|
//pbug('timeout set to short: $timeout_short seconds');
|
||
|
socket.setFastSend(true); //not needed, not sure if matters
|
||
|
//Sys.sleep(2); //doesn't help
|
||
|
pbug("writing request");
|
||
|
socket.write('$url\r\n');
|
||
|
socket.output.flush(); //shouldn't be needed, right?
|
||
|
pbug("request written");
|
||
|
socket.waitForRead();
|
||
|
var header=socket.input.read(1).toString();
|
||
|
if(header!=null){
|
||
|
pbug("reading header");
|
||
|
header+=socket.input.readUntil("\r".code);
|
||
|
socket.input.readByte();
|
||
|
if(header.split("")[0]=="3"){
|
||
|
var new_url=header.split("\r")[0].split(" ")[1];
|
||
|
pbug("redirect → "+new_url,info);
|
||
|
stuff(new_url);
|
||
|
redirect=true;
|
||
|
// stuff(new_url,true);
|
||
|
}
|
||
|
else if(header.split("")[0]=="2"){
|
||
|
var mime=header.split(" ")[1];
|
||
|
if(mime.split("/")[0].toLowerCase()=="text"){
|
||
|
pbug("mimetype is text",debug);
|
||
|
};
|
||
|
};
|
||
|
else println(header);
|
||
|
if(!redirect){pbug("header read");};
|
||
|
try {
|
||
|
buf.add(socket.input.read(1));
|
||
|
if(buf!=null){
|
||
|
pbug("reading body");
|
||
|
if(text){
|
||
|
while(true){
|
||
|
buf.addString(socket.input.readLine()+nl);
|
||
|
};
|
||
|
}
|
||
|
else {
|
||
|
while(true){
|
||
|
buf.add(socket.input.read(1));
|
||
|
//var a=socket.input.read(5);
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
pbug("body read");
|
||
|
//} catch (e:Any) { //since haxe 4.1 reccommended to drop wildcard type
|
||
|
}
|
||
|
catch (e:haxe.io.Error) {
|
||
|
if(e == haxe.io.Error.Blocked){
|
||
|
pbug("I/O Blocked, attempting with longer timeout",warn);
|
||
|
socket.setTimeout(timeout_long); //timeout in seconds
|
||
|
pbug('timeout set to long: $timeout_long seconds');
|
||
|
pbug("reading body");
|
||
|
try {
|
||
|
while(true){
|
||
|
buf.add(socket.input.read(1));
|
||
|
};
|
||
|
pbug("body read");
|
||
|
}
|
||
|
catch (e:haxe.io.Error) {
|
||
|
if(e == haxe.io.Error.Blocked){
|
||
|
pbug("I/O Blocked!",error);
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
catch (e:haxe.io.Eof) {
|
||
|
print(buf.getBytes());
|
||
|
if(!redirect){pbug('EOF of $url',info);};
|
||
|
};
|
||
|
};
|
||
|
socket.close();
|
||
|
//*/
|
||
|
}
|
||
|
}
|