mqtt 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/NEWS.md +27 -1
 - data/README.md +14 -5
 - data/lib/mqtt/client.rb +513 -478
 - data/lib/mqtt/openssl_fix.rb +29 -0
 - data/lib/mqtt/packet.rb +181 -234
 - data/lib/mqtt/proxy.rb +81 -85
 - data/lib/mqtt/sn/packet.rb +469 -512
 - data/lib/mqtt/version.rb +1 -1
 - data/lib/mqtt.rb +1 -8
 - data/spec/mqtt_client_spec.rb +173 -12
 - data/spec/mqtt_packet_spec.rb +10 -4
 - metadata +38 -11
 - data/lib/mqtt/patches/string_encoding.rb +0 -34
 
    
        data/lib/mqtt/proxy.rb
    CHANGED
    
    | 
         @@ -1,97 +1,94 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
               
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
              # Port to bind listening socket to
         
     | 
| 
       7 
     | 
    
         
            -
              attr_reader :local_port
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
              # Address of upstream server to send packets upstream to
         
     | 
| 
       10 
     | 
    
         
            -
              attr_reader :server_host
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
              # Port of upstream server to send packets upstream to.
         
     | 
| 
       13 
     | 
    
         
            -
              attr_reader :server_port
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
              # Time in seconds before disconnecting an idle connection
         
     | 
| 
       16 
     | 
    
         
            -
              attr_reader :select_timeout
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
              # Ruby Logger object to send informational messages to
         
     | 
| 
       19 
     | 
    
         
            -
              attr_reader :logger
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
              # Create a new MQTT Proxy instance.
         
     | 
| 
       22 
     | 
    
         
            -
              #
         
     | 
| 
       23 
     | 
    
         
            -
              # Possible argument keys:
         
     | 
| 
       24 
     | 
    
         
            -
              #
         
     | 
| 
       25 
     | 
    
         
            -
              #  :local_host      Address to bind listening socket to.
         
     | 
| 
       26 
     | 
    
         
            -
              #  :local_port      Port to bind listening socket to.
         
     | 
| 
       27 
     | 
    
         
            -
              #  :server_host     Address of upstream server to send packets upstream to.
         
     | 
| 
       28 
     | 
    
         
            -
              #  :server_port     Port of upstream server to send packets upstream to.
         
     | 
| 
       29 
     | 
    
         
            -
              #  :select_timeout  Time in seconds before disconnecting a connection.
         
     | 
| 
       30 
     | 
    
         
            -
              #  :logger          Ruby Logger object to send informational messages to.
         
     | 
| 
       31 
     | 
    
         
            -
              #
         
     | 
| 
       32 
     | 
    
         
            -
              # NOTE: be careful not to connect to yourself!
         
     | 
| 
       33 
     | 
    
         
            -
              def initialize(args={})
         
     | 
| 
       34 
     | 
    
         
            -
                @local_host = args[:local_host] || '0.0.0.0'
         
     | 
| 
       35 
     | 
    
         
            -
                @local_port = args[:local_port] || MQTT::DEFAULT_PORT
         
     | 
| 
       36 
     | 
    
         
            -
                @server_host = args[:server_host]
         
     | 
| 
       37 
     | 
    
         
            -
                @server_port = args[:server_port] || 18830
         
     | 
| 
       38 
     | 
    
         
            -
                @select_timeout = args[:select_timeout] || 60
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                # Setup a logger
         
     | 
| 
       41 
     | 
    
         
            -
                @logger = args[:logger]
         
     | 
| 
       42 
     | 
    
         
            -
                if @logger.nil?
         
     | 
| 
       43 
     | 
    
         
            -
                  @logger = Logger.new(STDOUT)
         
     | 
| 
       44 
     | 
    
         
            -
                  @logger.level = Logger::INFO
         
     | 
| 
       45 
     | 
    
         
            -
                end
         
     | 
| 
      
 1 
     | 
    
         
            +
            module MQTT
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Class for implementing a proxy to filter/mangle MQTT packets.
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Proxy
         
     | 
