-
POSTing data
Hi everyone. I'm slowly figuring out the ins and outs of C... at the moment I'm trying to create a small program that connects to a device via HTTP and sends some data via POST. I've managed to convert the MSDN existing code for my own use; at the moment I can request a file from the device.
From using Intel's UPnP tools, this is the entire data that I need to send to the device:
Code:
POST /AudioIn/Control HTTP/1.1
HOST: 10.0.1.136:1400
SOAPACTION: "urn:schemas-upnp-org:service:AudioIn:1#GetAudioInputName"
CONTENT-TYPE: text/xml ; charset="utf-8"
Content-Length: 286
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetAudioInputName xmlns:u="urn:schemas-upnp-org:service:AudioIn:1" />
</s:Body>
</s:Envelope>
I assume I have to put that code in the "WINHTTP_NO_ADDITIONAL_HEADERS" area of the following statement:
Code:
if( hRequest )
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
"sweet", 0,
0, 0 );
Is that right? I can post my whole code if requested, its only about 100 lines. It's very similar to the sample on MSDN
So... I guess my question is, is this the right way of going about a POST? Later on I'll have to recieve a response from the device but I'd like to get this down first.
-
No, you have to send the POST length as well.
Code:
if( hRequest )
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
"sweet", 5,
5, 0 );
-
OK, I've moved on a bit now. Managed to iron out most of the POST I think. Here's the code I've added at the start:
Code:
// UPnP request to be sent via POST in XML format
char *PostData =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
" <s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
" <s:Body>\n"
" <u:GetAudioInputName xmlns:u=\"urn:schemas-upnp-org:service:AudioIn:1\" />\n"
" </s:Body>\n"
"</s:Envelope>";
// SOAP header required for UPnP request
unsigned char *ExtraHeader = "SOAPACTION: \"urn:schemas-upnp-org:service:AudioIn:1#GetAudioInputName\"";
// Length of UPnP request
char PostLength = lstrlen(PostData)*sizeof(TCHAR);
// Length of SOAP header
char HeaderLength = lstrlen(ExtraHeader)*sizeof(TCHAR);
// Total length
char TotalLength = PostLength + HeaderLength;
// FYI
printf("postlength is %d\n", PostLength);
printf("headerlength is %d\n", HeaderLength);
printf("totallength is %d\n", TotalLength);
(By the way - the SOAP header gave a huge horrible error - assignment of pointer to const unsigned short to pointer to char - until I added the word "unsigned" in front of it. I hope this was the right fix, all I know is that it works.)
Anyway, here's my new HTTP request code:
Code:
// Send a request.
if( hRequest )
bResults = WinHttpSendRequest( hRequest,
ExtraHeader,
HeaderLength,
PostData, PostLength,
PostLength, 0 );
This now returns an error 87, which I beleive may be due to incorrect values of HeaderLength, PostLength and/or TotalLength.
Interestingly enough, when I run my program, with my "FYI" information that prints out the lengths of the header and POST data, this is what I get:
Code:
postlength is 18
headerlength is 70
totallength is 88
Now the 70 value looks about right, and totallength is calculating OK, but I know for a fact that the XML code I'm sending is a lot longer than 18 characters! What am i doing wrong here?
One more question - why do I use "*sizeof(TCHAR)" when figuring out length? I got that code from another sample somewhere.
-
I'm not sure. I copied/pasted your code into my compiler, and it gave me 274, not 18.
-
Fuh. I blame LCC or something.
Anyway, made a bit of progress.
New code that gives correct lengths:
Code:
// Length of UPnP request
int PostLength = strlen(PostData);
// Length of SOAP header
int HeaderLength = strlen(ExtraHeader);
// Total length
int TotalLength = PostLength + HeaderLength;
and
Code:
// Send a request.
if( hRequest )
bResults = WinHttpSendRequest( hRequest,
ExtraHeader, HeaderLength, // extra header data and length
PostData, PostLength, //data to post and length
TotalLength, 0 ); // length of extra header plus post data
Still getting Error 87. What's the deal? Should I post all my code?
-
OK, I think I've broken it down some more.
Here's what I need to have in my WinHttpSendRequest statement (from the MSDN article ):
pwszHeaders
[in] A pointer to a string that contains the additional headers to append to the request. This parameter can be WINHTTP_NO_ADDITIONAL_HEADERS if there are no additional headers to append.
It seems the POST data is a "pointer to a buffer" (char *postdata = "post data"; works) but the headers are a "pointer to a string". I don't know how to make a pointer to a string. God only knows why they aren't BOTH a "pointer to a buffer". I guess I'll start googling...
-
char *postdata = "post data"; is not a pointer to a buffer. It's a pointer to a string. If you want to pass a pointer to a buffer then just pass the name of the buffer. Example:
Code:
{
char buffer[512];
SomeFuncThatWantsABuffer(buffer);
}
-
Thats what I suspected... but... well... it works. I mean that part of my code does. WinHttpSendRequest accepts the code fine.
:/