92a25de4b2cb926718f0d63b79722d6ee0951a17
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / WebServiceHelper.cs
1 //
2 // System.Web.Services.Protocols.WebServiceHelper.cs
3 //
4 // Author:
5 //   Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // Copyright (C) Ximian, Inc. 2003
8 //
9
10 using System;
11 using System.IO;
12 using System.Net;
13 using System.Text;
14 using System.Xml;
15 using System.Xml.Schema;
16 using System.Xml.Serialization;
17 using System.Web.Services.Description;
18
19 namespace System.Web.Services.Protocols
20 {
21         internal class WebServiceHelper
22         {
23                 public const string SoapEnvelopeNamespace = "http://schemas.xmlsoap.org/soap/envelope/";
24
25                 public static Encoding GetContentEncoding (string cts, out string content_type)
26                 {
27                         string encoding;
28
29                         encoding = "utf-8";
30                         int start = 0;
31                         int idx = cts.IndexOf (';');
32                         if (idx == -1)
33                                 content_type = cts;
34                         else
35                                 content_type = cts.Substring (0, idx);
36
37                         content_type = content_type.Trim ();
38                         for (start = idx + 1; idx != -1;)
39                         {
40                                 idx = cts.IndexOf (";", start);
41                                 string body;
42                                 if (idx == -1)
43                                         body = cts.Substring (start);
44                                 else 
45                                 {
46                                         body = cts.Substring (start, idx - start);
47                                         start = idx + 1;
48                                 }
49                                 body = body.Trim ();
50                                 if (body.StartsWith ("charset="))
51                                 {
52                                         encoding = body.Substring (8);
53                                 }
54                         }
55
56                         return Encoding.GetEncoding (encoding);
57                 }
58
59                 public static void WriteSoapMessage (XmlTextWriter xtw, SoapTypeStubInfo info, SoapBindingUse methodUse, XmlSerializer bodySerializer, object bodyContent, SoapHeaderCollection headers)
60                 {
61                         xtw.WriteStartDocument ();
62                         xtw.WriteStartElement ("soap", "Envelope", WebServiceHelper.SoapEnvelopeNamespace);
63                         xtw.WriteAttributeString ("xmlns", "xsi", null, XmlSchema.InstanceNamespace);
64                         xtw.WriteAttributeString ("xmlns", "xsd", null, XmlSchema.Namespace);
65
66                         // Serialize headers
67                         if (headers != null)
68                         {
69                                 foreach (SoapHeader header in headers) 
70                                 {
71                                         XmlSerializer ser = info.GetHeaderSerializer (header.GetType(), methodUse);
72                                         xtw.WriteStartElement ("soap", "Header", WebServiceHelper.SoapEnvelopeNamespace);
73                                         ser.Serialize (xtw, header);
74                                         xtw.WriteEndElement ();
75                                 }
76                         }
77
78                         // Serialize body
79                         xtw.WriteStartElement ("soap", "Body", WebServiceHelper.SoapEnvelopeNamespace);
80                         bodySerializer.Serialize (xtw, bodyContent);
81
82                         xtw.WriteEndElement ();
83                         xtw.WriteEndElement ();
84                         xtw.Flush ();
85                 }
86
87                 public static void ReadSoapMessage (XmlTextReader xmlReader, SoapTypeStubInfo typeStubInfo, SoapBindingUse methodUse, XmlSerializer bodySerializer, out object body, out SoapHeaderCollection headers)
88                 {
89                         xmlReader.MoveToContent ();\r
90                         xmlReader.ReadStartElement ("Envelope", WebServiceHelper.SoapEnvelopeNamespace);\r
91 \r
92                         headers = ReadHeaders (typeStubInfo, methodUse, xmlReader);\r
93 \r
94                         xmlReader.MoveToContent ();\r
95                         xmlReader.ReadStartElement ("Body", WebServiceHelper.SoapEnvelopeNamespace);\r
96                         xmlReader.MoveToContent ();\r
97 \r
98                         body = bodySerializer.Deserialize (xmlReader);\r
99                 }
100
101                 static SoapHeaderCollection ReadHeaders (SoapTypeStubInfo typeStubInfo, SoapBindingUse methodUse, XmlTextReader xmlReader)
102                 {
103                         SoapHeaderCollection headers = new SoapHeaderCollection ();
104                         while (! (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == WebServiceHelper.SoapEnvelopeNamespace))
105                         {
106                                 if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Header" && xmlReader.NamespaceURI == WebServiceHelper.SoapEnvelopeNamespace)
107                                 {
108                                         xmlReader.ReadStartElement ();
109                                         xmlReader.MoveToContent ();
110                                         XmlQualifiedName qname = new XmlQualifiedName (xmlReader.LocalName, xmlReader.NamespaceURI);
111                                         XmlSerializer headerSerializer = typeStubInfo.GetHeaderSerializer (qname, methodUse);
112                                         if (headerSerializer != null)
113                                         {
114                                                 SoapHeader header = (SoapHeader) headerSerializer.Deserialize (xmlReader);
115                                                 headers.Add (header);
116                                         }
117                                         else
118                                         {
119                                                 while (xmlReader.NodeType == XmlNodeType.EndElement)
120                                                         xmlReader.Skip ();      // TODO: Check if the header has mustUnderstand=true
121                                                 xmlReader.Skip ();
122                                         }
123                                 }
124                                 else
125                                         xmlReader.Skip ();
126                         }
127                         return headers;
128                 }
129
130                 public static void InvalidOperation (string message, WebResponse response, Encoding enc)
131                 {
132                         if (response == null)
133                                 throw new InvalidOperationException (message);
134
135                         if (enc == null)
136                                 enc = Encoding.UTF8;
137
138                         StringBuilder sb = new StringBuilder ();
139                         sb.Append (message);
140                         sb.Append ("\r\nResponse error message:\r\n--\r\n");
141
142                         try {
143                                 StreamReader resp = new StreamReader (response.GetResponseStream (), enc);
144                                 sb.Append (resp.ReadToEnd ());
145                         } catch (Exception) {
146                         }
147
148                         throw new InvalidOperationException (sb.ToString ());
149                 }
150         }
151 }