using System; using System.Configuration; using System.Diagnostics; using System.Net; using System.Net.Http; using System.Security.Cryptography; using System.Web; namespace HNT { public class MainModule : IHttpModule { private static readonly string Pass = ConfigurationManager.AppSettings[nameof(Pass)]; public void Init(HttpApplication context) { context.BeginRequest += Context_BeginRequest; } private void Context_BeginRequest(object sender, EventArgs e) { var ctx = HttpContext.Current; var request = ctx.Request; if (Pass != request.QueryString["pass"]) { ctx.Error(403, "Access Denied"); return; } var app = ctx.ApplicationInstance; var response = ctx.Response; try { var bs = request.QueryString["bs"]; if (int.TryParse(bs, out var blockSize)) { var buffer = new byte[blockSize]; RandomNumberGenerator.Create().GetBytes(buffer, 0, blockSize); response.Headers["content-type"] = "application/octet-stream"; response.BinaryWrite(buffer); app.CompleteRequest(); return; } var url = request.QueryString["url"]; if (false == string.IsNullOrWhiteSpace(url)) { response.Write($"UserHostAddress: {request.UserHostAddress}{Environment.NewLine}"); response.Write($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} Start download{Environment.NewLine}"); using (var client = new HttpClient()) { var sw = new Stopwatch(); sw.Start(); var httpResponseMessage = client.GetAsync(url).Result; var statusCode = httpResponseMessage.StatusCode; response.Write($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} Response: {statusCode},Length: {httpResponseMessage.Content.Headers.ContentLength:N0} Bytes, Elapsed: {sw.ElapsedMilliseconds}Milliseconds{Environment.NewLine}"); if (HttpStatusCode.OK == statusCode) { httpResponseMessage.Content.ReadAsByteArrayAsync().Wait(); response.Write($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} End download, Elapsed: {sw.ElapsedMilliseconds:N0} Milliseconds, Speed: {httpResponseMessage.Content.Headers.ContentLength / (sw.ElapsedMilliseconds / 1000.0):N} Bytes per second{Environment.NewLine}"); } } app.CompleteRequest(); } else { ctx.Error(200, "It Works!"); } } catch (Exception exception) { ctx.Error(500, exception.ToString()); } catch { ctx.Error(500, "Uncatchable exception"); } } public void Dispose() { } } internal static class Ex { public static void Error(this HttpContext context, int code, string content) { var response = context.Response; response.StatusCode = code; response.ContentType = "text/plain"; response.TrySkipIisCustomErrors = true; response.Write(content); context.ApplicationInstance.CompleteRequest(); } } }