HTTP/1.1 400 Bad Request

Hi guys,

I am trying to cal the function Device_id from the server but in return i got the following error:
HTTP/1.1 400 Bad Request
Code is attached for the reference.
Anyone can help?

  //second 
  int inChar;
  char outBuf[64];
  char params[65];
  //sensors_data();
 //char sen[50]="temp=%i,smoke=%i,humidity=%i",t,s,h;
//  Serial.println(sen);
//sprintf(params,"temp=%i&smoke=%i&hum=%i",t,s,h);
//sprintf(params,"TempData=%i&SmokeData=%i&HumidityData=%i",t,s,h); 
//sprintf(params,"smoke=%i",s); 
//sprintf(params,"hum=%i",h);  
//temp="temp="+t;
  Serial.print(F("connecting..."));

  if(client.connect(serverName,807) == 1)
  {
    Serial.println(F("connected"));
    sprintf(outBuf,"<R_TempData>%ld</R_TempData>",t);
    Serial.println(outBuf);

    // send the header
    client.println(F("POST  http://jms.hopto.org:806/JMS_Auth_WebService.asmx HTTP/1.1"));
  sprintf(outBuf,"POST %s HTTP/1.1",serverName);
    client.println(F("Host: jms.hopto.org"));
    client.println(F("Content-Type: text/xml; charset=utf-8"));
    client.println(F("Content-Length: 325"));
    client.println(F("Connection: close"));
    client.println(F("SOAPAction: \"http://jms.hopto.org:806/GetThresholdOfDeviceForSaud\""));
    client.println();
    client.println(F("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
    client.println(F("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"));
    client.println(F("<soap:Body>"));
    client.println(F("<GetThresholdOfDeviceForSaud xmlns=\"http://jms.hopto.org:806\">"));
   client.println(F("<ns1:Device_id>2</ns1:Device_id>"));

   //client.println(F("<R_Device_Password>65B66132E919AAFC3E8EE39E246D66CDE4087400</R_Device_Password>"));
   
    //client.println(F("<R_Device_Password>3BF3B98E46A04B36CC640513B1F68F11C0A0662E</R_Device_Password>"));
    //sprintf(outBuf,"<R_TempData>%ld</R_TempData>",t);
    //client.println(outBuf);
    //sprintf(outBuf,"<R_HumidityData>%ld</R_HumidityData>",h);
    //client.println(outBuf);
    //sprintf(outBuf,"<R_SmokeData>%ld</R_SmokeData>",s);
    //client.println(outBuf);
    client.println(F("</GetThresholdOfDeviceForSaud>"));
    client.println(F("</soap:Body>"));
    client.println(F("</soap:Envelope>"));
     //client.println(F("Connection: close"));
   // client.p`ntln();
  } 
  else
  {
    Serial.println(F("failed"));
  //  return 0;
  }

  int connectLoop = 0;

  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      connectLoop = 0;
    }

    delay(1);
    connectLoop++;
    if(connectLoop > 30000)
    {
      Serial.println();
      Serial.println(F("Timeout"));
      client.stop();
    }
  }

  Serial.println();
  Serial.println(F("disconnecting."));
  client.stop();
  
  }

The reply from the server should contain a body which explains what the problem is. Instead of just exiting the loop, read the whole reply and echo it to Serial.

Thanks @PaulMurrayCbr

I tried but received the following response.

Starting ethernet...192.168.10.2
Ready
Entered<R_TempData>30</R_TempData>
<R_smokeData>213</R_TempData>
<R_humidityData>34</R_TempData>
connecting...connected
<R_TempData>30</R_TempData>
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 03 Nov 2016 08:12:42 GMT
Connection: close
Content-Length: 4414



