Error Connecting to Server Via WiFly Shield - RESOLVED

I'm trying to connect my WiFly Shield (http://www.sparkfun.com/products/9954) to a server I set up. I connected a button to pin 2 so that it sends the request when I push the button. I also have an LED set up on pin 3 to show when the connection is open.

I think I'm very close but missing something probably trivial. The shield connects to my wifi network and successfully sends out the "GET" command. I even copied the user agent from my MacBook so that the request looks exactly the one from the browser and yet I get a "400 Bad Request."

This is the Apache log for the request from Arduino:

XXX.XXX.XXX.XXX - - [08/Mar/2012:03:06:54 +0000] "GET /hit/on/id HTTP/1.1" 400 304 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 Safari/535.19"

However, if I type the URL into the browser, I get this:

XXX.XXX.XXX.XXX - - [08/Mar/2012:03:08:02 +0000] "GET /hit/on/id HTTP/1.1" 200 19 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 Safari/535.19"
XXX.XXX.XXX.XXX - - [08/Mar/2012:03:08:02 +0000] "GET /favicon.ico HTTP/1.1" 200 3101 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 Safari/535.19"

The requests look identical and yet the responses are different. What am I missing? Here's my code:

// (Based on Ethernet's WebClient Example)

#include "WiFly.h"
#include "Credentials.h"

const int buttonPin = 2;
const int ledPin = 3;

String url_hit = "";

WiFlyClient client("mydomain.com", 80);

void setup()
{
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);

Serial.begin(115200);
WiFly.begin();

if (!WiFly.join(ssid, passphrase))
{
Serial.println("Association failed.");
// Hang on failure.
while (1) {}
}

url_hit = "GET /hit/on/id HTTP/1.1";
}

void loop()
{
if(digitalRead(buttonPin))
{
Serial.println(getHTML(url_hit));
}
}

String getHTML(String url)
{
String html = "";
Serial.print("Connecting...");
if (client.connect())
{
Serial.println(" OK");
digitalWrite(ledPin, HIGH);

client.println(url);
client.println("User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 Safari/535.19");
client.println();

while(client.connected())
{
if (client.available())
{
char c = client.read();
html += c;
}
}

Serial.println("\nDisconnecting.");
digitalWrite(ledPin, LOW);
client.stop();
}
else
{
Serial.println(" Connection failed");
}
return html;
}

Any help would be greatly appreciated.

-George

The 400 error means "Bad Request". I'm guessing the '304' in the log entry means that 304 bytes were sent back. Did the error page have any further information? Looks like if you leave the host name out of the URI you need a "Host:" header:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html

"The most common form of Request-URI is that used to identify a resource on an origin server or gateway. In this case the absolute path of the URI MUST be transmitted (see section 3.2.1, abs_path) as the Request-URI, and the network location of the URI (authority) MUST be transmitted in a Host header field. For example, a client wishing to retrieve the resource above directly from the origin server would create a TCP connection to port 80 of the host "www.w3.org" and send the lines:

GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org

You could install wireshark on your PC and use that to capture the two requests. Then you can see any differences between the working and failing request. http://www.wireshark.org

If your server is a Linux box, you can use tcpdump to capture the packets also. Tcpdump is command-line driven.

OMG, that was it! I had to send the host. It's weird because when I instantiate the WyFly object, I have to do that by passing in the host and the port.

WiFlyClient client("mydomain.com", 80);

I assumed it would use those when I connect to a server and I wouldn't have to send it manually. Another great lesson about assuming. :slight_smile:

Thanks again for your help.

-George