//// /// Copyright (c) 2016 Saúl Piña . /// /// This file is part of xmlrpcwsc. /// /// xmlrpcwsc is free software: you can redistribute it and/or modify /// it under the terms of the GNU Lesser General Public License as published by /// the Free Software Foundation, either version 3 of the License, or /// (at your option) any later version. /// /// xmlrpcwsc is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU Lesser General Public License for more details. /// /// You should have received a copy of the GNU Lesser General Public License /// along with xmlrpcwsc. If not, see . //// using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.IO; using System.Threading; namespace XmlRpc { /// /// This class send a stream data xml. /// public class WebServiceConnection { public static readonly string DefaultContentType = "text/xml; charset=UTF-8"; public static readonly string DefaultRequestMethod = "POST"; public static readonly int DefaultTimeout = 5000; public static readonly int DefaultAttempts = 1; public static readonly int DefaultAttemptsTimeout = 500; public static readonly int DefaultConnectionLimit = 2; public static readonly ICredentials DefaultCredentials = CredentialCache.DefaultCredentials; public static readonly IWebProxy DefaultWebProxy = WebRequest.DefaultWebProxy; private int connectionLimit; private int attempts; private int attemptsTimeout; private int timeout; private string appName; /// /// For connection simultaneously /// public int ConnectionLimit { get { return connectionLimit; } set { if (value <= 0) connectionLimit = DefaultConnectionLimit; else connectionLimit = value; } } /// /// Attempts for request /// public int Attempts { get { return attempts; } set { if (value <= 0) attempts = DefaultAttempts; else attempts = value; } } /// /// Gets or sets the attempts timeout. Default: WebServiceConnection.DefaultAttemptsTimeout /// /// The attempts timeout public int AttemptsTimeout { get { return attemptsTimeout; } set { if (value <= 0) attemptsTimeout = DefaultTimeout; else attemptsTimeout = value; } } /// /// Timeout for request. Default: WebServiceConnection.DefaultTimeout /// public int Timeout { get { return timeout; } set { if (value <= 0) timeout = DefaultTimeout; else timeout = value; } } /// /// Gets or sets the name of the app /// /// The name of the app public string AppName { get { return appName; } set { if (appName == null) appName = ""; else appName = value; } } /// /// total Attempts for request /// public int AttemptsRequest { get; protected set; } /// /// Total time for request /// public int TimeRequest { get; protected set; } /// /// Proxy. Default: WebServiceConnection.DefaultProxy /// public IWebProxy Proxy { get; set; } /// /// Credentials. Default: WebServiceConnection.DefaultCredentials /// public ICredentials Credentials { get; set; } /// /// Url for connect /// public string Url { get; set; } /// /// Path for connect /// public string Path { get; set; } /// /// Data typ. Default: WebServiceConnection.DefaultContentType /// public string ContentType { get; set; } /// /// Method for request. Default: WebServiceConnection.DefaultRequestMethod /// public string RequestMethod { get; set; } /// /// Gets the user agent /// /// The user agent public string GetUserAgent() { return string.Format("{0} ({1}/{2}/{3}/{4}) {5}", ComponentInfo.Name, ComponentInfo.ComponentName, ComponentInfo.Version, ".NET", Environment.OSVersion, AppName).Trim(); } /// /// Build the Url for WebService Connection /// /// Url for create HttpWebRequest private string GetWebServiceUrl() { if (Path == null) return Url; string urlTemp = Url; if (urlTemp.EndsWith("/")) urlTemp = urlTemp.Substring(0, urlTemp.Length - 1); string path = Path; if (path.StartsWith("/")) path = path.Substring(1); return String.Format("{0}/{1}", urlTemp, path); } /// /// Default constructor /// public WebServiceConnection() { Timeout = DefaultTimeout; ContentType = DefaultContentType; RequestMethod = DefaultRequestMethod; Credentials = DefaultCredentials; Attempts = DefaultAttempts; ConnectionLimit = DefaultConnectionLimit; AttemptsTimeout = DefaultAttemptsTimeout; Proxy = DefaultWebProxy; Url = ""; AppName = ""; } /// /// FOR SSL /// /// /// /// /// /// private bool OnValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } /// /// Send data in xml format /// /// Xml Document /// Xml Response public XmlDocument SendRequest(XmlDocument dataRequest) { return SendRequest(dataRequest.OuterXml); } /// /// Send string data /// /// Data /// Xml Response public XmlDocument SendRequest(string dataRequest) { if (string.IsNullOrEmpty(Url)) throw new WebServiceException("URL must be different than empty or null"); ServicePointManager.ServerCertificateValidationCallback = OnValidateCertificate; ServicePointManager.DefaultConnectionLimit = ConnectionLimit; ServicePointManager.Expect100Continue = false; TimeSpan startTime = TimeSpan.FromMilliseconds(Environment.TickCount); AttemptsRequest = 0; bool successful = false; string dataResponse = ""; XmlDocument xmlDocument = new XmlDocument(); while (!successful) { AttemptsRequest++; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GetWebServiceUrl()); request.Timeout = Timeout; request.KeepAlive = false; request.Method = RequestMethod; request.UserAgent = GetUserAgent(); byte[] bytesData = Encoding.UTF8.GetBytes(dataRequest); request.ContentType = ContentType; request.ContentLength = bytesData.Length; if (Proxy != null) request.Proxy = Proxy; if (Credentials != null) request.Credentials = Credentials; try { Stream requestStreamData = request.GetRequestStream(); requestStreamData.Write(bytesData, 0, bytesData.Length); requestStreamData.Close(); WebResponse response = request.GetResponse(); Stream responseStreamData = response.GetResponseStream(); StreamReader readResponseStreamData = new StreamReader(responseStreamData, Encoding.UTF8); dataResponse = readResponseStreamData.ReadToEnd(); readResponseStreamData.Close(); responseStreamData.Close(); response.Close(); xmlDocument.LoadXml(dataResponse); successful = true; } catch (Exception e) { if (AttemptsRequest >= Attempts) { TimeRequest = (int)TimeSpan.FromMilliseconds(Environment.TickCount).Subtract(startTime).Duration().TotalMilliseconds; if (e.GetType().Equals(typeof(WebException))) { WebException we = (WebException)e; if (we.Status == WebExceptionStatus.Timeout) { throw new WebServiceTimeoutException("Timeout exception, operation has expired", e); } } throw new WebServiceException("Error sending request", e); } else { Thread.Sleep(AttemptsTimeout); continue; } } } TimeRequest = (int)TimeSpan.FromMilliseconds(Environment.TickCount).Subtract(startTime).Duration().TotalMilliseconds; return xmlDocument; } } }