Class: OpenC3::HttpServerInterface

Inherits:
Interface show all
Defined in:
lib/openc3/interfaces/http_server_interface.rb

Constant Summary

Constants included from Api

Api::DELAY_METRICS, Api::DURATION_METRICS, Api::SUBSCRIPTION_DELIMITER, Api::SUM_METRICS

Constants included from ApiShared

ApiShared::DEFAULT_TLM_POLLING_RATE

Constants included from Extract

Extract::SCANNING_REGULAR_EXPRESSION

Instance Attribute Summary

Attributes inherited from Interface

#auto_reconnect, #bytes_read, #bytes_written, #cmd_routers, #cmd_target_names, #config_params, #connect_on_startup, #disable_disconnect, #interfaces, #name, #num_clients, #options, #packet_log_writer_pairs, #protocol_info, #read_count, #read_protocols, #read_queue_size, #read_raw_data, #read_raw_data_time, #reconnect_delay, #routers, #scheduler, #secrets, #state, #stored_packet_log_writer_pairs, #stream_log_pair, #target_names, #tlm_target_names, #write_count, #write_protocols, #write_queue_size, #written_raw_data, #written_raw_data_time

Instance Method Summary collapse

Methods inherited from Interface

#_write, #add_protocol, #as_json, #copy_to, #interface_cmd, #protocol_cmd, #read, #read_allowed?, #read_interface_base, #start_raw_logging, #stop_raw_logging, #write, #write_allowed?, #write_interface_base, #write_raw, #write_raw_allowed?

Methods included from Api

#_build_cmd_output_string, #_cmd_implementation, #_extract_target_command_names, #_extract_target_command_parameter_names, #_extract_target_packet_item_names, #_extract_target_packet_names, #_get_and_set_cmd, #_get_item, #_limits_group, #_set_tlm_process_args, #_tlm_process_args, #_validate_tlm_type, #build_cmd, #cmd, #cmd_no_checks, #cmd_no_hazardous_check, #cmd_no_range_check, #cmd_raw, #cmd_raw_no_checks, #cmd_raw_no_hazardous_check, #cmd_raw_no_range_check, #config_tool_names, #connect_interface, #connect_router, #delete_config, #disable_cmd, #disable_limits, #disable_limits_group, #disconnect_interface, #disconnect_router, #enable_cmd, #enable_limits, #enable_limits_group, #get_all_cmd_names, #get_all_cmds, #get_all_interface_info, #get_all_router_info, #get_all_settings, #get_all_target_info, #get_all_tlm, #get_all_tlm_names, #get_cmd, #get_cmd_buffer, #get_cmd_cnt, #get_cmd_cnts, #get_cmd_hazardous, #get_cmd_time, #get_cmd_value, #get_interface, #get_interface_names, #get_item, #get_limits, #get_limits_events, #get_limits_groups, #get_limits_set, #get_limits_sets, #get_metrics, #get_out_of_limits, #get_overall_limits_state, #get_overrides, #get_packet_derived_items, #get_packets, #get_param, #get_router, #get_router_names, #get_setting, #get_settings, #get_target, #get_target_interfaces, #get_target_names, #get_tlm, #get_tlm_buffer, #get_tlm_cnt, #get_tlm_cnts, #get_tlm_packet, #get_tlm_values, #inject_tlm, #interface_cmd, #interface_protocol_cmd, #limits_enabled?, #list_configs, #list_settings, #load_config, #map_target_to_interface, #normalize_tlm, #offline_access_needed, #override_tlm, #router_cmd, #router_protocol_cmd, #save_config, #send_raw, #set_limits, #set_limits_set, #set_offline_access, #set_setting, #set_tlm, #start_raw_logging_interface, #start_raw_logging_router, #stash_all, #stash_delete, #stash_get, #stash_keys, #stash_set, #stop_raw_logging_interface, #stop_raw_logging_router, #subscribe_packets, #tlm, #tlm_formatted, #tlm_raw, #tlm_variable, #tlm_with_units

Constructor Details

#initialize(port = 80) ⇒ HttpServerInterface

Returns a new instance of HttpServerInterface.

Parameters:

  • port (Integer) (defaults to: 80)

    HTTP port



27
28
29
30
31
32
33
# File 'lib/openc3/interfaces/http_server_interface.rb', line 27

def initialize(port = 80)
  super()
  @listen_address = '0.0.0.0' # Default to ANY
  @port = Integer(port)
  @server = nil
  @request_queue = Queue.new
end

Instance Method Details

#connectObject

Connects the interface to its target(s)



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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/openc3/interfaces/http_server_interface.rb', line 51

