Skip to content

Commit

Permalink
Escape json posts in curl_json plugin
Browse files Browse the repository at this point in the history
*If* in the 'post' parameter we've been given a valid json string, it
definately won't work unless we do some escaping of double quotes.

If any strings in the JSON also contain (correctly escaped) double
quotes, even more backslashes are needed.

eg. The following JSON

```
{"param1":"something with a double quote \" in it"}
```

Would end up in the config file as

```
Post "{\"param1\":\"something with a double quote \\\" in it\"}"
```
  • Loading branch information
alexjfisher committed Dec 7, 2017
1 parent 72f796f commit d2b03bc
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
2 changes: 2 additions & 0 deletions spec/classes/collectd_plugin_fscache_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
let :facts do
{
osfamily: 'FreeBSD',
operatingsystem: 'FreeBSD',
os: { family: 'FreeBSD' },
collectd_version: '4.7.0',
operatingsystemmajrelease: '7',
Expand All @@ -31,6 +32,7 @@
let :facts do
{
osfamily: 'FreeBSD',
operatingsystem: 'FreeBSD',
os: { family: 'FreeBSD' },
collectd_version: '4.7.0',
operatingsystemmajrelease: '7',
Expand Down
38 changes: 30 additions & 8 deletions spec/defines/collectd_plugin_curl_json_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
verifypeer: 'false',
verifyhost: 'false',
cacert: '/path/to/ca.crt',
header: 'Accept: application/json',
post: '{secret: \"mysecret\"}',
header: 'Content-Type: application/x-www-form-urlencoded',
post: 'secret=mysecret&foo=bar',
timeout: 1000,
keys: {
'message_stats/publish' => {
Expand Down Expand Up @@ -106,8 +106,8 @@
it { is_expected.to contain_file(filename).with_content(%r{VerifyPeer false}) }
it { is_expected.to contain_file(filename).with_content(%r{VerifyHost false}) }
it { is_expected.to contain_file(filename).with_content(%r{CACert "/path/to/ca.crt"}) }
it { is_expected.to contain_file(filename).with_content(%r{Header "Accept: application/json"}) }
it { is_expected.to contain_file(filename).with_content(%r|Post "{secret: \\"mysecret\\"}"|) }
it { is_expected.to contain_file(filename).with_content(%r{Header "Content-Type: application/x-www-form-urlencoded"}) }
it { is_expected.to contain_file(filename).with_content(%r{Post "secret=mysecret&foo=bar"}) }
it { is_expected.to contain_file(filename).without_content(%r{Timeout}) }
it { is_expected.to contain_file(filename).with_content(%r{Key "message_stats/publish">}) }
it { is_expected.to contain_file(filename).with_content(%r{Type "gauge"}) }
Expand Down Expand Up @@ -139,8 +139,8 @@
it { is_expected.to contain_file(filename).with_content(%r{VerifyPeer false}) }
it { is_expected.to contain_file(filename).with_content(%r{VerifyHost false}) }
it { is_expected.to contain_file(filename).with_content(%r{CACert "/path/to/ca.crt"}) }
it { is_expected.to contain_file(filename).with_content(%r{Header "Accept: application/json"}) }
it { is_expected.to contain_file(filename).with_content(%r|Post "{secret: \\"mysecret\\"}"|) }
it { is_expected.to contain_file(filename).with_content(%r{Header "Content-Type: application/x-www-form-urlencoded"}) }
it { is_expected.to contain_file(filename).with_content(%r{Post "secret=mysecret&foo=bar"}) }
it { is_expected.to contain_file(filename).with_content(%r{Timeout 1000}) }
it { is_expected.to contain_file(filename).with_content(%r{Key "message_stats/publish">}) }
it { is_expected.to contain_file(filename).with_content(%r{Type "gauge"}) }
Expand Down Expand Up @@ -172,8 +172,8 @@
it { is_expected.to contain_file(filename).with_content(%r{VerifyPeer false}) }
it { is_expected.to contain_file(filename).with_content(%r{VerifyHost false}) }
it { is_expected.to contain_file(filename).with_content(%r{CACert "/path/to/ca.crt"}) }
it { is_expected.to contain_file(filename).with_content(%r{Header "Accept: application/json"}) }
it { is_expected.to contain_file(filename).with_content(%r|Post "{secret: \\"mysecret\\"}"|) }
it { is_expected.to contain_file(filename).with_content(%r{Header "Content-Type: application/x-www-form-urlencoded"}) }
it { is_expected.to contain_file(filename).with_content(%r{Post "secret=mysecret&foo=bar"}) }
it { is_expected.to contain_file(filename).with_content(%r{Timeout 1000}) }
it { is_expected.to contain_file(filename).with_content(%r{Key "message_stats/publish">}) }
it { is_expected.to contain_file(filename).with_content(%r{Type "gauge"}) }
Expand Down Expand Up @@ -211,6 +211,28 @@
it { is_expected.to contain_file(filename).with_content(%r{Type "gauge"}) }
it { is_expected.to contain_file(filename).with_content(%r{Instance "overview"}) }
end

context 'json posts' do
let(:post) do
{
'type' => 'read',
'mbean' => 'Catalina:name="http-nio-127.0.0.1-8080",type=GlobalRequestProcessor'
}.to_json
end

let(:params) do
my_params.merge(header: 'Content-Type: application/json', post: post)
end

let :facts do
facts.merge(collectd_version: '5.6.0')
end

it { is_expected.to contain_file(filename).with_content(%r{Header "Content-Type: application/json"}) }

# In the regex below, we have to escape the backslashes in "{\"type\":\"read\",\"mbean\":\"Catalina:name=\\\"http-nio-127.0.0.1-8080\\\",type=GlobalRequestProcessor\"}"
it { is_expected.to contain_file(filename).with_content(%r|Post "{\\"type\\":\\"read\\",\\"mbean\\":\\"Catalina:name=\\\\\\"http-nio-127\.0\.0\.1-8080\\\\\\",type=GlobalRequestProcessor\\"}"|) }
end
end
end
end
12 changes: 12 additions & 0 deletions templates/curl_json.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,22 @@ LoadPlugin "curl_json"
<% if @header -%>
Header "<%= @header %>"
<% end -%>
<%-
def valid_json?(json)
JSON.parse(json)
return true
rescue JSON::ParserError
return false
end
-%>
<% unless @post.nil? -%>
<% if valid_json?(@post) -%>
Post "<%= @post.gsub('\\"','\\\\\\\\\"').gsub!(%r{(?<!\\)"},'\"') %>"
<% else -%>
Post "<%= @post %>"
<% end -%>
<% end -%>
<% end -%>
<% if scope.lookupvar('collectd::collectd_version_real') and (scope.function_versioncmp([scope.lookupvar('collectd::collectd_version_real'), '5.5']) >= 0) -%>
<% unless @timeout.nil? -%>
Timeout <%= @timeout %>
Expand Down

0 comments on commit d2b03bc

Please sign in to comment.