Author Topic: Http Post using http.request results in bad request  (Read 342 times)

Offline juvo

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
Http Post using http.request results in bad request
« on: May 05, 2017, 03:22:01 pm »
Hello,

After days of surfing the web, reading forum topics and creating requests in scenes, I feel defeated and need some fresh idea's.
I'm trying to send a simple HTTP POST request to a Milestone XProtect system, containing an xml body.
Simple enough I would think...
Started by creating a scene in my Vera Edge.
Added the following code:
Code: [Select]
local http = require("socket.http")

http.TIMEOUT = 5

local response_body = { }

local body =[[<?xml version="1.0" encoding="utf-8"?><AnalyticsEvent xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:milestone-systems"><EventHeader><ID>00000000-0000-0000-0000-000000000000</ID><Timestamp>2017-05-02T20:48:12</Timestamp><Type>MyType</Type><Message>MyAnalyticsEvent01</Message><CustomTag>TagFromXML</CustomTag><Source><Name>192.168.1.32</Name></Source></EventHeader><Description>Analytics event description.</Description><Location>Event location 1</Location><Vendor><Name>My Smart Video</Name></Vendor></AnalyticsEvent>]]

local res, code, response_headers, status = http.request{
    url = "http://192.168.1.116:9090",
    sink = ltn12.sink.table(response_body),
    headers = {
      ["Content-Type"] = "text/xml",
      ["Content-Length"] = tostring(body:len()),
      ["Connection"] = "Keep-Alive"
    },
    source = ltn12.source.string(body),
    method = "POST"
}

luup.task('Response: = ' .. table.concat(response_body) .. ' code = ' .. code .. '   status = ' .. status,1,'Sample POST request with JSON data',-1)

When triggering this scene, it runs, but I get a message: Sample POST request with JSON data : Response: = Error: Invalid data code = 400 status = HTTP/1.1 400 Bad Request

Using wireshark on the server monitoring port 9090 I see there is a partial packet, the server response with 400 and after the response there is the rest of the POST (2 segments?)

Using a custom program to send the same xml data, all works fine. (Attached are both the wireshark captures)

I found things like this: http://forum.micasaverde.com/index.php?topic=30514.0
But it is still not working correctly...

HELP  :o ;) :D

I hope I provided enough information so that anyone can help me get back on track...

Thanks in advance

With kind regards,

Jan

Offline juvo

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
Re: Http Post using http.request results in bad request
« Reply #1 on: May 14, 2017, 09:12:15 am »
Solved my own problem.

I noticed the first package contained only the "POST / HTTP/1.1\r\n" portion.
After reading and interpreting the http.lua file. I noticed the next two lines:
Code: [Select]
h:sendrequestline(nreqt.method, nreqt.uri)
h:sendheaders(nreqt.headers)

So after sending the request line, my server is already responding.
Afterwards, the complete package was received.

So I combined the two functions to a single one whitch sends the requestline and headers in a singe c:send

Added a custom property to the request, when set it will use my custom function (to not disturb other use of http.socket)

Done!

All works nicely

If someone is interested in more details, just ask  8)



Online a-lurker

  • Hero Member
  • *****
  • Posts: 745
  • Karma: +40/-7
Re: Http Post using http.request results in bad request
« Reply #2 on: May 14, 2017, 06:28:59 pm »
Had exactly the same problem on RasPi. Glad to see it wasn't just me. See attached file:  lines 122 to 148.

Would be good to get this permanently fixed. The code would also be more efficient, as it would only send one packet instead of two. Not sure what the RFCs say but maybe our servers are not behaving?

Need to watch out for this as well:

http://forum.micasaverde.com/index.php?topic=13081.0

On your code - you might want to include a require of ltn12.

What's the Milestone XProtect set up like?

Offline RichardTSchaefer

  • Master Member
  • *******
  • Posts: 9428
  • Karma: +716/-130
    • RTS Services Plugins
Re: Http Post using http.request results in bad request
« Reply #3 on: May 15, 2017, 10:49:54 am »
I believe this is a server problem ... but most clients send the header contents in the original message ... so it is not well tested.

The server is supposed to accept headers until it gets a double  CRLF .
Since the initial packet only contained one ... it should have kept reading for headers ...

Offline juvo

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
Re: Http Post using http.request results in bad request
« Reply #4 on: May 15, 2017, 03:47:08 pm »
I agree with RichardTSchaefer. But because I will be waiting to long for Milestone to review their server, I have to solve the problem on the Vera side... :(

I had almost an identical (or complete identical) function as a-lurker, but added a switch so other users of http.lua aren't affected by my changes. (See file attached trequest function)
oh, and originally I added the ltn12 reference, just fell off when sending the post :D

The milestone setup... Using the protocol integration, I'm going to send xml events to the analytics event server (activated) to send alarms to the milestone alarm manager. This for a control room now using milestone to monitor an environment and to handle their alarms. Now we add a home automation part wich will produce some alarms in milestone.

Thanks for the info

Juvo

« Last Edit: May 15, 2017, 03:52:14 pm by juvo »