/// <summary>
/// Validates request header and returns a request context.
/// </summary>
/// <remarks>
/// This method verifies that the session id valid and that it uses secure channel id
/// associated with with current thread. It also verifies that the timestamp is not too
/// and that the sequence number is not out of order (update requests only).
/// </remarks>
public virtual OperationContext ValidateRequest(RequestHeader requestHeader, RequestType requestType)
{
if (requestHeader == null)
{
throw new ArgumentNullException(nameof(requestHeader));
}
Session session = null;
try
{
lock (m_lock)
{
// check for create session request.
if (requestType == RequestType.CreateSession || requestType == RequestType.ActivateSession)
{
return(new OperationContext(requestHeader, requestType));
}
// find session.
if (!m_sessions.TryGetValue(requestHeader.AuthenticationToken, out session))
{
var Handler = m_ValidateSessionLessRequest;
if (Handler != null)
{
var args = new ValidateSessionLessRequestEventArgs(requestHeader.AuthenticationToken, requestType);
Handler(this, args);
if (ServiceResult.IsBad(args.Error))
{
throw new ServiceResultException(args.Error);
}
return(new OperationContext(requestHeader, requestType, args.Identity));
}
throw new ServiceResultException(StatusCodes.BadSessionIdInvalid);
}
// validate request header.
session.ValidateRequest(requestHeader, requestType);
// return context.
return(new OperationContext(requestHeader, requestType, session));
}
}
catch (Exception e)
{
ServiceResultException sre = e as ServiceResultException;
if (sre != null && sre.StatusCode == StatusCodes.BadSessionNotActivated)
{
if (session != null)
{
CloseSession(session.Id);
}
}
throw new ServiceResultException(e, StatusCodes.BadUnexpectedError);
}
}