/// <include file='doc\DiscoveryDocumentReference.uex' path='docs/doc[@for="DiscoveryDocumentReference.Resolve"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        protected internal override void Resolve(string contentType, Stream stream)
        {
            DiscoveryDocument document = null;

            if (ContentType.IsHtml(contentType))
            {
                string newRef = LinkGrep.SearchForLink(stream);
                if (newRef != null)
                {
                    string newUrl = UriToString(Url, newRef);
                    document = GetDocumentNoParse(ref newUrl, ClientProtocol);
                    Url      = newUrl;
                }
                else
                {
                    throw new InvalidContentTypeException(Res.GetString(Res.WebInvalidContentType, contentType), contentType);
                }
            }

            if (document == null)   // probably xml...
            {
                XmlTextReader reader = new XmlTextReader(new StreamReader(stream, RequestResponseUtils.GetEncoding(contentType)));
                reader.XmlResolver        = null;
                reader.WhitespaceHandling = WhitespaceHandling.Significant;
                reader.DtdProcessing      = DtdProcessing.Prohibit;
                if (DiscoveryDocument.CanRead(reader))
                {
                    // it's a discovery document, so just read it.
                    document = DiscoveryDocument.Read(reader);
                }
                else
                {
                    // check out the processing instructions before the first tag.  if any of them
                    // match the form specified in the DISCO spec, save the href.
                    stream.Position = 0;
                    XmlTextReader newReader = new XmlTextReader(new StreamReader(stream, RequestResponseUtils.GetEncoding(contentType)));
                    newReader.XmlResolver   = null;
                    newReader.DtdProcessing = DtdProcessing.Prohibit;
                    while (newReader.NodeType != XmlNodeType.Element)
                    {
                        if (newReader.NodeType == XmlNodeType.ProcessingInstruction)
                        {
                            // manually parse the PI contents since XmlTextReader won't automatically do it
                            StringBuilder sb = new StringBuilder("<pi ");
                            sb.Append(newReader.Value);
                            sb.Append("/>");
                            XmlTextReader piReader = new XmlTextReader(new StringReader(sb.ToString()));
                            piReader.XmlResolver   = null;
                            piReader.DtdProcessing = DtdProcessing.Prohibit;
                            piReader.Read();
                            string type      = piReader["type"];
                            string alternate = piReader["alternate"];
                            string href      = piReader["href"];
                            if (type != null && ContentType.MatchesBase(type, ContentType.TextXml) &&
                                alternate != null && string.Compare(alternate, "yes", StringComparison.OrdinalIgnoreCase) == 0 &&
                                href != null)
                            {
                                // we got a PI with the right attributes

                                // there is a link to a discovery document. follow it after fully qualifying it.
                                string newUrl = UriToString(Url, href);
                                document = GetDocumentNoParse(ref newUrl, ClientProtocol);
                                Url      = newUrl;
                                break;
                            }
                        }
                        newReader.Read();
                    }
                }
            }

            if (document == null)
            {
                // there is no discovery document at this location
                Exception exception;
                if (ContentType.IsXml(contentType))
                {
                    exception = new ArgumentException(Res.GetString(Res.WebInvalidFormat));
                }
                else
                {
                    exception = new InvalidContentTypeException(Res.GetString(Res.WebInvalidContentType, contentType), contentType);
                }
                throw new InvalidOperationException(Res.GetString(Res.WebMissingDocument, Url), exception);
            }

            ClientProtocol.References[Url] = this;
            ClientProtocol.Documents[Url]  = document;

            foreach (object o in document.References)
            {
                if (o is DiscoveryReference)
                {
                    DiscoveryReference r = (DiscoveryReference)o;
                    if (r.Url.Length == 0)
                    {
                        throw new InvalidOperationException(Res.GetString(Res.WebEmptyRef, r.GetType().FullName, Url));
                    }
                    r.Url = UriToString(Url, r.Url);
                    //All inheritors of DiscoveryReference that got URIs relative
                    //to Ref property should adjust them like ContractReference does here.
                    ContractReference cr = r as ContractReference;
                    if ((cr != null) && (cr.DocRef != null))
                    {
                        cr.DocRef = UriToString(Url, cr.DocRef);
                    }
                    r.ClientProtocol = ClientProtocol;
                    ClientProtocol.References[r.Url] = r;
                }
                else
                {
                    ClientProtocol.AdditionalInformation.Add(o);
                }
            }

            return;
        }
