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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Connect;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
namespace MediaBrowser.Server.Implementations.Connect
{
public class ConnectEntryPoint : IServerEntryPoint
{
private Timer _timer;
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _appPaths;
private readonly ILogger _logger;
private readonly IConnectManager _connectManager;
private readonly INetworkManager _networkManager;
private readonly IApplicationHost _appHost;
public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager, IApplicationHost appHost)
{
_httpClient = httpClient;
_appPaths = appPaths;
_logger = logger;
_networkManager = networkManager;
_connectManager = connectManager;
_appHost = appHost;
}
public void Run()
{
LoadCachedAddress();
_timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3));
}
private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.emby.media/service/ip" };
private async void TimerCallback(object state)
{
foreach (var ipLookupUrl in _ipLookups)
{
try
{
using (var stream = await _httpClient.Get(new HttpRequestOptions
{
Url = ipLookupUrl,
UserAgent = "Emby Server/" + _appHost.ApplicationVersion
}).ConfigureAwait(false))
{
using (var reader = new StreamReader(stream))
{
var address = await reader.ReadToEndAsync().ConfigureAwait(false);
if (IsValid(address))
{
((ConnectManager)_connectManager).OnWanAddressResolved(address);
CacheAddress(address);
return;
}
}
}
}
catch (HttpException)
{
}
catch (Exception ex)
{
_logger.ErrorException("Error getting connection info", ex);
}
}
}
private string CacheFilePath
{
get { return Path.Combine(_appPaths.DataPath, "wan.txt"); }
}
private void CacheAddress(string address)
{
var path = CacheFilePath;
try
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
File.WriteAllText(path, address, Encoding.UTF8);
}
catch (Exception ex)
{
_logger.ErrorException("Error saving data", ex);
}
}
private void LoadCachedAddress()
{
var path = CacheFilePath;
try
{
var endpoint = File.ReadAllText(path, Encoding.UTF8);
if (IsValid(endpoint))
{
((ConnectManager)_connectManager).OnWanAddressResolved(endpoint);
}
}
catch (IOException)
{
// File isn't there. no biggie
}
catch (Exception ex)
{
_logger.ErrorException("Error loading data", ex);
}
}
private bool IsValid(string address)
{
IPAddress ipAddress;
var valid = IPAddress.TryParse(address, out ipAddress);
if (!valid)
{
_logger.Error("{0} is not a valid ip address", address);
}
return valid;
}
public void Dispose()
{
if (_timer != null)
{
_timer.Dispose();
_timer = null;
}
}
}
}
|