Skip to content

Commit 6136b26

Browse files
authored
Merge pull request #141 from atauenis/dev
Put the v0.17.2 release to master branch
2 parents c04ed83 + aed5d8d commit 6136b26

File tree

13 files changed

+227
-152
lines changed

13 files changed

+227
-152
lines changed

CertificateUtil.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ public static X509Certificate2 MakeChainSignedCert(string certSubject, X509Certi
215215
*/
216216

217217
// Save the certificate and return it.
218-
FakeCertificates.Add(certSubject, certificateWithKey);
218+
if (!FakeCertificates.ContainsKey(certSubject))
219+
FakeCertificates.Add(certSubject, certificateWithKey);
219220
return certificateWithKey;
220221
}
221222
}

Converter.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ private Stream RunConverter(LogWriter Log, string ConvCommandLine, Stream InputS
141141
{
142142
if (InputStream != null) new Task(() =>
143143
{
144-
while (InputStream.CanRead && !ConvProc.HasExited) { }; if (!ConvProc.HasExited) ConvProc.Kill(); Console.WriteLine();
144+
while (InputStream.CanRead && !ConvProc.HasExited)
145+
{
146+
Thread.Sleep(5000);
147+
if (InputStream.CanRead && !ConvProc.HasExited) Log.WriteLine(" Converter is still running.");
148+
}
149+
if (!ConvProc.HasExited) ConvProc.Kill(); Console.WriteLine();
145150
}).Start();
146151

147152
new Task(() =>
@@ -162,6 +167,9 @@ private Stream RunConverter(LogWriter Log, string ConvCommandLine, Stream InputS
162167
#endif
163168
if (File.Exists(SourceTmpFile)) File.Delete(SourceTmpFile);
164169
if (File.Exists(DestinationTmpFile)) File.Delete(DestinationTmpFile);
170+
#if DEBUG
171+
Log.WriteLine(" Remove temporary files if any.");
172+
#endif
165173
}).Start();
166174
return ConvProc.StandardOutput.BaseStream;
167175
}
@@ -181,8 +189,18 @@ private Stream RunConverter(LogWriter Log, string ConvCommandLine, Stream InputS
181189
#endif
182190
ConvProc.WaitForExit();
183191
InputStream.Close();
184-
if (File.Exists(SourceTmpFile)) File.Delete(SourceTmpFile);
185-
if (File.Exists(DestinationTmpFile)) File.Delete(DestinationTmpFile);
192+
193+
new Task(() =>
194+
{
195+
//wait 1 minute for let client time to download the file
196+
Thread.Sleep(60000);
197+
#if DEBUG
198+
Log.WriteLine(" Remove temporary files.");
199+
#endif
200+
if (File.Exists(SourceTmpFile)) File.Delete(SourceTmpFile);
201+
if (File.Exists(DestinationTmpFile)) File.Delete(DestinationTmpFile);
202+
}).Start();
203+
186204
return File.OpenRead(DestinationTmpFile);
187205
}
188206
}

