mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
140 lines
4.1 KiB
C++
140 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <thread>
|
|
#include <cstdint>
|
|
|
|
#include "Common/File/Path.h"
|
|
#include "Common/Net/NetBuffer.h"
|
|
#include "Common/Net/Resolve.h"
|
|
#include "Common/Net/HTTPRequest.h"
|
|
|
|
namespace net {
|
|
|
|
class Connection {
|
|
public:
|
|
virtual ~Connection();
|
|
|
|
// Inits the sockaddr_in.
|
|
bool Resolve(const char *host, int port, DNSType type = DNSType::ANY);
|
|
|
|
bool Connect(int maxTries = 2, double timeout = 20.0f, bool *cancelConnect = nullptr);
|
|
void Disconnect();
|
|
|
|
// Only to be used for bring-up and debugging.
|
|
uintptr_t sock() const { return sock_; }
|
|
|
|
protected:
|
|
// Store the remote host here, so we can send it along through HTTP/1.1 requests.
|
|
// TODO: Move to http::client?
|
|
std::string host_;
|
|
int port_ = -1;
|
|
|
|
addrinfo *resolved_ = nullptr;
|
|
|
|
private:
|
|
uintptr_t sock_ = -1;
|
|
|
|
};
|
|
|
|
} // namespace net
|
|
|
|
namespace http {
|
|
|
|
bool GetHeaderValue(const std::vector<std::string> &responseHeaders, const std::string &header, std::string *value);
|
|
|
|
class RequestParams {
|
|
public:
|
|
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 RequestParams &req, Buffer *output, net::RequestProgress *progress);
|
|
int GET(const RequestParams &req, Buffer *output, std::vector<std::string> &responseHeaders, net::RequestProgress *progress);
|
|
|
|
// Return value is the HTTP return code.
|
|
int POST(const RequestParams &req, const std::string &data, const std::string &mime, Buffer *output, net::RequestProgress *progress);
|
|
int POST(const RequestParams &req, const std::string &data, Buffer *output, net::RequestProgress *progress);
|
|
|
|
// HEAD, PUT, DELETE aren't implemented yet, but can be done with SendRequest.
|
|
|
|
int SendRequest(const char *method, const RequestParams &req, const char *otherHeaders, net::RequestProgress *progress);
|
|
int SendRequestWithData(const char *method, const RequestParams &req, const std::string &data, const char *otherHeaders, net::RequestProgress *progress);
|
|
int ReadResponseHeaders(net::Buffer *readbuf, std::vector<std::string> &responseHeaders, net::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, net::RequestProgress *progress);
|
|
|
|
void SetDataTimeout(double t) {
|
|
dataTimeout_ = t;
|
|
}
|
|
|
|
void SetUserAgent(const std::string &value) {
|
|
userAgent_ = value;
|
|
}
|
|
|
|
protected:
|
|
std::string userAgent_;
|
|
double dataTimeout_ = 900.0;
|
|
};
|
|
|
|
// Really an asynchronous request.
|
|
class HTTPRequest : public Request {
|
|
public:
|
|
HTTPRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, std::string_view name = "");
|
|
~HTTPRequest();
|
|
|
|
void Start() override;
|
|
void Join() override;
|
|
|
|
bool Done() override { return completed_; }
|
|
bool Failed() const override { return failed_; }
|
|
|
|
// NOTE! The value of ResultCode is INVALID until Done() returns true.
|
|
int ResultCode() const override { return resultCode_; }
|
|
|
|
const Path &outfile() const override { return outfile_; }
|
|
|
|
// If not downloading to a file, access this to get the result.
|
|
Buffer &buffer() override { return buffer_; }
|
|
const Buffer &buffer() const override { return buffer_; }
|
|
|
|
void Cancel() override {
|
|
cancelled_ = true;
|
|
}
|
|
|
|
bool IsCancelled() const override {
|
|
return cancelled_;
|
|
}
|
|
|
|
private:
|
|
void Do(); // Actually does the download. Runs on thread.
|
|
int Perform(const std::string &url);
|
|
std::string RedirectLocation(const std::string &baseUrl) const;
|
|
void SetFailed(int code);
|
|
|
|
std::string postData_;
|
|
Buffer buffer_;
|
|
std::vector<std::string> responseHeaders_;
|
|
Path outfile_;
|
|
std::thread thread_;
|
|
std::string postMime_;
|
|
int resultCode_ = 0;
|
|
bool completed_ = false;
|
|
bool failed_ = false;
|
|
bool cancelled_ = false;
|
|
bool joined_ = false;
|
|
};
|
|
|
|
} // http
|