Class used to convert a HttpRequest into a single long value that is almost unique for the requesting device. Two devices that share the same external IP address and HTTP headers will calculate to the same long value so it may not always be unique. The number of handsets that fall into this category should be sufficiently small enough for it not to present a practical problem. The date and time the request was received is also recorded to enable out of date records to be removed from the list.
Inheritance: IComparable
Beispiel #1
0
        /// <summary>
        /// Compares one request to another to determine if they are the same.
        /// </summary>
        /// <param name="obj">The object being compared.</param>
        /// <returns>If the object contains the same value as this instance.</returns>
        public int CompareTo(object obj)
        {
            RequestRecord candidate = obj as RequestRecord;

            if (candidate != null)
            {
                if (candidate.LastActiveDate < LastActiveDate)
                {
                    return(-1);
                }
                if (candidate.LastActiveDate > LastActiveDate)
                {
                    return(1);
                }
                if (candidate.Key < Key)
                {
                    return(-1);
                }
                if (candidate.Key > Key)
                {
                    return(1);
                }
                return(0);
            }
            throw new MobileException(
                      String.Format(
                          "Can not compare object of type '{0}' with '{1}'.",
                          obj.GetType(),
                          GetType()));
        }
Beispiel #2
0
        /// <summary>
        /// Read the records that should be retained in the sync file.
        /// </summary>
        /// <param name="stream">Stream for the sync file.</param>
        /// <param name="purgeDate">Date before which records should be removed.</param>
        /// <returns></returns>
        private static byte[] ReadRecords(FileStream stream, long purgeDate)
        {
            byte[]        buffer = null;
            long          offset = 0;
            BinaryReader  reader = new BinaryReader(stream);
            RequestRecord record = new RequestRecord();

            stream.Position = 0;
            for (offset = 0; offset < stream.Length; offset += RECORD_LENGTH)
            {
                record.Read(reader);
                // Check to see if the current record is newer than the purgeDate
                // and isn't equal to zero. Zero date indicates the record should be
                // removed from the history.
                if (record.LastActiveDate > purgeDate && record.LastActiveDate != 0)
                {
                    break;
                }
            }

            if (offset > 0 && offset < stream.Length)
            {
                int length = (int)(stream.Length - offset);
                buffer          = new byte[length];
                stream.Position = offset;
                stream.Read(buffer, 0, length);
            }

            return(buffer);
        }
Beispiel #3
0
        /// <summary>
        /// Checks to find out if the device associated with the HttpRequest
        /// has already been seen by the application. Always returns false
        /// if the sync file has not been specified.
        /// </summary>
        /// <param name="request">HttpRequest to be checked.</param>
        /// <returns>True if the device associated with the request has been seen.</returns>
        public bool IsPresent(HttpRequest request)
        {
            if (_syncFilePath != null)
            {
                RequestRecord record = new RequestRecord(request);

                // Check to see if new request data needs to be loaded.
                RefreshSyncFile();

                long expiryDateTime;
                if (_previous.Requests.TryGetValue(record.Key, out expiryDateTime))
                {
                    // If redirect timeout is zero then simply check to see if the
                    // device is present in the list of previous devices.
                    if (_redirectTimeout == 0)
                    {
                        return(true);
                    }

                    // Is it still valid?
                    return((new DateTime(expiryDateTime).AddMinutes(_redirectTimeout)).Ticks >=
                           record.LastActiveDate);
                }
            }
            return(false);
        }
Beispiel #4
0
        /// <summary>
        /// Adds this device request to the previous devices list.
        /// </summary>
        /// <param name="request">HttpRequest of the device.</param>
        public void Set(HttpRequest request)
        {
            if (_syncFilePath != null)
            {
                RequestRecord record = new RequestRecord(request);

                // Get the latest data.
                RefreshSyncFile();

                // Add this most recent request to the sync file.
                Add(record);

                // Check if the sync file needs to be serviced.
                CheckIfServiceRequired();
            }
        }
Beispiel #5
0
        /// <summary>
        /// Removes this device request from the previous devices list.
        /// </summary>
        /// <param name="request">HttpRequest of the device.</param>
        public void Remove(HttpRequest request)
        {
            if (_syncFilePath != null)
            {
                RequestRecord record = new RequestRecord(request);

                // Get the latest data.
                RefreshSyncFile();

                // Does the device exist in the previous devices list?
                if (_previous.Requests.ContainsKey(record.Key))
                {
                    // Set the last active date to zero so that it will be
                    // removed when the sync file is serviced.
                    record.LastActiveDate = 0;

                    // Add this most recent request to the sync file.
                    Add(record);
                }
            }
        }
