Ejemplo n.º 1
0
        /// <summary>
        /// Sends a multipart HTTP POST request (useful for posting files) but doesn't call GetResponse on it.
        /// </summary>
        /// <param name="request">The HTTP request.</param>
        /// <param name="requestHandler">The request handler.</param>
        /// <param name="parts">The parts to include in the POST entity.</param>
        internal static void PostMultipartNoGetResponse(this HttpWebRequest request, IDirectWebRequestHandler requestHandler, IEnumerable <MultipartPostPart> parts)
        {
            Contract.Requires <ArgumentNullException>(request != null);
            Contract.Requires <ArgumentNullException>(requestHandler != null);
            Contract.Requires <ArgumentNullException>(parts != null);

            Reporting.RecordFeatureUse("MessagingUtilities.PostMultipart");
            parts = parts.CacheGeneratedResults();
            string boundary = Guid.NewGuid().ToString();
            string initialPartLeadingBoundary = string.Format(CultureInfo.InvariantCulture, "--{0}\r\n", boundary);
            string partLeadingBoundary        = string.Format(CultureInfo.InvariantCulture, "\r\n--{0}\r\n", boundary);
            string finalTrailingBoundary      = string.Format(CultureInfo.InvariantCulture, "\r\n--{0}--\r\n", boundary);
            var    contentType = new ContentType("multipart/form-data")
            {
                Boundary = boundary,
                CharSet  = Channel.PostEntityEncoding.WebName,
            };

            request.Method      = "POST";
            request.ContentType = contentType.ToString();
            long contentLength = parts.Sum(p => partLeadingBoundary.Length + p.Length) + finalTrailingBoundary.Length;

            if (parts.Any())
            {
                contentLength -= 2;                 // the initial part leading boundary has no leading \r\n
            }
            request.ContentLength = contentLength;

            var requestStream = requestHandler.GetRequestStream(request);

            try {
                StreamWriter writer    = new StreamWriter(requestStream, Channel.PostEntityEncoding);
                bool         firstPart = true;
                foreach (var part in parts)
                {
                    writer.Write(firstPart ? initialPartLeadingBoundary : partLeadingBoundary);
                    firstPart = false;
                    part.Serialize(writer);
                    part.Dispose();
                }

                writer.Write(finalTrailingBoundary);
                writer.Flush();
            } finally {
                // We need to be sure to close the request stream...
                // unless it is a MemoryStream, which is a clue that we're in
                // a mock stream situation and closing it would preclude reading it later.
                if (!(requestStream is MemoryStream))
                {
                    requestStream.Dispose();
                }
            }
        }
 /// <summary>
 /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity.
 /// </summary>
 /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param>
 /// <returns>
 /// The stream the caller should write out the entity data to.
 /// </returns>
 /// <exception cref="ProtocolException">Thrown for any network error.</exception>
 /// <remarks>
 /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/>
 /// and any other appropriate properties <i>before</i> calling this method.
 /// Callers <i>must</i> close and dispose of the request stream when they are done
 /// writing to it to avoid taking up the connection too long and causing long waits on
 /// subsequent requests.</para>
 /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a
 /// <see cref="ProtocolException"/> to abstract away the transport and provide
 /// a single exception type for hosts to catch.</para>
 /// </remarks>
 public Stream GetRequestStream(HttpWebRequest request)
 {
     _action(request);
     return(_wrappedHandler.GetRequestStream(request));
 }