eada18b7e5
* SocketTCP/UDP -> TcpSocket * Ftp.makeDirectory -> createDirectory * some SocketSelector fixes + unfinished TcpListener git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1514 4e206d99-4929-0410-ac5d-dfc041789085
399 lines
13 KiB
D
399 lines
13 KiB
D
/*
|
|
* DSFML - SFML Library wrapper for the D programming language.
|
|
* Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com)
|
|
* Copyright (C) 2010 Andreas Hollandt
|
|
*
|
|
* This software is provided 'as-is', without any express or
|
|
* implied warranty. In no event will the authors be held
|
|
* liable for any damages arising from the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute
|
|
* it freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented;
|
|
* you must not claim that you wrote the original software.
|
|
* If you use this software in a product, an acknowledgment
|
|
* in the product documentation would be appreciated but
|
|
* is not required.
|
|
*
|
|
* 2. Altered source versions must be plainly marked as such,
|
|
* and must not be misrepresented as being the original software.
|
|
*
|
|
* 3. This notice may not be removed or altered from any
|
|
* source distribution.
|
|
*/
|
|
|
|
module dsfml.network.http;
|
|
|
|
import dsfml.system.stringutil;
|
|
import dsfml.system.common;
|
|
|
|
/**
|
|
* HTTP methods enumeration
|
|
*/
|
|
enum HttpMethod
|
|
{
|
|
GET, ///< Request in get mode, standard method to retrieve a page
|
|
POST, ///< Request in post mode, usually to send data to a page
|
|
HEAD ///< Request a page's header only
|
|
}
|
|
|
|
/**
|
|
* HTTP response status code
|
|
*/
|
|
enum HttpStatus
|
|
{
|
|
// 2xx: success
|
|
OK = 200, ///< Most common code returned when operation was successful
|
|
CREATED = 201, ///< The resource has successfully been created
|
|
ACCEPTED = 202, ///< The request has been accepted, but will be processed later by the server
|
|
NOCONTENT = 204, ///< Sent when the server didn't send any data in return
|
|
|
|
// 3xx: redirection
|
|
MULTIPLECHOICES = 300, ///< The requested page can be accessed from several locations
|
|
MOVEDPERMANENTLY = 301, ///< The requested page has permanently moved to a new location
|
|
MOVEDTEMPORARILY = 302, ///< The requested page has temporarily moved to a new location
|
|
NOTMODIFIED = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
|
|
|
|
// 4xx: client error
|
|
BADREQUEST = 400, ///< The server couldn't understand the request (syntax error)
|
|
UNAUTHORIZED = 401, ///< The requested page needs an authentification to be accessed
|
|
FORBIDDEN = 403, ///< The requested page cannot be accessed at all, even with authentification
|
|
NOTFOUND = 404, ///< The requested page doesn't exist
|
|
|
|
// 5xx: server error
|
|
INTERNALSERVERERROR = 500, ///< The server encountered an unexpected error
|
|
NOTIMPLEMENTED = 501, ///< The server doesn't implement a requested feature
|
|
BADGATEWAY = 502, ///< The gateway server has received an error from the source server
|
|
SERVICENOTAVAILABLE = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
|
|
|
|
// 10xx: SFML custom codes
|
|
INVALIDRESPONSE = 1000, ///< Response is not a valid HTTP one
|
|
CONNECTIONFAILED = 1001 ///< Connection with server failed
|
|
}
|
|
|
|
/**
|
|
* This class provides methods for manipulating the HTTP protocol (described in
|
|
* RFC 1945).
|
|
* It can connect to a website, get files, send requests
|
|
*/
|
|
class Http : DSFMLObject
|
|
{
|
|
/**
|
|
* Wrapper for a http request, which is basically :
|
|
* - a header with a method, a target URI and a set of field/value pairs
|
|
* - an optional body (for POST requests)
|
|
*/
|
|
static class Response : DSFMLObject
|
|
{
|
|
override void dispose()
|
|
{
|
|
sfHttpResponse_Destroy(m_ptr);
|
|
}
|
|
|
|
/**
|
|
* Get the value of a field
|
|
*
|
|
* Params:
|
|
* field = Name of the field to get (case-insensitive)
|
|
* Returns:
|
|
* Value of the field, or enpty string if not found
|
|
*/
|
|
string getField(string field)
|
|
{
|
|
return fromStringz(sfHttpResponse_GetField(m_ptr, toStringz(field)));
|
|
}
|
|
|
|
/**
|
|
* Get the header status code
|
|
*
|
|
* Returns:
|
|
* header status code
|
|
*/
|
|
HttpStatus getStatus()
|
|
{
|
|
return sfHttpResponse_GetStatus(m_ptr);
|
|
}
|
|
|
|
/**
|
|
* Get the major HTTP version number of the response
|
|
*
|
|
* Returns:
|
|
* Major version number
|
|
*/
|
|
uint getMajorHTTPVersion()
|
|
{
|
|
return sfHttpResponse_GetMajorVersion(m_ptr);
|
|
}
|
|
|
|
/**
|
|
* Get the minor HTTP version number of the response
|
|
*
|
|
* Returns:
|
|
* Minor version number
|
|
*/
|
|
uint getMinorHTTPVersion()
|
|
{
|
|
return sfHttpResponse_GetMinorVersion(m_ptr);
|
|
}
|
|
|
|
/**
|
|
* Get the body of the response. The body can contain :
|
|
* - the requested page (for GET requests)
|
|
* - a response from the server (for POST requests)
|
|
* - nothing (for HEAD requests)
|
|
* - an error message (in case of an error)
|
|
*
|
|
* Returns:
|
|
* the response body
|
|
*/
|
|
string getBody()
|
|
{
|
|
return fromStringz(sfHttpResponse_GetBody(m_ptr));
|
|
}
|
|
|
|
private:
|
|
this(SFMLClass ptr)
|
|
{
|
|
super(ptr);
|
|
}
|
|
// External ================================================================
|
|
extern (C)
|
|
{
|
|
typedef void function(SFMLClass) pf_sfHttpResponse_Destroy;
|
|
typedef ichar* function(SFMLClass, cchar*) pf_sfHttpResponse_GetField;
|
|
typedef HttpStatus function(SFMLClass) pf_sfHttpResponse_GetStatus;
|
|
typedef uint function(SFMLClass) pf_sfHttpResponse_GetMajorVersion;
|
|
typedef uint function(SFMLClass) pf_sfHttpResponse_GetMinorVersion;
|
|
typedef ichar* function(SFMLClass) pf_sfHttpResponse_GetBody;
|
|
|
|
static pf_sfHttpResponse_Destroy sfHttpResponse_Destroy;
|
|
static pf_sfHttpResponse_GetField sfHttpResponse_GetField;
|
|
static pf_sfHttpResponse_GetStatus sfHttpResponse_GetStatus;
|
|
static pf_sfHttpResponse_GetMajorVersion sfHttpResponse_GetMajorVersion;
|
|
static pf_sfHttpResponse_GetMinorVersion sfHttpResponse_GetMinorVersion;
|
|
static pf_sfHttpResponse_GetBody sfHttpResponse_GetBody;
|
|
}
|
|
|
|
static this()
|
|
{
|
|
DllLoader dll = DllLoader.load("csfml-network");
|
|
|
|
sfHttpResponse_Destroy = cast(pf_sfHttpResponse_Destroy)dll.getSymbol("sfHttpResponse_Destroy");
|
|
sfHttpResponse_GetField = cast(pf_sfHttpResponse_GetField)dll.getSymbol("sfHttpResponse_GetField");
|
|
sfHttpResponse_GetStatus = cast(pf_sfHttpResponse_GetStatus)dll.getSymbol("sfHttpResponse_GetStatus");
|
|
sfHttpResponse_GetMajorVersion = cast(pf_sfHttpResponse_GetMajorVersion)dll.getSymbol("sfHttpResponse_GetMajorVersion");
|
|
sfHttpResponse_GetMinorVersion = cast(pf_sfHttpResponse_GetMinorVersion)dll.getSymbol("sfHttpResponse_GetMinorVersion");
|
|
sfHttpResponse_GetBody = cast(pf_sfHttpResponse_GetBody)dll.getSymbol("sfHttpResponse_GetBody");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Wrapper for a HTTP response which is basically :
|
|
* - a header with a status code and a set of field/value pairs
|
|
* - a body (the content of the requested resource)
|
|
*/
|
|
static class Request : DSFMLObject
|
|
{
|
|
/**
|
|
* Constructor
|
|
*
|
|
* Params:
|
|
* requestMethod = Method to use for the request (Get by default)
|
|
* uri = Target URI ("/" by default -- index page)
|
|
* requestBody = Content of the request's body (empty by default)
|
|
*/
|
|
this(HttpMethod requestMethod = HttpMethod.GET, string uri = "/", string requestBody = "")
|
|
{
|
|
super(sfHttpRequest_Create());
|
|
sfHttpRequest_SetMethod(m_ptr, requestMethod);
|
|
sfHttpRequest_SetUri(m_ptr, toStringz(uri));
|
|
sfHttpRequest_SetBody(m_ptr, toStringz(requestBody));
|
|
}
|
|
|
|
/**
|
|
* Set the value of a field. Field is created if it doesn't exists.
|
|
*
|
|
* Params:
|
|
* field = name of the field to set (case-insensitive)
|
|
* value = value of the field
|
|
*/
|
|
void setField(string field, string value)
|
|
{
|
|
sfHttpRequest_SetField(m_ptr, toStringz(field), toStringz(value));
|
|
}
|
|
|
|
/**
|
|
* Set the request method.
|
|
*
|
|
* Params:
|
|
* requestMethod = Method to use for the request.
|
|
*/
|
|
void setMethod(HttpMethod requestMethod)
|
|
{
|
|
sfHttpRequest_SetMethod(m_ptr, requestMethod);
|
|
}
|
|
|
|
/**
|
|
* Set the target URI of the request.
|
|
*
|
|
* Params:
|
|
* uri = URI to request, local to the host.
|
|
* Returns:
|
|
*/
|
|
void setUri(string uri)
|
|
{
|
|
sfHttpRequest_SetUri(m_ptr, toStringz(uri));
|
|
}
|
|
|
|
/**
|
|
* Set the HTTP version of the request.
|
|
*
|
|
* Params:
|
|
* major = Major version number
|
|
* minor = Minor version number
|
|
*/
|
|
void setHttpVersion(uint major, uint minor)
|
|
{
|
|
sfHttpRequest_SetHttpVersion(m_ptr, major, minor);
|
|
}
|
|
|
|
/**
|
|
* Set the body of the request. This parameter is optionnal and make sense
|
|
* only for POST requests.
|
|
*
|
|
* Params:
|
|
* requestBody = Content of the request body.
|
|
*/
|
|
void setBody(string requestBody)
|
|
{
|
|
sfHttpRequest_SetBody(m_ptr, toStringz(requestBody));
|
|
}
|
|
|
|
private:
|
|
|
|
// External ================================================================
|
|
extern (C)
|
|
{
|
|
typedef SFMLClass function() pf_sfHttpRequest_Create;
|
|
typedef void function(SFMLClass) pf_sfHttpRequest_Destroy;
|
|
typedef void function(SFMLClass, cchar*, cchar*) pf_sfHttpRequest_SetField;
|
|
typedef void function(SFMLClass, HttpMethod) pf_sfHttpRequest_SetMethod;
|
|
typedef void function(SFMLClass, cchar*) pf_sfHttpRequest_SetUri;
|
|
typedef void function(SFMLClass, uint, uint) pf_sfHttpRequest_SetHttpVersion;
|
|
typedef void function(SFMLClass, cchar*) pf_sfHttpRequest_SetBody;
|
|
|
|
static pf_sfHttpRequest_Create sfHttpRequest_Create;
|
|
static pf_sfHttpRequest_Destroy sfHttpRequest_Destroy;
|
|
static pf_sfHttpRequest_SetField sfHttpRequest_SetField;
|
|
static pf_sfHttpRequest_SetMethod sfHttpRequest_SetMethod;
|
|
static pf_sfHttpRequest_SetUri sfHttpRequest_SetUri;
|
|
static pf_sfHttpRequest_SetHttpVersion sfHttpRequest_SetHttpVersion;
|
|
static pf_sfHttpRequest_SetBody sfHttpRequest_SetBody;
|
|
}
|
|
|
|
static this()
|
|
{
|
|
DllLoader dll = DllLoader.load("csfml-network");
|
|
|
|
sfHttpRequest_Create = cast(pf_sfHttpRequest_Create)dll.getSymbol("sfHttpRequest_Create");
|
|
sfHttpRequest_Destroy = cast(pf_sfHttpRequest_Destroy)dll.getSymbol("sfHttpRequest_Destroy");
|
|
sfHttpRequest_SetField = cast(pf_sfHttpRequest_SetField)dll.getSymbol("sfHttpRequest_SetField");
|
|
sfHttpRequest_SetMethod = cast(pf_sfHttpRequest_SetMethod)dll.getSymbol("sfHttpRequest_SetMethod");
|
|
sfHttpRequest_SetUri = cast(pf_sfHttpRequest_SetUri)dll.getSymbol("sfHttpRequest_SetUri");
|
|
sfHttpRequest_SetHttpVersion = cast(pf_sfHttpRequest_SetHttpVersion)dll.getSymbol("sfHttpRequest_SetHttpVersion");
|
|
sfHttpRequest_SetBody = cast(pf_sfHttpRequest_SetBody)dll.getSymbol("sfHttpRequest_SetBody");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
this()
|
|
{
|
|
super(sfHttp_Create());
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* Params:
|
|
* host = Web server to connect to
|
|
* port = port to use for connection (0 by default -- use the standard port of the protocol)
|
|
*/
|
|
this(string host, ushort port = 0)
|
|
{
|
|
super(sfHttp_Create());
|
|
sfHttp_SetHost(m_ptr, toStringz(host), port);
|
|
}
|
|
|
|
override void dispose()
|
|
{
|
|
sfHttp_Destroy(m_ptr);
|
|
}
|
|
|
|
/**
|
|
* Set the target host.
|
|
*
|
|
* Params:
|
|
* host = Web server to connect to
|
|
* port = port to use for connection (0 by default -- use the standard port of the protocol)
|
|
*/
|
|
void setHost(string host, ushort port = 0)
|
|
{
|
|
sfHttp_SetHost(m_ptr, toStringz(host), port);
|
|
}
|
|
|
|
/**
|
|
* Send a HTTP request and return the server's response.
|
|
* You must be connected to a host before sending requests.
|
|
* Any missing mandatory header field will be added with an appropriate value.
|
|
*
|
|
* Warning : this function waits for the server's response and may
|
|
* not return instantly; use a thread if you don't want to block your
|
|
* application.
|
|
*
|
|
* Params:
|
|
* req = Request to send
|
|
*
|
|
* Returns:
|
|
* Server's response
|
|
*/
|
|
|
|
Response sendRequest(Request req)
|
|
{
|
|
return new Response( sfHttp_SendRequest(m_ptr, req.nativePointer) );
|
|
}
|
|
|
|
private:
|
|
|
|
// External ====================================================================
|
|
|
|
extern (C)
|
|
{
|
|
typedef SFMLClass function() pf_sfHttp_Create;
|
|
typedef void function(SFMLClass) pf_sfHttp_Destroy;
|
|
typedef void function(SFMLClass, cchar*, ushort) pf_sfHttp_SetHost;
|
|
typedef SFMLClass function(SFMLClass, SFMLClass) pf_sfHttp_SendRequest;
|
|
|
|
static pf_sfHttp_Create sfHttp_Create;
|
|
static pf_sfHttp_Destroy sfHttp_Destroy;
|
|
static pf_sfHttp_SetHost sfHttp_SetHost;
|
|
static pf_sfHttp_SendRequest sfHttp_SendRequest;
|
|
}
|
|
|
|
static this()
|
|
{
|
|
debug
|
|
DllLoader dll = DllLoader.load("csfml-network-d");
|
|
else
|
|
DllLoader dll = DllLoader.load("csfml-network");
|
|
|
|
sfHttp_Create = cast(pf_sfHttp_Create)dll.getSymbol("sfHttp_Create");
|
|
sfHttp_Destroy = cast(pf_sfHttp_Destroy)dll.getSymbol("sfHttp_Destroy");
|
|
sfHttp_SetHost = cast(pf_sfHttp_SetHost)dll.getSymbol("sfHttp_SetHost");
|
|
sfHttp_SendRequest = cast(pf_sfHttp_SendRequest)dll.getSymbol("sfHttp_SendRequest");
|
|
}
|
|
}
|