using System; using System.Net.Http; namespace JSONAPI.Http { /// /// Default implementation of IBaseUrlService /// public class BaseUrlService : IBaseUrlService { private string _contextPath = string.Empty; private Uri _publicOrigin; /// /// Default constructor /// public BaseUrlService() { } /// /// Constructor which provides a context path for the routes of JSONAPI.NET /// /// context path for the routes public BaseUrlService(string contextPath) { CleanContextPath(contextPath); } /// /// Constructor which provides a public origin host and a context path for the routes of JSONAPI.NET. /// If only public origin is desired provide emtpy string to contextPath. /// /// public hostname /// context path for the routes public BaseUrlService(Uri publicOrigin, string contextPath) { CleanContextPath(contextPath); this._publicOrigin = publicOrigin; } /// /// Retrieve the base path to provide in responses. /// /// /// public virtual string GetBaseUrl(HttpRequestMessage requestMessage) { string pathAndQuery; string absolutUri = requestMessage.RequestUri.AbsoluteUri; if (_publicOrigin != null) { var publicUriBuilder = new UriBuilder(absolutUri) { Host = _publicOrigin.Host, Scheme = _publicOrigin.Scheme, Port = _publicOrigin.Port }; absolutUri = publicUriBuilder.Uri.AbsoluteUri; pathAndQuery = publicUriBuilder.Uri.PathAndQuery; } else { pathAndQuery = requestMessage.RequestUri.PathAndQuery; } pathAndQuery = RemoveFromBegin(pathAndQuery, GetContextPath()); pathAndQuery= pathAndQuery.TrimStart('/'); var baseUrl = RemoveFromEnd(absolutUri, pathAndQuery); return baseUrl; } /// /// Provides the context path to serve JSONAPI.NET without leading and trailing slash. /// /// public string GetContextPath() { return _contextPath; } /// /// Makes sure thre are no slashes at the beginnig or end. /// /// private void CleanContextPath(string contextPath) { if (!string.IsNullOrEmpty(contextPath) && !contextPath.EndsWith("/")) { contextPath = contextPath.TrimEnd('/'); } if (!string.IsNullOrEmpty(contextPath) && contextPath.StartsWith("/")) { contextPath = contextPath.TrimStart('/'); } _contextPath = contextPath; } private string RemoveFromEnd(string input, string suffix) { if (input.EndsWith(suffix)) { return input.Substring(0, input.Length - suffix.Length); } return input; } private string RemoveFromBegin(string input, string prefix) { prefix = "/" + prefix; if (input.StartsWith(prefix)) { return input.Substring(prefix.Length, input.Length - prefix.Length); } return input; } } }