Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:58:14

0001 ////////////////////////////////////////////////////////////
0002 //
0003 // SFML - Simple and Fast Multimedia Library
0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
0005 //
0006 // This software is provided 'as-is', without any express or implied warranty.
0007 // In no event will the authors be held liable for any damages arising from the use of this software.
0008 //
0009 // Permission is granted to anyone to use this software for any purpose,
0010 // including commercial applications, and to alter it and redistribute it freely,
0011 // subject to the following restrictions:
0012 //
0013 // 1. The origin of this software must not be misrepresented;
0014 //    you must not claim that you wrote the original software.
0015 //    If you use this software in a product, an acknowledgment
0016 //    in the product documentation would be appreciated but is not required.
0017 //
0018 // 2. Altered source versions must be plainly marked as such,
0019 //    and must not be misrepresented as being the original software.
0020 //
0021 // 3. This notice may not be removed or altered from any source distribution.
0022 //
0023 ////////////////////////////////////////////////////////////
0024 
0025 #ifndef SFML_HTTP_HPP
0026 #define SFML_HTTP_HPP
0027 
0028 ////////////////////////////////////////////////////////////
0029 // Headers
0030 ////////////////////////////////////////////////////////////
0031 #include <SFML/Network/Export.hpp>
0032 #include <SFML/Network/IpAddress.hpp>
0033 #include <SFML/Network/TcpSocket.hpp>
0034 #include <SFML/System/NonCopyable.hpp>
0035 #include <SFML/System/Time.hpp>
0036 #include <map>
0037 #include <string>
0038 
0039 
0040 namespace sf
0041 {
0042 ////////////////////////////////////////////////////////////
0043 /// \brief A HTTP client
0044 ///
0045 ////////////////////////////////////////////////////////////
0046 class SFML_NETWORK_API Http : NonCopyable
0047 {
0048 public:
0049 
0050     ////////////////////////////////////////////////////////////
0051     /// \brief Define a HTTP request
0052     ///
0053     ////////////////////////////////////////////////////////////
0054     class SFML_NETWORK_API Request
0055     {
0056     public:
0057 
0058         ////////////////////////////////////////////////////////////
0059         /// \brief Enumerate the available HTTP methods for a request
0060         ///
0061         ////////////////////////////////////////////////////////////
0062         enum Method
0063         {
0064             Get,   //!< Request in get mode, standard method to retrieve a page
0065             Post,  //!< Request in post mode, usually to send data to a page
0066             Head,  //!< Request a page's header only
0067             Put,   //!< Request in put mode, useful for a REST API
0068             Delete //!< Request in delete mode, useful for a REST API
0069         };
0070 
0071         ////////////////////////////////////////////////////////////
0072         /// \brief Default constructor
0073         ///
0074         /// This constructor creates a GET request, with the root
0075         /// URI ("/") and an empty body.
0076         ///
0077         /// \param uri    Target URI
0078         /// \param method Method to use for the request
0079         /// \param body   Content of the request's body
0080         ///
0081         ////////////////////////////////////////////////////////////
0082         Request(const std::string& uri = "/", Method method = Get, const std::string& body = "");
0083 
0084         ////////////////////////////////////////////////////////////
0085         /// \brief Set the value of a field
0086         ///
0087         /// The field is created if it doesn't exist. The name of
0088         /// the field is case-insensitive.
0089         /// By default, a request doesn't contain any field (but the
0090         /// mandatory fields are added later by the HTTP client when
0091         /// sending the request).
0092         ///
0093         /// \param field Name of the field to set
0094         /// \param value Value of the field
0095         ///
0096         ////////////////////////////////////////////////////////////
0097         void setField(const std::string& field, const std::string& value);
0098 
0099         ////////////////////////////////////////////////////////////
0100         /// \brief Set the request method
0101         ///
0102         /// See the Method enumeration for a complete list of all
0103         /// the availale methods.
0104         /// The method is Http::Request::Get by default.
0105         ///
0106         /// \param method Method to use for the request
0107         ///
0108         ////////////////////////////////////////////////////////////
0109         void setMethod(Method method);
0110 
0111         ////////////////////////////////////////////////////////////
0112         /// \brief Set the requested URI
0113         ///
0114         /// The URI is the resource (usually a web page or a file)
0115         /// that you want to get or post.
0116         /// The URI is "/" (the root page) by default.
0117         ///
0118         /// \param uri URI to request, relative to the host
0119         ///
0120         ////////////////////////////////////////////////////////////
0121         void setUri(const std::string& uri);
0122 
0123         ////////////////////////////////////////////////////////////
0124         /// \brief Set the HTTP version for the request
0125         ///
0126         /// The HTTP version is 1.0 by default.
0127         ///
0128         /// \param major Major HTTP version number
0129         /// \param minor Minor HTTP version number
0130         ///
0131         ////////////////////////////////////////////////////////////
0132         void setHttpVersion(unsigned int major, unsigned int minor);
0133 
0134         ////////////////////////////////////////////////////////////
0135         /// \brief Set the body of the request
0136         ///
0137         /// The body of a request is optional and only makes sense
0138         /// for POST requests. It is ignored for all other methods.
0139         /// The body is empty by default.
0140         ///
0141         /// \param body Content of the body
0142         ///
0143         ////////////////////////////////////////////////////////////
0144         void setBody(const std::string& body);
0145 
0146     private:
0147 
0148         friend class Http;
0149 
0150         ////////////////////////////////////////////////////////////
0151         /// \brief Prepare the final request to send to the server
0152         ///
0153         /// This is used internally by Http before sending the
0154         /// request to the web server.
0155         ///
0156         /// \return String containing the request, ready to be sent
0157         ///
0158         ////////////////////////////////////////////////////////////
0159         std::string prepare() const;
0160 
0161         ////////////////////////////////////////////////////////////
0162         /// \brief Check if the request defines a field
0163         ///
0164         /// This function uses case-insensitive comparisons.
0165         ///
0166         /// \param field Name of the field to test
0167         ///
0168         /// \return True if the field exists, false otherwise
0169         ///
0170         ////////////////////////////////////////////////////////////
0171         bool hasField(const std::string& field) const;
0172 
0173         ////////////////////////////////////////////////////////////
0174         // Types
0175         ////////////////////////////////////////////////////////////
0176         typedef std::map<std::string, std::string> FieldTable;
0177 
0178         ////////////////////////////////////////////////////////////
0179         // Member data
0180         ////////////////////////////////////////////////////////////
0181         FieldTable   m_fields;       //!< Fields of the header associated to their value
0182         Method       m_method;       //!< Method to use for the request
0183         std::string  m_uri;          //!< Target URI of the request
0184         unsigned int m_majorVersion; //!< Major HTTP version
0185         unsigned int m_minorVersion; //!< Minor HTTP version
0186         std::string  m_body;         //!< Body of the request
0187     };
0188 
0189     ////////////////////////////////////////////////////////////
0190     /// \brief Define a HTTP response
0191     ///
0192     ////////////////////////////////////////////////////////////
0193     class SFML_NETWORK_API Response
0194     {
0195     public:
0196 
0197         ////////////////////////////////////////////////////////////
0198         /// \brief Enumerate all the valid status codes for a response
0199         ///
0200         ////////////////////////////////////////////////////////////
0201         enum Status
0202         {
0203             // 2xx: success
0204             Ok             = 200, //!< Most common code returned when operation was successful
0205             Created        = 201, //!< The resource has successfully been created
0206             Accepted       = 202, //!< The request has been accepted, but will be processed later by the server
0207             NoContent      = 204, //!< The server didn't send any data in return
0208             ResetContent   = 205, //!< The server informs the client that it should clear the view (form) that caused the request to be sent
0209             PartialContent = 206, //!< The server has sent a part of the resource, as a response to a partial GET request
0210 
0211             // 3xx: redirection
0212             MultipleChoices  = 300, //!< The requested page can be accessed from several locations
0213             MovedPermanently = 301, //!< The requested page has permanently moved to a new location
0214             MovedTemporarily = 302, //!< The requested page has temporarily moved to a new location
0215             NotModified      = 304, //!< For conditional requests, means the requested page hasn't changed and doesn't need to be refreshed
0216 
0217             // 4xx: client error
0218             BadRequest          = 400, //!< The server couldn't understand the request (syntax error)
0219             Unauthorized        = 401, //!< The requested page needs an authentication to be accessed
0220             Forbidden           = 403, //!< The requested page cannot be accessed at all, even with authentication
0221             NotFound            = 404, //!< The requested page doesn't exist
0222             RangeNotSatisfiable = 407, //!< The server can't satisfy the partial GET request (with a "Range" header field)
0223 
0224             // 5xx: server error
0225             InternalServerError = 500, //!< The server encountered an unexpected error
0226             NotImplemented      = 501, //!< The server doesn't implement a requested feature
0227             BadGateway          = 502, //!< The gateway server has received an error from the source server
0228             ServiceNotAvailable = 503, //!< The server is temporarily unavailable (overloaded, in maintenance, ...)
0229             GatewayTimeout      = 504, //!< The gateway server couldn't receive a response from the source server
0230             VersionNotSupported = 505, //!< The server doesn't support the requested HTTP version
0231 
0232             // 10xx: SFML custom codes
0233             InvalidResponse  = 1000, //!< Response is not a valid HTTP one
0234             ConnectionFailed = 1001  //!< Connection with server failed
0235         };
0236 
0237         ////////////////////////////////////////////////////////////
0238         /// \brief Default constructor
0239         ///
0240         /// Constructs an empty response.
0241         ///
0242         ////////////////////////////////////////////////////////////
0243         Response();
0244 
0245         ////////////////////////////////////////////////////////////
0246         /// \brief Get the value of a field
0247         ///
0248         /// If the field \a field is not found in the response header,
0249         /// the empty string is returned. This function uses
0250         /// case-insensitive comparisons.
0251         ///
0252         /// \param field Name of the field to get
0253         ///
0254         /// \return Value of the field, or empty string if not found
0255         ///
0256         ////////////////////////////////////////////////////////////
0257         const std::string& getField(const std::string& field) const;
0258 
0259         ////////////////////////////////////////////////////////////
0260         /// \brief Get the response status code
0261         ///
0262         /// The status code should be the first thing to be checked
0263         /// after receiving a response, it defines whether it is a
0264         /// success, a failure or anything else (see the Status
0265         /// enumeration).
0266         ///
0267         /// \return Status code of the response
0268         ///
0269         ////////////////////////////////////////////////////////////
0270         Status getStatus() const;
0271 
0272         ////////////////////////////////////////////////////////////
0273         /// \brief Get the major HTTP version number of the response
0274         ///
0275         /// \return Major HTTP version number
0276         ///
0277         /// \see getMinorHttpVersion
0278         ///
0279         ////////////////////////////////////////////////////////////
0280         unsigned int getMajorHttpVersion() const;
0281 
0282         ////////////////////////////////////////////////////////////
0283         /// \brief Get the minor HTTP version number of the response
0284         ///
0285         /// \return Minor HTTP version number
0286         ///
0287         /// \see getMajorHttpVersion
0288         ///
0289         ////////////////////////////////////////////////////////////
0290         unsigned int getMinorHttpVersion() const;
0291 
0292         ////////////////////////////////////////////////////////////
0293         /// \brief Get the body of the response
0294         ///
0295         /// The body of a response may contain:
0296         /// \li the requested page (for GET requests)
0297         /// \li a response from the server (for POST requests)
0298         /// \li nothing (for HEAD requests)
0299         /// \li an error message (in case of an error)
0300         ///
0301         /// \return The response body
0302         ///
0303         ////////////////////////////////////////////////////////////
0304         const std::string& getBody() const;
0305 
0306     private:
0307 
0308         friend class Http;
0309 
0310         ////////////////////////////////////////////////////////////
0311         /// \brief Construct the header from a response string
0312         ///
0313         /// This function is used by Http to build the response
0314         /// of a request.
0315         ///
0316         /// \param data Content of the response to parse
0317         ///
0318         ////////////////////////////////////////////////////////////
0319         void parse(const std::string& data);
0320 
0321 
0322         ////////////////////////////////////////////////////////////
0323         /// \brief Read values passed in the answer header
0324         ///
0325         /// This function is used by Http to extract values passed
0326         /// in the response.
0327         ///
0328         /// \param in String stream containing the header values
0329         ///
0330         ////////////////////////////////////////////////////////////
0331         void parseFields(std::istream &in);
0332 
0333         ////////////////////////////////////////////////////////////
0334         // Types
0335         ////////////////////////////////////////////////////////////
0336         typedef std::map<std::string, std::string> FieldTable;
0337 
0338         ////////////////////////////////////////////////////////////
0339         // Member data
0340         ////////////////////////////////////////////////////////////
0341         FieldTable   m_fields;       //!< Fields of the header
0342         Status       m_status;       //!< Status code
0343         unsigned int m_majorVersion; //!< Major HTTP version
0344         unsigned int m_minorVersion; //!< Minor HTTP version
0345         std::string  m_body;         //!< Body of the response
0346     };
0347 
0348     ////////////////////////////////////////////////////////////
0349     /// \brief Default constructor
0350     ///
0351     ////////////////////////////////////////////////////////////
0352     Http();
0353 
0354     ////////////////////////////////////////////////////////////
0355     /// \brief Construct the HTTP client with the target host
0356     ///
0357     /// This is equivalent to calling setHost(host, port).
0358     /// The port has a default value of 0, which means that the
0359     /// HTTP client will use the right port according to the
0360     /// protocol used (80 for HTTP). You should leave it like
0361     /// this unless you really need a port other than the
0362     /// standard one, or use an unknown protocol.
0363     ///
0364     /// \param host Web server to connect to
0365     /// \param port Port to use for connection
0366     ///
0367     ////////////////////////////////////////////////////////////
0368     Http(const std::string& host, unsigned short port = 0);
0369 
0370     ////////////////////////////////////////////////////////////
0371     /// \brief Set the target host
0372     ///
0373     /// This function just stores the host address and port, it
0374     /// doesn't actually connect to it until you send a request.
0375     /// The port has a default value of 0, which means that the
0376     /// HTTP client will use the right port according to the
0377     /// protocol used (80 for HTTP). You should leave it like
0378     /// this unless you really need a port other than the
0379     /// standard one, or use an unknown protocol.
0380     ///
0381     /// \param host Web server to connect to
0382     /// \param port Port to use for connection
0383     ///
0384     ////////////////////////////////////////////////////////////
0385     void setHost(const std::string& host, unsigned short port = 0);
0386 
0387     ////////////////////////////////////////////////////////////
0388     /// \brief Send a HTTP request and return the server's response.
0389     ///
0390     /// You must have a valid host before sending a request (see setHost).
0391     /// Any missing mandatory header field in the request will be added
0392     /// with an appropriate value.
0393     /// Warning: this function waits for the server's response and may
0394     /// not return instantly; use a thread if you don't want to block your
0395     /// application, or use a timeout to limit the time to wait. A value
0396     /// of Time::Zero means that the client will use the system default timeout
0397     /// (which is usually pretty long).
0398     ///
0399     /// \param request Request to send
0400     /// \param timeout Maximum time to wait
0401     ///
0402     /// \return Server's response
0403     ///
0404     ////////////////////////////////////////////////////////////
0405     Response sendRequest(const Request& request, Time timeout = Time::Zero);
0406 
0407 private:
0408 
0409     ////////////////////////////////////////////////////////////
0410     // Member data
0411     ////////////////////////////////////////////////////////////
0412     TcpSocket      m_connection; //!< Connection to the host
0413     IpAddress      m_host;       //!< Web host address
0414     std::string    m_hostName;   //!< Web host name
0415     unsigned short m_port;       //!< Port used for connection with host
0416 };
0417 
0418 } // namespace sf
0419 
0420 
0421 #endif // SFML_HTTP_HPP
0422 
0423 
0424 ////////////////////////////////////////////////////////////
0425 /// \class sf::Http
0426 /// \ingroup network
0427 ///
0428 /// sf::Http is a very simple HTTP client that allows you
0429 /// to communicate with a web server. You can retrieve
0430 /// web pages, send data to an interactive resource,
0431 /// download a remote file, etc. The HTTPS protocol is
0432 /// not supported.
0433 ///
0434 /// The HTTP client is split into 3 classes:
0435 /// \li sf::Http::Request
0436 /// \li sf::Http::Response
0437 /// \li sf::Http
0438 ///
0439 /// sf::Http::Request builds the request that will be
0440 /// sent to the server. A request is made of:
0441 /// \li a method (what you want to do)
0442 /// \li a target URI (usually the name of the web page or file)
0443 /// \li one or more header fields (options that you can pass to the server)
0444 /// \li an optional body (for POST requests)
0445 ///
0446 /// sf::Http::Response parse the response from the web server
0447 /// and provides getters to read them. The response contains:
0448 /// \li a status code
0449 /// \li header fields (that may be answers to the ones that you requested)
0450 /// \li a body, which contains the contents of the requested resource
0451 ///
0452 /// sf::Http provides a simple function, SendRequest, to send a
0453 /// sf::Http::Request and return the corresponding sf::Http::Response
0454 /// from the server.
0455 ///
0456 /// Usage example:
0457 /// \code
0458 /// // Create a new HTTP client
0459 /// sf::Http http;
0460 ///
0461 /// // We'll work on http://www.sfml-dev.org
0462 /// http.setHost("http://www.sfml-dev.org");
0463 ///
0464 /// // Prepare a request to get the 'features.php' page
0465 /// sf::Http::Request request("features.php");
0466 ///
0467 /// // Send the request
0468 /// sf::Http::Response response = http.sendRequest(request);
0469 ///
0470 /// // Check the status code and display the result
0471 /// sf::Http::Response::Status status = response.getStatus();
0472 /// if (status == sf::Http::Response::Ok)
0473 /// {
0474 ///     std::cout << response.getBody() << std::endl;
0475 /// }
0476 /// else
0477 /// {
0478 ///     std::cout << "Error " << status << std::endl;
0479 /// }
0480 /// \endcode
0481 ///
0482 ////////////////////////////////////////////////////////////