| 
      
 4 
     | 
    
         
            +
                # Address to bind listening socket to
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :local_host
         
     | 
| 
       46 
6 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
                #  
     | 
| 
       48 
     | 
    
         
            -
                 
     | 
| 
       49 
     | 
    
         
            -
                @server_filter = nil
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Port to bind listening socket to
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :local_port
         
     | 
| 
       50 
9 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                #  
     | 
| 
       52 
     | 
    
         
            -
                 
     | 
| 
       53 
     | 
    
         
            -
                @logger.info "MQTT::Proxy listening on #{@local_host}:#{@local_port}"
         
     | 
| 
       54 
     | 
    
         
            -
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
                # Address of upstream server to send packets upstream to
         
     | 
| 
      
 11 
     | 
    
         
            +
                attr_reader :server_host
         
     | 
| 
       55 
12 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                @client_filter = proc
         
     | 
| 
       59 
     | 
    
         
            -
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
                # Port of upstream server to send packets upstream to.
         
     | 
| 
      
 14 
     | 
    
         
            +
                attr_reader :server_port
         
     | 
| 
       60 
15 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Time in seconds before disconnecting an idle connection
         
     | 
| 
      
 17 
     | 
    
         
            +
                attr_reader :select_timeout
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # Ruby Logger object to send informational messages to
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_reader :logger
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # A filter Proc for packets coming from the client (to the server).
         
     | 
| 
      
 23 
     | 
    
         
            +
                attr_writer :client_filter
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                # A filter Proc for packets coming from the server (to the client).
         
     | 
| 
      
 26 
     | 
    
         
            +
                attr_writer :server_filter
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                # Create a new MQTT Proxy instance.
         
     | 
| 
      
 29 
     | 
    
         
            +
                #
         
     | 
| 
      
 30 
     | 
    
         
            +
                # Possible argument keys:
         
     | 
| 
      
 31 
     | 
    
         
            +
                #
         
     | 
| 
      
 32 
     | 
    
         
            +
                #  :local_host      Address to bind listening socket to.
         
     | 
| 
      
 33 
     | 
    
         
            +
                #  :local_port      Port to bind listening socket to.
         
     | 
| 
      
 34 
     | 
    
         
            +
                #  :server_host     Address of upstream server to send packets upstream to.
         
     | 
| 
      
 35 
     | 
    
         
            +
                #  :server_port     Port of upstream server to send packets upstream to.
         
     | 
| 
      
 36 
     | 
    
         
            +
                #  :select_timeout  Time in seconds before disconnecting a connection.
         
     | 
| 
      
 37 
     | 
    
         
            +
                #  :logger          Ruby Logger object to send informational messages to.
         
     | 
| 
      
 38 
     | 
    
         
            +
                #
         
     | 
| 
      
 39 
     | 
    
         
            +
                # NOTE: be careful not to connect to yourself!
         
     | 
| 
      
 40 
     | 
    
         
            +
                def initialize(args = {})
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @local_host = args[:local_host] || '0.0.0.0'
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @local_port = args[:local_port] || MQTT::DEFAULT_PORT
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @server_host = args[:server_host]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @server_port = args[:server_port] || 18_830
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @select_timeout = args[:select_timeout] || 60
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  # Setup a logger
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @logger = args[:logger]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  if @logger.nil?
         
     | 
| 
      
 50 
     | 
    
         
            +
                    @logger = Logger.new(STDOUT)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @logger.level = Logger::INFO
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  # Default is not to have any filters
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @client_filter = nil
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @server_filter = nil
         
     | 
| 
       65 
57 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                     
     | 
| 
       76 
     | 
    
         
            -
                      logger. 
     | 
| 
      
 58 
     | 
    
         
            +
                  # Create TCP server socket
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @server = TCPServer.open(@local_host, @local_port)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @logger.info "MQTT::Proxy listening on #{@local_host}:#{@local_port}"
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                # Start accepting connections and processing packets.
         
     | 
| 
      
 64 
     | 
    
         
            +
                def run
         
     | 
| 
      
 65 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 66 
     | 
    
         
            +
                    # Wait for a client to connect and then create a thread for it
         
     | 
