Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARM architecture support. #99

Open
wants to merge 16 commits into
base: release
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<BranchVersionLabel Condition="'$(BranchVersionLabel)' == '' and '$(GITHUB_HEAD_REF)' != ''">$(GITHUB_HEAD_REF)</BranchVersionLabel>
<BranchVersionLabel Condition="'$(BranchVersionLabel)' == '' and '$(GITHUB_REF)' != ''">$(GITHUB_REF)</BranchVersionLabel>
<BranchVersionLabel Condition="'$(BranchVersionLabel)' != ''">$([System.Text.RegularExpressions.Regex]::Replace("$(BranchVersionLabel)", "^(.+/)?([^/]+)$", "ci.$2"))</BranchVersionLabel>
<BranchVersionLabel Condition="'$(BranchVersionLabel)' != ''">$([System.Text.RegularExpressions.Regex]::Replace($(BranchVersionLabel), '[^0-9A-Za-z\-\.]+', '-'))</BranchVersionLabel>
ProKn1fe marked this conversation as resolved.
Show resolved Hide resolved
<BranchVersionLabel Condition="'$(BranchVersionLabel)' != ''">$([System.Text.RegularExpressions.Regex]::Replace($(BranchVersionLabel), '\.0+(\d+(\.|$))', '.$1'))</BranchVersionLabel>
<BranchVersionLabel Condition="'$(BranchVersionLabel)' == ''">local</BranchVersionLabel>

<BuildVersionLabel Condition="'$(BuildVersionLabel)' == '' and '$(GITHUB_RUN_NUMBER)' != ''">.$(GITHUB_RUN_NUMBER)</BuildVersionLabel>
Expand Down
83 changes: 81 additions & 2 deletions src/TorSharp/ToolUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

using Knapcode.TorSharp.Tools;

namespace Knapcode.TorSharp
Expand Down Expand Up @@ -39,6 +41,8 @@ public static ToolSettings GetPrivoxyToolSettings(TorSharpSettings settings)