HttpRequestProcessor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ private void ProcessClientRequest(object Backend, LogWriter Logger, string SslLo
193193
catch { Request.Url = new Uri(Request.RawUrl); }
194194
break;
195195
case RequestKind.AlternateProxy:
196-
Request.Url = new Uri(Request.RawUrl[1..]);
196+
string url = Request.RawUrl[1..];
197+
if (url.Contains(":/") && !url.Contains("://")) url = url.Replace(":/", "://");
198+
Request.Url = new Uri(url);
197199
break;
198200
case RequestKind.StandardSslProxy:
199201
Request.Url = null;

HttpTransit.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,15 +232,18 @@ public void ProcessTransit()
232232

233233
if (ClientRequest.Kind == HttpUtil.RequestKind.AlternateProxy)
234234
{
235-
// "Local proxy mode"
235+
// "Alternate proxy access mode"
236+
// ex. "Local proxy mode"
236237
string FixedUrl = ClientRequest.RawUrl[1..];
238+
if (FixedUrl.Contains(":/") && !FixedUrl.Contains("://")) FixedUrl = FixedUrl.Replace(":/", "://");
237239
RequestURL = new Uri(FixedUrl);
238240
Log.WriteLine(" Alternate: {0}", RequestURL);
239241
}
240242

241243
if (ClientRequest.Kind == HttpUtil.RequestKind.DirtyAlternateProxy)
242244
{
243-
// "Dirty local proxy mode", try to use last used host: http://localhost/favicon.ico = http://example.com/favicon.ico
245+
// "Dirty alternate proxy access mode", try to use last used host: http://localhost/favicon.ico = http://example.com/favicon.ico
246+
// ex. "Dirty local proxy mode"
244247
string FixedUrl = "http://" + new Uri(LastURL).Host + RequestURL.LocalPath;
245248
RequestURL = new Uri(FixedUrl);
246249
if (RequestURL.Host == "999.999.999.999") { SendError(404, "The proxy server cannot guess domain name."); return; }
@@ -1186,6 +1189,11 @@ private void SendInternalPage(string InternalPageId, string Arguments)
11861189
}
11871190
return;
11881191
default:
1192+
if (InternalPageId.ToLowerInvariant() == "/rovp.htm" && !Program.ToBoolean(ConfigFile.WebVideoOptions["Enable"] ?? "yes"))
1193+
{
1194+
SendRedirect("/norovp.htm", "ROVP is disabled on this server.");
1195+
return;
1196+
}
11891197
if (CheckInternalContentModification(InternalPageId, ClientRequest.Headers["If-Modified-Since"]))
11901198
{
11911199
// send 304 Not Modified code
@@ -2283,7 +2291,18 @@ private void SendStream(Stream Potok, string ContentType, bool Close = true)
22832291
if (ex is FileNotFoundException) ErrNo = 404;
22842292
SendError(ErrNo, "Cannot retreive stream.<br>" + ex.ToString().Replace("\n", "<br>"));
22852293
}
2286-
else { Log.WriteLine("<Stream not sent: {0}", ex.Message); }
2294+
else
2295+
{
2296+
try
2297+
{
2298+
Potok.Close();
2299+
Log.WriteLine("<Stream closed: {0}", ex.Message);
2300+
}
2301+
catch
2302+
{
2303+
Log.WriteLine("<Stream not sent: {0}", ex.Message);
2304+
}
2305+
}
22872306
}
22882307
Dump("End is stream of " + ContentType);
22892308
}

Program.cs

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public static class Program
3333
public static string Protocols = "HTTP 1.1";
3434
public static bool DaemonMode = false;
3535
static bool ShutdownInitiated = false;
36+
static bool RebuildCA = false;
3637

