1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel.Channels 6 { 7 using System; 8 using System.Collections.Generic; 9 using System.Xml; 10 using System.Net; 11 using System.IO; 12 using System.Text; 13 using System.Globalization; 14 using System.Runtime.Serialization; 15 using System.ServiceModel.Diagnostics; 16 using System.Diagnostics; 17 18 abstract class ContextProtocol 19 { 20 ContextExchangeMechanism contextExchangeMechanism; 21 ContextProtocol(ContextExchangeMechanism contextExchangeMechanism)22 protected ContextProtocol(ContextExchangeMechanism contextExchangeMechanism) 23 { 24 if (!ContextExchangeMechanismHelper.IsDefined(contextExchangeMechanism)) 25 { 26 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("contextExchangeMechanism")); 27 } 28 this.contextExchangeMechanism = contextExchangeMechanism; 29 } 30 31 protected ContextExchangeMechanism ContextExchangeMechanism 32 { 33 get { return this.contextExchangeMechanism; } 34 } 35 OnIncomingMessage(Message message)36 public abstract void OnIncomingMessage(Message message); 37 OnOutgoingMessage(Message message, RequestContext requestContext)38 public abstract void OnOutgoingMessage(Message message, RequestContext requestContext); 39 OnSendSoapContextHeader(Message message, ContextMessageProperty context)40 protected void OnSendSoapContextHeader(Message message, ContextMessageProperty context) 41 { 42 if (message == null) 43 { 44 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 45 } 46 if (context == null) 47 { 48 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); 49 } 50 51 if (context.Context.Count > 0) 52 { 53 message.Headers.Add(new ContextMessageHeader(context.Context)); 54 } 55 56 if (DiagnosticUtility.ShouldTraceVerbose) 57 { 58 TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.ContextProtocolContextAddedToMessage, 59 SR.GetString(SR.TraceCodeContextProtocolContextAddedToMessage), this); 60 } 61 } 62 63 internal static class HttpCookieToolbox 64 { 65 public const string ContextHttpCookieName = "WscContext"; 66 public const string RemoveContextHttpCookieHeader = ContextHttpCookieName + ";Max-Age=0"; 67 EncodeContextAsHttpSetCookieHeader(ContextMessageProperty context, Uri uri)68 public static string EncodeContextAsHttpSetCookieHeader(ContextMessageProperty context, Uri uri) 69 { 70 if (uri == null) 71 { 72 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); 73 } 74 if (context == null) 75 { 76 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); 77 } 78 79 MemoryStream stream = new MemoryStream(); 80 XmlWriterSettings writerSettings = new XmlWriterSettings(); 81 writerSettings.OmitXmlDeclaration = true; 82 XmlWriter writer = XmlWriter.Create(stream, writerSettings); 83 ContextMessageHeader contextHeader = new ContextMessageHeader(context.Context); 84 contextHeader.WriteHeader(writer, MessageVersion.Default); 85 writer.Flush(); 86 87 string result = string.Format( 88 CultureInfo.InvariantCulture, 89 "{0}=\"{1}\";Path={2}", 90 HttpCookieToolbox.ContextHttpCookieName, 91 Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length), 92 uri.AbsolutePath); 93 94 return result; 95 } 96 TryCreateFromHttpCookieHeader(string httpCookieHeader, out ContextMessageProperty context)97 public static bool TryCreateFromHttpCookieHeader(string httpCookieHeader, out ContextMessageProperty context) 98 { 99 if (httpCookieHeader == null) 100 { 101 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("httpCookieHeader"); 102 } 103 104 context = null; 105 106 foreach (string token in httpCookieHeader.Split(';')) 107 { 108 string trimmedToken = token.Trim(); 109 if (trimmedToken.StartsWith(HttpCookieToolbox.ContextHttpCookieName, StringComparison.Ordinal)) 110 { 111 int equalsSignIndex = trimmedToken.IndexOf('='); 112 if (equalsSignIndex < 0) 113 { 114 context = new ContextMessageProperty(); 115 break; 116 } 117 if (equalsSignIndex < (trimmedToken.Length - 1)) 118 { 119 string value = trimmedToken.Substring(equalsSignIndex + 1).Trim(); 120 121 if (value.Length > 1 && (value[0] == '"') && (value[value.Length - 1] == '"')) 122 { 123 value = value.Substring(1, value.Length - 2); 124 } 125 try 126 { 127 context = ContextMessageHeader.ParseContextHeader( 128 XmlReader.Create(new MemoryStream(Convert.FromBase64String(value)))); 129 break; 130 } 131 catch (SerializationException e) 132 { 133 DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning); 134 } 135 catch (ProtocolException pe) 136 { 137 DiagnosticUtility.TraceHandledException(pe, TraceEventType.Warning); 138 } 139 } 140 } 141 } 142 143 return context != null; 144 } 145 } 146 } 147 } 148