101 lines
2.6 KiB
GDScript
101 lines
2.6 KiB
GDScript
class_name VSTAuthServer
|
|
|
|
extends Node
|
|
|
|
signal OnTokenReceived(token: String)
|
|
|
|
var SERVER_IDENTITY = 'AUTH_SERVER'
|
|
var TOKEN_KEY = 'token'
|
|
var AUTHENTICATION_REDIRECT_FILE_PATH = 'res://addons/very-simple-twitch/public/index.html'
|
|
|
|
var _clients: Array[StreamPeerTCP] = []
|
|
var _server: TCPServer
|
|
|
|
|
|
func start_server(port: int):
|
|
_server = TCPServer.new()
|
|
_server.listen(port)
|
|
print("Server started")
|
|
|
|
|
|
func stop_server():
|
|
if _server:
|
|
_server.stop()
|
|
_server = null
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
if !_server:
|
|
return
|
|
|
|
var newConnection = _server.take_connection()
|
|
if newConnection:
|
|
_clients.push_back(newConnection)
|
|
|
|
for client in _clients:
|
|
if client.get_status() != StreamPeerTCP.STATUS_CONNECTED:
|
|
continue
|
|
|
|
var bytes = client.get_available_bytes()
|
|
# after finisher reading bytes clear connection
|
|
_clients = _clients.filter(func (item): return item != client)
|
|
var requestAsString = client.get_string(bytes)
|
|
if requestAsString.length() < 1:
|
|
continue
|
|
|
|
var requestInformation = requestAsString.split('\n')[0].split(' ')
|
|
var method = requestInformation[0]
|
|
var url = requestInformation[1]
|
|
|
|
match method:
|
|
'GET':
|
|
# send html login page
|
|
handleGet(client)
|
|
'POST':
|
|
# handle token extraction
|
|
handlePost(client, url)
|
|
|
|
|
|
func handlePost(client: StreamPeer, url: String):
|
|
var urlSplitted:PackedStringArray = url.split('?')
|
|
if (len(urlSplitted) == 1):
|
|
return
|
|
var query = urlSplitted[1]
|
|
var token = getTokenFromQuery(query)
|
|
if !token:
|
|
return
|
|
OnTokenReceived.emit(token)
|
|
send200(client)
|
|
stop_server()
|
|
queue_free()
|
|
|
|
|
|
func handleGet(client: StreamPeer):
|
|
var pageAsString = loadLoginPage()
|
|
send200(client, pageAsString)
|
|
|
|
|
|
func getTokenFromQuery(query: String):
|
|
var queryKeyValues = query.split('&')
|
|
for keyValue in queryKeyValues:
|
|
var splittedKeyValue = keyValue.split('=')
|
|
var key = splittedKeyValue[0]
|
|
if key == TOKEN_KEY:
|
|
return splittedKeyValue[1]
|
|
|
|
|
|
func send200(client: StreamPeer, data: String = "", content_type: String = "text/html"):
|
|
var dataAsBuffer = data.to_ascii_buffer()
|
|
client.put_data(("HTTP/1.1 %d %s\r\n" % [200, 'OK']).to_ascii_buffer())
|
|
client.put_data(("Server: %s\r\n" % SERVER_IDENTITY).to_ascii_buffer())
|
|
client.put_data(("Content-Length: %d\r\n" % dataAsBuffer.size()).to_ascii_buffer())
|
|
client.put_data("Connection: close\r\n".to_ascii_buffer())
|
|
client.put_data(("Content-Type: %s\r\n\r\n" % content_type).to_ascii_buffer())
|
|
client.put_data(dataAsBuffer)
|
|
|
|
|
|
func loadLoginPage() -> String:
|
|
var file = FileAccess.open(AUTHENTICATION_REDIRECT_FILE_PATH, FileAccess.READ)
|
|
var loadedFile: String = file.get_as_text()
|
|
file.close()
|
|
return loadedFile
|