Filter data received from HTTP request - c++

So in my c++ program i create a socket then download file from my web server (website) which retrieves a http response (using recv) then store response in char buffer, in this question let's say the buffer identifier is something like httpbufff, if i take httpbufff and cout it, it will look like this:
HTTP/1.1 200 OK
Date: Tue, 12 Jul 2016 08:52:15 GMT
Server: Apache/2.4.16
X-Powered-By: PHP/5.4.45
Vary: Accept-Encoding,User-Agent
Connection: close
Content-Type: text/html
Website content test
My question is, is there a way to extract "Website content test" from my char buffer httpbufff?
I was thinking about using strtok but that doesn't seem like a good solution in my opinion.
thanks!

Related

HTTP/1.1 401 Unauthorized in Response Headers in Load runner for GET Requests

I am new to Load runner , Am facing am issue while play back of the script
LR 12.50
O.S Windows 7 SP2
Protocol is Mobile HTTP/HTML
Recording mode is Proxy
Let me explain my scenario
While executing following function:
web_custom_request("authenticate",
"URL=https://ws-xx.xxx.com/tcs/rest/authenticate?include=user,company",
"Method=POST",
"Resource=0",
"RecContentType=application/json",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTTP",
"EncType=application/json",
"Body={\"password\":\"xxx\",\"username\":\"xxx\",\"version\":\"1.0.40\"}",
LAST);
For the above POST method , am getting response as below
HTTP/1.1 200 OK\r\n
Date: Tue, 13 Oct 2015 19:19:21 GMT\r\n
Server: Apache-Coyote/1.1\r\n
Content-Type: application/json\r\n
Set-Cookie: dtCookie=DBE9311E44E5C47902702DC762030583|TXlBcHB8MQ; Path=/;
Domain=.xxx.com\r\n
Connection: close\r\n
Transfer-Encoding: chunked\r\n
Which is fine ,Now the second custom request is shown below
web_custom_request("profiles",
"URL=https://ws-test.xxx.com/tcs/rest/profiles",
"Method=GET",
"Resource=1",
"RecContentType=application/json",
"Referer=",
"Snapshot=t2.inf",
LAST);
For the above GET requests in the replay logs am getting:
401 unauthorized error.
GET /tcs/rest/profiles HTTP/1.1\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)\r\n
Accept: */*\r\n
Connection: Keep-Alive\r\n
Host: ws-test.xxx.com\r\n
Cookie: dtCookie=DBE9311E44E5C47902702DC762030583|TXlBcHB8MQ\r\n
\r\n
t=5921ms: 172-byte response headers for "https://ws-test.xxx.com/tcs/rest/profiles" (RelFrameId=1, Internal ID=2)
HTTP/1.1 401 Unauthorized\r\n
Date: Tue, 13 Oct 2015 19:19:22 GMT\r\n
Server: Apache-Coyote/1.1\r\n
Content-Type: application/json\r\n
Connection: close\r\n
Transfer-Encoding: chunked\r\n
\r\n
t=5922ms: 4-byte chunked response overhead for "https://ws-test.xxx.com/tcs/rest/profiles" (RelFrameId=1, Internal ID=2)
8b\r\n
t=5923ms: 139-byte chunked response body for "https://ws-test.xxx.com/tcs/rest/profiles" (RelFrameId=1, Internal ID=2)
{"errors":[{"message":"Authentication required to access endpoint","status":"401","code":"
NotAuthenticated","header":"Not Authenticated"}]}
I refereed this link.
My understanding from the above custom request , login is success but the next
subsequent requests are getting failed.
I have used web_cleanup_cookies() function but didn't solve the issue .
I tried to capture the Cookie ID using the below function
web_reg_save_param("COOKIE_ID",
"LR= Cookie: dtCookie=" ,
"RB= |TXlBcHB8MQ\r\n",
"Ord=All",
"RelFrameId=1",
"Search=All",
LAST);
web_add_header("Cookie",lr_eval_string("{COOKIE_ID}"));
Now question is where to place parameter "COOKIE_ID" in my script while there is
no value in script for COOKIE_ID?
How to handle this issue ? Can anybody please help me .
Please add below headers to the script
web_set_sockets_option("SSL_VERSION","TLS");
web_set_user("username", "password", "domain:portno" );
web_set_sockets_option("INITIAL_BASIC_AUTH","1");
In Vugen, Select snapshot view and compare both record and replay requests, suspecting there might be a missing of header in replay request.
If cookie is the only thing changing you can add it by using web_add_cookie function.

What is the quickest way to retrieve remote file size from HTTP server that doesn't support HEAD?

I am trying to download 1000s of files which may be very large (several GB) from an HTTP site using PycURL.
Everything was going swimmingly until I decided to check for partial downloads, so tried to use info I found on this forum to try to get the Content-Length. Once I realised it was always returning 179.0, I looked into the response and found that 179.0 seems to be the length of the "Why didn't you check first that what you are doing is supported?" response.
>>> c.setopt(c.RANGE, "NULL")
>>> c.setopt(c.HEADER,1)
>>> c.setopt(c.NOBODY,1)
>>> c.perform()
HTTP/1.1 501 Not Implemented
Date: Fri, 14 Aug 2015 02:00:35 GMT
Server: Apache-Coyote/1.1
Pragma: no-cache
DataServiceVersion: 1.0
Content-Type: application/xml
Content-Length: 179
Second attempt to get the size, I tried using RANGE. Range works on the server but running the suggested 0-0 seems to be extremely slow.
>>> c.setopt(c.RANGE, "0-0")
>>> c.setopt(c.HEADER,1)
>>> c.setopt(c.NOBODY,0)
>>> c.perform()
HTTP/1.1 206 Partial Content
Date: Fri, 14 Aug 2015 02:05:15 GMT
Server: Apache-Coyote/1.1
Pragma: no-cache
Accept-Ranges: bytes
Content-Disposition: inline; filename="foo.zip"
Content-Range: bytes 0-0/2278939680
I don't need to stick with PycURL to find the size but I do need speed.
N.B. I'm using Python 2.7

Multipart/form-data request to Drupal 7 REST server/Services module returns FALSE with 200 status code on file upload

I have been working for the last couple of days trying to get a file upload to my drupal REST Server and I feel like I am close but I am getting a somewhat confusing 200 status code with a response of "false". I am a total http-request novice so I have been having some trouble. Here is what my http-post looks like:
POST /?q=rest/file HTTP/1.1
Host: localhost:8888
Language: en-us,en;q=0.5Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Accept-Charset: ISO-8859-1,utf-8
Cookie: SESSdc0685ed01f285dab628a3700259e6bc=UAdNJUsQL5TpqEXIWFtXEcLw3wooEwqW9e0JxSz2ZHw
Content-Length: 389
Content-Type: multipart/form-data; boundary=---------------------------1137522503144128232716531729
-----------------------------1137522503144128232716531729
Content-Disposition: form-data; name=\"file\"; filename=\"empty folder.zip\"
Content-Type: application/zip
..
encoded content here
..
-----------------------------1137522503144128232716531729--
And the response I get is simply "false with a header that looks like this:
(("Content-Type" "application/json") ("Connection" "Keep-Alive") ("Keep-Alive" "timeout=5, max=100") ("Content-Length" "5") ("Vary" "Accept") ("ETag" "\"1328910809\"") ("Cache-Control" "no-cache, must-revalidate, post-check=0, pre-check=0") ("Last-Modified" "Fri, 10 Feb 2012 21:53:29 +0000") ("Expires" "Sun, 19 Nov 1978 05:00:00 GMT") ("X-Powered-By" "PHP/5.3.6") ("Server" "Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6") ("Date" "Fri, 10 Feb 2012 21:53:29 GMT") ("Status" "HTTP/1.1 200 OK"))
and status code 200. Also, the file is does not actually show up in the Drupal file system. Could the problem be that I need to specify where to put it? I snooped the http-post from the actual Drupal form and it looks almost identical to my post accept it has many more pieces of content.

Using a TCP connection to GET data from a HTTP server, on rare occasion there's garbage data

I'm writing a networked game in C++ using Winsocks 2.2, using Visual Studio 2010, and decided it would be a good idea to use my web-server to store a list of active servers for the game. When a server starts up, it will register itself with my web server, on exit un-register; and the server itself will attempt to clean the list when someone accesses the server list depending (this behavior I'm still working on designing to not involve too much work on the server; but I figured when the game server tries to add itself, my php file will use fsockopen to detect if it can actually access the server from an outside network, if not, the server won't get added until it can properly setup port forwarding or somehow resolve the issue).
Okay, so after some research, I figured out how to get something from the server using a TCP connection from formatting a specialized message for the HTTP server. Here's what I have:
if(FAIL == Connection::Get_Connection(&m_Connection, networkSettings.ServerListAddress, 80))
{
return FAIL;
}
m_Connection.SendMsg("GET /servers.php HTTP/1.1\r\nHost: cyclotron.leetnightshade.com\r\nUser-Agent: CycloTron\r\n\r\n");
I'm expecting back properly formatted data, which I'm not exactly getting. Here's what I'm getting:
2f
Server Count:1
129.21.138.1,40000,Depth of Hell
0
Here's another output of some garbage with all the header information:
HTTP/1.1 200 OK
Date: Tue, 12 Apr 2011 23:23:11 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=8254688ee345202bd177d57e4ba339b2; path=/
Set-Cookie: PHPSESSID=73eae89f61e7268f433af9bdfe299173; path=/
Set-Cookie: PHPSESSID=8fb5d6fd9f1023bb00290b4daa3c7952; path=/
Connection: close
Transfer-Encoding: chunked
Content-Type: text; charset=us-ascii
e
Server Count:1
21
129.21.138.1,40000,Depth of Hell
0
This is what my output is supposed to look like, and I do get this on occasion, but not all the time:
HTTP/1.1 200 OK
Date: Tue, 12 Apr 2011 23:32:13 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=a3c88c2d96d45c6f6d3b029e095c429a; path=/
Set-Cookie: PHPSESSID=bf19734ff60813d6d0a5ba944410356a; path=/
Set-Cookie: PHPSESSID=c36a2d9e12c81d4a19a7f41dc5522b4e; path=/
Content-Length: 47
Connection: close
Content-Type: text; charset=us-ascii
Server Count:1
129.21.138.1,40000,Depth of Hell
I don't think this matters too much, but this is my PHP code on the web server:
$num = mysql_num_rows($result);
echo 'Server Count:'.$num;
while ($row = mysql_fetch_assoc($result))
{
// TODO: check date of entry, if it's really old, remove it.
echo PHP_EOL.$row['address'].','.$row['port'].','.$row['displayName'];
}
And here's some of the code involving receiving the string (yes it's a little bare bones at the moment, and I realize I could use a cstring function to look for the two new lines so I don't have to do the string copy, I'm just trying to stick to using strings to make things easier):
memset(m_MsgBuffer, 0, sizeof (char) * M_BufferSize);
m_Received = recv(m_Connection.M_Socket, m_MsgBuffer, M_BufferSize, 0);
m_MsgBuffer[m_Received] = '\0';
string str = string(m_MsgBuffer);
size_t index = str.find("\r\n\r\n");
str.erase(0,index);
std::cout << "Received message: " << str << std::endl;
So, do any of you have an idea where this garbage data is coming from?
EDIT: After looking at the correct header information, the one with garbage has "Transfer-Encoding: chunked" and doens't have "content-length." ...what is going on?
The so-called "garbage" is in fact the chunked data from the server. An HTTP/1.1 server is free to send data back in chunked format, if it prefers, and the HTTP/1.1 spec is pretty clear: "All HTTP/1.1 applications MUST be able to receive and decode the "chunked" transfer-coding".
The details of chunked encoding are described in the HTTP/1.1 spec:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
If you are writing an HTTP client, you need to read the HTTP spec...

Detecting characters in C++ char stream

I am working on a piece of arduino code that is using the BlackWidow version with wifi built in. Using the WiServer.h library, I'm using the SimpleClient.pde example with mods to send a call to a webserver that will simply return an integer - 0, 1, or 2. The end goal is to turn on a pin for the proper red, green, or yellow of a stoplight. The integers represent the aggregate state of our Hudson CI.
I'm a PHP lazy bastard, and pointers scare me. The code I am working with is
// Function that prints data from the server
void printData(char* data, int len) {
// Print the data returned by the server
// Note that the data is not null-terminated, may be broken up into smaller packets, and
// includes the HTTP header.
while (len-- > 0) {
Serial.print(*(data++));
}
}
printData() is the callback of the call to the webserver, and when run it sends the following to the serial monitor (this is 3 loops, no newline before new output):
HTTP/1.1 200 OK
Date: Thu, 10 Feb 2011 17:37:37 GMT
Server: Apache/2.2.13 (Unix) mod_ssl/2.2.13 OpenSSL/0.9.8k DAV/2 PHP/5.2.11
X-Powered-By: PHP/5.2.11
Content-Length: 1
Connection: close
Content-Type: text/html
0HTTP/1.1 200 OK
Date: Thu, 10 Feb 2011 17:37:45 GMT
Server: Apache/2.2.13 (Unix) mod_ssl/2.2.13 OpenSSL/0.9.8k DAV/2 PHP/5.2.11
X-Powered-By: PHP/5.2.11
Content-Length: 1
Connection: close
Content-Type: text/html
0HTTP/1.1 200 OK
Date: Thu, 10 Feb 2011 17:37:58 GMT
Server: Apache/2.2.13 (Unix) mod_ssl/2.2.13 OpenSSL/0.9.8k DAV/2 PHP/5.2.11
X-Powered-By: PHP/5.2.11
Content-Length: 1
Connection: close
Content-Type: text/html
0
The part that I need to identify is the 0, which could also be 1 or 2.
Instead of printData(), this function will become turnOnAppropriateLight() or something, by simply setting a pin to HIGH. This will then activate a relay, to power the corresponding LED array.
Now that I've written this up it looks like I just need to keep the last character around and do a switch based on the value. The *(data++) is the confusing part even though I know it's incrementing a pointer index...I'm just not sure how to go directly to the last char in that index. No need for this looping to spit out the result.
This is not robust AT ALL, but
Serial.print(data[len-1])
See what that gets you
this should be all you need:
data[len - 1]
You could be neurotic and parse each line, or look for the last tags: Content-Type:.
I would convert the C-style string into a C++ std::string then use the find_first method to look for the keywords.
The std::istringstream can be used to convert from text "0" to numeric 0.