Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 84 lines (64 sloc) 1.579 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
require "socket"
require "warden/protocol"

module Warden

  class Client

    class Error < StandardError; end
    class ServerError < Error; end

    attr_reader :path

    def initialize(path)
      @path = path
    end

    def connected?
      !@sock.nil?
    end

    def connect
      raise "already connected" if connected?
      @sock = ::UNIXSocket.new(path)
    end

    def disconnect
      raise "not connected" unless connected?
      @sock.close rescue nil
      @sock = nil
    end

    def reconnect
      disconnect if connected?
      connect
    end

    def io
      rv = yield
      if rv.nil?
        disconnect
        raise ::EOFError
      end

      rv
    end

    def read
      length = io { @sock.gets }
      data = io { @sock.read(length.to_i) }

      # Discard \r\n
      io { @sock.read(2) }

      wrapped_response = Warden::Protocol::WrappedResponse.decode(data)
      response = wrapped_response.response

      # Raise error replies
      if response.is_a?(Warden::Protocol::ErrorResponse)
        raise Warden::Client::ServerError.new(response.message)
      end

      response
    end

    def write(request)
      data = request.wrap.encode.to_s
      @sock.write data.length.to_s + "\r\n"
      @sock.write data + "\r\n"
    end

    def call(request)
      write(request)
      read
    end

    def method_missing(sym, *args, &blk)
      klass_name = sym.to_s.gsub(/(^|_)([a-z])/) { $2.upcase }
      klass_name += "Request"
      klass = Warden::Protocol.const_get(klass_name)

      call(klass.new(*args))
    end
  end
end
Something went wrong with that request. Please try again.