C++ Header

Hi, I've always used CURL, but I was forced to use sockets this time for some reason. This is my code;

#include "stdafx.h"
#include <winsock2.h>
#include <string>
#include <iostream>
using namespace std;

void HTTPReq(
    const char* verb,
    const char* hostname,
    int port,
    const char* resource,
    const char* opt_urlencoded,
    string& response)
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
    {
        cout << "WSAStartup failed.\n";
        exit(1);
    }

    SOCKET Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    struct hostent *host;
    host = gethostbyname(hostname);

    SOCKADDR_IN SockAddr;
    SockAddr.sin_port=htons(port);
    SockAddr.sin_family=AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

    if (connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0)
    {
        exit(1);
    }

    // Build request
    string req = verb; // GET | POST
    req.append(" ");
    // Note, on GET, 'resource' must contain the encoded parameters, if any:
    req.append(resource);
    req.append(" HTTP/1.1\r\n");

    req.append("Host: ");
    req.append(hostname);
    req.append(":");
    req.append(to_string(static_cast<long long>(port)));
    req.append("\r\n");

    if (strcmp(verb, "POST") == 0)
    {
        req.append("Cache-Control: no-cache\r\n");
        req.append("Content-length: ");
        req.append(to_string(static_cast<long long>(strlen(opt_urlencoded))));
        req.append("\r\n");
        req.append("Content-Type: application/x-www-form-urlencoded\r\n\r\n");

        // User is required to handle URI encoding for this value
        req.append(opt_urlencoded);

    }
    else // default, GET
    {
        req.append("Cache-Control: no-cache\r\n");
        req.append("Connection: close\r\n\r\n");
    }


    send(Socket, req.c_str(), req.size(), 0);

    char buffer[1024*10];
    int nlen;

    while ((nlen = recv(Socket,buffer,1024*10,0)) > 0)
    {
        response.append(buffer, 0, nlen);
    }
    closesocket(Socket);
    WSACleanup();

}

void main()
{
	string response;
    HTTPReq("GET", "MYIP", 80, "/crypto/index.php", NULL, response);

    cout << "==============================="
        << endl
        << response
        << endl
        << "=============================== "
        << endl;
}

Open in new window



My problem is that the code is returning beyond the response and header. I need only response! No need header...



a
magdiel linharesAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Fabrice LambertFabrice LambertCommented:
Hi,

This is the way web servers answer to HTTP requests: with headers AND response (unless you ask for an HEAD request, in this case, you only get headers).
You'll have to parse the returned data and strip whatever you don't need.
But, don't overlook headers, they hold usefull data, starting with the error code returned by the server.
In you case: 200, wich mean the server processed your request without troubles (I suggest you take a look at HTTP error codes).

And while I'm at it:
Using the directive "using namespace std;" is considered a bad practice. It's sole purpose was to maintain hold code base when namespaces were introduced in C++ (back in 1990).
Modern codes should not use it.
Either fully qualify your functions call with the correct namespace or select precisely what you need:
int main()
{
    std::cout << "Hello world." << std::endl;
}

int main()
{
    using std::cout;
    using std::endl;

    cout << "Hello world." << endl;
}

Open in new window

Pre-declaring variables is also considered a bad practice, as it give vaiables a longer lifetime than needed.

The main function should return an integer, this inform the server that you app terminated as expected (return 0) or not.

Finally, concerning sockets, you might be interrested by the boost::asio library, wich is full C++ enabled (instead of using those horribles C-style arrays).
0
sarabandeCommented:
you may try

int main()
{
    std::string response, result;
    HTTPReq("GET", "MYIP", 80, "/crypto/index.php", NULL, response);

    size_t lpos = response.find("Content-Type:");
    if (lpos != std::string::npos) 
    {
         lpos = response.find(std::endl, lpos+1);
         if (lpos  != std::string::npos)
         {
                result = response.substr(lpos+1);
                response.resize(lpos);
         }
    }
    
    std::cout << "==============================="
        << std::endl
        << response
        << std::endl
        << "=============================== "
        <<  result
        << std::endl;
        return 0;   // means no error
}

Open in new window


of course you should add some error handling (probably HTTPReq should return success or error code) and take advice from Fabrice.

Sara
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.