[web] C++ HTTP Requests

Started by
20 comments, last by GameDev.net 18 years, 3 months ago
I saw a thread on it about a week or two ago but sadly the search and my attempt at a manual search resulted in a miserable failure. Does anyone know how to make HTTP requests from C++ (not .NET)? I'm looking to setup a PHP script that will take a highscore along with some type of key to validate it. The application will then call the script and upload the highscores. Or if there is any other solution available, that would be great. Maybe even running remote MySQL queries directly from the application....
Rob Loach [Website] [Projects] [Contact]
Advertisement
I use libcurl http://curl.haxx.se/ to perform http queries. It's easy to set up a multiplayer game to request a php script that returns a list of servers for example, and easy to run the php script with variables in the url to interact more with the database.
Quote:Original post by Rob Loach
Or if there is any other solution available, that would be great. Maybe even running remote MySQL queries directly from the application....


No that would be less than ideal.

This is because the user would be able to detect the MySQL login / password and put in their own data, which would be bad.

Using a PHP (or even a CGI program written in C++, maybe, so it can reuse code from the app itself) script to update high scores, list servers etc, is definitely the way to go.

It's much easier to code this sort of high-score updater or server-list manager in PHP than it would be in C++ (well, if you know PHP anyway).

A server-list manager would need to be able to query servers though to check that they were online

Mark
libwww
Free Mac Mini (I know, I'm a tool)
No other alternatives? I have yet to try either out completely, but will get to it sometime.... Anyone have any other suggestions?
Rob Loach [Website] [Projects] [Contact]
Is this it? If not (ehh it's more than a few weeks old lol), I htink you will need to use WinSock to do this in C++. Here is another thing to look at.
I suggest going the libcurl route. I've attached a really simple HTTP GET class. It should be easily modifiable to support HTTP POST or SSL, if that's what you need:

I decided to go the stateful route (only allowing the object to handle one download at a time) for 2 reasons: It allowed easy re-use of the CURL handle (which allows for pipelined transactions), and it allowed me to re-use buffers (so the user doesn't have to allocate their own entire buffer ahead of time, they just have to get a pointer). This has the downside of keeping a buffer around that's as large as the largest file you ever downloaded, but for my application, that doesn't matter. In my usage, almost all downloads will be about the same size, pipelineing is important, and the downloads will only be about ~1meg.

If all you're doing is reporting scores, then the buffer size should stay small, and it won't matter.

Obviously, the content/contentLength/contentType will be overwritten on each call to downloadFile().

HTTPDownloader.h:
#include <string>#include <curl/curl.h>#ifndef HTTP_DOWNLOADER_GUARD#define HTTP_DOWNLOADER_GUARDclass HTTPDownloader {public:	HTTPDownloader();	~HTTPDownloader();	bool downloadFile(const std::string url);	std::string contentType() const;	unsigned int contentLength() const;	char* content() const;private:	static size_t httpFetch(void* ptr, size_t size, size_t nmemb, void* stream);	CURL* curlHandle;	char* data;	unsigned int length;	unsigned int allocatedLength;	std::string type;};#endif /* HTTP_DOWNLOADER_GUARD */


HTTPDownloader.cpp
#include "HTTPDownloader.h"#include <iostream>#include <cassert>using namespace std;const int kInitialBufferSize = 1024*1024;HTTPDownloader::HTTPDownloader():curlHandle(curl_easy_init()), data(NULL), length(0), allocatedLength(0){}HTTPDownloader::~HTTPDownloader() {	curl_easy_cleanup(curlHandle);	if (data) {		free(data);		data = NULL;		allocatedLength = 0;		length = 0;	}}bool HTTPDownloader::downloadFile(const std::string url) {	length = 0;	//  set up transfer	CURLcode curlErr = curl_easy_setopt(curlHandle, CURLOPT_URL, url.c_str());	if (curlErr != CURLE_OK) {		cerr << "got curl error on setopt url " << curlErr << endl;		return false;	}	curlErr = curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, httpFetch);	if (curlErr != CURLE_OK) {		cerr << "got curl error on setopt func " << curlErr << endl;		return false;	}	curlErr = curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, this);	if (curlErr != CURLE_OK) {		cerr << "got curl error on setopt url " << curlErr << endl;		return false;	}	//  perform transfer	curlErr = curl_easy_perform(curlHandle);	if (curlErr != CURLE_OK) {		cerr << "got curl error on perform " << curlErr << endl;		return false;	}	char* contentType = NULL;	curlErr = curl_easy_getinfo(curlHandle, CURLINFO_CONTENT_TYPE, &contentType);	if (curlErr != CURLE_OK) {		cerr << "got curl error on getopt for CONTENT_TYPE " << curlErr << endl;		return false;	}	type = string(contentType);	return true;}std::string HTTPDownloader::contentType() const {	return type;}unsigned int HTTPDownloader::contentLength() const {	return length;}char* HTTPDownloader::content() const {	return data;}size_t HTTPDownloader::httpFetch(void* ptr, size_t size, size_t nmemb, void* stream) {	HTTPDownloader* handle = (HTTPDownloader*)stream;	size_t newDataSize = size*nmemb;	if (handle->data == NULL) {		assert(handle->allocatedLength == 0);		handle->data = (char*)malloc(kInitialBufferSize);		handle->allocatedLength = kInitialBufferSize;		handle->length = 0;	}	while (handle->length+newDataSize+1 > handle->allocatedLength) {		assert(handle->allocatedLength > 0);		handle->data = (char*)realloc(handle->data, handle->allocatedLength*2);		handle->allocatedLength *= 2;	}	memcpy(handle->data + handle->length, ptr, newDataSize);	handle->length += newDataSize;	return newDataSize;}
Why not simply use sockets and send out the HTTP requests directly by yourself? As long as you don't anything too fancy, it won't be really hard. And there is a lot of resource available on the HTTP protocol on internet.
[google]
Just found a libcURL Wrapper courtasy of Mayukh. I haven't tried it out yet, but it looks pretty good.

Sorry for the necro, I just thought this needed mentioning.
Rob Loach [Website] [Projects] [Contact]

This topic is closed to new replies.

Advertisement