The data of Intermediate Node Object.
Inheritance: NodeObject
Beispiel #1
0
            /// <summary>
            /// This method is used to build a root node object from a byte array.
            /// </summary>
            /// <param name="fileContent">Specify the byte array.</param>
            /// <returns>Return a root node object build from the byte array.</returns>
            public IntermediateNodeObject Build(byte[] fileContent)
            {
                IntermediateNodeObject rootNode = new IntermediateNodeObject();

                rootNode.Signature                  = new SignatureObject();
                rootNode.DataSize                   = new DataSizeObject();
                rootNode.DataSize.DataSize          = (ulong)fileContent.Length;
                rootNode.ExGuid                     = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());
                rootNode.IntermediateNodeObjectList = ChunkingFactory.CreateChunkingInstance(fileContent).Chunking();
                return(rootNode);
            }
            /// <summary>
            /// This method is used to build intermediate node object from a byte array with a signature.
            /// </summary>
            /// <param name="array">Specify the byte array.</param>
            /// <param name="signature">Specify the signature.</param>
            /// <returns>Return the intermediate node object.</returns>
            public IntermediateNodeObject Build(byte[] array, SignatureObject signature)
            {
                IntermediateNodeObject nodeObject = new IntermediateNodeObject();

                nodeObject.DataSize          = new DataSizeObject();
                nodeObject.DataSize.DataSize = (ulong)array.Length;

                nodeObject.Signature = signature;
                nodeObject.ExGuid    = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());

                nodeObject.DataNodeObjectData         = new DataNodeObjectData(array, 0, array.Length);
                nodeObject.IntermediateNodeObjectList = null;

                // Now in the current implementation, one intermediate node only contain one single data object node.
                return(nodeObject);
            }
Beispiel #3
0
        /// <summary>
        /// This method is used to create the instance of AbstractChunking.
        /// </summary>
        /// <param name="nodeObject">Specify the root node object.</param>
        /// <returns>The instance of AbstractChunking.</returns>
        public static AbstractChunking CreateChunkingInstance(IntermediateNodeObject nodeObject)
        {
            byte[] fileContent = nodeObject.GetContent().ToArray();

            if (EditorsTableUtils.IsEditorsTableHeader(fileContent))
            {
                return(null);
            }

            if (ZipHeader.IsFileHeader(fileContent, 0))
            {
                return(new ZipFilesChunking(fileContent));
            }
            else
            {
                // For SharePoint Server 2013 compatible SUTs, always using the RDC Chunking method in the current test suite involved file resources.
                if (SharedContext.Current.CellStorageVersionType.MinorVersion >= 2)
                {
                    return(new RDCAnalysisChunking(fileContent));
                }

                // For SharePoint Server 2010 SP2 compatible SUTs, chunking method depends on file content and size. So first try using the simple chunking.
                AbstractChunking returnChunking = new SimpleChunking(fileContent);

                List <LeafNodeObject> nodes = returnChunking.Chunking();
                if (nodeObject.IntermediateNodeObjectList.Count == nodes.Count)
                {
                    bool isDataSizeMatching = true;
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != nodes[i].DataSize.DataSize)
                        {
                            isDataSizeMatching = false;
                            break;
                        }
                    }

                    if (isDataSizeMatching)
                    {
                        return(returnChunking);
                    }
                }

                // If the intermediate count number or data size does not equals, then try to use RDC chunking method.
                return(new RDCAnalysisChunking(fileContent));
            }
        }