def connect
  @server = WEBrick::HTTPServer.new(:BindAddress => @listen_address, :Port => @port)
  @request_queue = Queue.new

  # Create a response hook for every command packet
  @target_names.each do |target_name|
    System.commands.packets(target_name).each do |packet_name, packet|
      packet.restore_defaults
      path = nil
      begin
        path = packet.read('HTTP_PATH')
      rescue => e
        # No HTTP_PATH is an error
        Logger.error("HttpServerInterface Packet #{target_name} #{packet_name} unable to read HTTP_PATH\n#{e.formatted}")
      end
      if path
        @server.mount_proc path do |req, res|
          # Build the Response
          begin
            status = packet.read('HTTP_STATUS')
            if status
              res.status = status
            end
          rescue
            # No HTTP_STATUS - Leave at default
          end

          # http_accessor stores all the pseudo-derived HTTP configuration in extra
          if packet.extra
            headers = packet.extra['HTTP_HEADERS']
            if headers
              headers.each do |key, value|
                res[key] = value
              end
            end
          end

          res.body = packet.buffer

          # Save the Request
          packet_name = nil
          begin
            packet_name = packet.read('HTTP_PACKET')
          rescue
            # No packet name means dont save the request as telemetry
          end
          if packet_name
            data = req.body.to_s.dup # Dup to remove frozen
            extra = {}
            extra['HTTP_REQUEST_TARGET_NAME'] = target_name
            extra['HTTP_REQUEST_PACKET_NAME'] = packet_name

            headers = req.header
            if headers
              extra['HTTP_HEADERS'] = {}
              headers.each do |key, value|
                extra['HTTP_HEADERS'][key.downcase] = value
              end
            end

            queries = req.query
            if queries
              extra['HTTP_QUERIES'] = {}
              queries.each do |key, value|
                extra['HTTP_QUERIES'][key] = value
              end
            end

            @request_queue << [data, extra]
          end
        end
      end
    end
  end

  super()

  Thread.new do
    # This blocks, but will be unblocked by server.shutdown called in disconnect()
    @server.start
  end
end

#connected?Boolean

Returns:

  • (Boolean)


134
135
136
137
138
139
140
# File 'lib/openc3/interfaces/http_server_interface.rb', line 134

def connected?
  if @server
    return true
  else
    return false
  end
end

#connection_stringObject



46
47
48
# File 'lib/openc3/interfaces/http_server_interface.rb', line 46

def connection_string
  return "listening on #{@listen_address}:#{@port}"
end

#convert_data_to_packet(data, extra = nil) ⇒ Packet

Called to convert the read data into a OpenC3 Packet object

Parameters:

  • data (String)

    Raw packet data

Returns:

  • (Packet)

    OpenC3 Packet with buffer filled with data



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/openc3/interfaces/http_server_interface.rb', line 173

def convert_data_to_packet(data, extra = nil)
  packet = Packet.new(nil, nil, :BIG_ENDIAN, nil, data.to_s)
  packet.accessor = HttpAccessor.new(packet)
  if extra
    # Identify the response
    request_target_name = extra['HTTP_REQUEST_TARGET_NAME']
    request_packet_name = extra['HTTP_REQUEST_PACKET_NAME']
    if request_target_name and request_packet_name
      packet.target_name = request_target_name.to_s.upcase
      packet.packet_name = request_packet_name.to_s.upcase
    end
    extra.delete("HTTP_REQUEST_TARGET_NAME")
    extra.delete("HTTP_REQUEST_PACKET_NAME")
    packet.extra = extra
  end

  return packet
end

#convert_packet_to_data(_packet) ⇒ Object

Called to convert a packet into the data to send

Parameters:

  • packet (Packet)

    Packet to extract data from

Returns:

  • data



196
197
198
# File 'lib/openc3/interfaces/http_server_interface.rb', line 196

def convert_packet_to_data(_packet)
  raise "Commands cannot be sent to HttpServerInterface"
end

#disconnectObject

Disconnects the interface from its target(s)



143
144
145
146
147
148
149
150
151
# File 'lib/openc3/interfaces/http_server_interface.rb', line 143

def disconnect
  @server.shutdown if @server
  @server = nil
  while @request_queue.length > 0
    @request_queue.pop
  end
  super()
  @request_queue.push(nil)
end

#read_interfaceObject

Reads from the socket if the read_port is defined



154
155
156
157
158
159
160
161
# File 'lib/openc3/interfaces/http_server_interface.rb', line 154

def read_interface
  # Get the Faraday Response
  data, extra = @request_queue.pop
  return nil if data.nil?

  read_interface_base(data, extra)
  return data, extra
end

#set_option(option_name, option_values) ⇒ Object

Supported Options LISTEN_ADDRESS - Ip address of the interface to accept connections on (see Interface#set_option)



38
39
40
41
42
43
44
# File 'lib/openc3/interfaces/http_server_interface.rb', line 38

def set_option(option_name, option_values)
  super(option_name, option_values)
  case option_name.upcase
  when 'LISTEN_ADDRESS'
    @listen_address = option_values[0]
  end
end

#write_interface(_data, _extra = nil) ⇒ Object

Writes to the socket

Parameters:

  • data (Hash)

    For the HTTP Interface, data is a hash with the needed request info



165
166
167
# File 'lib/openc3/interfaces/http_server_interface.rb', line 165

def write_interface(_data, _extra = nil)
  raise "Commands cannot be sent to HttpServerInterface"
end