Qv2ray/src/components/pac/QvGFWPACConverter.cpp
2020-02-28 22:49:53 +08:00

118 lines
4.5 KiB
C++

/* ORIGINAL LICENSE: Do What The F*ck You Want To Public License
* AUTHOR: LBYPatrick
*
* MODIFIED BY Leroy.H.Y @lhy0403 re-licenced under GPLv3
*/
#include "common/QvHelpers.hpp"
namespace Qv2ray::components::pac
{
// Private function
string getRawDomain(string originLine)
{
size_t startPosition = 0;
size_t endPosition = originLine.size();
string returnBuffer;
bool skipRule1 = originLine.find("[") != string::npos; // [Auto xxxx...
bool skipRule2 = originLine.find("!") != string::npos; // Comments
bool skipRule3 = originLine.find("@") != string::npos; // Non-proxy Lines
bool skipRule4 = originLine.find("*") != string::npos;
bool passRule1 = originLine.find("|") != string::npos; // Proxy Lines
bool passRule2 = originLine.find(".") != string::npos; // Link-Contained Lines
if (originLine[endPosition] == '\n') { endPosition -= 1; }
if (originLine.find("http://") != string::npos) { startPosition += 8; }
else if (originLine.find("https://") != string::npos)
{
startPosition += 9;
}
// Skip unrelated lines
if (skipRule1 || skipRule2 || skipRule3 || skipRule4) { return ""; }
else if (passRule2)
{
if (passRule1) { startPosition += originLine.find_last_of("|") + 1; }
if (originLine[startPosition] == '\n') startPosition += 1;
for (size_t i = startPosition; i < endPosition; ++i) { returnBuffer += originLine[i]; }
}
return returnBuffer;
}
QString ConvertGFWToPAC(const QString &rawContent, const QString &customProxyString)
{
auto rawFileContent = Base64Decode(rawContent).toStdString();
string readBuffer = ""; // cleanup
string writeBuffer;
string domainListCache = "";
for (size_t i = 0; i < rawFileContent.size(); ++i)
{
readBuffer += rawFileContent[i];
if (rawFileContent[i + 1] == '\n')
{
writeBuffer = getRawDomain(readBuffer);
if (writeBuffer != "") { domainListCache += writeBuffer + "\n"; }
readBuffer = "";
i += 1;
}
}
size_t rotatorTwo = 0;
string readDomainBuffer = "";
bool isFirstLine = true;
string outputContent = "";
// Header
outputContent += "var domains = {\n";
// Read and process output content line by line
while (rotatorTwo < domainListCache.size())
{
while (true)
{
// Get Domain
readDomainBuffer += domainListCache[rotatorTwo];
if (domainListCache[rotatorTwo + 1] == '\n')
{
rotatorTwo += 2;
break;
}
rotatorTwo++;
}
// Format
if (!isFirstLine) outputContent += ",\n";
else
isFirstLine = false;
outputContent += "\t\"";
outputContent += readDomainBuffer;
outputContent += "\" : 1";
readDomainBuffer = "";
}
// End Message
outputContent += NEWLINE "};" NEWLINE "" NEWLINE " var proxy = \"" + customProxyString.toStdString() + ";\";" +
NEWLINE " var direct = 'DIRECT;';" NEWLINE " function FindProxyForURL(url, host) {" NEWLINE
" var suffix;" NEWLINE " var pos = host.lastIndexOf('.');" NEWLINE
" pos = host.lastIndexOf('.', pos - 1);" NEWLINE " //" NEWLINE " while (1) {" NEWLINE
" if (domains[host] != undefined) {" NEWLINE " return proxy;" NEWLINE
" }" NEWLINE " else if (pos <= 0) {" NEWLINE
" return domains['.' + host] != undefined ? proxy : direct;" NEWLINE " }" NEWLINE
" suffix = host.substring(pos);" NEWLINE " if (domains[suffix] != undefined) {" NEWLINE
" return proxy;" NEWLINE " }" NEWLINE
" pos = host.lastIndexOf('.', pos - 1);" NEWLINE " }" NEWLINE " }";
//
return QString::fromStdString(outputContent);
}
} // namespace Qv2ray::components::pac