mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-09 17:25:37 -06:00
sceNpWebApi2AddHttpRequestHeader
This commit is contained in:
parent
8f04464ada
commit
710aa909c3
@ -17,9 +17,15 @@ s32 PS4_SYSV_ABI sceNpWebApi2AbortRequest(s64 request_id) {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpWebApi2AddHttpRequestHeader() {
|
||||
LOG_ERROR(Lib_NpWebApi2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceNpWebApi2AddHttpRequestHeader(s64 request_id, const char* field_name,
|
||||
const char* field_value) {
|
||||
if (!field_name || !field_value) {
|
||||
LOG_ERROR(Lib_NpWebApi2, "Invalid parameters");
|
||||
return ORBIS_NP_WEBAPI2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
LOG_INFO(Lib_NpWebApi2, "called, request_id = {:#x}, field_name = {}, field_value = {}",
|
||||
request_id, field_name, field_value);
|
||||
return addHttpRequestHeader(request_id, field_name, field_value);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpWebApi2AddMultipartPart() {
|
||||
@ -134,7 +140,8 @@ s32 PS4_SYSV_ABI sceNpWebApi2Initialize(s32 lib_http_ctx_id, u64 pool_size) {
|
||||
LOG_DEBUG(Lib_NpWebApi2, "called, lib_http_ctx_id = {:#x}, pool_size = {:#x}", lib_http_ctx_id,
|
||||
pool_size);
|
||||
|
||||
s32 ctx_id = createLibraryContext(lib_http_ctx_id, pool_size, nullptr);
|
||||
// Uses a sceLncUtilGetAppStatus check to enable debug mode. For now, default to normal.
|
||||
s32 ctx_id = createLibraryContext(lib_http_ctx_id, 1, pool_size, nullptr);
|
||||
if (ctx_id > 0) {
|
||||
LOG_INFO(Lib_NpWebApi2, "created lib_ctx_id = {:#x}", ctx_id);
|
||||
}
|
||||
@ -145,7 +152,7 @@ s32 PS4_SYSV_ABI sceNpWebApi2InitializeForPresence(s32 lib_http_ctx_id, u64 pool
|
||||
LOG_DEBUG(Lib_NpWebApi2, "called, lib_http_ctx_id = {:#x}, pool_size = {:#x}", lib_http_ctx_id,
|
||||
pool_size);
|
||||
|
||||
s32 ctx_id = createLibraryContext(lib_http_ctx_id, pool_size, nullptr);
|
||||
s32 ctx_id = createLibraryContext(lib_http_ctx_id, 3, pool_size, nullptr);
|
||||
if (ctx_id > 0) {
|
||||
LOG_INFO(Lib_NpWebApi2, "created lib_ctx_id = {:#x}", ctx_id);
|
||||
}
|
||||
@ -165,7 +172,7 @@ s32 PS4_SYSV_ABI sceNpWebApi2IntInitialize(const OrbisNpWebApi2IntInitializeArgs
|
||||
LOG_DEBUG(Lib_NpWebApi2, "called, lib_http_ctx_id = {:#x}, pool_size = {:#x}, name = {}",
|
||||
args->lib_http_ctx_id, args->pool_size, args->name ? args->name : "(null)");
|
||||
|
||||
s32 ctx_id = createLibraryContext(args->lib_http_ctx_id, args->pool_size, args->name);
|
||||
s32 ctx_id = createLibraryContext(args->lib_http_ctx_id, 2, args->pool_size, args->name);
|
||||
if (ctx_id > 0) {
|
||||
LOG_INFO(Lib_NpWebApi2, "created lib_ctx_id = {:#x}", ctx_id);
|
||||
}
|
||||
@ -184,7 +191,7 @@ s32 PS4_SYSV_ABI sceNpWebApi2IntInitialize2(const OrbisNpWebApi2IntInitialize2Ar
|
||||
args->lib_http_ctx_id, args->pool_size, args->name ? args->name : "(null)",
|
||||
args->push_config_group);
|
||||
|
||||
s32 ctx_id = createLibraryContext(args->lib_http_ctx_id, args->pool_size, args->name);
|
||||
s32 ctx_id = createLibraryContext(args->lib_http_ctx_id, 2, args->pool_size, args->name);
|
||||
if (ctx_id > 0) {
|
||||
LOG_INFO(Lib_NpWebApi2, "created lib_ctx_id = {:#x}", ctx_id);
|
||||
}
|
||||
|
||||
@ -73,15 +73,16 @@ s32 UserContext::Initialize() {
|
||||
const char* name = this->parent_ctx->GetName();
|
||||
|
||||
char sw_version[8];
|
||||
memset(sw_version, 0, sizeof(sw_version));
|
||||
std::memset(sw_version, 0, sizeof(sw_version));
|
||||
Libraries::Np::NpCommon::sceNpGetSdkVersion(sw_version);
|
||||
|
||||
char user_agent_buf[0x40];
|
||||
memset(user_agent_buf, 0, sizeof(user_agent_buf));
|
||||
std::memset(user_agent_buf, 0, sizeof(user_agent_buf));
|
||||
if (name) {
|
||||
snprintf(user_agent_buf, sizeof(user_agent_buf), "NpWebApi2/%s (%s)", sw_version, name);
|
||||
std::snprintf(user_agent_buf, sizeof(user_agent_buf), "NpWebApi2/%s (%s)", sw_version,
|
||||
name);
|
||||
} else {
|
||||
snprintf(user_agent_buf, sizeof(user_agent_buf), "NpWebApi2/%s", sw_version);
|
||||
std::snprintf(user_agent_buf, sizeof(user_agent_buf), "NpWebApi2/%s", sw_version);
|
||||
}
|
||||
this->user_agent = std::string{user_agent_buf};
|
||||
|
||||
@ -131,4 +132,64 @@ s32 UserContext::CreateRequest(const char* api_group, const char* path, const ch
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
Request* UserContext::GetRequest(s64 request_id) {
|
||||
this->Lock();
|
||||
if (!this->requests.contains(request_id)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Request* request = this->requests[request_id];
|
||||
request->AddUser();
|
||||
this->Unlock();
|
||||
return request;
|
||||
}
|
||||
|
||||
bool IsInternalHeader(const char* header_name) {
|
||||
std::string lower_name{header_name};
|
||||
std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(),
|
||||
[](char c) { return std::tolower(c); });
|
||||
// These headers are all skipped if the request's library context
|
||||
// was not created through the IntInitialize functions.
|
||||
return lower_name.compare("content-type") == 0 || lower_name.compare("user-agent") == 0 ||
|
||||
lower_name.compare("authorization") == 0 ||
|
||||
lower_name.compare("x-psn-np-title-id") == 0 ||
|
||||
lower_name.compare("x-psn-np-title-token") == 0 ||
|
||||
lower_name.compare("x-psn-request-id") == 0 ||
|
||||
lower_name.compare("x-psn-sdk-ver") == 0 ||
|
||||
lower_name.compare("x-psn-debug-settings") == 0 || lower_name.compare("npdebug") == 0 ||
|
||||
lower_name.compare("x-psn-trc-check-notification-enabled") == 0 ||
|
||||
lower_name.compare("x-psn-webtrace-enabled") == 0 ||
|
||||
lower_name.compare("x-psn-npwebapi2-context") == 0 ||
|
||||
lower_name.compare("x-psn-fake-rate-limit-enabled") == 0 ||
|
||||
lower_name.compare("x-psn-fake-rate-limit-targets") == 0;
|
||||
}
|
||||
|
||||
s32 Request::AddHttpRequestHeader(const char* field_name, const char* field_value) {
|
||||
std::string name{field_name};
|
||||
std::string value{field_value};
|
||||
|
||||
if (!this->parent_ctx->IsInternal() && IsInternalHeader(field_name)) {
|
||||
LOG_WARNING(Lib_NpWebApi2, "This is not an internal context, skipping field name {}",
|
||||
field_name);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
this->Lock();
|
||||
HttpRequestHeader* new_header = new HttpRequestHeader(nullptr, nullptr, name, value);
|
||||
if (!this->http_headers) {
|
||||
// Creates a new blank head node
|
||||
this->http_headers = new HttpRequestHeader(nullptr, nullptr, "", "");
|
||||
this->http_headers->prev = this->http_headers;
|
||||
this->http_headers->next = this->http_headers;
|
||||
}
|
||||
|
||||
new_header->prev = this->http_headers->prev;
|
||||
new_header->next = this->http_headers;
|
||||
this->http_headers->prev->next = new_header;
|
||||
this->http_headers->prev = new_header;
|
||||
http_header_count++;
|
||||
this->Unlock();
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
}; // namespace Libraries::Np::NpWebApi2
|
||||
@ -18,10 +18,12 @@ class Request;
|
||||
|
||||
class LibraryContext {
|
||||
public:
|
||||
LibraryContext(s32 ctx_id, s32 http_ctx_id, u64 pool_size)
|
||||
: id(ctx_id), http_ctx_id(http_ctx_id), pool_size(pool_size) {}
|
||||
LibraryContext(s32 ctx_id, s32 http_ctx_id, u64 pool_size, const char* name)
|
||||
: id(ctx_id), http_ctx_id(http_ctx_id), pool_size(pool_size), name(name) {}
|
||||
LibraryContext(s32 ctx_id, s32 type, s32 http_ctx_id, u64 pool_size)
|
||||
: id(ctx_id), type(static_cast<LibraryContextType>(type)), http_ctx_id(http_ctx_id),
|
||||
pool_size(pool_size) {}
|
||||
LibraryContext(s32 ctx_id, s32 type, s32 http_ctx_id, u64 pool_size, const char* name)
|
||||
: id(ctx_id), type(static_cast<LibraryContextType>(type)), http_ctx_id(http_ctx_id),
|
||||
pool_size(pool_size), name(name) {}
|
||||
|
||||
void Lock() {
|
||||
lock.lock();
|
||||
@ -57,6 +59,22 @@ public:
|
||||
return name.empty() ? nullptr : name.data();
|
||||
}
|
||||
|
||||
bool IsDebug() {
|
||||
return type == LibraryContextType::Debug;
|
||||
}
|
||||
|
||||
bool IsNormal() {
|
||||
return type == LibraryContextType::Normal;
|
||||
}
|
||||
|
||||
bool IsInternal() {
|
||||
return type == LibraryContextType::Internal;
|
||||
}
|
||||
|
||||
bool IsPresence() {
|
||||
return type == LibraryContextType::Presence;
|
||||
}
|
||||
|
||||
s32 CreateUserContext(Libraries::UserService::OrbisUserServiceUserId user_id);
|
||||
UserContext* GetUserContext(s32 user_ctx_id);
|
||||
UserContext* GetUserContextByUserId(Libraries::UserService::OrbisUserServiceUserId user_id);
|
||||
@ -70,6 +88,12 @@ private:
|
||||
s32 id{};
|
||||
s32 http_ctx_id{};
|
||||
s32 user_count{};
|
||||
enum LibraryContextType : s32 {
|
||||
Debug = 0,
|
||||
Normal = 1,
|
||||
Internal = 2,
|
||||
Presence = 3,
|
||||
} type;
|
||||
u64 pool_size{};
|
||||
std::recursive_mutex lock{};
|
||||
std::string name{};
|
||||
@ -93,15 +117,15 @@ public:
|
||||
}
|
||||
|
||||
void AddUser() {
|
||||
parent_ctx->Lock();
|
||||
Lock();
|
||||
user_count++;
|
||||
parent_ctx->Unlock();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void RemoveUser() {
|
||||
parent_ctx->Lock();
|
||||
Lock();
|
||||
user_count--;
|
||||
parent_ctx->Unlock();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
s32 GetId() {
|
||||
@ -117,6 +141,7 @@ public:
|
||||
s32 CreateRequest(const char* api_group, const char* path, const char* method,
|
||||
const OrbisNpWebApi2ContentParameter* content_parameter, bool multipart,
|
||||
Request** request);
|
||||
Request* GetRequest(s64 request_id);
|
||||
|
||||
private:
|
||||
s32 id{};
|
||||
@ -140,11 +165,35 @@ public:
|
||||
: parent_ctx(parent), id(request_id), api_group(api_group), path(path), method(method),
|
||||
multipart_supported(multipart), content_type(content_parameter->content_type) {}
|
||||
|
||||
void Lock() {
|
||||
parent_ctx->Lock();
|
||||
}
|
||||
|
||||
void Unlock() {
|
||||
parent_ctx->Unlock();
|
||||
}
|
||||
|
||||
void AddUser() {
|
||||
Lock();
|
||||
user_count++;
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void RemoveUser() {
|
||||
Lock();
|
||||
user_count--;
|
||||
Unlock();
|
||||
}
|
||||
|
||||
s64 GetId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
s32 Initialize();
|
||||
bool HasSent() {
|
||||
return sent;
|
||||
}
|
||||
|
||||
s32 AddHttpRequestHeader(const char* field_name, const char* field_value);
|
||||
|
||||
private:
|
||||
s64 id{};
|
||||
@ -156,6 +205,15 @@ private:
|
||||
std::string method{};
|
||||
std::string content_type{};
|
||||
bool multipart_supported{};
|
||||
bool sent{};
|
||||
|
||||
struct HttpRequestHeader {
|
||||
HttpRequestHeader* prev;
|
||||
HttpRequestHeader* next;
|
||||
std::string field_name;
|
||||
std::string field_value;
|
||||
}* http_headers{};
|
||||
s32 http_header_count{};
|
||||
};
|
||||
|
||||
}; // namespace Libraries::Np::NpWebApi2
|
||||
@ -17,7 +17,7 @@ std::recursive_mutex g_mutex{};
|
||||
s32 g_current_lib_context_id{};
|
||||
std::map<s32, LibraryContext*> g_lib_contexts{};
|
||||
|
||||
s32 createLibraryContext(s32 http_ctx_id, u64 pool_size, const char* name) {
|
||||
s32 createLibraryContext(s32 http_ctx_id, s32 type, u64 pool_size, const char* name) {
|
||||
std::scoped_lock lk{g_mutex};
|
||||
|
||||
if (g_lib_contexts.size() >= 0x8000) {
|
||||
@ -34,10 +34,10 @@ s32 createLibraryContext(s32 http_ctx_id, u64 pool_size, const char* name) {
|
||||
|
||||
if (!name) {
|
||||
g_lib_contexts[g_current_lib_context_id] =
|
||||
new LibraryContext(g_current_lib_context_id, http_ctx_id, pool_size);
|
||||
new LibraryContext(g_current_lib_context_id, type, http_ctx_id, pool_size);
|
||||
} else {
|
||||
g_lib_contexts[g_current_lib_context_id] =
|
||||
new LibraryContext(g_current_lib_context_id, http_ctx_id, pool_size, name);
|
||||
new LibraryContext(g_current_lib_context_id, type, http_ctx_id, pool_size, name);
|
||||
}
|
||||
return g_current_lib_context_id;
|
||||
}
|
||||
@ -146,4 +146,43 @@ s32 createRequest(s32 user_ctx_id, const char* api_group, const char* path, cons
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 addHttpRequestHeader(s64 request_id, const char* field_name, const char* field_value) {
|
||||
s32 lib_ctx_id = static_cast<s32>(request_id >> 0x30);
|
||||
s32 user_ctx_id = static_cast<s32>(request_id >> 0x20);
|
||||
LibraryContext* lib_ctx = getLibraryContext(lib_ctx_id);
|
||||
if (!lib_ctx) {
|
||||
LOG_ERROR(Lib_NpWebApi2, "No library context for request id {:#x}", request_id);
|
||||
return ORBIS_NP_WEBAPI2_ERROR_LIB_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
UserContext* user_ctx = lib_ctx->GetUserContext(user_ctx_id);
|
||||
if (!user_ctx) {
|
||||
LOG_ERROR(Lib_NpWebApi2, "No user context for request id {:#x}", request_id);
|
||||
lib_ctx->RemoveUser();
|
||||
return ORBIS_NP_WEBAPI2_ERROR_USER_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
Request* request = user_ctx->GetRequest(request_id);
|
||||
if (!request) {
|
||||
LOG_ERROR(Lib_NpWebApi2, "No request with id {:#x}", request_id);
|
||||
user_ctx->RemoveUser();
|
||||
lib_ctx->RemoveUser();
|
||||
return ORBIS_NP_WEBAPI2_ERROR_REQUEST_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (request->HasSent()) {
|
||||
LOG_ERROR(Lib_NpWebApi2, "Request is already sent");
|
||||
request->RemoveUser();
|
||||
user_ctx->RemoveUser();
|
||||
lib_ctx->RemoveUser();
|
||||
return ORBIS_NP_WEBAPI2_ERROR_AFTER_SEND;
|
||||
}
|
||||
|
||||
s32 result = request->AddHttpRequestHeader(field_name, field_value);
|
||||
request->RemoveUser();
|
||||
user_ctx->RemoveUser();
|
||||
lib_ctx->RemoveUser();
|
||||
return result;
|
||||
}
|
||||
|
||||
}; // namespace Libraries::Np::NpWebApi2
|
||||
@ -5,10 +5,11 @@
|
||||
|
||||
namespace Libraries::Np::NpWebApi2 {
|
||||
|
||||
s32 createLibraryContext(s32 http_ctx_id, u64 pool_size, const char* name);
|
||||
s32 createLibraryContext(s32 http_ctx_id, s32 type, u64 pool_size, const char* name);
|
||||
s32 getMemoryPoolStats(s32 lib_ctx_id, OrbisNpWebApi2MemoryPoolStats* stats);
|
||||
s32 createUserContext(s32 lib_ctx_id, Libraries::UserService::OrbisUserServiceUserId user_id);
|
||||
s32 createRequest(s32 user_ctx_id, const char* api_group, const char* path, const char* method,
|
||||
const OrbisNpWebApi2ContentParameter* content_parameter, bool multipart,
|
||||
s64* request_id);
|
||||
s32 addHttpRequestHeader(s64 request_id, const char* field_name, const char* field_value);
|
||||
}; // namespace Libraries::Np::NpWebApi2
|
||||
Loading…
Reference in New Issue
Block a user