3738
const string CmdLineArgUnnamed = "--wo-short";
3839
static List<KeyValuePair<string, string>> CmdLineOptions = new List<KeyValuePair<string, string>>();
@@ -147,36 +148,54 @@ static void Main(string[] args)
147148
if (HaveCrtKey) HaveCrtKey = (new FileInfo(ConfigFile.SslCertificate).Length > MinPemLentgh) && (new FileInfo(ConfigFile.SslPrivateKey).Length > MinPemLentgh);
148149
if (HaveCrtKey)
149150
{ Log.WriteLine(false, false, "Using as SSL Certificate Authority: {0}, {1}.", ConfigFile.SslCertificate, ConfigFile.SslPrivateKey); }
150-
else
151+
else if (!RebuildCA)
151152
{
152-
Log.WriteLine(true, false, "Creating root SSL Certificate & Private Key for CA...");
153-
CertificateUtil.MakeSelfSignedCert(ConfigFile.SslCertificate, ConfigFile.SslPrivateKey, ConfigFile.SslRootSubject, ConfigFile.SslHashAlgorithm);
154-
Log.WriteLine(true, false, "CA Certificate: {0}; Key: {1}.", ConfigFile.SslCertificate, ConfigFile.SslPrivateKey);
153+
CreateRootCertificate();
155154
}
156-
RootCertificate = new X509Certificate2(X509Certificate2.CreateFromPemFile(ConfigFile.SslCertificate, ConfigFile.SslPrivateKey).Export(X509ContentType.Pkcs12));
157-
Protocols += ", HTTPS 1.1";
158-
if (!DefaultPACoverriden) DefaultPAC += DefaultPAChttps;
159-
160-
//check validness period
161-
if (RootCertificate.NotAfter < DateTime.Now || RootCertificate.NotBefore > DateTime.Now)
155+
if (RebuildCA)
162156
{
163-
Log.WriteLine(true, false, "Warning! CA Certificate is out of date: {0}-{1}, now {2}.", RootCertificate.NotBefore, RootCertificate.NotAfter, DateTime.Now);
157+
Console.WriteLine();
158+
Log.WriteLine(true, false, "CA Certificate will be new, so import it to browser(s) after build succeeds.");
159+
CreateRootCertificate();
160+
RootCertificate = new X509Certificate2(X509Certificate2.CreateFromPemFile(ConfigFile.SslCertificate, ConfigFile.SslPrivateKey).Export(X509ContentType.Pkcs12));
161+
Log.WriteLine(true, false, "The new certificate is called \"" + RootCertificate.GetNameInfo(X509NameType.SimpleName, false) + "\".");
162+
Log.WriteLine(true, false, "WebOne will now exit.");
163+
Environment.Exit(0);
164164
}
165-
166-
if (RootCertificate.NotAfter < DateTimeOffset.Now.AddDays(ConfigFile.SslCertVaildAfterNow) ||
167-
RootCertificate.NotBefore > DateTimeOffset.Now.AddDays(ConfigFile.SslCertVaildBeforeNow))
165+
try
168166
{
169-
Log.WriteLine(true, false, "Warning! CA Certificate is too fresh or expires too soon. Check configuration.");
167+
RootCertificate = new X509Certificate2(X509Certificate2.CreateFromPemFile(ConfigFile.SslCertificate, ConfigFile.SslPrivateKey).Export(X509ContentType.Pkcs12));
168+
Protocols += ", HTTPS 1.1";
169+
if (!DefaultPACoverriden) DefaultPAC += DefaultPAChttps;
170170

171+
//check validness period
172+
if (RootCertificate.NotAfter < DateTime.Now || RootCertificate.NotBefore > DateTime.Now)
173+
{
174+
Log.WriteLine(true, false, "Warning! CA Certificate is out of date: {0}-{1}, now {2}.", RootCertificate.NotBefore, RootCertificate.NotAfter, DateTime.Now);
175+
}
176+
177+
if (RootCertificate.NotAfter < DateTimeOffset.Now.AddDays(ConfigFile.SslCertVaildAfterNow) ||
178+
RootCertificate.NotBefore > DateTimeOffset.Now.AddDays(ConfigFile.SslCertVaildBeforeNow))
179+
{
180+
Log.WriteLine(true, false, "Warning! CA Certificate is too fresh or expires too soon. Check configuration.");
181+
}
182+
}
183+
catch (Exception CertLoadEx)
184+
{
185+
if (CertLoadEx.InnerException != null)
186+
{
187+
Log.WriteLine(true, false, "Unable to load CA Certificate: {0}.", CertLoadEx.InnerException.Message);
188+
}
189+
else
190+
{
191+
Log.WriteLine(true, false, "Unable to load CA Certificate: {0}.", CertLoadEx.Message);
192+
}
193+
ConfigFile.SslEnable = false;
171194
}
172195
}
173196
catch (Exception CertCreateEx)
174197
{
175198
Log.WriteLine(true, false, "Unable to create CA Certificate: {0}.", CertCreateEx.Message);
176-
/*
177-
Log.WriteLine(true, false, CertCreateEx.StackTrace.Replace("\n", " ; ")); //only for debug purposes at this moment
178-
Log.WriteLine(true, false, "End of CA build error information. HTTPS won't be available!");
179-
*/
180199
ConfigFile.SslEnable = false;
181200
}
182201

@@ -196,7 +215,7 @@ static void Main(string[] args)
196215
if (!DefaultPACoverriden) DefaultPAC += DefaultPACfooter;
197216
if (!DefaultPACoverriden) ConfigFile.PAC = DefaultPAC;
198217

199-
Log.WriteLine(false, false, "Configured to http://{1}:{2}/, {3}", ConfigFileName, ConfigFile.DefaultHostName, ConfigFile.Port, Protocols);
218+
Log.WriteLine(false, false, "Configured to http://{1}:{2}/, {3}", ConfigFileName, ConfigFile.DefaultHostName, ConfigFile.Port, Protocols);
200219

201220
//initialize server
202221
try
@@ -280,6 +299,16 @@ static void Main(string[] args)
280299
Shutdown();
281300
}
282301

302+
/// <summary>
303+
/// Create certificate and private key files for WebOne Certificate Authority
304+
/// </summary>
305+
private static void CreateRootCertificate()
306+
{
307+
Log.WriteLine(true, false, "Creating root SSL Certificate & Private Key for CA...");
308+
CertificateUtil.MakeSelfSignedCert(ConfigFile.SslCertificate, ConfigFile.SslPrivateKey, ConfigFile.SslRootSubject, ConfigFile.SslHashAlgorithm);
309+
Log.WriteLine(true, false, "CA Certificate: {0}; Key: {1}.", ConfigFile.SslCertificate, ConfigFile.SslPrivateKey);
310+
}
311+
283312
/// <summary>
284313
/// Shut down server and terminate process
285314
/// </summary>
@@ -382,6 +411,9 @@ private static void ProcessCommandLine(string[] args)
382411
case "--dump-requests":
383412
//all will be processed in ProcessCommandLineOptions()
384413
break;
414+
case "--rebuild-ca":
415+
RebuildCA = true;
416+
break;
385417
case "--daemon":
386418
DaemonMode = true;
387419
break;