Beispiel #4
0
            /// <summary>
            /// This method is used to travel the node tree and build the ObjectGroupDataElementData and the extra data element list.
            /// </summary>
            /// <param name="node">Specify the object node.</param>
            /// <param name="dataElements">Specify the list of data elements.</param>
            private void TravelNodeObject(NodeObject node, ref List <DataElement> dataElements)
            {
                if (node is RootNodeObject)
                {
                    ObjectGroupDataElementData data = new ObjectGroupDataElementData();
                    data.ObjectGroupDeclarations.ObjectDeclarationList.Add(this.CreateObjectDeclare(node));
                    data.ObjectGroupData.ObjectGroupObjectDataList.Add(this.CreateObjectData(node as RootNodeObject));

                    dataElements.Add(new DataElement(DataElementType.ObjectGroupDataElementData, data));

                    foreach (IntermediateNodeObject child in (node as RootNodeObject).IntermediateNodeObjectList)
                    {
                        this.TravelNodeObject(child, ref dataElements);
                    }
                }
                else if (node is IntermediateNodeObject)
                {
                    IntermediateNodeObject intermediateNode = node as IntermediateNodeObject;

                    ObjectGroupDataElementData data = new ObjectGroupDataElementData();
                    data.ObjectGroupDeclarations.ObjectDeclarationList.Add(this.CreateObjectDeclare(node));
                    data.ObjectGroupData.ObjectGroupObjectDataList.Add(this.CreateObjectData(intermediateNode));

                    if (intermediateNode.DataNodeObjectData != null)
                    {
                        data.ObjectGroupDeclarations.ObjectDeclarationList.Add(this.CreateObjectDeclare(intermediateNode.DataNodeObjectData));
                        data.ObjectGroupData.ObjectGroupObjectDataList.Add(this.CreateObjectData(intermediateNode.DataNodeObjectData));
                        dataElements.Add(new DataElement(DataElementType.ObjectGroupDataElementData, data));
                        return;
                    }

                    if (intermediateNode.DataNodeObjectData == null && intermediateNode.IntermediateNodeObjectList != null)
                    {
                        dataElements.Add(new DataElement(DataElementType.ObjectGroupDataElementData, data));

                        foreach (IntermediateNodeObject child in intermediateNode.IntermediateNodeObjectList)
                        {
                            this.TravelNodeObject(child, ref dataElements);
                        }

                        return;
                    }

                    throw new System.InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList properties in IntermediateNodeObject type cannot be null in the same time.");
                }
            }
            /// <summary>
            /// This method is used to create ObjectGroupObjectData instance from a root node object.
            /// </summary>
            /// <param name="node">Specify the node object.</param>
            /// <returns>Return the ObjectGroupObjectData instance.</returns>
            private ObjectGroupObjectData CreateObjectData(IntermediateNodeObject node)
            {
                ObjectGroupObjectData objectData = new ObjectGroupObjectData();

                objectData.CellIDArray = new CellIDArray(0u, null);

                List <ExGuid> extendedGuidList = new List <ExGuid>();

                foreach (LeafNodeObject child in node.IntermediateNodeObjectList)
                {
                    extendedGuidList.Add(child.ExGuid);
                }

                objectData.ObjectExGUIDArray = new ExGUIDArray(extendedGuidList);
                objectData.Data = new BinaryItem(node.SerializeToByteList());

                return(objectData);
            }
Beispiel #6
0
        /// <summary>
        /// This method is used to analyze the chunk for simple chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(IntermediateNodeObject rootNode, ITestSite site)
        {
            if (rootNode.DataSize.DataSize <= 1024 * 1024)
            {
                // These would be something ignored for MOSS2010, when the file size is less than 1MB.
                // In this case the server will response data without signature, but to be consistent with the behavior,
                // The Simple chunk still will be used, but empty signature check will be ignored.
                return;
            }
            else if (rootNode.DataSize.DataSize <= 250 * 1024 * 1024)
            {
                foreach (LeafNodeObject interNode in rootNode.IntermediateNodeObjectList)
                {
                    SignatureObject expect    = this.GetSignature(interNode.DataNodeObjectData.ObjectData);
                    SignatureObject realValue = interNode.Signature;
                    if (!expect.Equals(interNode.Signature))
                    {
                        site.Assert.Fail("Expect the signature value {0}, but actual value is {1}", expect.ToString(), realValue.ToString());
                    }

                    site.Assert.IsTrue(interNode.DataSize.DataSize <= 1024 * 1024, "The size of each chunk should be equal or less than 1MB for simple chunk.");

                    site.Assert.AreEqual <ulong>(
                        (ulong)interNode.GetContent().Count,
                        interNode.DataSize.DataSize,
                        "Expect the data size value equal the number represented by the chunk.");

                    site.Assert.IsNotNull(
                        interNode.DataNodeObjectData,
                        "The Object References array of the Intermediate Node Object associated with this Data Node Object MUST have a single entry which MUST be the Object ID of the Data Node Object.");
                }

                site.Log.Add(LogEntryKind.Debug, "All the intermediate signature value matches.");

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifySimpleChunk(SharedContext.Current.Site);
                }
            }
            else
            {
                throw new NotImplementedException("When the file size is larger than 250MB, because the signature method is not implemented, the analysis method is also not implemented.");
            }
        }