| 
      
 67 
     | 
    
         
            +
                    Thread.new(@server.accept) do |client_socket|
         
     | 
| 
      
 68 
     | 
    
         
            +
                      logger.info "Accepted client: #{client_socket.peeraddr.join(':')}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                      server_socket = TCPSocket.new(@server_host, @server_port)
         
     | 
| 
      
 70 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 71 
     | 
    
         
            +
                        process_packets(client_socket, server_socket)
         
     | 
| 
      
 72 
     | 
    
         
            +
                      rescue Exception => exp
         
     | 
| 
      
 73 
     | 
    
         
            +
                        logger.error exp.to_s
         
     | 
| 
      
 74 
     | 
    
         
            +
                      end
         
     | 
| 
      
 75 
     | 
    
         
            +
                      logger.info "Disconnected: #{client_socket.peeraddr.join(':')}"
         
     | 
| 
      
 76 
     | 
    
         
            +
                      server_socket.close
         
     | 
| 
      
 77 
     | 
    
         
            +
                      client_socket.close
         
     | 
| 
       77 
78 
     | 
    
         
             
                    end
         
     | 
| 
       78 
     | 
    
         
            -
                    logger.info "Disconnected: #{client_socket.peeraddr.join(':')}"
         
     | 
| 
       79 
     | 
    
         
            -
                    server_socket.close
         
     | 
| 
       80 
     | 
    
         
            -
                    client_socket.close
         
     | 
| 
       81 
79 
     | 
    
         
             
                  end
         
     | 
| 
       82 
80 
     | 
    
         
             
                end
         
     | 
| 
       83 
     | 
    
         
            -
              end
         
     | 
| 
       84 
81 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
                private
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def process_packets(client_socket, server_socket)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 86 
     | 
    
         
            +
                    # Wait for some data on either socket
         
     | 
| 
      
 87 
     | 
    
         
            +
                    selected = IO.select([client_socket, server_socket], nil, nil, @select_timeout)
         
     | 
| 
       86 
88 
     | 
    
         | 
| 
       87 
     | 
    
         
            -
              def process_packets(client_socket,server_socket)
         
     | 
| 
       88 
     | 
    
         
            -
                loop do
         
     | 
| 
       89 
     | 
    
         
            -
                  # Wait for some data on either socket
         
     | 
| 
       90 
     | 
    
         
            -
                  selected = IO.select([client_socket,server_socket], nil, nil, @select_timeout)
         
     | 
| 
       91 
     | 
    
         
            -
                  if selected.nil?
         
     | 
| 
       92 
89 
     | 
    
         
             
                    # Timeout
         
     | 
| 
       93 
     | 
    
         
            -
                    raise  
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
      
 90 
     | 
    
         
            +
                    raise 'Timeout in select' if selected.nil?
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
       95 
92 
     | 
    
         
             
                    # Iterate through each of the sockets with data to read
         
     | 
| 
       96 
93 
     | 
    
         
             
                    if selected[0].include?(client_socket)
         
     | 
| 
       97 
94 
     | 
    
         
             
                      packet = MQTT::Packet.read(client_socket)
         
     | 
| 
         @@ -110,10 +107,9 @@ class MQTT::Proxy 
     | 
|
| 
       110 
107 
     | 
    
         
             
                        logger.debug "<#{packet.type_name}> -> client"
         
     | 
| 
       111 
108 
     | 
    
         
             
                      end
         
     | 
| 
       112 
109 
     | 
    
         
             
                    else
         
     | 
| 
       113 
     | 
    
         
            -
                      logger.error  
     | 
| 
      
 110 
     | 
    
         
            +
                      logger.error 'Problem with select: socket is neither server or client'
         
     | 
| 
       114 
111 
     | 
    
         
             
                    end
         
     | 
| 
       115 
112 
     | 
    
         
             
                  end
         
     | 
| 
       116 
113 
     | 
    
         
             
                end
         
     | 
| 
       117 
114 
     | 
    
         
             
              end
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
115 
     | 
    
         
             
            end
         
     |