return e;
},
TryFindInSystem = settings.TorSettings.AutomaticallyFindInSystem,
TryFindExecutableName = "privoxy.exe"
};
}
else if (settings.OSPlatform == TorSharpOSPlatform.Linux)
Expand Down Expand Up @@ -92,6 +96,8 @@ public static ToolSettings GetPrivoxyToolSettings(TorSharpSettings settings)
return null;
}
},
TryFindInSystem = settings.TorSettings.AutomaticallyFindInSystem,
TryFindExecutableName = "privoxy"
};
}
else
Expand All @@ -118,11 +124,15 @@ public static ToolSettings GetTorToolSettings(TorSharpSettings settings)
GetEnvironmentVariables = t => new Dictionary<string, string>(),
ZippedToolFormat = ZippedToolFormat.TarGz,
GetEntryPath = e => e,
TryFindInSystem = settings.TorSettings.AutomaticallyFindInSystem,
TryFindExecutableName = "tor.exe"
};
}
else if (settings.OSPlatform == TorSharpOSPlatform.Linux)
{
var prefix = default(string);
var archiveFormat = ZippedToolFormat.TarGz;
var getEntryPath = (string a) => a;
if (settings.Architecture == TorSharpArchitecture.X86)
{
prefix = "tor-linux32-";
Expand All @@ -131,6 +141,41 @@ public static ToolSettings GetTorToolSettings(TorSharpSettings settings)
{
prefix = "tor-linux64-";
}
else if (settings.Architecture.Contains("Arm"))
{
if (settings.Architecture == TorSharpArchitecture.Arm32)
{
prefix = "tor-browser-linux-armhf-";
}
else if (settings.Architecture == TorSharpArchitecture.Arm64)
{
prefix = "tor-browser-linux-arm64-";
}
archiveFormat = ZippedToolFormat.TarXz;
getEntryPath = e =>
{
const string entryPrefix = "tor-browser/Browser/TorBrowser/";
if (e.StartsWith(entryPrefix + "Data/Tor/"))
{
return e.Substring(entryPrefix.Length).ToLower();
}
else if (e.StartsWith(entryPrefix + "Tor/"))
{
if (e.StartsWith(entryPrefix + "Tor/PluggableTransports/"))
{
return null;
}
else
{
return e.Substring(entryPrefix.Length).ToLower();
}
}
else
{
return null;
}
};
}
else
{
settings.RejectRuntime("determine Linux Tor prefix");
Expand Down Expand Up @@ -169,8 +214,10 @@ public static ToolSettings GetTorToolSettings(TorSharpSettings settings)

return output;
},
ZippedToolFormat = ZippedToolFormat.TarGz,
GetEntryPath = e => e,
ZippedToolFormat = archiveFormat,
GetEntryPath = getEntryPath,
TryFindInSystem = settings.TorSettings.AutomaticallyFindInSystem,
TryFindExecutableName = "tor"
};
}
else
Expand All @@ -192,6 +239,9 @@ public static Tool GetLatestToolOrNull(
TorSharpSettings settings,
ToolSettings toolSettings)
{
if (toolSettings.TryFindInSystem && TryFindToolInSystem(settings, toolSettings, out var tool))
return tool;

if (!Directory.Exists(settings.ZippedToolsDirectory))
{
return null;
Expand Down Expand Up @@ -232,5 +282,34 @@ public static Tool GetLatestToolOrNull(
.OrderByDescending(t => t.Version)
.FirstOrDefault();
}

public static bool TryFindToolInSystem(TorSharpSettings settings, ToolSettings toolSettings, out Tool tool)
{
tool = null;

var toolPath = WhichUtility.Which(settings, toolSettings.TryFindExecutableName);
var toolVariants = toolPath.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
var binToolVariant = toolVariants.FirstOrDefault();
if (!string.IsNullOrEmpty(binToolVariant))
{
var directoryPath = Path.Combine(settings.ExtractedToolsDirectory, "local");
var workingDirectory = Path.Combine(directoryPath, toolSettings.WorkingDirectory);
var configurationPath = Path.Combine(directoryPath, toolSettings.ConfigurationPath);
DirectoryUtility.CreateDirectoryIfNotExists(directoryPath, workingDirectory,
Path.GetDirectoryName(configurationPath));
tool = new Tool()
{
Settings = toolSettings,
ZipPath = null,
DirectoryPath = directoryPath,
Version = null,
ExecutablePath = binToolVariant,
WorkingDirectory = workingDirectory,
ConfigurationPath = configurationPath,
AutomaticallyDetected = true
};
}
return true;
}
}
}
23 changes: 9 additions & 14 deletions src/TorSharp/Tools/ArchiveUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Knapcode.TorSharp.Tools
{
internal class ArchiveUtility
internal static class ArchiveUtility
{
public static async Task TestAsync(ZippedToolFormat format, string path)
{
Expand Down Expand Up @@ -61,19 +61,14 @@ public static async Task ExtractAsync(

public static string GetFileExtension(ZippedToolFormat format)
{
switch (format)
return format switch
{
case ZippedToolFormat.Zip:
return ".zip";
case ZippedToolFormat.Deb:
return ".deb";
case ZippedToolFormat.TarXz:
return ".tar.xz";
case ZippedToolFormat.TarGz:
return ".tar.gz";
default:
throw new NotImplementedException($"The zipped tool format {format} does not have a known extension.");
}
ZippedToolFormat.Zip => ".zip",
ZippedToolFormat.Deb => ".deb",
ZippedToolFormat.TarXz => ".tar.xz",
ZippedToolFormat.TarGz => ".tar.gz",
_ => throw new NotImplementedException($"The zipped tool format {format} does not have a known extension."),
};
}

public static async Task TestZipAsync(string zipPath)
Expand Down Expand Up @@ -245,7 +240,7 @@ await ReadTarXzAsync(
}
}

private class ArFileHeader
private sealed class ArFileHeader
{
public ArFileHeader(string fileIdentifier, uint fileSize)
{
Expand Down
19 changes: 19 additions & 0 deletions src/TorSharp/Tools/DirectoryUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.IO;

namespace Knapcode.TorSharp.Tools
{
internal static class DirectoryUtility
{
public static void CreateDirectoryIfNotExists(params string[] path)
{
foreach (var p in path)
CreateDirectoryIfNotExists(p);
}

public static void CreateDirectoryIfNotExists(string path)
{
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directory.CreateDirectory already gracefully handles the case when the directory already exists. I think this CreateDirectoryIfNotExists method is not necessary.

}
}
}
12 changes: 12 additions & 0 deletions src/TorSharp/Tools/EnumHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace Knapcode.TorSharp.Tools
{
internal static class EnumHelper
{
public static bool Contains<T>(this T value, string enumValue) where T : Enum
{
return value.ToString().Contains(enumValue);
}
}
}
31 changes: 27 additions & 4 deletions src/TorSharp/Tools/FetcherHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.ServiceModel.Syndication;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -26,8 +27,7 @@ public static async Task<string> GetStringAsync(
public static async Task<DownloadableFile> GetLatestDownloadableFileAsync(
HttpClient httpClient,
Uri baseUrl,
string fileNamePattern,
ZippedToolFormat format,
FileNamePatternAndFormat patternAndFormat,
CancellationToken token)
{
var versionsContent = await httpClient.GetStringAsync(baseUrl, token).ConfigureAwait(false);
Expand All @@ -44,7 +44,7 @@ public static async Task<DownloadableFile> GetLatestDownloadableFileAsync(

foreach (var link in GetLinks(listContent))
{
var match = Regex.Match(link, fileNamePattern, RegexOptions.IgnoreCase);
var match = Regex.Match(link, patternAndFormat.Pattern, RegexOptions.IgnoreCase);
if (!match.Success)
{
continue;
Expand All @@ -61,7 +61,7 @@ public static async Task<DownloadableFile> GetLatestDownloadableFileAsync(
return new DownloadableFile(
parsedVersion,
downloadUrl,
format);
patternAndFormat.Format);
}
}

Expand Down Expand Up @@ -95,5 +95,28 @@ private static IEnumerable<string> GetLinks(string content)
.OfType<Match>()
.Select(x => x.Groups["Link"].Value);
}

internal static DownloadableFile GetDownloadableFile(
FileNamePatternAndFormat fileNamePatternAndFormat,
SyndicationItem item)
{
var match = Regex.Match(
item.Title.Text,
fileNamePatternAndFormat.Pattern,
RegexOptions.IgnoreCase);

if (!match.Success)
{
return null;
}

if (!Version.TryParse(match.Groups["Version"].Value, out var parsedVersion))
{
return null;
}

var downloadUrl = item.Links[0].Uri;
return new DownloadableFile(parsedVersion, downloadUrl, fileNamePatternAndFormat.Format);
}
}
}
14 changes: 5 additions & 9 deletions src/TorSharp/Tools/LineByLineConfigurer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task ApplySettings(Tool tool, TorSharpSettings settings)
try
{
// write first to a temporary file
temporaryPath = Path.GetTempFileName();
temporaryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting: https://rules.sonarsource.com/csharp/RSPEC-5445.
I never heard of this before. Thanks!

TextReader reader;

// read the existing configuration, if there is some
Expand Down Expand Up @@ -57,15 +57,12 @@ public async Task ApplySettings(Tool tool, TorSharpSettings settings)
// write the remaining lines
foreach (var pair in dictionary.OrderBy(p => p.Key))
{
if (pair.Value != null && pair.Value.Any())
if (pair.Value?.Any() == true)
{
foreach (var value in pair.Value)
foreach (var value in pair.Value.Where(a => a != null))
{
if (value != null)
{
string newLine = _format.CreateLine(new KeyValuePair<string, string>(pair.Key, value));
await writer.WriteLineAsync(newLine).ConfigureAwait(false);
}
string newLine = _format.CreateLine(new KeyValuePair<string, string>(pair.Key, value));
await writer.WriteLineAsync(newLine).ConfigureAwait(false);
}
}
}
Expand Down Expand Up @@ -109,7 +106,6 @@ public async Task ApplySettings(Tool tool, TorSharpSettings settings)
}
}
}

}
}
}
34 changes: 4 additions & 30 deletions src/TorSharp/Tools/Privoxy/PrivoxyFetcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private async Task<List<DownloadableFile>> GetResultsAsync(bool takeFirst)
await Task.WhenAll(faults).ConfigureAwait(false);
}

