Closing brace missing in webhook JSON

I set up a webhook in Discourse today for the first time. I’ve got a great use case for it and can’t wait to finish the code. :slight_smile:

But the post and topic event JSON sent by Discourse is not playing well with my receiving PHP script. PHP fails to parse it. Through json_last_error_msg, I saw that there is a syntax error somewhere in the payload, which is why json_decode is failing.

From the webhook’s log panel in Discourse, the request JSON validated when I tested it, so I set up a simple script to verify that PHP is receiving the same data that Discourse is reporting, but that doesn’t seem to be the case.


$data = file_get_contents('php://input');


Discourse receives a response that seems to show that a closing brace is omitted in the payload being received by PHP.

Here’s the well-formed JSON payload reported by Discourse:

…and here’s what print_r returns to Discourse:

1 Like

Any ideas @fantasticfears?

PHP respects Content-Length correctly so it truncates the string in the middle. The problem is that the payload is not count in octets.

Pull request: FIX: Content-Lenght should be the size in octets by fantasticfears · Pull Request #4451 · discourse/discourse · GitHub


@fantasticfears Can you check if Excon sets the Content-Length header for us?

Yes, it does if the field is not provided. In connection.rb:

body = datum[:body].is_a?(String) ?[:body]) : datum[:body]

# The HTTP spec isn't clear on it, but specifically, GET requests don't usually send bodies;
# if they don't, sending Content-Length:0 can cause issues.
unless datum[:method].to_s.casecmp('GET') == 0 && body.nil?
  unless datum[:headers].has_key?('Content-Length')
    datum[:headers]['Content-Length'] = detect_content_length(body)
def detect_content_length(body)
  if body.respond_to?(:size)
    # IO object: File, Tempfile, StringIO, etc.
  elsif body.respond_to?(:stat)
    # for 1.8.7 where file does not have size

Since we need to record that field in the log, it doesn’t matter.

But it’s worthwhile to build a module for the job and redeliver action. 1) Reuse the code. 2) Easier to replace Excon.

A post was split to a new topic: Super impressed with Discourse’s development cycle