Class: LogStash::Inputs::Http

Inherits:
Base
  • Object
show all
Defined in:
lib/logstash/inputs/http_bold.rb,
lib/logstash/inputs/http_bold/tls.rb,
lib/logstash/inputs/http_bold/message_handler.rb

Overview

Using this input you can receive single or multiline events over http(s). Applications can send a HTTP POST request with a body to the endpoint started by this input and Logstash will convert it into an event for subsequent processing. Users can pass plain text, JSON, or any formatted data and use a corresponding codec with this input. For Content-Type ‘application/json` the `json` codec is used, but for all other data formats, `plain` codec is used.

This input can also be used to receive webhook requests to integrate with other services and applications. By taking advantage of the vast plugin ecosystem available in Logstash you can trigger actionable events right from your application.

Security

This plugin supports standard HTTP basic authentication headers to identify the requester. You can pass in an username, password combination while sending data to this input

You can also setup SSL and send data securely over https, with an option of validating the client’s certificate. Currently, the certificate setup is through docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html[Java Keystore format]

Defined Under Namespace

Classes: MessageHandler, TLS

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_domain_port(http_host) ⇒ Object

match the domain and port in either IPV4, “127.0.0.1:8080”, or IPV6, “[2001:db8::8a2e:370:7334]:8080”, style return [domain, port]



221
222
223
224
225
226
227
# File 'lib/logstash/inputs/http_bold.rb', line 221

def self.get_domain_port(http_host)
  if /^(([^:]+)|\[(.*)\])\:([\d]+)$/ =~ http_host
    ["#{$2 || $3}", $4.to_i]
  else
    [http_host, nil]
  end
end

Instance Method Details

#add_ecs_fields(headers, event) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/logstash/inputs/http_bold.rb', line 192

def add_ecs_fields(headers, event)
  return if ecs_compatibility == :disabled

  http_version = headers.get("http_version")
  event.set("[http][version]", http_version) if http_version

  http_user_agent = headers.get("http_user_agent")
  event.set("[user_agent][original]", http_user_agent) if http_user_agent

  http_host = headers.get("http_host")
  domain, port = self.class.get_domain_port(http_host)
  event.set("[url][domain]", domain) if domain
  event.set("[url][port]", port) if port

  request_method = headers.get("request_method")
  event.set("[http][method]", request_method) if request_method

  request_path = headers.get("request_path")
  event.set("[url][path]", request_path) if request_path

  content_length = headers.get("content_length")
  event.set("[http][request][body][bytes]", content_length) if content_length

  content_type = headers.get("content_type")
  event.set("[http][request][mime_type]", content_type) if content_type
end

#build_ssl_paramsObject



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/logstash/inputs/http_bold.rb', line 260

def build_ssl_params
  return nil unless @ssl

  if @keystore && @keystore_password
    ssl_builder = org.logstash.plugins.inputs.http_bold.util.JksSslBuilder.new(@keystore, @keystore_password.value)
  else
    begin
      ssl_builder = org.logstash.plugins.inputs.http_bold.util.SslSimpleBuilder
                        .new(@ssl_certificate, @ssl_key, @ssl_key_passphrase.nil? ? nil : @ssl_key_passphrase.value)
                        .setCipherSuites(normalized_ciphers)
    rescue java.lang.IllegalArgumentException => e
      @logger.error("SSL configuration invalid", error_details(e))
      raise LogStash::ConfigurationError, e
    end

    if client_authentication?
      ssl_builder.setCertificateAuthorities(@ssl_certificate_authorities)
    end
  end

  new_ssl_handshake_provider(ssl_builder)
end

#client_authentication?Boolean

Returns:

  • (Boolean)


291
292
293
# File 'lib/logstash/inputs/http_bold.rb', line 291

def client_authentication?
  @ssl_certificate_authorities && @ssl_certificate_authorities.size > 0
end

#closeObject



164
165
166
# File 'lib/logstash/inputs/http_bold.rb', line 164

def close
  @http_server.close() rescue nil
end

#create_http_server(message_handler) ⇒ Object



255
256
257
258
# File 'lib/logstash/inputs/http_bold.rb', line 255

def create_http_server(message_handler)
  org.logstash.plugins.inputs.http_bold.NettyHttpServer.new(
    @host, @port, message_handler, build_ssl_params(), @threads, @max_pending_requests, @max_content_length, @response_code)
end

#decode_body(headers, remote_address, body, default_codec, additional_codecs) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/logstash/inputs/http_bold.rb', line 168

def decode_body(headers, remote_address, body, default_codec, additional_codecs)
  content_type = headers.fetch("content_type", "")
  codec = additional_codecs.fetch(HttpUtil.getMimeType(content_type), default_codec)
  codec.decode(body) { |event| push_decoded_event(headers, remote_address, event) }
  codec.flush { |event| push_decoded_event(headers, remote_address, event) }
  true
rescue => e
  @logger.error(
    "unable to process event.",
    :message => e.message,
    :class => e.class.name,
    :backtrace => e.backtrace
  )
  false
end

#push_decoded_event(headers, remote_address, event) ⇒ Object



184
185
186
187
188
189
190
# File 'lib/logstash/inputs/http_bold.rb', line 184

def push_decoded_event(headers, remote_address, event)
  add_ecs_fields(headers, event)
  event.set(@request_headers_target_field, headers)
  event.set(@remote_host_target_field, remote_address)
  decorate(event)
  @queue << event
end

#registerObject



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/logstash/inputs/http_bold.rb', line 131

def register

  validate_ssl_settings!

  if @user && @password
    token = Base64.strict_encode64("#{@user}:#{@password.value}")
    @auth_token = "Basic #{token}"
  end

  @codecs = Hash.new

  @additional_codecs.each do |content_type, codec|
    @codecs[content_type] = LogStash::Plugin.lookup("codec", codec).new
  end

  require "logstash/inputs/http_bold/message_handler"
  message_handler = MessageHandler.new(self, @codec, @codecs, @auth_token)
  @http_server = create_http_server(message_handler)

  @remote_host_target_field ||= ecs_select[disabled: "host", v1: "[host][ip]"]
  @request_headers_target_field ||= ecs_select[disabled: "headers", v1: "[@metadata][input][http][request][headers]"]
end

#require_certificate_authorities?Boolean

Returns:

  • (Boolean)


295
296
297
# File 'lib/logstash/inputs/http_bold.rb', line 295

def require_certificate_authorities?
  @ssl_verify_mode_final == "force_peer" || @ssl_verify_mode_final == "peer"
end

#run(queue) ⇒ Object

def register



154
155
156
157
158
# File 'lib/logstash/inputs/http_bold.rb', line 154

def run(queue)
  @queue = queue
  @logger.info("Starting http input listener", :address => "#{@host}:#{@port}", :ssl => "#{@ssl}")
  @http_server.run()
end

#ssl_jks_configured?Boolean

Returns:

  • (Boolean)


287
288
289
# File 'lib/logstash/inputs/http_bold.rb', line 287

def ssl_jks_configured?
  !!(@keystore && @keystore_password)
end

#ssl_key_configured?Boolean

Returns:

  • (Boolean)


283
284
285
# File 'lib/logstash/inputs/http_bold.rb', line 283

def ssl_key_configured?
  !!(@ssl_certificate && @ssl_key)
end

#stopObject



160
161
162
# File 'lib/logstash/inputs/http_bold.rb', line 160

def stop
  @http_server.close() rescue nil
end

#validate_ssl_settings!Object



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/logstash/inputs/http_bold.rb', line 229

def validate_ssl_settings!
  if !@ssl
    @logger.warn("SSL Certificate will not be used") if @ssl_certificate
    @logger.warn("SSL Key will not be used") if @ssl_key
    @logger.warn("SSL Java Key Store will not be used") if @keystore
  elsif !(ssl_key_configured? || ssl_jks_configured?)
    raise LogStash::ConfigurationError, "Certificate or JKS must be configured"
  end

  if @ssl && (original_params.key?("verify_mode") && original_params.key?("ssl_verify_mode"))
      raise LogStash::ConfigurationError, "Both 'ssl_verify_mode' and 'verify_mode' were set. Use only 'ssl_verify_mode'."
  elsif original_params.key?("verify_mode")
    @ssl_verify_mode_final = @verify_mode
  elsif original_params.key?("ssl_verify_mode")
    @ssl_verify_mode_final = @ssl_verify_mode
  else
    @ssl_verify_mode_final = @ssl_verify_mode
  end

  if @ssl && require_certificate_authorities? && !client_authentication?
    raise LogStash::ConfigurationError, "Using `ssl_verify_mode` or `verify_mode` set to PEER or FORCE_PEER, requires the configuration of `ssl_certificate_authorities`"
  elsif @ssl && !require_certificate_authorities? && client_authentication?
    raise LogStash::ConfigurationError, "The configuration of `ssl_certificate_authorities` requires setting `ssl_verify_mode` or `verify_mode` to PEER or FORCE_PEER"
  end
end