diff --git a/Common/File/PathBrowser.cpp b/Common/File/PathBrowser.cpp index 756f0f74b3..64dff74057 100644 --- a/Common/File/PathBrowser.cpp +++ b/Common/File/PathBrowser.cpp @@ -38,10 +38,11 @@ bool LoadRemoteFileList(const Path &url, bool *cancel, std::vector &responseHeaders, RequestProgress *progress) { +int Client::GET(const RequestParams &req, Buffer *output, std::vector &responseHeaders, RequestProgress *progress) { const char *otherHeaders = - "Accept: */*\r\n" "Accept-Encoding: gzip\r\n"; - int err = SendRequest("GET", resource, otherHeaders, progress); + int err = SendRequest("GET", req, otherHeaders, progress); if (err < 0) { return err; } @@ -265,20 +264,20 @@ int Client::GET(const char *resource, Buffer *output, std::vector & return code; } -int Client::GET(const char *resource, Buffer *output, RequestProgress *progress) { +int Client::GET(const RequestParams &req, Buffer *output, RequestProgress *progress) { std::vector responseHeaders; - int code = GET(resource, output, responseHeaders, progress); + int code = GET(req, output, responseHeaders, progress); return code; } -int Client::POST(const char *resource, const std::string &data, const std::string &mime, Buffer *output, RequestProgress *progress) { +int Client::POST(const RequestParams &req, const std::string &data, const std::string &mime, Buffer *output, RequestProgress *progress) { char otherHeaders[2048]; if (mime.empty()) { snprintf(otherHeaders, sizeof(otherHeaders), "Content-Length: %lld\r\n", (long long)data.size()); } else { snprintf(otherHeaders, sizeof(otherHeaders), "Content-Length: %lld\r\nContent-Type: %s\r\n", (long long)data.size(), mime.c_str()); } - int err = SendRequestWithData("POST", resource, data, otherHeaders, progress); + int err = SendRequestWithData("POST", req, data, otherHeaders, progress); if (err < 0) { return err; } @@ -297,15 +296,15 @@ int Client::POST(const char *resource, const std::string &data, const std::strin return code; } -int Client::POST(const char *resource, const std::string &data, Buffer *output, RequestProgress *progress) { - return POST(resource, data, "", output, progress); +int Client::POST(const RequestParams &req, const std::string &data, Buffer *output, RequestProgress *progress) { + return POST(req, data, "", output, progress); } -int Client::SendRequest(const char *method, const char *resource, const char *otherHeaders, RequestProgress *progress) { - return SendRequestWithData(method, resource, "", otherHeaders, progress); +int Client::SendRequest(const char *method, const RequestParams &req, const char *otherHeaders, RequestProgress *progress) { + return SendRequestWithData(method, req, "", otherHeaders, progress); } -int Client::SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders, RequestProgress *progress) { +int Client::SendRequestWithData(const char *method, const RequestParams &req, const std::string &data, const char *otherHeaders, RequestProgress *progress) { progress->progress = 0.01f; net::Buffer buffer; @@ -313,14 +312,16 @@ int Client::SendRequestWithData(const char *method, const char *resource, const "%s %s HTTP/%s\r\n" "Host: %s\r\n" "User-Agent: %s\r\n" + "Accept: %s\r\n" "Connection: close\r\n" "%s" "\r\n"; buffer.Printf(tpl, - method, resource, httpVersion_, + method, req.resource.c_str(), httpVersion_, host_.c_str(), userAgent_.c_str(), + req.acceptMime, otherHeaders ? otherHeaders : ""); buffer.Append(data); bool flushed = buffer.FlushSocket(sock(), dataTimeout_, progress->cancelled); @@ -508,7 +509,8 @@ int Download::PerformGET(const std::string &url) { return -1; } - return client.GET(fileUrl.Resource().c_str(), &buffer_, responseHeaders_, &progress_); + RequestParams req(fileUrl.Resource(), "*/*"); + return client.GET(req, &buffer_, responseHeaders_, &progress_); } std::string Download::RedirectLocation(const std::string &baseUrl) { diff --git a/Common/Net/HTTPClient.h b/Common/Net/HTTPClient.h index dd8933c1b6..8146353b2f 100644 --- a/Common/Net/HTTPClient.h +++ b/Common/Net/HTTPClient.h @@ -53,23 +53,32 @@ struct RequestProgress { bool *cancelled = nullptr; }; +struct RequestParams { + RequestParams() {} + explicit RequestParams(const char *r) : resource(r) {} + RequestParams(const std::string &r, const char *a) : resource(r), acceptMime(a) {} + + std::string resource; + const char *acceptMime = "*/*"; +}; + class Client : public net::Connection { public: Client(); ~Client(); // Return value is the HTTP return code. 200 means OK. < 0 means some local error. - int GET(const char *resource, Buffer *output, RequestProgress *progress); - int GET(const char *resource, Buffer *output, std::vector &responseHeaders, RequestProgress *progress); + int GET(const RequestParams &req, Buffer *output, RequestProgress *progress); + int GET(const RequestParams &req, Buffer *output, std::vector &responseHeaders, RequestProgress *progress); // Return value is the HTTP return code. - int POST(const char *resource, const std::string &data, const std::string &mime, Buffer *output, RequestProgress *progress); - int POST(const char *resource, const std::string &data, Buffer *output, RequestProgress *progress); + int POST(const RequestParams &req, const std::string &data, const std::string &mime, Buffer *output, RequestProgress *progress); + int POST(const RequestParams &req, const std::string &data, Buffer *output, RequestProgress *progress); // HEAD, PUT, DELETE aren't implemented yet, but can be done with SendRequest. - int SendRequest(const char *method, const char *resource, const char *otherHeaders, RequestProgress *progress); - int SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders, RequestProgress *progress); + int SendRequest(const char *method, const RequestParams &req, const char *otherHeaders, RequestProgress *progress); + int SendRequestWithData(const char *method, const RequestParams &req, const std::string &data, const char *otherHeaders, RequestProgress *progress); int ReadResponseHeaders(net::Buffer *readbuf, std::vector &responseHeaders, RequestProgress *progress); // If your response contains a response, you must read it. int ReadResponseEntity(net::Buffer *readbuf, const std::vector &responseHeaders, Buffer *output, RequestProgress *progress); diff --git a/Core/FileLoaders/HTTPFileLoader.cpp b/Core/FileLoaders/HTTPFileLoader.cpp index 5078dcc4a3..a2d4080844 100644 --- a/Core/FileLoaders/HTTPFileLoader.cpp +++ b/Core/FileLoaders/HTTPFileLoader.cpp @@ -137,7 +137,8 @@ int HTTPFileLoader::SendHEAD(const Url &url, std::vector &responseH return -400; } - int err = client_.SendRequest("HEAD", url.Resource().c_str(), nullptr, &progress_); + http::RequestParams req(url.Resource(), "*/*"); + int err = client_.SendRequest("HEAD", req, nullptr, &progress_); if (err < 0) { ERROR_LOG(LOADER, "HTTP request failed, failed to send request: %s port %d", url.Host().c_str(), url.Port()); latestError_ = "Could not connect (could not request data)"; @@ -196,7 +197,8 @@ size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags f snprintf(requestHeaders, sizeof(requestHeaders), "Range: bytes=%lld-%lld\r\n", absolutePos, absoluteEnd - 1); - int err = client_.SendRequest("GET", url_.Resource().c_str(), requestHeaders, &progress_); + http::RequestParams req(url_.Resource(), "*/*"); + int err = client_.SendRequest("GET", req, requestHeaders, &progress_); if (err < 0) { latestError_ = "Invalid response reading data"; Disconnect(); diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index c5bab7ac6e..ec66977c36 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -282,7 +282,7 @@ namespace Reporting if (http.Resolve(serverHost, ServerPort())) { http.Connect(); - int result = http.POST(uri, data, mimeType, output, &progress); + int result = http.POST(http::RequestParams(uri), data, mimeType, output, &progress); http.Disconnect(); return result >= 200 && result < 300; diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index b3b1b9b333..e84de770f1 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -74,7 +74,7 @@ static bool RegisterServer(int port) { std::string ip = fd_util::GetLocalIP(http.sock()); snprintf(resource4, sizeof(resource4) - 1, "/match/update?local=%s&port=%d", ip.c_str(), port); - if (http.GET(resource4, &theVoid, &progress) > 0) + if (http.GET(http::RequestParams(resource4), &theVoid, &progress) > 0) success = true; theVoid.Skip(theVoid.size()); http.Disconnect(); @@ -87,7 +87,7 @@ static bool RegisterServer(int port) { // We register both IPv4 and IPv6 in case the other client is using a different one. if (resource4[0] != 0 && http.Connect(timeout)) { - if (http.GET(resource4, &theVoid, &progress) > 0) + if (http.GET(http::RequestParams(resource4), &theVoid, &progress) > 0) success = true; theVoid.Skip(theVoid.size()); http.Disconnect(); @@ -99,7 +99,7 @@ static bool RegisterServer(int port) { std::string ip = fd_util::GetLocalIP(http.sock()); snprintf(resource6, sizeof(resource6) - 1, "/match/update?local=%s&port=%d", ip.c_str(), port); - if (http.GET(resource6, &theVoid, &progress) > 0) + if (http.GET(http::RequestParams(resource6), &theVoid, &progress) > 0) success = true; theVoid.Skip(theVoid.size()); http.Disconnect(); diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index b5d80bf76d..d67783e4e7 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -137,7 +137,7 @@ bool RemoteISOConnectScreen::FindServer(std::string &resultHost, int &resultPort SetStatus("Loading game list from [URL]...", host, port); http::RequestProgress progress(&scanCancelled); - code = http.GET(subdir.c_str(), &result, &progress); + code = http.GET(http::RequestParams(subdir.c_str()), &result, &progress); http.Disconnect(); if (code != 200) { @@ -191,7 +191,7 @@ bool RemoteISOConnectScreen::FindServer(std::string &resultHost, int &resultPort if (http.Resolve(REPORT_HOSTNAME, REPORT_PORT)) { if (http.Connect(2, 20.0, &scanCancelled)) { http::RequestProgress progress(&scanCancelled); - code = http.GET("/match/list", &result, &progress); + code = http.GET(http::RequestParams("/match/list"), &result, &progress); http.Disconnect(); } }