logstash-input-http 3.1.0-java → 3.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/VERSION +1 -1
- data/docs/index.asciidoc +16 -0
- data/lib/logstash-input-http_jars.rb +1 -1
- data/lib/logstash/inputs/http.rb +16 -34
- data/lib/logstash/inputs/http/message_handler.rb +11 -21
- data/spec/inputs/http_spec.rb +92 -1
- data/vendor/jar-dependencies/org/logstash/plugins/input/http/logstash-input-http/{3.1.0/logstash-input-http-3.1.0.jar → 3.2.0/logstash-input-http-3.2.0.jar} +0 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd4ab63a8da778ab6b98669f405773f04defba698bef77a3430d0ea4eb778cf0
|
4
|
+
data.tar.gz: 8bc8d4d7909fa768424d63142198644bb97e6b8ea44bef779288267d48044052
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91ee9ad30eaf383efbf38b2f8a6720a3a9bba045ed7dda602734600dfa63b6d7c532bbee12b078a6c1444632e7edb3afe19569d72e9f2f4e94405092849d4a6c
|
7
|
+
data.tar.gz: b09f089df723d4240a6a89d8c78cb46c54a914784d8a15491604be7b31238c4f668044ea15f3cceb74e557f70678783ff0b4c9444ba8d61c56d55f0f8bd844c8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 3.2.0
|
2
|
+
- Add `request_headers_target_field` and `remote_host_target_field` configuration options with default to `host` and `headers` respectively #68
|
3
|
+
- Sanitize content-type header with getMimeType #87
|
4
|
+
- Move most message handling code to java #85
|
5
|
+
- Fix: respond with correct http protocol version #84
|
6
|
+
|
1
7
|
## 3.1.0
|
2
8
|
- Replace Puma web server with Netty
|
3
9
|
- Support crt/key certificates
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.0
|
data/docs/index.asciidoc
CHANGED
@@ -184,6 +184,22 @@ Persistent Queue for the logstash pipeline.
|
|
184
184
|
|
185
185
|
specify a custom set of response headers
|
186
186
|
|
187
|
+
[id="plugins-{type}s-{plugin}-remote_host_target_field"]
|
188
|
+
===== `remote_host_target_field`
|
189
|
+
|
190
|
+
* Value type is <<string,string>>
|
191
|
+
* Default value is `"host"`
|
192
|
+
|
193
|
+
specify a target field for the client host of the http request
|
194
|
+
|
195
|
+
[id="plugins-{type}s-{plugin}-request_headers_target_field"]
|
196
|
+
===== `request_headers_target_field`
|
197
|
+
|
198
|
+
* Value type is <<string,string>>
|
199
|
+
* Default value is `"headers"`
|
200
|
+
|
201
|
+
specify target field for the client host of the http request
|
202
|
+
|
187
203
|
[id="plugins-{type}s-{plugin}-ssl"]
|
188
204
|
===== `ssl`
|
189
205
|
|
@@ -4,4 +4,4 @@ require 'jar_dependencies'
|
|
4
4
|
require_jar('io.netty', 'netty-all', '4.1.18.Final')
|
5
5
|
require_jar('io.netty', 'netty-tcnative-boringssl-static', '2.0.7.Final')
|
6
6
|
require_jar('org.apache.logging.log4j', 'log4j-api', '2.6.2')
|
7
|
-
require_jar('org.logstash.plugins.input.http', 'logstash-input-http', '3.
|
7
|
+
require_jar('org.logstash.plugins.input.http', 'logstash-input-http', '3.2.0')
|
data/lib/logstash/inputs/http.rb
CHANGED
@@ -4,6 +4,8 @@ require "logstash/namespace"
|
|
4
4
|
require "stud/interval"
|
5
5
|
require "logstash-input-http_jars"
|
6
6
|
|
7
|
+
java_import "io.netty.handler.codec.http.HttpUtil"
|
8
|
+
|
7
9
|
# Using this input you can receive single or multiline events over http(s).
|
8
10
|
# Applications can send a HTTP POST request with a body to the endpoint started by this
|
9
11
|
# input and Logstash will convert it into an event for subsequent processing. Users
|
@@ -101,6 +103,12 @@ class LogStash::Inputs::Http < LogStash::Inputs::Base
|
|
101
103
|
# specify a custom set of response headers
|
102
104
|
config :response_headers, :validate => :hash, :default => { 'Content-Type' => 'text/plain' }
|
103
105
|
|
106
|
+
# target field for the client host of the http request
|
107
|
+
config :remote_host_target_field, :validate => :string, :default => "host"
|
108
|
+
|
109
|
+
# target field for the client host of the http request
|
110
|
+
config :request_headers_target_field, :validate => :string, :default => "headers"
|
111
|
+
|
104
112
|
config :threads, :validate => :number, :required => false, :default => ::LogStash::Config::CpuCoreStrategy.maximum
|
105
113
|
|
106
114
|
config :max_pending_requests, :validate => :number, :required => false, :default => 200
|
@@ -133,7 +141,7 @@ class LogStash::Inputs::Http < LogStash::Inputs::Base
|
|
133
141
|
end
|
134
142
|
|
135
143
|
require "logstash/inputs/http/message_handler"
|
136
|
-
message_handler = MessageHandler.new(self, @codec, @codecs)
|
144
|
+
message_handler = MessageHandler.new(self, @codec, @codecs, @auth_token)
|
137
145
|
@http_server = create_http_server(message_handler)
|
138
146
|
end # def register
|
139
147
|
|
@@ -151,23 +159,12 @@ class LogStash::Inputs::Http < LogStash::Inputs::Base
|
|
151
159
|
@http_server.close() rescue nil
|
152
160
|
end
|
153
161
|
|
154
|
-
def decode_body(remote_address,
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
http_full_request.headers.each do |header|
|
159
|
-
headers[header.key.downcase.tr('-', '_')] = header.value
|
160
|
-
end
|
161
|
-
headers["request_method"] = http_full_request.getMethod.name
|
162
|
-
headers["request_path"] = http_full_request.getUri
|
163
|
-
headers["http_version"] = http_full_request.getProtocolVersion.text
|
164
|
-
headers["http_accept"] = headers.delete("accept")
|
165
|
-
headers["http_host"] = headers.delete("host")
|
166
|
-
headers["http_user_agent"] = headers.delete("user_agent")
|
167
|
-
codec = additional_codecs.fetch(headers["content_type"], default_codec)
|
162
|
+
def decode_body(headers, remote_address, body, default_codec, additional_codecs)
|
163
|
+
content_type = headers.fetch("content_type", "")
|
164
|
+
codec = additional_codecs.fetch(HttpUtil.getMimeType(content_type), default_codec)
|
168
165
|
codec.decode(body) { |event| push_decoded_event(headers, remote_address, event) }
|
169
166
|
codec.flush { |event| push_decoded_event(headers, remote_address, event) }
|
170
|
-
|
167
|
+
true
|
171
168
|
rescue => e
|
172
169
|
@logger.error(
|
173
170
|
"unable to process event.",
|
@@ -175,31 +172,16 @@ class LogStash::Inputs::Http < LogStash::Inputs::Base
|
|
175
172
|
:class => e.class.name,
|
176
173
|
:backtrace => e.backtrace
|
177
174
|
)
|
178
|
-
|
175
|
+
false
|
179
176
|
end
|
180
177
|
|
181
178
|
def push_decoded_event(headers, remote_address, event)
|
182
|
-
event.set(
|
183
|
-
event.set(
|
179
|
+
event.set(@request_headers_target_field, headers)
|
180
|
+
event.set(@remote_host_target_field, remote_address)
|
184
181
|
decorate(event)
|
185
182
|
@queue << event
|
186
183
|
end
|
187
184
|
|
188
|
-
def valid_auth?(token)
|
189
|
-
if @auth_token
|
190
|
-
@auth_token == token
|
191
|
-
else
|
192
|
-
true
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
private
|
197
|
-
def read_bytes(bytebuffer)
|
198
|
-
bytes = Java::byte[bytebuffer.readableBytes].new
|
199
|
-
bytebuffer.getBytes(0, bytes)
|
200
|
-
String.from_java_bytes(bytes, "ASCII-8BIT")
|
201
|
-
end
|
202
|
-
|
203
185
|
def validate_ssl_settings!
|
204
186
|
if !@ssl
|
205
187
|
@logger.warn("SSL Certificate will not be used") if @ssl_certificate
|
@@ -14,37 +14,27 @@ module LogStash module Inputs class Http
|
|
14
14
|
|
15
15
|
attr_reader :input
|
16
16
|
|
17
|
-
def initialize(input, default_codec, additional_codecs)
|
17
|
+
def initialize(input, default_codec, additional_codecs, auth_token)
|
18
18
|
@input = input
|
19
19
|
@default_codec = default_codec
|
20
20
|
@additional_codecs = additional_codecs
|
21
|
+
@auth_token = auth_token
|
21
22
|
end
|
22
23
|
|
23
|
-
def
|
24
|
-
if
|
25
|
-
|
26
|
-
status, headers, content = @input.decode_body(remote_address, message, @default_codec, @additional_codecs)
|
24
|
+
def validates_token(token)
|
25
|
+
if @auth_token
|
26
|
+
@auth_token == token
|
27
27
|
else
|
28
|
-
|
28
|
+
true
|
29
29
|
end
|
30
|
-
generate_response(status, headers, content)
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
payload = Unpooled.copiedBuffer(content.to_java_string, CharsetUtil::UTF_8)
|
36
|
-
response = DefaultFullHttpResponse.new(
|
37
|
-
HttpVersion::HTTP_1_1,
|
38
|
-
HttpResponseStatus.valueOf(status),
|
39
|
-
payload)
|
40
|
-
response.headers().set(HttpHeaderNames::CONTENT_LENGTH, payload.readable_bytes());
|
41
|
-
response.headers().set(HttpHeaderNames::CONTENT_TYPE, "text/plain");
|
42
|
-
headers.each { |k, v| response.headers().set(k, v) }
|
43
|
-
response
|
32
|
+
def onNewMessage(remote_address, headers, body)
|
33
|
+
@input.decode_body(headers, remote_address, body, @default_codec, @additional_codecs)
|
44
34
|
end
|
45
35
|
|
46
36
|
def copy
|
47
|
-
MessageHandler.new(@input, @default_codec.clone, clone_additional_codecs())
|
37
|
+
MessageHandler.new(@input, @default_codec.clone, clone_additional_codecs(), @auth_token)
|
48
38
|
end
|
49
39
|
|
50
40
|
def clone_additional_codecs
|
@@ -55,8 +45,8 @@ module LogStash module Inputs class Http
|
|
55
45
|
clone_additional_codecs
|
56
46
|
end
|
57
47
|
|
58
|
-
def
|
59
|
-
@input.
|
48
|
+
def response_headers
|
49
|
+
@input.response_headers
|
60
50
|
end
|
61
51
|
end
|
62
52
|
end; end; end
|
data/spec/inputs/http_spec.rb
CHANGED
@@ -29,6 +29,7 @@ describe LogStash::Inputs::Http do
|
|
29
29
|
|
30
30
|
describe "request handling" do
|
31
31
|
subject { LogStash::Inputs::Http.new("port" => port) }
|
32
|
+
|
32
33
|
before :each do
|
33
34
|
subject.register
|
34
35
|
t = Thread.new { subject.run(logstash_queue) }
|
@@ -81,6 +82,57 @@ describe LogStash::Inputs::Http do
|
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
85
|
+
describe "remote host" do
|
86
|
+
subject { LogStash::Inputs::Http.new(config.merge("port" => port)) }
|
87
|
+
context "by default" do
|
88
|
+
let(:config) { {} }
|
89
|
+
it "is written to the \"host\" field" do
|
90
|
+
client.post("http://localhost:#{port}/meh.json",
|
91
|
+
:headers => { "content-type" => "text/plain" },
|
92
|
+
:body => "hello").call
|
93
|
+
event = logstash_queue.pop
|
94
|
+
expect(event.get("host")).to eq("127.0.0.1")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when using remote_host_target_field" do
|
99
|
+
let(:config) { { "remote_host_target_field" => "remote_host" } }
|
100
|
+
it "is written to the value of \"remote_host_target_field\" property" do
|
101
|
+
client.post("http://localhost:#{port}/meh.json",
|
102
|
+
:headers => { "content-type" => "text/plain" },
|
103
|
+
:body => "hello").call
|
104
|
+
event = logstash_queue.pop
|
105
|
+
expect(event.get("remote_host")).to eq("127.0.0.1")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "request headers" do
|
111
|
+
subject { LogStash::Inputs::Http.new(config.merge("port" => port)) }
|
112
|
+
context "by default" do
|
113
|
+
let(:config) { {} }
|
114
|
+
it "are written to the \"headers\" field" do
|
115
|
+
client.post("http://localhost:#{port}/meh.json",
|
116
|
+
:headers => { "content-type" => "text/plain" },
|
117
|
+
:body => "hello").call
|
118
|
+
event = logstash_queue.pop
|
119
|
+
expect(event.get("headers")).to be_a(Hash)
|
120
|
+
expect(event.get("headers")).to include("request_method" => "POST")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
context "when using request_headers_target_field" do
|
124
|
+
let(:config) { { "request_headers_target_field" => "request_headers" } }
|
125
|
+
it "are written to the field set in \"request_headers_target_field\"" do
|
126
|
+
client.post("http://localhost:#{port}/meh.json",
|
127
|
+
:headers => { "content-type" => "text/plain" },
|
128
|
+
:body => "hello").call
|
129
|
+
event = logstash_queue.pop
|
130
|
+
expect(event.get("request_headers")).to be_a(Hash)
|
131
|
+
expect(event.get("request_headers")).to include("request_method" => "POST")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
84
136
|
it "should include remote host in \"host\" property" do
|
85
137
|
client.post("http://127.0.0.1:#{port}/meh.json",
|
86
138
|
:headers => { "content-type" => "text/plain" },
|
@@ -190,6 +242,19 @@ describe LogStash::Inputs::Http do
|
|
190
242
|
expect(event.get("message")).to eq(body)
|
191
243
|
end
|
192
244
|
end
|
245
|
+
|
246
|
+
context "when receiving a content-type with a charset" do
|
247
|
+
subject { LogStash::Inputs::Http.new("port" => port,
|
248
|
+
"additional_codecs" => { "application/json" => "plain" }) }
|
249
|
+
it "should decode the message accordingly" do
|
250
|
+
body = { "message" => "Hello" }.to_json
|
251
|
+
client.post("http://127.0.0.1:#{port}/meh.json",
|
252
|
+
:headers => { "content-type" => "application/json; charset=utf-8" },
|
253
|
+
:body => body).call
|
254
|
+
event = logstash_queue.pop
|
255
|
+
expect(event.get("message")).to eq(body)
|
256
|
+
end
|
257
|
+
end
|
193
258
|
|
194
259
|
context "when using custom headers" do
|
195
260
|
let(:custom_headers) { { 'access-control-allow-origin' => '*' } }
|
@@ -197,7 +262,7 @@ describe LogStash::Inputs::Http do
|
|
197
262
|
|
198
263
|
describe "the response" do
|
199
264
|
it "should include the custom headers" do
|
200
|
-
response = client.post("http://127.0.0.1:#{port}/meh", :body => "hello")
|
265
|
+
response = client.post("http://127.0.0.1:#{port}/meh", :body => "hello").call
|
201
266
|
expect(response.headers.to_hash).to include(custom_headers)
|
202
267
|
end
|
203
268
|
end
|
@@ -248,6 +313,32 @@ describe LogStash::Inputs::Http do
|
|
248
313
|
end
|
249
314
|
end
|
250
315
|
|
316
|
+
describe "HTTP Protocol Handling" do
|
317
|
+
context "when an HTTP1.1 request is made" do
|
318
|
+
let(:protocol_version) do
|
319
|
+
Java::OrgApacheHttp::HttpVersion::HTTP_1_1
|
320
|
+
end
|
321
|
+
it "responds with a HTTP1.1 response" do
|
322
|
+
response = client.post("http://127.0.0.1:#{port}", :body => "hello")
|
323
|
+
response.request.set_protocol_version(protocol_version)
|
324
|
+
response.call
|
325
|
+
response_protocol_version = response.instance_variable_get(:@response).get_protocol_version
|
326
|
+
expect(response_protocol_version).to eq(protocol_version)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
context "when an HTTP1.0 request is made" do
|
330
|
+
let(:protocol_version) do
|
331
|
+
Java::OrgApacheHttp::HttpVersion::HTTP_1_0
|
332
|
+
end
|
333
|
+
it "responds with a HTTP1.0 response" do
|
334
|
+
response = client.post("http://127.0.0.1:#{port}", :body => "hello")
|
335
|
+
response.request.set_protocol_version(protocol_version)
|
336
|
+
response.call
|
337
|
+
response_protocol_version = response.instance_variable_get(:@response).get_protocol_version
|
338
|
+
expect(response_protocol_version).to eq(protocol_version)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
251
342
|
end
|
252
343
|
|
253
344
|
context "with :ssl => false" do
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,7 +141,7 @@ files:
|
|
141
141
|
- vendor/jar-dependencies/io/netty/netty-all/4.1.18.Final/netty-all-4.1.18.Final.jar
|
142
142
|
- vendor/jar-dependencies/io/netty/netty-tcnative-boringssl-static/2.0.7.Final/netty-tcnative-boringssl-static-2.0.7.Final.jar
|
143
143
|
- vendor/jar-dependencies/org/apache/logging/log4j/log4j-api/2.6.2/log4j-api-2.6.2.jar
|
144
|
-
- vendor/jar-dependencies/org/logstash/plugins/input/http/logstash-input-http/3.
|
144
|
+
- vendor/jar-dependencies/org/logstash/plugins/input/http/logstash-input-http/3.2.0/logstash-input-http-3.2.0.jar
|
145
145
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
146
146
|
licenses:
|
147
147
|
- Apache License (2.0)
|
@@ -165,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
165
|
version: '0'
|
166
166
|
requirements: []
|
167
167
|
rubyforge_project:
|
168
|
-
rubygems_version: 2.6.
|
168
|
+
rubygems_version: 2.6.13
|
169
169
|
signing_key:
|
170
170
|
specification_version: 4
|
171
171
|
summary: Receives events over HTTP or HTTPS
|