<html>

    <head><link rel="alternate" type="text/xml" href="/JMS_Auth_WebService.asmx?disco" />

    <style type="text/css">
    
		BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; }
		#content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; }
		A:link { color: #336699; font-weight: bold; text-decoration: underline; }
		A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; }
		A:active { color: #336699; font-weight: bold; text-decoration: underline; }
		A:hover { color: cc3300; font-weight: bold; text-decoration: underline; }
		P { color: #000000; margin-top: 0px; margin-bottom: 12px; font-family: Verdana; }
		pre { background-color: #e5e5cc; padding: 5px; font-family: Courier New; font-size: x-small; margin-top: -5px; border: 1px #f0f0e0 solid; }
		td { color: #000000; font-family: Verdana; font-size: .7em; }
		h2 { font-size: 1.5em; font-weight: bold; margin-top: 25px; margin-bottom: 10px; border-top: 1px solid #003366; margin-left: -15px; color: #003366; }
		h3 { font-size: 1.1em; color: #000000; margin-left: -15px; margin-top: 10px; margin-bottom: 10px; }
		ul { margin-top: 10px; margin-left: 20px; }
		ol { margin-top: 10px; margin-left: 20px; }
		li { margin-top: 10px; color: #000000; }
		font.value { color: darkblue; font: bold; }
		font.key { color: darkgreen; font: bold; }
		font.error { color: darkred; font: bold; }
		.heading1 { color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal; background-color: #003366; margin-top: 0px; margin-bottom: 0px; margin-left: -30px; padding-top: 10px; padding-bottom: 3px; padding-left: 15px; width: 105%; }
		.button { background-color: #dcdcdc; font-family: Verdana; font-size: 1em; border-top: #cccccc 1px solid; border-bottom: #666666 1px solid; border-left: #cccccc 1px solid; border-right: #666666 1px solid; }
		.frmheader { color: #000000; background: #dcdcdc; font-family: Verdana; font-size: .7em; font-weight: normal; border-bottom: 1px solid #dcdcdc; padding-top: 2px; padding-bottom: 2px; }
		.frmtext { font-family: Verdana; font-size: .7em; margin-top: 8px; margin-bottom: 0px; margin-left: 32px; }
		.frmInput { font-family: Verdana; font-size: 1em; }
		.intro { margin-left: -15px; }
           
    </style>

    <title>
	JMS_Auth_WebService Web Service
</title></head>

  <body>

    <div id="content">

      <p class="heading1">JMS_Auth_WebService</p>


      

      <span>

          <p class="intro">The following operations are supported.  For a formal definition, please review the <a href="JMS_Auth_WebService.asmx?WSDL">Service Description</a>. </p>
          
          
              <ul>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=AuthenticateUser">AuthenticateUser</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetListOfDevicesInBranch">GetListOfDevicesInBranch</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetThresholdOfDevice">GetThresholdOfDevice</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetThresholdOfDeviceForSaud">GetThresholdOfDeviceForSaud</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetUpdatedDataInDevice">GetUpdatedDataInDevice</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=SaveTokenAndGetBranches">SaveTokenAndGetBranches</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=SendDeviceData">SendDeviceData</a>
                
                
              </li>
              <p>
            
              </ul>
            
      </span>

      
      

    <span>
        
    </span>
    
      

      

    
  </body>
</html>

disconnecting.
1
    client.println(F("POST  http://jms.hopto.org:806/JMS_Auth_WebService.asmx HTTP/1.1"));

Rubbish. The protocol is NOT part of the GET/POST request. You have already connected to the server, so the server is NOT part of the request, either.

    client.println(F("POST  /JMS_Auth_WebService.asmx HTTP/1.1"));

So, which of the supported operations are you using in the POST request? Doesn't look to me like you are using any of the supported operations.

@PaulS
I tried using:
sprintf(outBuf,“POST /JMS_Auth_WebService.asmx HTTP/1.1”);
and get this result:

HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Thu, 03 Nov 2016 09:49:38 GMT
Connection: close
Content-Length: 326

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>
<hr><p>HTTP Error 400. The request verb is invalid.</p>
</BODY></HTML>

disconnecting

I wanna call the function “GetThresholdOfDeviceForSaud”. What should i do?

Bad Request - Invalid Verb

Doesn’t that tell you something? What verb did you use? Doesn’t it seem reasonable that none is invalid?

Every example in reply #2 has ?op=someVerb as part of the request.

I tried using:
sprintf(outBuf,"POST  /JMS_Auth_WebService.asmx HTTP/1.1");

It is pointless to use sprintf() without a format string.

    client.println(F("POST  /JMS_Auth_WebService.asmx?op=GetThresholdOfDeviceForSaud HTTP/1.1"));

I followed your suggestion:

client.println(F("POST  /JMS_Auth_WebService.asmx?op=GetThresholdOfDeviceForSaud HTTP/1.1"));

Now it shows, invalid header

Starting ethernet...192.168.10.2
Ready
Entered<R_TempData>28</R_TempData>
<R_smokeData>200</R_TempData>
<R_humidityData>35</R_TempData>
connecting...connected
<R_TempData>28</R_TempData>
HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Thu, 03 Nov 2016 10:02:01 GMT
Connection: close
Content-Length: 339

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>

disconnecting.

saudkhalid:
Thanks @PaulMurrayCbr

I tried but received the following response.

Hmm.

The following operations are supported. For a formal definition, please review the Service Description.
AuthenticateUser
GetListOfDevicesInBranch
GetThresholdOfDevice
GetThresholdOfDeviceForSaud
GetUpdatedDataInDevice
SaveTokenAndGetBranches
SendDeviceData

I don’t understand SOAP al that much, but it looks like to are trying to do a “GetThresholdOfDeviceForSaud” . Oh - hang on. That’s in the list. And you haven’t misspelled it.

Hmm.

Two possibilities are that you require an XML namespace, or that your parameter list is not quite right. I’m betting on a requirement for a namespace.

I’m not able to get info for jms.hopto.org, just the IP address 39.40.60.210 which appears to be nothing in particular, so I can’t find the docs for you. And google manly reports this thread itself when I ask about your keywords.

Anyway. Find an example packet, and look for an xmlns: declaration. Your xml declares xmi, xsd, and soap - you may be missing a default.


HTTP Error 400. The request has an invalid header name.

Excellent! Making progress!

The SOAPAction header looks a bit sus.

Hmm:

The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request.

The presence and content of the SOAPAction header field can be used by servers such as firewalls to appropriately filter SOAP request messages in HTTP. The header field value of empty string ("") means that the intent of the SOAP message is provided by the HTTP Request-URI. No value means that there is no indication of the intent of the message.

3 options:

1 - remove the header
2 - make it blank
3 - read the docs and find out what it’s supposed to be.

I wouldn’t have expected it to contain the domain name of the server you are talking to: I’d have expected it to contain soe sort of generic JMS URI.

But in any case: this is no longer an arduino problem, it’s a “how can I talk SOAP?” problem. Now that your arduino is giving you the message that it got in reply to the HTTP request, you can see that the arduino code is essentially doing the Right Thing: connecting, sending a well-formed request, etc. Your bugs are now on layer 6, which is not really this forum’s focus of interest.

Thanks. I got the response from web server HTTP/1.1 200 OK and as you mentioned, my function is also working properly. But how can i read the list that is being returned by web service?

saudkhalid:
Thanks. I got the response from web server HTTP/1.1 200 OK and as you mentioned, my function is also working properly. But how can i read the list that is being returned by web service?

After several modifications to your code, you've made some good progress, but it still doesn't do everything you want. So, you thought that you'd ask some more questions about the code that we can't see.

Doesn't work that way.

@PaulS

Here is the code

//second 
  int inChar;
  char outBuf[64];
  char params[65];
  //sensors_data();
 //char sen[50]="temp=%i,smoke=%i,humidity=%i",t,s,h;
//  Serial.println(sen);
//sprintf(params,"temp=%i&smoke=%i&hum=%i",t,s,h);
//sprintf(params,"TempData=%i&SmokeData=%i&HumidityData=%i",t,s,h); 
//sprintf(params,"smoke=%i",s); 
//sprintf(params,"hum=%i",h);  
//temp="temp="+t;
  Serial.print(F("connecting..."));

  if(client.connect(serverName,807) == 1)
  {
    Serial.println(F("connected"));
    sprintf(outBuf,"<R_TempData>%ld</R_TempData>",t);
    Serial.println(outBuf);

    // send the header
    client.println(F("GET  /JMS_Auth_WebService.asmx HTTP/1.1"));
  sprintf(outBuf,"POST %s HTTP/1.1",serverName);
    client.println(F("Host: 198.38.93.76"));
    client.println(F("Content-Type: text/xml; charset=utf-8"));
    client.println(F("Content-Length: 325"));
    client.println(F("Connection: close"));
    client.println(F("SOAPAction: \"http://jms.hopto.org:806/GetThresholdOfDeviceForSaud\""));
    client.println();
    client.println(F("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
    client.println(F("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"));
    client.println(F("<soap:Body>"));
    client.println(F("<GetThresholdOfDeviceForSaud xmlns=\"http://jms.hopto.org:806\">"));
   client.println(F("<Device_id>2</Device_id>"));

   //client.println(F("<R_Device_Password>65B66132E919AAFC3E8EE39E246D66CDE4087400</R_Device_Password>"));
   
    //client.println(F("<R_Device_Password>3BF3B98E46A04B36CC640513B1F68F11C0A0662E</R_Device_Password>"));
    //sprintf(outBuf,"<R_TempData>%ld</R_TempData>",t);
    //client.println(outBuf);
    //sprintf(outBuf,"<R_HumidityData>%ld</R_HumidityData>",h);
    //client.println(outBuf);
    //sprintf(outBuf,"<R_SmokeData>%ld</R_SmokeData>",s);
    //client.println(outBuf);
    client.println(F("</GetThresholdOfDeviceForSaud>"));
    client.println(F("</soap:Body>"));
    client.println(F("</soap:Envelope>"));
  //   client.println(F("Connection: close"));
   // client.p`ntln();
  } 
  else
  {
    Serial.println(F("failed"));
  //  return 0;
  }

  int connectLoop = 0;

  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      connectLoop = 0;
    }

    delay(1);
    connectLoop++;
    if(connectLoop > 30000)
    {
      Serial.println();
      Serial.println(F("Timeout"));
      client.stop();
    }
  }

  Serial.println();
  Serial.println(F("disconnecting."));
  client.stop();
  
  
  }

And in the result i got:

Entered<R_TempData>28</R_TempData>
<R_smokeData>192</R_TempData>
<R_humidityData>35</R_TempData>
connecting...connected
<R_TempData>28</R_TempData>
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 03 Nov 2016 18:50:15 GMT
Connection: close
Content-Length: 4414



<html>

    <head><link rel="alternate" type="text/xml" href="/JMS_Auth_WebService.asmx?disco" />

    <style type="text/css">
    
		BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; }
		#content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; }
		A:link { color: #336699; font-weight: bold; text-decoration: underline; }
		A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; }
		A:active { color: #336699; font-weight: bold; text-decoration: underline; }
		A:hover { color: cc3300; font-weight: bold; text-decoration: underline; }
		P { color: #000000; margin-top: 0px; margin-bottom: 12px; font-family: Verdana; }
		pre { background-color: #e5e5cc; padding: 5px; font-family: Courier New; font-size: x-small; margin-top: -5px; border: 1px #f0f0e0 solid; }
		td { color: #000000; font-family: Verdana; font-size: .7em; }
		h2 { font-size: 1.5em; font-weight: bold; margin-top: 25px; margin-bottom: 10px; border-top: 1px solid #003366; margin-left: -15px; color: #003366; }
		h3 { font-size: 1.1em; color: #000000; margin-left: -15px; margin-top: 10px; margin-bottom: 10px; }
		ul { margin-top: 10px; margin-left: 20px; }
		ol { margin-top: 10px; margin-left: 20px; }
		li { margin-top: 10px; color: #000000; }
		font.value { color: darkblue; font: bold; }
		font.key { color: darkgreen; font: bold; }
		font.error { color: darkred; font: bold; }
		.heading1 { color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal; background-color: #003366; margin-top: 0px; margin-bottom: 0px; margin-left: -30px; padding-top: 10px; padding-bottom: 3px; padding-left: 15px; width: 105%; }
		.button { background-color: #dcdcdc; font-family: Verdana; font-size: 1em; border-top: #cccccc 1px solid; border-bottom: #666666 1px solid; border-left: #cccccc 1px solid; border-right: #666666 1px solid; }
		.frmheader { color: #000000; background: #dcdcdc; font-family: Verdana; font-size: .7em; font-weight: normal; border-bottom: 1px solid #dcdcdc; padding-top: 2px; padding-bottom: 2px; }
		.frmtext { font-family: Verdana; font-size: .7em; margin-top: 8px; margin-bottom: 0px; margin-left: 32px; }
		.frmInput { font-family: Verdana; font-size: 1em; }
		.intro { margin-left: -15px; }
           
    </style>

    <title>
	JMS_Auth_WebService Web Service
</title></head>

  <body>

    <div id="content">

      <p class="heading1">JMS_Auth_WebService</p>


      

      <span>

          <p class="intro">The following operations are supported.  For a formal definition, please review the <a href="JMS_Auth_WebService.asmx?WSDL">Service Description</a>. </p>
          
          
              <ul>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=AuthenticateUser">AuthenticateUser</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetListOfDevicesInBranch">GetListOfDevicesInBranch</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetThresholdOfDevice">GetThresholdOfDevice</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetThresholdOfDeviceForSaud">GetThresholdOfDeviceForSaud</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=GetUpdatedDataInDevice">GetUpdatedDataInDevice</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=SaveTokenAndGetBranches">SaveTokenAndGetBranches</a>
                
                
              </li>
              <p>
            
              <li>
                <a href="JMS_Auth_WebService.asmx?op=SendDeviceData">SendDeviceData</a>
                
                
              </li>
              <p>
            
              </ul>
            
      </span>

      
      

    <span>
        
    </span>
    
      

      

    
  </body>
</html>

disconnecting.

How can i read the list that is being returned by the server? Basically i wanna read the values from the function GetThresholdOfDeviceForSaud
Your help would be appreciated

Here is the code

Is your delete key broken? All that commented out "code" is useless, since it NOT compiled, linked, uploaded or executed. Make it easy for people to help you. DELETE code that you don't want.

The code you did post is incomplete.

    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      connectLoop = 0;
    }

Just reading and printing the response from the server is not going to enable you to parse and use the reply.

Can you please send me the complete sample code for reference?

saudkhalid:
Can you please send me the complete sample code for reference?

What sample code?

Robin2 has a thread that details how to save and parse serial data. Saving and parsing client data is exactly the same.

PaulS:
What sample code?

Robin2 has a thread that details how to save and parse serial data. Saving and parsing client data is exactly the same.

http://forum.arduino.cc/index.php?topic=396450.0

First i need to get the correct response from the server then i will may parse it. However your link didn’t help me.

saudkhalid:
First i need to get the correct response from the server then i will may parse it. However your link didn't help me.

You are NOT invoking any method of the service:

    client.println(F("GET  /JMS_Auth_WebService.asmx HTTP/1.1"));

That GET request failed for you earlier, and yet now you claim that it works. It does NOT. THAT is what the service is telling you.

The response to your SOAP request is an HTML page. The reason for this is that you have not told the server what content type you would like in response. The way to fix this is to tell the server what kind of reply you want, and the way you do that is by adding an 'Accept' HTTP header.

client.println(F("Accept: application/xml"));

or

client.println(F("Accept: text/xml"));

or perhaps even

client.println(F("Accept: application/json"));

or maybe even

client.println(F("Accept: text/plain"));

If you ask for a content type that the server cannot supply, it should reply with a 406 error code.

I asked google "content type for soap reply", and apparently what it likes is "application/soap+xml". Seeing as that is what your request is, it would be polite to change this

client.println(F("Content-Type: text/xml; charset=utf-8"));

to this

client.println(F("Content-Type: application/soap+xml; charset=utf-8"));

and add

client.println(F("Accept: application/soap+xml; charset=utf-8"));

Thus: "I am sending you application/soap+xml, and I would like to receive application/soap+xml in reply".

From there, it's a matter of parsing the XML, for which I imagine there are libraries you could plug in.