Class: RFlow::Components::HTTP::Server
- Inherits:
-
RFlow::Component
- Object
- RFlow::Component
- RFlow::Components::HTTP::Server
- Defined in:
- lib/rflow/components/http/server.rb
Overview
Implements a HTTP server based on eventmachine_httpserver. Accepts incoming HTTP connections, marshals the HTTP request into an RFlow message, annotates the message with a bit of provenance (see below) and then sends the message out its #request_port. When a HTTP response message is received on #response_port, checks the provenance to see if it matches an underlying TCP/HTTP connection and, if so, creates an actual HTTP response from the incoming message and sends it to the client.
The HTTP request message sent from the HTTP server component utilizes the RFlow::Message provenance feature to annotate a request message with a bit of metadata that allows subsequent response messages to be matched to their underlying TCP/HTTP connections. This means that any component that processes HTTP request messages to generate response messages must copy the provenance from the request message to the response message.
Instance Attribute Summary collapse
-
#request_port ⇒ RFlow::Component::OutputPort
readonly
Produces RFlow::Messages of type Message::Data::HTTP::Request representing requests that have arrived on the socket managed by the component.
-
#response_port ⇒ RFlow::Component::InputPort
readonly
Expects RFlow::Messages of type Message::Data::HTTP::Response representing responses being sent back corresponding to previously received requests.
Instance Method Summary collapse
-
#configure!(config) ⇒ void
RFlow-called method at startup.
-
#process_message(input_port, input_port_key, connection, message) ⇒ void
RFlow-called method upon message arrival.
-
#run! ⇒ void
RFlow-called method at startup.
Instance Attribute Details
#request_port ⇒ RFlow::Component::OutputPort (readonly)
Produces RFlow::Messages of type Message::Data::HTTP::Request representing requests that have arrived on the socket managed by the component. Each features provenance that must be copied to any response message.
35 |
# File 'lib/rflow/components/http/server.rb', line 35 output_port :request_port |
#response_port ⇒ RFlow::Component::InputPort (readonly)
Expects RFlow::Messages of type Message::Data::HTTP::Response representing responses being sent back corresponding to previously received requests. Each response should have provenance copied from the request it’s responding to.
28 |
# File 'lib/rflow/components/http/server.rb', line 28 input_port :response_port |
Instance Method Details
#configure!(config) ⇒ void
This method returns an undefined value.
RFlow-called method at startup.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rflow/components/http/server.rb', line 44 def configure!(config) @listen = config['listen'] ? config['listen'] : '127.0.0.1' @port = config['port'] ? config['port'].to_i : 8000 @proxy_real_client_ip_header = config.has_key?('proxy-real-client-ip-header') ? config['proxy-real-client-ip-header'] : 'X-Real-IP' @proxy_real_client_port_header = config.has_key?('proxy-real-client-port-header') ? config['proxy-real-client-port-header'] : 'X-Real-Port' @proxy_real_server_ip_header = config.has_key?('proxy-real-server-ip-header') ? config['proxy-real-server-ip-header'] : 'X-Server-IP' @proxy_real_server_port_header = config.has_key?('proxy-real-server-port-header') ? config['proxy-real-server-port-header'] : 'X-Server-Port' @connections = {} @closed_connections = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes) end |
#process_message(input_port, input_port_key, connection, message) ⇒ void
This method returns an undefined value.
RFlow-called method upon message arrival.
Filters for messages that pertain to this component and have active connections by inspecting the provenance, specifically the context attribute that we stored originally.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/rflow/components/http/server.rb', line 72 def (input_port, input_port_key, connection, ) return unless .data_type_name == 'RFlow::Message::Data::HTTP::Response' my_events = .provenance.find_all {|processing_event| processing_event.component_instance_uuid == uuid} my_events.each do |processing_event| connection_signature_string = processing_event.context.to_s if connections[connection_signature_string] connections[connection_signature_string].send_http_response else conn = closed_connections.read(connection_signature_string) if conn RFlow.logger.info "#{name}: Could not send HTTP response to #{conn.client_details}: connection is already closed" else RFlow.logger.info "#{name}: Could not send HTTP response to <client details expired>: connection is already closed" end end end end |
#run! ⇒ void
This method returns an undefined value.
RFlow-called method at startup.
57 58 59 60 61 62 63 |
# File 'lib/rflow/components/http/server.rb', line 57 def run! @server_signature = EM.start_server(@listen, @port, Connection) do |conn| conn.server = self self.connections[conn.signature.to_s] = conn RFlow.logger.debug { "#{name}: Connection from #{conn.client_details} to #{conn.server_details}" } end end |