Beispiel #1
0
        /// <summary>
        /// Sets the request stream.
        /// </summary>
        /// <param name="requestStreamContent">The content stream to copy into the request stream.</param>
        internal void SetRequestStream(ContentStream requestStreamContent)
        {
            if (requestStreamContent.IsKnownMemoryStream)
            {
                this.SetContentLengthHeader();
            }

#if DEBUG
            this.ValidateHeaders();
#endif
            using (Stream requestStream = this.requestMessage.GetStream())
            {
                if (requestStreamContent.IsKnownMemoryStream)
                {
                    MemoryStream bufferableStream = (MemoryStream)requestStreamContent.Stream;
                    Debug.Assert(bufferableStream.Position == 0, "Cached/buffered stream position should be 0");

                    byte[] buffer       = bufferableStream.GetBuffer();
                    int    bufferOffset = checked ((int)bufferableStream.Position);
                    int    bufferLength = checked ((int)bufferableStream.Length) - bufferOffset;

                    // the following is useful in the debugging Immediate Window
                    // string x = System.Text.Encoding.UTF8.GetString(buffer, bufferOffset, bufferLength);
                    requestStream.Write(buffer, bufferOffset, bufferLength);
                }
                else
                {
                    byte[] buffer = new byte[WebUtil.DefaultBufferSizeForStreamCopy];
                    WebUtil.CopyStream(requestStreamContent.Stream, requestStream, ref buffer);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// copy the response data
        /// </summary>
        /// <param name="response">response object</param>
        private void HandleOperationResponseData(IODataResponseMessage response)
        {
            Debug.Assert(response != null, "response != null");

            using (Stream stream = response.GetStream())
            {
                if (stream != null)
                {
                    // we need to check for whether the incoming stream was data or not. Hence we need to copy it to a temporary memory stream
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        if (WebUtil.CopyStream(stream, memoryStream, ref this.buildBatchBuffer) != 0)
                        {
                            // set the memory stream position to zero again.
                            memoryStream.Position = 0;
                            this.HandleOperationResponseData(response, memoryStream);
                        }
                        else
                        {
                            this.HandleOperationResponseData(response, null);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Processed the operation response reported by the batch reader.
        /// This is a side-effecting method that is tied deeply to how it is used in the batch processing pipeline.
        /// </summary>
        /// <param name="batchReader">The batch reader to get the operation response from.</param>
        /// <param name="isChangesetOperation">True if the current operation is inside a changeset (implying CUD, not query)</param>
        /// <returns>An exception if the operation response is an error response, null for success response.</returns>
        private Exception ProcessCurrentOperationResponse(ODataBatchReader batchReader, bool isChangesetOperation)
        {
            Debug.Assert(batchReader != null, "batchReader != null");
            Debug.Assert(batchReader.State == ODataBatchReaderState.Operation, "This method requires the batch reader to be on an operation.");

            ODataBatchOperationResponseMessage operationResponseMessage = batchReader.CreateOperationResponseMessage();
            Descriptor descriptor = null;

            if (isChangesetOperation)
            {
                // We need to peek at the content-Id before handing the response to the user, so we can expose the Descriptor them.
                // We're OK with this exception to our general rule of not using them before ReceivingResponse event is fired.
                this.entryIndex = this.ValidateContentID(operationResponseMessage.ContentId);
                descriptor      = this.ChangedEntries[entryIndex];
            }

            // If we hit en error inside a batch, we will never expose a descriptor since we don't know which one to return.
            // The descriptor we fetched above based on the content-ID is bogus because the server returns an errounous content-id when
            // it hits an error inside batch.
            if (!WebUtil.SuccessStatusCode((HttpStatusCode)operationResponseMessage.StatusCode))
            {
                descriptor = null;
            }

            this.RequestInfo.Context.FireReceivingResponseEvent(new ReceivingResponseEventArgs(operationResponseMessage, descriptor, true));

            // We need to know if the content of the operation response is empty or not.
            // We also need to cache the entire content, since in case of GET response the response itself will be parsed
            // lazily and so it can happen that we will move the batch reader after this operation before we actually read
            // the content of the operation.
            Stream originalOperationResponseContentStream = operationResponseMessage.GetStream();

            if (originalOperationResponseContentStream == null)
            {
                Error.ThrowBatchExpectedResponse(InternalError.NullResponseStream);
            }

            MemoryStream operationResponseContentStream;

            try
            {
                operationResponseContentStream = new MemoryStream();
                WebUtil.CopyStream(originalOperationResponseContentStream, operationResponseContentStream, ref this.streamCopyBuffer);
                operationResponseContentStream.Position = 0;
            }
            finally
            {
                originalOperationResponseContentStream.Dispose();
            }

            this.currentOperationResponse = new CurrentOperationResponse(
                (HttpStatusCode)operationResponseMessage.StatusCode,
                operationResponseMessage.Headers,
                operationResponseContentStream);

            Version responseVersion;
            string  headerName = XmlConstants.HttpODataVersion;

            return(BaseSaveResult.HandleResponse(
                       this.RequestInfo,
                       this.currentOperationResponse.StatusCode,
                       this.currentOperationResponse.Headers.GetHeader(headerName),
                       () => this.currentOperationResponse.ContentStream,
                       false,
                       out responseVersion));
        }
Beispiel #4
0
        internal void ExecuteQuery()
        {
            try
            {
                if (this.requestContentStream != null && this.requestContentStream.Stream != null)
                {
                    this.Request.SetRequestStream(this.requestContentStream);
                }
#if false
                if ((null != requestContent) && (0 < requestContent.Length))
                {
                    using (System.IO.Stream stream = Util.NullCheck(this.Request.GetRequestStream(), InternalError.InvalidGetRequestStream))
                    {
                        byte[] buffer       = requestContent.GetBuffer();
                        int    bufferOffset = checked ((int)requestContent.Position);
                        int    bufferLength = checked ((int)requestContent.Length) - bufferOffset;

                        // the following is useful in the debugging Immediate Window
                        // string x = System.Text.Encoding.UTF8.GetString(buffer, bufferOffset, bufferLength);
                        stream.Write(buffer, bufferOffset, bufferLength);
                    }
                }
#endif
                IODataResponseMessage response = null;
                response = this.RequestInfo.GetSyncronousResponse(this.Request, true);
                this.SetHttpWebResponse(Util.NullCheck(response, InternalError.InvalidGetResponse));

                if (HttpStatusCode.NoContent != this.StatusCode)
                {
                    using (Stream stream = this.responseMessage.GetStream())
                    {
                        if (null != stream)
                        {
                            Stream copy = this.GetAsyncResponseStreamCopy();
                            this.outputResponseStream = copy;

                            Byte[] buffer = this.GetAsyncResponseStreamCopyBuffer();

                            long copied = WebUtil.CopyStream(stream, copy, ref buffer);
                            if (this.responseStreamOwner)
                            {
                                if (0 == copied)
                                {
                                    this.outputResponseStream = null;
                                }
                                else if (copy.Position < copy.Length)
                                {   // In Silverlight, generally 3 bytes less than advertised by ContentLength are read
                                    ((MemoryStream)copy).SetLength(copy.Position);
                                }
                            }

                            this.PutAsyncResponseStreamCopyBuffer(buffer);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                this.HandleFailure(e);
                throw;
            }
            finally
            {
                this.SetCompleted();
                this.CompletedRequest();
            }

            if (null != this.Failure)
            {
                throw this.Failure;
            }
        }