16 #include "../../stdafx.h"
17 #include "../../debug.h"
18 #include "../../rev.h"
19 #include "../network_func.h"
23 #include "../../safeguards.h"
38 HTTPCallback *callback,
const char *host,
const char *url,
39 const char *data,
int depth) :
45 redirect_depth(depth),
48 size_t bufferSize = strlen(url) + strlen(host) + strlen(_openttd_revision) + (data == NULL ? 0 : strlen(data)) + 128;
49 char *buffer =
AllocaM(
char, bufferSize);
51 DEBUG(net, 7,
"[tcp/http] requesting %s%s", host, url);
53 seprintf(buffer, buffer + bufferSize - 1,
"POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: OpenTTD/%s\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s\r\n", url, host, _openttd_revision, (
int)strlen(data), data);
55 seprintf(buffer, buffer + bufferSize - 1,
"GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: OpenTTD/%s\r\n\r\n", url, host, _openttd_revision);
58 ssize_t size = strlen(buffer);
59 ssize_t res = send(this->
sock, (
const char*)buffer, size, 0);
68 *_http_connections.
Append() =
this;
76 if (this->
sock != INVALID_SOCKET) closesocket(this->
sock);
77 this->
sock = INVALID_SOCKET;
91 #define return_error(msg) { DEBUG(net, 0, msg); return -1; }
93 static const char *
const NEWLINE =
"\r\n";
95 static const char *
const HTTP_1_0 =
"HTTP/1.0 ";
96 static const char *
const HTTP_1_1 =
"HTTP/1.1 ";
98 static const char *
const LOCATION =
"Location: ";
122 if (strncmp(status,
"200", 3) == 0) {
127 if (length == NULL)
return_error(
"[tcp/http] missing 'content-length' header");
134 char *end_of_line = strstr(length,
NEWLINE);
138 int len = atoi(length);
145 if (len == 0)
return_error(
"[tcp/http] refusing to download 0 bytes");
147 DEBUG(net, 7,
"[tcp/http] downloading %i bytes", len);
151 if (strncmp(status,
"301", 3) != 0 &&
152 strncmp(status,
"302", 3) != 0 &&
153 strncmp(status,
"303", 3) != 0 &&
154 strncmp(status,
"307", 3) != 0) {
159 *strstr(status,
NEWLINE) =
'\0';
160 DEBUG(net, 0,
"[tcp/http] unhandled status reply %s", status);
168 if (uri == NULL)
return_error(
"[tcp/http] missing 'location' header for redirect");
174 char *end_of_line = strstr(uri,
NEWLINE);
177 DEBUG(net, 6,
"[tcp/http] redirecting to %s", uri);
180 if (ret != 0)
return ret;
199 char *hname = strstr(uri,
"://");
200 if (hname == NULL)
return_error(
"[tcp/http] invalid location");
204 char *url = strchr(hname,
'/');
205 if (url == NULL)
return_error(
"[tcp/http] invalid location");
210 const char *company = NULL;
211 const char *port = NULL;
213 if (company != NULL)
return_error(
"[tcp/http] invalid hostname");
237 int err = GET_LAST_ERROR();
238 if (err != EWOULDBLOCK) {
240 if (err != 104)
DEBUG(net, 0,
"recv failed with error %d", err);
266 if (end_of_header == NULL) {
268 DEBUG(net, 0,
"[tcp/http] header too big");
274 if (ret <= 0)
return ret;
302 if (_http_connections.
Length() == 0)
return;
309 FD_SET((*iter)->sock, &read_fd);
312 tv.tv_sec = tv.tv_usec = 0;
313 #if !defined(__MORPHOS__) && !defined(__AMIGA__)
314 int n = select(FD_SETSIZE, &read_fd, NULL, NULL, &tv);
316 int n = WaitSelect(FD_SETSIZE, &read_fd, NULL, NULL, &tv, NULL);
323 if (FD_ISSET(cur->
sock, &read_fd)) {
330 _http_connections.
Erase(iter);