WebOne.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<OutputType>Exe</OutputType>
66
<TargetFramework>net6.0</TargetFramework>
77
<Authors>Alexander Tauenis</Authors>
8-
<Version>0.17.1</Version>
8+
<Version>0.17.2</Version>
99
<VersionSuffix></VersionSuffix> <!--<VersionSuffix>-pre</VersionSuffix>-->
1010
<PackageVersion>$(Version)$(VersionSuffix)</PackageVersion>
1111
<Company>World</Company>
@@ -289,5 +289,7 @@ fi
289289
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
290290
<Link>__MACOSX/%(Filename)%(Extension)</Link>
291291
</None>
292+
<None Include="openssl_webone.cnf" CopyToPublishDirectory="Always">
293+
</None>
292294
</ItemGroup>
293295
</Project>

WebVideoPlayer.cs

Lines changed: 7 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -31,118 +31,20 @@ public WebVideoPlayer(NameValueCollection Parameters)
3131

3232
if (!Program.ToBoolean(ConfigFile.WebVideoOptions["Enable"] ?? "yes"))
3333
{
34-
Page.Content = "Sorry, proxy server administrator has disabled the online video download feature.";
34+
Page.Content = "It's disabled.";
35+
Page.HttpHeaders.Add("Refresh", "0;url=/norovp.htm");
3536
return;
3637
}
3738