Beispiel #7
0
        /// <summary>
        /// This method is used to analyze the chunk for the RDC analysis chunk method.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, TestTools.ITestSite site)
        {
            List <IntermediateNodeObject> expectList = this.Chunking();

            foreach (IntermediateNodeObject nodeObject in rootNode.IntermediateNodeObjectList)
            {
                IntermediateNodeObject expect = expectList.First();

                if (!expect.Signature.Equals(nodeObject.Signature))
                {
                    site.Assert.Fail("For the RDC chunk method expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                }

                if (expect.DataSize.DataSize != nodeObject.DataSize.DataSize)
                {
                    site.Assert.Fail("For the RDC chunk method expect the chunk size, actual chunk size {1}", expect.DataSize.DataSize, nodeObject.DataSize.DataSize);
                }

                expectList.RemoveAt(0);
            }

            // If runs here, then all the requirements related for RDC analysis can be captured.
            MsfsshttpdCapture.VerifyRdcAnalysisChunk(SharedContext.Current.Site);
        }
        /// <summary>
        /// This method is used to verify the intermediate node related requirements.
        /// </summary>
        /// <param name="instance">Specify the intermediate node instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public void VerifyIntermediateNodeObject(IntermediateNodeObject instance, ITestSite site)
        {
            // If the instance is not null and there are no parsing errors, then the IntermediateNodeObject related adapter requirements can be directly captured.
            if (null == instance)
            {
                site.Assert.Fail("The instance of type IntermediateNodeObject is null due to parsing error or type casting error.");
            }

            // Verify the stream object header related requirements.
            this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site);

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R55
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderStart16bit),
                     instance.StreamObjectHeaderStart.GetType(),
                     "MS-FSSHTTPD",
                     55,
                     @"[In Intermediate Node Object Data] Intermediate Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x1, Type of 0x1F, and Length of 0x00.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R56
            site.CaptureRequirementIfAreEqual<ushort>(
                     0xFC,
                     LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                     "MS-FSSHTTPD",
                     56,
                     @"[In Intermediate Node Object Data] Intermediate Node Start (2 bytes): The value of this field[Intermediate Node Start] MUST be 0x00FC.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R57
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderStart16bit),
                     instance.Signature.StreamObjectHeaderStart.GetType(),
                     "MS-FSSHTTPD",
                     57,
                     @"[In Intermediate Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R61
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderStart16bit),
                     instance.DataSize.StreamObjectHeaderStart.GetType(),
                     "MS-FSSHTTPD",
                     61,
                     @"[In Intermediate Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size).");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8013
            site.CaptureRequirementIfAreEqual<uint>(
                     0x1110,
                     LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                     "MS-FSSHTTPD",
                     8013,
                     @"[In Intermediate Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110.");

            // Verify the stream object header end related requirements.
            this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site);
            this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site);

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R63
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderEnd8bit),
                     instance.StreamObjectHeaderEnd.GetType(),
                     "MS-FSSHTTPD",
                     63,
                     @"[In Intermediate Node Object Data] Intermediate Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x1F.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8014
            site.CaptureRequirementIfAreEqual<byte>(
                     0x7D,
                     instance.StreamObjectHeaderEnd.SerializeToByteList()[0],
                     "MS-FSSHTTPD",
                     8014,
                     @"[In Intermediate Node Object Data] Intermediate Node End (1 byte):The value of this field[Intermediate Node End] MUST be 0x7D.");
        }
            /// <summary>
            /// This method is used to create ObjectGroupObjectData instance from a intermediate node object.
            /// </summary>
            /// <param name="node">Specify the node object.</param>
            /// <returns>Return the ObjectGroupObjectData instance.</returns>
            private ObjectGroupObjectData CreateObjectData(IntermediateNodeObject node)
            {
                ObjectGroupObjectData objectData = new ObjectGroupObjectData();

                objectData.CellIDArray = new CellIDArray(0u, null);
                List<ExGuid> extendedGuidList = new List<ExGuid>();

                if (node.DataNodeObjectData != null)
                {
                    extendedGuidList.Add(node.DataNodeObjectData.ExGuid);
                }
                else if (node.IntermediateNodeObjectList != null)
                {
                    foreach (IntermediateNodeObject child in node.IntermediateNodeObjectList)
                    {
                        extendedGuidList.Add(child.ExGuid);
                    }
                }

                objectData.ObjectExGUIDArray = new ExGUIDArray(extendedGuidList);
                objectData.Data = new BinaryItem(node.SerializeToByteList());

                return objectData;
            }
        /// <summary>
        /// This method is used to verify the requirements related with the IntermediateNodeObject type.
        /// </summary>
        /// <param name="interNode">Specify the IntermediateNodeObject instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public static void VerifyIntermediateNodeObject(IntermediateNodeObject interNode, ITestSite site)
        {
            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R69
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     69,
                     @"[In Data Node Object Data] Binary data than specifies the contents of the chunk of the file that is represented by this Data Node.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R62
            site.CaptureRequirementIfAreEqual<ulong>(
                     (ulong)interNode.GetContent().Count,
                     interNode.DataSize.DataSize,
                     "MS-FSSHTTPD",
                     62,
                     @"[In Intermediate Node Object Data] Data Size (8 bytes): An unsigned 64-bit integer that specifies the size of the file data represented by this Intermediate Node Object.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R66
            site.CaptureRequirementIfAreEqual<ulong>(
                     (ulong)interNode.GetContent().Count,
                     interNode.DataSize.DataSize,
                     "MS-FSSHTTPD",
                     66,
                     @"[In Intermediate Node Object References] The size of the Data Node Object or the sum of the Data Size values from all of the Intermediate Node Objects MUST equal the Data Size specified in the Object Data of this Intermediate Node Object.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8015
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     8015,
                     @"[In Intermediate Node Object References] The ordered set of Object Extended GUIDs MUST contain the Object Extended GUID of a single Data Node Object or an ordered list of Extended GUIDs for the Intermediate Node Object.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8017
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     8017,
                     @"[In Intermediate Node Object References] Object Extended GUID Array entries MUST be ordered based on the sequential file bytes represented by each Node Object. ");
        }
Beispiel #11
0
            /// <summary>
            /// This method is used to build intermediate node object from an list of object group data element.
            /// </summary>
            /// <param name="objectGroupList">Specify the list of object group data elements.</param>
            /// <param name="dataObj">Specify the object group object.</param>
            /// <param name="intermediateGuid">Specify the intermediate extended GUID.</param>
            /// <returns>Return the intermediate node object.</returns>
            public LeafNodeObject Build(List <ObjectGroupDataElementData> objectGroupList, ObjectGroupObjectData dataObj, ExGuid intermediateGuid)
            {
                LeafNodeObject         node     = null;
                IntermediateNodeObject rootNode = null;

                int index = 0;

                if (StreamObject.TryGetCurrent <LeafNodeObject>(dataObj.Data.Content.ToArray(), ref index, out node))
                {
                    if (dataObj.ObjectExGUIDArray == null)
                    {
                        throw new InvalidOperationException("Failed to build intermediate node because the object extend GUID array does not exist.");
                    }

                    node.ExGuid = intermediateGuid;

                    // Contain a single Data Node Object.
                    if (dataObj.ObjectExGUIDArray.Count.DecodedValue == 1u)
                    {
                        ObjectGroupObjectDeclare dataNodeDeclare;
                        ObjectGroupObjectData    dataNodeData = this.FindByExGuid(objectGroupList, dataObj.ObjectExGUIDArray.Content[0], out dataNodeDeclare);
                        BinaryItem data = dataNodeData.Data;

                        node.DataNodeObjectData         = new DataNodeObjectData(data.Content.ToArray(), 0, (int)data.Length.DecodedValue);
                        node.DataNodeObjectData.ExGuid  = dataObj.ObjectExGUIDArray.Content[0];
                        node.IntermediateNodeObjectList = null;

                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForDataNodeObject(dataNodeData, dataNodeDeclare, objectGroupList, SharedContext.Current.Site);
                        }
                    }
                    else
                    {
                        // Contain a list of LeafNodeObjectData
                        node.IntermediateNodeObjectList = new List <LeafNodeObject>();
                        node.DataNodeObjectData         = null;
                        foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content)
                        {
                            ObjectGroupObjectDeclare intermediateDeclare;
                            ObjectGroupObjectData    intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                            node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                            if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                            {
                                MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                            }
                        }
                    }
                }
                else if (StreamObject.TryGetCurrent <IntermediateNodeObject>(dataObj.Data.Content.ToArray(), ref index, out rootNode))
                {
                    // In Sub chunking for larger than 1MB zip file, MOSS2010 could return IntermediateNodeObject.
                    // For easy further process, the rootNode will be replaced by intermediate node instead.
                    node = new LeafNodeObject();
                    node.IntermediateNodeObjectList = new List <LeafNodeObject>();
                    node.DataSize           = rootNode.DataSize;
                    node.ExGuid             = rootNode.ExGuid;
                    node.Signature          = rootNode.Signature;
                    node.DataNodeObjectData = null;
                    foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content)
                    {
                        ObjectGroupObjectDeclare intermediateDeclare;
                        ObjectGroupObjectData    intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                        node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException("In the ObjectGroupDataElement cannot only contain the IntermediateNodeObject or IntermediateNodeOBject.");
                }

                return(node);
            }
