mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #14755 from unknownbrackets/http-accept
Specify Accept headers for HTTP requests
This commit is contained in:
commit
fef7b8918d
11 changed files with 70 additions and 40 deletions
|
@ -38,10 +38,11 @@ bool LoadRemoteFileList(const Path &url, bool *cancel, std::vector<File::FileInf
|
|||
}
|
||||
|
||||
// Start by requesting the list of files from the server.
|
||||
http::RequestParams req(baseURL.Resource(), "text/plain, text/html; q=0.9, */*; q=0.8");
|
||||
if (http.Resolve(baseURL.Host().c_str(), baseURL.Port())) {
|
||||
if (http.Connect(2, 20.0, cancel)) {
|
||||
http::RequestProgress progress(cancel);
|
||||
code = http.GET(baseURL.Resource().c_str(), &result, responseHeaders, &progress);
|
||||
code = http.GET(req, &result, responseHeaders, &progress);
|
||||
http.Disconnect();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,11 +243,10 @@ void DeChunk(Buffer *inbuffer, Buffer *outbuffer, int contentLength, float *prog
|
|||
}
|
||||
}
|
||||
|
||||
int Client::GET(const char *resource, Buffer *output, std::vector<std::string> &responseHeaders, RequestProgress *progress) {
|
||||
int Client::GET(const RequestParams &req, Buffer *output, std::vector<std::string> &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<std::string> &
|
|||
return code;
|
||||
}
|
||||
|
||||
int Client::GET(const char *resource, Buffer *output, RequestProgress *progress) {
|
||||
int Client::GET(const RequestParams &req, Buffer *output, RequestProgress *progress) {
|
||||
std::vector<std::string> 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(), acceptMime_);
|
||||
return client.GET(req, &buffer_, responseHeaders_, &progress_);
|
||||
}
|
||||
|
||||
std::string Download::RedirectLocation(const std::string &baseUrl) {
|
||||
|
@ -569,8 +571,10 @@ void Download::Do() {
|
|||
completed_ = true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> Downloader::StartDownload(const std::string &url, const Path &outfile) {
|
||||
std::shared_ptr<Download> Downloader::StartDownload(const std::string &url, const Path &outfile, const char *acceptMime) {
|
||||
std::shared_ptr<Download> dl(new Download(url, outfile));
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
downloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
|
@ -579,8 +583,11 @@ std::shared_ptr<Download> Downloader::StartDownload(const std::string &url, cons
|
|||
std::shared_ptr<Download> Downloader::StartDownloadWithCallback(
|
||||
const std::string &url,
|
||||
const Path &outfile,
|
||||
std::function<void(Download &)> callback) {
|
||||
std::function<void(Download &)> callback,
|
||||
const char *acceptMime) {
|
||||
std::shared_ptr<Download> dl(new Download(url, outfile));
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
dl->SetCallback(callback);
|
||||
downloads_.push_back(dl);
|
||||
dl->Start();
|
||||
|
|
|
@ -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<std::string> &responseHeaders, RequestProgress *progress);
|
||||
int GET(const RequestParams &req, Buffer *output, RequestProgress *progress);
|
||||
int GET(const RequestParams &req, Buffer *output, std::vector<std::string> &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<std::string> &responseHeaders, RequestProgress *progress);
|
||||
// If your response contains a response, you must read it.
|
||||
int ReadResponseEntity(net::Buffer *readbuf, const std::vector<std::string> &responseHeaders, Buffer *output, RequestProgress *progress);
|
||||
|
@ -111,6 +120,10 @@ public:
|
|||
std::string url() const { return url_; }
|
||||
const Path &outfile() const { return outfile_; }
|
||||
|
||||
void SetAccept(const char *mime) {
|
||||
acceptMime_ = mime;
|
||||
}
|
||||
|
||||
// If not downloading to a file, access this to get the result.
|
||||
Buffer &buffer() { return buffer_; }
|
||||
const Buffer &buffer() const { return buffer_; }
|
||||
|
@ -151,6 +164,7 @@ private:
|
|||
std::string url_;
|
||||
Path outfile_;
|
||||
std::thread thread_;
|
||||
const char *acceptMime_ = "*/*";
|
||||
int resultCode_ = 0;
|
||||
bool completed_ = false;
|
||||
bool failed_ = false;
|
||||
|
@ -168,12 +182,13 @@ public:
|
|||
CancelAll();
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> StartDownload(const std::string &url, const Path &outfile);
|
||||
std::shared_ptr<Download> StartDownload(const std::string &url, const Path &outfile, const char *acceptMime = nullptr);
|
||||
|
||||
std::shared_ptr<Download> StartDownloadWithCallback(
|
||||
const std::string &url,
|
||||
const Path &outfile,
|
||||
std::function<void(Download &)> callback);
|
||||
std::function<void(Download &)> callback,
|
||||
const char *acceptMime = nullptr);
|
||||
|
||||
// Drops finished downloads from the list.
|
||||
void Update();
|
||||
|
|
|
@ -1393,8 +1393,9 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
|
|||
// splash screen quickly), but then we'll just show the notification next time instead, we store the
|
||||
// upgrade number in the ini.
|
||||
if (iRunCount % 10 == 0 && bCheckForNewVersion) {
|
||||
std::shared_ptr<http::Download> dl = g_DownloadManager.StartDownloadWithCallback(
|
||||
"http://www.ppsspp.org/version.json", Path(), &DownloadCompletedCallback);
|
||||
const char *versionUrl = "http://www.ppsspp.org/version.json";
|
||||
const char *acceptMime = "application/json, text/*; q=0.9, */*; q=0.8";
|
||||
auto dl = g_DownloadManager.StartDownloadWithCallback(versionUrl, Path(), &DownloadCompletedCallback, acceptMime);
|
||||
dl->SetHidden(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,8 @@ int HTTPFileLoader::SendHEAD(const Url &url, std::vector<std::string> &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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -100,7 +100,8 @@ bool GameManager::DownloadAndInstall(std::string storeFileUrl) {
|
|||
}
|
||||
|
||||
Path filename = GetTempFilename();
|
||||
curDownload_ = g_DownloadManager.StartDownload(storeFileUrl, filename);
|
||||
const char *acceptMime = "application/zip, application/x-cso, application/x-iso9660-image, application/octet-stream; q=0.9, */*; q=0.8";
|
||||
curDownload_ = g_DownloadManager.StartDownload(storeFileUrl, filename, acceptMime);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1206,7 +1206,8 @@ void FrameDumpTestScreen::update() {
|
|||
UIScreen::update();
|
||||
|
||||
if (!listing_) {
|
||||
listing_ = g_DownloadManager.StartDownload(framedumpsBaseUrl, Path());
|
||||
const char *acceptMime = "text/html, */*; q=0.8";
|
||||
listing_ = g_DownloadManager.StartDownload(framedumpsBaseUrl, Path(), acceptMime);
|
||||
}
|
||||
|
||||
if (listing_ && listing_->Done() && files_.empty()) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,9 @@ void HttpImageFileView::DownloadCompletedCallback(http::Download &download) {
|
|||
void HttpImageFileView::Draw(UIContext &dc) {
|
||||
using namespace Draw;
|
||||
if (!texture_ && !textureFailed_ && !path_.empty() && !download_) {
|
||||
download_ = downloader_->StartDownloadWithCallback(path_, Path(), std::bind(&HttpImageFileView::DownloadCompletedCallback, this, std::placeholders::_1));
|
||||
auto cb = std::bind(&HttpImageFileView::DownloadCompletedCallback, this, std::placeholders::_1);
|
||||
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
|
||||
download_ = downloader_->StartDownloadWithCallback(path_, Path(), cb, acceptMime);
|
||||
download_->SetHidden(true);
|
||||
}
|
||||
|
||||
|
@ -366,8 +368,8 @@ StoreScreen::StoreScreen() {
|
|||
loading_ = true;
|
||||
|
||||
std::string indexPath = storeBaseUrl + "index.json";
|
||||
|
||||
listing_ = g_DownloadManager.StartDownload(indexPath, Path());
|
||||
const char *acceptMime = "application/json, */*; q=0.8";
|
||||
listing_ = g_DownloadManager.StartDownload(indexPath, Path(), acceptMime);
|
||||
}
|
||||
|
||||
StoreScreen::~StoreScreen() {
|
||||
|
|
Loading…
Add table
Reference in a new issue