Sha256: 8658d45e5b458906290a5a11f1d6b36eb54110c249065d0495df65fd249e428a

Contents?: true

Size: 1.52 KB

Versions: 7

Compression:

Stored size: 1.52 KB

Contents

# frozen_string_literal: true

require 'polyphony'
require_relative './tipi/http1_adapter'
require_relative './tipi/http2_adapter'
require_relative './tipi/configuration'

module Tipi
  ALPN_PROTOCOLS = %w[h2 http/1.1].freeze
  H2_PROTOCOL = 'h2'
  
  class << self
    def serve(host, port, opts = {}, &handler)
      opts[:alpn_protocols] = ALPN_PROTOCOLS
      server = Polyphony::Net.tcp_listen(host, port, opts)
      accept_loop(server, opts, &handler)
    ensure
      server&.close
    end
    
    def listen(host, port, opts = {})
      opts[:alpn_protocols] = ALPN_PROTOCOLS
      Polyphony::Net.tcp_listen(host, port, opts).tap do |socket|
        socket.define_singleton_method(:each) do |&block|
          ::Tipi.accept_loop(socket, opts, &block)
        end
      end
    end
    
    def accept_loop(server, opts, &handler)
      server.accept_loop do |client|
        spin { client_loop(client, opts, &handler) }
      rescue OpenSSL::SSL::SSLError
        # disregard
      end
    end
    
    def client_loop(client, opts, &handler)
      client.no_delay if client.respond_to?(:no_delay)
      adapter = protocol_adapter(client, opts)
      adapter.each(&handler)
    ensure
      client.close rescue nil
    end
    
    def protocol_adapter(socket, opts)
      use_http2 = socket.respond_to?(:alpn_protocol) &&
                  socket.alpn_protocol == H2_PROTOCOL
      klass = use_http2 ? HTTP2Adapter : HTTP1Adapter
      klass.new(socket, opts)
    end

    def route(&block)
      proc { |req| req.route(&block) }
    end
  end
end

Version data entries

7 entries across 7 versions & 1 rubygems

Version Path
tipi-0.39 lib/tipi.rb
tipi-0.38 lib/tipi.rb
tipi-0.37.2 lib/tipi.rb
tipi-0.37.1 lib/tipi.rb
tipi-0.37 lib/tipi.rb
tipi-0.36 lib/tipi.rb
tipi-0.35 lib/tipi.rb