Format HTTP Post requests with JSON-RPC

I’m trying to send some a POST packet with a JSON-RPC payload. Trouble is, I’m new to it, and I can’t find a decent reference for structure, code, and other stuff.

I need to send a packet with these values inside to an {ip address}/sony/camera

					{
"method": "actTakePicture",
"params": [],
"id": 1,
"version": "1.0"

					}

Here’s the code I’m working on:

client.connect(ip,64321);
        {
            Serial.println("Connected to camera");
            //Encodes JSON Data so that the camera will understand it.
            //Also adds POST data and sends packet 
 
             client.println("POST /camera HTTP//1.1");
            client.println("Host: " + webAddress + "//sony");
            client.println("Accept: application/json");
            client.print("Content-Length: ");
            client.println(strlen(request));
            client.println("Content-Type: application/json-rpc");
            client.println("{/"method/":/"actTakePicture/",/"params/":/"[]/",/"id/": 1,/"version/": /"1.0/"}");
        }

I’ve got some questions I need to know before I can send the thing. How do I encode the JSON parameters? Do I need to calculate the length of the packet, or is that handled by the TCP library?

How much of the above stuff do I need? I’m just not sure what I need to send, and am thus having trouble coding for it.

Thank you!

EDIT: Here is an encoding function that I found online that might be required

String URLEncode(const char* msg)
{
    const char *hex = "0123456789abcdef";
    String encodedMsg = "";

    while (*msg!='\0'){
        if( ('a' <= *msg && *msg <= 'z')
                || ('A' <= *msg && *msg <= 'Z')
                || ('0' <= *msg && *msg <= '9') ) {
            encodedMsg += *msg;
        } else {
            encodedMsg += '%';
            encodedMsg += hex[*msg >> 4];
            encodedMsg += hex[*msg & 15];
        }
        msg++;
    }
    return encodedMsg;
}

I don’t think you need the encoding function - that’s for form encoded data. Here you are sending the body as is - nice and simple! :slight_smile:

Some things to try:

  • change the protocol to HTTP/1.0
  • the content length is set to strlen(request) - I don’t see the request variable. Either way, make request point to your encoded json, so you are sure the content length is properly set.
  • the Host header should just be the server name -without the /camera directory. Similarly, the first line should be POST /sony/camera HTTP/1.0
  • after the last header, I believe you need a CRLF, so add client.println() before printing the json.

Before writing the code on the spark core, I would play about sending requests to the camera using the command line utility curl just to sanity-test that things work. Put the json request in a file request.json and then send it to the camera like this:

curl -X POST -d @request.json http://<camera-ip>/sony/camera

PS: The spec for HTTP is at http://www.w3.org/Protocols/HTTP/1.0/spec.html

1 Like

Curl will work. I ended up using the Advanced Rest Client API for chrome

A note on JSON, for curl you’ll need the -H tag to set the content-type

curl -X POST -H "Content-type:json-rpc" -d @request.json http://<camera-ip>/sony/camera

I finally got it to work, it turned out that the port was incorrect for the API calls. Protocol didn’t need to be changed though. Thanks for the help.

2 Likes