diff --git a/QuickFIXn/HttpServer.cs b/QuickFIXn/HttpServer.cs
index 2de690779..d0c452e3a 100644
--- a/QuickFIXn/HttpServer.cs
+++ b/QuickFIXn/HttpServer.cs
@@ -153,7 +153,10 @@ private string EnableSessions(HttpListenerRequest request, StringBuilder pageBui
private string RefreshSession(HttpListenerRequest request, StringBuilder pageBuilder)
{
- SessionID sessionId = new SessionID(request.QueryString["beginstring"], request.QueryString["sendercompid"], request.QueryString["targetcompid"]);
+ SessionID sessionId = new SessionID(
+ request.QueryString["beginstring"] ?? "",
+ request.QueryString["sendercompid"] ?? "",
+ request.QueryString["targetcompid"] ?? "");
Session? sessionDetails = Session.LookupSession(sessionId);
if (sessionDetails == null) throw new Exception("Session not found");
bool confirm = false;
@@ -248,7 +251,10 @@ private string ResetSessions(HttpListenerRequest request, StringBuilder pageBuil
private string ResetSession(HttpListenerRequest request, StringBuilder pageBuilder)
{
- SessionID sessionId = new SessionID(request.QueryString["beginstring"], request.QueryString["sendercompid"], request.QueryString["targetcompid"]);
+ SessionID sessionId = new SessionID(
+ request.QueryString["beginstring"] ?? "",
+ request.QueryString["sendercompid"] ?? "",
+ request.QueryString["targetcompid"] ?? "");
Session? sessionDetails = Session.LookupSession(sessionId);
if (sessionDetails == null) throw new Exception("Session not found");
@@ -326,7 +332,10 @@ private string ProcessRoot(HttpListenerRequest request, StringBuilder pageBuilde
private string SessionDetails(HttpListenerRequest request, StringBuilder pageBuilder)
{
- SessionID sessionId = new SessionID(request.QueryString["beginstring"], request.QueryString["sendercompid"], request.QueryString["targetcompid"]);
+ SessionID sessionId = new SessionID(
+ request.QueryString["beginstring"] ?? "",
+ request.QueryString["sendercompid"] ?? "",
+ request.QueryString["targetcompid"] ?? "");
Session? sessionDetails = Session.LookupSession(sessionId);
if (sessionDetails == null) throw new Exception("Session not found");
diff --git a/QuickFIXn/SessionFactory.cs b/QuickFIXn/SessionFactory.cs
index eb433a8a1..7ceca116d 100755
--- a/QuickFIXn/SessionFactory.cs
+++ b/QuickFIXn/SessionFactory.cs
@@ -23,7 +23,7 @@ public SessionFactory(
IMessageFactory? messageFactory = null)
{
// TODO: for V2, consider ONLY instantiating MessageFactory in the Create() method,
- // and removing instance var messageFactory_ altogether.
+ // and removing instance var _messageFactory altogether.
// This makes sense because we can't distinguish FIX50 versions here in this constructor,
// and thus can't create the right FIX-Version factory because we don't know what
// session to use to look up the BeginString and DefaultApplVerID.
diff --git a/QuickFIXn/SessionID.cs b/QuickFIXn/SessionID.cs
index cef7203c0..55fc2cb98 100755
--- a/QuickFIXn/SessionID.cs
+++ b/QuickFIXn/SessionID.cs
@@ -1,4 +1,4 @@
-
+#nullable enable
using System;
namespace QuickFix
@@ -8,64 +8,36 @@ namespace QuickFix
/// and a session qualifier. Sessions are also identified by FIX version so
/// that it's possible to have multiple sessions to the same counterparty
/// but using different FIX versions (and/or session qualifiers).
- ///
///
public class SessionID
{
#region Properties
- public string BeginString
- {
- get { return beginString_; }
- }
+ public string BeginString { get; }
- public string SenderCompID
- {
- get { return senderCompID_; }
- }
+ public string SenderCompID { get; }
- public string SenderSubID
- {
- get { return senderSubID_; }
- }
+ public string SenderSubID { get; }
- public string SenderLocationID
- {
- get { return senderLocationID_; }
- }
+ public string SenderLocationID { get; }
- public string TargetCompID
- {
- get { return targetCompID_; }
- }
+ public string TargetCompID { get; }
- public string TargetSubID
- {
- get { return targetSubID_; }
- }
+ public string TargetSubID { get; }
- public string TargetLocationID
- {
- get { return targetLocationID_; }
- }
+ public string TargetLocationID { get; }
///
/// Session qualifier can be used to identify different sessions
/// for the same target company ID. Session qualifiers can only be used
/// with initiated sessions. They cannot be used with accepted sessions.
///
- public string SessionQualifier
- {
- get { return sessionQualifier_; }
- }
+ public string? SessionQualifier { get; }
///
/// Returns whether session version is FIXT 1.1 or newer
///
- public bool IsFIXT
- {
- get { return isFIXT_; }
- }
+ public bool IsFIXT { get; }
#endregion
@@ -74,87 +46,64 @@ public bool IsFIXT
#endregion
#region Private Members
- private string id_;
- private string beginString_;
- private string senderCompID_;
- private string senderSubID_;
- private string senderLocationID_;
- private string targetCompID_;
- private string targetSubID_;
- private string targetLocationID_;
- private string sessionQualifier_;
- private bool isFIXT_;
+ private readonly string _id;
#endregion
- public SessionID(string beginString, string senderCompID, string senderSubID, string senderLocationID, string targetCompID, string targetSubID, string targetLocationID, string sessionQualifier)
+ public SessionID(string beginString, string senderCompId, string senderSubId, string senderLocationId, string targetCompId, string targetSubId, string targetLocationId, string? sessionQualifier = NOT_SET)
{
- if (beginString == null)
- throw new ArgumentNullException("beginString");
- if (senderCompID == null)
- throw new ArgumentNullException("senderCompID");
- if (targetCompID == null)
- throw new ArgumentNullException("targetCompID");
- beginString_ = beginString;
- senderCompID_ = senderCompID;
- senderSubID_ = senderSubID;
- senderLocationID_ = senderLocationID;
- targetCompID_ = targetCompID;
- targetSubID_ = targetSubID;
- targetLocationID_ = targetLocationID;
- sessionQualifier_ = sessionQualifier;
- isFIXT_ = beginString_.StartsWith("FIXT", StringComparison.Ordinal);
-
- id_ = beginString_
+ BeginString = beginString ?? throw new ArgumentNullException(nameof(beginString));
+ SenderCompID = senderCompId ?? throw new ArgumentNullException(nameof(senderCompId));
+ SenderSubID = senderSubId;
+ SenderLocationID = senderLocationId;
+ TargetCompID = targetCompId ?? throw new ArgumentNullException(nameof(targetCompId));
+ TargetSubID = targetSubId;
+ TargetLocationID = targetLocationId;
+ SessionQualifier = sessionQualifier;
+ IsFIXT = BeginString.StartsWith("FIXT", StringComparison.Ordinal);
+
+ _id = BeginString
+ ":"
- + senderCompID_
- + (IsSet(senderSubID_) ? "/" + senderSubID_ : "")
- + (IsSet(senderLocationID_) ? "/" + senderLocationID_ : "")
+ + SenderCompID
+ + (IsSet(SenderSubID) ? "/" + SenderSubID : "")
+ + (IsSet(SenderLocationID) ? "/" + SenderLocationID : "")
+ "->"
- + targetCompID_
- + (IsSet(targetSubID_) ? "/" + targetSubID_ : "")
- + (IsSet(targetLocationID_) ? "/" + targetLocationID_ : "");
- if (null != sessionQualifier_ && sessionQualifier_.Length > 0)
- id_ += ":" + sessionQualifier_;
+ + TargetCompID
+ + (IsSet(TargetSubID) ? "/" + TargetSubID : "")
+ + (IsSet(TargetLocationID) ? "/" + TargetLocationID : "");
+ if (SessionQualifier is not null && SessionQualifier.Length > 0)
+ _id += ":" + SessionQualifier;
}
- public SessionID(string beginString, string senderCompID, string targetCompID)
- : this(beginString, senderCompID, targetCompID, NOT_SET)
- { }
-
- public SessionID(string beginString, string senderCompID, string senderSubID, string targetCompID, string targetSubID)
- : this(beginString, senderCompID, senderSubID, NOT_SET, targetCompID, targetSubID, NOT_SET, NOT_SET)
- { }
-
- public SessionID(string beginString, string senderCompID, string senderSubID, string senderLocationID, string targetCompID, string targetSubID, string targetLocationID)
- : this(beginString, senderCompID, senderSubID, senderLocationID, targetCompID, targetSubID, targetLocationID, NOT_SET)
+ public SessionID(string beginString, string senderCompId, string senderSubId, string targetCompId, string targetSubId)
+ : this(beginString, senderCompId, senderSubId, senderLocationId: NOT_SET, targetCompId, targetSubId, targetLocationId: NOT_SET)
{ }
- public SessionID(string beginString, string senderCompID, string targetCompID, string sessionQualifier)
- : this(beginString, senderCompID, NOT_SET, NOT_SET, targetCompID, NOT_SET, NOT_SET, sessionQualifier)
+ public SessionID(string beginString, string senderCompId, string targetCompId, string sessionQualifier = NOT_SET)
+ : this(beginString, senderCompId, senderSubId: NOT_SET, senderLocationId: NOT_SET, targetCompId, targetSubId: NOT_SET, targetLocationId: NOT_SET, sessionQualifier)
{ }
- public static bool IsSet(string value)
+ public static bool IsSet(string? value)
{
return value != null && value != NOT_SET;
}
public override string ToString()
{
- return id_;
+ return _id;
}
public override int GetHashCode()
{
- return id_.GetHashCode();
+ return _id.GetHashCode();
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
SessionID rhs = (SessionID)obj;
- return id_.Equals(rhs.id_);
+ return _id.Equals(rhs._id);
}
}
}
diff --git a/QuickFIXn/SessionSchedule.cs b/QuickFIXn/SessionSchedule.cs
index 7e4b54d61..ebb8390df 100755
--- a/QuickFIXn/SessionSchedule.cs
+++ b/QuickFIXn/SessionSchedule.cs
@@ -1,47 +1,48 @@
-
+#nullable enable
using System;
+
namespace QuickFix
{
public class SessionSchedule
{
- public System.TimeSpan StartTime { get; private set; }
- public System.TimeSpan EndTime { get; private set; }
+ public TimeSpan? StartTime { get; }
+ public TimeSpan? EndTime { get; }
- public bool WeeklySession { get; private set; }
- public System.DayOfWeek StartDay { get; private set; }
- public System.DayOfWeek EndDay { get; private set; }
+ public bool WeeklySession { get; }
+ public DayOfWeek? StartDay { get; }
+ public DayOfWeek? EndDay { get; }
- public bool NonStopSession { get; private set; }
+ public bool NonStopSession { get; }
- public bool UseLocalTime { get; private set; }
- public System.TimeZoneInfo TimeZone { get; private set; }
+ public bool UseLocalTime { get; }
+ public TimeZoneInfo? TimeZone { get; }
///
/// Returns true if testtime is in a different and newer session than old time
/// (or more explicitly: oldtime <= some EndTime < testtime)
///
- ///
- ///
+ ///
+ ///
///
- public bool IsNewSession(DateTime oldtime_utc, DateTime testtime_utc)
+ public bool IsNewSession(DateTime oldtimeUtc, DateTime testtimeUtc)
{
if (NonStopSession)
{
return false;
}
- if (oldtime_utc.Kind != System.DateTimeKind.Utc)
- throw new System.ArgumentException("Only UTC time is supported", "oldtime");
- if (testtime_utc.Kind != System.DateTimeKind.Utc)
- throw new System.ArgumentException("Only UTC time is supported", "testtime");
+ if (oldtimeUtc.Kind != DateTimeKind.Utc)
+ throw new ArgumentException("Only UTC time is supported", nameof(oldtimeUtc));
+ if (testtimeUtc.Kind != DateTimeKind.Utc)
+ throw new ArgumentException("Only UTC time is supported", nameof(testtimeUtc));
- DateTime old = AdjustUtcDateTime(oldtime_utc);
- DateTime test = AdjustUtcDateTime(testtime_utc);
+ DateTime old = AdjustUtcDateTime(oldtimeUtc);
+ DateTime test = AdjustUtcDateTime(testtimeUtc);
if (DateTime.Compare(old, test) < 0) // old is earlier than test
{
- DateTime nextend = NextEndTime(oldtime_utc);
+ DateTime nextend = NextEndTime(oldtimeUtc);
return (DateTime.Compare(old, nextend) <= 0) && (DateTime.Compare(nextend, test) < 0);
}
@@ -55,28 +56,23 @@ public bool IsNewSession(DateTime oldtime_utc, DateTime testtime_utc)
///
public DateTime AdjustUtcDateTime(DateTime utc)
{
- if (utc.Kind != System.DateTimeKind.Utc)
- throw new System.ArgumentException("Only UTC time is supported", "time");
+ if (utc.Kind != DateTimeKind.Utc)
+ throw new ArgumentException("Only UTC time is supported", nameof(utc));
if(UseLocalTime)
return utc.ToLocalTime();
- else if (TimeZone==null)
- return utc;
- else
- return System.TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZone);
+
+ return TimeZone==null ? utc : TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZone);
}
- public bool IsSessionTime(System.DateTime utc)
+ public bool IsSessionTime(DateTime utc)
{
- if (utc.Kind != System.DateTimeKind.Utc)
- throw new System.ArgumentException("Only UTC time is supported", "time");
+ if (utc.Kind != DateTimeKind.Utc)
+ throw new ArgumentException("Only UTC time is supported", nameof(utc));
- System.DateTime adjusted = AdjustUtcDateTime(utc);
+ DateTime adjusted = AdjustUtcDateTime(utc);
- if (WeeklySession)
- return CheckDay(adjusted);
- else
- return CheckTime(adjusted.TimeOfDay);
+ return WeeklySession ? CheckDay(adjusted) : CheckTime(adjusted.TimeOfDay);
}
///
@@ -87,19 +83,19 @@ public bool IsSessionTime(System.DateTime utc)
public DateTime NextEndTime(DateTime utc)
{
if (NonStopSession)
- {
throw new NotSupportedException("NonStopSession");
- }
+
+ TimeSpan vEndTime = EndTime ?? throw new QuickFix.ConfigError("EndTime is null");
if (utc.Kind != DateTimeKind.Utc)
- throw new ArgumentException("Only UTC time is supported", "time");
+ throw new ArgumentException("Only UTC time is supported", nameof(utc));
DateTime d = AdjustUtcDateTime(utc);
DateTime end = DateTime.MinValue;
if (WeeklySession)
{
- end = new DateTime(d.Year, d.Month, d.Day, EndTime.Hours, EndTime.Minutes, EndTime.Seconds, d.Kind);
+ end = new DateTime(d.Year, d.Month, d.Day, vEndTime.Hours, vEndTime.Minutes, vEndTime.Seconds, d.Kind);
while (end.DayOfWeek != EndDay)
end = end.AddDays(1);
if (DateTime.Compare(d, end) > 0) // d is later than end
@@ -107,7 +103,7 @@ public DateTime NextEndTime(DateTime utc)
}
else
{
- end = new DateTime(d.Year, d.Month, d.Day, EndTime.Hours, EndTime.Minutes, EndTime.Seconds, d.Kind);
+ end = new DateTime(d.Year, d.Month, d.Day, vEndTime.Hours, vEndTime.Minutes, vEndTime.Seconds, d.Kind);
if (DateTime.Compare(d, end) > 0) // d is later than end
end = end.AddDays(1);
}
@@ -115,83 +111,48 @@ public DateTime NextEndTime(DateTime utc)
return end;
}
- // TODO: consider removing this function in v2.0, as it's not used.
- ///
- /// Return the latest EndTime (in UTC) before time.
- ///
- ///
- ///
- public DateTime LastEndTime(DateTime utc)
- {
- if (NonStopSession)
- {
- throw new NotSupportedException("NonStopSession");
- }
-
- if (utc.Kind != DateTimeKind.Utc)
- throw new ArgumentException("Only UTC time is supported", "time");
-
- DateTime n = NextEndTime(utc);
- if (WeeklySession)
- n = n.AddDays(-7);
- else
- n = n.AddDays(-1);
-
- if (UseLocalTime)
- return n.ToUniversalTime();
- if (TimeZone != null)
- return TimeZoneInfo.ConvertTimeBySystemTimeZoneId(n, this.TimeZone.Id, "UTC");
- return n;
- }
-
///
/// return true if time falls within StartTime/EndTime
///
///
///
- private bool CheckDay(System.DateTime time)
+ private bool CheckDay(DateTime time)
{
if (NonStopSession)
- {
throw new InvalidOperationException("NonStopSession is set -- this should never be called.");
- }
- if (StartDay < EndDay)
+
+ DayOfWeek vStartDay = StartDay ?? throw new QuickFix.ConfigError("StartDay is null");
+ DayOfWeek vEndDay = EndDay ?? throw new QuickFix.ConfigError("EndDay is null");
+ TimeSpan vStartTime = StartTime ?? throw new QuickFix.ConfigError("StartTime is null");
+ TimeSpan vEndTime = EndTime ?? throw new QuickFix.ConfigError("EndTime is null");
+
+ if (vStartDay < vEndDay)
{
- if (time.DayOfWeek < StartDay || time.DayOfWeek > EndDay)
- {
+ if (time.DayOfWeek < vStartDay || time.DayOfWeek > vEndDay)
return false;
- }
- else if (time.DayOfWeek < EndDay)
- {
- return (StartDay < time.DayOfWeek) || (StartTime.CompareTo(time.TimeOfDay) <= 0);
- }
- else
- {
- return (time.DayOfWeek < EndDay) || (EndTime.CompareTo(time.TimeOfDay) >= 0);
- }
+
+ if (time.DayOfWeek < vEndDay)
+ return (vStartDay < time.DayOfWeek) || (vStartTime.CompareTo(time.TimeOfDay) <= 0);
+
+ return (time.DayOfWeek < vEndDay) || (vEndTime.CompareTo(time.TimeOfDay) >= 0);
}
- if (EndDay < StartDay)
+ if (vEndDay < vStartDay)
{
- if (EndDay < time.DayOfWeek && time.DayOfWeek < StartDay)
- {
+ if (vEndDay < time.DayOfWeek && time.DayOfWeek < vStartDay)
return false;
- }
- else if (time.DayOfWeek < StartDay)
- {
- return (time.DayOfWeek < EndDay) || (EndTime.CompareTo(time.TimeOfDay) >= 0);
- }
- else
- {
- return (time.DayOfWeek > StartDay) || (StartTime.CompareTo(time.TimeOfDay) <= 0);
- }
+
+ if (time.DayOfWeek < vStartDay)
+ return (time.DayOfWeek < vEndDay) || (vEndTime.CompareTo(time.TimeOfDay) >= 0);
+
+ return (time.DayOfWeek > vStartDay) || (vStartTime.CompareTo(time.TimeOfDay) <= 0);
}
//start day must be same as end day
- if (StartTime >= EndTime)
- return time.DayOfWeek != StartDay || CheckTime(time.TimeOfDay);
- else
- return time.DayOfWeek == StartDay && CheckTime(time.TimeOfDay);
+ if (vStartTime >= vEndTime)
+ return time.DayOfWeek != vStartDay || CheckTime(time.TimeOfDay);
+
+ return time.DayOfWeek == vStartDay && CheckTime(time.TimeOfDay);
}
///
@@ -199,22 +160,24 @@ private bool CheckDay(System.DateTime time)
///
///
///
- private bool CheckTime(System.TimeSpan time)
+ private bool CheckTime(TimeSpan time)
{
if (NonStopSession)
- {
return true;
- }
- if (StartTime.CompareTo(EndTime) < 0)
+ TimeSpan vStartTime = StartTime ?? throw new QuickFix.ConfigError("StartTime is null");
+ TimeSpan vEndTime = EndTime ?? throw new QuickFix.ConfigError("EndTime is null");
+
+ if (vStartTime.CompareTo(vEndTime) < 0)
{
- return (time.CompareTo(StartTime) >= 0 &&
- time.CompareTo(EndTime) <= 0);
+ return (time.CompareTo(vStartTime) >= 0 &&
+ time.CompareTo(vEndTime) <= 0);
}
- else if (StartTime.CompareTo(EndTime) > 0)
+
+ if (vStartTime.CompareTo(vEndTime) > 0)
{
- return (time.CompareTo(StartTime) >= 0 ||
- time.CompareTo(EndTime) <= 0);
+ return time.CompareTo(vStartTime) >= 0 ||
+ time.CompareTo(vEndTime) <= 0;
}
return true;
@@ -226,23 +189,16 @@ private bool CheckTime(System.TimeSpan time)
public SessionSchedule(QuickFix.Dictionary settings)
{
if (settings.Has(SessionSettings.NON_STOP_SESSION))
- {
NonStopSession = settings.GetBool(SessionSettings.NON_STOP_SESSION);
- }
+
if (NonStopSession)
- {
return;
- }
if (!settings.Has(SessionSettings.START_DAY) && settings.Has(SessionSettings.END_DAY))
- {
throw new QuickFix.ConfigError("EndDay used without StartDay");
- }
if (settings.Has(SessionSettings.START_DAY) && !settings.Has(SessionSettings.END_DAY))
- {
throw new QuickFix.ConfigError("StartDay used without EndDay");
- }
if (settings.Has(SessionSettings.START_DAY) && settings.Has(SessionSettings.END_DAY))
{
@@ -264,18 +220,18 @@ public SessionSchedule(QuickFix.Dictionary settings)
SessionSettings.TIME_ZONE + " conflicts with " + SessionSettings.USE_LOCAL_TIME);
}
string id = settings.GetString(SessionSettings.TIME_ZONE);
- TimeZone = System.TimeZoneInfo.FindSystemTimeZoneById(id);
+ TimeZone = TimeZoneInfo.FindSystemTimeZoneById(id);
}
try
{
- this.StartTime = System.TimeSpan.Parse(
+ StartTime = TimeSpan.Parse(
settings.GetString(SessionSettings.START_TIME));
- this.EndTime = System.TimeSpan.Parse(
+ EndTime = TimeSpan.Parse(
settings.GetString(SessionSettings.END_TIME));
}
- catch (System.FormatException e)
+ catch (FormatException e)
{
throw new ConfigError(e.Message);
}
diff --git a/QuickFIXn/SessionSettings.cs b/QuickFIXn/SessionSettings.cs
index 7f87d8364..abefde561 100755
--- a/QuickFIXn/SessionSettings.cs
+++ b/QuickFIXn/SessionSettings.cs
@@ -84,8 +84,8 @@ public class SessionSettings
#region Private Members
- private QuickFix.Dictionary defaults_ = new QuickFix.Dictionary();
- private System.Collections.Generic.Dictionary settings_ = new Dictionary();
+ private QuickFix.Dictionary _defaults = new();
+ private readonly System.Collections.Generic.Dictionary _settings = new();
#endregion
@@ -101,7 +101,7 @@ public SessionSettings(string file)
}
catch (System.Exception e)
{
- throw new ConfigError("File " + file + " not found (" + e.Message + ")");
+ throw new ConfigError($"File {file} not found ({e.Message})");
}
}
@@ -121,9 +121,9 @@ protected void Load(TextReader conf)
//---- load the DEFAULT section
LinkedList section = settings.Get("DEFAULT");
- QuickFix.Dictionary def = new QuickFix.Dictionary();
+ QuickFix.Dictionary def = new();
if (section.Count > 0)
- def = section.First.Value;
+ def = section.First!.Value;
Set(def);
//---- load each SESSION section
@@ -133,29 +133,29 @@ protected void Load(TextReader conf)
dict.Merge(def);
string sessionQualifier = SessionID.NOT_SET;
- string senderSubID = SessionID.NOT_SET;
- string senderLocID = SessionID.NOT_SET;
- string targetSubID = SessionID.NOT_SET;
- string targetLocID = SessionID.NOT_SET;
+ string senderSubId = SessionID.NOT_SET;
+ string senderLocId = SessionID.NOT_SET;
+ string targetSubId = SessionID.NOT_SET;
+ string targetLocId = SessionID.NOT_SET;
if (dict.Has(SESSION_QUALIFIER))
sessionQualifier = dict.GetString(SESSION_QUALIFIER);
if (dict.Has(SENDERSUBID))
- senderSubID = dict.GetString(SENDERSUBID);
+ senderSubId = dict.GetString(SENDERSUBID);
if (dict.Has(SENDERLOCID))
- senderLocID = dict.GetString(SENDERLOCID);
+ senderLocId = dict.GetString(SENDERLOCID);
if (dict.Has(TARGETSUBID))
- targetSubID = dict.GetString(TARGETSUBID);
+ targetSubId = dict.GetString(TARGETSUBID);
if (dict.Has(TARGETLOCID))
- targetLocID = dict.GetString(TARGETLOCID);
- SessionID sessionID = new SessionID(dict.GetString(BEGINSTRING), dict.GetString(SENDERCOMPID), senderSubID, senderLocID, dict.GetString(TARGETCOMPID), targetSubID, targetLocID, sessionQualifier);
- Set(sessionID, dict);
+ targetLocId = dict.GetString(TARGETLOCID);
+ SessionID sessionId = new SessionID(dict.GetString(BEGINSTRING), dict.GetString(SENDERCOMPID), senderSubId, senderLocId, dict.GetString(TARGETCOMPID), targetSubId, targetLocId, sessionQualifier);
+ Set(sessionId, dict);
}
}
- public bool Has(SessionID sessionID)
+ public bool Has(SessionID sessionId)
{
- return settings_.ContainsKey(sessionID);
+ return _settings.ContainsKey(sessionId);
}
///
@@ -164,68 +164,67 @@ public bool Has(SessionID sessionID)
/// Dictionary of settings from the [DEFAULT] section
public QuickFix.Dictionary Get()
{
- return defaults_;
+ return _defaults;
}
///
/// Get a dictionary for a session
///
- /// the ID of the session
+ /// the ID of the session
/// Dictionary of settings from the [SESSION] section for the given SessionID
- public Dictionary Get(SessionID sessionID)
+ public Dictionary Get(SessionID sessionId)
{
- Dictionary dict;
- if (!settings_.TryGetValue(sessionID, out dict))
- throw new ConfigError("Session '" + sessionID + "' not found");
+ if (!_settings.TryGetValue(sessionId, out var dict))
+ throw new ConfigError($"Session '{sessionId}' not found");
return dict;
}
public void Set(QuickFix.Dictionary defaults)
{
- defaults_ = defaults;
- foreach (KeyValuePair entry in settings_)
- entry.Value.Merge(defaults_);
+ _defaults = defaults;
+ foreach (KeyValuePair entry in _settings)
+ entry.Value.Merge(_defaults);
}
///
/// Remove existing session config from the settings
///
- /// ID of session for which config is to be removed
+ /// ID of session for which config is to be removed
/// true if removed, false if config for the session does not exist
- public bool Remove(SessionID sessionID)
+ public bool Remove(SessionID sessionId)
{
- return settings_.Remove(sessionID);
+ return _settings.Remove(sessionId);
}
///
/// Add new session config
///
- /// ID of session for which to add config
+ /// ID of session for which to add config
/// session config
- public void Set(SessionID sessionID, QuickFix.Dictionary settings)
+ public void Set(SessionID sessionId, QuickFix.Dictionary settings)
{
- if (Has(sessionID))
- throw new ConfigError("Duplicate Session " + sessionID.ToString());
- settings.SetString(BEGINSTRING, sessionID.BeginString);
- settings.SetString(SENDERCOMPID, sessionID.SenderCompID);
- if (SessionID.IsSet(sessionID.SenderSubID))
- settings.SetString(SENDERSUBID, sessionID.SenderSubID);
- if (SessionID.IsSet(sessionID.SenderLocationID))
- settings.SetString(SENDERLOCID, sessionID.SenderLocationID);
- settings.SetString(TARGETCOMPID, sessionID.TargetCompID);
- if (SessionID.IsSet(sessionID.TargetSubID))
- settings.SetString(TARGETSUBID, sessionID.TargetSubID);
- if (SessionID.IsSet(sessionID.TargetLocationID))
- settings.SetString(TARGETLOCID, sessionID.TargetLocationID);
- settings.Merge(defaults_);
+ if (Has(sessionId))
+ throw new ConfigError($"Duplicate Session {sessionId}");
+ settings.SetString(BEGINSTRING, sessionId.BeginString);
+ settings.SetString(SENDERCOMPID, sessionId.SenderCompID);
+ if (SessionID.IsSet(sessionId.SenderSubID))
+ settings.SetString(SENDERSUBID, sessionId.SenderSubID);
+ if (SessionID.IsSet(sessionId.SenderLocationID))
+ settings.SetString(SENDERLOCID, sessionId.SenderLocationID);
+ settings.SetString(TARGETCOMPID, sessionId.TargetCompID);
+ if (SessionID.IsSet(sessionId.TargetSubID))
+ settings.SetString(TARGETSUBID, sessionId.TargetSubID);
+ if (SessionID.IsSet(sessionId.TargetLocationID))
+ settings.SetString(TARGETLOCID, sessionId.TargetLocationID);
+ settings.Merge(_defaults);
Validate(settings);
- settings_[sessionID] = settings;
+ _settings[sessionId] = settings;
}
public HashSet GetSessions()
{
HashSet result = new HashSet();
- foreach (KeyValuePair entry in settings_)
+ foreach (KeyValuePair entry in _settings)
result.Add(entry.Key);
return result;
}
@@ -235,15 +234,15 @@ public override string ToString()
System.Text.StringBuilder s = new System.Text.StringBuilder();
s.AppendLine("[DEFAULT]");
- foreach (System.Collections.Generic.KeyValuePair entry in defaults_)
+ foreach (System.Collections.Generic.KeyValuePair entry in _defaults)
s.Append(entry.Key).Append('=').AppendLine(entry.Value);
- foreach (KeyValuePair entry in settings_)
+ foreach (KeyValuePair entry in _settings)
{
s.AppendLine().AppendLine("[SESSION]");
foreach (System.Collections.Generic.KeyValuePair kvp in entry.Value)
{
- if (defaults_.Has(kvp.Key) && defaults_.GetString(kvp.Key).Equals(kvp.Value))
+ if (_defaults.Has(kvp.Key) && _defaults.GetString(kvp.Key).Equals(kvp.Value))
continue;
s.Append(kvp.Key).Append('=').AppendLine(kvp.Value);
}
@@ -262,13 +261,13 @@ protected void Validate(QuickFix.Dictionary dictionary)
beginString != Values.BeginString_FIX44 &&
beginString != Values.BeginString_FIXT11)
{
- throw new ConfigError(BEGINSTRING + " (" + beginString + ") must be FIX.4.0 to FIX.4.4 or FIXT.1.1");
+ throw new ConfigError($"{BEGINSTRING} ({beginString}) must be FIX.4.0 to FIX.4.4 or FIXT.1.1");
}
string connectionType = dictionary.GetString(CONNECTION_TYPE);
if (!"initiator".Equals(connectionType) && !"acceptor".Equals(connectionType))
{
- throw new ConfigError(CONNECTION_TYPE + " must be 'initiator' or 'acceptor'");
+ throw new ConfigError($"{CONNECTION_TYPE} must be 'initiator' or 'acceptor'");
}
}
}
diff --git a/QuickFIXn/Settings.cs b/QuickFIXn/Settings.cs
index 1219dc222..1cd517ea1 100755
--- a/QuickFIXn/Settings.cs
+++ b/QuickFIXn/Settings.cs
@@ -1,16 +1,17 @@
-using System.Collections.Generic;
+#nullable enable
+using System.Collections.Generic;
namespace QuickFix
{
public class Settings
{
- private LinkedList sections_ = new LinkedList();
+ private readonly LinkedList _sections = new();
public Settings(System.IO.TextReader conf)
{
- QuickFix.Dictionary currentSection = null;
+ QuickFix.Dictionary? currentSection = null;
- string line = null;
+ string? line;
while ((line = conf.ReadLine()) != null)
{
line = line.Trim();
@@ -18,7 +19,8 @@ public Settings(System.IO.TextReader conf)
{
continue;
}
- else if (IsSection(line))
+
+ if (IsSection(line))
{
currentSection = Add(new Dictionary(SplitSection(line)));
}
@@ -56,12 +58,12 @@ public static bool IsSection(string s)
{
if (s.Length < 2)
return false;
- return s[0] == '[' && s[s.Length - 1] == ']';
+ return s[0] == '[' && s[^1] == ']';
}
public QuickFix.Dictionary Add(QuickFix.Dictionary section)
{
- sections_.AddLast(section);
+ _sections.AddLast(section);
return section;
}
@@ -73,8 +75,8 @@ public QuickFix.Dictionary Add(QuickFix.Dictionary section)
///
public LinkedList Get(string sectionName)
{
- LinkedList result = new LinkedList();
- foreach (QuickFix.Dictionary dict in sections_)
+ LinkedList result = new();
+ foreach (QuickFix.Dictionary dict in _sections)
if (sectionName.ToUpperInvariant() == dict.Name.ToUpperInvariant())
result.AddLast(dict);
return result;
diff --git a/QuickFIXn/Transport/StreamFactory.cs b/QuickFIXn/Transport/StreamFactory.cs
index a420ed585..8b637fea9 100644
--- a/QuickFIXn/Transport/StreamFactory.cs
+++ b/QuickFIXn/Transport/StreamFactory.cs
@@ -1,4 +1,5 @@
-using System;
+#nullable enable
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -17,9 +18,9 @@ namespace QuickFix.Transport
///
public static class StreamFactory
{
- private static Socket CreateTunnelThruProxy(string destIP, int destPort)
+ private static Socket? CreateTunnelThruProxy(string destIp, int destPort)
{
- string destUriWithPort = $"{destIP}:{destPort}";
+ string destUriWithPort = $"{destIp}:{destPort}";
UriBuilder uriBuilder = new UriBuilder(destUriWithPort);
Uri destUri = uriBuilder.Uri;
IWebProxy webProxy = WebRequest.GetSystemWebProxy();
@@ -36,8 +37,8 @@ private static Socket CreateTunnelThruProxy(string destIP, int destPort)
return null;
}
- Uri proxyUri = webProxy.GetProxy(destUri);
- if (proxyUri == null)
+ Uri? proxyUri = webProxy.GetProxy(destUri);
+ if (proxyUri is null)
return null;
IPAddress[] proxyEntry = Dns.GetHostAddresses(proxyUri.Host);
@@ -47,18 +48,17 @@ private static Socket CreateTunnelThruProxy(string destIP, int destPort)
Socket socketThruProxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketThruProxy.Connect(proxyEndPoint);
- string proxyMsg = $"CONNECT {destIP}:{destPort} HTTP/1.1 \n\n";
+ string proxyMsg = $"CONNECT {destIp}:{destPort} HTTP/1.1 \n\n";
byte[] buffer = Encoding.ASCII.GetBytes(proxyMsg);
byte[] buffer12 = new byte[500];
socketThruProxy.Send(buffer, buffer.Length, 0);
- int msg = socketThruProxy.Receive(buffer12, 500, 0);
- string data;
- data = Encoding.ASCII.GetString(buffer12);
+ socketThruProxy.Receive(buffer12, 500, 0);
+ string data = Encoding.ASCII.GetString(buffer12);
int index = data.IndexOf("200", StringComparison.Ordinal);
if (index < 0)
throw new ApplicationException(
- $"Connection failed to {destUriWithPort} through proxy server {proxyUri.ToString()}.");
+ $"Connection failed to {destUriWithPort} through proxy server {proxyUri}.");
return socketThruProxy;
}
@@ -73,10 +73,10 @@ private static Socket CreateTunnelThruProxy(string destIP, int destPort)
public static Stream CreateClientStream(IPEndPoint endpoint, SocketSettings settings, ILog logger)
{
// If system has configured a proxy for this config, use it.
- Socket socket = CreateTunnelThruProxy(endpoint.Address.ToString(), endpoint.Port);
+ Socket? socket = CreateTunnelThruProxy(endpoint.Address.ToString(), endpoint.Port);
// No proxy. Set up a regular socket.
- if (socket == null)
+ if (socket is null)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.NoDelay = settings.SocketNodelay;
@@ -102,10 +102,7 @@ public static Stream CreateClientStream(IPEndPoint endpoint, SocketSettings sett
Stream stream = new NetworkStream(socket, true);
if (settings.UseSSL)
- {
- stream = new SSLStreamFactory(logger, settings)
- .CreateClientStreamAndAuthenticate(stream);
- }
+ stream = new SslStreamFactory(logger, settings).CreateClientStreamAndAuthenticate(stream);
return stream;
}
@@ -121,13 +118,12 @@ public static Stream CreateClientStream(IPEndPoint endpoint, SocketSettings sett
public static Stream CreateServerStream(TcpClient tcpClient, SocketSettings settings, ILog logger)
{
if (tcpClient.Connected == false)
- throw new ArgumentException("tcp client must be connected in order to get stream", "tcpClient");
+ throw new ArgumentException("tcp client must be connected in order to get stream", nameof(tcpClient));
Stream stream = tcpClient.GetStream();
if (settings.UseSSL)
{
- stream = new SSLStreamFactory(logger, settings)
- .CreateServerStreamAndAuthenticate(stream);
+ stream = new SslStreamFactory(logger, settings).CreateServerStreamAndAuthenticate(stream);
}
return stream;
@@ -136,7 +132,7 @@ public static Stream CreateServerStream(TcpClient tcpClient, SocketSettings sett
///
/// Cache loaded certificates since loading a certificate can be a costly operation
///
- private static Dictionary _certificateCache = new Dictionary();
+ private static readonly Dictionary CertificateCache = new ();
///
/// Loads the specified certificate given a path, DistinguishedName or subject name
@@ -144,22 +140,20 @@ public static Stream CreateServerStream(TcpClient tcpClient, SocketSettings sett
/// The certificate path or DistinguishedName/subjectname if it should be loaded from the personal certificate store.
/// The certificate password.
/// The specified certificate, or null if no certificate is found
- internal static X509Certificate2 LoadCertificate(string name, string password)
+ private static X509Certificate2? LoadCertificate(string name, string? password)
{
- X509Certificate2 certificate;
-
// TODO: Change _certificateCache's type to ConcurrentDictionary once we start targeting .NET 4,
// then remove this lock and use GetOrAdd function of concurrent dictionary
// e.g.: certificate = _certificateCache.GetOrAdd(name, (key) => LoadCertificateInner(name, password));
- lock (_certificateCache)
+ lock (CertificateCache)
{
- if (_certificateCache.TryGetValue(name, out certificate))
+ if (CertificateCache.TryGetValue(name, out X509Certificate2? certificate))
return certificate;
certificate = LoadCertificateInner(name, password);
- if (certificate != null)
- _certificateCache.Add(name, certificate);
+ if (certificate is not null)
+ CertificateCache.Add(name, certificate);
return certificate;
}
@@ -171,21 +165,19 @@ internal static X509Certificate2 LoadCertificate(string name, string password)
/// The certificate path or DistinguishedName/subjectname if it should be loaded from the personal certificate store.
/// The certificate password.
/// The specified certificate, or null if no certificate is found
- private static X509Certificate2 LoadCertificateInner(string name, string password)
+ private static X509Certificate2? LoadCertificateInner(string name, string? password)
{
- X509Certificate2 certificate;
+ X509Certificate2? certificate;
// If no extension is found try to get from certificate store
if (!File.Exists(name))
{
certificate = GetCertificateFromStore(name);
}
- else
- {
- if (password != null)
- certificate = new X509Certificate2(name, password);
- else
- certificate = new X509Certificate2(name);
+ else {
+ certificate = password is not null
+ ? new X509Certificate2(name, password)
+ : new X509Certificate2(name);
}
return certificate;
}
@@ -195,14 +187,14 @@ private static X509Certificate2 LoadCertificateInner(string name, string passwor
///
/// See http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.aspx for complete example
/// Name of the cert.
- ///
- private static X509Certificate2 GetCertificateFromStore(string certName)
+ /// The cert, or null if not found
+ private static X509Certificate2? GetCertificateFromStore(string certName)
{
return GetCertificateFromStoreHelper(certName, new X509Store(StoreLocation.LocalMachine))
?? GetCertificateFromStoreHelper(certName, new X509Store(StoreLocation.CurrentUser));
}
- private static X509Certificate2 GetCertificateFromStoreHelper(string certName, X509Store store)
+ private static X509Certificate2? GetCertificateFromStoreHelper(string certName, X509Store store)
{
try
{
@@ -214,10 +206,9 @@ private static X509Certificate2 GetCertificateFromStoreHelper(string certName, X
// currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, true);
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
- if (certName.Contains("CN="))
- currentCerts = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false);
- else
- currentCerts = currentCerts.Find(X509FindType.FindBySubjectName, certName, false);
+ currentCerts = currentCerts.Find(certName.Contains("CN=")
+ ? X509FindType.FindBySubjectDistinguishedName
+ : X509FindType.FindBySubjectName, certName, false);
if (currentCerts.Count == 0)
return null;
@@ -234,17 +225,17 @@ private static X509Certificate2 GetCertificateFromStoreHelper(string certName, X
///
/// The SSLClientStreamFactory is responsible for setting up a SSLStream in either client or server mode
///
- private sealed class SSLStreamFactory
+ private sealed class SslStreamFactory
{
- ILog log_;
- SocketSettings socketSettings_;
- const string clientAuthenticationOid = "1.3.6.1.5.5.7.3.2";
- const string serverAuthenticationOid = "1.3.6.1.5.5.7.3.1";
+ private readonly ILog _log;
+ private readonly SocketSettings _socketSettings;
+ private const string CLIENT_AUTHENTICATION_OID = "1.3.6.1.5.5.7.3.2";
+ private const string SERVER_AUTHENTICATION_OID = "1.3.6.1.5.5.7.3.1";
- public SSLStreamFactory(ILog log, SocketSettings settings)
+ public SslStreamFactory(ILog log, SocketSettings settings)
{
- log_ = log;
- socketSettings_ = settings;
+ _log = log;
+ _socketSettings = settings;
}
///
@@ -254,20 +245,27 @@ public SSLStreamFactory(ILog log, SocketSettings settings)
/// a ssl enabled stream
public Stream CreateClientStreamAndAuthenticate(Stream innerStream)
{
- SslStream sslStream = new SslStream(innerStream, false, ValidateServerCertificate, SelectLocalCertificate);
+ SslStream sslStream = new SslStream(
+ innerStream,
+ false,
+ ValidateServerCertificate,
+#pragma warning disable CS8621 // Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
+ // Per MS docs, this delete /should/ have a nullable return type
+ SelectLocalCertificate);
+#pragma warning restore CS8621 // Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
try
{
// Setup secure SSL Communication
X509CertificateCollection clientCertificates = GetClientCertificates();
- sslStream.AuthenticateAsClient(socketSettings_.ServerCommonName,
+ sslStream.AuthenticateAsClient(_socketSettings.ServerCommonName,
clientCertificates,
- socketSettings_.SslProtocol,
- socketSettings_.CheckCertificateRevocation);
+ _socketSettings.SslProtocol,
+ _socketSettings.CheckCertificateRevocation);
}
catch (System.Security.Authentication.AuthenticationException ex)
{
- log_.OnEvent("Unable to perform authentication against server: " + ex.Message);
+ _log.OnEvent("Unable to perform authentication against server: " + ex.Message);
throw;
}
@@ -281,23 +279,34 @@ public Stream CreateClientStreamAndAuthenticate(Stream innerStream)
/// a ssl enabled stream
public Stream CreateServerStreamAndAuthenticate(Stream innerStream)
{
- SslStream sslStream = new SslStream(innerStream, false, ValidateClientCertificate, SelectLocalCertificate);
+ SslStream sslStream = new SslStream(
+ innerStream,
+ false,
+ ValidateClientCertificate,
+#pragma warning disable CS8621 // Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
+ // Per MS docs, this delete /should/ have a nullable return type
+ SelectLocalCertificate);
+#pragma warning restore CS8621 // Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
try
{
- if (string.IsNullOrEmpty(socketSettings_.CertificatePath))
- throw new Exception(string.Format("No server certificate specified, the {0} setting must be configured", SessionSettings.SSL_CERTIFICATE));
+ if (string.IsNullOrEmpty(_socketSettings.CertificatePath))
+ throw new Exception($"No server certificate specified, the {SessionSettings.SSL_CERTIFICATE} setting must be configured");
// Setup secure SSL Communication
- X509Certificate2 serverCertificate = StreamFactory.LoadCertificate(socketSettings_.CertificatePath, socketSettings_.CertificatePassword);
- sslStream.AuthenticateAsServer(serverCertificate,
- socketSettings_.RequireClientCertificate,
- socketSettings_.SslProtocol,
- socketSettings_.CheckCertificateRevocation);
+ X509Certificate2? serverCertificate = LoadCertificate(_socketSettings.CertificatePath, _socketSettings.CertificatePassword);
+ sslStream.AuthenticateAsServer(new SslServerAuthenticationOptions
+ {
+ ServerCertificate = serverCertificate,
+ ClientCertificateRequired = _socketSettings.RequireClientCertificate,
+ EnabledSslProtocols = _socketSettings.SslProtocol,
+ CertificateRevocationCheckMode = _socketSettings.CheckCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
+ EncryptionPolicy = EncryptionPolicy.RequireEncryption
+ });
}
catch (System.Security.Authentication.AuthenticationException ex)
{
- log_.OnEvent("Unable to perform authentication against server: " + ex.Message);
+ _log.OnEvent("Unable to perform authentication against server: " + ex.Message);
throw;
}
@@ -306,44 +315,43 @@ public Stream CreateServerStreamAndAuthenticate(Stream innerStream)
private X509CertificateCollection GetClientCertificates()
{
- if (!string.IsNullOrEmpty(socketSettings_.CertificatePath))
- {
- X509CertificateCollection certificates = new X509Certificate2Collection();
- X509Certificate2 clientCert = StreamFactory.LoadCertificate(socketSettings_.CertificatePath, socketSettings_.CertificatePassword);
- certificates.Add(clientCert);
- return certificates;
- }
- else
+ var rv = new X509Certificate2Collection();
+ if (!string.IsNullOrEmpty(_socketSettings.CertificatePath))
{
- return new X509Certificate2Collection();
+ X509Certificate2? clientCert = LoadCertificate(_socketSettings.CertificatePath, _socketSettings.CertificatePassword);
+ if (clientCert is not null)
+ rv.Add(clientCert);
}
- }
+ return rv;
+ }
///
/// Perform validation of the servers certificate. (the initiator validates the server/acceptors certificate)
+ /// (Satisfies interface to delegate System.Net.Security.RemoteCertificateValidationCallback)
///
/// The sender.
/// The certificate.
/// The chain.
/// The SSL policy errors.
/// true if the certificate should be treated as trusted; otherwise false
- private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ private bool ValidateServerCertificate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
{
- return VerifyRemoteCertificate(certificate, sslPolicyErrors, serverAuthenticationOid);
+ return VerifyRemoteCertificate(certificate, sslPolicyErrors, SERVER_AUTHENTICATION_OID);
}
///
/// Perform validation of a a client certificate.(the acceptor validates the client/initiators certificate)
+ /// (Satisfies interface to delegate System.Net.Security.RemoteCertificateValidationCallback)
///
/// The sender.
/// The certificate.
/// The chain.
/// The SSL policy errors.
/// true if the certificate should be treated as trusted; otherwise false
- private bool ValidateClientCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ private bool ValidateClientCertificate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
{
- return VerifyRemoteCertificate(certificate, sslPolicyErrors, clientAuthenticationOid);
+ return VerifyRemoteCertificate(certificate, sslPolicyErrors, CLIENT_AUTHENTICATION_OID);
}
///
@@ -353,46 +361,66 @@ private bool ValidateClientCertificate(object sender, X509Certificate certificat
/// The SSL policy errors supplied by .Net.
/// Enhanced key usage, which the remote computers certificate should contain.
/// true if the certificate should be treated as trusted; otherwise false
- private bool VerifyRemoteCertificate(X509Certificate certificate, SslPolicyErrors sslPolicyErrors, string enhancedKeyUsage)
+ private bool VerifyRemoteCertificate(
+ X509Certificate? certificate,
+ SslPolicyErrors sslPolicyErrors,
+ string enhancedKeyUsage)
{
// Accept without looking at if the certificate is valid if validation is disabled
- if (socketSettings_.ValidateCertificates == false)
+ if (_socketSettings.ValidateCertificates == false)
return true;
+ if (certificate is null)
+ return false;
+
// Validate enhanced key usage
- if (!ContainsEnhancedKeyUsage(certificate, enhancedKeyUsage))
- {
- if (enhancedKeyUsage == clientAuthenticationOid)
- log_.OnEvent("Remote certificate is not intended for client authentication: It is missing enhanced key usage " + enhancedKeyUsage);
+ if (!ContainsEnhancedKeyUsage(certificate, enhancedKeyUsage)) {
+ if (enhancedKeyUsage == CLIENT_AUTHENTICATION_OID)
+ _log.OnEvent(
+ "Remote certificate is not intended for client authentication: It is missing enhanced key usage " +
+ enhancedKeyUsage);
else
- log_.OnEvent("Remote certificate is not intended for server authentication: It is missing enhanced key usage " + enhancedKeyUsage);
+ _log.OnEvent(
+ "Remote certificate is not intended for server authentication: It is missing enhanced key usage " +
+ enhancedKeyUsage);
+
+ return false;
+ }
+
+ if (string.IsNullOrEmpty(_socketSettings.CACertificatePath)) {
+ _log.OnEvent("CACertificatePath is not specified");
+ return false;
+ }
+ // If CA Certficiate is specified then validate agains the CA certificate, otherwise it is validated against the installed certificates
+ X509Certificate2? cert = LoadCertificate(_socketSettings.CACertificatePath, null);
+ if (cert is null) {
+ _log.OnEvent("Remote certificate was not recognized as a valid certificate: " + sslPolicyErrors);
return false;
}
- // If CA Certficiate is specifed then validate agains the CA certificate, otherwise it is validated against the installed certificates
- if (!string.IsNullOrEmpty(socketSettings_.CACertificatePath))
+ X509Chain chain0 = new X509Chain();
+ chain0.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
+ // add all your extra certificate chain
+
+ chain0.ChainPolicy.ExtraStore.Add(cert);
+ chain0.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
+ bool isValid = chain0.Build((X509Certificate2)certificate);
+
+ if (isValid)
+ {
+ // resets the sslPolicyErrors.RemoteCertificateChainErrors status
+ sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
+ }
+ else
{
- X509Chain chain0 = new X509Chain();
- chain0.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
- // add all your extra certificate chain
-
- chain0.ChainPolicy.ExtraStore.Add(StreamFactory.LoadCertificate(socketSettings_.CACertificatePath, null));
- chain0.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
- bool isValid = chain0.Build((X509Certificate2)certificate);
-
- // If the certificate is valid then reset the sslPolicyErrors.RemoteCertificateChainErrors status
- if (isValid)
- sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
- // If the certificate could not be validated against CA, then set the SslPolicyErrors.RemoteCertificateChainErrors
- else //if (isValid == false)
- sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
+ sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
}
// Any basic authentication check failed, do after checking CA
if (sslPolicyErrors != SslPolicyErrors.None)
{
- log_.OnEvent("Remote certificate was not recognized as a valid certificate: " + sslPolicyErrors);
+ _log.OnEvent("Remote certificate was not recognized as a valid certificate: " + sslPolicyErrors);
return false;
}
@@ -408,16 +436,12 @@ private bool VerifyRemoteCertificate(X509Certificate certificate, SslPolicyError
/// true if the oid is specified as an enhanced key usage; otherwise false
private static bool ContainsEnhancedKeyUsage(X509Certificate certificate, string enhancedKeyOid)
{
- X509Certificate2 cert2 = certificate as X509Certificate2;
-
- if (cert2 == null)
- cert2 = new X509Certificate2(certificate);
+ X509Certificate2 cert2 = certificate as X509Certificate2 ?? new X509Certificate2(certificate);
foreach (X509Extension extension in cert2.Extensions)
{
- if (extension is X509EnhancedKeyUsageExtension)
+ if (extension is X509EnhancedKeyUsageExtension keyUsage)
{
- X509EnhancedKeyUsageExtension keyUsage = (X509EnhancedKeyUsageExtension)extension;
foreach (System.Security.Cryptography.Oid oid in keyUsage.EnhancedKeyUsages)
{
if (oid.Value == enhancedKeyOid)
@@ -429,21 +453,31 @@ private static bool ContainsEnhancedKeyUsage(X509Certificate certificate, string
return false;
}
-
- public X509Certificate SelectLocalCertificate(object sender, string targetHost,
- X509CertificateCollection localCertificates,
- X509Certificate remoteCertificate,
- string[] acceptableIssuers)
+ ///
+ /// (Satisfies interface to delegate System.Net.Security.LocalCertificateSelectionCallback)
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static X509Certificate? SelectLocalCertificate(
+ object sender,
+ string targetHost,
+ X509CertificateCollection localCertificates,
+ X509Certificate? remoteCertificate,
+ string[] acceptableIssuers)
{
// No certificate can be selected if we have no local certificates at all
- if (localCertificates == null || localCertificates.Count <= 0)
+ if (localCertificates.Count <= 0)
return null;
- Debug.Assert(localCertificates != null && localCertificates.Count > 0);
+ Debug.Assert(localCertificates is not null && localCertificates.Count > 0);
//Otherwise we select the first availible certificate as per msdn documentation
// http://msdn.microsoft.com/en-us/library/system.net.security.localcertificateselectioncallback.aspx
- if (acceptableIssuers != null)
+ if (acceptableIssuers.Length > 0)
{
// Use the first certificate that is from an acceptable issuer.
foreach (X509Certificate certificate in localCertificates)
@@ -454,8 +488,11 @@ public X509Certificate SelectLocalCertificate(object sender, string targetHost,
}
}
- // Just use any certificate
- return localCertificates[0];
+ // Just use any certificate (if there is one)
+ if (localCertificates.Count > 0)
+ return localCertificates[0];
+
+ return null;
}
}
}
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index e4d27b1a9..86af9145d 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -42,6 +42,10 @@ What's New
* Session: Logon() and Logout() made internal and renamed. No one should be using these.
* SessionState: ctor now requires a MessageStore. (Existing callers used an object initializer anyway)
* Many protected functions were altered, but probably no user code is touching them
+* #827 - cleanup/nullable-ize StreamFactory, SessionID, Settings, SessionSettings, SessionSchedule (gbirchmeier)
+ * StreamFactory: privatized a lot of members; I don't think users are inheriting from this
+ * SessionSchedule: remove unused LastEndTime()
+
**Non-breaking changes**
* #400 - added DDTool, a C#-based codegen, and deleted Ruby-based generator (gbirchmeier)
diff --git a/UnitTests/SessionScheduleTests.cs b/UnitTests/SessionScheduleTests.cs
index 1cd70a4a1..b5854f4d0 100755
--- a/UnitTests/SessionScheduleTests.cs
+++ b/UnitTests/SessionScheduleTests.cs
@@ -353,101 +353,6 @@ public void testTimeZone()
Assert.IsFalse(sched.IsSessionTime(new DateTime(2011, 10, 17, 20, 0, 1, DateTimeKind.Utc)));
}
- [Test]
- public void testLastEndTime_takesUtcOnly()
- {
- QuickFix.Dictionary settings = new QuickFix.Dictionary();
- settings.SetString(QuickFix.SessionSettings.START_TIME, "09:30:00");
- settings.SetString(QuickFix.SessionSettings.END_TIME, "16:00:00");
-
- QuickFix.SessionSchedule sched = new QuickFix.SessionSchedule(settings);
-
- Assert.Throws(
- delegate { sched.LastEndTime(new DateTime(2012, 10, 18, 12, 00, 00, DateTimeKind.Local)); });
- Assert.Throws(
- delegate { sched.LastEndTime(new DateTime(2012, 10, 18, 12, 00, 00, DateTimeKind.Unspecified)); });
- }
-
- [Test]
- public void testLastEndTime_DailySessions()
- {
- QuickFix.Dictionary settings = new QuickFix.Dictionary();
- settings.SetString(QuickFix.SessionSettings.START_TIME, "09:30:00");
- settings.SetString(QuickFix.SessionSettings.END_TIME, "16:00:00");
- QuickFix.SessionSchedule sched = new QuickFix.SessionSchedule(settings);
-
- DateTime thisDayEnd = new DateTime(2013, 02, 05, 16, 00, 00, DateTimeKind.Utc);
- DateTime prevDayEnd = new DateTime(2013, 02, 04, 16, 00, 00, DateTimeKind.Utc);
-
- // before starttime
- Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc)));
- // during session
- Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 10, 00, 00, DateTimeKind.Utc)));
- // equals endtime
- Assert.AreEqual(prevDayEnd, sched.LastEndTime(thisDayEnd));
- // after endtime
- Assert.AreEqual(thisDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 17, 00, 00, DateTimeKind.Utc)));
-
- // ==========
- // Settings file is specified in a zone (est, -5)
- settings = new QuickFix.Dictionary();
- settings.SetString(QuickFix.SessionSettings.START_TIME, "04:30:00"); // 09:30:00 utc
- settings.SetString(QuickFix.SessionSettings.END_TIME, "11:00:00"); // 16:00:00 utc
- settings.SetString(QuickFix.SessionSettings.TIME_ZONE, EASTERN_STANDARD_TIME_ZONE_ID); //-5
- sched = new QuickFix.SessionSchedule(settings);
-
- // before starttime
- Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc)));
- // during session
- Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 10, 00, 00, DateTimeKind.Utc)));
- // equals endtime
- Assert.AreEqual(prevDayEnd, sched.LastEndTime(thisDayEnd));
- // after endtime
- Assert.AreEqual(thisDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 17, 00, 00, DateTimeKind.Utc)));
- }
-
- [Test]
- public void testLastEndTime_WeeklySessions()
- {
- QuickFix.Dictionary settings = new QuickFix.Dictionary();
- settings.SetString(QuickFix.SessionSettings.START_TIME, "09:30:00");
- settings.SetString(QuickFix.SessionSettings.END_TIME, "16:00:00");
- settings.SetDay(QuickFix.SessionSettings.START_DAY, System.DayOfWeek.Monday);
- settings.SetDay(QuickFix.SessionSettings.END_DAY, System.DayOfWeek.Friday);
- QuickFix.SessionSchedule sched = new QuickFix.SessionSchedule(settings);
-
- DateTime thisWeekEnd = new DateTime(2013, 02, 08, 16, 00, 00, DateTimeKind.Utc);
- DateTime prevWeekEnd = new DateTime(2013, 02, 01, 16, 00, 00, DateTimeKind.Utc);
-
- // before starttime
- Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 04, 08, 00, 00, DateTimeKind.Utc)));
- // during session
- Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc)));
- // equals endtime
- Assert.AreEqual(prevWeekEnd, sched.LastEndTime(thisWeekEnd));
- // after endtime
- Assert.AreEqual(thisWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 08, 17, 00, 00, DateTimeKind.Utc)));
-
- // ==========
- // Settings file is specified in a zone (est, -5)
- settings = new QuickFix.Dictionary();
- settings.SetString(QuickFix.SessionSettings.START_TIME, "04:30:00"); // 09:30:00 utc
- settings.SetString(QuickFix.SessionSettings.END_TIME, "11:00:00"); // 16:00:00 utc
- settings.SetString(QuickFix.SessionSettings.TIME_ZONE, EASTERN_STANDARD_TIME_ZONE_ID); //-5
- settings.SetDay(QuickFix.SessionSettings.START_DAY, System.DayOfWeek.Monday);
- settings.SetDay(QuickFix.SessionSettings.END_DAY, System.DayOfWeek.Friday);
- sched = new QuickFix.SessionSchedule(settings);
-
- // before starttime
- Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 04, 08, 00, 00, DateTimeKind.Utc)));
- // during session
- Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc)));
- // equals endtime
- Assert.AreEqual(prevWeekEnd, sched.LastEndTime(thisWeekEnd));
- // after endtime
- Assert.AreEqual(thisWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 08, 17, 00, 00, DateTimeKind.Utc)));
- }
-
[Test]
public void testNextEndTime_takesUtcOnly()
{