2022-06-12 18:36:25 +02:00
|
|
|
import http.client, re, socket, sys, time, _thread
|
2022-01-31 23:49:50 +01:00
|
|
|
|
|
|
|
RECBUF = 1024
|
|
|
|
|
|
|
|
def getargv(arg, default="", n=1, args=sys.argv):
|
|
|
|
if arg in args and len(args) > args.index(arg)+n:
|
|
|
|
return args[args.index(arg)+n]
|
|
|
|
else:
|
|
|
|
return default
|
|
|
|
|
|
|
|
p_clen = re.compile("\r?\ncontent-length: *(\d+)\r?\n?", re.IGNORECASE)
|
|
|
|
|
2022-06-12 18:36:25 +02:00
|
|
|
def handle(client):
|
|
|
|
# Get request
|
|
|
|
paquet = b""
|
|
|
|
header = b""
|
|
|
|
content = b""
|
|
|
|
content_len = 0
|
|
|
|
resp = {}
|
|
|
|
lf = 0
|
|
|
|
while True:
|
|
|
|
raw = client.recv(RECBUF)
|
|
|
|
if raw:
|
|
|
|
paquet += raw
|
|
|
|
if lf >= 0:
|
|
|
|
for c in raw:
|
|
|
|
if c == 10:# LF
|
|
|
|
lf += 1
|
|
|
|
elif c != 13:# CR
|
|
|
|
lf = 0
|
|
|
|
if lf > 1:
|
|
|
|
parts = paquet.split(b"\r\n\r\n")
|
|
|
|
header = parts[0]
|
|
|
|
content = parts[1]
|
|
|
|
try:
|
|
|
|
content_len = int(p_clen.search(header.decode()).group(1))
|
|
|
|
except (AttributeError, ValueError):
|
|
|
|
content_len = 0
|
|
|
|
break
|
|
|
|
if lf > 1:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
while len(content) < content_len:
|
|
|
|
raw = client.recv(RECBUF)
|
|
|
|
paquet += raw
|
|
|
|
content += raw
|
|
|
|
|
|
|
|
httpreq = paquet.split(b" ", 2)
|
|
|
|
if len(httpreq) != 3:
|
|
|
|
client.close()
|
|
|
|
return
|
|
|
|
method = httpreq[0]
|
|
|
|
url = httpreq[1]
|
|
|
|
rest = httpreq[2]
|
|
|
|
|
|
|
|
if b"/send/m.room.message/" in url:
|
|
|
|
method = b"PUT"
|
|
|
|
|
|
|
|
matrix_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
if matrix_https:
|
|
|
|
matrix_sock = ssl_ctx.wrap_socket(matrix_sock, server_hostname=matrix_addr)
|
|
|
|
matrix_sock.settimeout(60)
|
|
|
|
try:
|
|
|
|
matrix_sock.connect((matrix_addr, matrix_port))
|
|
|
|
except socket.timeout:
|
|
|
|
sys.stderr.write("timeout connecting to matrix")
|
|
|
|
return
|
|
|
|
matrix_sock.settimeout(None)
|
|
|
|
|
|
|
|
matrix_sock.sendall(b" ".join([method, url, rest]))
|
|
|
|
|
|
|
|
paquet = b""
|
|
|
|
header = b""
|
|
|
|
content = b""
|
|
|
|
content_len = 0
|
|
|
|
resp = {}
|
|
|
|
lf = 0
|
|
|
|
while True:
|
|
|
|
raw = matrix_sock.recv(RECBUF)
|
|
|
|
if raw:
|
|
|
|
paquet += raw
|
|
|
|
if lf >= 0:
|
|
|
|
for c in raw:
|
|
|
|
if c == 10:# LF
|
|
|
|
lf += 1
|
|
|
|
elif c != 13:# CR
|
|
|
|
lf = 0
|
|
|
|
if lf > 1:
|
|
|
|
parts = paquet.split(b"\r\n\r\n")
|
|
|
|
header = parts[0]
|
|
|
|
content = parts[1]
|
|
|
|
try:
|
|
|
|
content_len = int(p_clen.search(header.decode()).group(1))
|
|
|
|
except AttributeError:
|
|
|
|
content_len = 0
|
|
|
|
break
|
|
|
|
if lf > 1:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
while len(content) < content_len:
|
|
|
|
raw = matrix_sock.recv(RECBUF)
|
|
|
|
paquet += raw
|
|
|
|
content += raw
|
|
|
|
|
|
|
|
client.sendall(paquet)
|
|
|
|
|
|
|
|
client.close()
|
|
|
|
|
2022-01-31 23:49:50 +01:00
|
|
|
if __name__ == "__main__":
|
|
|
|
if "--help" in sys.argv or "-h" in sys.argv:
|
|
|
|
print("""MineTest Matrix Bridge mod proxy
|
|
|
|
GNU AGPLv3, CopyLeft 2022 Pascal Engélibert
|
|
|
|
|
|
|
|
This program is useful for <5.4.0 MineTest servers using the mod matrix_bridge.
|
|
|
|
For security reasons, please listen to a local address (default value is OK) and use a firewall if needed to prevent public access.
|
|
|
|
|
|
|
|
Options: (with defaults)
|
|
|
|
-a 127.0.0.1 Listen address
|
|
|
|
-p 18448 Listen port
|
|
|
|
-A matrix.txmn.tk Matrix address (without protocol and port)
|
|
|
|
-P 8448 Matrix port
|
|
|
|
-s Use HTTP instead of HTTPS (default: no)
|
|
|
|
""")
|
|
|
|
exit()
|
|
|
|
|
|
|
|
listen_addr = getargv("-a", "127.0.0.1")
|
|
|
|
listen_port = int(getargv("-p", 18448))
|
|
|
|
matrix_addr = getargv("-A", "matrix.txmn.tk")
|
|
|
|
matrix_port = int(getargv("-P", 8448))
|
|
|
|
matrix_https = not "-s" in sys.argv
|
|
|
|
|
|
|
|
if matrix_https:
|
|
|
|
import ssl
|
2022-07-11 12:15:28 +02:00
|
|
|
ssl_ctx = ssl.create_default_context()
|
2022-01-31 23:49:50 +01:00
|
|
|
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
|
|
sock.settimeout(60)
|
|
|
|
sock.bind((listen_addr, listen_port))
|
|
|
|
sock.listen(1)
|
|
|
|
|
|
|
|
try:
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
client, addr = sock.accept()
|
|
|
|
except socket.timeout:
|
|
|
|
continue
|
|
|
|
|
2022-06-12 18:36:25 +02:00
|
|
|
_thread.start_new_thread(handle, (client,))
|
2022-01-31 23:49:50 +01:00
|
|
|
sock.close()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
sock.shutdown(socket.SHUT_WR)
|