/// <summary> /// Create a new instance of the WCF Message class that has the correct content type (xml/json) and has a serialized /// instance of the SyncError class which is a representation of the error message. /// </summary> /// <param name="httpStatusCode">Status code to be used for the outgoing response.</param> /// <param name="errorDescription">A description of the error.</param> /// <returns>An instance of the WCF Message class that is sent as response.</returns> private Message CreateExceptionMessage(HttpContextServiceHost ctx, HttpStatusCode httpStatusCode, string errorDescription) { ctx.StatusCode = httpStatusCode; ctx.StatusDescription = (httpStatusCode == HttpStatusCode.InternalServerError ? Strings.InternalServerError : errorDescription); var error = new ServiceError { ErrorDescription = errorDescription }; Message message; if (_syncConfiguration.SerializationFormat == SyncSerializationFormat.ODataJson) { message = Message.CreateMessage(MessageVersion.None, String.Empty, error, new DataContractJsonSerializer(typeof(ServiceError))); message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json)); } else { message = Message.CreateMessage(MessageVersion.None, String.Empty, error, new DataContractSerializer(typeof(ServiceError))); message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml)); } var property = new HttpResponseMessageProperty { StatusCode = httpStatusCode }; property.Headers.Add(HttpResponseHeader.ContentType, WebUtil.GetContentType(_serviceHost.GetOutputSerializationFormat(_syncConfiguration.SerializationFormat))); message.Properties.Add(HttpResponseMessageProperty.Name, property); return(message); }
/// <summary>Create a instance of <see cref="Message" /> from an exception. This is sent as the response.</summary> /// <param name="exception">Exception to process</param> /// <returns>An instance of <see cref="Message" /> class.</returns> private Message CreateMessageFromUnhandledException(HttpContextServiceHost ctx, Exception exception) { string exceptionMessage = WebUtil.GetExceptionMessage(exception); SyncServiceTracer.TraceError(exceptionMessage); return(_syncConfiguration.UseVerboseErrors ? CreateExceptionMessage(ctx, HttpStatusCode.InternalServerError, exceptionMessage) : CreateExceptionMessage(ctx, HttpStatusCode.InternalServerError, Strings.InternalServerError)); }
private Message CreateExceptionMessage(HttpContextServiceHost ctx, Exception exception) { if (exceptionCodes.ContainsKey(exception.GetType())) { return(CreateExceptionMessage(ctx, exceptionCodes[exception.GetType()], exception.Message)); } else { return(CreateExceptionMessage(ctx, HttpStatusCode.InternalServerError, exception.Message)); } }
/// <summary> /// Process an incoming request and return a WCF Message class instance. /// </summary> /// <param name="messageBody">Message body</param> /// <returns>Instance of the WCF Message class</returns> public Message ProcessRequestForMessage(Stream messageBody) { try { // Intialize the service host first, since most of the logic depends on it. _serviceHost = new HttpContextServiceHost(messageBody); _serviceHost.ValidateRequestHttpVerbAndSegments(); // Create the configuration. The first call will initialize the configuration // and all other calls will be a no-op. CreateConfiguration(); // Raise event for user code InvokeOnSyncRequestStart(); _requestDescription = new RequestParser(_serviceHost, _syncConfiguration).ParseIncomingRequest(); if (null == _requestDescription.SyncBlob || 0 == _requestDescription.SyncBlob.Length) { InitializeNewClient(); } _requestProcessor = RequestProcessorFactory.GetRequestProcessorInstance(_requestDescription.RequestCommand, _syncConfiguration, _serviceHost); _outgoingMessage = _requestProcessor.ProcessRequest(_requestDescription); // Add sync properties var responseProperties = _outgoingMessage.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty; if (null != responseProperties) { responseProperties.Headers[SyncServiceConstants.SYNC_SERVICE_VERSION_KEY] = SyncServiceConstants.SYNC_SERVICE_VERSION_VALUE; } // Raise event for user code InvokeOnEndSyncRequest(_outgoingMessage); } catch (SyncServiceException syncServiceException) { ProcessSyncServiceException(syncServiceException); } catch (Exception exception) { if (WebUtil.IsFatalException(exception)) { throw; } _outgoingMessage = CreateMessageFromUnhandledException(exception); } return(_outgoingMessage); }
protected SyncRequestProcessorBase(SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) { WebUtil.CheckArgumentNull(configuration, "configuration"); Debug.Assert(0 != configuration.ScopeNames.Count); _configuration = configuration; _scopeName = configuration.ScopeNames[0]; _serviceHost = serviceHost; _serverConnectionString = _configuration.ServerConnectionString; _conflictResolutionPolicy = _configuration.ConflictResolutionPolicy; }
private Message CreateExceptionMessageEx(Exception exception, HttpContextServiceHost ctx) { if (exceptionCodes.ContainsKey(exception.GetType())) { return(CreateExceptionMessage(ctx, exception)); } if (exception.InnerException != null) { return(CreateExceptionMessage(ctx, exception.InnerException)); } else { return(null); } }
/// <summary> /// Process an incoming request and return a WCF Message class instance. /// </summary> /// <param name="messageBody">Message body</param> /// <returns>Instance of the WCF Message class</returns> /// private Guid Logon(HttpContextServiceHost ctx, out string email) { String configName = ctx.Headers["configname"]; String configVersion = ctx.Headers["configversion"]; if (configName == null || configVersion == null) { throw new Exception("Unknown client version"); } // resolution = ctx.Headers["resolution"] ?? "Default"; email = null; String userId = ctx.Headers["userid"]; if (!String.IsNullOrEmpty(userId)) { return(new Guid(userId)); } else { NetworkCredential credential = null; if (!String.IsNullOrEmpty(ctx.UserName) && !String.IsNullOrEmpty(ctx.UserPassword)) { credential = new NetworkCredential(ctx.UserName, ctx.UserPassword); } if (credential == null) { String username = ctx.Headers["username"]; String password = ctx.Headers["password"]; if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password)) { credential = new NetworkCredential(username, password); } } if (credential == null) { throw new UnauthorizedAccessException("Invalid user name or password"); } return(Common.Logon.GetUserId2(CurrentScope(), credential, configName, configVersion, out email)); } }
internal static IRequestProcessor GetRequestProcessorInstance(RequestCommand requestCommand, SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) { switch (requestCommand) { case RequestCommand.UploadChanges: return new UploadChangesRequestProcessor(configuration, serviceHost); case RequestCommand.DownloadChanges: return new DownloadChangesRequestProcessor(configuration, serviceHost); case RequestCommand.SyncScopes: return new SyncScopesRequestProcessor(configuration); case RequestCommand.ScopeMetadata: return new ScopeSchemaRequestProcessor(configuration); default: throw new NotSupportedException(); } }
private void LogToDb(RequestCommand cmd, HttpContextServiceHost ctx, DateTime startTime, WebHeaderCollection headers, Exception e) { try { String statusDescription = ctx.StatusDescription; if (e != null) { statusDescription = e.Message; while (e.InnerException != null) { statusDescription = statusDescription + "; " + e.InnerException.Message; e = e.InnerException; } } System.Collections.Generic.Dictionary <String, object> d = new Dictionary <string, object>(); foreach (String key in headers.Keys) { d.Add(key.ToLower().Replace("-", ""), headers[key]); } d.Add("StartTime".ToLower(), startTime); d.Add("EndTime".ToLower(), DateTime.Now); d.Add("Direction".ToLower(), (int)cmd); d.Add("Login".ToLower(), ctx.UserName); if (String.IsNullOrEmpty(ctx.UserId)) { d.Add("UserId".ToLower(), null); } else { d.Add("UserId".ToLower(), Guid.Parse(ctx.UserId)); } d.Add("UserEMail".ToLower(), ctx.UserEMail); d.Add("ResourceVersion".ToLower(), ctx.ResourceVersion); d.Add("OutputContentLength".ToLower(), ctx.OriginalContentLength); d.Add("StatusCode".ToLower(), (int)ctx.StatusCode); d.Add("StatusDescription".ToLower(), statusDescription); d.Add("FirstSync".ToLower(), (null == _requestDescription.SyncBlob || 0 == _requestDescription.SyncBlob.Length)); Common.Logon.WriteLog(CurrentScope(), d); } catch { } }
private void ProcessSyncServiceException(HttpContextServiceHost ctx, SyncServiceException syncServiceException) { string exceptionMessage = WebUtil.GetExceptionMessage(syncServiceException); SyncServiceTracer.TraceWarning(exceptionMessage); _outgoingMessage = _syncConfiguration.UseVerboseErrors ? CreateExceptionMessage(ctx, (HttpStatusCode)syncServiceException.StatusCode, exceptionMessage) : CreateExceptionMessage(ctx, (HttpStatusCode)syncServiceException.StatusCode, syncServiceException.Message); // Add the "Allow" HTTP header if present._outgoingMessage.Properties[HttpResponseMessageProperty.Name]. if (!String.IsNullOrEmpty(syncServiceException.ResponseAllowHeader) && null != _outgoingMessage.Properties[HttpResponseMessageProperty.Name]) { ((HttpResponseMessageProperty)_outgoingMessage.Properties[HttpResponseMessageProperty.Name]). Headers.Add("Allow", syncServiceException.ResponseAllowHeader); } }
/// <summary> /// This method is invoked when a GET request is made to the service root. /// We will redirect this request to the /$syncscopes URL which will return a list of scopes. /// Without this, the service returns a missing operation error. /// </summary> public void ProcessRequestToServiceRoot() { _serviceHost = new HttpContextServiceHost(null); // Look at the host header to determine the domain to which the request was made. // In Windows Azure, the Uri class does not give accurate information about the request host. string requestHost = !String.IsNullOrEmpty(_serviceHost.HostHeader) ? _serviceHost.HostHeader : _serviceHost.RequestUri.Authority; // Create the URL corresponding to $syncscopes. // SchemeName is "http" or "https" // requestHost will contain domain and port number (if any) // AbsolutePath for this operation contract will be "/<servicename>.svc/" _serviceHost.OutgoingResponse.Location = String.Format("{0}://{1}{2}{3}", _serviceHost.RequestUri.Scheme, requestHost, _serviceHost.RequestUri.AbsolutePath, SyncServiceConstants.SYNC_SCOPES_URL_SEGMENT); _serviceHost.OutgoingResponse.StatusCode = HttpStatusCode.Redirect; }
internal static IRequestProcessor GetRequestProcessorInstance(RequestCommand requestCommand, SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) { switch (requestCommand) { case RequestCommand.UploadChanges: return(new UploadChangesRequestProcessor(configuration, serviceHost)); case RequestCommand.DownloadChanges: return(new DownloadChangesRequestProcessor(configuration, serviceHost)); case RequestCommand.SyncScopes: return(new SyncScopesRequestProcessor(configuration)); case RequestCommand.ScopeMetadata: return(new ScopeSchemaRequestProcessor(configuration)); default: throw new NotSupportedException(); } }
private System.IO.Stream MessageToStream(Message message, HttpContextServiceHost ctx) { System.IO.Stream ms = new System.IO.MemoryStream(); using (System.IO.Stream tempms = new System.IO.MemoryStream()) { using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(tempms)) { message.WriteMessage(writer); writer.Flush(); } ctx.OriginalContentLength = (int)tempms.Length; tempms.Position = 0; /* * using (System.IO.FileStream fs = new FileStream(@"d:\f1.xml", FileMode.CreateNew)) * { * tempms.CopyTo(fs); * fs.Flush(); * } * tempms.Position = 0; */ using (System.IO.Compression.GZipStream gzip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress, true)) { tempms.CopyTo(gzip); } } ms.Position = 0; /* * using (System.IO.FileStream fs = new FileStream(@"d:\f2.xml.zip", FileMode.CreateNew)) * { * ms.CopyTo(fs); * fs.Flush(); * } * ms.Position = 0; */ return(ms); }
private System.IO.Stream MessageToStream(HttpContextServiceHost ctx, Message message) { System.IO.Stream ms = new System.IO.MemoryStream(); using (System.IO.Stream tempms = new System.IO.MemoryStream()) { using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(tempms)) { message.WriteMessage(writer); writer.Flush(); } ctx.OriginalContentLength = (int)tempms.Length; tempms.Position = 0; using (System.IO.Compression.GZipStream gzip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress, true)) { tempms.CopyTo(gzip); } } ms.Position = 0; return(ms); }
internal Request(RequestCommand requestCommand, HttpContextServiceHost serviceHost, Dictionary<CommandParamType, object> commandParams, byte[] blob, List<IOfflineEntity> entities, SyncSerializationFormat responseSerializationFormat) { IdToTempIdMapping = new Dictionary<string, string>(); RequestCommand = requestCommand; ServiceHost = serviceHost; CommandParams = commandParams; SyncBlob = blob; ResponseSerializationFormat = responseSerializationFormat; if (null != entities && requestCommand != RequestCommand.UploadChanges) { throw SyncServiceException.CreateBadRequestError(Strings.EntitiesOnlyAllowedForUploadChangesRequest); } EntityList = entities; }
internal Request(RequestCommand requestCommand, HttpContextServiceHost serviceHost, Dictionary <CommandParamType, object> commandParams, byte[] blob, List <IOfflineEntity> entities, SyncSerializationFormat responseSerializationFormat) { IdToTempIdMapping = new Dictionary <string, string>(); RequestCommand = requestCommand; ServiceHost = serviceHost; CommandParams = commandParams; SyncBlob = blob; ResponseSerializationFormat = responseSerializationFormat; if (null != entities && requestCommand != RequestCommand.UploadChanges) { throw SyncServiceException.CreateBadRequestError(Strings.EntitiesOnlyAllowedForUploadChangesRequest); } EntityList = entities; }
/// <summary>Processes the diagnostics page request.</summary> /// <returns>The response <see cref="Message"/>.</returns> public Message ProcessRequestForDiagnostics() { try { // Intialize the service host. _serviceHost = new HttpContextServiceHost(); // Ensure configuration. CreateConfiguration(); Debug.Assert(_syncConfiguration != null, "_syncConfiguration != null"); // Check the EnableDiagPage property and invoke the callback if necessary. // Return 404-Not Found if not enabled. if (!_syncConfiguration.EnableDiagnosticPage || !OnBeginDiagnosticRequest()) { throw SyncServiceException.CreateResourceNotFound(); } // Perform diagnostic checks and prepare outgoing message. _outgoingMessage = DiagHelper.CreateDiagResponseMessage(_syncConfiguration, _serviceHost); } catch (SyncServiceException syncServiceException) { ProcessSyncServiceException(syncServiceException); } catch (Exception exception) { if (WebUtil.IsFatalException(exception)) { throw; } _outgoingMessage = CreateMessageFromUnhandledException(exception); } return(_outgoingMessage); }
private HttpContextServiceHost CreateContext(Stream messageBody) { HttpContextServiceHost ctx = new HttpContextServiceHost(messageBody); ctx.UserName = credential.UserName; ctx.UserPassword = credential.Password; ctx.ContentType = WebOperationContext.Current.IncomingRequest.ContentType; ctx.HostHeader = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Host]; ctx.QueryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters; ctx.RequestUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri; ctx.RelativeUriSegments = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RelativePathSegments.ToArray(); ctx.RequestAccept = WebOperationContext.Current.IncomingRequest.Accept; ctx.RequestHeaders = WebOperationContext.Current.IncomingRequest.Headers; ctx.RequestHttpMethod = WebOperationContext.Current.IncomingRequest.Method; ctx.RequestIfMatch = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.IfMatch]; ctx.RequestIfNoneMatch = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.IfNoneMatch]; ctx.ServiceBaseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri; HttpRequestMessageProperty g = OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; ctx.Headers = g.Headers; return ctx; }
public Stream ProcessRequestForMessage(Stream messageBody) { HttpContextServiceHost ctx = CreateContext(messageBody); Stream result; if (!Common.Logon.CheckServerLicence(ctx.Headers["deviceId"])) { result = MessageToStream(ctx, CreateLicenseExceptionMessage(ctx, "Limit of server licenses exceeded")); } else { result = ((IRequestHandlerProxy)GetProxy()).ProcessRequest(ctx); } WebOperationContext.Current.OutgoingResponse.Headers[SyncServiceConstants.SYNC_SERVICE_USERID] = ctx.UserId; WebOperationContext.Current.OutgoingResponse.Headers[SyncServiceConstants.SYNC_SERVICE_USEREMAIL] = (String.IsNullOrEmpty(ctx.UserEMail) ? "" : ctx.UserEMail); WebOperationContext.Current.OutgoingResponse.Headers[SyncServiceConstants.SYNC_SERVICE_CONTENTLENGTH] = ctx.OriginalContentLength.ToString(); WebOperationContext.Current.OutgoingResponse.Headers[SyncServiceConstants.SYNC_SERVICE_RESOURCEVERSION] = ctx.ResourceVersion == null ? "" : ctx.ResourceVersion; WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.ContentEncoding] = "gzip"; WebOperationContext.Current.OutgoingResponse.StatusCode = ctx.StatusCode; WebOperationContext.Current.OutgoingResponse.StatusDescription = ctx.StatusDescription; return(result); }
/* * protected System.IO.Stream MakeExceptionAnswer(Exception e) * { * String text = e.Message; * while (e.InnerException != null) * { * text = text + "; " + e.InnerException.Message; * e = e.InnerException; * } * text = text + e.StackTrace; * return MakeTextAnswer(text); * } * * private System.IO.Stream MakeTextAnswer(String text) * { * MemoryStream ms = new MemoryStream(); * byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text); * ms.Write(bytes, 0, bytes.Length); * ms.Position = 0; * return ms; * } */ private Message CreateLicenseExceptionMessage(HttpContextServiceHost ctx, string errorDescription) { ctx.StatusCode = HttpStatusCode.PaymentRequired; ctx.StatusDescription = errorDescription; var error = new ServiceError { ErrorDescription = errorDescription }; Message message; message = Message.CreateMessage(MessageVersion.None, String.Empty, error, new DataContractSerializer(typeof(ServiceError))); message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml)); var property = new HttpResponseMessageProperty { StatusCode = ctx.StatusCode }; property.Headers.Add(HttpResponseHeader.ContentType, "application/atom+xml"); message.Properties.Add(HttpResponseMessageProperty.Name, property); return(message); }
private HttpContextServiceHost CreateContext(Stream messageBody) { HttpContextServiceHost ctx = new HttpContextServiceHost(messageBody); ctx.UserName = credential.UserName; ctx.UserPassword = credential.Password; ctx.ContentType = WebOperationContext.Current.IncomingRequest.ContentType; ctx.HostHeader = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Host]; ctx.QueryParameters = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters; ctx.RequestUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri; ctx.RelativeUriSegments = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RelativePathSegments.ToArray(); ctx.RequestAccept = WebOperationContext.Current.IncomingRequest.Accept; ctx.RequestHeaders = WebOperationContext.Current.IncomingRequest.Headers; ctx.RequestHttpMethod = WebOperationContext.Current.IncomingRequest.Method; ctx.RequestIfMatch = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.IfMatch]; ctx.RequestIfNoneMatch = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.IfNoneMatch]; ctx.ServiceBaseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri; HttpRequestMessageProperty g = OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; ctx.Headers = g.Headers; return(ctx); }
/* protected System.IO.Stream MakeExceptionAnswer(Exception e) { String text = e.Message; while (e.InnerException != null) { text = text + "; " + e.InnerException.Message; e = e.InnerException; } text = text + e.StackTrace; return MakeTextAnswer(text); } private System.IO.Stream MakeTextAnswer(String text) { MemoryStream ms = new MemoryStream(); byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text); ms.Write(bytes, 0, bytes.Length); ms.Position = 0; return ms; } */ private Message CreateLicenseExceptionMessage(HttpContextServiceHost ctx, string errorDescription) { ctx.StatusCode = HttpStatusCode.PaymentRequired; ctx.StatusDescription = errorDescription; var error = new ServiceError { ErrorDescription = errorDescription }; Message message; message = Message.CreateMessage(MessageVersion.None, String.Empty, error, new DataContractSerializer(typeof(ServiceError))); message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml)); var property = new HttpResponseMessageProperty { StatusCode = ctx.StatusCode }; property.Headers.Add(HttpResponseHeader.ContentType, "application/atom+xml"); message.Properties.Add(HttpResponseMessageProperty.Name, property); return message; }
public Stream ProcessRequest(HttpContextServiceHost ctx) { DateTime startTime = DateTime.Now; bool logged = false; Exception raisedException = null; try { try { // Intialize the service host first, since most of the logic depends on it. _serviceHost = ctx;// new HttpContextServiceHost(messageBody); //_serviceHost.ValidateRequestHttpVerbAndSegments(); // Create the configuration. The first call will initialize the configuration // and all other calls will be a no-op. CreateConfiguration(CurrentScope()); // Raise event for user code InvokeOnSyncRequestStart(); _requestDescription = new RequestParser(_serviceHost, _syncConfiguration).ParseIncomingRequest(); string email; Guid userId = Logon(ctx, out email); ctx.UserId = userId.ToString(); ctx.UserEMail = email; Common.Logon.CheckLicense(CurrentScope(), ctx.Headers["deviceId"]); Common.Logon.CheckCoreVersion(CurrentScope(), ctx.Headers["coreversion"]); ctx.ResourceVersion = Common.Logon.GetResourceVersion(CurrentScope()); //add request parameters _requestDescription.RequestParams = new Dictionary <string, object>(); _requestDescription.RequestParams.Add("@UserId", userId); if (null == _requestDescription.SyncBlob || 0 == _requestDescription.SyncBlob.Length) { InitializeNewClient(userId, "Default"); } _requestProcessor = RequestProcessorFactory.GetRequestProcessorInstance(_requestDescription.RequestCommand, _syncConfiguration, _serviceHost); _outgoingMessage = _requestProcessor.ProcessRequest(_requestDescription); // Add sync properties var responseProperties = _outgoingMessage.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty; if (null != responseProperties) { responseProperties.Headers[SyncServiceConstants.SYNC_SERVICE_VERSION_KEY] = SyncServiceConstants.SYNC_SERVICE_VERSION_VALUE; responseProperties.Headers[SyncServiceConstants.SYNC_SERVICE_USERID] = userId.ToString(); } // Raise event for user code InvokeOnEndSyncRequest(_outgoingMessage); } catch (SyncServiceException syncServiceException) { raisedException = syncServiceException; ProcessSyncServiceException(ctx, syncServiceException); //_outgoingMessage is set inside } catch (DbSyncException dbSyncException) { raisedException = dbSyncException; if (dbSyncException.Message.StartsWith("Cannot find a valid scope")) { _outgoingMessage = CreateExceptionMessage(ctx, HttpStatusCode.Conflict, dbSyncException.Message); } else { _outgoingMessage = CreateExceptionMessageEx(dbSyncException, ctx); } } catch (Exception exception) { if (WebUtil.IsFatalException(exception)) { throw; } raisedException = exception; if (_outgoingMessage == null) { _outgoingMessage = CreateExceptionMessageEx(exception, ctx); } if (_outgoingMessage == null) { _outgoingMessage = CreateMessageFromUnhandledException(ctx, exception); } } return(MessageToStream(_outgoingMessage, ctx)); } finally { if (!logged) { logged = LogRequestInfo(startTime, ctx.Headers); } if (raisedException != null) { LogException(raisedException); } LogToDb(_requestDescription.RequestCommand, ctx, startTime, ctx.Headers, raisedException); } }
public DownloadChangesRequestProcessor(SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) : base(configuration, serviceHost) { base._syncOperation = SyncOperations.Download; }
internal RequestParser(HttpContextServiceHost serviceHost, SyncServiceConfiguration configuration) { _serviceHost = serviceHost; _configuration = configuration; }
/// <summary> /// Perform diagnostic checks and return an instance of the <see cref="Message" /> class. /// </summary> /// <param name="configuration">Service configuration</param> /// <param name="serviceHost">HttpContext for the service</param> /// <returns>Result of the diagnostic checks</returns> internal static Message CreateDiagResponseMessage(SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) { // Check core msi presence by creating SyncKnowledge instance. DiagTestResult syncFxCoreCheck = CheckForSyncFxCore(); // Establish connnection to SQL Server. DiagTestResult sqlConnectionCheck = CheckSqlConnection(configuration); // Check database provisioning. DiagTestResult dbProvisionedCheck = CheckDbProvisioning(configuration); // Check for clientaccesspolicy.xml or crossdomain.xml file. //DiagTestResult clientAccessPolicyCheck = CheckForClientAccessPolicy(serviceHost); // Check presence of batching folder. DiagTestResult batchingFolderExistsResult = CheckBatchingFolderExists(configuration); // Check write access to batching folder. DiagTestResult writeAccessToBatchingFolder = CheckWriteAccessToBatchingFolder(configuration); // Add configuration related information var configElement = new XElement("Configuration", new XElement("ScopeName", HttpUtility.HtmlEncode(configuration.ScopeNames[0])), new XElement("ConflictResolution", configuration.ConflictResolutionPolicy), new XElement("SerializationFormat", configuration.SerializationFormat), new XElement("VerboseEnabled", configuration.UseVerboseErrors), new XElement("BatchingDirectory", configuration.DownloadBatchSizeInKB == null ? DiagConstants.BATCHING_NOT_ENABLED : configuration.BatchSpoolDirectory), new XElement("BatchSize", configuration.DownloadBatchSizeInKB == null ? DiagConstants.BATCHING_NOT_ENABLED : configuration.DownloadBatchSizeInKB.Value.ToString())); var diagXDocument = new XDocument(); var rootNode = new XElement("root"); diagXDocument.AddFirst(rootNode); // Add the results to the xml document. rootNode.Add( new XElement("SyncFxCore", new XElement("Result") { Value = syncFxCoreCheck.TestResult }, new XElement("ErrorInfo") { Value = syncFxCoreCheck.ExceptionDetails ?? String.Empty }), new XElement("SqlConnection", new XElement("Result") { Value = sqlConnectionCheck.TestResult }, new XElement("ErrorInfo") { Value = sqlConnectionCheck.ExceptionDetails ?? String.Empty }), new XElement("DbProvisioned", new XElement("Result") { Value = dbProvisionedCheck.TestResult }, new XElement("ErrorInfo") { Value = dbProvisionedCheck.ExceptionDetails ?? String.Empty }), new XElement("BatchingFolderPresent", new XElement("Result") { Value = batchingFolderExistsResult.TestResult }, new XElement("ErrorInfo") { Value = batchingFolderExistsResult.ExceptionDetails ?? String.Empty }), new XElement("WriteAccessToBatchingFolder", new XElement("Result") { Value = writeAccessToBatchingFolder.TestResult }, new XElement("ErrorInfo") { Value = writeAccessToBatchingFolder.ExceptionDetails ?? String.Empty }), //new XElement("PolicyFiles", // new XElement("Result") { Value = clientAccessPolicyCheck.TestResult }, // new XElement("ErrorInfo") { Value = clientAccessPolicyCheck.ExceptionDetails ?? String.Empty }), // Add the configuration node. new XElement(configElement)); // Create and cache the XslCompiledTransform if it is already not in the cache. ConfigureXslCompiledTransform(); Message message; using (XmlReader diagXmlReader = diagXDocument.CreateReader()) { var document = new XPathDocument(diagXmlReader); using (var writer = new StringWriter()) { // Transform the xml document into HTML. _compiledTransform.Transform(document, null, writer); // Create an return an instance of the Message class. message = Message.CreateMessage(MessageVersion.None, String.Empty, XDocument.Parse(writer.ToString()).CreateReader()); message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml)); var property = new HttpResponseMessageProperty { StatusCode = HttpStatusCode.OK }; property.Headers.Add(HttpResponseHeader.ContentType, SyncServiceConstants.CONTENT_TYPE_HTML); message.Properties.Add(HttpResponseMessageProperty.Name, property); } } return message; }
/// <summary>Check whether the website root has a ClientAccessPolicy.xml or CrossDomain.xml file.</summary> /// <returns>Result of the diagnostic check</returns> private static DiagTestResult CheckForClientAccessPolicy(HttpContextServiceHost serviceHost) { Debug.Assert(WebOperationContext.Current != null, "WebOperationContext.Current != null"); var result = new DiagTestResult(); try { Uri requestUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri; string requestHost = !String.IsNullOrEmpty(serviceHost.HostHeader) ? serviceHost.HostHeader : requestUri.Authority; // create the webroot string string webRoot = String.Format("{0}://{1}/", requestUri.Scheme, requestHost); var webRequest = (HttpWebRequest)WebRequest.Create(new Uri(webRoot + DiagConstants.CLIENT_ACCESS_POLICY_FILENAME)); webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); // First, attempt to retrieve the clientaccesspolicy.xml file. HttpWebResponse response = null; try { response = (HttpWebResponse)webRequest.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { result.TestResult = DiagConstants.FOUND_CLIENT_ACCESS_POLICY; } } catch (WebException) { // Continue and ignore this error. } if (result.TestResult != DiagConstants.FOUND_CLIENT_ACCESS_POLICY) { // Attempt to retrieve the crossdomain.xml file. webRequest = (HttpWebRequest) WebRequest.Create(new Uri(webRoot + DiagConstants.CROSS_DOMAIN_FILENAME)); webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); try { response = (HttpWebResponse)webRequest.GetResponse(); result.TestResult = response.StatusCode == HttpStatusCode.OK ? DiagConstants.FOUND_CROSSDOMAIN_POLICY_FILE : DiagConstants.CLIENT_ACCESS_POLICY_OR_CROSS_DOMAIN_NOT_FOUND; } catch (WebException exception) { // Could not find both clientaccesspolicy.xml and crossdomain.xml. result.TestResult = DiagConstants.CLIENT_ACCESS_POLICY_OR_CROSS_DOMAIN_NOT_FOUND; AddExceptionInfo(exception, result); } } } catch (Exception exception) { result.TestResult = DiagConstants.UNKNOWN_ERROR; AddExceptionInfo(exception, result); } return result; }
/// <summary> /// Perform diagnostic checks and return an instance of the <see cref="Message" /> class. /// </summary> /// <param name="configuration">Service configuration</param> /// <param name="serviceHost">HttpContext for the service</param> /// <returns>Result of the diagnostic checks</returns> internal static Message CreateDiagResponseMessage(SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) { // Check core msi presence by creating SyncKnowledge instance. DiagTestResult syncFxCoreCheck = CheckForSyncFxCore(); // Establish connnection to SQL Server. DiagTestResult sqlConnectionCheck = CheckSqlConnection(configuration); // Check database provisioning. DiagTestResult dbProvisionedCheck = CheckDbProvisioning(configuration); // Check for clientaccesspolicy.xml or crossdomain.xml file. DiagTestResult clientAccessPolicyCheck = CheckForClientAccessPolicy(serviceHost); // Check presence of batching folder. DiagTestResult batchingFolderExistsResult = CheckBatchingFolderExists(configuration); // Check write access to batching folder. DiagTestResult writeAccessToBatchingFolder = CheckWriteAccessToBatchingFolder(configuration); // Add configuration related information var configElement = new XElement("Configuration", new XElement("ScopeName", HttpUtility.HtmlEncode(configuration.ScopeNames[0])), new XElement("ConflictResolution", configuration.ConflictResolutionPolicy), new XElement("SerializationFormat", configuration.SerializationFormat), new XElement("VerboseEnabled", configuration.UseVerboseErrors), new XElement("BatchingDirectory", configuration.DownloadBatchSizeInKB == null ? DiagConstants.BATCHING_NOT_ENABLED : configuration.BatchSpoolDirectory), new XElement("BatchSize", configuration.DownloadBatchSizeInKB == null ? DiagConstants.BATCHING_NOT_ENABLED : configuration.DownloadBatchSizeInKB.Value.ToString())); var diagXDocument = new XDocument(); var rootNode = new XElement("root"); diagXDocument.AddFirst(rootNode); // Add the results to the xml document. rootNode.Add( new XElement("SyncFxCore", new XElement("Result") { Value = syncFxCoreCheck.TestResult }, new XElement("ErrorInfo") { Value = syncFxCoreCheck.ExceptionDetails ?? String.Empty }), new XElement("SqlConnection", new XElement("Result") { Value = sqlConnectionCheck.TestResult }, new XElement("ErrorInfo") { Value = sqlConnectionCheck.ExceptionDetails ?? String.Empty }), new XElement("DbProvisioned", new XElement("Result") { Value = dbProvisionedCheck.TestResult }, new XElement("ErrorInfo") { Value = dbProvisionedCheck.ExceptionDetails ?? String.Empty }), new XElement("BatchingFolderPresent", new XElement("Result") { Value = batchingFolderExistsResult.TestResult }, new XElement("ErrorInfo") { Value = batchingFolderExistsResult.ExceptionDetails ?? String.Empty }), new XElement("WriteAccessToBatchingFolder", new XElement("Result") { Value = writeAccessToBatchingFolder.TestResult }, new XElement("ErrorInfo") { Value = writeAccessToBatchingFolder.ExceptionDetails ?? String.Empty }), new XElement("PolicyFiles", new XElement("Result") { Value = clientAccessPolicyCheck.TestResult }, new XElement("ErrorInfo") { Value = clientAccessPolicyCheck.ExceptionDetails ?? String.Empty }), // Add the configuration node. new XElement(configElement)); // Create and cache the XslCompiledTransform if it is already not in the cache. ConfigureXslCompiledTransform(); Message message; using (XmlReader diagXmlReader = diagXDocument.CreateReader()) { var document = new XPathDocument(diagXmlReader); using (var writer = new StringWriter()) { // Transform the xml document into HTML. _compiledTransform.Transform(document, null, writer); // Create an return an instance of the Message class. message = Message.CreateMessage(MessageVersion.None, String.Empty, XDocument.Parse(writer.ToString()).CreateReader()); message.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml)); var property = new HttpResponseMessageProperty { StatusCode = HttpStatusCode.OK }; property.Headers.Add(HttpResponseHeader.ContentType, SyncServiceConstants.CONTENT_TYPE_HTML); message.Properties.Add(HttpResponseMessageProperty.Name, property); } } return(message); }
/// <summary>Check whether the website root has a ClientAccessPolicy.xml or CrossDomain.xml file.</summary> /// <returns>Result of the diagnostic check</returns> private static DiagTestResult CheckForClientAccessPolicy(HttpContextServiceHost serviceHost) { Debug.Assert(WebOperationContext.Current != null, "WebOperationContext.Current != null"); var result = new DiagTestResult(); try { Uri requestUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri; string requestHost = !String.IsNullOrEmpty(serviceHost.HostHeader) ? serviceHost.HostHeader : requestUri.Authority; // create the webroot string string webRoot = String.Format("{0}://{1}/", requestUri.Scheme, requestHost); var webRequest = (HttpWebRequest)WebRequest.Create(new Uri(webRoot + DiagConstants.CLIENT_ACCESS_POLICY_FILENAME)); webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); // First, attempt to retrieve the clientaccesspolicy.xml file. HttpWebResponse response = null; try { response = (HttpWebResponse)webRequest.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { result.TestResult = DiagConstants.FOUND_CLIENT_ACCESS_POLICY; } } catch (WebException) { // Continue and ignore this error. } if (result.TestResult != DiagConstants.FOUND_CLIENT_ACCESS_POLICY) { // Attempt to retrieve the crossdomain.xml file. webRequest = (HttpWebRequest)WebRequest.Create(new Uri(webRoot + DiagConstants.CROSS_DOMAIN_FILENAME)); webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); try { response = (HttpWebResponse)webRequest.GetResponse(); result.TestResult = response.StatusCode == HttpStatusCode.OK ? DiagConstants.FOUND_CROSSDOMAIN_POLICY_FILE : DiagConstants.CLIENT_ACCESS_POLICY_OR_CROSS_DOMAIN_NOT_FOUND; } catch (WebException exception) { // Could not find both clientaccesspolicy.xml and crossdomain.xml. result.TestResult = DiagConstants.CLIENT_ACCESS_POLICY_OR_CROSS_DOMAIN_NOT_FOUND; AddExceptionInfo(exception, result); } } } catch (Exception exception) { result.TestResult = DiagConstants.UNKNOWN_ERROR; AddExceptionInfo(exception, result); } return(result); }
private System.IO.Stream MessageToStream(HttpContextServiceHost ctx, Message message) { System.IO.Stream ms = new System.IO.MemoryStream(); using (System.IO.Stream tempms = new System.IO.MemoryStream()) { using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(tempms)) { message.WriteMessage(writer); writer.Flush(); } ctx.OriginalContentLength = (int)tempms.Length; tempms.Position = 0; using (System.IO.Compression.GZipStream gzip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress, true)) { tempms.CopyTo(gzip); } } ms.Position = 0; return ms; }
public UploadChangesRequestProcessor(SyncServiceConfiguration configuration, HttpContextServiceHost serviceHost) : base(configuration, serviceHost) { base._syncOperation = SyncOperations.Upload; }