OpenTTD Source
12.0-beta2
|
Go to the documentation of this file.
12 #include "../../stdafx.h"
13 #include "../../debug.h"
14 #include "../../rev.h"
15 #include "../network_internal.h"
20 #include "../../safeguards.h"
35 HTTPCallback *callback,
const std::string &host,
const char *url,
36 const char *data,
int depth) :
42 redirect_depth(depth),
45 Debug(net, 5,
"[tcp/http] Requesting {}{}", host, url);
47 if (
data !=
nullptr) {
48 request = fmt::format(
"POST {} HTTP/1.0\r\nHost: {}\r\nUser-Agent: OpenTTD/{}\r\nContent-Type: text/plain\r\nContent-Length: {}\r\n\r\n{}\r\n", url, host,
GetNetworkRevisionString(), strlen(
data),
data);
50 request = fmt::format(
"GET {} HTTP/1.0\r\nHost: {}\r\nUser-Agent: OpenTTD/{}\r\n\r\n", url, host,
GetNetworkRevisionString());
53 ssize_t res = send(this->
sock, request.data(), (
int)request.size(), 0);
54 if (res != (ssize_t)request.size()) {
78 if (this->
sock != INVALID_SOCKET) closesocket(this->
sock);
79 this->
sock = INVALID_SOCKET;
86 #define return_error(msg) { Debug(net, 1, msg); return -1; }
88 static const char *
const NEWLINE =
"\r\n";
90 static const char *
const HTTP_1_0 =
"HTTP/1.0 ";
91 static const char *
const HTTP_1_1 =
"HTTP/1.1 ";
93 static const char *
const LOCATION =
"Location: ";
117 if (strncmp(status,
"200", 3) == 0) {
122 if (length ==
nullptr)
return_error(
"[tcp/http] Missing 'content-length' header");
129 char *end_of_line = strstr(length,
NEWLINE);
133 int len = atoi(length);
140 if (len == 0)
return_error(
"[tcp/http] Refusing to download 0 bytes");
142 Debug(net, 7,
"[tcp/http] Downloading {} bytes", len);
146 if (strncmp(status,
"301", 3) != 0 &&
147 strncmp(status,
"302", 3) != 0 &&
148 strncmp(status,
"303", 3) != 0 &&
149 strncmp(status,
"307", 3) != 0) {
154 *strstr(status,
NEWLINE) =
'\0';
155 Debug(net, 1,
"[tcp/http] Unhandled status reply {}", status);
163 if (uri ==
nullptr)
return_error(
"[tcp/http] Missing 'location' header for redirect");
169 char *end_of_line = strstr(uri,
NEWLINE);
172 Debug(net, 7,
"[tcp/http] Redirecting to {}", uri);
175 if (ret != 0)
return ret;
178 this->
data =
nullptr;
194 char *hname = strstr(uri,
"://");
195 if (hname ==
nullptr)
return_error(
"[tcp/http] Invalid location");
199 char *url = strchr(hname,
'/');
200 if (url ==
nullptr)
return_error(
"[tcp/http] Invalid location");
204 std::string hostname = std::string(hname);
246 ssize_t read = this->
recv_pos + res;
255 if (end_of_header ==
nullptr) {
257 Debug(net, 1,
"[tcp/http] Header too big");
263 if (ret <= 0)
return ret;
268 int len = std::min(read - (end_of_header - this->
recv_buffer), res);
298 FD_SET(handler->sock, &read_fd);
301 tv.tv_sec = tv.tv_usec = 0;
302 int n = select(FD_SETSIZE, &read_fd,
nullptr,
nullptr, &tv);
308 if (FD_ISSET(cur->
sock, &read_fd)) {
static const char *const END_OF_HEADER
End of header marker.
Base socket handler for HTTP traffic.
HTTPCallback * callback
The callback to call for the incoming data.
Callback for when the HTTP handler has something to tell us.
SocketHandler for all network sockets in OpenTTD.
const char * data
The (POST) data we might want to forward (to a redirect).
virtual void OnReceiveData(const char *data, size_t length)=0
We're receiving data.
std::string_view GetNetworkRevisionString()
Get the network version string used by this build.
static const char *const LOCATION
Header for location.
~NetworkHTTPSocketHandler()
Free whatever needs to be freed.
Connect with a HTTP server and do ONE query.
NetworkHTTPSocketHandler(SOCKET sock, HTTPCallback *callback, const std::string &host, const char *url, const char *data, int depth)
Start the querying.
int redirect_depth
The depth of the redirection.
int recv_pos
Current position in buffer.
char recv_buffer[4096]
Partially received message.
static const char *const HTTP_1_1
Preamble for HTTP 1.1 servers.
bool WouldBlock() const
Check whether this error describes that the operation would block.
static NetworkError GetLast()
Get the last network error.
void CloseSocket()
Close the actual socket of the connection.
static std::vector< NetworkHTTPSocketHandler * > _http_connections
List of open HTTP connections.
virtual void OnFailure()=0
An error has occurred and the connection has been closed.
static int Connect(char *uri, HTTPCallback *callback, const char *data=nullptr, int depth=0)
Connect to the given URI.
int Receive()
Handle receiving of HTTP data.
static const char *const HTTP_1_0
Preamble for HTTP 1.0 servers.
static void HTTPReceive()
Do the receiving for all HTTP connections.
bool IsConnectionReset() const
Check whether this error describes a connection reset.
const std::string & AsString() const
Get the string representation of the error message.
Abstraction of a network error where all implementation details of the error codes are encapsulated i...
#define return_error(msg)
Helper to simplify the error handling.
static const char *const NEWLINE
End of line marker.
int recv_length
Length of the data still retrieving.
#define Debug(name, level, format_string,...)
Ouptut a line of debugging information.
#define lengthof(x)
Return the length of an fixed size array.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
static const char *const CONTENT_LENGTH
Header for the length of the content.
SOCKET sock
The socket currently connected to.
int HandleHeader()
Handle the header of a HTTP reply.