Attempting to return streams as response content.

Fails horribly after reaching the end and attempting to access the methods
This commit is contained in:
Alessandro Proto 2023-01-13 20:39:54 +01:00
parent 84401bc12a
commit 027c13d86e
5 changed files with 580 additions and 10 deletions

View file

@ -0,0 +1,128 @@
using KeraLua;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Capy64.LuaRuntime.Handlers;
[Obsolete("Work in progress")]
public class BinaryReadHandle
{
private readonly BinaryReader _stream;
private bool isClosed = false;
private bool ended => _stream.BaseStream.Position == _stream.BaseStream.Length;
public BinaryReadHandle(Stream stream)
{
_stream = new BinaryReader(stream);
}
public BinaryReadHandle(BinaryReader stream)
{
_stream = stream;
}
/*public void Push(Lua L)
{
L.NewTable();
L.PushString("readAll");
L.PushCFunction(L_ReadAll);
L.SetTable(-3);
L.PushString("readLine");
L.PushCFunction(L_ReadLine);
L.SetTable(-3);
L.PushString("read");
L.PushCFunction(L_Read);
L.SetTable(-3);
L.PushString("close");
L.PushCFunction(L_Close);
L.SetTable(-3);
}
private int L_ReadAll(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
if (ended)
{
L.PushNil();
return 1;
}
//var content = _stream.read;
L.PushString(content);
return 1;
}
private int L_ReadLine(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
if (ended)
{
L.PushNil();
return 1;
}
var line = _stream.ReadLine();
if (line is null)
L.PushNil();
else
L.PushString(line);
return 1;
}
private int L_Read(IntPtr state)
{
var L = Lua.FromIntPtr(state);
var count = (int)L.OptNumber(1, 1);
L.ArgumentCheck(count < 1, 1, "count must be a positive integer");
if (ended)
L.Error("handle is closed");
if (_stream.EndOfStream)
{
L.PushNil();
return 1;
}
var chunk = new char[count];
_stream.Read(chunk, 0, count);
L.PushString(new string(chunk));
return 1;
}
private int L_Close(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
return 0;
_stream.Close();
isClosed = true;
return 0;
}*/
}

View file

@ -0,0 +1,127 @@
using KeraLua;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Capy64.LuaRuntime.Handlers;
[Obsolete("Work in progress")]
public class BinaryWriteHandle
{
private readonly BinaryWriter _stream;
private bool isClosed = false;
public BinaryWriteHandle(Stream stream)
{
_stream = new BinaryWriter(stream);
}
public BinaryWriteHandle(BinaryWriter stream)
{
_stream = stream;
}
/*public void Push(Lua L)
{
L.NewTable();
L.PushString("readAll");
L.PushCFunction(L_ReadAll);
L.SetTable(-3);
L.PushString("readLine");
L.PushCFunction(L_ReadLine);
L.SetTable(-3);
L.PushString("read");
L.PushCFunction(L_Read);
L.SetTable(-3);
L.PushString("close");
L.PushCFunction(L_Close);
L.SetTable(-3);
}
private int L_ReadAll(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
if (ended)
{
L.PushNil();
return 1;
}
//var content = _stream.read;
L.PushString(content);
return 1;
}
private int L_ReadLine(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
if (ended)
{
L.PushNil();
return 1;
}
var line = _stream.ReadLine();
if (line is null)
L.PushNil();
else
L.PushString(line);
return 1;
}
private int L_Read(IntPtr state)
{
var L = Lua.FromIntPtr(state);
var count = (int)L.OptNumber(1, 1);
L.ArgumentCheck(count < 1, 1, "count must be a positive integer");
if (ended)
L.Error("handle is closed");
if (_stream.EndOfStream)
{
L.PushNil();
return 1;
}
var chunk = new char[count];
_stream.Read(chunk, 0, count);
L.PushString(new string(chunk));
return 1;
}
private int L_Close(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
return 0;
_stream.Close();
isClosed = true;
return 0;
}*/
}

View file

