From a2902ff6d54258ce41bdd4759bb150f9f6114ccf Mon Sep 17 00:00:00 2001 From: "madhavan.jagannathan" Date: Thu, 17 Mar 2016 13:02:18 +0530 Subject: [PATCH] Handling base64 encoding in swql studio --- Src/Contract/InfoServiceDefaultBehaviour.cs | 61 +++++++++++++++++++ Src/Contract/InfoServiceProxy.cs | 1 + .../InformationServiceDataReader.cs | 25 ++++++-- ...arWinds.InformationService.Contract.csproj | 1 + 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 Src/Contract/InfoServiceDefaultBehaviour.cs diff --git a/Src/Contract/InfoServiceDefaultBehaviour.cs b/Src/Contract/InfoServiceDefaultBehaviour.cs new file mode 100644 index 000000000..6dc67789c --- /dev/null +++ b/Src/Contract/InfoServiceDefaultBehaviour.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Text; + +namespace SolarWinds.InformationService.Contract2 +{ + class InfoServiceDefaultBehaviour : IEndpointBehavior, IClientMessageInspector + { + private static readonly IDictionary _defaultHeaderValue = new Dictionary() + { + { "IsBase64EncodingAccepted", true } + }; + + #region IEndpointBehavior Members + + public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) + { + } + + public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) + { + clientRuntime.MessageInspectors.Add(this); + } + + public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) + { + throw new NotImplementedException(); + } + + public void Validate(ServiceEndpoint endpoint) + { + } + + #endregion + + #region IClientMessageInspector Members + + public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) + { + } + + public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) + { + foreach (var kv in _defaultHeaderValue) + { + if (request.Headers.FindHeader(kv.Key, Constants.Namespace) == -1) + { + request.Headers.Add(MessageHeader.CreateHeader(kv.Key, Constants.Namespace, kv.Value)); + } + } + + return null; + } + + #endregion + } +} diff --git a/Src/Contract/InfoServiceProxy.cs b/Src/Contract/InfoServiceProxy.cs index 73fd72d75..da307fa46 100644 --- a/Src/Contract/InfoServiceProxy.cs +++ b/Src/Contract/InfoServiceProxy.cs @@ -176,6 +176,7 @@ private void CorrectChannelFactory() // ???: how can I detect that channel binding is securited _activityMonitor = new InfoServiceActivityMonitor(); + _channelFactory.Endpoint.Behaviors.Add(new InfoServiceDefaultBehaviour()); _channelFactory.Endpoint.Behaviors.Add(_activityMonitor); } diff --git a/Src/Contract/InformationServiceClient/InformationServiceDataReader.cs b/Src/Contract/InformationServiceClient/InformationServiceDataReader.cs index 1978e9062..db3f8668a 100644 --- a/Src/Contract/InformationServiceClient/InformationServiceDataReader.cs +++ b/Src/Contract/InformationServiceClient/InformationServiceDataReader.cs @@ -308,6 +308,8 @@ private enum ParserState private List columns; private int currentColumnOrdinal; private bool currentColumnDBNull; + private bool currentColumnEncoded; + private string currentColumnEncodingType; private object[] values; private List arrayColumnValues = new List(); private bool closed = false; @@ -319,6 +321,10 @@ private enum ParserState internal const string DBNullPrefix = "xsi"; internal const string DBNullAttribute = "nil"; internal const string DBNullValue = "true"; + internal const string DBBase64 = "Base64"; + + internal const string IsEncodedAttribute = "isEncoded"; + internal const string EncodingTypeAttribute = "encodingType"; public List Errors { get; private set; } @@ -544,9 +550,6 @@ public override bool Read() if (this.closed) throw new InvalidOperationException("DataReader is closed"); - if (!this.hasRows) - return false; - return ReadNextEntity(); } @@ -760,7 +763,10 @@ private bool ReadNextEntity() return false; case ParserState.Root: - ValidateEndElement(reader.LocalName, "queryResult", ParserState.Errors); + if (hasRows) + ValidateEndElement(reader.LocalName, "queryResult", ParserState.Errors); + else + return false; break; case ParserState.Data: @@ -855,6 +861,9 @@ private void BeginColumn(XmlReader reader) string dbNullAtt = reader.GetAttribute(DBNullAttribute, DBNullNamespace); this.currentColumnDBNull = (!string.IsNullOrEmpty(dbNullAtt) && dbNullAtt.CompareTo(DBNullValue) == 0); + bool.TryParse(reader.GetAttribute(IsEncodedAttribute), out this.currentColumnEncoded); + this.currentColumnEncodingType = this.currentColumnEncoded ? reader.GetAttribute(EncodingTypeAttribute) : string.Empty; + ColumnInfo columnInfo = this.columns[this.currentColumnOrdinal]; if (columnInfo.IsArray) this.state = ParserState.ArrayColumn; @@ -911,6 +920,13 @@ private object DeserializeScalarValue(string value, EntityPropertyType columnTyp { switch (columnType) { + case EntityPropertyType.String: + if (this.currentColumnEncoded) + { + if (DBBase64.Equals(this.currentColumnEncodingType, StringComparison.OrdinalIgnoreCase)) + value = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(value)); + } + return Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture); case EntityPropertyType.Boolean: case EntityPropertyType.Byte: case EntityPropertyType.Char: @@ -920,7 +936,6 @@ private object DeserializeScalarValue(string value, EntityPropertyType columnTyp case EntityPropertyType.Int32: case EntityPropertyType.Int64: case EntityPropertyType.Single: - case EntityPropertyType.String: case EntityPropertyType.Type: case EntityPropertyType.Uri: return Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture); diff --git a/Src/Contract/SolarWinds.InformationService.Contract.csproj b/Src/Contract/SolarWinds.InformationService.Contract.csproj index 4ed91f1b1..521b03869 100644 --- a/Src/Contract/SolarWinds.InformationService.Contract.csproj +++ b/Src/Contract/SolarWinds.InformationService.Contract.csproj @@ -88,6 +88,7 @@ +