class Puma::MiniSSL::Socket - puma-3.11.4 Documentation

# class Puma::MiniSSL::Socket

### Public Class Methods

new(socket, engine) click to toggle source

    # File lib/puma/minissl.rb, line 9
    def initialize(socket, engine)
      @socket = socket
      @engine = engine
      @peercert = nil
    end

### Public Instance Methods

<<(data)
Alias for: write
close() click to toggle source

    # File lib/puma/minissl.rb, line 138
    def close
      begin
        # Read any drop any partially initialized sockets and any received bytes during shutdown.
        # Don't let this socket hold this loop forever.
        # If it can't send more packets within 1s, then give up.
        while should_drop_bytes?
          return if read_and_drop(1) == :timeout
        end
      rescue IOError, SystemCallError
        Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
        # nothing
      ensure
        @socket.close
      end
    end

closed?() click to toggle source

    # File lib/puma/minissl.rb, line 19
    def closed?
      @socket.closed?
    end

engine_read_all() click to toggle source

    # File lib/puma/minissl.rb, line 40
    def engine_read_all
      output = @engine.read
      while output and additional_output = @engine.read
        output << additional_output
      end
      output
    end

flush() click to toggle source

    # File lib/puma/minissl.rb, line 121
    def flush
      @socket.flush
    end

peeraddr() click to toggle source

    # File lib/puma/minissl.rb, line 154
    def peeraddr
      @socket.peeraddr
    end

peercert() click to toggle source

    # File lib/puma/minissl.rb, line 158
    def peercert
      return @peercert if @peercert

      raw = @engine.peercert
      return nil unless raw

      @peercert = OpenSSL::X509::Certificate.new raw
    end

read_and_drop(timeout = 1) click to toggle source

    # File lib/puma/minissl.rb, line 125
    def read_and_drop(timeout = 1)
      return :timeout unless IO.select([@socket], nil, nil, timeout)
      read_nonblock(1024)
      :drop
    rescue Errno::EAGAIN
      # do nothing
      :eagain
    end

read_nonblock(size, *_) click to toggle source

    # File lib/puma/minissl.rb, line 48
    def read_nonblock(size, *_)
      # *_ is to deal with keyword args that were added
      # at some point (and being used in the wild)
      while true
        output = engine_read_all
        return output if output

        begin
          data = @socket.read_nonblock(size, exception: false)
          if data == :wait_readable || data == :wait_writable
            if @socket.to_io.respond_to?(data)
              @socket.to_io.__send__(data)
            elsif data == :wait_readable
              IO.select([@socket.to_io])
            else
              IO.select(nil, [@socket.to_io])
            end
          elsif !data
            return nil
          else
            break
          end
        end while true

        @engine.inject(data)
        output = engine_read_all

        return output if output

        while neg_data = @engine.extract
          @socket.write neg_data
        end
      end
    end

readpartial(size) click to toggle source

    # File lib/puma/minissl.rb, line 23
    def readpartial(size)
      while true
        output = @engine.read
        return output if output

        data = @socket.readpartial(size)
        @engine.inject(data)
        output = @engine.read

        return output if output

        while neg_data = @engine.extract
          @socket.write neg_data
        end
      end
    end

should_drop_bytes?() click to toggle source

    # File lib/puma/minissl.rb, line 134
    def should_drop_bytes?
      @engine.init? || !@engine.shutdown
    end

syswrite(data)
Alias for: write
to_io() click to toggle source

    # File lib/puma/minissl.rb, line 15
    def to_io
      @socket
    end

write(data) click to toggle source

    # File lib/puma/minissl.rb, line 83
    def write(data)
      return 0 if data.empty?

      need = data.bytesize

      while true
        wrote = @engine.write data
        enc = @engine.extract

        while enc
          @socket.write enc
          enc = @engine.extract
        end

        need -= wrote

        return data.bytesize if need == 0

        data = data[wrote..-1]
      end
    end

Also aliased as: syswrite, <<
write_nonblock(data, *_) click to toggle source

This is a temporary fix to deal with websockets code using write_nonblock. The problem with implementing it properly is that it means we'd have to have the ability to rewind an engine because after we write+extract, the socket #write_nonblock call might raise an exception and later code would pass the same data in, but the engine would think it had already written the data in. So for the time being (and since write blocking is quite rare), go ahead and actually block in write_nonblock.

    # File lib/puma/minissl.rb, line 117
    def write_nonblock(data, *_)
      write data
    end