-1

I have a c++ program that use socket to make HTTP POST Request. My question is how to parse the response that the server sent and put it in string vector.

Here is my code for receive:

char buffer[1028];
recv(socket, buffer, sizeof(buffer), 0);
printf("%s", buffer);

Then here is the response:

    HTTP/1.1 200 OK
    Data: Mon, 19 May 2014 12:46:36 GMT
    Server: Apache/2.4.9 (Win32) OpenSSL/0.9.8y PHP/5.4.27
    X-Powered-By: PHP/5.4.27
    Coneten-Length: 28
    Content-Type: text/html

    All done! Do some stuff now.

And what I want to get from this response are 3 message. The 200 OK, the 28 (content-length) and the actual response message "All done! Do some stuff now."

And here is my expected result:

response[0] = 200 OK;
response[1] = 28
response[2] = All done! Do some stuff now
6
  • 1
    What have you done by yourself? Commented May 19, 2014 at 11:33
  • Go hunt down a good c++ http class or library. Doing this yourself seems a bit crazy in this day and age... unless this is homework? Commented May 19, 2014 at 11:35
  • 1
    Just like any other string? This is way too broad. Your question is essentially "How do I parse a string". Also "Coneten-Length" seems dubious. Commented May 19, 2014 at 11:35
  • 4
    Here let me give you a Jeopardy answer: What is libcurl? Commented May 19, 2014 at 11:38
  • 2
    Firstly, you can't be sure to get all the data after one call to recv, even if there's ultimately less than 1028 bytes - you should check the return value from recv and loop reading further into the buffer until you hit some end-of-message delimiter or end-of-file (disconnection). Secondly, to populate your vector you'll need to find and extract specific text: there are hundreds of ways to do that - for a "C++" approach you could try std::istringstream iss(buffer); then use getline and >> - you'll find lots of examples in any introductory tutorial on "iostreams". Commented May 19, 2014 at 11:42

1 Answer 1

3

Use regex expressions to retrieve the status code and content length. Try something like this:

boost::regex regexStatus("^HTTP/\\d\\.\\d (\\d{3} .+)$");
boost::regex regexContentLength("^Content-Length: (\\d+)$");

Take the content of the first match group for both matches and convert the content length to an integer by using boost::lexical_cast. Then split the string at the two newlines and read as many bytes from the second split string as the content length indicates.

Sign up to request clarification or add additional context in comments.

3 Comments

+1 that's a reasonable hack, though strictly speaking there are lots of expectations of HTTP parsing like ignoring leading and embedded whitespace, case insensitivity, potential version numbers like 2.13 or 12.3 etc. (see e.g. [here] for starters(www.w3.org/Protocols/rfc2616/rfc2616-sec3.html)).
That's true. If you want a bullet-proof implementation either read the RFC thoroughly or use an existing library like libcurl.
I think libcurl does not offer such functionality: stackoverflow.com/questions/4580548/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.