-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathStartup.cs
More file actions
130 lines (116 loc) · 5.95 KB
/
Startup.cs
File metadata and controls
130 lines (116 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright(C) 2017 Shane Macaulay smacaulay@gmail.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or(at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.If not, see<http://www.gnu.org/licenses/>.
using System;
using System.Globalization;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Text;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using ProtoBuf;
using System.Collections.Concurrent;
using Microsoft.Extensions.Configuration.Json;
using System.Threading;
namespace HashServer
{
public class Startup
{
private const int _chunkSize = 4096;
private const int _defaultNumChunks = 16;
private static byte[] _chunk = Encoding.UTF8.GetBytes(new string('a', _chunkSize));
static string GoldenState = "GoldState.buf";
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
var logger = loggerFactory.CreateLogger("Default");
Program.log = logger;
logger.Log<string>(LogLevel.Information, new EventId(0, "Configure"), "Booting up", null, (state, ex) => { return $"{state}"; });
List<string> gRoots = new List<string>();
var gi = new GoldImages(logger);
// figuer out a default locatedb if one does not exist
var locateDb = File.Exists(Program.Settings.Host.FileLocateNfo) ? Program.Settings.Host.FileLocateNfo : GoldenState;
if (File.Exists(locateDb))
{
using (var SerData = File.OpenRead(locateDb))
{
logger.LogInformation($"Serialed data found {locateDb} for golden image locate database, will skip filesystem scan");
GoldImages.DiskFiles = Serializer.Deserialize<ConcurrentDictionary<string, ConcurrentBag<Tuple<uint, uint, string>>>>(SerData);
GoldImages.AtLeastOneGoldImageSetIndexed = true;
logger.LogInformation($"{GoldImages.DiskFiles.Count} files have been located from the configured inputs, to regenerate, delete the {locateDb} and restart.");
if (GoldImages.DiskFiles.Count < 1024)
logger.LogWarning($"Only {GoldImages.DiskFiles.Count} files found, this seems low, try adding more folders to the config file. Or delete the {locateDb} file so it can be re-generated.");
}
} else if(Program.Settings.GoldSourceFiles != null && Program.Settings.GoldSourceFiles.Images != null && Program.Settings.GoldSourceFiles.Images.Length > 0)
{
foreach(var imageSet in Program.Settings.GoldSourceFiles.Images)
{
logger.LogInformation($"Compiling gold locate db from {imageSet.ROOT} {imageSet.OS}, server will continue after filesystem scan.");
if(!Directory.Exists(imageSet.ROOT))
{
logger.LogCritical($"Unable to handle configured gold image path {imageSet.ROOT} skipping.");
continue;
}
gi.Init(new string[] { imageSet.ROOT });
}
}
else
// by default we'll use the local C:\ as the golden image, it's not very optimal since
// many files will be inaccessable due to permissions and in-use
{
logger.LogInformation("No specified path found to use as 'golden' images. Using C:");
gi.Init(new string[] { "c:\\" });
}
if(!GoldImages.AtLeastOneGoldImageSetIndexed)
{
logger.LogCritical($"Fatal state!!! No golden images were able to be loaded so this server has no work to do, exiting in 5 seconds.");
Thread.Sleep(5000);
Environment.Exit(-1);
}
try
{
app.Run(async (context) =>
{
// pull in data from POST
var connectionFeature = context.Connection;
logger.Log<string>(LogLevel.Information, new EventId(1, "IP"), $"Peer: {connectionFeature.RemoteIpAddress?.ToString()}:{connectionFeature.RemotePort}"
+ $"{Environment.NewLine}"
+ $"{context.Request.Path}{Environment.NewLine}", null, (state, ex) => $"{state}");
var request = context.Request;
var response = context.Response;
await PageHash.Run(context, "x", logger).ConfigureAwait(false);
return;
});
}
finally
{
var saveFile = Program.Settings.Host.FileLocateNfo;
if (string.IsNullOrWhiteSpace(saveFile))
saveFile = GoldenState;
Program.Settings.Host.FileLocateNfo = GoldenState;
logger.LogInformation($"Saving locate database to {saveFile}");
using (var serOut = File.OpenWrite(saveFile))
Serializer.Serialize<ConcurrentDictionary<string, ConcurrentBag<Tuple<uint, uint, string>>>>(serOut, GoldImages.DiskFiles);
}
}
}
}