Exemplo n.º 1
0
        private void ProcessNonInviteResponse(IResponse response)
        {
            /* If a provisional response is received while in the "Trying" state, the
             * response MUST be passed to the TU, and then the client transaction
             * SHOULD move to the "Proceeding" state.
             */
            if (StatusCodeHelper.Is1xx(response))
            {
                _state = TransactionState.Proceeding;
            }

            /* If a final response (status codes 200-699) is received while in the "Trying" state,
             * the response MUST be passed to the TU, and the client transaction MUST transition
             * to the "Completed" state
             *
             * same stuff is stated for proceeding state.
             */
            else
            {
                _state = TransactionState.Completed;

                // Once the client transaction enters the "Completed" state, it MUST set
                // Timer K to fire in T4 seconds for unreliable transports, and zero
                // seconds for reliable transports
                if (_timerK == null)
                {
                    _timerK = new Timer(OnTerminate, null, Timeout.Infinite, Timeout.Infinite);
                }
                _timerK.Change(TransactionManager.T4, Timeout.Infinite);
            }

            ResponseReceived(this, new ResponseEventArgs(response, _endPoint));
        }
Exemplo n.º 2
0
        private Saml2Response(XmlDocument xml)
        {
            xmlDocument = xml;

            id = new Saml2Id(xml.DocumentElement.Attributes["ID"].Value);

            var parsedInResponseTo = xml.DocumentElement.Attributes["InResponseTo"].GetValueIfNotNull();

            if (parsedInResponseTo != null)
            {
                inResponseTo = new Saml2Id(parsedInResponseTo);
            }

            issueInstant = DateTime.Parse(xml.DocumentElement.Attributes["IssueInstant"].Value,
                                          CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);

            var statusString = xml.DocumentElement["Status", Saml2Namespaces.Saml2PName]
                               ["StatusCode", Saml2Namespaces.Saml2PName].Attributes["Value"].Value;

            status = StatusCodeHelper.FromString(statusString);

            statusMessage = xml.DocumentElement["Status", Saml2Namespaces.Saml2PName]
                            ["StatusMessage", Saml2Namespaces.Saml2PName].GetTrimmedTextIfNotNull();

            issuer = new EntityId(xmlDocument.DocumentElement["Issuer", Saml2Namespaces.Saml2Name].GetTrimmedTextIfNotNull());

            var destinationUrlString = xmlDocument.DocumentElement.Attributes["Destination"].GetValueIfNotNull();

            if (destinationUrlString != null)
            {
                destinationUrl = new Uri(destinationUrlString);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// RFC3261 Section 8.1.3.5 Processing 4xx Responses
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private bool Process4xx(IClientTransaction transaction, IResponse response)
        {
            if (!StatusCodeHelper.Is4xx(response))
            {
                return(true);
            }

            // Certain 4xx response codes require specific UA processing,
            // independent of the method.

            // If a 401 (Unauthorized) or 407 (Proxy Authentication Required)
            // response is received, the UAC SHOULD follow the authorization
            // procedures of Section 22.2 and Section 22.3 to retry the request with
            // credentials.
            if (response.StatusCode == StatusCode.Unauthorized)
            {
                var request      = (IRequest)transaction.Request.Clone();
                var authenticate = (Authenticate)response.Headers[Authenticate.WWW_NAME];

                var authorization = new Authorization();
                authorization.Nonce = authenticate.Nonce;
            }

            // If a 413 (Request Entity Too Large) response is received (Section
            // 21.4.11), the request contained a body that was longer than the UAS
            // was willing to accept.  If possible, the UAC SHOULD retry the
            // request, either omitting the body or using one of a smaller length.


            // If a 415 (Unsupported Media Type) response is received (Section
            // 21.4.13), the request contained media types not supported by the UAS.
            // The UAC SHOULD retry sending the request, this time only using
            // content with types listed in the Accept header field in the response,
            // with encodings listed in the Accept-Encoding header field in the
            // response, and with languages listed in the Accept-Language in the
            // response.

            // If a 416 (Unsupported URI Scheme) response is received (Section
            // 21.4.14), the Request-URI used a URI scheme not supported by the
            // server.  The client SHOULD retry the request, this time, using a SIP
            // URI.

            // If a 420 (Bad Extension) response is received (Section 21.4.15), the
            // request contained a Require or Proxy-Require header field listing an
            // option-tag for a feature not supported by a proxy or UAS.  The UAC
            // SHOULD retry the request, this time omitting any extensions listed in
            // the Unsupported header field in the response.

            // In all of the above cases, the request is retried by creating a new
            // request with the appropriate modifications.  This new request
            // constitutes a new transaction and SHOULD have the same value of the
            // Call-ID, To, and From of the previous request, but the CSeq should
            // contain a new sequence number that is one higher than the previous.

            // With other 4xx responses, including those yet to be defined, a retry
            // may or may not be possible depending on the method and the use case.
            _logger.Warning("Failed to handle status code: " + response);
            return(false);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Create a new response.
        /// </summary>
        /// <param name="code">Response status code</param>
        /// <param name="reason">Reason to why the status code was used.</param>
        /// <returns>A Created response.</returns>
        /// <exception cref="InvalidOperationException">Provisional responses is only valid for INVITE method.</exception>
        public IResponse CreateResponse(StatusCode code, string reason)
        {
            if (StatusCodeHelper.Is1xx(code) && Method != "INVITE")
            {
                throw new InvalidOperationException("Provisional responses is only valid for INVITE method.");
            }

            var response = new Response(SipVersion, code, reason);

            // When a 100 (Trying) response is generated, any Timestamp header field
            // present in the request MUST be copied into this 100 (Trying)
            // response.  If there is a delay in generating the response, the UAS
            // SHOULD add a delay value into the Timestamp value in the response.
            // This value MUST contain the difference between the time of sending of
            // the response and receipt of the request, measured in seconds.
            if (StatusCodeHelper.Is1xx(code) && Headers["Timestamp"] != null)
            {
                response.Headers.Add("Timestamp", Headers["Timestamp"]);
            }

            // The From field of the response MUST equal the From header field of
            // the request.  The Call-ID header field of the response MUST equal the
            // Call-ID header field of the request.  The CSeq header field of the
            // response MUST equal the CSeq field of the request.  The Via header
            // field values in the response MUST equal the Via header field values
            // in the request and MUST maintain the same ordering.
            response.From   = From;
            response.CallId = CallId;
            response.CSeq   = CSeq;
            response.Via    = (Via)Via.Clone();


            // If a request contained a To tag in the request, the To header field
            // in the response MUST equal that of the request.  However, if the To
            // header field in the request did not contain a tag, the URI in the To
            // header field in the response MUST equal the URI in the To header
            // field; additionally, the UAS MUST add a tag to the To header field in
            // the response (with the exception of the 100 (Trying) response, in
            // which a tag MAY be present).  This serves to identify the UAS that is
            // responding, possibly resulting in a component of a dialog ID.  The
            // same tag MUST be used for all responses to that request, both final
            // and provisional (again excepting the 100 (Trying)).  Procedures for
            // the generation of tags are defined in Section 19.3.
            response.To = To;
            if (To.Parameters["tag"] != null)
            {
                // RFC3261 Section 17.2.1:
                // The 100 (Trying) response is constructed
                // according to the procedures in Section 8.2.6, except that the
                // insertion of tags in the To header field of the response (when none
                // was present in the request) is downgraded from MAY to SHOULD NOT.
                if (!StatusCodeHelper.Is1xx(code))
                {
                    response.To.Parameters.Add("tag", Guid.NewGuid().ToString().Replace("-", string.Empty));
                }
            }

            return(response);
        }
Exemplo n.º 5
0
        private void ProcessInviteResponse(IResponse response)
        {
            /*
             * If the client transaction receives a provisional response while in
             * the "Calling" state, it transitions to the "Proceeding" state. In the
             * "Proceeding" state, the client transaction SHOULD NOT retransmit the
             * request any longer. Furthermore, the provisional response MUST be
             * passed to the TU.  Any further provisional responses MUST be passed
             * up to the TU while in the "Proceeding" state.
             */
            if (_state == TransactionState.Calling && StatusCodeHelper.Is1xx(response))
            {
                _timerA.Change(Timeout.Infinite, Timeout.Infinite);
                _state = TransactionState.Proceeding;
            }
            else if (_state == TransactionState.Calling || _state == TransactionState.Proceeding)
            {
                /* When in either the "Calling" or "Proceeding" states, reception of a
                 * 2xx response MUST cause the client transaction to enter the
                 * "Terminated" state, and the response MUST be passed up to the TU.
                 */
                if (StatusCodeHelper.Is2xx(response))
                {
                    _state = TransactionState.Terminated;
                }

                /*
                 * When in either the "Calling" or "Proceeding" states, reception of a
                 * response with status code from 300-699 MUST cause the client
                 * transaction to transition to "Completed".
                 *
                 * Report msg and send an ACK back.
                 */
                else if (StatusCodeHelper.Is3456xx(response))
                {
                    _state = TransactionState.Completed;
                    SendAck(response);
                    _timerD.Change(_timerDValue, Timeout.Infinite);
                }

                ResponseReceived(this, new ResponseEventArgs(response, _endPoint));
            }
            else if (_state == TransactionState.Proceeding)
            {
                ResponseReceived(this, new ResponseEventArgs(response, _endPoint));
            }
            else if (_state == TransactionState.Completed)
            {
                /*
                 * Any retransmissions of the final response that are received while in
                 * the "Completed" state MUST cause the ACK to be re-passed to the
                 * transport layer for retransmission, but the newly received response
                 * MUST NOT be passed up to the TU
                 */
                SendAck(response);
            }
        }
Exemplo n.º 6
0
        public void Send(IResponse response)
        {
            // Any other final responses passed by the TU to the server
            // transaction MUST be discarded while in the "Completed" state.
            if (State == TransactionState.Completed || State == TransactionState.Terminated)
            {
                return;
            }

            _response = response;

            // While in the "Trying" state, if the TU passes a provisional response
            // to the server transaction, the server transaction MUST enter the
            // "Proceeding" state.
            if (State == TransactionState.Trying && StatusCodeHelper.Is1xx(response))
            {
                State = TransactionState.Proceeding;
            }

            // The response MUST be passed to the transport
            // layer for transmission.  Any further provisional responses that are
            // received from the TU while in the "Proceeding" state MUST be passed
            // to the transport layer for transmission.

            // If the TU passes a final response (status
            // codes 200-699) to the server while in the "Proceeding" state, the
            // transaction MUST enter the "Completed" state, and the response MUST
            // be passed to the transport layer for transmission.
            if (State == TransactionState.Proceeding)
            {
                if (StatusCodeHelper.Is2xx(response))
                {
                    // retransmissions of 2xx
                    // responses are handled by the TU.  The server transaction MUST then
                    // transition to the "Terminated" state.
                    _transport.Send(response);
                    Terminate(true);
                }
                else if (StatusCodeHelper.Is3456xx(response))
                {
                    _transport.Send(response);
                    State = TransactionState.Completed;
                    if (!response.IsReliableProtocol)
                    {
                        _timerG.Change(TransactionManager.T1, Timeout.Infinite);
                    }
                    _timerH.Change(64 * TransactionManager.T1, Timeout.Infinite);
                }
                if (!StatusCodeHelper.Is1xx(response))
                {
                    State = TransactionState.Completed;
                }
            }

            _response = response;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="xml">Root xml element.</param>
        /// <param name="expectedInResponseTo">The expected value of the
        /// InReplyTo parameter in the message.</param>
        /// <param name="options">Service provider settings used when validating Saml response</param>
        public Saml2Response(XmlElement xml, Saml2Id expectedInResponseTo, IOptions options)
        {
            if (xml == null)
            {
                throw new ArgumentNullException(nameof(xml));
            }

            if (xml.LocalName != "Response" ||
                xml.NamespaceURI != Saml2Namespaces.Saml2P)
            {
                throw new XmlException("Expected a SAML2 assertion document");
            }

            if (xml.Attributes["Version"].Value != "2.0")
            {
                throw new XmlException("Wrong or unsupported SAML2 version");
            }

            xmlElement = xml;

            id = new Saml2Id(xml.GetRequiredAttributeValue("ID"));

            ReadAndValidateInResponseTo(xml, expectedInResponseTo, options);

            issueInstant = DateTime.Parse(xml.GetRequiredAttributeValue("IssueInstant"),
                                          CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);

            var statusElement     = xml.GetRequiredElement("Status", Saml2Namespaces.Saml2PName);
            var statusCodeElement = statusElement.GetRequiredElement("StatusCode", Saml2Namespaces.Saml2PName);
            var statusString      = statusCodeElement.GetRequiredAttributeValue("Value");

            status = StatusCodeHelper.FromString(statusString);

            statusMessage = statusElement
                            ["StatusMessage", Saml2Namespaces.Saml2PName].GetTrimmedTextIfNotNull();
            if (statusCodeElement["StatusCode", Saml2Namespaces.Saml2PName] != null)
            {
                secondLevelStatus = statusCodeElement["StatusCode", Saml2Namespaces.Saml2PName].Attributes["Value"]
                                    .Value;
            }

            Issuer = new EntityId(xmlElement["Issuer", Saml2Namespaces.Saml2Name].GetTrimmedTextIfNotNull());

            var destinationUrlString = xmlElement.Attributes["Destination"].GetValueIfNotNull();

            if (destinationUrlString != null)
            {
                Uri parsedDestination;
                if (!Uri.TryCreate(destinationUrlString, UriKind.Absolute, out parsedDestination))
                {
                    throw new BadFormatSamlResponseException("Destination value was not a valid Uri");
                }

                DestinationUrl = parsedDestination;
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="xml">Root xml element.</param>
        /// <param name="relayState"></param>
        public Saml2Response(XmlElement xml, string relayState)
        {
            if (xml == null)
            {
                throw new ArgumentNullException(nameof(xml));
            }

            if (xml.LocalName != "Response" ||
                xml.NamespaceURI != Saml2Namespaces.Saml2P)
            {
                throw new XmlException("Expected a SAML2 assertion document");
            }

            if (xml.Attributes["Version"].Value != "2.0")
            {
                throw new XmlException("Wrong or unsupported SAML2 version");
            }

            xmlElement = xml;
            RelayState = relayState;

            id = new Saml2Id(xml.Attributes["ID"].Value);

            var parsedInResponseTo = xml.Attributes["InResponseTo"].GetValueIfNotNull();

            if (parsedInResponseTo != null)
            {
                InResponseTo = new Saml2Id(parsedInResponseTo);
            }

            issueInstant = DateTime.Parse(xml.Attributes["IssueInstant"].Value,
                                          CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);

            var statusString = xml["Status", Saml2Namespaces.Saml2PName]
                               ["StatusCode", Saml2Namespaces.Saml2PName].Attributes["Value"].Value;

            status = StatusCodeHelper.FromString(statusString);

            statusMessage = xml["Status", Saml2Namespaces.Saml2PName]
                            ["StatusMessage", Saml2Namespaces.Saml2PName].GetTrimmedTextIfNotNull();
            if (xml["Status", Saml2Namespaces.Saml2PName]["StatusCode", Saml2Namespaces.Saml2PName]["StatusCode", Saml2Namespaces.Saml2PName] != null)
            {
                secondLevelStatus = xml["Status", Saml2Namespaces.Saml2PName]["StatusCode", Saml2Namespaces.Saml2PName]["StatusCode", Saml2Namespaces.Saml2PName].Attributes["Value"].Value;
            }

            Issuer = new EntityId(xmlElement["Issuer", Saml2Namespaces.Saml2Name].GetTrimmedTextIfNotNull());

            var destinationUrlString = xmlElement.Attributes["Destination"].GetValueIfNotNull();

            if (destinationUrlString != null)
            {
                DestinationUrl = new Uri(destinationUrlString);
            }
        }
Exemplo n.º 9
0
        protected ActionResult <T> RespInnerTyped <T>(T responseVM) where T : BaseResponseVm
        {
            var logger = WebImpactLogger.CreateLogger();

            if (logger.IsEnabled(LogLevel.Debug))
            {
                string message = JsonConvert.SerializeObject((object)responseVM);
                logger.LogDebug(message);
            }
            return(this.StatusCode(StatusCodeHelper.GetIntStatusCodeForResponse(responseVM), (object)responseVM));
        }
Exemplo n.º 10
0
 /// <summary>
 /// Appends xml for the Saml2LogoutResponse to the given parent node.
 /// </summary>
 /// <param name="parentNode">Xml for the Saml2LogoutResponse is appended
 /// to the children of this node.</param>
 public void AppendTo(XmlNode parentNode)
 {
     parentNode.StartElement("LogoutResponse", Saml2Namespaces.Saml2PUri)
     .AddAttribute("ID", Id.Value)
     .AddAttribute("Version", "2.0")
     .AddAttribute("IssueInstant", IssueInstant.ToSaml2DateTimeString())
     .AddAttributeIfNotNull("InResponseTo", InResponseTo?.Value)
     .AddAttributeIfNotNull("Destination", DestinationUrl?.OriginalString)
     .If(Issuer != null, x => x.AddElement("Issuer", Saml2Namespaces.Saml2Uri, Issuer.Id))
     .StartElement("Status", Saml2Namespaces.Saml2PUri)
     .StartElement("StatusCode", Saml2Namespaces.Saml2PUri)
     .AddAttribute("Value", StatusCodeHelper.FromCode(Status));
 }
Exemplo n.º 11
0
        /// <summary>
        /// Load values into
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static Saml2LogoutResponse FromXml(XmlElement xml)
        {
            if (xml == null)
            {
                throw new ArgumentNullException(nameof(xml));
            }

            var status = StatusCodeHelper.FromString(
                xml["Status", Saml2Namespaces.Saml2PName]
                ["StatusCode", Saml2Namespaces.Saml2PName]
                .GetAttribute("Value"));

            return(new Saml2LogoutResponse(status));
        }
Exemplo n.º 12
0
        private void CreateXmlDocument()
        {
            var xml = new XmlDocument();

            xml.AppendChild(xml.CreateXmlDeclaration("1.0", null, null));

            var responseElement = xml.CreateElement("saml2p", "Response", Saml2Namespaces.Saml2PName);

            if (DestinationUrl != null)
            {
                responseElement.SetAttributeNode("Destination", "").Value = DestinationUrl.ToString();
            }

            responseElement.SetAttributeNode("ID", "").Value           = id.Value;
            responseElement.SetAttributeNode("Version", "").Value      = "2.0";
            responseElement.SetAttributeNode("IssueInstant", "").Value =
                DateTime.UtcNow.ToSaml2DateTimeString();
            if (InResponseTo != null)
            {
                responseElement.SetAttributeNode("InResponseTo", "").Value = InResponseTo.Value;
            }
            xml.AppendChild(responseElement);

            var issuerElement = xml.CreateElement("saml2", "Issuer", Saml2Namespaces.Saml2Name);

            issuerElement.InnerText = issuer.Id;
            responseElement.AppendChild(issuerElement);

            var statusElement     = xml.CreateElement("saml2p", "Status", Saml2Namespaces.Saml2PName);
            var statusCodeElement = xml.CreateElement("saml2p", "StatusCode", Saml2Namespaces.Saml2PName);

            statusCodeElement.SetAttributeNode("Value", "").Value = StatusCodeHelper.FromCode(Status);
            statusElement.AppendChild(statusCodeElement);
            responseElement.AppendChild(statusElement);

            foreach (var ci in claimsIdentities)
            {
                responseElement.AppendChild(xml.ReadNode(
                                                ci.ToSaml2Assertion(issuer).ToXElement().CreateReader()));
            }

            xmlDocument = xml;

            xml.Sign(issuerCertificate);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="xml">Parsed XML with message.</param>
        public Saml2ArtifactResponse(XmlElement xml)
        {
            if (xml == null)
            {
                throw new ArgumentNullException(nameof(xml));
            }

            Status = StatusCodeHelper.FromString(
                xml["Status", Saml2Namespaces.Saml2PName]
                ["StatusCode", Saml2Namespaces.Saml2PName]
                .GetAttribute("Value"));

            if (Status == Saml2StatusCode.Success)
            {
                message = xml.ChildNodes.OfType <XmlElement>()
                          .SkipWhile(x => x.LocalName != "Status")
                          .Skip(1).Single();
            }
        }
Exemplo n.º 14
0
        public void Send(IResponse response)
        {
            // Any other final responses passed by the TU to the server
            // transaction MUST be discarded while in the "Completed" state
            if (!StatusCodeHelper.Is1xx(response) && State == TransactionState.Completed)
            {
                return;
            }
            if (State == TransactionState.Terminated)
            {
                return;
            }

            _response = response;
            if (State == TransactionState.Trying)
            {
                if (StatusCodeHelper.Is1xx(response))
                {
                    State = TransactionState.Proceeding;
                }
            }
            else if (State == TransactionState.Proceeding)
            {
                if (StatusCodeHelper.Is1xx(response))
                {
                    _transport.Send(response);
                }
                else
                {
                    State = TransactionState.Completed;
                    if (!_request.IsReliableProtocol)
                    {
                        _timerJ.Change(TransactionManager.T1 * 64, Timeout.Infinite);
                    }
                    else
                    {
                        _timerJ.Change(0, Timeout.Infinite);
                    }
                }
            }
            _transport.Send(response);
        }
        private async Task WriteExceptionToResponse(Exception ex, HttpContext httpContext)
        {
            var responseVM = new BaseResponseVm(ex);

            if (ex is WebImpactExternalResourceException externalException)
            {
                if (externalException.WebImpactDebugInfo is BaseResponseVm webImpactResponse)
                {
                    responseVM.SystemErrorMessage += "/////" + webImpactResponse.SystemErrorMessage;
                    responseVM.SystemErrorStack   += "/////" + webImpactResponse.SystemErrorStack;
                    responseVM.SystemMessage      += "/////" + webImpactResponse.SystemMessage;
                    responseVM.Result              = webImpactResponse.Result;
                }
                else
                {
                    responseVM.SystemMessage = JsonConvert.SerializeObject(externalException.WebImpactDebugInfo, new JsonSerializerSettings {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                    });
                }

                responseVM.DebugInfo = new
                {
                    Request  = externalException.RequestData,
                    Response = externalException.WebImpactDebugInfo
                };
            }

            // httpContext.Response.Clear(); // Do not clear headers to support CORS

            var calculatedStatusCode = StatusCodeHelper.GetIntStatusCodeForResponse(responseVM);

            if (httpContext.Response.StatusCode != calculatedStatusCode)
            {
                httpContext.Response.StatusCode = calculatedStatusCode;
            }

            httpContext.Response.ContentType = "application/json";

            var response = JsonConvert.SerializeObject(responseVM, _jsonSettings);

            await httpContext.Response.WriteAsync(response);
        }
Exemplo n.º 16
0
        public override XElement ToXElement()
        {
            var xe = new XElement(Saml2Namespaces.Saml2P + "LogoutResponse",
                                  new XAttribute("ID", Id.Value),
                                  new XAttribute("Version", "2.0"),
                                  new XAttribute("IssueInstant", IssueInstant.ToSaml2DateTimeString()),
                                  new XElement(Saml2Namespaces.Saml2P + "Status",
                                               new XElement(Saml2Namespaces.Saml2P + "StatusCode",
                                                            new XAttribute("Value", StatusCodeHelper.FromCode(Status)))));

            if (Issuer != null)
            {
                xe.AddFirst(new XElement(Saml2Namespaces.Saml2 + "Issuer", Issuer.Id));
            }

            xe.AddAttributeIfNotNullOrEmpty("InResponseTo", InResponseTo?.Value);
            xe.AddAttributeIfNotNullOrEmpty("Destination", DestinationUrl?.OriginalString);

            return(xe);
        }
Exemplo n.º 17
0
        public async Task <dynamic> GetPieChartData(string id, int run)
        {
            if (string.IsNullOrWhiteSpace(id) || run <= 0)
            {
                return(NotFound());
            }

            var result = await _dataStoreSvr.GetStatusCodePieData(id, run);

            var data   = new List <decimal>();
            var colour = new List <string>();
            var labels = new List <string>();

            foreach (var item in result)
            {
                data.Add(item.StatusCodePercent);
                colour.Add(StatusCodeHelper.GetColour(item.StatusCode));
                labels.Add(StatusCodeHelper.GetStatusCodeString(item.StatusCode));
            }

            var json = new
            {
                datasets = new[]
                {
                    new
                    {
                        data            = data.ToArray(),
                        backgroundColor = colour.ToArray()
                    }
                },

                labels = labels.ToArray()
            };

            return(json);
        }
Exemplo n.º 18
0
        public bool Process(IResponse response, EndPoint endPoint)
        {
            if (State == TransactionState.Terminated)
            {
                return(false); // Ignore everything in terminated until we get disposed.
            }

            /*
             *             If the client transaction receives a provisional response while in
             *             the "Calling" state, it transitions to the "Proceeding" state. In the
             *             "Proceeding" state, the client transaction SHOULD NOT retransmit the
             *             request any longer. Furthermore, the provisional response MUST be
             *             passed to the TU.  Any further provisional responses MUST be passed
             *             up to the TU while in the "Proceeding" state.
             */
            if (State == TransactionState.Calling && StatusCodeHelper.Is1xx(response))
            {
                _timerA.Change(Timeout.Infinite, Timeout.Infinite);
                State = TransactionState.Proceeding;
            }
            else if (State == TransactionState.Calling || State == TransactionState.Proceeding)
            {
                bool changeTimerD = false;

                /* When in either the "Calling" or "Proceeding" states, reception of a
                 * 2xx response MUST cause the client transaction to enter the
                 * "Terminated" state, and the response MUST be passed up to the TU.
                 */
                if (StatusCodeHelper.Is2xx(response))
                {
                    State = TransactionState.Terminated;
                }

                /*
                 * When in either the "Calling" or "Proceeding" states, reception of a
                 * response with status code from 300-699 MUST cause the client
                 * transaction to transition to "Completed".
                 *
                 * Report msg and send an ACK back.
                 */
                else if (StatusCodeHelper.Is3456xx(response))
                {
                    State = TransactionState.Completed;
                    SendAck(response);
                    changeTimerD = true;
                }

                ResponseReceived(this, new ResponseEventArgs(response, endPoint));

                //triggering it here instead of in the if clause to make sure
                // that response have been processed successfully first.
                if (changeTimerD)
                {
                    _timerD.Change(_timerDValue, Timeout.Infinite);
                }
            }
            else if (State == TransactionState.Completed)
            {
                /*
                 * Any retransmissions of the final response that are received while in
                 * the "Completed" state MUST cause the ACK to be re-passed to the
                 * transport layer for retransmission, but the newly received response
                 * MUST NOT be passed up to the TU
                 */
                SendAck(response);
            }

            return(true);
        }
Exemplo n.º 19
0
    /// <summary>
    /// Invokes the <see cref="HttpLoggingMiddleware" />.
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task Invoke(HttpContext context)
    {
        var options = _options.CurrentValue;

        var elements = new string[_fieldsLength];
        var additionalHeaderElements = new string[_additionalRequestHeaders.Count];

        // Whether any of the requested fields actually had content
        bool shouldLog = false;

        var now       = DateTime.UtcNow;
        var stopWatch = ValueStopwatch.StartNew();

        if (options.LoggingFields.HasFlag(W3CLoggingFields.Date))
        {
            shouldLog |= AddToList(elements, _dateIndex, now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
        }

        if (options.LoggingFields.HasFlag(W3CLoggingFields.Time))
        {
            shouldLog |= AddToList(elements, _timeIndex, now.ToString("HH:mm:ss", CultureInfo.InvariantCulture));
        }

        if (options.LoggingFields.HasFlag(W3CLoggingFields.ServerName))
        {
            _serverName ??= Environment.MachineName;
            shouldLog |= AddToList(elements, _serverNameIndex, _serverName);
        }

        if ((W3CLoggingFields.ConnectionInfoFields & options.LoggingFields) != W3CLoggingFields.None)
        {
            var connectionInfo = context.Connection;

            if (options.LoggingFields.HasFlag(W3CLoggingFields.ClientIpAddress))
            {
                shouldLog |= AddToList(elements, _clientIpIndex, connectionInfo.RemoteIpAddress is null ? "" : connectionInfo.RemoteIpAddress.ToString());
            }

            if (options.LoggingFields.HasFlag(W3CLoggingFields.ServerIpAddress))
            {
                shouldLog |= AddToList(elements, _serverIpIndex, connectionInfo.LocalIpAddress is null ? "" : connectionInfo.LocalIpAddress.ToString());
            }

            if (options.LoggingFields.HasFlag(W3CLoggingFields.ServerPort))
            {
                shouldLog |= AddToList(elements, _serverPortIndex, connectionInfo.LocalPort.ToString(CultureInfo.InvariantCulture));
            }
        }

        if ((W3CLoggingFields.Request & options.LoggingFields) != W3CLoggingFields.None)
        {
            var request = context.Request;

            if (options.LoggingFields.HasFlag(W3CLoggingFields.ProtocolVersion))
            {
                shouldLog |= AddToList(elements, _protocolVersionIndex, request.Protocol);
            }

            if (options.LoggingFields.HasFlag(W3CLoggingFields.Method))
            {
                shouldLog |= AddToList(elements, _methodIndex, request.Method);
            }

            if (options.LoggingFields.HasFlag(W3CLoggingFields.UriStem))
            {
                shouldLog |= AddToList(elements, _uriStemIndex, (request.PathBase + request.Path).ToUriComponent());
            }

            if (options.LoggingFields.HasFlag(W3CLoggingFields.UriQuery))
            {
                shouldLog |= AddToList(elements, _uriQueryIndex, request.QueryString.Value);
            }

            if ((W3CLoggingFields.RequestHeaders & options.LoggingFields) != W3CLoggingFields.None)
            {
                if (options.LoggingFields.HasFlag(W3CLoggingFields.Host))
                {
                    if (request.Headers.TryGetValue(HeaderNames.Host, out var host))
                    {
                        shouldLog |= AddToList(elements, _hostIndex, host.ToString());
                    }
                }

                if (options.LoggingFields.HasFlag(W3CLoggingFields.Referer))
                {
                    if (request.Headers.TryGetValue(HeaderNames.Referer, out var referer))
                    {
                        shouldLog |= AddToList(elements, _refererIndex, referer.ToString());
                    }
                }

                if (options.LoggingFields.HasFlag(W3CLoggingFields.UserAgent))
                {
                    if (request.Headers.TryGetValue(HeaderNames.UserAgent, out var agent))
                    {
                        shouldLog |= AddToList(elements, _userAgentIndex, agent.ToString());
                    }
                }

                if (options.LoggingFields.HasFlag(W3CLoggingFields.Cookie))
                {
                    if (request.Headers.TryGetValue(HeaderNames.Cookie, out var cookie))
                    {
                        shouldLog |= AddToList(elements, _cookieIndex, cookie.ToString());
                    }
                }
            }
        }

        if (_additionalRequestHeaders.Count != 0)
        {
            var additionalRequestHeaders = _additionalRequestHeaders.ToList();

            for (var i = 0; i < additionalRequestHeaders.Count; i++)
            {
                if (context.Request.Headers.TryGetValue(additionalRequestHeaders[i], out var headerValue))
                {
                    shouldLog |= AddToList(additionalHeaderElements, i, headerValue.ToString());
                }
            }
        }

        var response = context.Response;

        try
        {
            await _next(context);
        }
        catch
        {
            // Write the log
            if (shouldLog)
            {
                _w3cLogger.Log(elements, additionalHeaderElements);
            }
            throw;
        }

        if (options.LoggingFields.HasFlag(W3CLoggingFields.UserName))
        {
            shouldLog |= AddToList(elements, _userNameIndex, context.User?.Identity?.Name ?? "");
        }

        if (options.LoggingFields.HasFlag(W3CLoggingFields.ProtocolStatus))
        {
            shouldLog |= AddToList(elements, _protocolStatusIndex, StatusCodeHelper.ToStatusString(response.StatusCode));
        }

        if (options.LoggingFields.HasFlag(W3CLoggingFields.TimeTaken))
        {
            shouldLog |= AddToList(elements, _timeTakenIndex, stopWatch.GetElapsedTime().TotalMilliseconds.ToString(CultureInfo.InvariantCulture));
        }

        // Write the log
        if (shouldLog)
        {
            _w3cLogger.Log(elements, additionalHeaderElements);
        }
    }
Exemplo n.º 20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="type"></param>
        /// <param name="controller"></param>
        /// <param name="action"></param>
        /// <param name="thread"></param>
        /// <param name="level"></param>
        /// <param name="logger"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="requestor"></param>
        /// <param name="requestTime"></param>
        /// <param name="responseMillis"></param>
        /// <param name="statusCode"></param>
        /// <param name="method"></param>
        /// <param name="path"></param>
        /// <param name="queryString"></param>
        /// <param name="requestBody"></param>
        /// <param name="responseBody"></param>
        /// <param name="appname"></param>
        /// <remarks>https://salslab.com/a/safely-logging-api-requests-and-responses-in-asp-net-core</remarks>
        public void AddApiLog(string type, string controller, string action,
                              string thread, string level, string logger,
                              string message, string exception,
                              string requestor,
                              DateTime?requestTime,
                              long responseMillis,
                              int statusCode,
                              string method,
                              string path,
                              string queryString,
                              string requestBody,
                              string responseBody,
                              string appname)
        {
            if (path.ToLower().Contains("/account/authenticate"))
            {
                requestBody = "(Request logging disabled for /api/v1/account/authenticate)";
                if (StatusCodeHelper.IsStatusOK(statusCode))
                {
                    //If the request was in the 200's then disable the response log.
                    responseBody = "(Response logging disabled for /api/v1/account/authenticate)";
                }
                else
                {
                    //Log the failed response message.
                }
            }

            if (requestBody?.ToLower().Contains("password") ?? false)
            {
                requestBody = "(Request logging disabled for body containing the word 'password')";
            }

            if (requestBody?.Length > 100)
            {
                requestBody = $"(Truncated to 100 chars) {requestBody.Substring(0, 100)}";
            }

            if (responseBody?.Length > 100)
            {
                responseBody = $"(Truncated to 100 chars) {responseBody.Substring(0, 100)}";
            }

            if (queryString.Length > 100)
            {
                queryString = $"(Truncated to 100 chars) {queryString.Substring(0, 100)}";
            }

            _apiService.spLogInsert(type, controller, action,
                                    thread, level, logger,
                                    message, exception,
                                    requestor,
                                    requestTime,
                                    responseMillis,
                                    statusCode,
                                    method,
                                    path,
                                    queryString,
                                    requestBody,
                                    responseBody,
                                    appname);
        }
Exemplo n.º 21
0
        /// <summary>
        /// Create a dialog from as an user agent server.
        /// </summary>
        /// <param name="transaction"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        /// <remarks>
        /// Described in RFC3261 Section 12.1.1 UAS behavior
        /// </remarks>
        private Dialog CreateServerDialog(IServerTransaction transaction, IResponse response)
        {
            if (!transaction.Request.To.HasParameter("tag") && StatusCodeHelper.Is1xx(response))
            {
                _logger.Debug("Request do not have a to tag, ignoring response " + response + " for request " +
                              transaction.Request);
                return(null);
            }

            // See RFC3261 Section 12.1 Creation of a Dialog
            if (StatusCodeHelper.Is3456xx(response))
            {
                _logger.Warning("Error response: " + response + " to request " + transaction.Request);
                return(null);
            }

            // RFC 3261 Section 12.1.2
            var dialog = new Dialog();

            // If the request was sent over TLS, and the Request-URI contained a SIPS URI,
            // the "secure" flag is set to TRUE.
            dialog.IsSecure = transaction.Request.Uri.Scheme == "sips";

            //The route set MUST be set to the list of URIs in the Record-Route
            //header field from the request, taken in order and preserving all URI
            //parameters.  If no Record-Route header field is present in the
            //request, the route set MUST be set to the empty set.  This route set,
            //even if empty, overrides any pre-existing route set for future
            //requests in this dialog.
            dialog.RouteSet = response.Headers.Contains(Route.RECORD_ROUTE_LNAME)
                                  ? CopyAndReverse((Route)response.Headers[Route.RECORD_ROUTE_LNAME])
                                  : new Route("Route");


            // The remote target MUST be set to the URI
            //from the Contact header field of the response.
            dialog.RemoteTarget = response.Contact;

            //   The remote sequence number MUST be set to the value of the sequence
            //   number in the CSeq header field of the request.  The local sequence
            //   number MUST be empty.
            dialog.LocalSequenceNumber  = transaction.Request.CSeq.Number;
            dialog.RemoteSequenceNumber = 0;


            // The call identifier component of the dialog ID
            //   MUST be set to the value of the Call-ID in the request.  The local
            //   tag component of the dialog ID MUST be set to the tag in the To field
            //   in the response to the request (which always includes a tag), and the
            //   remote tag component of the dialog ID MUST be set to the tag from the
            //   From field in the request.  A UAS MUST be prepared to receive a
            //   request without a tag in the From field, in which case the tag is
            //   considered to have a value of null.
            dialog.CallId    = transaction.Request.CallId;
            dialog.LocalTag  = transaction.Request.To.Parameters["tag"];
            dialog.RemoteTag = response.From.Parameters["tag"];

            // The remote URI MUST be set to the URI in the From field, and the
            // local URI MUST be set to the URI in the To field.
            dialog.RemoteUri = transaction.Request.From.Uri;
            dialog.LocalUri  = transaction.Request.To.Uri;

            dialog.Id = response.CallId + "-" + (response.To.Parameters["tag"] ?? string.Empty) + "-" +
                        (response.From.Parameters["tag"] ?? string.Empty);

            return(dialog);
        }
Exemplo n.º 22
0
        private bool Process3xx(IResponse response)
        {
            if (!StatusCodeHelper.IsRedirected(response))
            {
                return(true);
            }

            // Upon receipt of a redirection response (for example, a 301 response
            // status code), clients SHOULD use the URI(s) in the Contact header
            // field to formulate one or more new requests based on the redirected
            // request.  This process is similar to that of a proxy recursing on a
            // 3xx class response as detailed in Sections 16.5 and 16.6.  A client
            // starts with an initial target set containing exactly one URI, the
            // Request-URI of the original request.  If a client wishes to formulate
            // new requests based on a 3xx class response to that request, it places
            // the URIs to try into the target set.  Subject to the restrictions in
            // this specification, a client can choose which Contact URIs it places
            // into the target set.  As with proxy recursion, a client processing
            // 3xx class responses MUST NOT add any given URI to the target set more
            // than once.  If the original request had a SIPS URI in the Request-
            // URI, the client MAY choose to recurse to a non-SIPS URI, but SHOULD
            // inform the user of the redirection to an insecure URI.


            //    Any new request may receive 3xx responses themselves containing
            //    the original URI as a contact.  Two locations can be configured to
            //    redirect to each other.  Placing any given URI in the target set
            //    only once prevents infinite redirection loops.

            // As the target set grows, the client MAY generate new requests to the
            // URIs in any order.  A common mechanism is to order the set by the "q"
            // parameter value from the Contact header field value.  Requests to the
            // URIs MAY be generated serially or in parallel.  One approach is to
            // process groups of decreasing q-values serially and process the URIs
            // in each q-value group in parallel.  Another is to perform only serial
            // processing in decreasing q-value order, arbitrarily choosing between
            // contacts of equal q-value.

            // If contacting an address in the list results in a failure, as defined
            // in the next paragraph, the element moves to the next address in the
            // list, until the list is exhausted.  If the list is exhausted, then
            // the request has failed.

            // Failures SHOULD be detected through failure response codes (codes
            // greater than 399); for network errors the client transaction will
            // report any transport layer failures to the transaction user.  Note
            // that some response codes (detailed in 8.1.3.5) indicate that the
            // request can be retried; requests that are reattempted should not be
            // considered failures.

            // When a failure for a particular contact address is received, the
            // client SHOULD try the next contact address.  This will involve
            // creating a new client transaction to deliver a new request.

            // In order to create a request based on a contact address in a 3xx
            // response, a UAC MUST copy the entire URI from the target set into the
            // Request-URI, except for the "method-param" and "header" URI
            // parameters (see Section 19.1.1 for a definition of these parameters).
            // It uses the "header" parameters to create header field values for the
            // new request, overwriting header field values associated with the
            // redirected request in accordance with the guidelines in Section
            // 19.1.5.

            // Note that in some instances, header fields that have been
            // communicated in the contact address may instead append to existing
            // request header fields in the original redirected request.  As a
            // general rule, if the header field can accept a comma-separated list
            // of values, then the new header field value MAY be appended to any
            // existing values in the original redirected request.  If the header
            // field does not accept multiple values, the value in the original
            // redirected request MAY be overwritten by the header field value
            // communicated in the contact address.  For example, if a contact
            // address is returned with the following value:

            //    sip:user@host?Subject=foo&Call-Info=<http://www.foo.com>

            // Then any Subject header field in the original redirected request is
            // overwritten, but the HTTP URL is merely appended to any existing
            // Call-Info header field values.

            // It is RECOMMENDED that the UAC reuse the same To, From, and Call-ID
            // used in the original redirected request, but the UAC MAY also choose
            // to update the Call-ID header field value for new requests, for
            // example.

            // Finally, once the new request has been constructed, it is sent using
            // a new client transaction, and therefore MUST have a new branch ID in
            // the top Via field as discussed in Section 8.1.1.7.

            // In all other respects, requests sent upon receipt of a redirect
            // response SHOULD re-use the header fields and bodies of the original
            // request.

            // In some instances, Contact header field values may be cached at UAC
            // temporarily or permanently depending on the status code received and
            // the presence of an expiration interval; see Sections 21.3.2 and
            // 21.3.3.
            return(false);
        }