using Google.Protobuf; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Authentication; using System.Text; using System.Threading.Tasks; using System.Web; using Tango.PMR.Synchronization; namespace Tango.Transport.Web { public class WebTransportClient : IWebTransportClient { private HttpClient _httpClient; private static JsonSerializerSettings _settings; public string AuthenticationToken { get; set; } public TimeSpan RequestTimeout { get { return _httpClient.Timeout; } set { _httpClient.Timeout = value; } } static WebTransportClient() { _settings = new JsonSerializerSettings() { }; } public WebTransportClient() { _httpClient = new HttpClient(); } public WebTransportClient(String authenticationToken) : this() { AuthenticationToken = authenticationToken; } public Task PostProto(String url, Request request) where Request : class, IMessage where Response : class, IMessage { return Task.Factory.StartNew(() => { var req = new ByteArrayContent(request.ToByteArray()); req.Headers.Add("Content-Type", "application/x-protobuf"); if (AuthenticationToken != null) { _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken); } else { _httpClient.DefaultRequestHeaders.Authorization = null; } var response = _httpClient.PostAsync(url, req).Result; var data = response.Content.ReadAsByteArrayAsync().Result; if (response.StatusCode != System.Net.HttpStatusCode.OK) { HttpProtoException exception = HttpProtoException.Parser.ParseFrom(data); throw new HttpException(exception.StatusCode, exception.Message); } Response dummy = Activator.CreateInstance() as Response; return dummy.GetParser().ParseFrom(data) as Response; }); } public Task PostJson(string url, Request request) where Request : class, IWebRequestMessage where Response : class, IWebResponseMessage { return Task.Factory.StartNew(() => { var req = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(request, _settings))); req.Headers.Add("Content-Type", "application/json"); if (AuthenticationToken != null) { _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationToken); } else { _httpClient.DefaultRequestHeaders.Authorization = null; } var response = _httpClient.PostAsync(url, req).Result; var data = response.Content.ReadAsStringAsync().Result; try { response.EnsureSuccessStatusCode(); } catch (HttpRequestException ex) { bool handled = false; try { String message = JObject.Parse(data).GetValue("Message").ToString(); Exception exception = null; try { String exceptionMessage = JObject.Parse(data).GetValue("ExceptionMessage").ToString(); String exceptionType = JObject.Parse(data).GetValue("ExceptionType").ToString(); String stackTrace = JObject.Parse(data).GetValue("StackTrace").ToString(); Type type = GetType(exceptionType); if (type != null) { exception = Activator.CreateInstance(type, new object[] { exceptionMessage + "\n" + stackTrace }) as Exception; } else { exception = new HttpException(exceptionMessage + "\n" + stackTrace); } } catch { if (message == null) { Logging.LogManager.Default.Log($"Error parsing response message!\n{data}"); } throw new HttpRequestException(ex.Message + " " + message); } handled = true; throw exception; } catch (Exception handledException) { if (handled) { throw handledException; } else { throw ex; } } } return JsonConvert.DeserializeObject(data); }); } private static Type GetType(string typeName) { var type = Type.GetType(typeName); if (type != null) return type; foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { type = a.GetType(typeName); if (type != null) return type; } return null; } public void Dispose() { _httpClient.Dispose(); } } }