HTTP GET Request results in 400 Bad Request

Hello,

Some assistance would be appreciated on this matter. I have searched the forums for some answers and have tried the following:

WiFiClient client;
//IPAddress server(149,255,60,143);  // numeric IP for Webserver (no DNS)
char server[] = "saavanhirani.co.uk";    // name address for Webserver
String headerTwo = "GET /test/php/Arduino.txt";
String footerOne = " HTTP/1.0";
if(stringThree != 0) {
  client.print(headerTwo);
  Serial.print(headerTwo);
//  client.print(headerOne);
//  Serial.print(headerOne);
//  client.print(stringOne);
//  Serial.print(stringOne);
//  client.print(stringTwo);
//  Serial.print(stringTwo);
//  client.print(stringThree);
//  Serial.print(stringThree);
//  client.print(stringFour);
//  Serial.print(stringFour);
  client.println(footerOne);
  Serial.println(footerOne);
  client.println("Host: www.saavanhirani.co.uk");
  Serial.println("Host: www.saavanhirani.co.uk");
  client.println("Connection: close");
  Serial.println("Connection: close");
  client.println();
  Serial.println();

  while(client.connected() && !client.available()) delay(1);
  while(client.connected() || client.available()) {
    char c = client.read();
    Serial.write(c);
  }
  delay(100);
}

Here is the output from the serial monitor:

GET /test/php/Arduino.txt HTTP/1.0
Host:saavanhirani.co.uk
Connection: close

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.

045</p>
<hr>
<address>Apache Server at default Port 80</address>
</body></html>

So I have tried adding the \n\r's to the end of my lines with no joy, even tried adjusting HTTP1.1 to 1.0 for those permutations with no joy. Have tried changing the directory the files are stored in on my web space.

So I have been using the Arduino.txt just to see if I can actaully GET this test file. My end game is to be able to request:

GET /test/php/parse.php?id=xxxxxxxxxxxx HTTP/1.1

Hope this is enough information, please let me know if you need more.

Thanks.

What does the error log on the hosting side say? It may have a clue why that URL isn't correct.

-br

Try the below code and see if it works. Is so, compare to your code.

//zoomkat 9-22-12
//simple client test
//for use with IDE 1.0.1
//with DNS, DHCP, and Host
//open serial monitor and send an e to test
//for use with W5100 based ethernet shields
//remove SD card if inserted

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address

char serverName[] = "web.comporium.net"; // zoomkat's test web page server
EthernetClient client;

//////////////////////

void setup(){

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }

  Serial.begin(9600); 
  Serial.println("Better client test 9/22/12"); // so I can keep track of what is loaded
  Serial.println("Send an e in serial monitor to test"); // what to do to test
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) //if something in serial buffer
  {
    byte inChar; // sets inChar as a byte
    inChar = Serial.read(); //gets byte from buffer
    if(inChar == 'e') // checks to see byte is an e
    {
      sendGET(); // call sendGET function below when byte is an e
    }
  }  
} 

//////////////////////////

void sendGET() //client function to send/receive GET request data.
{
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0"); //download text
    client.println("Host: web.comporium.net");
    client.println(); //end of get request
  } 
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    Serial.print(c); //prints byte to serial monitor 
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop(); //stop client

}

You must should send the GET request line in one packet. You are sending it in two.

String headerTwo = "GET /test/php/Arduino.txt";
String footerOne = " HTTP/1.0";

  // here is one packet
  client.print(headerTwo);
  Serial.print(headerTwo);

  // here is a second packet
  client.println(footerOne);
  Serial.println(footerOne);

Try this instead:

String headerTwo = "GET /test/php/Arduino.txt HTTP/1.0";

  client.print(headerTwo);
  Serial.print(headerTwo);

edit: Some servers will take the GET request in two packets, and some won't.
BTW, I tested that page with my client code and got this page:
THIS IS A TEST GET REQUEST...TEXT DOC

Thanks for all the assistance, I have managed to solve the problem.

Firstly thanks to Zoomkat, I had run into your code before, hence the adoption of the 'listen' function.

Billroy, your suggestion to look at the logs also helped immensely when finally getting my request working and tracking down the ensuing '500' errors when it came to the DB connection.

SurferTim, Thanks to you I went back to basics and found that the order of initialisation with my functions was the problem. I had previously upon start up, had my sensor (RFID) set-up, then connection to the internet, then connection to server. The incoming strings from the sensor (loop) would then trigger the request. However the previous connection to the server form initialisation was not maintained and that's what was throwing those '400's'. So I simply put a check before sending the client requests to check if the server connection was still alive.

Also I had taken your advice to try and send the request in a single packet but was failing miserably with reliably concatenating the various strings involved (header, request variable 1-4 (from RFID), footer). In the end, sending one at a time was not a problem for my server to handle and made life a lot easier for me.

However I did find that using the (F("xxx")); for printing static strings helped a lot with memory leaks and made the whole process more reliable. In that the reading from the sensor did not occasionally miss a particular byte (1-4).

Here is the output from my serial monitor for those who may find it useful:

Initialised Serial Port at 9600bps
Attempting to connect to WPA network, SSID: MVH-NETGEAR2
You're connected to the network

Network SSID: XXX-XXXXXXX
BSSID (Router MAC): XX:XX:XX:XX:XX:XX
WiFi Shield IP Address: XXX.XXX.X.XX
WiFi Shield MAC address: XX:XX:X:XX:XX:XX
Signal Strength (RSSI): -43
Encryption Type: 4

1st:1
2nd:149
3rd:213
4th:36
-----------------

Starting connection to server...
connected to server
GET /test/php/parse.php?request=114921336 HTTP/1.0
Host: www.saavanhirani.co.uk
Connection: close

HTTP/1.1 200 OK
Date: Tue, 16 Apr 2013 17:58:00 GMT
Server: Apache
X-Powered-By: PleskLin
Content-Length: 79
Connection: close
Content-Type: text/html

{"Patient_ID":"114921336","0":"114921336","NHS Number":"4678832","1":"4678832"}
1st:1
2nd:183
3rd:187
4th:192
-----------------

Starting connection to server...
connected to server
GET /test/php/parse.php?request=1183187192 HTTP/1.0
Host: www.saavanhirani.co.uk
Connection: close

HTTP/1.1 200 OK
Date: Tue, 16 Apr 2013 17:58:07 GMT
Server: Apache
X-Powered-By: PleskLin
Content-Length: 81
Connection: close
Content-Type: text/html

{"Patient_ID":"1183187192","0":"1183187192","NHS Number":"1566745","1":"1566745"}

Thanks again. If need of any of the code used, feel free to let me know.