/// <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); }
/// <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); }