mirror of
https://gitea.invidious.io/iv-org/lsquic.cr
synced 2024-08-15 00:43:31 +00:00
Add support for writing headers
This commit is contained in:
parent
33a6cdd79e
commit
6e4b028f45
2 changed files with 70 additions and 49 deletions
113
src/lsquic.cr
113
src/lsquic.cr
|
@ -1,9 +1,10 @@
|
||||||
require "./lsquic/*"
|
require "./lsquic/*"
|
||||||
|
# require "http/headers"
|
||||||
require "http"
|
require "http"
|
||||||
require "socket"
|
require "socket"
|
||||||
|
|
||||||
# TODO: Move into StreamCtx as HTTP::Client::Request
|
# TODO: Move into StreamCtx as HTTP::Client::Request
|
||||||
PATH = "/"
|
PATH = "/watch?v=QmyhcjpsF6E"
|
||||||
METHOD = "GET"
|
METHOD = "GET"
|
||||||
HEADERS = HTTP::Headers{
|
HEADERS = HTTP::Headers{
|
||||||
":method" => METHOD,
|
":method" => METHOD,
|
||||||
|
@ -11,16 +12,16 @@ HEADERS = HTTP::Headers{
|
||||||
":path" => PATH,
|
":path" => PATH,
|
||||||
":authority" => "www.youtube.com",
|
":authority" => "www.youtube.com",
|
||||||
"user-agent" => "lsquic/2.6.1",
|
"user-agent" => "lsquic/2.6.1",
|
||||||
# TODO: Only sent if payload
|
# TODO: Send if payload
|
||||||
# "content-type" => "application/octet-stream"
|
# "content-type" => "application/octet-stream"
|
||||||
# "content-length" => "0",
|
# "content-length" => "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
logger_if = LibLsquic::LoggerIf.new
|
# logger_if = LibLsquic::LoggerIf.new
|
||||||
logger_if.log_buf = ->(logger_ctx : Void*, msg_buf : LibC::Char*, msg_size : LibC::SizeT) { puts String.new(msg_buf); 0 }
|
# logger_if.log_buf = ->(logger_ctx : Void*, msg_buf : LibC::Char*, msg_size : LibC::SizeT) { puts String.new(msg_buf); 0 }
|
||||||
LibLsquic.logger_init(pointerof(logger_if), nil, LibLsquic::LoggerTimestampStyle::LltsHhmmssms)
|
# LibLsquic.logger_init(pointerof(logger_if), nil, LibLsquic::LoggerTimestampStyle::LltsHhmmssms)
|
||||||
# LibLsquic.set_log_level("debug")
|
# LibLsquic.set_log_level("debug")
|
||||||
LibLsquic.logger_lopt("qlog=debug,conn=debug,engine=debug")
|
# LibLsquic.logger_lopt("conn=debug")
|
||||||
|
|
||||||
engine_flags = LibLsquic::LSENG_HTTP
|
engine_flags = LibLsquic::LSENG_HTTP
|
||||||
LibLsquic.engine_init_settings(out engine_settings, engine_flags)
|
LibLsquic.engine_init_settings(out engine_settings, engine_flags)
|
||||||
|
@ -29,7 +30,7 @@ engine_settings.es_ecn = 0
|
||||||
|
|
||||||
LibLsquic.global_init(engine_flags & LibLsquic::LSENG_SERVER ? LibLsquic::GLOBAL_SERVER : LibLsquic::GLOBAL_CLIENT)
|
LibLsquic.global_init(engine_flags & LibLsquic::LSENG_SERVER ? LibLsquic::GLOBAL_SERVER : LibLsquic::GLOBAL_CLIENT)
|
||||||
|
|
||||||
err_buf = Bytes.new(128)
|
err_buf = Bytes.new(0x100)
|
||||||
err_code = LibLsquic.engine_check_settings(pointerof(engine_settings), engine_flags, err_buf, err_buf.size)
|
err_code = LibLsquic.engine_check_settings(pointerof(engine_settings), engine_flags, err_buf, err_buf.size)
|
||||||
raise String.new(err_buf) if err_code != 0
|
raise String.new(err_buf) if err_code != 0
|
||||||
|
|
||||||
|
@ -48,45 +49,71 @@ stream_if.on_new_stream = ->(stream_if_ctx : Void*, s : LibLsquic::StreamT) do
|
||||||
|
|
||||||
stream_if_ctx
|
stream_if_ctx
|
||||||
end
|
end
|
||||||
stream_if.on_read = ->(s : LibLsquic::StreamT, stream_if_ctx : Void*) { pp "b"; stream_if_ctx }
|
|
||||||
stream_if.on_write = ->(s : LibLsquic::StreamT, stream_if_ctx : Void*) do
|
|
||||||
# TODO: Handle if ctx has written headers(?)
|
|
||||||
|
|
||||||
pp "c"
|
stream_if.on_read = ->(s : LibLsquic::StreamT, stream_if_ctx : Void*) do
|
||||||
|
buffer = Bytes.new(0x200)
|
||||||
# headers = HEADERS.map do |name, values|
|
bytes_read = LibLsquic.stream_read(s, buffer, buffer.size)
|
||||||
# value = values[0]
|
if bytes_read > 0
|
||||||
|
print String.new(buffer[0, bytes_read])
|
||||||
# name_vec = LibLsquic::Iovec.new
|
elsif bytes_read == 0
|
||||||
# name_vec.iov_base = name.to_slice
|
LibLsquic.stream_shutdown(s, 0)
|
||||||
# name_vec.iov_len = name.bytesize
|
# LibLsquic.stream_wantread(s, 0)
|
||||||
|
# LibLsquic.stream_close(s)
|
||||||
# value_vec = LibLsquic::Iovec.new
|
elsif LibLsquic.stream_is_rejected(s)
|
||||||
# value_vec.iov_base = value.to_slice
|
LibLsquic.stream_close(s)
|
||||||
# value_vec.iov_len = value.bytesize
|
else
|
||||||
|
raise "Could not read stream"
|
||||||
# header = LibLsquic::HttpHeader.new
|
end
|
||||||
# header.name = name_vec
|
|
||||||
# header.value = value_vec
|
|
||||||
|
|
||||||
# header
|
|
||||||
# end
|
|
||||||
|
|
||||||
# pp headers
|
|
||||||
|
|
||||||
# LibLsquic.stream_wantwrite(s, 0)
|
|
||||||
# LibLsquic.stream_wantread(s, 1)
|
|
||||||
# LibLsquic.stream_shutdown(s, 1)
|
|
||||||
|
|
||||||
stream_if_ctx
|
stream_if_ctx
|
||||||
end
|
end
|
||||||
stream_if.on_close = ->(s : LibLsquic::StreamT, stream_if_ctx : Void*) { stream_if_ctx }
|
|
||||||
|
stream_if.on_write = ->(s : LibLsquic::StreamT, stream_if_ctx : Void*) do
|
||||||
|
# TODO: Handle if ctx has written headers(?)
|
||||||
|
|
||||||
|
headers = HEADERS.map do |name, values|
|
||||||
|
value = values[0]
|
||||||
|
|
||||||
|
name_vec = LibLsquic::Iovec.new
|
||||||
|
name_vec.iov_base = name.to_slice
|
||||||
|
name_vec.iov_len = name.bytesize
|
||||||
|
|
||||||
|
value_vec = LibLsquic::Iovec.new
|
||||||
|
value_vec.iov_base = value.to_slice
|
||||||
|
value_vec.iov_len = value.bytesize
|
||||||
|
|
||||||
|
header = LibLsquic::HttpHeader.new
|
||||||
|
header.name = name_vec
|
||||||
|
header.value = value_vec
|
||||||
|
|
||||||
|
header
|
||||||
|
end
|
||||||
|
|
||||||
|
http_headers = LibLsquic::HttpHeaders.new
|
||||||
|
http_headers.count = headers.size
|
||||||
|
http_headers.headers = headers.to_unsafe
|
||||||
|
|
||||||
|
# For payload, last argument is 0
|
||||||
|
raise "Could not send headers" if LibLsquic.stream_send_headers(s, pointerof(http_headers), 1) != 0
|
||||||
|
|
||||||
|
LibLsquic.stream_shutdown(s, 1)
|
||||||
|
LibLsquic.stream_wantwrite(s, 0)
|
||||||
|
LibLsquic.stream_wantread(s, 1)
|
||||||
|
|
||||||
|
stream_if_ctx
|
||||||
|
end
|
||||||
|
|
||||||
|
stream_if.on_close = ->(s : LibLsquic::StreamT, stream_if_ctx : Void*) do
|
||||||
|
LibLsquic.conn_close(LibLsquic.stream_conn(s))
|
||||||
|
stream_if_ctx
|
||||||
|
end
|
||||||
|
|
||||||
engine_api = LibLsquic::EngineApi.new
|
engine_api = LibLsquic::EngineApi.new
|
||||||
engine_api.ea_settings = pointerof(engine_settings)
|
engine_api.ea_settings = pointerof(engine_settings)
|
||||||
engine_api.ea_stream_if = pointerof(stream_if)
|
engine_api.ea_stream_if = pointerof(stream_if)
|
||||||
engine_api.ea_stream_if_ctx = Box.box(IO::Memory.new) # TODO
|
engine_api.ea_stream_if_ctx = Box.box(IO::Memory.new) # TODO
|
||||||
# engine_api.ea_get_ssl_ctx = ->(peer_ctx : Void*) {}
|
# engine_api.ea_get_ssl_ctx = ->(peer_ctx : Void*) {}
|
||||||
|
|
||||||
engine_api.ea_packets_out = ->(peer_ctx : Void*, specs : LibLsquic::OutSpec*, count : LibC::UInt) do
|
engine_api.ea_packets_out = ->(peer_ctx : Void*, specs : LibLsquic::OutSpec*, count : LibC::UInt) do
|
||||||
count.times do |i|
|
count.times do |i|
|
||||||
spec = specs[i]
|
spec = specs[i]
|
||||||
|
@ -100,6 +127,7 @@ engine_api.ea_packets_out = ->(peer_ctx : Void*, specs : LibLsquic::OutSpec*, co
|
||||||
|
|
||||||
count.to_i32
|
count.to_i32
|
||||||
end
|
end
|
||||||
|
|
||||||
engine = LibLsquic.engine_new(engine_flags, pointerof(engine_api))
|
engine = LibLsquic.engine_new(engine_flags, pointerof(engine_api))
|
||||||
|
|
||||||
hostname = "www.youtube.com"
|
hostname = "www.youtube.com"
|
||||||
|
@ -130,16 +158,9 @@ loop do
|
||||||
|
|
||||||
if LibLsquic.engine_earliest_adv_tick(engine, out diff) == 0
|
if LibLsquic.engine_earliest_adv_tick(engine, out diff) == 0
|
||||||
break
|
break
|
||||||
else
|
|
||||||
sleep (diff / 1000000).seconds
|
|
||||||
sleep (diff % 1000000).nanoseconds
|
|
||||||
end
|
end
|
||||||
|
|
||||||
buffer = Bytes.new(1370)
|
buffer = Bytes.new(0x600)
|
||||||
bytes_read = buffer.size
|
bytes_read = peer_ctx.socket.read(buffer)
|
||||||
until bytes_read < buffer.size
|
LibLsquic.engine_packet_in(engine, buffer[0, bytes_read], bytes_read, peer_ctx.socket.local_address, peer_addr, Box.box(peer_ctx), 0)
|
||||||
bytes_read = peer_ctx.socket.read(buffer)
|
|
||||||
LibLsquic.engine_packet_in(engine, buffer, buffer.size, peer_ctx.socket.local_address, peer_addr, Box.box(peer_ctx), 0)
|
|
||||||
LibLsquic.engine_process_conns(engine)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -79,7 +79,7 @@ lib LibLsquic
|
||||||
|
|
||||||
struct HttpHeaders
|
struct HttpHeaders
|
||||||
count : LibC::Int
|
count : LibC::Int
|
||||||
headers : HttpHeaderT*
|
headers : HttpHeader*
|
||||||
end
|
end
|
||||||
|
|
||||||
struct HttpHeader
|
struct HttpHeader
|
||||||
|
@ -294,10 +294,10 @@ lib LibLsquic
|
||||||
|
|
||||||
fun stream_writef = lsquic_stream_writef(x0 : StreamT, x1 : Reader*) : SsizeT
|
fun stream_writef = lsquic_stream_writef(x0 : StreamT, x1 : Reader*) : SsizeT
|
||||||
fun stream_flush = lsquic_stream_flush(s : StreamT) : LibC::Int
|
fun stream_flush = lsquic_stream_flush(s : StreamT) : LibC::Int
|
||||||
fun stream_send_headers = lsquic_stream_send_headers(s : StreamT, h : HttpHeadersT*, eos : LibC::Int) : LibC::Int
|
fun stream_send_headers = lsquic_stream_send_headers(s : StreamT, h : HttpHeaders*, eos : LibC::Int) : LibC::Int
|
||||||
type HttpHeadersT = HttpHeaders
|
type HttpHeadersT = HttpHeaders
|
||||||
fun stream_get_hset = lsquic_stream_get_hset(x0 : StreamT) : Void*
|
fun stream_get_hset = lsquic_stream_get_hset(x0 : StreamT) : Void*
|
||||||
fun conn_push_stream = lsquic_conn_push_stream(c : ConnT, hdr_set : Void*, s : StreamT, url : Iovec*, authority : Iovec*, headers : HttpHeadersT*) : LibC::Int
|
fun conn_push_stream = lsquic_conn_push_stream(c : ConnT, hdr_set : Void*, s : StreamT, url : Iovec*, authority : Iovec*, headers : HttpHeaders*) : LibC::Int
|
||||||
fun conn_is_push_enabled = lsquic_conn_is_push_enabled(x0 : ConnT) : LibC::Int
|
fun conn_is_push_enabled = lsquic_conn_is_push_enabled(x0 : ConnT) : LibC::Int
|
||||||
fun stream_shutdown = lsquic_stream_shutdown(s : StreamT, how : LibC::Int) : LibC::Int
|
fun stream_shutdown = lsquic_stream_shutdown(s : StreamT, how : LibC::Int) : LibC::Int
|
||||||
fun stream_close = lsquic_stream_close(s : StreamT) : LibC::Int
|
fun stream_close = lsquic_stream_close(s : StreamT) : LibC::Int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue