added seperate input and working on http / sockets

This commit is contained in:
2026-05-27 17:01:26 -04:00
parent 59e09a5995
commit f7b64c11b7
43 changed files with 5035 additions and 533 deletions

View File

@@ -1 +1,306 @@
--:Minify:--
local kernel = ...
local handler = {}
local http = kernel.apis.http
kernel.cct.httpqueue = kernel.cct.httpqueue or {}
kernel.cct.httpresponse = kernel.cct.httpresponse or {}
kernel.cct.httperror = kernel.cct.httperror or {}
local function parseRawRequest(raw)
local sepLen = 4
local headerEnd =
raw:find("\r\n\r\n", 1, true)
if not headerEnd then
headerEnd =
raw:find("\n\n", 1, true)
sepLen = 2
end
local headerPart
local body = ""
if headerEnd then
headerPart = raw:sub(1, headerEnd - 1)
body = raw:sub(headerEnd + sepLen)
else
headerPart = raw
end
local lines = {}
for line in headerPart:gmatch("[^\r\n]+") do
lines[#lines + 1] = line
end
if #lines == 0 then
return nil, "EINVAL"
end
local method, path =
lines[1]:match("^(%S+)%s+(%S+)")
if not method or not path then
return nil, "EBADMSG"
end
local headers = {}
for i = 2, #lines do
local k, v =
lines[i]:match("^([^:]+):%s*(.*)$")
if k then
headers[k] = v
end
end
local host = headers.Host or headers.host
if not host and not path:match("^https?://") then
return nil, "EHOSTUNREACH"
end
local url
if path:match("^https?://") then
url = path
else
url = "http://" .. host .. path
end
local req = {
url = url,
method = method,
headers = headers
}
if body ~= "" then
req.body = body
end
return req
end
local function buildResponse(resp)
if not resp then
return nil, "EINVAL"
end
local code, msg = resp.getResponseCode()
local headers =
resp:getResponseHeaders()
local body =
resp:readAll() or ""
local out = {
"HTTP/1.1 " ..
tostring(code) ..
" " ..
tostring(msg)
}
local hasLength = false
for k, v in pairs(headers or {}) do
if k:lower() == "content-length" then
hasLength = true
end
out[#out + 1] =
tostring(k) ..
": " ..
tostring(v)
end
if not hasLength then
out[#out + 1] =
"Content-Length: " ..
tostring(#body)
end
out[#out + 1] = ""
out[#out + 1] = body
return table.concat(out, "\r\n")
end
function handler.connect(fd, address)
local fdo = kernel.currentTask.fd[fd]
if not fdo then
return nil, "EBADF"
end
fdo.socket.rbuf = ""
fdo.socket.closed = false
fdo.socket.httpid = nil
fdo.handle.write = function(raw)
local req, err =
parseRawRequest(raw)
if not req then
return nil, err
end
local id =
tostring(kernel.uuid())
fdo.socket.httpid = id
kernel.cct.httpqueue[id] = true
local ok, err =
http.request(req, id)
if not ok then
kernel.cct.httpqueue[id] = nil
return nil, err
end
return true
end
fdo.handle.read = function(count)
count = count or 4096
local sock = fdo.socket
if #sock.rbuf > 0 then
local out =
sock.rbuf:sub(1, count)
sock.rbuf =
sock.rbuf:sub(count + 1)
return out
end
local id = sock.httpid
if not id then
return ""
end
local function finish(resp)
sock.rbuf =
buildResponse(resp) or ""
local out =
sock.rbuf:sub(1, count)
sock.rbuf =
sock.rbuf:sub(count + 1)
return out
end
if kernel.cct.httpresponse[id] then
local resp =
kernel.cct.httpresponse[id]
kernel.cct.httpresponse[id] = nil
kernel.cct.httpqueue[id] = nil
return finish(resp)
end
if kernel.cct.httperror[id] then
local err =
kernel.cct.httperror[id]
kernel.cct.httperror[id] = nil
kernel.cct.httpqueue[id] = nil
return nil, err
end
kernel.currentTask.status = "D"
local coro
coro = function()
if kernel.cct.httpresponse[id] then
local resp =
kernel.cct.httpresponse[id]
kernel.cct.httpresponse[id] = nil
kernel.cct.httpqueue[id] = nil
kernel.asyncReturn(
finish(resp)
)
return
end
if kernel.cct.httperror[id] then
local err =
kernel.cct.httperror[id]
kernel.cct.httperror[id] = nil
kernel.cct.httpqueue[id] = nil
kernel.asyncReturn(
nil,
err
)
return
end
coroutine.yield()
end
kernel.currentTask.ksh =
coroutine.create(function()
local ok, err =
xpcall(
coro,
debug.traceback
)
if not ok then
kernel.asyncReturn(
nil,
err
)
end
end)
end
fdo.handle.close = function()
fdo.socket.closed = true
local id =
fdo.socket.httpid
if id then
kernel.cct.httpqueue[id] = nil
kernel.cct.httpresponse[id] = nil
kernel.cct.httperror[id] = nil
end
return true
end
return true
end
kernel.socket.registerProtocal(
"http://",
handler
)
kernel.socket.registerProtocal(
"https://",
handler
)

View File

@@ -223,6 +223,9 @@ local function newtty(obj, id, ev)
gctrl=function()
return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt)
end,
isvirt=function()
return false
end,
gplt=function()
return plt
end
@@ -243,8 +246,39 @@ end
local fifo = kernel.newFifo()
kernel.cct.fifo=fifo
newtty(kernel.apis.term, "1", fifo.pop)
newtty(kernel.apis.term, "1", function() end)
for i,v in ipairs({peripheral.find("monitor")}) do
newtty(v,tostring(i+1),function () end)
end
kernel.devfs.data["input"]["keyboard1"] = function(op, mode)
if op=="type" then
return "Keyboard"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {fifo.pop()}
if event[1] then
rv=rv..event[1]
end
end
if rv=="" then rv=nil end
return rv
end,
write=function(content)
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end

View File

@@ -4,6 +4,7 @@ local keys=kernel.apis.keys
kernel.processes.cctdeamon = function()
local timeout = false
kernel.log("CCT deamon started")
while true do
local event = {kernel.EFI:getMachineEvent()}
@@ -66,6 +67,12 @@ kernel.processes.cctdeamon = function()
elseif eventType == "keyTyped" then
if charOrKey then kernel.cct.fifo.push(charOrKey) end
elseif eventType == "mouse_scroll" then
if event[2] == 1 then
kernel.cct.fifo.push("S")
else
kernel.cct.fifo.push("T")
end
elseif eventType == "http_success" then
kernel.cct.httpqueue[event[2]]=nil
kernel.cct.httpresponse[event[2]]=event[3]
@@ -83,4 +90,6 @@ kernel.processes.cctdeamon = function()
sleep(0.05)
end
end
end
end
kernel.log("CCT deamon queued for execution")