8000 Fix Server implementation and add more tests. · zarqman/async-websocket@0faee70 · GitHub < 10000 /head>
[go: up one dir, main page]

Skip to content

Commit 0faee70

Browse files
committed
Fix Server implementation and add more tests.
1 parent 8546d08 commit 0faee70

File tree

4 files changed

+115
-104
lines changed
  • test/async/websocket
  • 4 files changed

    +115
    -104
    lines changed

    lib/async/websocket/server.rb

    Lines changed: 4 additions & 26 deletions
    Original file line numberDiff line numberDiff line change
    @@ -13,37 +13,15 @@ module WebSocket
    1313
    class Server < ::Protocol::HTTP::Middleware
    1414
    include ::Protocol::WebSocket::Headers
    1515

    16-
    def initialize(delegate, protocols: [], handler: Connection)
    16+
    def initialize(delegate, **options, &block)
    1717
    super(delegate)
    1818

    19-
    @protocols = protocols
    20-
    @handler = handler
    21-
    end
    22-
    23-
    def select_protocol(request)
    24-
    if requested_protocol = request.headers[SEC_WEBSOCKET_PROTOCOL]
    25-
    return (requested_protocol & @protocols).first
    26-
    end
    27-
    end
    28-
    29-
    def response(request)
    19+
    @options = options
    20+
    @block = block
    3021
    end
    3122

    3223
    def call(request)
    33-
    if request.protocol == PROTOCOL
    34-
    # Select websocket sub-protocol:
    35-
    protocol = select_protocol(request)
    36-
    37-
    # request.headers = nil
    38-
    39-
    Response.for(request, headers, protocol: protocol, **options) do |stream|
    40-
    framer = Protocol::WebSocket::Framer.new(stream)
    41-
    42-
    yield handler.call(framer, protocol)
    43-
    end
    44-
    else
    45-
    super
    46-
    end
    24+
    Async::WebSocket::Adapters::HTTP.open(request, **@options, &@block) or super
    4725
    end
    4826
    end
    4927
    end

    test/async/websocket/adapters/rack.rb

    Lines changed: 36 additions & 29 deletions
    Original file line numberDiff line numberDiff line change
    @@ -9,42 +9,49 @@
    99
    require 'rack_application'
    1010

    1111
    describe Async::WebSocket::Adapters::Rack do
    12-
    include RackApplication
    13-
    14-
    it "can make non-websocket connection to server" do
    15-
    response = client.get("/")
    16-
    17-
    expect(response).to be(:success?)
    18-
    expect(response.read).to be == "Hello World"
    19-
    20-
    client.close
    21-
    end
    22-
    23-
    let(:message) do
    24-
    Protocol::WebSocket::JSONMessage.generate({text: "Hello World"})
    12+
    it "can determine whether a rack env is a websocket request" do
    13+
    expect(Async::WebSocket::Adapters::Rack.websocket?(Rack::MockRequest.env_for("/"))).to be == false
    14+
    expect(Async::WebSocket::Adapters::Rack.websocket?(Rack::MockRequest.env_for("/", 'HTTP_CONNECTION' => 'upgrade', 'HTTP_UPGRADE' => 'websocket'))).to be == true
    2515
    end
    2616

    27-
    it "can make websocket connection to server" do
    28-
    Async::WebSocket::Client.connect(client_endpoint) do |connection|
    29-
    connection.write(message)
    17+
    with 'rack application' do
    18+
    include RackApplication
    19+
    20+
    it "can make non-websocket connection to server" do
    21+
    response = client.get("/")
    3022

    31-
    expect(connection.read).to be == message
    23+
    expect(response).to be(:success?)
    24+
    expect(response.read).to be == "Hello World"
    3225

    33-
    connection.close
    26+
    client.close
    3427
    end
    35-
    end
    36-
    37-
    it "should use mask over insecure connection" do
    38-
    expect(endpoint).not.to be(:secure?)
    3928

    40-
    Async::WebSocket::Client.connect(client_endpoint) do |connection|
    41-
    expect(connection.mask).not.to be_nil
    29+
    let(:message) do
    30+
    Protocol::WebSocket::JSONMessage.generate({text: "Hello World"})
    4231
    end
    43-
    end
    44-
    45-
    it "should negotiate protocol" do
    46-
    Async::WebSocket::Client.connect(client_endpoint, protocols: ['ws']) do |connection|
    47-
    expect(connection.protocol).to be == 'ws'
    32+
    33+
    it "can make websocket connection to server" do
    34+
    Async::WebSocket::Client.connect(client_endpoint) do |connection|
    35+
    connection.write(message)
    36+
    37+
    expect(connection.read).to be == message
    38+
    39+
    connection.close
    40+
    end
    41+
    end
    42+
    43+
    it "should use mask over insecure connection" do
    44+
    expect(endpoint).not.to be(:secure?)
    45+
    46+
    Async::WebSocket::Client.connect(client_endpoint) do |connection|
    47+
    expect(connection.mask).not.to be_nil
    48+
    end
    49+
    end
    50+
    51+
    it "should negotiate protocol" do
    52+
    Async::WebSocket::Client.connect(client_endpoint, protocols: ['ws']) do |connection|
    53+
    expect(connection.protocol).to be == 'ws'
    54+
    end
    4855
    end
    4956
    end
    5057
    end

    test/async/websocket/client.rb

    Lines changed: 7 additions & 7 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,8 +1,6 @@
    11

    22

    33
    ClientExamples = Sus::Shared("a websocket client") do
    4-
    include Sus::Fixtures::Async::HTTP::ServerContext
    5-
    64
    let(:app) do
    75
    Protocol::HTTP::Middleware.for do |request|
    86
    Async::WebSocket::Adapters::HTTP.open(request) do |connection|
    @@ -15,8 +13,6 @@
    1513
    end
    1614
    end
    1715

    18-
    let(:timeout) {nil}
    19-
    2016
    it "can connect to a websocket server and close underlying client" do
    2117
    Async do |task|
    2218
    connection = Async::WebSocket::Client.connect(client_endpoint)
    @@ -31,11 +27,15 @@
    3127
    end
    3228

    3329
    describe Async::WebSocket::Client do
    34-
    with "http/1", protocol: Async::HTTP::Protocol::HTTP1 do
    30+
    include Sus::Fixtures::Async::HTTP::ServerContext
    31+
    32+
    with 'http/1' do
    33+
    let(:protocol) {Async::HTTP::Protocol::HTTP1}
    3534
    it_behaves_like ClientExamples
    3635
    end
    37-
    38-
    with "http/2", protocol: Async::HTTP::Protocol::HTTP2 do
    36+
    37+
    with 'http/2' do
    38+
    let(:protocol) {Async::HTTP::Protocol::HTTP2}
    3939
    it_behaves_like ClientExamples
    4040
    end
    4141
    end

    test/async/websocket/server.rb

    Lines changed: 68 additions & 42 deletions
    Original file line numberDiff line numberDiff line change
    @@ -4,6 +4,7 @@
    44
    # Copyright, 2022, by Samuel Williams.
    55

    66
    require 'protocol/websocket/json_message'
    7+
    require 'protocol/http/middleware/builder'
    78

    89
    require 'async/websocket/client'
    910
    require 'async/websocket/server'
    @@ -12,54 +13,77 @@
    1213
    require 'sus/fixtures/async/http/server_context'
    1314

    1415
    ServerExamples = Sus::Shared('a websocket server') do
    15-
    include Sus::Fixtures::Async::HTTP::ServerContext
    16-
    17-
    let(:message) {"Hello World"}
    18-
    19-
    let(:app) do
    20-
    Protocol::HTTP::Middleware.for do |request|
    21-
    Async::WebSocket::Adapters::HTTP.open(request) do |connection|
    22-
    connection.send_text(message)
    23-
    connection.close
    24-
    end or Protocol::HTTP::Response[404, {}, []]
    25-
    end
    26-
    end
    27-
    2816
    let(:websocket_client) {Async::WebSocket::Client.open(client_endpoint)}
    2917

    30-
    it "can establish connection" do
    31-
    connection = websocket_client.connect(endpoint.authority, "/server")
    32-
    33-
    begin
    34-
    expect(connection.read).to be == message
    35-
    expect(connection.read).to be_nil
    36-
    expect(connection).to be(:closed?)
    37-
    ensure
    38-
    connection.close
    39-
    end
    40-
    end
    41-
    42-
    with "headers" do
    43-
    let(:headers) {{"foo" => "bar"}}
    18+
    with 'generic application' do
    19+
    let(:message) {"Hello World"}
    4420

    4521
    let(:app) do
    4622
    Protocol::HTTP::Middleware.for do |request|
    4723
    Async::WebSocket::Adapters::HTTP.open(request) do |connection|
    48-
    message = Protocol::WebSocket::JSONMessage.generate(request.headers.fields)
    49-
    message.send(connection)
    50-
    24+
    connection.send_text(message)
    5125
    connection.close
    5226
    end or Protocol::HTTP::Response[404, {}, []]
    5327
    end
    5428
    end
    5529

    56-
    it "can send headers" do
    57-
    connection = websocket_client.connect(endpoint.authority, "/headers", headers: headers)
    30+
    it "can establish connection" do
    31+
    connection = websocket_client.connect(endpoint.authority, "/server")
    5832

    5933
    begin
    60-
    json_message = Protocol::WebSocket::JSONMessage.wrap(connection.read)
    34+
    expect(connection.read).to be == message
    35+
    expect(connection.read).to be_nil
    36+
    expect(connection).to be(:closed?)
    37+
    ensure
    38+
    connection.close
    39+
    end
    40+
    end
    41+
    42+
    with "headers" do
    43+
    let(:headers) {{"foo" => "bar"}}
    44+
    45+
    let(:app) do
    46+
    Protocol::HTTP::Middleware.for do |request|
    47+
    Async::WebSocket::Adapters::HTTP.open(request) do |connection|
    48+
    message = Protocol::WebSocket::JSONMessage.generate(request.headers.fields)
    49+
    message.send(connection)
    50+
    51+
    connection.close
    52+
    end or Protocol::HTTP::Response[404, {}, []]
    53+
    end
    54+
    end
    55+
    56+
    it "can send headers" do
    57+
    connection = websocket_client.connect(endpoint.authority, "/headers", headers: headers)
    6158

    62-
    expect(json_message.to_h).to have_keys(*headers.keys)
    59+
    begin
    60+
    json_message = Protocol::WebSocket::JSONMessage.wrap(connection.read)
    61+
    62+
    expect(json_message.to_h).to have_keys(*headers.keys)
    63+
    expect(connection.read).to be_nil
    64+
    expect(connection).to be(:closed?)
    65+
    ensure
    66+
    connection.close
    67+
    end
    68+
    end
    69+
    end
    70+
    end
    71+
    72+
    with 'server middleware' do
    73+
    let(:app) do
    74+
    Protocol::HTTP::Middleware.build do
    75+
    use Async::WebSocket::Server do |connection|
    76+
    connection.send_text("Hello World")
    77+
    connection.close
    78+
    end
    79+
    end
    80+
    end
    81+
    82+
    it "can establish connection" do
    83+
    connection = websocket_client.connect(endpoint.authority, "/server")
    84+
    85+
    begin
    86+
    expect(connection.read).to be == "Hello World"
    6387
    expect(connection.read).to be_nil
    6488
    expect(connection).to be(:closed?)
    6589
    ensure
    @@ -69,14 +93,16 @@
    6993
    end
    7094
    end
    7195

    72-
    describe Async::HTTP::Protocol::HTTP1 do
    73-
    let(:protocol) {subject}
    96+
    describe Async::WebSocket::Server do
    97+
    include Sus::Fixtures::Async::HTTP::ServerContext
    7498

    75-
    it_behaves_like ServerExamples
    76-
    end
    77-
    78-
    describe Async::HTTP::Protocol::HTTP2 do
    79-
    let(:protocol) {subject}
    99+
    with 'http/1' do
    100+
    let(:protocol) {Async::HTTP::Protocol::HTTP1}
    101+
    it_behaves_like ServerExamples
    102+
    end
    80103

    81-
    it_behaves_like ServerExamples
    104+
    with 'http/2' do
    105+
    let(:protocol) {Async::HTTP::Protocol::HTTP2}
    106+
    it_behaves_like ServerExamples
    107+
    end
    82108
    end

    0 commit comments

    Comments
     (0)
    0