Esempio n. 2
0
        public DiscoveryDocument DiscoverAny(string url)
        {
            try
            {
                string contentType = null;
                Stream stream      = Download(ref url, ref contentType);

                if (contentType.IndexOf("text/html") != -1)
                {
                    // Look for an alternate url

                    StreamReader sr  = new StreamReader(stream);
                    string       str = sr.ReadToEnd();

                    string rex = "link\\s*rel\\s*=\\s*[\"']?alternate[\"']?\\s*";
                    rex += "type\\s*=\\s*[\"']?text/xml[\"']?\\s*href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|'(?<1>[^']*)'|(?<1>\\S+))";
                    Regex rob = new Regex(rex, RegexOptions.IgnoreCase);
                    Match m   = rob.Match(str);
                    if (!m.Success)
                    {
                        throw new InvalidOperationException("The HTML document does not contain Web service discovery information");
                    }

                    if (url.StartsWith("/"))
                    {
                        Uri uri = new Uri(url);
                        url = uri.GetLeftPart(UriPartial.Authority) + m.Groups[1];
                    }
                    else
                    {
                        int i = url.LastIndexOf('/');
                        if (i == -1)
                        {
                            throw new InvalidOperationException("The HTML document does not contain Web service discovery information");
                        }

                        Uri tmp = new Uri(url);
                        tmp = new Uri(tmp, m.Groups [1].ToString());
                        url = tmp.ToString();
                    }
                    stream = Download(ref url);
                }

                XmlTextReader reader = new XmlTextReader(url, stream);
                reader.XmlResolver = null;
                reader.MoveToContent();
                DiscoveryDocument  doc;
                DiscoveryReference refe = null;

                if (DiscoveryDocument.CanRead(reader))
                {
                    doc = DiscoveryDocument.Read(reader);
                    documents.Add(url, doc);
                    refe = new DiscoveryDocumentReference();
                    AddDiscoReferences(doc);
                }
#if !MOBILE
                else if (ServiceDescription.CanRead(reader))
                {
                    ServiceDescription wsdl = ServiceDescription.Read(reader);
                    documents.Add(url, wsdl);
                    doc  = new DiscoveryDocument();
                    refe = new ContractReference();
                    doc.References.Add(refe);
                    refe.Url = url;
                    ((ContractReference)refe).ResolveInternal(this, wsdl);
                }
#endif
                else
                {
                    XmlSchema schema = XmlSchema.Read(reader, null);
                    documents.Add(url, schema);
                    doc      = new DiscoveryDocument();
                    refe     = new SchemaReference();
                    refe.Url = url;
                    ((SchemaReference)refe).ResolveInternal(this, schema);
                    doc.References.Add(refe);
                }

                refe.ClientProtocol = this;
                refe.Url            = url;
                references.Add(url, refe);

                reader.Close();
                return(doc);
            }
            catch (DiscoveryException ex) {
                throw ex.Exception;
            }
        }
        protected internal override void Resolve(string contentType, Stream stream)
        {
            DiscoveryDocument documentNoParse = null;

            if (ContentType.IsHtml(contentType))
            {
                string relUrl = LinkGrep.SearchForLink(stream);
                if (relUrl == null)
                {
                    throw new InvalidContentTypeException(System.Web.Services.Res.GetString("WebInvalidContentType", new object[] { contentType }), contentType);
                }
                string url = DiscoveryReference.UriToString(this.Url, relUrl);
                documentNoParse = GetDocumentNoParse(ref url, base.ClientProtocol);
                this.Url        = url;
            }
            if (documentNoParse == null)
            {
                XmlTextReader xmlReader = new XmlTextReader(new StreamReader(stream, RequestResponseUtils.GetEncoding(contentType)))
                {
                    XmlResolver        = null,
                    WhitespaceHandling = WhitespaceHandling.Significant,
                    DtdProcessing      = DtdProcessing.Prohibit
                };
                if (DiscoveryDocument.CanRead(xmlReader))
                {
                    documentNoParse = DiscoveryDocument.Read(xmlReader);
                }
                else
                {
                    stream.Position = 0L;
                    XmlTextReader reader2 = new XmlTextReader(new StreamReader(stream, RequestResponseUtils.GetEncoding(contentType)))
                    {
                        XmlResolver   = null,
                        DtdProcessing = DtdProcessing.Prohibit
                    };
                    while (reader2.NodeType != XmlNodeType.Element)
                    {
                        if (reader2.NodeType == XmlNodeType.ProcessingInstruction)
                        {
                            StringBuilder builder = new StringBuilder("<pi ");
                            builder.Append(reader2.Value);
                            builder.Append("/>");
                            XmlTextReader reader3 = new XmlTextReader(new StringReader(builder.ToString()))
                            {
                                XmlResolver   = null,
                                DtdProcessing = DtdProcessing.Prohibit
                            };
                            reader3.Read();
                            string str3 = reader3["type"];
                            string strA = reader3["alternate"];
                            string str5 = reader3["href"];
                            if ((((str3 != null) && ContentType.MatchesBase(str3, "text/xml")) && ((strA != null) && (string.Compare(strA, "yes", StringComparison.OrdinalIgnoreCase) == 0))) && (str5 != null))
                            {
                                string str6 = DiscoveryReference.UriToString(this.Url, str5);
                                documentNoParse = GetDocumentNoParse(ref str6, base.ClientProtocol);
                                this.Url        = str6;
                                break;
                            }
                        }
                        reader2.Read();
                    }
                }
            }
            if (documentNoParse == null)
            {
                Exception exception;
                if (ContentType.IsXml(contentType))
                {
                    exception = new ArgumentException(System.Web.Services.Res.GetString("WebInvalidFormat"));
                }
                else
                {
                    exception = new InvalidContentTypeException(System.Web.Services.Res.GetString("WebInvalidContentType", new object[] { contentType }), contentType);
                }
                throw new InvalidOperationException(System.Web.Services.Res.GetString("WebMissingDocument", new object[] { this.Url }), exception);
            }
            base.ClientProtocol.References[this.Url] = this;
            base.ClientProtocol.Documents[this.Url]  = documentNoParse;
            foreach (object obj2 in documentNoParse.References)
            {
                if (obj2 is DiscoveryReference)
                {
                    DiscoveryReference reference = (DiscoveryReference)obj2;
                    if (reference.Url.Length == 0)
                    {
                        throw new InvalidOperationException(System.Web.Services.Res.GetString("WebEmptyRef", new object[] { reference.GetType().FullName, this.Url }));
                    }
                    reference.Url = DiscoveryReference.UriToString(this.Url, reference.Url);
                    ContractReference reference2 = reference as ContractReference;
                    if ((reference2 != null) && (reference2.DocRef != null))
                    {
                        reference2.DocRef = DiscoveryReference.UriToString(this.Url, reference2.DocRef);
                    }
                    reference.ClientProtocol = base.ClientProtocol;
                    base.ClientProtocol.References[reference.Url] = reference;
                }
                else
                {
                    base.ClientProtocol.AdditionalInformation.Add(obj2);
                }
            }
        }