mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 00:13:08 +00:00
implemented sceHttpUriParse
This commit is contained in:
parent
db868ea400
commit
01af261ed0
@ -298,6 +298,7 @@ set(KERNEL_LIB src/core/libraries/kernel/sync/mutex.cpp
|
||||
|
||||
set(NETWORK_LIBS src/core/libraries/network/http.cpp
|
||||
src/core/libraries/network/http.h
|
||||
src/core/libraries/network/http_error.h
|
||||
src/core/libraries/network/http2.cpp
|
||||
src/core/libraries/network/http2.h
|
||||
src/core/libraries/network/net.cpp
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/network/http.h"
|
||||
#include "http_error.h"
|
||||
|
||||
namespace Libraries::Http {
|
||||
|
||||
@ -566,17 +567,244 @@ int PS4_SYSV_ABI sceHttpUriMerge() {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceHttpUriParse() {
|
||||
// Helper function to calculate the length of a URI component
|
||||
static size_t calculateComponentLength(const char* start, const char* end) {
|
||||
return (end > start) ? (size_t)(end - start) : 0;
|
||||
}
|
||||
|
||||
// Helper function to parse the port from the URI
|
||||
static int parsePort(const char* uri, int* offset) {
|
||||
int port = 0;
|
||||
int digits = 0;
|
||||
|
||||
while (uri[*offset] >= '0' && uri[*offset] <= '9' && digits < 5) {
|
||||
port = port * 10 + (uri[*offset] - '0');
|
||||
(*offset)++;
|
||||
digits++;
|
||||
}
|
||||
|
||||
if (digits == 0 || port > 65535) {
|
||||
return 0; // Invalid port
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, void* pool,
|
||||
size_t* require, size_t prepare) {
|
||||
LOG_INFO(Lib_Http, "srcUri = {}", std::string(srcUri));
|
||||
if (!srcUri) {
|
||||
LOG_ERROR(Lib_Http, "invalid values");
|
||||
return ORBIS_HTTP_ERROR_INVALID_URL;
|
||||
}
|
||||
|
||||
// Initialize the output structure if provided
|
||||
if (out) {
|
||||
memset(out, 0, sizeof(OrbisHttpUriElement));
|
||||
}
|
||||
|
||||
// Calculate the required buffer size
|
||||
size_t requiredBufferSize = 0;
|
||||
char* currentPos = (char*)srcUri;
|
||||
|
||||
// Scheme (e.g., "http:")
|
||||
char* schemeEnd = strchr(currentPos, ':');
|
||||
if (!schemeEnd) {
|
||||
LOG_ERROR(Lib_Http, "invalid url");
|
||||
return ORBIS_HTTP_ERROR_INVALID_URL;
|
||||
}
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, schemeEnd) + 1; // Include null terminator
|
||||
currentPos = schemeEnd + 1;
|
||||
|
||||
// Check if the URI is opaque or hierarchical
|
||||
bool isOpaque = true; // Assume opaque by default
|
||||
if (strncmp(currentPos, "//", 2) == 0) {
|
||||
isOpaque = false; // Hierarchical if "//" is present
|
||||
currentPos += 2; // Skip "//"
|
||||
}
|
||||
|
||||
//in case it starts with file://///
|
||||
if (strncmp(currentPos, "//", 2) == 0) {
|
||||
currentPos += 2; // Skip "//"
|
||||
}
|
||||
|
||||
// Host and port (e.g., "example.com:8080")
|
||||
char* hostEnd = strchr(currentPos, '/');
|
||||
if (!hostEnd) {
|
||||
hostEnd = currentPos + strlen(currentPos);
|
||||
}
|
||||
|
||||
// Check for credentials (username:password@host)
|
||||
char* atSymbol = strchr(currentPos, '@');
|
||||
if (atSymbol && atSymbol < hostEnd) {
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, atSymbol) + 1; // Include null terminator
|
||||
currentPos = atSymbol + 1;
|
||||
}
|
||||
|
||||
// Check for port (host:port)
|
||||
char* colon = strchr(currentPos, ':');
|
||||
if (colon && colon < hostEnd) {
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, colon) + 1; // Include null terminator
|
||||
currentPos = colon + 1;
|
||||
}
|
||||
|
||||
// Host
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, hostEnd) + 1; // Include null terminator
|
||||
currentPos = hostEnd;
|
||||
|
||||
// Path (e.g., "/path")
|
||||
char* pathEnd = strchr(currentPos, '?');
|
||||
if (!pathEnd) {
|
||||
pathEnd = strchr(currentPos, '#');
|
||||
if (!pathEnd) {
|
||||
pathEnd = currentPos + strlen(currentPos);
|
||||
}
|
||||
}
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, pathEnd) + 1; // Include null terminator
|
||||
currentPos = pathEnd;
|
||||
|
||||
// Query (e.g., "?query=value")
|
||||
if (*currentPos == '?') {
|
||||
currentPos++;
|
||||
char* queryEnd = strchr(currentPos, '#');
|
||||
if (!queryEnd) {
|
||||
queryEnd = currentPos + strlen(currentPos);
|
||||
}
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, queryEnd) + 1; // Include null terminator
|
||||
currentPos = queryEnd;
|
||||
}
|
||||
|
||||
// Fragment (e.g., "#fragment")
|
||||
if (*currentPos == '#') {
|
||||
currentPos++;
|
||||
requiredBufferSize +=
|
||||
calculateComponentLength(currentPos, currentPos + strlen(currentPos)) +
|
||||
1; // Include null terminator
|
||||
}
|
||||
|
||||
// Return the required buffer size
|
||||
if (require) {
|
||||
*require = requiredBufferSize;
|
||||
}
|
||||
|
||||
// If pool is NULL, we're done
|
||||
if (!pool) {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Check if the provided buffer is large enough
|
||||
if (prepare < requiredBufferSize) {
|
||||
LOG_ERROR(Lib_Http, "out of memory");
|
||||
return ORBIS_HTTP_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Copy the URI components to the buffer
|
||||
char* buffer = (char*)pool;
|
||||
strncpy(buffer, srcUri, prepare);
|
||||
buffer[prepare - 1] = '\0'; // Ensure null termination
|
||||
|
||||
// Parse and assign the components to the output structure if provided
|
||||
if (out) {
|
||||
// Scheme
|
||||
schemeEnd = strchr(buffer, ':');
|
||||
*schemeEnd = '\0';
|
||||
out->scheme = buffer;
|
||||
buffer = schemeEnd + 1;
|
||||
|
||||
// Opaque flag
|
||||
out->opaque = isOpaque;
|
||||
|
||||
// Host and port
|
||||
if (!isOpaque) {
|
||||
buffer += 2; // Skip "//"
|
||||
}
|
||||
|
||||
hostEnd = strchr(buffer, '/');
|
||||
if (!hostEnd) {
|
||||
hostEnd = buffer + strlen(buffer);
|
||||
}
|
||||
|
||||
// Credentials (username:password@host)
|
||||
atSymbol = strchr(buffer, '@');
|
||||
if (atSymbol && atSymbol < hostEnd) {
|
||||
*atSymbol = '\0';
|
||||
colon = strchr(buffer, ':');
|
||||
if (colon) {
|
||||
*colon = '\0';
|
||||
out->username = buffer;
|
||||
out->password = colon + 1;
|
||||
} else {
|
||||
out->username = buffer;
|
||||
}
|
||||
buffer = atSymbol + 1;
|
||||
}
|
||||
|
||||
// Port (host:port)
|
||||
colon = strchr(buffer, ':');
|
||||
if (colon && colon < hostEnd) {
|
||||
*colon = '\0';
|
||||
int offset = colon + 1 - buffer;
|
||||
out->port = parsePort(buffer, &offset);
|
||||
if (out->port == 0) {
|
||||
LOG_ERROR(Lib_Http, "invalid url");
|
||||
return ORBIS_HTTP_ERROR_INVALID_URL;
|
||||
}
|
||||
}
|
||||
|
||||
// Host
|
||||
*hostEnd = '\0';
|
||||
out->hostname = buffer;
|
||||
buffer = hostEnd + 1;
|
||||
|
||||
// Path
|
||||
pathEnd = strchr(buffer, '?');
|
||||
if (!pathEnd) {
|
||||
pathEnd = strchr(buffer, '#');
|
||||
if (!pathEnd) {
|
||||
pathEnd = buffer + strlen(buffer);
|
||||
}
|
||||
}
|
||||
*pathEnd = '\0';
|
||||
out->path = buffer;
|
||||
buffer = pathEnd + 1;
|
||||
|
||||
// Query
|
||||
if (*buffer == '?') {
|
||||
buffer++;
|
||||
char* queryEnd = strchr(buffer, '#');
|
||||
if (!queryEnd) {
|
||||
queryEnd = buffer + strlen(buffer);
|
||||
}
|
||||
*queryEnd = '\0';
|
||||
out->query = buffer;
|
||||
buffer = queryEnd + 1;
|
||||
}
|
||||
|
||||
// Fragment
|
||||
if (*buffer == '#') {
|
||||
buffer++;
|
||||
out->fragment = buffer;
|
||||
}
|
||||
|
||||
// Initialize the reserved field to zero
|
||||
memset(out->reserved, 0, sizeof(out->reserved)); // RE indicates some works here but haven't
|
||||
// been added not sure if it neccesary
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize) {
|
||||
LOG_ERROR(Lib_Http, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceHttpUriSweepPath() {
|
||||
LOG_ERROR(Lib_Http, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceHttpUriUnescape() {
|
||||
int PS4_SYSV_ABI sceHttpUriUnescape(char* out, size_t* require, size_t prepare, const char* in) {
|
||||
LOG_ERROR(Lib_Http, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -11,6 +11,19 @@ class SymbolsResolver;
|
||||
|
||||
namespace Libraries::Http {
|
||||
|
||||
struct OrbisHttpUriElement {
|
||||
bool opaque;
|
||||
char* scheme;
|
||||
char* username;
|
||||
char* password;
|
||||
char* hostname;
|
||||
char* path;
|
||||
char* query;
|
||||
char* fragment;
|
||||
u16 port;
|
||||
u8 reserved[10];
|
||||
};
|
||||
|
||||
int PS4_SYSV_ABI sceHttpAbortRequest();
|
||||
int PS4_SYSV_ABI sceHttpAbortRequestForce();
|
||||
int PS4_SYSV_ABI sceHttpAbortWaitRequest();
|
||||
@ -122,9 +135,10 @@ int PS4_SYSV_ABI sceHttpUriBuild();
|
||||
int PS4_SYSV_ABI sceHttpUriCopy();
|
||||
int PS4_SYSV_ABI sceHttpUriEscape();
|
||||
int PS4_SYSV_ABI sceHttpUriMerge();
|
||||
int PS4_SYSV_ABI sceHttpUriParse();
|
||||
int PS4_SYSV_ABI sceHttpUriSweepPath();
|
||||
int PS4_SYSV_ABI sceHttpUriUnescape();
|
||||
int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, void* pool,
|
||||
size_t* require, size_t prepare);
|
||||
int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize);
|
||||
int PS4_SYSV_ABI sceHttpUriUnescape(char* out, size_t* require, size_t prepare, const char* in);
|
||||
int PS4_SYSV_ABI sceHttpWaitRequest();
|
||||
|
||||
void RegisterlibSceHttp(Core::Loader::SymbolsResolver* sym);
|
||||
|
66
src/core/libraries/network/http_error.h
Normal file
66
src/core/libraries/network/http_error.h
Normal file
@ -0,0 +1,66 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
constexpr int ORBIS_HTTP_ERROR_BEFORE_INIT = 0x80431001;
|
||||
constexpr int ORBIS_HTTP_ERROR_ALREADY_INITED = 0x80431020;
|
||||
constexpr int ORBIS_HTTP_ERROR_BUSY = 0x80431021;
|
||||
constexpr int ORBIS_HTTP_ERROR_OUT_OF_MEMORY = 0x80431022;
|
||||
constexpr int ORBIS_HTTP_ERROR_NOT_FOUND = 0x80431025;
|
||||
constexpr int ORBIS_HTTP_ERROR_INVALID_VERSION = 0x8043106a;
|
||||
constexpr int ORBIS_HTTP_ERROR_INVALID_ID = 0x80431100;
|
||||
constexpr int ORBIS_HTTP_ERROR_OUT_OF_SIZE = 0x80431104;
|
||||
constexpr int ORBIS_HTTP_ERROR_INVALID_VALUE = 0x804311fe;
|
||||
|
||||
constexpr int ORBIS_HTTP_ERROR_INVALID_URL = 0x80433060;
|
||||
constexpr int ORBIS_HTTP_ERROR_UNKNOWN_SCHEME = 0x80431061;
|
||||
constexpr int ORBIS_HTTP_ERROR_NETWORK = 0x80431063;
|
||||
constexpr int ORBIS_HTTP_ERROR_BAD_RESPONSE = 0x80431064;
|
||||
constexpr int ORBIS_HTTP_ERROR_BEFORE_SEND = 0x80431065;
|
||||
constexpr int ORBIS_HTTP_ERROR_AFTER_SEND = 0x80431066;
|
||||
constexpr int ORBIS_HTTP_ERROR_TIMEOUT = 0x80431068;
|
||||
constexpr int ORBIS_HTTP_ERROR_UNKNOWN_AUTH_TYPE = 0x80431069;
|
||||
constexpr int ORBIS_HTTP_ERROR_UNKNOWN_METHOD = 0x8043106b;
|
||||
constexpr int ORBIS_HTTP_ERROR_READ_BY_HEAD_METHOD = 0x8043106f;
|
||||
constexpr int ORBIS_HTTP_ERROR_NOT_IN_COM = 0x80431070;
|
||||
constexpr int ORBIS_HTTP_ERROR_NO_CONTENT_LENGTH = 0x80431071;
|
||||
constexpr int ORBIS_HTTP_ERROR_CHUNK_ENC = 0x80431072;
|
||||
constexpr int ORBIS_HTTP_ERROR_TOO_LARGE_RESPONSE_HEADER = 0x80431073;
|
||||
constexpr int ORBIS_HTTP_ERROR_SSL = 0x80431075;
|
||||
constexpr int ORBIS_HTTP_ERROR_INSUFFICIENT_STACKSIZE = 0x80431076;
|
||||
constexpr int ORBIS_HTTP_ERROR_ABORTED = 0x80431080;
|
||||
constexpr int ORBIS_HTTP_ERROR_UNKNOWN = 0x80431081;
|
||||
constexpr int ORBIS_HTTP_ERROR_EAGAIN = 0x80431082;
|
||||
constexpr int ORBIS_HTTP_ERROR_PROXY = 0x80431084;
|
||||
constexpr int ORBIS_HTTP_ERROR_BROKEN = 0x80431085;
|
||||
|
||||
constexpr int ORBIS_HTTP_ERROR_PARSE_HTTP_NOT_FOUND = 0x80432025;
|
||||
constexpr int ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE = 0x80432060;
|
||||
constexpr int ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_VALUE = 0x804321fe;
|
||||
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_EPACKET = 0x80436001;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ENODNS = 0x80436002;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ETIMEDOUT = 0x80436003;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ENOSUPPORT = 0x80436004;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_EFORMAT = 0x80436005;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ESERVERFAILURE = 0x80436006;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ENOHOST = 0x80436007;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ENOTIMPLEMENTED = 0x80436008;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ESERVERREFUSED = 0x80436009;
|
||||
constexpr int ORBIS_HTTP_ERROR_RESOLVER_ENORECORD = 0x8043600a;
|
||||
|
||||
constexpr int ORBIS_HTTPS_ERROR_CERT = 0x80435060;
|
||||
constexpr int ORBIS_HTTPS_ERROR_HANDSHAKE = 0x80435061;
|
||||
constexpr int ORBIS_HTTPS_ERROR_IO = 0x80435062;
|
||||
constexpr int ORBIS_HTTPS_ERROR_INTERNAL = 0x80435063;
|
||||
constexpr int ORBIS_HTTPS_ERROR_PROXY = 0x80435064;
|
||||
|
||||
constexpr int ORBIS_HTTPS_ERROR_SSL_INTERNAL = 0x01;
|
||||
constexpr int ORBIS_HTTPS_ERROR_SSL_INVALID_CERT = 0x02;
|
||||
constexpr int ORBIS_HTTPS_ERROR_SSL_CN_CHECK = 0x04;
|
||||
constexpr int ORBIS_HTTPS_ERROR_SSL_NOT_AFTER_CHECK = 0x08;
|
||||
constexpr int ORBIS_HTTPS_ERROR_SSL_NOT_BEFORE_CHECK = 0x10;
|
||||
constexpr int ORBIS_HTTPS_ERROR_SSL_UNKNOWN_CA = 0x20;
|
Loading…
Reference in New Issue
Block a user