summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs30
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs14
2 files changed, 41 insertions, 3 deletions
diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
index 26ce4cd..5a4c78e 100644
--- a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
@@ -11,8 +11,10 @@ namespace DotNetOpenAuth.Test.Messaging
using System.Collections.Specialized;
using System.IO;
using System.Net;
+ using System.Text.RegularExpressions;
using System.Web;
using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Test.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
@@ -139,5 +141,33 @@ namespace DotNetOpenAuth.Test.Messaging
Assert.AreEqual("%C2%80", MessagingUtilities.EscapeUriDataStringRfc3986("\u0080"));
Assert.AreEqual("%E3%80%81", MessagingUtilities.EscapeUriDataStringRfc3986("\u3001"));
}
+
+ /// <summary>
+ /// Verifies the overall format of the multipart POST is correct.
+ /// </summary>
+ [TestMethod]
+ public void PostMultipart() {
+ var httpHandler = new TestWebRequestHandler();
+ bool callbackTriggered = false;
+ httpHandler.Callback = req => {
+ Match m = Regex.Match(req.ContentType, "multipart/form-data; boundary=(.+)");
+ Assert.IsTrue(m.Success, "Content-Type HTTP header not set correctly.");
+ string boundary = m.Groups[1].Value;
+ string expectedEntity = "--{0}\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\nb\r\n--{0}--\r\n";
+ expectedEntity = string.Format(expectedEntity, boundary);
+ string actualEntity = httpHandler.RequestEntityAsString;
+ Assert.AreEqual(expectedEntity, actualEntity);
+ callbackTriggered = true;
+ Assert.AreEqual(req.ContentLength, actualEntity.Length);
+ IncomingWebResponse resp = new CachedDirectWebResponse();
+ return resp;
+ };
+ var request = (HttpWebRequest)WebRequest.Create("http://someserver");
+ var parts = new [] {
+ MultipartPostPart.CreateFormPart("a", "b"),
+ };
+ request.PostMultipart(httpHandler, parts);
+ Assert.IsTrue(callbackTriggered);
+ }
}
}
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 3f77a25..f57cf6b 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -141,7 +141,7 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
- /// Sends an multipart HTTP POST request (useful for posting files).
+ /// Sends a multipart HTTP POST request (useful for posting files).
/// </summary>
/// <param name="request">The HTTP request.</param>
/// <param name="requestHandler">The request handler.</param>
@@ -153,13 +153,19 @@ namespace DotNetOpenAuth.Messaging {
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);
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=" + boundary;
- request.ContentLength = parts.Sum(p => partLeadingBoundary.Length + p.Length) + finalTrailingBoundary.Length;
+ 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;
// Setting the content-encoding to "utf-8" causes Google to reply
// with a 415 UnsupportedMediaType. But adding it doesn't buy us
@@ -169,8 +175,10 @@ namespace DotNetOpenAuth.Messaging {
var requestStream = requestHandler.GetRequestStream(request);
try {
StreamWriter writer = new StreamWriter(requestStream, Channel.PostEntityEncoding);
+ bool firstPart = true;
foreach (var part in parts) {
- writer.Write(partLeadingBoundary);
+ writer.Write(firstPart ? initialPartLeadingBoundary : partLeadingBoundary);
+ firstPart = false;
part.Serialize(writer);
part.Dispose();
}