A chunked response for Mailbox Server Endpoint.
        /// <summary>
        /// This method sends the disconnect request through MAPIHTTP transport to the server.
        /// </summary>
        /// <returns>If the method succeeds, the return value is 0. If the method fails, the return value is an implementation-specific error code.</returns>
        public uint Disconnect()
        {
            uint returnValue = 0;
            DisconnectRequestBody disconnectBody = new DisconnectRequestBody();

            disconnectBody.AuxiliaryBufferSize = 0;
            disconnectBody.AuxiliaryBuffer     = new byte[] { };
            HttpWebResponse response         = SendMAPIHttpRequest(this.site, this.mailStoreUrl, this.userName, this.domain, this.userPassword, disconnectBody, "Disconnect", this.cookies);
            string          transferEncoding = response.Headers["Transfer-Encoding"];
            string          pendingInterval  = response.Headers["X-PendingPeriod"];
            string          responseCode     = response.Headers["X-ResponseCode"];

            if (transferEncoding != null)
            {
                if (string.Compare(transferEncoding, "chunked") == 0)
                {
                    byte[] rawBuffer = ReadHttpResponse(response);

                    if (uint.Parse(responseCode) == 0)
                    {
                        ChunkedResponse chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer);
                        DisconnectSuccessResponseBody responseSuccess = DisconnectSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
                        returnValue = responseSuccess.ErrorCode;
                    }
                }
            }

            response.GetResponseStream().Close();
            this.cookies = null;

            return(returnValue);
        }
        /// <summary>
        /// The private method to connect the exchange server through MAPIHTTP transport.
        /// </summary>
        /// <param name="mailStoreUrl">The mail store Url.</param>
        /// <param name="domain">The domain the server is deployed.</param>
        /// <param name="userName">The domain account name</param>
        /// <param name="userDN">User's distinguished name (DN).</param>
        /// <param name="password">user Password.</param>
        /// <returns>If the method succeeds, the return value is 0. If the method fails, the return value is an implementation-specific error code.</returns>
        public uint Connect(string mailStoreUrl, string domain, string userName, string userDN, string password)
        {
            uint returnValue = 0;

            this.domain       = domain;
            this.userPassword = password;
            this.mailStoreUrl = mailStoreUrl;
            this.userName     = userName;

            ConnectRequestBody connectBody = new ConnectRequestBody();

            connectBody.UserDN = userDN;

            // The server MUST NOT compress ROP response payload (rgbOut) or auxiliary payload (rgbAuxOut).
            connectBody.Flags = 0x00000001;

            // The code page in which text data is sent.
            connectBody.Cpid = 1252;

            // The local ID for everything other than sorting.
            connectBody.LcidString = 0x00000409;

            // The local ID for sorting.
            connectBody.LcidSort            = 0x00000409;
            connectBody.AuxiliaryBufferSize = 0;
            connectBody.AuxiliaryBuffer     = new byte[] { };
            if (this.cookies == null)
            {
                this.cookies = new CookieCollection();
            }

            HttpWebResponse response         = SendMAPIHttpRequest(this.site, mailStoreUrl, userName, domain, password, connectBody, "Connect", this.cookies);
            string          transferEncoding = response.Headers["Transfer-Encoding"];
            string          pendingInterval  = response.Headers["X-PendingPeriod"];
            string          responseCode     = response.Headers["X-ResponseCode"];

            if (transferEncoding != null)
            {
                if (string.Compare(transferEncoding, "chunked") == 0)
                {
                    byte[] rawBuffer = ReadHttpResponse(response);

                    returnValue = uint.Parse(responseCode);
                    if (returnValue == 0)
                    {
                        ChunkedResponse            chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer);
                        ConnectSuccessResponseBody responseSuccess = ConnectSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
                    }
                    else
                    {
                        this.site.Assert.Fail("Can't connect the server through MAPI over HTTP, the error code is: {0}", responseCode);
                    }
                }
            }

            response.GetResponseStream().Close();
            this.cookies = response.Cookies;

            return(returnValue);
        }
        /// <summary>
        /// The method to send NotificationWait request to the server.
        /// </summary>
        /// <param name="requestBody">The NotificationWait request body.</param>
        /// <returns>Return the NotificationWait response body.</returns>
        public NotificationWaitSuccessResponseBody NotificationWaitCall(IRequestBody requestBody)
        {
            string          requestType = "NotificationWait";
            HttpWebResponse response    = SendMAPIHttpRequest(this.site, this.mailStoreUrl, this.userName, this.domain, this.userPassword, requestBody, requestType, this.cookies);

            NotificationWaitSuccessResponseBody result = null;

            string responseCode = response.Headers["X-ResponseCode"];

            byte[] rawBuffer = ReadHttpResponse(response);

            response.GetResponseStream().Close();

            if (int.Parse(responseCode) == 0)
            {
                ChunkedResponse chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer);
                NotificationWaitSuccessResponseBody responseSuccess = NotificationWaitSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
                result = responseSuccess;
            }
            else
            {
                this.site.Assert.Fail("MAPIHTTP call failed, the error code returned from server is: {0}", responseCode);
            }

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// The method to parse the chunked response from server.
        /// </summary>
        /// <param name="rawData">The response data from the server.</param>
        /// <returns>The structure for chunked response.</returns>
        public static ChunkedResponse ParseChunkedResponse(byte[] rawData)
        {
            ChunkedResponse response = new ChunkedResponse();

            response.MetaTags        = new List <string>();
            response.AdditionHeaders = new Dictionary <string, string>();
            List <byte> responseBodyData = new List <byte>();
            bool        isDone           = false;
            bool        isStartReadBody  = false;

            do
            {
                byte[] lineData = ReadLine(ref rawData, isStartReadBody);
                string line     = Encoding.ASCII.GetString(lineData);
                if (isDone == false)
                {
                    if (string.Compare(line, "PROCESSING", true) == 0 || string.Compare(line, "PENDING", true) == 0)
                    {
                        response.MetaTags.Add(line);
                    }
                    else if (string.Compare(line, "DONE", true) == 0)
                    {
                        response.MetaTags.Add(line);
                        isDone = true;
                    }
                }
                else
                {
                    if (isStartReadBody == false)
                    {
                        if (line == string.Empty)
                        {
                            isStartReadBody = true;
                        }
                        else
                        {
                            string[] headerkeyAndValue = line.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
                            response.AdditionHeaders.Add(headerkeyAndValue[0], headerkeyAndValue[1]);
                        }
                    }
                    else
                    {
                        responseBodyData.AddRange(lineData);
                    }
                }
            }while (rawData.Length > 0);

            response.ResponseBodyRawData = responseBodyData.ToArray();

            return(response);
        }
        /// <summary>
        /// The method to parse the chunked response from server.
        /// </summary>
        /// <param name="rawData">The response data from the server.</param>
        /// <returns>The structure for chunked response.</returns>
        public static ChunkedResponse ParseChunkedResponse(byte[] rawData)
        {
            ChunkedResponse response = new ChunkedResponse();
            response.MetaTags = new List<string>();
            response.AdditionHeaders = new Dictionary<string, string>();
            List<byte> responseBodyData = new List<byte>();
            bool isDone = false;
            bool isStartReadBody = false;
            do
            {
                byte[] lineData = ReadLine(ref rawData, isStartReadBody);
                string line = Encoding.ASCII.GetString(lineData);
                if (isDone == false)
                {
                    if (string.Compare(line, "PROCESSING", true) == 0 || string.Compare(line, "PENDING", true) == 0)
                    {
                        response.MetaTags.Add(line);
                    }
                    else if (string.Compare(line, "DONE", true) == 0)
                    {
                        response.MetaTags.Add(line);
                        isDone = true;
                    }
                }
                else
                {
                    if (isStartReadBody == false)
                    {
                        if (line == string.Empty)
                        {
                            isStartReadBody = true;
                        }
                        else
                        {
                            string[] headerkeyAndValue = line.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
                            response.AdditionHeaders.Add(headerkeyAndValue[0], headerkeyAndValue[1]);
                        }
                    }
                    else
                    {
                        responseBodyData.AddRange(lineData);
                    }
                }
            }
            while (rawData.Length > 0);

            response.ResponseBodyRawData = responseBodyData.ToArray();

            return response;
        }
        /// <summary>
        /// Send ROP request through MAPI over HTTP
        /// </summary>
        /// <param name="rgbIn">ROP request buffer.</param>
        /// <param name="pcbOut">The maximum size of the rgbOut buffer to place response in.</param>
        /// <param name="rawData">The response payload bytes.</param>
        /// <returns>0 indicates success, other values indicate failure. </returns>
        public uint Execute(byte[] rgbIn, uint pcbOut, out byte[] rawData)
        {
            uint ret = 0;

            ExecuteRequestBody executeBody = new ExecuteRequestBody();

            // Client requests server to not compress or XOR payload of rgbOut and rgbAuxOut.
            executeBody.Flags         = 0x00000003;
            executeBody.RopBufferSize = (uint)rgbIn.Length;
            executeBody.RopBuffer     = rgbIn;

            // Set the max size of the rgbAuxOut
            executeBody.MaxRopOut           = pcbOut; // 0x10008;
            executeBody.AuxiliaryBufferSize = 0;
            executeBody.AuxiliaryBuffer     = new byte[] { };

            HttpWebResponse response = SendMAPIHttpRequest(
                this.site,
                this.mailStoreUrl,
                this.userName,
                this.domain,
                this.userPassword,
                executeBody,
                "Execute",
                this.cookies);

            string responseCode = response.Headers["X-ResponseCode"];

            byte[] rawBuffer = ReadHttpResponse(response);
            response.GetResponseStream().Close();

            if (int.Parse(responseCode) == 0)
            {
                ChunkedResponse chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer);

                ExecuteSuccessResponseBody responseSuccess = ExecuteSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData);

                rawData = responseSuccess.RopBuffer;
                ret     = responseSuccess.ErrorCode;
            }
            else
            {
                rawData = null;
                this.site.Assert.Fail("MAPIHTTP call failed, the error code returned from server is: {0}", responseCode);
            }

            this.cookies = response.Cookies;
            return(ret);
        }