public void UseCase1() { MemoryStream ms = new MemoryStream(); var w = XmlDictionaryWriter.CreateMtomWriter(ms, Encoding.UTF8, 10000, "sTaRt", "myboundary", "urn:foo", false, false); w.WriteStartElement("root"); w.WriteRaw("RAW"); w.WriteStartElement("foo"); w.WriteChars(new char [] { 'b', 'c', 'd' }, 0, 3); w.WriteBase64(new byte [] { 50, 60, 70 }, 0, 3); w.WriteArray("", "arr", "", new bool [] { true, false, true }, 0, 3); w.WriteValue(new MyStreamProvider()); w.WriteString("999\r\n\r\n666"); w.WriteEndElement(); //w.WriteProcessingInstruction ("pi", "data"); w.WriteEndElement(); // it outputs end of mime data. w.WriteStartElement("root"); // it is in the next part). w.WriteEndElement(); // it does not close current part. w.WriteEndDocument(); // no effect. w.WriteStartElement("root"); w.WriteEndElement(); w.WriteStartElement("root"); w.WriteEndElement(); w.WriteEndDocument(); w.Flush(); ms.Position = 0; // there are some insiginificant output differences Assert.AreEqual(usecase1, new StreamReader(ms).ReadToEnd().Replace("<root />", "<root/>")); }
public override void WriteMessage(Message message, Stream stream) { VerifyMessageVersion(message); // FIXME: no way to acquire maxSizeInBytes and startInfo? message.WriteMessage(XmlDictionaryWriter.CreateMtomWriter(stream, encoding, int.MaxValue, null)); }
XmlDictionaryWriter TakeStreamedWriter(Stream stream, string startInfo, string boundary, string startUri, bool writeMessageHeaders) { if (streamedWriterPool == null) { lock (thisLock) { if (streamedWriterPool == null) { streamedWriterPool = new SynchronizedPool <XmlDictionaryWriter>(maxWritePoolSize); } } } XmlDictionaryWriter xmlWriter = streamedWriterPool.Take(); if (xmlWriter == null) { xmlWriter = XmlDictionaryWriter.CreateMtomWriter(stream, this.writeEncoding, int.MaxValue, startInfo, boundary, startUri, writeMessageHeaders, false); if (TD.WritePoolMissIsEnabled()) { TD.WritePoolMiss(xmlWriter.GetType().Name); } } else { ((IXmlMtomWriterInitializer)xmlWriter).SetOutput(stream, this.writeEncoding, int.MaxValue, startInfo, boundary, startUri, writeMessageHeaders, false); } return(xmlWriter); }
public static void CreateMtomReaderWriter_Throw_PNSE() { using (var stream = new MemoryStream()) { string startInfo = "application/soap+xml"; Assert.Throws <PlatformNotSupportedException>(() => XmlDictionaryWriter.CreateMtomWriter(stream, Encoding.UTF8, int.MaxValue, startInfo)); } }
private XmlDictionaryWriter CreateMtomWriter(Stream stream, System.ServiceModel.Channels.Message message) { string boundary = message.Properties[TextOrMtomEncodingBindingElement.MtomBoundaryPropertyName] as string; string startUri = message.Properties[TextOrMtomEncodingBindingElement.MtomStartUriPropertyName] as string; string startInfo = message.Properties[TextOrMtomEncodingBindingElement.MtomStartInfoPropertyName] as string; return(XmlDictionaryWriter.CreateMtomWriter(stream, Encoding.UTF8, int.MaxValue, startInfo, boundary, startUri, false, false)); }
static void Main(string[] args) { Employee employee = new Employee { Id = "001", Name = "张三", Gender = "男", Department = "销售部" }; string startInfo = "Application/soap+xml"; string boundary = "http://www.artech.com/boundary"; string startUri = "http://www.artech.com/contentid"; WriteObject <Employee>(employee, stream => XmlDictionaryWriter.CreateMtomWriter(stream, Encoding.UTF8, int.MaxValue, startInfo, boundary, startUri, true, false)); }
protected override XmlDictionaryWriter TakeXmlWriter(Stream stream) { XmlDictionaryWriter returnedWriter = writer; if (returnedWriter == null) { returnedWriter = XmlDictionaryWriter.CreateMtomWriter(stream, messageEncoder.writeEncoding, MaxSizeInBytes, StartInfo, Boundary, StartUri, WriteMessageHeaders, false); } else { writer = null; ((IXmlMtomWriterInitializer)returnedWriter).SetOutput(stream, messageEncoder.writeEncoding, MaxSizeInBytes, StartInfo, Boundary, StartUri, WriteMessageHeaders, false); } if (messageEncoder.writeEncoding.WebName != "utf-8") { returnedWriter.WriteStartDocument(); } return(returnedWriter); }
protected override XmlDictionaryWriter TakeXmlWriter(Stream stream) { XmlDictionaryWriter writer = this.writer; if (writer == null) { writer = XmlDictionaryWriter.CreateMtomWriter(stream, this.messageEncoder.writeEncoding, this.MaxSizeInBytes, this.StartInfo, this.Boundary, this.StartUri, this.WriteMessageHeaders, false); } else { this.writer = null; ((IXmlMtomWriterInitializer)writer).SetOutput(stream, this.messageEncoder.writeEncoding, this.MaxSizeInBytes, this.StartInfo, this.Boundary, this.StartUri, this.WriteMessageHeaders, false); } if (this.messageEncoder.writeEncoding.WebName != "utf-8") { writer.WriteStartDocument(); } return(writer); }
private XmlDictionaryWriter TakeStreamedWriter(Stream stream, string startInfo, string boundary, string startUri, bool writeMessageHeaders) { if (this.streamedWriterPool == null) { lock (this.thisLock) { if (this.streamedWriterPool == null) { this.streamedWriterPool = new SynchronizedPool <XmlDictionaryWriter>(this.maxWritePoolSize); } } } XmlDictionaryWriter writer = this.streamedWriterPool.Take(); if (writer == null) { return(XmlDictionaryWriter.CreateMtomWriter(stream, this.writeEncoding, 0x7fffffff, startInfo, boundary, startUri, writeMessageHeaders, false)); } ((IXmlMtomWriterInitializer)writer).SetOutput(stream, this.writeEncoding, 0x7fffffff, startInfo, boundary, startUri, writeMessageHeaders, false); return(writer); }
/// <summary> /// Creates a <see cref="XmlWriter"/> suitable for outputing a MTOM message. /// </summary> /// <param name="stream"></param> /// <param name="message"></param> /// <returns></returns> XmlDictionaryWriter CreateMtomWriter(Stream stream, Message message) { if (stream is null) { throw new ArgumentNullException(nameof(stream)); } if (message is null) { throw new ArgumentNullException(nameof(message)); } return(XmlDictionaryWriter.CreateMtomWriter( stream, Encoding.UTF8, int.MaxValue, message.Properties[TextOrMtomEncodingBindingElement.MtomStartInfoPropertyName] as string, message.Properties[TextOrMtomEncodingBindingElement.MtomBoundaryPropertyName] as string, message.Properties[TextOrMtomEncodingBindingElement.MtomStartUriPropertyName] as string, false, false)); }
public static void IXmlMtomReaderWriterInitializerTest() { DataContractSerializer serializer = new DataContractSerializer(typeof(TestData)); MemoryStream ms = new MemoryStream(); TestData td = new TestData(); XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateMtomWriter(ms, Encoding.UTF8, int.MaxValue, "application/soap+xml", null, null, true, false); IXmlMtomWriterInitializer writerInitializer = (IXmlMtomWriterInitializer)binaryWriter; writerInitializer.SetOutput(ms, Encoding.UTF8, int.MaxValue, "application/soap+xml", null, null, true, false); serializer.WriteObject(ms, td); binaryWriter.Flush(); byte[] xmlDoc = ms.ToArray(); binaryWriter.Close(); Encoding[] allEncodings = new Encoding[] { Encoding.Unicode, Encoding.BigEndianUnicode, Encoding.UTF8 }; XmlDictionaryReader mtomReader = XmlDictionaryReader.CreateMtomReader(xmlDoc, 0, xmlDoc.Length, allEncodings, null, XmlDictionaryReaderQuotas.Max, int.MaxValue, new OnXmlDictionaryReaderClose((XmlDictionaryReader reader) => { })); IXmlMtomReaderInitializer readerInitializer = (IXmlMtomReaderInitializer)mtomReader; readerInitializer.SetInput(xmlDoc, 0, xmlDoc.Length, allEncodings, null, XmlDictionaryReaderQuotas.Max, int.MaxValue, new OnXmlDictionaryReaderClose((XmlDictionaryReader reader) => { })); var b = mtomReader.ReadContentAsObject(); mtomReader.Close(); }
public static void CreateMtomReaderWriterTest() { using (MemoryStream stream = new MemoryStream()) { string startInfo = "application/soap+xml"; using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateMtomWriter(stream, Encoding.UTF8, int.MaxValue, startInfo)) { writer.WriteElementString("localName", "the value"); writer.Flush(); byte[] bytes = stream.ToArray(); StreamReader reader = new StreamReader(stream); stream.Position = 0; string content = reader.ReadToEnd(); reader.Close(); using (XmlDictionaryReader xreader = XmlDictionaryReader.CreateMtomReader(bytes, 0, bytes.Length, Encoding.UTF8, new XmlDictionaryReaderQuotas())) { xreader.Read(); xreader.ReadOuterXml(); } } } }
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) { string startInfo = "application/soap+xml"; string boundary = string.Format("uuid:{0}+id=1", Guid.NewGuid()); string startUri = "http://tempuri.org/0"; // Set message ID UniqueId messageId = new UniqueId(); soapMessages.SoapRequestMessageId = messageId.ToString(); // Modify MessageId and From headers request.Headers.MessageId = messageId; request.Headers.From = new EndpointAddress("http://www.w3.org/2005/08/addressing/anonymous"); request.Headers.To = new Uri("http://www.w3.org/2005/08/addressing/anonymous"); // Create message buffer (Message needs to be recreated multiple times) MessageBuffer msgBuffer = request.CreateBufferedCopy(int.MaxValue); // Get assembled soap request and sign var messageToSign = msgBuffer.CreateMessage(); var bigXml = ConvertMessageToString(messageToSign); var signedBigXml = Encoding.UTF8.GetString(SoapSignatureUtility.SignBodyAndAddressingHeaders(Encoding.UTF8.GetBytes(bigXml), signingCertificate)); soapMessages.SoapRequest = signedBigXml; // Encoding message into MTOM format using MTOM writer request = msgBuffer.CreateMessage(); var initialMs = new MemoryStream(); var initialWriter = XmlDictionaryWriter.CreateMtomWriter(initialMs, Encoding.UTF8, int.MaxValue, startInfo, boundary, startUri, true, true); request.WriteMessage(initialWriter); initialWriter.Flush(); var originalMessageSize = (int)initialMs.Length; // Copy MTOM message into buffer byte[] bufferUnsigned = new byte[originalMessageSize]; Array.Copy(initialMs.GetBuffer(), 0, bufferUnsigned, 0, (int)initialMs.Position); string mtomString = Encoding.UTF8.GetString(bufferUnsigned); // Get SOAP XML from MTOM message, with start and end index int startSoapIndex; var unsignedXml = GetSoapFromString(mtomString, out startSoapIndex); int endSoapIndex = startSoapIndex + unsignedXml.Length; // If binary MIME parts are found in MTOM message, then replace out base64 content with MTOM include statement string signedFinalXml = signedBigXml; var partHeaderMatches = Regex.Matches(mtomString, @"((Content-ID: <.*>\s+)|(Content-Transfer-Encoding: binary\s+)|(Content-Type: application/octet-stream\s+)){3}", RegexOptions.IgnoreCase); if (partHeaderMatches.Count > 0) { for (int x = 0; x < partHeaderMatches.Count; x++) { var contentId = Regex.Match(partHeaderMatches[x].Value, "Content-ID: <(.*?)>"); var encodedContentId = HttpUtility.UrlEncode(contentId.Groups[1].Value).Replace(".", @"\."); var unencodedContentId = contentId.Groups[1].Value.Replace(".", @"\."); // var xopIncludeMatch = Regex.Match(unsignedXml, "(<[^>]+?>)(<([^>]+?:)?Include href=\"cid:(" + encodedContentId + ")\"[^>]*?/>)(</[^>]+?>)", RegexOptions.IgnoreCase); var xopIncludeMatch = Regex.Match(unsignedXml, "(<[^>]+?>)(<([^>]+?:)?Include href=\"cid:(" + encodedContentId + "|" + unencodedContentId + ")\"[^>]*?/>)(</[^>]+?>)", RegexOptions.IgnoreCase); signedFinalXml = Regex.Replace(signedFinalXml, xopIncludeMatch.Groups[1] + "[^<]*?" + xopIncludeMatch.Groups[5], xopIncludeMatch.Groups[0].Value); } } else { signedFinalXml = signedBigXml; } // Get difference in message length between unsigned and signed SOAP messages int diff = Encoding.UTF8.GetBytes(signedFinalXml).Length - Encoding.UTF8.GetBytes(unsignedXml).Length; // Create buffer large enough to contain MTOM message with signed SOAP XML byte[] bufferSigned = new byte[bufferUnsigned.Length + diff]; // Copy MIME start content (everything before SOAP XML) from unsigned buffer to signed buffer Array.Copy(bufferUnsigned, bufferSigned, startSoapIndex); // Copy signed SOAP XML into signed buffer after MIME start content var signedXmlArray = Encoding.UTF8.GetBytes(signedFinalXml); Array.Copy(signedXmlArray, 0, bufferSigned, startSoapIndex, signedXmlArray.Length); // Copy MIME end content to after signed SOAP XML Array.Copy(bufferUnsigned, endSoapIndex, bufferSigned, startSoapIndex + signedXmlArray.Length, bufferUnsigned.Length - (endSoapIndex + 1)); var mimeContent = new ArraySegment <byte>(bufferSigned, 0, originalMessageSize + diff).Array; soapMessages.MtomRequest = mimeContent; // Recreate request (Message) using MTOM reader var outputReader = XmlDictionaryReader.CreateMtomReader(mimeContent, 0, mimeContent.Length, Encoding.UTF8, new XmlDictionaryReaderQuotas()); request = Message.CreateMessage(outputReader, int.MaxValue, request.Version); // Dispose things msgBuffer.Close(); return(null); }