forked from bonesoul/uhttpsharp
-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathSessionHandler.cs
More file actions
81 lines (67 loc) · 2.32 KB
/
SessionHandler.cs
File metadata and controls
81 lines (67 loc) · 2.32 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
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace uhttpsharp.Handlers
{
public class SessionHandler<TSession> : IHttpRequestHandler
{
private readonly Func<TSession> _sessionFactory;
private readonly TimeSpan _expiration;
private static readonly Random RandomGenerator = new Random();
private class SessionHolder
{
private readonly TSession _session;
private DateTime _lastAccessTime = DateTime.Now;
public TSession Session
{
get
{
_lastAccessTime = DateTime.Now;
return _session;
}
}
public DateTime LastAccessTime
{
get
{
return _lastAccessTime;
}
}
public SessionHolder(TSession session)
{
_session = session;
}
}
private readonly ConcurrentDictionary<string, SessionHolder> _sessions = new ConcurrentDictionary<string, SessionHolder>();
public SessionHandler(Func<TSession> sessionFactory, TimeSpan expiration)
{
_sessionFactory = sessionFactory;
_expiration = expiration;
}
public Task Handle(IHttpContext context, Func<Task> next)
{
string sessId;
if (!context.Cookies.TryGetByName("SESSID", out sessId))
{
sessId = RandomGenerator.Next().ToString(CultureInfo.InvariantCulture);
context.Cookies.Upsert("SESSID", sessId);
}
var sessionHolder = _sessions.GetOrAdd(sessId, CreateSession);
if (DateTime.Now - sessionHolder.LastAccessTime > _expiration)
{
sessionHolder = CreateSession(sessId);
_sessions.AddOrUpdate(sessId, sessionHolder, (sessionId, oldSession) => sessionHolder);
}
context.State.Session = sessionHolder.Session;
return next();
}
private SessionHolder CreateSession(string sessionId)
{
return new SessionHolder(_sessionFactory());
}
}
}