Beispiel #12
0
            /// <summary>
            /// This method is used to build a root node object from an object group data element list with the specified root extended GUID.
            /// </summary>
            /// <param name="objectGroupList">Specify the object group data element list.</param>
            /// <param name="rootExGuid">Specify the root extended GUID.</param>
            /// <returns>Return a root node object build from the object group data element list.</returns>
            private IntermediateNodeObject Build(List <ObjectGroupDataElementData> objectGroupList, ExGuid rootExGuid)
            {
                ObjectGroupObjectDeclare rootDeclare;
                ObjectGroupObjectData    root = this.FindByExGuid(objectGroupList, rootExGuid, out rootDeclare);

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifyObjectCount(root, SharedContext.Current.Site);
                }

                int index = 0;
                IntermediateNodeObject rootNode = null;

                if (StreamObject.TryGetCurrent <IntermediateNodeObject>(root.Data.Content.ToArray(), ref index, out rootNode))
                {
                    rootNode.ExGuid = rootExGuid;

                    foreach (ExGuid extGuid in root.ObjectExGUIDArray.Content)
                    {
                        ObjectGroupObjectDeclare intermediateDeclare;
                        ObjectGroupObjectData    intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                        rootNode.IntermediateNodeObjectList.Add(new LeafNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                        // Capture the intermediate related requirements
                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                            MsfsshttpdCapture.VerifyLeafNodeObject(rootNode.IntermediateNodeObjectList.Last(), SharedContext.Current.Site);
                        }
                    }

                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        // Capture the root node related requirements.
                        MsfsshttpdCapture.VerifyObjectGroupObjectDataForRootNode(root, rootDeclare, objectGroupList, SharedContext.Current.Site);
                        MsfsshttpdCapture.VerifyIntermediateNodeObject(rootNode, SharedContext.Current.Site);
                    }
                }
                else
                {
                    // If there is only one object in the file, SharePoint Server 2010 does not return the Root Node Object, but an Intermediate Node Object at the beginning.
                    // At this case, we will add the root node object for the further parsing.
                    rootNode        = new IntermediateNodeObject();
                    rootNode.ExGuid = rootExGuid;

                    rootNode.IntermediateNodeObjectList.Add(new LeafNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, root, rootExGuid));
                    rootNode.DataSize          = new DataSizeObject();
                    rootNode.DataSize.DataSize = (ulong)rootNode.IntermediateNodeObjectList.Sum(o => (float)o.DataSize.DataSize);
                }

                // Capture all the signature related requirements.
                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    AbstractChunking chunking = ChunkingFactory.CreateChunkingInstance(rootNode);

                    if (chunking != null)
                    {
                        chunking.AnalyzeChunking(rootNode, SharedContext.Current.Site);
                    }
                }

                return(rootNode);
            }
 /// <summary>
 /// This method is used to analyze the chunk.
 /// </summary>
 /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
 /// <param name="site">Specify the ITestSite instance.</param>
 public abstract void AnalyzeChunking(IntermediateNodeObject rootNode, ITestSite site);
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(IntermediateNodeObject rootNode, ITestSite site)
        {
            List <LeafNodeObject> cloneList = new List <LeafNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                LeafNodeObject nodeObject = cloneList.First();
                byte[]         content    = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header         = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int    headerLength   = header.Length;
                        int    compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            if (Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointFoundation2010" && Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointServer2010")
                            {
                                LeafNodeObject expectNode = new LeafNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                                if (!expectNode.Signature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                                }
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8213, SharedContext.Current.Site))
                                {
                                    bool isR8213Verified = false;
                                    if (compressedSize > 1024 * 1024 && nodeObject.IntermediateNodeObjectList.Count > 1)
                                    {
                                        isR8213Verified = true;
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8213Verified,
                                        "MS-FSSHTTPD",
                                        8213,
                                        @"[In Appendix A: Product Behavior] For implementation, if the number of .ZIP file bytes represented by a chunk is greater than 1 megabyte, a list of subchunks is generated. <4> Section 2.4.1:  For SharePoint Server 2010, if the number of .ZIP file bytes represented by a chunk is greater than 1 megabyte, a list of subchunks is generated.");
                                }

                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8207, SharedContext.Current.Site))
                                {
                                    bool isR8207Verified = false;
                                    if (compressedSize > 3 * 1024 * 1024 && nodeObject.IntermediateNodeObjectList.Count > 1)
                                    {
                                        isR8207Verified = true;
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8207Verified,
                                        "MS-FSSHTTPD",
                                        8207,
                                        @"[In Appendix A: Product Behavior] For implementation, if the number of .ZIP file bytes represented by a chunk is greater than 3 megabytes, a list of subchunks is generated. (Microsoft Office 2013/Microsoft SharePoint Foundation 2013/Microsoft SharePoint Server 2013/Microsoft SharePoint Workspace 2010/Microsft Office 2016/Microsft SharePoint Server 2016 follow this behavior.)");
                                }

                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8208, SharedContext.Current.Site) && Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8210, SharedContext.Current.Site))
                                {
                                    bool isR8208Verified = true;
                                    bool isR8210Verified = true;
                                    if (nodeObject.IntermediateNodeObjectList[nodeObject.IntermediateNodeObjectList.Count - 1].DataSize.DataSize > 1024 * 1024)
                                    {
                                        isR8208Verified = false;
                                    }

                                    for (int i = 0; i < nodeObject.IntermediateNodeObjectList.Count - 1; i++)
                                    {
                                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != 1024 * 1024)
                                        {
                                            isR8210Verified = false;
                                        }
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8208Verified,
                                        "MS-FSSHTTPD",
                                        8208,
                                        @"[In Appendix A: Product Behavior] The size of each subchunk is at most 1 megabyte. (Microsoft SharePoint Server 2010 follows this behavior.)");

                                    site.CaptureRequirementIfIsTrue(
                                        isR8210Verified,
                                        "MS-FSSHTTPD",
                                        8210,
                                        @"[In Appendix A: Product Behavior] All but the last subchunk MUST be 1 megabyte in size. (Microsfot SharePoint Server 2010 follows this behavior.)");
                                }

                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8209, SharedContext.Current.Site) && Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8211, SharedContext.Current.Site))
                                {
                                    bool isR8209Verified = true;
                                    bool isR8211Verified = true;
                                    if (nodeObject.IntermediateNodeObjectList[nodeObject.IntermediateNodeObjectList.Count - 1].DataSize.DataSize > 3 * 1024 * 1024)
                                    {
                                        isR8209Verified = false;
                                    }

                                    for (int i = 0; i < nodeObject.IntermediateNodeObjectList.Count - 1; i++)
                                    {
                                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != 3 * 1024 * 1024)
                                        {
                                            isR8211Verified = false;
                                        }
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8209Verified,
                                        "MS-FSSHTTPD",
                                        8209,
                                        @"[In Appendix A: Product Behavior] The size of each subchunk is at most 3 megabytes. (Microsoft Office 2013/Microsoft SharePoint Foundation 2013/Microsoft SharePoint Server 2013/Microsoft SharePoint Workspace 2010/Microsft Office 2016/Microsft SharePoint Server 2016 follow this behavior.)");

                                    site.CaptureRequirementIfIsTrue(
                                        isR8211Verified,
                                        "MS-FSSHTTPD",
                                        8211,
                                        @"[In Appendix A: Product Behavior] All but the last subchunk MUST be 3 megabyte in size. (Microsoft Office 2013/Microsoft SharePoint Foundation 2013/Microsoft SharePoint Server 2013/Microsoft SharePoint Workspace 2010/Microsft Office 2016/Microsft SharePoint Server 2016 follow this behavior.)");
                                }
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual <ulong>(
                                    (ulong)compressedSize,
                                    nodeObject.DataSize.DataSize,
                                    "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                if (Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointFoundation2010" && Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointServer2010")
                                {
                                    SignatureObject contentSignature = new SignatureObject();
                                    contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                    if (!contentSignature.Equals(nodeObject.Signature))
                                    {
                                        site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                    }
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }
Beispiel #15
0
        /// <summary>
        /// This method is used to verify the intermediate node related requirements.
        /// </summary>
        /// <param name="instance">Specify the intermediate node instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public void VerifyIntermediateNodeObject(IntermediateNodeObject instance, ITestSite site)
        {
            // If the instance is not null and there are no parsing errors, then the IntermediateNodeObject related adapter requirements can be directly captured.
            if (null == instance)
            {
                site.Assert.Fail("The instance of type IntermediateNodeObject is null due to parsing error or type casting error.");
            }

            // Verify the stream object header related requirements.
            this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site);

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R55
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderStart16bit),
                instance.StreamObjectHeaderStart.GetType(),
                "MS-FSSHTTPD",
                55,
                @"[In Intermediate Node Object Data] Intermediate Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x1, Type of 0x1F, and Length of 0x00.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R56
            site.CaptureRequirementIfAreEqual <ushort>(
                0xFC,
                LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                "MS-FSSHTTPD",
                56,
                @"[In Intermediate Node Object Data] Intermediate Node Start (2 bytes): The value of this field[Intermediate Node Start] MUST be 0x00FC.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R57
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderStart16bit),
                instance.Signature.StreamObjectHeaderStart.GetType(),
                "MS-FSSHTTPD",
                57,
                @"[In Intermediate Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R61
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderStart16bit),
                instance.DataSize.StreamObjectHeaderStart.GetType(),
                "MS-FSSHTTPD",
                61,
                @"[In Intermediate Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size).");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8013
            site.CaptureRequirementIfAreEqual <uint>(
                0x1110,
                LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                "MS-FSSHTTPD",
                8013,
                @"[In Intermediate Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110.");

            // Verify the stream object header end related requirements.
            this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site);
            this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site);

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R63
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderEnd8bit),
                instance.StreamObjectHeaderEnd.GetType(),
                "MS-FSSHTTPD",
                63,
                @"[In Intermediate Node Object Data] Intermediate Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x1F.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8014
            site.CaptureRequirementIfAreEqual <byte>(
                0x7D,
                instance.StreamObjectHeaderEnd.SerializeToByteList()[0],
                "MS-FSSHTTPD",
                8014,
                @"[In Intermediate Node Object Data] Intermediate Node End (1 byte):The value of this field[Intermediate Node End] MUST be 0x7D.");
        }
            /// <summary>
            /// This method is used to build intermediate node object from a byte array with a signature.
            /// </summary>
            /// <param name="array">Specify the byte array.</param>
            /// <param name="signature">Specify the signature.</param>
            /// <returns>Return the intermediate node object.</returns>
            public IntermediateNodeObject Build(byte[] array, SignatureObject signature)
            {
                IntermediateNodeObject nodeObject = new IntermediateNodeObject();
                nodeObject.DataSize = new DataSizeObject();
                nodeObject.DataSize.DataSize = (ulong)array.Length;

                nodeObject.Signature = signature;
                nodeObject.ExGuid = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());

                nodeObject.DataNodeObjectData = new DataNodeObjectData(array, 0, array.Length);
                nodeObject.IntermediateNodeObjectList = null;

                // Now in the current implementation, one intermediate node only contain one single data object node.
                return nodeObject;
            }
            /// <summary>
            /// This method is used to build intermediate node object from an list of object group data element.
            /// </summary>
            /// <param name="objectGroupList">Specify the list of object group data elements.</param>
            /// <param name="dataObj">Specify the object group object.</param>
            /// <param name="intermediateGuid">Specify the intermediate extended GUID.</param>
            /// <returns>Return the intermediate node object.</returns>
            public IntermediateNodeObject Build(List<ObjectGroupDataElementData> objectGroupList, ObjectGroupObjectData dataObj, ExGuid intermediateGuid)
            {
                IntermediateNodeObject node = null;
                RootNodeObject rootNode = null;

                int index = 0;
                if (StreamObject.TryGetCurrent<IntermediateNodeObject>(dataObj.Data.Content.ToArray(), ref index, out node))
                {
                    if (dataObj.ObjectExGUIDArray == null)
                    {
                        throw new InvalidOperationException("Failed to build intermediate node because the object extend GUID array does not exist.");
                    }

                    node.ExGuid = intermediateGuid;

                    // Contain a single Data Node Object.
                    if (dataObj.ObjectExGUIDArray.Count.DecodedValue == 1u)
                    {
                        ObjectGroupObjectDeclare dataNodeDeclare;
                        ObjectGroupObjectData dataNodeData = this.FindByExGuid(objectGroupList, dataObj.ObjectExGUIDArray.Content[0], out dataNodeDeclare);
                        BinaryItem data = dataNodeData.Data;
                        
                        node.DataNodeObjectData = new DataNodeObjectData(data.Content.ToArray(), 0, (int)data.Length.DecodedValue);
                        node.DataNodeObjectData.ExGuid = dataObj.ObjectExGUIDArray.Content[0];
                        node.IntermediateNodeObjectList = null;

                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForDataNodeObject(dataNodeData, dataNodeDeclare, objectGroupList, SharedContext.Current.Site);
                        }
                    }
                    else
                    {
                        // Contain a list of IntermediateNodeObject
                        node.IntermediateNodeObjectList = new List<IntermediateNodeObject>();
                        node.DataNodeObjectData = null;
                        foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content)
                        {
                            ObjectGroupObjectDeclare intermediateDeclare;
                            ObjectGroupObjectData intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                            node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                            if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                            {
                                MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                            }
                        }
                    }
                }
                else if (StreamObject.TryGetCurrent<RootNodeObject>(dataObj.Data.Content.ToArray(), ref index, out rootNode))
                {
                    // In Sub chunking for larger than 1MB zip file, MOSS2010 could return RootNodeObject.
                    // For easy further process, the rootNode will be replaced by intermediate node instead.
                    node = new IntermediateNodeObject();
                    node.IntermediateNodeObjectList = new List<IntermediateNodeObject>();
                    node.DataSize = rootNode.DataSize;
                    node.ExGuid = rootNode.ExGuid;
                    node.Signature = rootNode.Signature;
                    node.DataNodeObjectData = null;
                    foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content)
                    {
                        ObjectGroupObjectDeclare intermediateDeclare;
                        ObjectGroupObjectData intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                        node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException("In the ObjectGroupDataElement cannot only contain the RootNodeObject or IntermediateNodeOBject.");
                }

                return node;
            }
Beispiel #18
0
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            List <IntermediateNodeObject> cloneList = new List <IntermediateNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                IntermediateNodeObject nodeObject = cloneList.First();
                byte[] content = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header         = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int    headerLength   = header.Length;
                        int    compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            IntermediateNodeObject expectNode = new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                            if (!expectNode.Signature.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                // This situation could most happens for MOSS2010, we fake intermediate node instead of the root node when the zip file size is larger than 1M.
                                // In the current stage, this kind of signature algorithm is not mentioned in the open specification, so leave this verify blank.
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual <ulong>(
                                    (ulong)compressedSize,
                                    nodeObject.DataSize.DataSize,
                                    "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                SignatureObject contentSignature = new SignatureObject();
                                contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                if (!contentSignature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }