Beispiel #1
0
        /// <summary> Get the initial response from the execution properties. </summary>
        /// <returns>initial response string</returns>
        internal String GetLastOfflineInitialResponse()
        {
            //Extract and decode the initial response from the execution properties
            IEncryptor encryptor              = PersistentOnlyCacheManager.GetInstance();
            String     initialResponseString  = null;
            int        lastOfflineFileVersion = LastOfflineFileVersion;

            byte[] initialResponseBytes = Encoding.Default.GetBytes(LastOfflineExecutionProperties[ConstInterface.INITIAL_RESPONSE]);

            if (encryptor.EncryptionDisabled)
            {
                initialResponseString = Encoding.UTF8.GetString(initialResponseBytes, 0, initialResponseBytes.Length);
            }
            else
            {
                if (lastOfflineFileVersion == 1)
                {
                    initialResponseBytes = Base64.decodeToByte(Encoding.ASCII.GetString(initialResponseBytes, 0, initialResponseBytes.Length));
                }

                initialResponseBytes  = encryptor.Decrypt(initialResponseBytes);
                initialResponseString = Encoding.UTF8.GetString(initialResponseBytes, 0, initialResponseBytes.Length);
            }

            return(initialResponseString);
        }
        /// <summary>
        /// writes content to temporary file.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="content"></param>
        private void WriteToTemporarySourceFile(String url, byte[] content)
        {
            // extract file url & remote time
            String tempSourceFileUrl = BuildTemporarySourceFileName(GetFileNameFromURL(url));
            String remoteTime        = GetRemoteTime(url);

            PersistentOnlyCacheManager.GetInstance().PutFile(tempSourceFileUrl, content, remoteTime);
        }
Beispiel #3
0
        /// <summary> Get the contents from the previously cached contents from the requested URL</summary>
        /// <param name="completeCachedFileRetrievalURL">complete cached file retrieval request (including the server-side time stamp),
        /// e.g. http://[server]/[requester]?CTX=&CACHE=My Application_DbhDataIds.xml|31/07/2013%2020:15:15</param>
        /// <param name="decryptResponse">if true, the contents will be be decrypted using the 'encryptionKey' passed to 'PersistentOnlyCacheManager.SetProperties'.</param>
        /// <returns></returns>
        internal override byte[] GetContent(string completeCachedFileRetrievalURL, bool decryptResponse)
        {
            //TODO: Kaushal. Most of this code is similar to that in HttpManager.GetContent().
            //Check if this duplication can be avoided.
            String remoteTime = null;

            byte[] response          = null;
            int    indexOfCacheToken = completeCachedFileRetrievalURL.IndexOf(ConstInterface.RC_TOKEN_CACHED_FILE);

            //In disconnected state, we should reach here only for the cached files.
            Debug.Assert(indexOfCacheToken != -1);

            // split the url --> url and remote time
            string[] urlAndRemoteTimePair   = HttpUtility.UrlDecode(completeCachedFileRetrievalURL, Encoding.UTF8).Split('|');
            String   cachedFileRetrievalURL = urlAndRemoteTimePair[0]; // the cached file retrieval request without the timestamp, e.g. http://[server]/[requester]?CTX=&CACHE=MG1VAI3T_MP_0$$$_$_$_N02400$$$$G8FM01_.xml
            string   cachedFileLocalURL     = CacheUtils.URLToFileName(cachedFileRetrievalURL);

            if (urlAndRemoteTimePair.Length > 1 && urlAndRemoteTimePair[1] != null)
            {
                remoteTime = urlAndRemoteTimePair[1];

                //is the file encrypted?
                int indexOfNonEncryptedToken = remoteTime.IndexOf(ConstInterface.RC_TOKEN_NON_ENCRYPTED);
                if (indexOfNonEncryptedToken != -1)
                {
                    decryptResponse = false;
                    remoteTime      = remoteTime.Substring(0, indexOfNonEncryptedToken - 1);
                }
            }

            ICacheManager cacheManager = PersistentOnlyCacheManager.GetInstance();

            if (remoteTime == null)
            {
                response = cacheManager.GetFile(cachedFileLocalURL);
            }
            else
            {
                response = cacheManager.GetFile(cachedFileLocalURL, remoteTime);
            }

            if (response != null)
            {
                if (decryptResponse)
                {
                    IEncryptor encryptor = PersistentOnlyCacheManager.GetInstance();
                    response = encryptor.Decrypt(response);
                }
            }
            else
            {
                throw new LocalSourceNotFoundException("Some of the required files are missing. Please restart the application when connected to the network.");
            }

            return(response);
        }
Beispiel #4
0
 /// <summary>
 /// record an offline-required metadata + its local time
 /// </summary>
 /// <param name="requestedURL">complete cache file retrieval request to an offline-required metadata,
 /// e.g. http://[server]/[requester]?CTX=&CACHE=MG1VAI3T_MP_0$$$_$_$_N02400$$$$G8FM01_.xml|31/07/2013%2020:15:15</param>
 internal void Collect(string requestedURL)
 {
     if (Enabled)
     {
         string cachedFileServerFileName;
         string cachedFileLocalFileName;
         PersistentOnlyCacheManager.GetInstance().CompleteCacheRequestURLToFileNames(requestedURL, out cachedFileServerFileName, out cachedFileLocalFileName);
         Debug.Assert(HandleFiles.isExists(cachedFileLocalFileName));
         CollectedMetadata[cachedFileServerFileName] = HandleFiles.getFileTime(cachedFileLocalFileName);
     }
 }
        /// <summary>
        /// Reads the sources from server and writes its content to temporary sources.
        /// For Local session reads sources from cache.
        /// </summary>
        /// <param name="completeCachedFileRetrievalURL">complete cached file retrieval request (including the server-side time stamp),
        /// e.g. http://[server]/[requester]?CTX=&CACHE=MG1VAI3T_MP_0$$$_$_$_N02400$$$$G8FM01_.xml|31/07/2013%2020:15:15</param>
        /// <param name="cachedContentShouldBeReturned">if false, the method will return null as the retrieved content (avoiding retrieval of the requested URL from the local/client cache folder, to save resources / improve performance).</param>
        /// <param name="allowOutdatedContent">if true, check only file existence at client cache</param>
        /// <returns>content</returns>
        internal byte[] ReadSource(String completeCachedFileRetrievalURL, bool cachedContentShouldBeReturned, bool allowOutdatedContent)
        {
            Logger.Instance.WriteSupportToLog("ReadSource():>>>>> ", true);

            byte[] content = null;

            if (_enableSourcesIntegrity && CommandsProcessorManager.SessionStatus == CommandsProcessorManager.SessionStatusEnum.Remote)
            {
                var cachingStrategy = new HttpManager.CachingStrategy()
                {
                    CanWriteToCache = false, CachedContentShouldBeReturned = cachedContentShouldBeReturned, AllowOutdatedContent = allowOutdatedContent
                };
                content = RemoteCommandsProcessor.GetInstance().GetContent(completeCachedFileRetrievalURL, null, null, false, cachingStrategy);

                // if sources were modified (i.e. not retrieved from the cache), save the content to a temporary file:
                if (!cachingStrategy.FoundInCache)
                {
                    WriteToTemporarySourceFile(completeCachedFileRetrievalURL, content);
                    _commitList.Add(completeCachedFileRetrievalURL);
                }
                else
                {
                    // record/register a cached file path + its local time:
                    OfflineRequiredMetadataCollection.Collect(completeCachedFileRetrievalURL);
                }

                if (cachedContentShouldBeReturned)
                {
                    content = PersistentOnlyCacheManager.GetInstance().Decrypt(content);
                }
            }
            else
            {
                if (cachedContentShouldBeReturned)
                {
                    content = CommandsProcessorManager.GetContent(completeCachedFileRetrievalURL, true);
                }
                else
                {
                    if (!PersistentOnlyCacheManager.GetInstance().IsCompleteCacheRequestURLExistsLocally(completeCachedFileRetrievalURL))
                    {
                        throw new LocalSourceNotFoundException("Some of the required files are missing. Please restart the application when connected to the network."); //TODO: use a message from mgconst - here as well as in LocalCommandsProcessor.GetContent
                    }
                }

                // record/register a cached file path + its local time:
                OfflineRequiredMetadataCollection.Collect(completeCachedFileRetrievalURL);
            }

            Logger.Instance.WriteSupportToLog("ReadSource():<<<< ", true);
            return(content);
        }
Beispiel #6
0
        /// <summary>
        /// Read old data source repository
        /// </summary>
        /// <param name="dataDefinitionIdsUrl"> repository url to read old repository </param>
        /// <returns>returns old data source repository only if it is modified</returns>
        private DataSourceDefinitionManager GetOldDataSourceDefinitions(String dataDefinitionIdsUrl)
        {
            DataSourceDefinitionManager oldDataSourceDefinitionManager = null;

            try
            {
                // Get old data source repository url from last offline response
                String oldDataDefinitionIdsUrl = GetLastDataSourcesIdUrl();

                // Last offline response can not be available if startup program is modified or in case of executing non-offline program.
                // In this case , read the repository file available in cache without remote time constraint
                if (oldDataDefinitionIdsUrl == null)
                {
                    // split the url --> url and remote time
                    string[] urlAndRemoteTimePair = HttpUtility.UrlDecode(dataDefinitionIdsUrl, Encoding.UTF8).Split('|');
                    oldDataDefinitionIdsUrl = urlAndRemoteTimePair[0];
                }

                // read content form data source repository
                byte[] oldRepositoryContents = null;
                // the old (i.e. without the '_tmp' suffix) DbhDataIds may not be found in case this is the first access to the application.
                if (PersistentOnlyCacheManager.GetInstance().IsCompleteCacheRequestURLExistsLocally(oldDataDefinitionIdsUrl))
                {
                    oldRepositoryContents = LocalCommandsProcessor.GetInstance().GetContent(oldDataDefinitionIdsUrl, true);
                }

                // if contents are modified then return old data source repository
                if (oldRepositoryContents != null && (oldRepositoryContents.Length != NewDataSourceRepositoryContents.Length ||
                                                      !Misc.CompareByteArray(oldRepositoryContents, NewDataSourceRepositoryContents, NewDataSourceRepositoryContents.Length)))
                {
                    // parse repository content and read data sources and build the data source definition collection
                    oldDataSourceDefinitionManager = new DataSourceDefinitionManager();
                    oldDataSourceDefinitionManager.DataSourceBuilder.DataSourceReader = GetOldDataSourceBuffer;
                    new DataSourceDefinitionManagerSaxHandler(oldRepositoryContents, oldDataSourceDefinitionManager);
                }

                // new repository contents are not needed more for datasource converter
                NewDataSourceRepositoryContents = null;
            }
            catch (Exception ex)
            {
                Logger.Instance.WriteExceptionToLog(ex);
            }

            CommandsProcessorManager.SessionStatus = CommandsProcessorManager.SessionStatusEnum.Remote;

            return(oldDataSourceDefinitionManager);
        }
Beispiel #7
0
        /// <summary>
        ///  Initializes the encryptor that handles encryption/decryption of cached content (this functionality is currently embedded in the PersistentOnlyCacheManager..)
        /// </summary>
        internal void InitializeEncryptor()
        {
            // retrieve the required encryption state (enabled/disabled) and key:
            bool   disableEncryption = GetLastOfflineExecutionPropertyBool(ConstInterface.DISABLE_ENCRYPTION);
            string encryptionKeyStr  = LastOfflineExecutionProperties.getProperty(ConstInterface.ENCRYPTION_KEY);

            byte[] encryptionKey = null;

            if (!String.IsNullOrEmpty(encryptionKeyStr))
            {
                // TODO: Scrambling the encryption key in the execution.properties_LastOffline file is not secured enough!
                encryptionKeyStr = Scrambler.UnScramble(encryptionKeyStr, 0, encryptionKeyStr.Length - 1);
                encryptionKey    = Encoding.Default.GetBytes(encryptionKeyStr);
            }

            // initialize the encryptor:
            IEncryptor encryptor = PersistentOnlyCacheManager.CreateInstance(disableEncryption, encryptionKey);
        }
        /// <summary>
        /// commit modified sources to cache.
        /// </summary>
        internal void Commit()
        {
            Logger.Instance.WriteSupportToLog("Commit():>>>> ", true);

            bool success = true;

            // It is about to start committing the sources. So save the status. If process get terminated during commit,
            // in next execution, client will get to know the status of sources synchronization and take action accordingly.
            SourcesSyncStatus.InvalidSources = true;
            SourcesSyncStatus.SaveToFile();

            // Renames the temporary sources to original names.
            foreach (String url in _commitList)
            {
                String tempFileName               = BuildTemporarySourceFileName(GetFileNameFromURL(url));
                String tempSourceFileFullName     = PersistentOnlyCacheManager.GetInstance().URLToLocalFileName(tempFileName);
                String originalSourceFileFullName = PersistentOnlyCacheManager.GetInstance().URLToLocalFileName(GetFileNameFromURL(url));
                String remoteTime = GetRemoteTime(url);

                // check if source with remotetime exist
                if (IsFileExistWithRequestedTime(tempSourceFileFullName, remoteTime))
                {
                    Logger.Instance.WriteSupportToLog(String.Format("commit(): renaming {0}", tempFileName), true);

                    success = HandleFiles.renameFile(tempSourceFileFullName, originalSourceFileFullName);
                    if (!success)
                    {
                        break;
                    }

                    if (remoteTime != null)
                    {
                        HandleFiles.setFileTime(originalSourceFileFullName, remoteTime);
                    }

                    // record/register a cached file path + its local time:
                    OfflineRequiredMetadataCollection.Collect(url);
                }
            }

            if (!success)
            {
                String errorMessage;

                // sources commit failed
                // If tables were converted and committed, there structure won't match the sources
                if (SourcesSyncStatus.TablesIncompatibleWithDataSources == true)
                {
                    errorMessage = ClientManager.Instance.getMessageString(MsgInterface.RC_ERROR_INCOMPATIBLE_DATASOURCES);
                }
                else
                {
                    errorMessage = ClientManager.Instance.getMessageString(MsgInterface.RC_ERROR_INVALID_SOURCES);
                }

                throw new InvalidSourcesException(errorMessage, null);
            }

            // Commit is done successfully, clear the status.
            SourcesSyncStatus.Clear();

            Logger.Instance.WriteSupportToLog("Commit():<<<< ", true);
        }
Beispiel #9
0
        /// <summary> interact with the cache manager; execute HTTP request if needed; if 'decryptResponse' is true, fresh
        /// responses from the server will be decrypted (if needed) using the 'encryptionKey' passed to 'setProperties'; </summary>
        /// <param name="requestedURL">URL to be accessed. If the URL contains a time stamp on the server-side (|timestamp), the time stamp is seperated from the URL and checked against the local/client-side cache.</param>
        /// <param name="requestContent">content to be sent to server (relevant only for POST method - is null for other methods). may be byte[] or string.</param>
        /// <param name="requestContentType">type of the content to be sent to server, e.g application/octet-stream (for POST method only).</param>
        /// <param name="decryptResponse">if true, fresh responses from the server will be decrypted using the 'encryptionKey' passed to 'HttpManager.SetProperties'.</param>
        /// <param name="allowRetry">whether or not retry after connection failure.</param>
        /// <param name="cachingStrategy">Enabels or disables cache read/write operations.</param>
        /// <param name="isError">set to true if server returns error processing the request.</param>
        /// <returns>response (from the server).</returns>
        internal byte[] GetContent(String requestedURL, object requestContent, String requestContentType, bool decryptResponse, bool allowRetry,
                                   CachingStrategy cachingStrategy, out bool isError)
        {
            String urlCachedByRequest = null; // a cached file retrieval request without the timestamp, e.g. http://[server]/[requester]?CTX=&CACHE=MG1VAI3T_MP_0$$$_$_$_N02400$$$$G8FM01_.xml

            byte[]   response         = null;
            long     startTime        = Misc.getSystemMilliseconds();
            TimeSpan requestStartTime = DateTime.Now.TimeOfDay; // for RecentNetworkActivities only
            bool     isCacheRequest   = false;

            try
            {
                Logger.Instance.WriteServerToLog(
                    "*************************************************************************************************");

                cachingStrategy.FoundInCache = false;
                isError = false;

                String remoteTime = null;

                // GET request
                if (requestContent == null)
                {
                    //--------------------------------------------------------------------------------------------
                    // topic #16 (MAGIC version 1.8 for WIN) RC - Cache security enhancements:
                    //   the server reports the time stamp as part as the URL, for example:
                    //      http://../mgrqispi.dll?CTX=155842418385&CACHE=KeyboardMapping.xml%7C19/03/2009%2009:45:33
                    //   cache files are accessed via a request, in this example:
                    //      http://myserver/MagicScripts/mgrqispi.dll?CTX=155842418385&CACHE=KeyboardMapping.xml
                    //                                                               ^ indexOfCacheToken
                    //--------------------------------------------------------------------------------------------
                    // extract the remote time from the request
                    int indexOfCacheToken = requestedURL.IndexOf(ConstInterface.RC_TOKEN_CACHED_FILE);
                    if (indexOfCacheToken != -1)
                    {
                        isCacheRequest = true;
                        string decodedUrl = HttpUtility.UrlDecode(requestedURL, Encoding.UTF8);
                        requestedURL = CacheUtils.URLToFileName(decodedUrl);

                        string cacheFilePath = String.Empty;
                        CacheUtils.GetCacheFileDetailsFromUrl(decodedUrl, ref cacheFilePath, ref remoteTime, ref decryptResponse);

                        byte[]     bufferToSend = Encoding.UTF8.GetBytes(cacheFilePath);
                        IEncryptor encryptor    = PersistentOnlyCacheManager.GetInstance();
                        if (!encryptor.EncryptionDisabled)
                        {
                            byte[] encryptedURL = encryptor.Encrypt(Encoding.UTF8.GetBytes(cacheFilePath));
                            byte[] base64EncodedEncryptedURL = Base64.encode(encryptedURL);
                            bufferToSend = base64EncodedEncryptedURL;
                        }
                        // prepare URL again by encoding only CACHE value
                        urlCachedByRequest = decodedUrl.Substring(0, indexOfCacheToken) +
                                             ConstInterface.RC_INDICATION +
                                             ConstInterface.RC_TOKEN_CACHED_FILE +
                                             HttpUtility.UrlEncode(bufferToSend);
                    }
                    else if (requestedURL.IndexOf('?') == -1)
                    {
                        // i.e. the url refers to a file on the web server, rather than a requester + query string
                        remoteTime = _httpClient.GetRemoteTime(requestedURL);
                    }
                }

                Logger.Instance.WriteServerToLog(requestedURL);

                byte[] errorResponse = null;
                // Story#138618: remoteTime will not exist in the cache url.
                // (for backward compatibility remoteTime exist in url if  SpecialTimeStampRIACache is ON)
                if (remoteTime == null && !isCacheRequest)
                {
                    // resources for which no remote time could be retrieved (either by the web server or by the runtime-engine, in a cache request url) can't be and aren't cached,
                    // since without a time stamp the client can't decide if the client-side copy is out-dated.
                    //-----------------------------

                    LogAccessToServer("", requestContent);
                    response = GetContentByHTTPRequest(requestedURL, requestContent, requestContentType, allowRetry);
                    Debug.Assert(response != null);
                    errorResponse = CheckAndGetErrorResponse(response);
                }
                else
                {
                    // cachable resources ..
                    //----------------------

                    ICacheManager cacheManager = PersistentOnlyCacheManager.GetInstance();
                    if (cachingStrategy.CachedContentShouldBeReturned)
                    {
                        response = (remoteTime == null
                                ? cacheManager.GetFile(requestedURL)
                                : cacheManager.GetFile(requestedURL, remoteTime));
                        cachingStrategy.FoundInCache = (response != null);
                    }
                    else
                    {
                        // here 'requestedURL' is excluding the server-side time stamp, e.g. /MG1VAI3T_MP_0$$$_$_$_N02400$$$$G8FM01_.xml.
                        Debug.Assert(requestedURL.IndexOf('|') == -1);
                        cachingStrategy.FoundInCache = (cachingStrategy.AllowOutdatedContent || remoteTime == null
                                                      ? cacheManager.IsExists(requestedURL)
                                                      : cacheManager.CheckFile(requestedURL, remoteTime));
                    }

                    if (cachingStrategy.FoundInCache)
                    {
                        Logger.Instance.WriteServerToLog("Found in cache.");
                    }
                    else
                    {
                        LogAccessToServer(String.Format("Not in cache{0}!", cachingStrategy.AllowOutdatedContent ? "" : " or outdated"), null);

                        // get fresh content & put in the cache
                        response = GetContentByHTTPRequest((urlCachedByRequest ?? requestedURL), null, requestContentType, allowRetry);
                        if (response != null)
                        {
                            errorResponse = CheckAndGetErrorResponse(response);

                            // do not save the file, if there is an error.
                            if (errorResponse == null && cachingStrategy.CanWriteToCache)
                            {
                                cacheManager.PutFile(requestedURL, response, remoteTime);
                            }
                        }
                    }
                }

                //Error messages are never encrypted. So, do not decrypt them.
                if (errorResponse != null)
                {
                    response = errorResponse;
                    isError  = true;
                }
                else if (decryptResponse && response != null)
                {
                    IEncryptor encryptor = PersistentOnlyCacheManager.GetInstance();
                    response = encryptor.Decrypt(response);
                }

#if PocketPC
                GUIMain.getInstance().MainForm.updateProgressBar();
#endif

                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message + OSEnvironment.EolSeq +
                                    (new Uri((urlCachedByRequest ?? requestedURL))).GetLeftPart(UriPartial.Path), ex);
            }
            finally
            {
                //collect statistics
                var elapsedTime = (uint)(Misc.getSystemMilliseconds() - startTime);

                // !foundInCache ==> the request was executed by the HTTP client ==> should be recorded
                if (!cachingStrategy.FoundInCache)
                {
                    Statistics.RecordRequest(elapsedTime,
                                             (ulong)(requestContent != null
                                                    ? HttpClient.GetRequestContentLength(requestContent)
                                                    : 0),
                                             (ulong)(response != null
                                                    ? response.Length
                                                    : 0));
                }
                Logger.Instance.WriteServerToLog(
                    string.Format(
                        "Completed {0}: {1:N0} ms, accumulated: {2:N0} ms (server: {3:N0}), {4}{5}{6}**************************************************************************************************",
                        (cachingStrategy.FoundInCache
                      ? ""
                      : string.Format("#{0:N0}", Statistics.GetRequestsCnt())
                        ),
                        elapsedTime,
                        Statistics.GetAccumulatedExternalTime(), Statistics.GetAccumulatedServerTime(),
                        (cachingStrategy.FoundInCache
                      ? ""
                      : (response != null
                            ? string.Format("{0:N0} bytes downloaded", response.Length)
                            : "Null response!")
                        ),
                        OSEnvironment.EolSeq, OSEnvironment.TabSeq)
                    );
                if (!cachingStrategy.FoundInCache && ClientManager.Instance.getDisplayStatisticInfo())
                {
                    // Add the networking activity.
                    var downloadSizeKB = (ulong)(response != null
                                                ? response.Length
                                                : 0);
                    RecentNetworkActivities.Append(Statistics.GetRequestsCnt(), requestStartTime, elapsedTime, downloadSizeKB, requestedURL);
                }
            }
        }