Aller au contenu

Warning

This page refers to an in-development version of SFML and as such may not have been updated yet.
Click here to navigate to the version of the latest official release.

Web requests with HTTP

Introduction

SFML provides a simple HTTP client class which you can use to communicate with HTTP servers. "Simple" means that it supports the most basic features of HTTP: POST, GET and HEAD request types, accessing HTTP header fields, and reading/writing the pages body.

If you need more advanced features, such as secured HTTP (HTTPS) for example, you're better off using a true HTTP library, like libcurl or cpp-netlib.

For basic interaction between your program and an HTTP server, it should be enough.

sf::Http

To communicate with an HTTP server you must use the sf::Http class.

#include <SFML/Network.hpp>

sf::Http http;
http.setHost("http://www.some-server.org/");

// or
sf::Http http("http://www.some-server.org/");

Note that setting the host doesn't trigger any connection. A temporary connection is created for each request.

The only other function in sf::Http, sends requests. This is basically all that the class does.

sf::Http::Request request;
// fill the request...
sf::Http::Response response = http.sendRequest(request);

Requests

An HTTP request, represented by the sf::Http::Request class, contains the following information:

  • The method: POST (send content), GET (retrieve a resource), HEAD (retrieve a resource header, without its body)
  • The URI: the address of the resource (page, image, ...) to get/post, relative to the root directory
  • The HTTP version (it is 1.0 by default but you can choose a different version if you use specific features)
  • The header: a set of fields with key and value
  • The body of the page (used only with the POST method)
sf::Http::Request request;
request.setMethod(sf::Http::Request::Post);
request.setUri("/page.html");
request.setHttpVersion(1, 1); // HTTP 1.1
request.setField("From", "me");
request.setField("Content-Type", "application/x-www-form-urlencoded");
request.setBody("para1=value1&param2=value2");

sf::Http::Response response = http.sendRequest(request);

SFML automatically fills mandatory header fields, such as "Host", "Content-Length", etc. You can send your requests without worrying about them. SFML will do its best to make sure they are valid.

Responses

If the sf::Http class could successfully connect to the host and send the request, a response is sent back and returned to the user, encapsulated in an instance of the sf::Http::Response class. Responses contain the following members:

  • A status code which precisely indicates how the server processed the request (OK, redirected, not found, etc.)
  • The HTTP version of the server
  • The header: a set of fields with key and value
  • The body of the response
sf::Http::Response response = http.sendRequest(request);
std::cout << "status: " << response.getStatus() << std::endl;
std::cout << "HTTP version: " << response.getMajorHttpVersion() << "." << response.getMinorHttpVersion() << std::endl;
std::cout << "Content-Type header:" << response.getField("Content-Type") << std::endl;
std::cout << "body: " << response.getBody() << std::endl;

The status code can be used to check whether the request was successfully processed or not: codes 2xx represent success, codes 3xx represent a redirection, codes 4xx represent client errors, codes 5xx represent server errors, and codes 10xx represent SFML specific errors which are not part of the HTTP standard.

Example: sending scores to an online server

Here is a short example that demonstrates how to perform a simple task: Sending a score to an online database.

#include <SFML/Network.hpp>
#include <sstream>

void sendScore(int score, const std::string& name)
{
    // prepare the request
    sf::Http::Request request("/send-score.php", sf::Http::Request::Post);

    // encode the parameters in the request body
    std::ostringstream stream;
    stream << "name=" << name << "&score=" << score;
    request.setBody(stream.str());

    // send the request
    sf::Http http("http://www.myserver.com/");
    sf::Http::Response response = http.sendRequest(request);

    // check the status
    if (response.getStatus() == sf::Http::Response::Ok)
    {
        // check the contents of the response
        std::cout << response.getBody() << std::endl;
    }
    else
    {
        std::cout << "request failed" << std::endl;
    }
}

Of course, this is a very simple way to handle online scores. There's no protection: Anybody could easily send a false score. A more robust approach would probably involve an extra parameter, like a hash code that ensures that the request was sent by the program. That is beyond the scope of this tutorial.

And finally, here is a very simple example of what the PHP page on server might look like.

<?php
    $name = $_POST['name'];
    $score = $_POST['score'];

    if (write_to_database($name, $score)) // this is not a PHP tutorial :)
    {
        echo "name and score added!";
    }
    else
    {
        echo "failed to write name and score to database...";
    }
?>