/// <summary> /// Sets the headers on the IMimePart. /// </summary> /// <param name="part">Part to set headers on.</param> /// <param name="headers">Headers to set on part.</param> /// <returns>Part with new headers.</returns> public static IMimePart SetHeaders(this IMimePart part, Dictionary <string, string> headers) { part.Headers.Clear(); foreach (var header in headers) { part.Headers.Add(header); } return(part); }
/// <summary> /// Gets the appropriate encoding to use based on the mime-part's headers or returns the default encoding /// </summary> /// <param name="mimePart">The mime part</param> /// <returns>The specific encoding or the default encoding</returns> public static Encoding GetEncodingFromHeadersOrDefault(this IMimePart mimePart) { string charset; if (!mimePart.TryGetMimeCharset(out charset)) { charset = null; } return(HttpUtilities.GetEncodingOrDefault(charset)); }
/// <summary> /// Gets the request changeset with the specified mime parts and content type. /// </summary> /// <param name="operations">Operations to go into changeset</param> /// <param name="requestManager">RequestManager to build the request.</param> /// <returns>A batch request changeset.</returns> public static BatchRequestChangeset GetRequestChangeset( IMimePart[] operations, IODataRequestManager requestManager ) { ExceptionUtilities.CheckArgumentNotNull(operations, "operations"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); return BatchPayloadBuilder.RequestChangeset("changeset_" + Guid.NewGuid().ToString(), Encoding.UTF8.WebName, operations.ToArray()); }
private void WriteHeaders(IMimePart batchPart) { foreach (var header in batchPart.Headers) { this.writer.Write(header.Key); this.writer.Write(": "); this.writer.WriteLine(header.Value); } this.writer.WriteLine(); this.writer.Flush(); }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="batchBoundary">The batch boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultQueryBatch( IODataRequestManager requestManager, int queryCount, bool forRequest, string batchBoundary = null) { Debug.Assert(queryCount >= 0, "batchSize >= 0"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[queryCount]; if (forRequest) { var queryOperation = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i = 0; i < queryCount; ++i) { parts[i] = queryOperation; } ; string requestBoundary = batchBoundary ?? "bb_multiple_request_queries_" + queryCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }); } // Response operation with no payload and a status code of 200 var emptyPayloadResponse = emptyPayload.InResponseOperation(200, requestManager); for (int i = 0; i < queryCount; ++i) { parts[i] = emptyPayloadResponse; } ; string responseBoundary = batchBoundary ?? "bb_multiple_response_queries_" + queryCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }); }
/// <summary> /// Gets the value of the given header for the given request or response and converts it into a DataServiceProtocolVersion /// </summary> /// <param name="part">The request or response to get the version header value from</param> /// <param name="header">The header to convert</param> /// <returns>The converted value of the header from the request</returns> private static DataServiceProtocolVersion GetProtocolVersionFromHeader(this IMimePart part, string header) { string version; if (!part.Headers.TryGetValue(header, out version)) { return(DataServiceProtocolVersion.Unspecified); } else { return(VersionHelper.ConvertToDataServiceProtocolVersion(version)); } }
/// <summary> /// Returns a the value of the given header if it exists, otherwise null /// </summary> /// <param name="mimePart">Mime part to get header value from</param> /// <param name="header">Specific header value to retrieve</param> /// <returns>The specified header value or null if it didnt exist</returns> public static string GetHeaderValueIfExists(this IMimePart mimePart, string header) { ExceptionUtilities.CheckArgumentNotNull(mimePart, "mimePart"); string headerValue; if (!mimePart.Headers.TryGetValue(header, out headerValue)) { headerValue = null; } return(headerValue); }
public static bool TryGetHeaderValueIgnoreHeaderCase(this IMimePart mimePart, string parameterName, out string parameterValue) { bool foundContentType = mimePart.Headers.TryGetValue(parameterName, out parameterValue); if (!foundContentType) { if (!mimePart.Headers.TryGetValue(parameterName.ToLowerInvariant(), out parameterValue)) { return(false); } } return(true); }
/// <summary> /// Tries to get the given parameter from the mime part's content type /// </summary> /// <param name="mimePart">The mime part</param> /// <param name="parameterName">The content-type paramter to look for</param> /// <param name="parameterValue">The value of the parameter if it is found</param> /// <returns>Whether or not the parameter was found</returns> internal static bool TryGetContentTypeParameter(this IMimePart mimePart, string parameterName, out string parameterValue) { ExceptionUtilities.CheckArgumentNotNull(mimePart, "mimePart"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(parameterName, "parameterName"); parameterValue = null; string contentType; if (!mimePart.TryGetHeaderValueIgnoreHeaderCase(HttpHeaders.ContentType, out contentType)) { return(false); } return(HttpUtilities.TryGetContentTypeParameter(contentType, parameterName, out parameterValue)); }
internal static void ReadHeaders(ref byte[] buffer, IMimePart mimePart, Encoding encoding) { while (buffer.Length > 0) { var line = ReadLine(ref buffer, encoding); if (string.IsNullOrEmpty(line)) { // indicates two newlines in a row, means we should stop break; } int index = line.IndexOf(": ", StringComparison.Ordinal); if (index < 0) { // throw? mimePart.Headers[line] = null; } else { mimePart.Headers[line.Substring(0, index)] = line.Substring(index + 2); } } }
/// <summary> /// Tries to get the 'charset' portion of the given mime-part's content-type /// </summary> /// <param name="mimePart">The mime part to get the charset for</param> /// <param name="charset">The charset if its value is found</param> /// <returns>Whether or not the charset was found</returns> public static bool TryGetMimeCharset(this IMimePart mimePart, out string charset) { ExceptionUtilities.CheckArgumentNotNull(mimePart, "mimePart"); return(mimePart.TryGetContentTypeParameter(HttpHeaders.Charset, out charset)); }
/// <summary> /// Tries to get the 'boundary' portion of the given mime-part's content-type /// </summary> /// <param name="mimePart">The mime part to get the boundary for</param> /// <param name="boundary">The boundary if its value is found</param> /// <returns>Whether or not the boundary was found</returns> public static bool TryGetMimeBoundary(this IMimePart mimePart, out string boundary) { ExceptionUtilities.CheckArgumentNotNull(mimePart, "mimePart"); return(mimePart.TryGetContentTypeParameter(HttpHeaders.Boundary, out boundary)); }
internal MimePartData <HttpResponseData> BuildResponseFromPart(MimePartData <byte[]> mimePart, IMimePart currentRequestPart, Encoding encoding) { var odataRequest = currentRequestPart as ODataRequest; HttpResponseData responsePart = CreateResponse(mimePart.Body, encoding); if (odataRequest != null) { responsePart = this.RequestManager.BuildResponse(odataRequest, responsePart); } var rebuiltPart = new MimePartData <HttpResponseData>(); rebuiltPart.Headers.AddRange(mimePart.Headers); rebuiltPart.Body = responsePart; return(rebuiltPart); }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="changeSetBoundary">The changeset boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultChangeSetBatch( IODataRequestManager requestManager, int changeSetCount, int[] changeSetSizes, bool forRequest, string changeSetBoundary = null) { Debug.Assert(changeSetCount >= 0, "batchSize >= 0"); Debug.Assert(changeSetSizes != null, "changeSetSizes != null"); Debug.Assert(changeSetSizes.Length == changeSetCount, "Size of the batch must match the length of the change set sizes array!"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[changeSetCount]; if (forRequest) { // Delete operation with no payload var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i = 0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var deleteOperations = new IMimePart[changeSetSize]; for (int j = 0; j < changeSetSize; ++j) { deleteOperations[j] = deleteOperation; } var changeset = BatchUtils.GetRequestChangeset(deleteOperations, requestManager); parts[i] = changeset; } ; string requestBoundary = changeSetBoundary ?? "bb_multiple_request_changesets_" + changeSetCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }); } // Response operation with no payload and a status code of 200 var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager); for (int i = 0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var operationResponses = new IMimePart[changeSetSize]; for (int j = 0; j < changeSetSize; ++j) { operationResponses[j] = emptyPayloadOperation; } var changeset = BatchUtils.GetResponseChangeset(operationResponses, requestManager); parts[i] = changeset; } ; string responseBoundary = changeSetBoundary ?? "bb_multiple_response_changesets_" + changeSetCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }); }
/// <summary> /// Adds a header to the IMimePart /// </summary> /// <param name="part">The part to add header to.</param> /// <param name="header">The header to add.</param> /// <returns>The IMimePart with an additional header.</returns> public static IMimePart AddHeader(this IMimePart part, KeyValuePair <string, string> header) { part.Headers.Add(header); return(part); }
/// <summary> /// Gets the value of the 'DataServiceVersion' header for the given request or response /// </summary> /// <param name="part">The request to get the version header value from</param> /// <returns>The value of the 'DataServiceVersion' header from the request or response</returns> public static DataServiceProtocolVersion GetDataServiceVersion(this IMimePart part) { return(part.GetProtocolVersionFromHeader(HttpHeaders.DataServiceVersion)); }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="batchBoundary">The batch boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultQueryBatch( IODataRequestManager requestManager, int queryCount, bool forRequest, string batchBoundary = null) { Debug.Assert(queryCount >= 0, "batchSize >= 0"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[queryCount]; if (forRequest) { var queryOperation = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i = 0; i < queryCount; ++i) { parts[i] = queryOperation; }; string requestBoundary = batchBoundary ?? "bb_multiple_request_queries_" + queryCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }; } // Response operation with no payload and a status code of 200 var emptyPayloadResponse = emptyPayload.InResponseOperation(200, requestManager); for (int i=0; i < queryCount; ++i) { parts[i] = emptyPayloadResponse; }; string responseBoundary = batchBoundary ?? "bb_multiple_response_queries_" + queryCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }; }
internal MimePartData<HttpResponseData> BuildResponseFromPart(MimePartData<byte[]> mimePart, IMimePart currentRequestPart, Encoding encoding) { var odataRequest = currentRequestPart as ODataRequest; HttpResponseData responsePart = CreateResponse(mimePart.Body, encoding); if (odataRequest != null) { responsePart = this.RequestManager.BuildResponse(odataRequest, responsePart); } var rebuiltPart = new MimePartData<HttpResponseData>(); rebuiltPart.Headers.AddRange(mimePart.Headers); rebuiltPart.Body = responsePart; return rebuiltPart; }
/// <summary> /// Reads a batch operation response message from the batch reader. /// </summary> /// <param name="batchReader">The batch reader to read from.</param> /// <param name="expectedPart">The expected part representing the operation in the test OM; used to determine the expected payload kind.</param> /// <param name="indexInPart">The index of the operation in the current changeset or -1 for a top-level operation.</param> /// <returns>The <see cref="ODataBatchOperation"/> read from the batch reader.</returns> private ODataBatchOperation GetResponseOperation(ODataBatchReaderTestWrapper batchReader, IMimePart expectedPart, int indexInPart) { IMimePart responsePart = indexInPart < 0 ? ((MimePartData<HttpResponseData>)expectedPart).Body : ((BatchResponseChangeset)expectedPart).Operations.ElementAt(indexInPart); ODataPayloadElement expectedPartElement = null; ODataResponse odataResponse = responsePart as ODataResponse; if (odataResponse != null) { expectedPartElement = odataResponse.Body == null ? null : odataResponse.RootElement; } object partPayload = null; ODataBatchOperationResponseMessage responseMessage = batchReader.CreateOperationResponseMessage(); if (expectedPartElement != null) { ODataPayloadKind expectedPartKind = expectedPartElement.GetPayloadKindFromPayloadElement(); ODataMessageReaderSettings messageReaderSettings = new ODataMessageReaderSettings(this.testConfiguration.MessageReaderSettings) { DisableMessageStreamDisposal = false }; using (ODataMessageReader partMessageReader = new ODataMessageReader(responseMessage, messageReaderSettings, this.payloadModel)) { ODataMessageReaderTestWrapper partMessageReaderWrapper = new ODataMessageReaderTestWrapper( partMessageReader, messageReaderSettings, this.testConfiguration); partPayload = this.messageToObjectModelReader.ReadMessage( partMessageReaderWrapper, expectedPartKind, this.payloadModel, PayloadReaderTestDescriptor.ReaderMetadata.None, /*batchPayload*/ null, this.testConfiguration); } } return new ODataBatchResponseOperation { StatusCode = responseMessage.StatusCode, Headers = responseMessage.Headers, Payload = partPayload, }; }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="changeSetBoundary">The changeset boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultChangeSetBatch( IODataRequestManager requestManager, int changeSetCount, int[] changeSetSizes, bool forRequest, string changeSetBoundary = null) { Debug.Assert(changeSetCount >= 0, "batchSize >= 0"); Debug.Assert(changeSetSizes != null, "changeSetSizes != null"); Debug.Assert(changeSetSizes.Length == changeSetCount, "Size of the batch must match the length of the change set sizes array!"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[changeSetCount]; if (forRequest) { // Delete operation with no payload var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i=0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var deleteOperations = new IMimePart[changeSetSize]; for(int j=0; j< changeSetSize; ++j) { deleteOperations[j] = deleteOperation; } var changeset = BatchUtils.GetRequestChangeset(deleteOperations, requestManager); parts[i] = changeset; }; string requestBoundary = changeSetBoundary ?? "bb_multiple_request_changesets_" + changeSetCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }; } // Response operation with no payload and a status code of 200 var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager); for (int i=0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var operationResponses = new IMimePart[changeSetSize]; for(int j=0; j< changeSetSize; ++j) { operationResponses[j] = emptyPayloadOperation; } var changeset = BatchUtils.GetResponseChangeset(operationResponses, requestManager); parts[i] = changeset; }; string responseBoundary = changeSetBoundary ?? "bb_multiple_response_changesets_" + changeSetCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }; }