harlequin-tech / WiFlyHQ

WiFly RN-XV Arduino Library
Other
110 stars 68 forks source link

problem sending post requests #18

Closed fluxsaas closed 11 years ago

fluxsaas commented 11 years ago

when i send an POST request, the request header get cropped, if i inspect the request on the server i can see the following:

headers: { host: 'localhost:3000', 'content-type': 'application' },

with this setup;

void SendJasonPacket()
  {
    wifly.open(Server, ServerPort);
    wifly.println("POST / HTTP/1.1");
    wifly.println("Host: localhost:3000");
    wifly.println("Content-type: application/json");
    wifly.println("Accept: application/json");
    wifly.println("Content-Length: 93");
    wifly.println("User-Agent: easyPEP/0.0.1");
    wifly.println("{'checkin':{'device_token': '122','card_token': '12312', 'timestamp': '2012-10-29T14:31:03'}}");
    wifly.close();
  }

i tried a couple of different headers, that's what i got:

  headers: { 'user-agent': 'easyPEP/0.0.1', accept: 'application/j' },
  headers: { accept: 'application/json', 'user-agent': 'easyPEP/0' },
  headers: { host: 'localhost:3000', 'content-type': 'application' },

it seems, that it get cropped after a specific character count, not sure what i did wrong here....

bsalinas commented 11 years ago

Try placing an empty println between your Content-Length and your actual content. I found that I had to do that as well as have my data appear right after the Content-Length line.

fluxsaas commented 11 years ago

mh, doesn't seems to work. i tried with differen servers to debug the headers:

sinatra:

  POST / HTTP/1.1
  Host: localhost:3000
  Content-type: application

  /json
  Accept: application/json
  User-Agent: easyPEP/0.0.1
  Cont

  !! Invalid request

node.js

....
headers: { host: 'localhost:3000', 'content-type': 'application' },
....
url: '/',
method: 'POST',
....

the ruby version seems to have some weired \n linebreaks somehow and is cut off after 'application' that's where the node.js headers end too.

my code is now:

  wifly.open(Server, ServerPort);
  wifly.println("POST / HTTP/1.1");
  wifly.println("Host: localhost:3000");
  wifly.println("Content-type: application/json");
  wifly.println("Accept: application/json");
  wifly.println("User-Agent: easyPEP/0.0.1");
  wifly.println("Content-Length: 93");
  wifly.println();
  wifly.println("{'checkin':{'device_token': '122','card_token': '12312', 'timestamp': '2012-10-29T14:31:03'}}");
  wifly.close();
bsalinas commented 11 years ago

Here is what I did for a Sinatra server:

if (_wifly->open(_site, _port)) {
        _wifly->print("POST ");
        _wifly->print(request);
        _wifly->println(" HTTP/1.1");
        _wifly->println("Content-Type: application/x-www-form-urlencoded");
        _wifly->println("Connection: close");
        _wifly->print("Host: ");
        _wifly->println(_site);
        _wifly->print("Content-Length: ");
        _wifly->println(strlen(data));
        _wifly->println();
        _wifly->print(data);
        return waitForResponse();
    }

I do recall that it has finicky about whether the http:// was present or not. Note that I opted not to use JSON for my posts. Instead my data string looks like "param1=ABC&param2=DEF&param3=GHI".

The other difference I notice is that my "Host: " is of the site I am posting to and not "localhost:3000". Not sure if this will make a difference or not.

Best of luck.

fluxsaas commented 11 years ago

what's with the request variable in your code from: _wifly->print(request); ? i guess its the path for ther server, right ?

bsalinas commented 11 years ago

Yep. Here is an example of the text which actually gets printed out

POST /add_measurement HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Connection: close
Host: trestle.herokuapp.com
Content-Length: 83

station_identifier=Station2&sensor_identifier=MyFirstSensor&value=1683&multiplier=1

In this case, the site that I am opening is trestle.herokuapp.com. So in this case request=/add_measurement and _site=trestle.herokuapp.com and data=station_identifier=Station2&sensor_identifier=MyFirstSensor&value=1683&multiplier=1

I spent some time fighting with which pieces of the header I actually needed and found that this was all that was necessary, though it seems to vary some by server. When I was running the server on my localhost, I didn't need the Host line, but I got errors back when I tried that with Heroku.

In case it is helpful, here is an example of the data I get back from the server

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
Server: thin 1.4.1 codename Chromeo
X-Frame-Options: sameorigin
X-Xss-Protection: 1; mode=block
Content-Length: 17
Connection: Close

{"response":"ok"}
fluxsaas commented 11 years ago

Hey,

i finally made it working with:

    Serial.print("Connected to ");
    Serial.println(site);
    String params = "{\"checkin\":{\"device_token\": \"122\",\"card_token\": \"12312\", \"timestamp\": \"2012-10-29T14:31:03\"}}";
    String paramsLength = String(params.length());
    /* Send the request */
    wifly.println("POST /checkins HTTP/1.1");
    wifly.println("Host: localhost:3000");
    wifly.println("Content-type: application/json");
    wifly.println("Accept: application/json");
    wifly.print("Content-Length: ");
    wifly.println(paramsLength);
    wifly.println("User-Agent: easyPEP/0.0.1");
    wifly.println();
    wifly.println(params);

it works fine, but i still get an strange warning on my rails app:

 Completed 201 Created in 8ms (Views: 1.1ms | ActiveRecord: 2.0ms)
 [2012-12-20 11:09:14] ERROR bad Request-Line `'.

but thats just gonna be some smaller issue...

thanks for your help!

fluxsaas commented 11 years ago

by the way, using json as params hash works too with:

String params = "{\"checkin\":{\"device_token\": \"122\",\"card_token\": \"12312\", \"timestamp\": \"2012-10-29T14:31:03\"}}";
String paramsLength = String(params.length());