@ -0,0 +1,126 @@
using KeraLua;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace Capy64.LuaRuntime.Handlers;
public class ReadHandle : IDisposable
{
private readonly MemoryStream _memoryStream;
private readonly StreamReader _stream;
private bool isClosed = false;
public ReadHandle(Stream stream)
{
_memoryStream = new MemoryStream(capacity: (int)stream.Length);
stream.CopyTo(_memoryStream);
_memoryStream.Position = 0;
_stream = new StreamReader(_memoryStream);
}
public void Push(Lua L)
{
L.NewTable();
L.PushString("readAll");
L.PushCFunction(L_ReadAll);
L.SetTable(-3);
L.PushString("readLine");
L.PushCFunction(L_ReadLine);
L.SetTable(-3);
L.PushString("read");
L.PushCFunction(L_Read);
L.SetTable(-3);
L.PushString("close");
L.PushCFunction(L_Close);
L.SetTable(-3);
}
private int L_ReadAll(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
if (_stream.EndOfStream)
{
L.PushNil();
return 1;
}
var content = _stream.ReadToEnd();
L.PushString(content);
return 1;
}
private int L_ReadLine(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
var line = _stream.ReadLine();
if (line is null)
L.PushNil();
else
L.PushString(line);
return 1;
}
private int L_Read(IntPtr state)
{
var L = Lua.FromIntPtr(state);
var count = (int)L.OptNumber(1, 1);
L.ArgumentCheck(count >= 1, 1, "count must be a positive integer");
if (isClosed)
L.Error("handle is closed");
if (_stream.EndOfStream)
{
L.PushNil();
return 1;
}
var chunk = new char[count];
_stream.Read(chunk, 0, count);
L.PushString(new string(chunk));
return 1;
}
private int L_Close(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
return 0;
_stream.Close();
isClosed = true;
return 0;
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
}

View file

@ -0,0 +1,102 @@
using KeraLua;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Capy64.LuaRuntime.Handlers;
public class WriteHandle
{
private readonly StreamWriter _stream;
private bool isClosed = false;
public WriteHandle(Stream stream)
{
_stream = new StreamWriter(stream);
}
public WriteHandle(StreamWriter stream)
{
_stream = stream;
}
public void Push(Lua L)
{
L.NewTable();
L.PushString("write");
L.PushCFunction(L_Write);
L.SetTable(-3);
L.PushString("writeLine");
L.PushCFunction(L_WriteLine);
L.SetTable(-3);
L.PushString("flush");
L.PushCFunction(L_Flush);
L.SetTable(-3);
L.PushString("close");
L.PushCFunction(L_Close);
L.SetTable(-3);
}
private int L_Write(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
var content = L.CheckString(1);
_stream.Write(content);
return 0;
}
private int L_WriteLine(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
var content = L.CheckString(1);
_stream.WriteLine(content);
return 0;
}
private int L_Flush(IntPtr state)
{
var L = Lua.FromIntPtr(state);
var count = (int)L.OptNumber(1, 1);
L.ArgumentCheck(count < 1, 1, "count must be a positive integer");
if (isClosed)
L.Error("handle is closed");
_stream.Flush();
return 0;
}
private int L_Close(IntPtr state)
{
var L = Lua.FromIntPtr(state);
if (isClosed)
return 0;
_stream.Close();
isClosed = true;
return 0;
}
}

View file

@ -1,8 +1,10 @@
using Capy64.API;
using Capy64.LuaRuntime.Extensions;
using Capy64.LuaRuntime.Handlers;
using KeraLua;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
@ -13,6 +15,7 @@ public class HTTP : IPlugin
private static IGame _game;
private static HttpClient _client;
private static long RequestId;
private static List<ReadHandle> ReadHandles = new();
private readonly LuaRegister[] HttpLib = new LuaRegister[]
{
@ -151,12 +154,14 @@ public class HTTP : IPlugin
reqTask.ContinueWith(async (task) =>
{
var response = await task;
object content;
/*object content;
if ((bool)options["binary"])
content = await response.Content.ReadAsByteArrayAsync();
else
content = await response.Content.ReadAsStringAsync();
content = await response.Content.ReadAsStringAsync();*/
var _stream = new StreamReader(await response.Content.ReadAsStreamAsync());
var isClosed = false;
_game.LuaRuntime.PushEvent("http_response", L =>
{
@ -178,23 +183,105 @@ public class HTTP : IPlugin
L.PushString(response.ReasonPhrase);
L.SetTable(-3);
L.PushString("content");
if ((bool)options["binary"])
L.PushBuffer((byte[])content);
else
L.PushString((string)content);
L.SetTable(-3);
L.PushString("headers");
L.NewTable();
foreach(var header in response.Headers)
foreach (var header in response.Headers)
{
L.PushString(header.Key);
L.PushArray(header.Value.ToArray());
L.SetTable(-3);
}
L.SetTable(-3);
L.PushString("content");
L.NewTable();
L.PushString("readAll");
L.PushCFunction((IntPtr state) =>
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
if (_stream.EndOfStream)
{
L.PushNil();
return 1;
}
var content = _stream.ReadToEnd();
L.PushString(content);
return 1;
});
L.SetTable(-3);
L.PushString("readLine");
L.PushCFunction((IntPtr state) =>
{
var L = Lua.FromIntPtr(state);
if (isClosed)
L.Error("handle is closed");
var line = _stream.ReadLine();
if (line is null)
L.PushNil();
else
L.PushString(line);
return 1;
});
L.SetTable(-3);
L.PushString("read");
L.PushCFunction((IntPtr state) =>
{
var L = Lua.FromIntPtr(state);
var count = (int)L.OptNumber(1, 1);
L.ArgumentCheck(count >= 1, 1, "count must be a positive integer");
if (isClosed)
L.Error("handle is closed");
if (_stream.EndOfStream)
{
L.PushNil();
return 1;
}
var chunk = new char[count];
_stream.Read(chunk, 0, count);
L.PushString(new string(chunk));
return 1;
});
L.SetTable(-3);
L.PushString("close");
L.PushCFunction((IntPtr state) =>
{
var L = Lua.FromIntPtr(state);
if (isClosed)
return 0;
_stream.Close();
isClosed = true;
return 0;
});
L.SetTable(-3);
L.SetTable(-3);
return 2;