Beispiel #6
0
        private void ProcessSyncFile()
        {
            // Record if the sync file exists to avoid repeated calls
            // to the operating system.
            if (_syncFileExists == false)
            {
                _syncFileExists = File.Exists(_syncFilePath);
            }

            if (_syncFileExists)
            {
                // Used to indicate if the process should be repeated.
                bool repeatProcess = false;

                // Lock the list of devices we're about to update to ensure they can't be
                // changed by subsequent requests to this callback.
                lock (_previous.Requests)
                {
                    // Open the sync file for read access ensuring it's disposed
                    // as soon as possible.
                    FileStream stream = OpenSyncFilePath(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    if (stream != null)
                    {
                        // Record the length of the file so that if it changes we can abandon this
                        // update and rely on a subsequent call to this methd to complete
                        // processing.
                        using (BinaryReader reader = new BinaryReader(stream))
                        {
                            long          length      = stream.Length;
                            RequestRecord record      = new RequestRecord();
                            RequestRecord firstDevice = null;
                            long          rows        = length / RECORD_LENGTH;
                            for (long row = 0; row < rows; row++)
                            {
                                // Read the current row in reverse order. Capture EOF exceptions
                                // in case the file length has changed since we started processing.
                                try
                                {
                                    stream.Position = ((rows - row) * RECORD_LENGTH) - RECORD_LENGTH;
                                    record.Read(reader);
                                }
                                catch (EndOfStreamException ex)
                                {
                                    // The file has been trimmed by another process. Break and
                                    // allow the resulting call to this event to complete
                                    // processing.
                                    EventLog.Debug(ex);
                                    break;
                                }

                                // If the current record is the same as the last one we got last time
                                // this method was called then stop processing more records.
                                if (record.CompareTo(_previous.lastRequest) == 0)
                                {
                                    break;
                                }

                                // Update the memory version.
                                if (record.LastActiveDate == 0)
                                {
                                    // Remove from the device as the last active date is zero.
                                    _previous.Requests.Remove(record.Key);
                                }
                                else
                                {
                                    // Update or insert a new record.
                                    if (_previous.Requests.ContainsKey(record.Key))
                                    {
                                        _previous.Requests[record.Key] = record.LastActiveDate;
                                    }
                                    else
                                    {
                                        _previous.Requests.Add(record.Key, record.LastActiveDate);
                                    }
                                }

                                if (firstDevice == null)
                                {
                                    firstDevice = new RequestRecord(record);
                                }
                            }
                            // If the length of the file hasn't changed during the processing
                            // then update the last device record to limit the number of rows
                            // examined in future file changes.
                            if (length == stream.Length && firstDevice != null)
                            {
                                _previous.lastRequest = firstDevice;
                            }

                            // Signal to all the method again if the length of the file
                            // has changed during processing.
                            repeatProcess = length != stream.Length;
                        }
                    }
                }
                // If the file was altered during the processing then call the method
                // again to capture any new records.
                if (repeatProcess)
                {
                    ProcessSyncFile();
                }
            }
        }
 /// <summary>
 /// Constructs a new instance of <see cref="RequestRecord"/> class.
 /// Copies the values of the <see cref="RequestRecord"/> provided to
 /// the new instance.
 /// </summary>
 /// <param name="recordToCopy"></param>
 protected internal RequestRecord(RequestRecord recordToCopy)
 {
     _key = recordToCopy.Key;
     _lastActiveDate = recordToCopy.LastActiveDate;
 }
Beispiel #8
0
 /// <summary>
 /// Constructs a new instance of <see cref="RequestRecord"/> class.
 /// Copies the values of the <see cref="RequestRecord"/> provided to
 /// the new instance.
 /// </summary>
 /// <param name="recordToCopy"></param>
 protected internal RequestRecord(RequestRecord recordToCopy)
 {
     _key            = recordToCopy.Key;
     _lastActiveDate = recordToCopy.LastActiveDate;
 }
        /// <summary>
        /// Read the records that should be retained in the sync file.
        /// </summary>
        /// <param name="stream">Stream for the sync file.</param>
        /// <param name="purgeDate">Date before which records should be removed.</param>
        /// <returns></returns>
        private static byte[] ReadRecords(FileStream stream, long purgeDate)
        {
            byte[] buffer = null;
            long offset = 0;
            BinaryReader reader = new BinaryReader(stream);
            RequestRecord record = new RequestRecord();
            stream.Position = 0;
            for (offset = 0; offset < stream.Length; offset += RECORD_LENGTH)
            {
                record.Read(reader);
                // Check to see if the current record is newer than the purgeDate
                // and isn't equal to zero. Zero date indicates the record should be
                // removed from the history.
                if (record.LastActiveDate > purgeDate && record.LastActiveDate != 0)
                    break;
            }

            if (offset > 0 && offset < stream.Length)
            {
                int length = (int) (stream.Length - offset);
                buffer = new byte[length];
                stream.Position = offset;
                stream.Read(buffer, 0, length);
            }

            return buffer;
        }
        private void ProcessSyncFile()
        {
            // Record if the sync file exists to avoid repeated calls
            // to the operating system.
            if (_syncFileExists == false)
                _syncFileExists = File.Exists(_syncFilePath);

            if (_syncFileExists)
            {
                // Used to indicate if the process should be repeated.
                bool repeatProcess = false;

                // Lock the list of devices we're about to update to ensure they can't be
                // changed by subsequent requests to this callback.
                lock (_previous.Requests)
                {
                    // Open the sync file for read access ensuring it's disposed 
                    // as soon as possible.
                    using (FileStream stream = OpenSyncFilePath(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        if (stream != null)
                        {
                            // Record the length of the file so that if it changes we can abandon this
                            // update and rely on a subsequent call to this methd to complete 
                            // processing.
                            long length = stream.Length;
                            BinaryReader reader = new BinaryReader(stream);
                            RequestRecord record = new RequestRecord();
                            RequestRecord firstDevice = null;
                            long rows = length/RECORD_LENGTH;
                            for (long row = 0; row < rows; row++)
                            {
                                // Read the current row in reverse order. Capture EOF exceptions
                                // in case the file length has changed since we started processing.
                                try
                                {
                                    stream.Position = ((rows - row)*RECORD_LENGTH) - RECORD_LENGTH;
                                    record.Read(reader);
                                }
                                catch (EndOfStreamException ex)
                                {
                                    // The file has been trimmed by another process. Break and
                                    // allow the resulting call to this event to complete
                                    // processing.
                                    EventLog.Debug(ex);
                                    break;
                                }

                                // If the current record is the same as the last one we got last time
                                // this method was called then stop processing more records.
                                if (record.CompareTo(_previous.lastRequest) == 0)
                                    break;

                                // Update the memory version.
                                if (record.LastActiveDate == 0)
                                {
                                    // Remove from the device as the last active date is zero.
                                    _previous.Requests.Remove(record.Key);
                                }
                                else
                                {
                                    // Update or insert a new record.
                                    if (_previous.Requests.ContainsKey(record.Key))
                                        _previous.Requests[record.Key] = record.LastActiveDate;
                                    else
                                        _previous.Requests.Add(record.Key, record.LastActiveDate);
                                }

                                if (firstDevice == null)
                                    firstDevice = new RequestRecord(record);
                            }
                            // If the length of the file hasn't changed during the processing
                            // then update the last device record to limit the number of rows
                            // examined in future file changes.
                            if (length == stream.Length && firstDevice != null)
                                _previous.lastRequest = firstDevice;

                            // Signal to all the method again if the length of the file
                            // has changed during processing.
                            repeatProcess = length != stream.Length;

                            reader.Close();

                        }
                    }
                }
                // If the file was altered during the processing then call the method
                // again to capture any new records.
                if (repeatProcess)
                    ProcessSyncFile();
            }
        }
        /// <summary>
        /// Removes this device request from the previous devices list.
        /// </summary>
        /// <param name="request">HttpRequest of the device.</param>
        public void Remove(HttpRequest request)
        {
            if (_syncFilePath != null)
            {
                RequestRecord record = new RequestRecord(request);

                // Get the latest data.
                RefreshSyncFile();

                // Does the device exist in the previous devices list?
                if (_previous.Requests.ContainsKey(record.Key))
                {
                    // Set the last active date to zero so that it will be 
                    // removed when the sync file is serviced.
                    record.LastActiveDate = 0;

                    // Add this most recent request to the sync file.
                    Add(record);
                }
            }
        }
        /// <summary>
        /// Adds this device request to the previous devices list.
        /// </summary>
        /// <param name="request">HttpRequest of the device.</param>
        public void Set(HttpRequest request)
        {
            if (_syncFilePath != null)
            {
                RequestRecord record = new RequestRecord(request);

                // Get the latest data.
                RefreshSyncFile();

                // Add this most recent request to the sync file.
                Add(record);

                // Check if the sync file needs to be serviced.
                CheckIfServiceRequired();
            }
        }
        /// <summary>
        /// Checks to find out if the device associated with the HttpRequest
        /// has already been seen by the application. Always returns false
        /// if the sync file has not been specified.
        /// </summary>
        /// <param name="request">HttpRequest to be checked.</param>
        /// <returns>True if the device associated with the request has been seen.</returns>
        public bool IsPresent(HttpRequest request)
        {
            if (_syncFilePath != null)
            {
                RequestRecord record = new RequestRecord(request);

                // Check to see if new request data needs to be loaded.
                RefreshSyncFile();

                long expiryDateTime;
                if (_previous.Requests.TryGetValue(record.Key, out expiryDateTime))
                {
                    // If redirect timeout is zero then simply check to see if the
                    // device is present in the list of previous devices.
                    if (_redirectTimeout == 0)
                        return true;

                    // Is it still valid?
                    return (new DateTime(expiryDateTime).AddMinutes(_redirectTimeout)).Ticks >=
                        record.LastActiveDate;
                }
            }
            return false;
        }