add ability to install shared URL from web interface

This commit is contained in:
Chee Yee
2023-08-06 17:53:27 -07:00
parent 83661c7fcb
commit e28e562a10
26 changed files with 674 additions and 187 deletions
+6 -2
View File
@@ -41,7 +41,12 @@ add_executable(ezremote_client
source/clients/webdavclient.cpp
source/clients/sftpclient.cpp
source/clients/rclone.cpp
source/filehost/gdrive_host.cpp
source/filehost/directhost.cpp
source/filehost/gdrive.cpp
source/filehost/filehost.cpp
source/filehost/1fichier.cpp
source/filehost/mediafire.cpp
source/filehost/pixeldrain.cpp
source/server/http_server.cpp
source/actions.cpp
source/config.cpp
@@ -67,7 +72,6 @@ add_self(ezremote_client)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.10" 32 0)
target_link_libraries(ezremote_client
dbglogger
c
c++
png
+1
View File
@@ -41,6 +41,7 @@
permissionsUrl: '/__local__/permission',
installUrl: '/__local__/install',
uploadResumeSizeUrl: '__local__/uploadResumeSize',
installUrlUrl: '/__local__/install_url',
multipleDownloadFileName: 'ezremote-client.zip',
isExtractableFilePattern: /\.(7z|rar|zip)$/i,
pickCallback: function (item) {
+1 -1
View File
@@ -82,7 +82,7 @@ STR_ONETIME_URL=One Time Url
STR_NOT_A_VALID_PACKAGE=Not a valid Package
STR_WAIT_FOR_INSTALL_MSG=Waiting for Package to finish installing
STR_FAIL_INSTALL_TMP_PKG_MSG=Failed to install pkg file. Please delete the tmp pkg manually
STR_FAIL_TO_OBTAIN_GG_DL_MSG=Failed to obtain google download URL
STR_FAIL_TO_OBTAIN_GG_DL_MSG=Failed to obtain download URL
STR_AUTO_DELETE_TMP_PKG=Auto delete temporary downloaded pkg file after install
STR_PROTOCOL_NOT_SUPPORTED=Protocol not supported
STR_COULD_NOT_RESOLVE_HOST=Could not resolve hostname
File diff suppressed because one or more lines are too long
+13 -84
View File
@@ -16,6 +16,7 @@
#include "clients/iis.h"
#include "clients/rclone.h"
#include "clients/sftpclient.h"
#include "filehost/filehost.h"
#include "common.h"
#include "fs.h"
#include "config.h"
@@ -707,7 +708,8 @@ namespace Actions
}
else
{
if (INSTALLER::InstallRemotePkg(it->path, &header) == 0)
std::string url = INSTALLER::getRemoteUrl(it->path, true);
if (INSTALLER::InstallRemotePkg(url, &header, true) == 0)
failed++;
else
success++;
@@ -919,87 +921,6 @@ namespace Actions
}
}
std::string GetGoogleDownloadUrl(std::string &url)
{
size_t scheme_pos = url.find_first_of("://");
size_t path_pos = url.find_first_of("/", scheme_pos + 3);
std::string host = url.substr(0, path_pos);
std::string path = url.substr(path_pos);
std::string first_download_path;
size_t file_id_start_pos = path.find("/file/d/");
if (file_id_start_pos != std::string::npos)
{
file_id_start_pos = file_id_start_pos + 8;
std::string file_id = path.substr(file_id_start_pos);
size_t file_id_end_pos = file_id.find_first_of("/");
file_id = file_id.substr(0, file_id_end_pos);
first_download_path = "/uc?export=download&id=" + file_id;
}
else if (path.find("/uc?export=download") != std::string::npos)
{
first_download_path = path;
}
else
{
return "";
}
WebDAV::WebDavClient tmp_client;
tmp_client.Connect(host.c_str(), "", "", false);
WebDAV::dict_t headers;
tmp_client.GetHeaders(first_download_path.c_str(), &headers);
std::string content_type = WebDAV::get(headers, "content-type");
if (content_type.find("application/octet-stream") != std::string::npos)
{
return first_download_path;
}
else if (content_type.find("text/html") == std::string::npos)
{
return "";
}
char *buffer_ptr = nullptr;
unsigned long long buffer_size = 0;
tmp_client.GetClient()->download_to(first_download_path, buffer_ptr, buffer_size);
lxb_status_t status;
lxb_dom_element_t *element;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)buffer_ptr, buffer_size);
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"form", 4);
if (status != LXB_STATUS_OK)
return "";
std::string download_url;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
std::string form_id((char *)element->attr_id->value->data, element->attr_id->value->length);
if (form_id == "download-form")
{
size_t value_len;
const lxb_char_t *value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"action", 6, &value_len);
download_url = std::string((char *)value, value_len);
break;
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return download_url;
}
void *InstallUrlPkgThread(void *argp)
{
bytes_transfered = 0;
@@ -1013,8 +934,16 @@ namespace Actions
sprintf(filename, "%s/%lu.pkg", DATA_PATH, tick.mytick);
std::string full_url = std::string(install_pkg_url.url);
if (full_url.find("https://drive.google.com") != std::string::npos)
full_url = GetGoogleDownloadUrl(full_url);
FileHost *filehost = FileHost::getFileHost(full_url);
if (!filehost->IsValidUrl())
{
sprintf(status_message, "%s", lang_strings[STR_FAIL_TO_OBTAIN_GG_DL_MSG]);
activity_inprogess = false;
Windows::SetModalMode(false);
return NULL;
}
full_url = filehost->GetDownloadUrl();
delete(filehost);
if (full_url.empty())
{
+6 -2
View File
@@ -6,7 +6,7 @@
class Base64
{
public:
static int Encode(const std::string &input, std::string &out)
static int Encode(unsigned char *input, size_t in_len, std::string &out)
{
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
@@ -18,7 +18,6 @@ public:
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
size_t in_len = input.size();
size_t out_len = 4 * ((in_len + 2) / 3);
out.resize(out_len);
size_t i;
@@ -50,6 +49,11 @@ public:
return 1;
}
static int Encode(const std::string &input, std::string &out)
{
return Encode((unsigned char*)input.data(), input.size(), out);
}
static int Decode(const std::string &input, std::string &out)
{
static constexpr unsigned char kDecodingTable[] = {
-22
View File
@@ -1,5 +1,3 @@
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <fstream>
#include <curl/curl.h>
#include "common.h"
@@ -319,23 +317,3 @@ std::string BaseClient::DecodeUrl(const std::string &url)
}
return "";
}
lxb_dom_node_t *BaseClient::NextChildElement(lxb_dom_element_t *element)
{
lxb_dom_node_t *node = element->node.first_child;
while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
node = node->next;
}
return node;
}
lxb_dom_node_t *BaseClient::NextElement(lxb_dom_node_t *node)
{
lxb_dom_node_t *next = node->next;
while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
next = next->next;
}
return next;
}
-2
View File
@@ -40,8 +40,6 @@ public:
uint32_t SupportedActions();
static std::string EncodeUrl(const std::string &url);
static std::string DecodeUrl(const std::string &url);
static lxb_dom_node_t *NextChildElement(lxb_dom_element_t *element);
static lxb_dom_node_t *NextElement(lxb_dom_node_t *node);
protected:
httplib::Client *client;
+42
View File
@@ -4,6 +4,8 @@
#include <string>
#include <vector>
#include <string.h>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#define HTTP_SUCCESS(x) (x >= 200 && x < 300)
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -86,4 +88,44 @@ struct DirEntry
}
};
static lxb_dom_node_t *NextChildElement(lxb_dom_element_t *element)
{
lxb_dom_node_t *node = element->node.first_child;
while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
node = node->next;
}
return node;
}
static lxb_dom_node_t *NextElement(lxb_dom_node_t *node)
{
lxb_dom_node_t *next = node->next;
while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
next = next->next;
}
return next;
}
static lxb_dom_node_t *NextChildTextNode(lxb_dom_element_t *element)
{
lxb_dom_node_t *node = element->node.first_child;
while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_TEXT)
{
node = node->next;
}
return node;
}
static lxb_dom_node_t *NextTextNode(lxb_dom_node_t *node)
{
lxb_dom_node_t *next = node->next;
while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_TEXT)
{
next = next->next;
}
return next;
}
#endif
+142
View File
@@ -0,0 +1,142 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "1fichier.h"
#define VALIDATION_REGEX "https:\\/\\/1fichier\\.com\\/(.*)"
FichierHost::FichierHost(const std::string &url) : FileHost(url)
{
}
bool FichierHost::IsValidUrl()
{
std::regex regex(VALIDATION_REGEX);
if (std::regex_match(url, regex))
return true;
return false;
}
std::string FichierHost::GetDownloadUrl()
{
std::regex re("https:\\/\\/1fichier\\.com");
std::string path = std::regex_replace(url, re, "");
httplib::Client tmp_client("https://1fichier.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
lxb_status_t status;
lxb_dom_element_t *element;
lxb_dom_node_t *node;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
const lxb_char_t *value;
size_t value_len;
std::string download_url = "";
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"input", 5);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
std::string post_data;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"name", 4, &value_len);
if (value != nullptr)
{
std::string name_attr((char *)value, value_len);
if (name_attr == "adz")
{
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"value", 5, &value_len);
std::string adz_value((char *)value, value_len);
post_data = std::string("adz=") + adz_value + "&did=0&dl_no_ssl=off&dlinline=on";
break;
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
if (auto res = tmp_client.Post(path, post_data.c_str(), post_data.length(), "application/x-www-form-urlencoded"))
{
if (HTTP_SUCCESS(res->status))
{
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"a", 1);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"class", 5, &value_len);
if (value != nullptr)
{
std::string class_value((char*) value, value_len);
if (class_value == "ok btn-general btn-orange")
{
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"href", 4, &value_len);
if (value != nullptr)
{
download_url = std::string((char*) value, value_len);
break;
}
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
}
}
return download_url;
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef FICHIER_HOST_H
#define FICHIER_HOST_H
#include "filehost.h"
class FichierHost : public FileHost
{
public:
FichierHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "directhost.h"
#define VALIDATION_REGEX "(.*)"
DirectHost::DirectHost(const std::string &url) : FileHost(url)
{
}
bool DirectHost::IsValidUrl()
{
std::regex regex_1(VALIDATION_REGEX);
if (std::regex_match(url, regex_1))
return true;
return false;
}
std::string DirectHost::GetDownloadUrl()
{
return url;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef DIRECT_HOST_H
#define DIRECT_HOST_H
#include "filehost.h"
class DirectHost : public FileHost
{
public:
DirectHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+64
View File
@@ -0,0 +1,64 @@
#include <regex>
#include <string>
#include <vector>
#include <map>
#include "openssl/md5.h"
#include "filehost.h"
#include "1fichier.h"
#include "filehost/directhost.h"
#include "filehost/gdrive.h"
#include "filehost/mediafire.h"
#include "filehost/pixeldrain.h"
#include "base64.h"
#include "util.h"
#define GDRIVE_REGEX "https:\\/\\/drive\\.google\\.com\\/(.*)"
#define MEDIAFIRE_REGEX "https:\\/\\/www\\.mediafire\\.com\\/(.*)"
#define PIXELDRAIN_REGEX "https:\\/\\/pixeldrain\\.com\\/(.*)"
#define FICHIER_REGEX "https:\\/\\/1fichier\\.com\\/(.*)"
static std::map<std::string, std::string> cache_downloal_urls;
std::string FileHost::Hash()
{
std::vector<unsigned char> res(16);
MD5((const unsigned char *)this->url.c_str(), this->url.length(), res.data());
std::string out;
Base64::Encode(res.data(), res.size(), out);
Util::ReplaceAll(out, "=", "_");
Util::ReplaceAll(out, "+", "_");
out = out + ".pkg";
return out;
}
FileHost *FileHost::getFileHost(const std::string &url)
{
std::regex google_re(GDRIVE_REGEX);
std::regex mediafire_re(MEDIAFIRE_REGEX);
std::regex pixeldrain_re(PIXELDRAIN_REGEX);
std::regex fichier_re(FICHIER_REGEX);
if (std::regex_match(url, google_re))
return new GDriveHost(url);
else if (std::regex_match(url, mediafire_re))
return new MediaFireHost(url);
else if (std::regex_match(url, pixeldrain_re))
return new PixelDrainHost(url);
else if (std::regex_match(url, fichier_re))
return new FichierHost(url);
else
return new DirectHost(url);
}
std::string FileHost::GetCachedDownloadUrl(std::string &hash)
{
return cache_downloal_urls[hash];
}
void FileHost::AddCacheDownloadUrl(std::string &hash, std::string &url)
{
std::pair<std::string, std::string> pair = std::make_pair(hash, url);
cache_downloal_urls.insert(pair);
}
+4 -7
View File
@@ -3,7 +3,6 @@
#include <string>
#include <vector>
#include "openssl/md5.h"
class FileHost
{
@@ -13,12 +12,10 @@ public:
virtual bool IsValidUrl() = 0;
virtual std::string GetDownloadUrl() = 0;
std::vector<unsigned char> Hash()
{
std::vector<unsigned char> res(16);
MD5((const unsigned char *)this->url.c_str(), this->url.length(), res.data());
return res;
}
std::string Hash();
static FileHost *getFileHost(const std::string &url);
static std::string GetCachedDownloadUrl(std::string &hash);
static void AddCacheDownloadUrl(std::string &hash, std::string &url);
protected:
std::string url;
@@ -4,11 +4,10 @@
#include <http/httplib.h>
#include "common.h"
#include "gdrive_host.h"
#include "gdrive.h"
#define VALIDATION_REGEX_1 "https:\\/\\/drive\\.google\\.com\\/file\\/d\\/(.*)\\/(edit|view)\\?usp=(.*)"
#define VALIDATION_REGEX_2 "https:\\/\\/drive\\.google\\.com\\/uc\\?export=download&id=(.*)"
#define VALIDATION_REGEX_2 "https:\\/\\/drive\\.google\\.com\\/(.*)uc\\?(id=|export=)(.*)&(id=|export=)(.*)"
GDriveHost::GDriveHost(const std::string &url) : FileHost(url)
{
@@ -17,7 +16,7 @@ GDriveHost::GDriveHost(const std::string &url) : FileHost(url)
bool GDriveHost::IsValidUrl()
{
std::regex regex_1(VALIDATION_REGEX_1);
std::regex regex_2(VALIDATION_REGEX_1);
std::regex regex_2(VALIDATION_REGEX_2);
if (std::regex_match(url, regex_1) || std::regex_match(url, regex_2))
return true;
@@ -26,22 +25,39 @@ bool GDriveHost::IsValidUrl()
std::string GDriveHost::GetDownloadUrl()
{
std::regex re("https:\\/\\/drive\\.google\\.com");
std::string path = std::regex_replace(url, re, "");
std::regex regex_1(VALIDATION_REGEX_1);
std::smatch matches;
std::string path;
if(std::regex_search(url, matches, regex_1))
{
path = std::string("/uc?export=download&id=") + matches[1].str();
}
else
{
std::regex re("https:\\/\\/drive\\.google\\.com");
path = std::regex_replace(url, re, "");
}
httplib::Client tmp_client("https://drive.google.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Head(path);
if (HTTP_SUCCESS(res->status))
{
std::string content_type = res->get_header_value("Content-Type");
if (content_type == "application/octet-stream")
return url;
else if (content_type != "text/html")
else if (content_type.find("text/html") == std::string::npos)
return "";
}
else
return "";
res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
@@ -50,6 +66,7 @@ std::string GDriveHost::GetDownloadUrl()
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
@@ -57,12 +74,19 @@ std::string GDriveHost::GetDownloadUrl()
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"form", 4);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
std::string download_url;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
@@ -76,6 +100,7 @@ std::string GDriveHost::GetDownloadUrl()
break;
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
+89
View File
@@ -0,0 +1,89 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "mediafire.h"
#define VALIDATION_REGEX "https:\\/\\/www\\.mediafire\\.com\\/file\\/(.*)\\/(.*)\\/file"
MediaFireHost::MediaFireHost(const std::string &url) : FileHost(url)
{
}
bool MediaFireHost::IsValidUrl()
{
std::regex regex(VALIDATION_REGEX);
if (std::regex_match(url, regex))
return true;
return false;
}
std::string MediaFireHost::GetDownloadUrl()
{
std::regex re("https:\\/\\/www\\.mediafire\\.com");
std::string path = std::regex_replace(url, re, "");
httplib::Client tmp_client("https://www.mediafire.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
lxb_status_t status;
lxb_dom_element_t *element;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"a", 1);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
std::string download_url;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
if (element->attr_id != nullptr)
{
std::string a_id((char *)element->attr_id->value->data, element->attr_id->value->length);
if (a_id == "downloadButton")
{
size_t value_len;
const lxb_char_t *value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"href", 4, &value_len);
download_url = std::string((char *)value, value_len);
break;
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return download_url;
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef MEDIAFIRE_HOST_H
#define MEDIAFIRE_HOST_H
#include "filehost.h"
class MediaFireHost : public FileHost
{
public:
MediaFireHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+38
View File
@@ -0,0 +1,38 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "pixeldrain.h"
#define VALIDATION_REGEX "https:\\/\\/pixeldrain\\.com\\/u\\/(.*)"
PixelDrainHost::PixelDrainHost(const std::string &url) : FileHost(url)
{
}
bool PixelDrainHost::IsValidUrl()
{
std::regex re(VALIDATION_REGEX);
if (std::regex_match(url, re))
return true;
return false;
}
std::string PixelDrainHost::GetDownloadUrl()
{
std::regex re(VALIDATION_REGEX);
std::smatch matches;
if(std::regex_search(url, matches, re))
{
if (matches.size() > 1)
{
return std::string("https://pixeldrain.com/api/file/") + matches[1].str() + "?download=";
}
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef PIXELDRAIN_HOST_H
#define PIXELDRAIN_HOST_H
#include "filehost.h"
class PixelDrainHost : public FileHost
{
public:
PixelDrainHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+36 -26
View File
@@ -145,15 +145,12 @@ namespace INSTALLER
return true;
}
int InstallRemotePkg(const std::string &path, pkg_header *header)
int InstallRemotePkg(const std::string &url, pkg_header *header, bool prompt)
{
std::string url = getRemoteUrl(path, true);
if (url.empty())
return 0;
int ret;
std::string filename = path.substr(path.find_last_of("/")+1);
std::string cid = std::string((char *)header->pkg_content_id);
cid = cid.substr(cid.find_first_of("-") + 1, 9);
int user_id;
@@ -199,7 +196,7 @@ namespace INSTALLER
params.entitlementType = 5;
params.id = (char *)header->pkg_content_id;
params.contentUrl = url.c_str();
params.contentName = filename.c_str();
params.contentName = cid.c_str();
params.iconPath = "";
params.playgoScenarioId = "0";
params.option = ORBIS_BGFT_TASK_OPT_DISABLE_CDN_QUERY_PARAM;
@@ -216,18 +213,28 @@ namespace INSTALLER
ret = sceBgftServiceIntDebugDownloadRegisterPkg(&params, &task_id);
if (ret == 0x80990088 || ret == 0x80990015)
{
sprintf(confirm_message, "%s - %s?", path.c_str(), lang_strings[STR_REINSTALL_CONFIRM_MSG]);
confirm_state = CONFIRM_WAIT;
action_to_take = selected_action;
activity_inprogess = false;
while (confirm_state == CONFIRM_WAIT)
if (prompt)
{
sceKernelUsleep(100000);
}
activity_inprogess = true;
selected_action = action_to_take;
sprintf(confirm_message, "%s - %s?", cid.c_str(), lang_strings[STR_REINSTALL_CONFIRM_MSG]);
confirm_state = CONFIRM_WAIT;
action_to_take = selected_action;
activity_inprogess = false;
while (confirm_state == CONFIRM_WAIT)
{
sceKernelUsleep(100000);
}
activity_inprogess = true;
selected_action = action_to_take;
if (confirm_state == CONFIRM_YES)
if (confirm_state == CONFIRM_YES)
{
ret = sceAppInstUtilAppUnInstall(cid.c_str());
if (ret != 0)
goto err;
goto retry;
}
}
else
{
ret = sceAppInstUtilAppUnInstall(cid.c_str());
if (ret != 0)
@@ -244,19 +251,22 @@ namespace INSTALLER
goto err;
}
Util::Notify("%s queued", filename.c_str());
Util::Notify("%s queued", cid.c_str());
file_transfering = true;
bytes_to_download = 100;
bytes_transfered = 0;
while (bytes_transfered < 99)
if (prompt)
{
memset(&progress_info, 0, sizeof(progress_info));
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
return 0;
bytes_transfered = (uint32_t)(((float)progress_info.transferred / progress_info.length) * 100.f);
sceSystemServicePowerTick();
file_transfering = true;
bytes_to_download = 100;
bytes_transfered = 0;
while (bytes_transfered < 99)
{
memset(&progress_info, 0, sizeof(progress_info));
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
return 0;
bytes_transfered = (uint32_t)(((float)progress_info.transferred / progress_info.length) * 100.f);
sceSystemServicePowerTick();
}
}
return 1;
+1 -1
View File
@@ -121,7 +121,7 @@ namespace INSTALLER
bool canInstallRemotePkg(const std::string &url);
std::string getRemoteUrl(const std::string path, bool encodeUrl = false);
int InstallRemotePkg(const std::string &path, pkg_header *header);
int InstallRemotePkg(const std::string &path, pkg_header *header, bool prompt = false);
int InstallLocalPkg(const std::string &path);
int InstallLocalPkg(const std::string &path, pkg_header *header, bool remove_after_install = false);
bool ExtractLocalPkg(const std::string &path, const std::string sfo_path, const std::string icon_path);
+1 -1
View File
@@ -94,7 +94,7 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Not a valid Package", // STR_NOT_A_VALID_PACKAGE
"Waiting for Package to finish installing", // STR_WAIT_FOR_INSTALL_MSG
"Failed to install pkg file. Please delete the tmp pkg manually", // STR_FAIL_INSTALL_TMP_PKG_MSG
"Failed to obtain google download URL", // STR_FAIL_TO_OBTAIN_GG_DL_MSG
"Failed to obtain download URL", // STR_FAIL_TO_OBTAIN_GG_DL_MSG
"Auto delete temporary downloaded pkg file after install", // STR_AUTO_DELETE_TMP_PKG
"Protocol not supported", // STR_PROTOCOL_NOT_SUPPORTED
"Could not resolve hostname", // STR_COULD_NOT_RESOLVE_HOST
+3 -3
View File
@@ -11,7 +11,7 @@
#include <orbis/Pad.h>
#include <orbis/AudioOut.h>
#include <orbis/Net.h>
#include <dbglogger.h>
// #include <dbglogger.h>
#include "imgui.h"
#include "SDL2/SDL.h"
@@ -271,8 +271,8 @@ static void terminate()
int main()
{
dbglogger_init();
dbglogger_log("If you see this you've set up dbglogger correctly.");
// dbglogger_init();
// dbglogger_log("If you see this you've set up dbglogger correctly.");
int rc;
// No buffering
setvbuf(stdout, NULL, _IONBF, 0);
+109 -27
View File
@@ -8,6 +8,7 @@
#include "clients/smbclient.h"
#include "clients/ftpclient.h"
#include "clients/nfsclient.h"
#include "filehost/filehost.h"
#include "config.h"
#include "fs.h"
#include "windows.h"
@@ -925,33 +926,50 @@ namespace HttpServer
RemoteClient *tmp_client;
RemoteSettings *tmp_settings;
auto site_idx = std::stoi(req.matches[1])-1;
auto path = std::string("/") + std::string(req.matches[3]);
std::string path;
tmp_settings = &site_settings[sites[site_idx]];
if (site_idx != 98)
{
path = std::string("/") + std::string(req.matches[3]);
if (tmp_settings->type == CLIENT_TYPE_SFTP)
{
tmp_client = new SFTPClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_SMB)
{
tmp_client = new SmbClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_FTP)
{
tmp_client = new FtpClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_NFS)
{
tmp_client = new NfsClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
tmp_settings = &site_settings[sites[site_idx]];
if (tmp_settings->type == CLIENT_TYPE_SFTP)
{
tmp_client = new SFTPClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_SMB)
{
tmp_client = new SmbClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_FTP)
{
tmp_client = new FtpClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_NFS)
{
tmp_client = new NfsClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else
{
tmp_client = remoteclient;
}
}
else
{
tmp_client = remoteclient;
std::string hash = std::string(req.matches[3]);
std::string url = FileHost::GetCachedDownloadUrl(hash);
size_t scheme_pos = url.find("://");
size_t root_pos = url.find("/", scheme_pos + 3);
std::string host = url.substr(0, root_pos);
path = url.substr(root_pos);
tmp_client = new BaseClient();
tmp_client->Connect(host, "", "");
}
if (tmp_client == nullptr || !tmp_client->IsConnected())
@@ -987,11 +1005,12 @@ namespace HttpServer
int ret = tmp_client->GetRange(path, sink, length, offset);
return (ret == 1);
},
[tmp_client, path](bool success) {
[tmp_client, path, site_idx](bool success) {
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|| tmp_client->clientType() == CLIENT_TYPE_NFS))
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
{
tmp_client->Quit();
delete tmp_client;
@@ -1015,11 +1034,12 @@ namespace HttpServer
int ret = tmp_client->GetRange(path, sink, range_len, range.first);
return (ret == 1);
},
[tmp_client, path, range, range_len](bool success) {
[tmp_client, site_idx, path, range, range_len](bool success) {
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|| tmp_client->clientType() == CLIENT_TYPE_NFS))
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
{
tmp_client->Quit();
delete tmp_client;
@@ -1028,6 +1048,68 @@ namespace HttpServer
}
});
svr->Post("/__local__/install_url", [&](const Request & req, Response & res)
{
std::string url;
const char *url_param;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
{
url_param = json_object_get_string(json_object_object_get(jobj, "url"));
if (url_param == nullptr)
{
bad_request(res, "Required newPath parameter missing");
return;
}
}
else
{
bad_request(res, "Invalid payload");
return;
}
url = std::string(url_param);
FileHost *filehost = FileHost::getFileHost(url);
if (!filehost->IsValidUrl())
{
failed(res, 200, "InValid URL");
return;
}
std::string hash = filehost->Hash();
std::string download_url = filehost->GetDownloadUrl();
if (download_url.empty())
{
failed(res, 200, "Couldn't extract download url");
return;
}
FileHost::AddCacheDownloadUrl(hash, download_url);
delete(filehost);
size_t scheme_pos = download_url.find("://");
size_t root_pos = download_url.find("/", scheme_pos + 3);
std::string host = download_url.substr(0, root_pos);
std::string path = download_url.substr(root_pos);
pkg_header header;
BaseClient *baseclient = new BaseClient();
baseclient->Connect(host, "", "");
baseclient->Head(path, &header, sizeof(pkg_header));
delete(baseclient);
std::string remote_install_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/Site%2099/" + hash;
int rc = INSTALLER::InstallRemotePkg(remote_install_url, &header);
if (rc == 0)
{
failed(res, 200, "Failed to install from URL");
return;
}
success(res);
});
svr->Get("/stop", [&](const Request & /*req*/, Response & /*res*/)
{
svr->stop();
@@ -1047,7 +1129,7 @@ namespace HttpServer
dbglogger_log("%s", log(req, res).c_str());
});
*/
svr->set_payload_max_length(1024 * 1024 * 12);
svr->set_tcp_nodelay(true);
svr->set_mount_point("/", "/");