3839
switch (Parameters["type"])
3940
{
4041
case "":
4142
case null:
42-
string Frameset =
43-
"<form action='/!player/' method='GET' target='player_frame' align='center'>" +
44-
" <table border='0' width='100%'>" +
45-
" <tr>" +
46-
" <td align='right'>Video</td>" +
47-
" <td align='center' colspan='4'><input type='text'" +
48-
" size='65' name='url' style='width: 100%'" +
49-
" value='" + SampleUrl + "'></td>" +
50-
" <td align='center' rowspan='3' colspan='2'><input" +
51-
" type='submit' value='Load video'" +
52-
" style='height: 70px;'></td>" +
53-
" </tr>" +
54-
" <tr>" +
55-
" <td align='right'>Format</td>" +
56-
" <td align='left'><select name='f' size='1'" +
57-
" title='Audio/video container'>" +
58-
" <option value='avi'>AVI</option>" +
59-
" <option value='mpeg1video'>MPEG 1</option>" +
60-
" <option value='mpeg2video'>MPEG 2</option>" +
61-
//" <option value='mp4'>MPEG 4</option>" + //muxer does not support non seekable output
62-
" <option selected value='mpegts'>MPEG TS</option>" +
63-
" <option value='asf'>Microsoft ASF</option>" +
64-
" <option value='asf_stream'>Microsoft ASF (stream)</option>" +
65-
//" <option value='mov'>QuickTime</option>" + //muxer does not support non seekable output
66-
" <option value='ogg'>Ogg</option>" + // Theora & Vorbis only
67-
" <option value='webm'>WebM</option>" + // Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.
68-
" <option value='swf'>Macromedia Flash</option>" + // SWF muxer only supports VP6, FLV1 and MJPEG
69-
//" <option value='rm'>RealMedia</option>" + //[rm @ 06cc61c0] Invalid codec tag
70-
//" <option value='3gp'>3GPP</option>" + //muxer does not support non seekable output
71-
" </select></td>" +
72-
" <td align='right'>Codecs</td>" +
73-
" <td align='left'><select name='vcodec' size='1'" +
74-
" title='Video codec'>" +
75-
" <option value='mpeg1video'>MPEG 1</option>" +
76-
" <option value='mpeg2video'>MPEG 2</option>" +
77-
" <option value='mpeg4'>MPEG 4</option>" +
78-
" <option value='wmv1'>WMV 7</option>" +
79-
" <option value='wmv2'>WMV 8</option>" +
80-
" <option value='h263'>H.263</option>" + // Valid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152.
81-
" <option selected value='h264'>H.264 AVC</option>" +
82-
" <option value='hevc'>H.265 HEVC</option>" +
83-
" <option value='theora'>Ogg Theora</option>" +
84-
" <option value='vp8'>VP8</option>" +
85-
" <option value='vp9'>VP9</option>" +
86-
" <option value='mjpeg'>MJPEG</option>" +
87-
" <option value='msvideo1'>MS Video 1</option>" + // width and height must be multiples of 4
88-
" <option value='copy'>(original)</option>" +
89-
" </select> <select name='vf' size='1'" +
90-
" title='Video resolution'>" +
91-
" <option value='scale=\"1080:-1\"'>1080p</option>" +
92-
" <option value='scale=\"720:-1\"'>720p</option>" +
93-
" <option selected value='scale=\"480:-1\"'>480p</option>" +
94-
" <option value='scale=\"360:-1\"'>360p</option>" +
95-
" <option value='scale=\"240:-1\"'>240p</option>" +
96-
" <option value='scale=\"144:-1\"'>144p</option>" +
97-
" <option value='scale=\"1024x768\"'>1024x768</option>" +
98-
" <option value='scale=\"800x600\"'>800x600</option>" +
99-
" <option value='scale=\"640x480\"'>640x480</option>" +
100-
" <option value='scale=\"320x200\"'>320x200</option>" +
101-
" <option value='scale=\"704x576\"'>704x576</option>" +
102-
" <option value='scale=\"352x288\"'>352x288</option>" +
103-
" <option value='scale=\"176x144\"'>176x144</option>" +
104-
" <option value='scale=\"128x96\"'>128x96</option>" +
105-
" <option value='scale=\"-1:-1\"'>(original)</option>" +
106-
" </select> &nbsp; <select name='acodec' size='1'" +
107-
" title='Audio codec'>" +
108-
" <option value='mp2'>MPEG 2</option>" +
109-
" <option selected value='mp3'>MPEG 3</option>" +
110-
" <option value='wmav1'>WMA 1</option>" +
111-
" <option value='wmav2'>WMA 2</option>" +
112-
" <option value='aac'>AAC</option>" +
113-
" <option value='pcm_dvd'>PCM</option>" +
114-
" <option value='vorbis -strict -2'>Ogg Vorbis</option>" + // Current FFmpeg Vorbis encoder only supports 2 channels.
115-
" <option value='opus -strict -2'>Opus</option>" +
116-
" <option value='ra_144'>RealAudio 1</option>" +
117-
" <option value='copy'>(original)</option>" +
118-
" </select> <select name='ac' size='1'" +
119-
" title='Audio channels'>" +
120-
" <option selected value='1'>Mono</option>" +
121-
" <option value='2'>Stereo</option>" +
122-
" </select></td>" +
123-
" <td>(<a href='http://github.com/atauenis/webone/wiki/YouTube-playback'>?</a>)</td>" +
124-
" </tr>" +
125-
" <tr>" +
126-
" <td align='right'></td>" +
127-
" <td align='center' colspan='4'>" +
128-
" <input type='radio'name='type' value='embed'>Embed, " +
129-
" <input type='radio'name='type' value='embedwm' checked>WMP, " +
130-
" <input type='radio'name='type' value='embedvlc'>VLC, " +
131-
" <input type='radio' name='type' value='objectwm'>WinMedia, " +
132-
" <input type='radio' name='type' value='objectns'>NetShow, " +
133-
" <input type='radio' name='type' value='dynimg'>DynImg, " +
134-
" <input type='radio' name='type' value='html5'>HTML5, " +
135-
" <input type='radio' name='type' value='link'>link, " +
136-
" <input type='radio' name='type' value='file'>file" +
137-
" </td>" +
138-
" </tr>" +
139-
" </table>" +
140-
"</form>" +
141-
"" +
142-
"<iframe name='player_frame' src='/!player/?type=" + PreferPage + "' " +
143-
"border='0' width='100%' height='100%' style='border-style: none;'>" +
144-
"Use the toolbar to watch a video.</iframe>"; ;
145-
Page.Content = Frameset;
43+
Page.Content = "<p align=\"center\">";
44+
Page.Content += "<a href=\"/rovp.htm\"><img src=\"/rovp.gif\" alt=\"Click here to open Retro Online Video Player.\"></a>";
45+
Page.Content += "<br><h1 align=\"center\">Retro Online Video Player</h1>";
46+
Page.Content += "</p>";
47+
Page.HttpHeaders.Add("Refresh", "5;url=/rovp.htm");
14648
break;
14749
case "intro":
14850
Page.Content = "<p align='center'><big>Use the toolbar above to watch a video.</big></p>";

Win32-full/yt-dlp.exe

119 KB
Binary file not shown.

0 commit comments

Comments
 (0)