private void ProcessResponse(SoapMessage message, Boolean isclient) { MessageProcessor ctx = MessageProcessor.Instance; // if (!MessageProcessor.Enabled) // return; if (Trace.CorrelationManager.ActivityId == Guid.Empty) { Guid newGuid = Guid.NewGuid(); Trace.CorrelationManager.ActivityId = newGuid; } try { AgentMessageTable ctx2 = AgentMessageTable.Instance; AgentMessageTable hashtable = AgentMessageTable.Instance; if (localhashcode == -1) { Logger.warn(this.GetType().FullName + " ProcessResponse unable to local hash reference coresponding request message"); return; } if (isclient && HttpContext.Current == null) //if this is a standalone client processing a response, this is common { MessageCorrelator mc = AgentMessageTable.RemoveMessage(localhashcode); if (mc == null) { Logger.warn( this.GetType().FullName + " ProcessResponse unable to reference coresponding request message"); return; } if (isclient && MessageProcessor.GetConfig.DependencyInjectionEnabled) { IEnumerator it = message.Headers.GetEnumerator(); while (it.MoveNext()) { SoapUnknownHeader e = it.Current as SoapUnknownHeader; if (e != null) { //if (e.Element.Name.Equals(FGSMSSoapHeaderTransactionThreadIdWCF.Name2) && e.Element.NamespaceURI.Equals(FGSMSSoapHeaderTransactionThreadIdWCF.Namespace2)) //{ // mc.threadid = e.Element.InnerText; //} if (e.Element.Name.Equals(FGSMSSoapHeaderRelatedMessageIdWCF.Name2) && e.Element.NamespaceURI.Equals(FGSMSSoapHeaderRelatedMessageIdWCF.Namespace2)) { mc.relatedtransactionid = e.Element.InnerText; } } } } if (String.IsNullOrEmpty(mc.threadid)) { mc.threadid = MessageProcessor.GetTransactionThreadId(Thread.CurrentContext.ContextID.ToString() + Thread.CurrentThread.ManagedThreadId.ToString() + ":" + Thread.GetDomainID().ToString() + Thread.CurrentThread.Name); if (String.IsNullOrEmpty(mc.threadid)) { mc.threadid = Guid.NewGuid().ToString(); } } if (!isclient && MessageProcessor.GetConfig.DependencyInjectionEnabled) { message.Headers.Add(new FGSMSSoapHeaderRelatedMessageASPNET(mc.MessageID)); message.Headers.Add(new FGSMSSoapHeaderTransactionThreadIdASPNET(mc.threadid)); } try { if (String.IsNullOrEmpty(mc.soapAction)) { string action = "urn:undeterminable"; if (action == "urn:undeterminable") { action = message.Action; action = action.Replace("\"", ""); action = action.Replace("'", ""); if (String.IsNullOrEmpty(action)) { action = "urn:undeterminable"; } } if (action == "urn:undeterminable") { action = message.MethodInfo.Name;; action = action.Replace("\"", ""); action = action.Replace("'", ""); if (String.IsNullOrEmpty(action)) { action = "urn:undeterminable"; } } } string ip = ""; try { string myHost = System.Net.Dns.GetHostName(); System.Net.IPAddress[] list = System.Net.Dns.GetHostEntry(myHost).AddressList; for (int i = 0; i < list.Length; i++) { if (!IPAddress.IsLoopback(System.Net.Dns.GetHostEntry(myHost).AddressList[i])) { ip = System.Net.Dns.GetHostEntry(myHost).AddressList[i].ToString(); break; } } } catch { } string user = System.Environment.UserName; mc.identity = new List <string>(); mc.identity.Add(user); // mc.identity.Add(ip); mc.ipaddress = ip; mc.CompletedAt = DateTime.Now; mc.IsFault = AgentSoapExtension.IsFault(message); mc.agenttype = this.GetType().FullName + ".client"; mc.memo = "MsgMap=" + AgentMessageTable.GetSize(); if (mc.ResponseHeaders == null) { mc.ResponseHeaders = new NameValueCollection(); } if (HttpContext.Current != null && HttpContext.Current.Response != null && HttpContext.Current.Response.Headers != null) { mc.ResponseHeaders.Add(HttpContext.Current.Response.Headers); } else { mc.ResponseHeaders.Add("SOAPAction", message.Action); } if (message.OneWay) { mc.ResponseMessage = ""; mc.responsesize = 0; MessageProcessor.ProcessMessage(mc); /* * mc.ipaddress = ip; * MessageProcessor.ProcessMessage(( * url), * start, * DateTime.Now, * action, * req, * "", * localhashcode.ToString(), * AgentSoapExtension.IsFault(message), * null, * ip, this.GetType().FullName + ".client", * user * );*/ } else { mc.responsesize = mc.ResponseMessage.Length; MessageProcessor.ProcessMessage(mc); /* * MessageProcessor.ProcessMessage((url), * start, * DateTime.Now, * action, * req, * //InputMessageToString(message), * StreamtoString(message.Stream), * localhashcode.ToString(), * AgentSoapExtension.IsFault(message), * null, * ip, this.GetType().FullName + ".client", * user * );*/ } } catch (Exception ex) { try { AgentMessageTable.RemoveMessage(localhashcode); } catch { } Logger.error(ex, this.GetType().FullName + " Error caught process response for clients"); } } else { //this is a response from a service, either directly from the service, or a service chaining event and the caller is processing the response try { if (HttpContext.Current == null) { Logger.warn(this.GetType().FullName + " SniiferFilter failure, http context is null, this shouldn't happen please report if you see this message"); } else { // HttpContext.Current.Response.Filter = new SniiferFilter(HttpContext.Current.Response.Filter); HttpContext.Current.Response.Filter = new SniiferFilter(HttpContext.Current.Response.Filter); } // if (FGSMSConstants.log) EventLog.WriteEntry(this.GetType().FullName, "SniiferFilter success to " + System.Web.HttpContext.Current.Request.Url.ToString(), EventLogEntryType.Information); } catch { } } //this may be a good hook for dependency checking //HttpContext.Current.Items.Add( //need to make a container, add it to the context somehow //on each outbound message, grab the context container, add dependency if detected. //on the first inbound connection, setup the context //on an outbound connection, check if it's a request or response //if response, we are done, send dependency tree to the message processor //if request, get the context, add the dependency try { //if (FGSMSConstants.log) EventLog.WriteEntry(this.GetType().FullName, "ProcessOutbound success", EventLogEntryType.Information); } catch { } } catch (Exception ex) { Logger.error(ex, "Process outbound"); } if (!isclient) { try { MessageProcessor.ClearTransactionThreadId(Thread.CurrentContext.ContextID.ToString() + Thread.CurrentThread.ManagedThreadId.ToString() + ":" + Thread.GetDomainID().ToString() + Thread.CurrentThread.Name); } catch { } } else { try { MessageProcessor.ClearTransactionThreadId(Thread.CurrentContext.ContextID.ToString() + Thread.CurrentThread.ManagedThreadId.ToString() + ":" + Thread.GetDomainID().ToString() + Thread.CurrentThread.Name); } catch { } } //PurgeOldMessages(); }
} // end AfterReceiveRequest /// <summary> /// service traffic outbound response /// </summary> /// <param name="reply"></param> /// <param name="correlationState"></param> public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { // object prop; // string requestHeader = null; //Console.WriteLine("In {0}", MethodBase.GetCurrentMethod().Name); WCFContainer w = null; try { try { w = (WCFContainer)correlationState; } catch (Exception ex) { Logger.debug(ex, "can't get reference to the correlation object"); } if (w == null) { Logger.debug("can't get reference to the correlation object"); return; } /****************************** * BEGIN, do not remove this code, there's some kind of strange bug in wcf that causes services using this handler to hang after 10 invocations * unless this code is execute. I believe it's related to obtaining http headers */ /* * if (OperationContext.Current.IncomingMessageProperties.TryGetValue(HttpRequestMessageProperty.Name, out prop)) * { * HttpRequestMessageProperty reqProp = (HttpRequestMessageProperty)prop; * requestHeader = reqProp.Headers["X-MyHeader"]; * // Console.WriteLine("Got the request header: {0}", requestHeader); * } * * if (!OperationContext.Current.OutgoingMessageProperties.TryGetValue(HttpResponseMessageProperty.Name, out prop)) * { * prop = new HttpResponseMessageProperty(); * OperationContext.Current.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, prop); * } * HttpResponseMessageProperty respProp = (HttpResponseMessageProperty)prop; * respProp.Headers["X-MyResponseHeader2"] = "Added from BeforeSendReply - " + requestHeader; * */ /********************************** * END */ } catch (Exception ex) { Logger.debug(ex, "can't get reference to the correlation object"); } //this is usually a ?wsdl request or a null request such a get MessageProcessor ctx = MessageProcessor.Instance; try { string use = string.Empty; use = w.thisid; String action = "urn:undeterminable"; if (w.action != null) { action = w.action; action = action.Replace("\"", ""); action = action.Replace("'", ""); if (String.IsNullOrEmpty(action)) { action = "urn:undeterminable"; } } if (action.Equals("urn:undeterminable") && w.myinboundheaders != null && !String.IsNullOrEmpty(w.myinboundheaders.Headers["SOAPAction"])) // if (System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.Headers != null && // !String.IsNullOrEmpty(System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.Headers.Action)) { action = w.myinboundheaders.Headers["SOAPAction"]; //System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.Headers.Action; action = action.Replace("\"", ""); action = action.Replace("'", ""); if (String.IsNullOrEmpty(action)) { action = "urn:undeterminable"; } } if (action.Equals("urn:undeterminable") && HttpContext.Current != null) { action = HttpContext.Current.Request.Headers.Get("SOAPAction"); action = action.Replace("\"", ""); action = action.Replace("'", ""); if (String.IsNullOrEmpty(action)) { action = "urn:undeterminable"; } } if (action.Equals("urn:undeterminable") && HttpContext.Current != null) { action = HttpContext.Current.Request.HttpMethod; action = action.Replace("\"", ""); action = action.Replace("'", ""); if (String.IsNullOrEmpty(action)) { action = "urn:undeterminable"; } } string ip = string.Empty; NameValueCollection reqheaders = null; if (w.myinboundheaders != null && w.myinboundheaders.Headers != null) { reqheaders = w.myinboundheaders.Headers; } NameValueCollection resheaders = new NameValueCollection(); if (HttpContext.Current != null) { ip = HttpContext.Current.Request.UserHostAddress; resheaders = HttpContext.Current.Response.Headers; reqheaders = HttpContext.Current.Request.Headers; } else { if (OperationContext.Current != null) { try { MessageProperties messageProperties = OperationContext.Current.IncomingMessageProperties; if (w.myinboundheaders == null) { w.myinboundheaders = messageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; } RemoteEndpointMessageProperty endpointProperty = messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; ip = endpointProperty.Address; } catch (Exception ex) { Logger.debug(ex); } if (w.myinboundheaders != null) { if (action.Equals("urn:undeterminable")) { action = w.myinboundheaders.Method + w.myinboundheaders.QueryString; } if (w.myinboundheaders.Headers != null) { reqheaders = w.myinboundheaders.Headers; } } } } if (ip == "127.0.0.1" || ip == "::1") { try { string myHost = System.Net.Dns.GetHostName(); System.Net.IPAddress[] list = System.Net.Dns.GetHostEntry(myHost).AddressList; for (int i = 0; i < list.Length; i++) { if (!IPAddress.IsLoopback(System.Net.Dns.GetHostEntry(myHost).AddressList[i])) { ip = System.Net.Dns.GetHostEntry(myHost).AddressList[i].ToString(); break; } } } catch (Exception ex) { Logger.debug(ex); } } string user = user = w.user; if (resheaders != null && MessageProcessor.GetConfig.DependencyInjectionEnabled) { resheaders.Add(FGSMSConstants.MessageId, use); resheaders.Add(FGSMSConstants.transactionthreadKey, w.thistid); } if (MessageProcessor.GetConfig.DependencyInjectionEnabled)// && !OperationContext.Current.OutgoingMessageProperties.TryGetValue(HttpResponseMessageProperty.Name, out prop)) { HttpResponseMessageProperty respProp = null; try { respProp = (HttpResponseMessageProperty)OperationContext.Current.OutgoingMessageProperties[HttpResponseMessageProperty.Name]; } catch { } if (respProp != null) { respProp.Headers.Add(FGSMSConstants.MessageId, use); respProp.Headers.Add(FGSMSConstants.transactionthreadKey, w.thistid); } if (reply != null && reply.Version != MessageVersion.None) { try { reply.Headers.Add(new FGSMSSoapHeaderRelatedMessageIdWCF(use)); reply.Headers.Add(new FGSMSSoapHeaderTransactionThreadIdWCF(w.thistid)); } catch { } } //else can't add response http headers! } MessageProcessor.ProcessMessage(w.url, //System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.Headers.To.ToString(), w.start, DateTime.Now, action, w.req, //System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.ToString(), MessageHelper.MessagetoString(ref reply), // reply.ToString(), use, (reply == null) ? false : reply.IsFault, HttpContext.Current, ip, this.GetType().FullName, user, "Current .net thread: " + Thread.CurrentThread.ManagedThreadId, //thread id w.thistid, //related transaction (id of the inbound message) w.relatedid, reqheaders, resheaders); } catch (Exception ex) { Logger.error(ex, this.GetType().FullName + " Error from FGSMS WCF Service Agent, BeforeSendReply. This typically means that the message traffic to the url " + w.url + " could not be added the queue: "); } try { MessageProcessor.ClearTransactionThreadId(Thread.CurrentContext.ContextID.ToString() + Thread.CurrentThread.ManagedThreadId.ToString() + ":" + Thread.GetDomainID().ToString() + Thread.CurrentThread.Name); } catch (Exception ex) { Logger.debug(ex); } } // end BeforeSendReply