1

Digging into sending a multipart POST call using flurl to a client's server. Unfortunately, their server is a black box to us. I'm getting a 400 back, with a generic message, so before I bug them, I need to have all my bases covered.

Performing a call like this:

string s = await "https://clientservier.com/cgi-bin/perl-script"
    .PostMultipartAsync(mp => mp
        .AddString("DisplayActive", "IsDisplayed")
        .AddString("ControlTypeHidden", "ALL")
        .AddString("QueryHidden", "KEYs")
        .AddString("dump_app_trace", "false")
        .AddString("db_debug", "false")
        .AddString("Get Data", "Get Data"))
    .ReceiveString();

If I attach a handler on the BeforeCall event, and look at HttpCall object, my variables are listed in the Request.Content.Parts as expected. However, the RequestBody is null- I'd like to see the string output of the request sent, similar to:

-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="DisplayActive"

IsDisplayed
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="ControlTypeHidden"

ALL
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="QueryHidden"

KEYs
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="Get Data"

Get Data
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="dump_app_trace"

false
-----------------------------13377838992432022416720759
Content-Disposition: form-data; name="db_debug"

false
-----------------------------13377838992432022416720759--

(Obviously, yes, the boundary would be different, this is just a browser example.) Interestingly, when the call comes back with the 400, the AfterCall event handler does NOT have the above Parts in the object, so I'm wondering if I'm forgetting to do something before making this call.

Coyttl
  • 537
  • 1
  • 4
  • 19
  • Would ask why the downvote, to help improve my questions, but I'm pretty sure it was just a troll. – Coyttl Aug 17 '20 at 15:26

1 Answers1

1

It's definitely unintuitive that RequestBody is null in this case. In the HttpClient stack, request bodies are basically read-once streams, making it difficult to read it back as a string if you need to for diagnostics. Flurl basically says, yeah, that's probably a micro-optimization in most typical cases, such as JSON or URL-encoded POSTs where request bodies don't tend to be very big. So internally it uses a type called CapturedStringContent, which just "captures" the string to a property on construction. Event handlers use this to expose that RequestBody property.

But multipart requests are much more likely to be large, and capturing the request body in string could be a legitimate memory concern. So the types at play here don't derive from CapturedStringContent and hence you can't easily get at the body as a string.

As to why Parts is empty, HttpClient (which Flurl is built to top of) disposes the HttpContent object automatically after the request is sent. Strangely (in my opinion), this clears the underlying collection that Parts comes from, which I confirmed in the source.

All that being said, your code looks fine to me and I have little doubt it's doing what you expect. But if you want to be absolutely certain, I'd suggest using a network sniffer like Fiddler or Wireshark.

Todd Menier
  • 37,557
  • 17
  • 150
  • 173
  • Okay, that makes sense, since the multipart is often used for binary files. I will likely get Wireshark and take a peek - though I'm still concerned by my "Parts" in the AfterCall event are empty - that worries me a little as well. – Coyttl Aug 14 '20 at 21:18
  • 1
    Interesting point about Parts being empty after the call. I wasn't even aware of that behavior but I figured out why and updated the answer. I could probably come up with a way for Flurl to make sure it doesn't lose it. Feel free to log an issue, I think it would be a good enhancement. – Todd Menier Aug 15 '20 at 14:32
  • Will do, thanks for the explanation too. In this case, I have something else going on and will need help from the client. Thanks! – Coyttl Aug 15 '20 at 20:32