throw new TorSharpException($"No version of Privoxy could be found.");
throw new TorSharpException("No version of Privoxy could be found.");
}

return results;
Expand Down Expand Up @@ -121,8 +121,7 @@ private async Task<DownloadableFile> GetLatestOrNullFromFileListingAsync(
var downloadableFile = await FetcherHelpers.GetLatestDownloadableFileAsync(
_httpClient,
osBaseUrl,
fileNamePatternAndFormat.Pattern,
fileNamePatternAndFormat.Format,
fileNamePatternAndFormat,
token).ConfigureAwait(false);

if (downloadableFile == null)
Expand Down Expand Up @@ -161,9 +160,8 @@ private async Task<DownloadableFile> GetLatestOrNullFromRssAsync(

var downloadableFile = syndicationFeed
.Items
.Where(i => i.Links.Any())
.Where(i => TitleStartWithDirectory(directory, i))
.Select(i => GetDownloadableFile(fileNamePatternAndFormat.Pattern, fileNamePatternAndFormat.Format, i))
.Where(i => i.Links.Any() && TitleStartWithDirectory(directory, i))
.Select(i => FetcherHelpers.GetDownloadableFile(fileNamePatternAndFormat, i))
.Where(i => i != null)
.OrderByDescending(x => x.Version)
.FirstOrDefault();
Expand All @@ -186,30 +184,6 @@ private static bool TitleStartWithDirectory(string directory, SyndicationItem it
RegexOptions.IgnoreCase);
}

private DownloadableFile GetDownloadableFile(
string fileNamePattern,
ZippedToolFormat format,
SyndicationItem item)
{
var match = Regex.Match(
item.Title.Text,
fileNamePattern,
RegexOptions.IgnoreCase);

if (!match.Success)
{
return null;
}

if (!Version.TryParse(match.Groups["Version"].Value, out var parsedVersion))
{
return null;
}

var downloadUrl = item.Links.First().Uri;
return new DownloadableFile(parsedVersion, downloadUrl, format);
}

private string GetFileListingDirectory(Uri baseUrl)
{
string directory = null;
Expand Down
Loading