0

I need to mock a post request with multipart form body as given below. I tried with a regex pattern for the unique string in the body --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN , but it didn't work. Can some one guide me on this?

BODY :

"body":"--Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN
Content-Disposition: form-data; name="dataset"
Content-Type: text/plain;charset=UTF-8
Content-Length: 14 drugs --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN
Content-Disposition: form-data; name="searchQuery"
Content-Type: text/plain;charset=UTF-8
Content-Length: 6 cancer --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN
Content-Disposition: form-data; name="queryLanguage"
Content-Type: text/plain;charset=UTF-8
Content-Length: 4 ssql --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN
Content-Disposition: form-data; name="returnFields"
Content-Type: text/plain;charset=UTF-8
Content-Length: 22 Id,name --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN
Content-Disposition: form-data; name="returnLimit"
Content-Type: text/plain;charset=UTF-8
Content-Length: 1 1 --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN
Content-Disposition: form-data; name="offset"
Content-Type: text/plain;charset=UTF-8
Content-Length: 1 0 --Z5KfGboCdJvPl4VsEq74AeK7PZN4EyN-- "

I tried like -

mockServerClient
.when(
request()
.withMethod("POST")
.withHeaders(
new Header("Content-Type", "multipart/form-data"))
.withPath("abc/xyz")
.withBody(**regex("[\n.\w\W]***
Content-Disposition: form-data; name="dataset"
Content-Type: text/plain;charset=UTF-8
Content-Length: 14 drugs [\n.\w\W]*
Content-Disposition: form-data; name="searchQuery"
Content-Type: text/plain;charset=UTF-8
Content-Length: 6 cancer [\n.\w\W]*
Content-Disposition: form-data; name="queryLanguage"
Content-Type: text/plain;charset=UTF-8
Content-Length: 4 ssql [\n.\w\W]*
Content-Disposition: form-data; name="returnFields"
Content-Type: text/plain;charset=UTF-8
Content-Length: 22 Id,name [\n.\w\W]*
Content-Disposition: form-data; name="returnLimit"
Content-Type: text/plain;charset=UTF-8
Content-Length: 1 1 [\n.\w\W]*
Content-Disposition: form-data; name="offset"
Content-Type: text/plain;charset=UTF-8
Content-Length: 1 0 [\n.\w\W]*-- "))
)
rgettman
  • 176,041
  • 30
  • 275
  • 357

3 Answers3

0

Try this regex:

^(--[\w]+)$\n(?:^Content-Disposition: form-data; name=\"\w+?\"$\n^Content-Type: text/plain;charset=UTF-8$\n^Content-Length: \d+? [\w,]+ \1(?:-- $|$\n))+

In your version I didn't see that you are escaping the double quotes " to a \", wondering if the code compiles at all. Also the [\n.\w\W] seems to be a bit too generic.

The above version is also generic, but in a different way:

(--[\w]+) - this is a group that expects the border boundary string. In the rest of the expression the match it is "back referenced" as \1, this means only requests with the same border over the whole request are accepted.

A longer part is following for one of the parts between the borders boundaries. Please note that the expression does not care which parts are actually contained in the request. If you need that, let me know then I can update the expression to accept just the given parts.

Update to state it clearly: You can put any string between the boundaries that you want, any headers etc. But you have to use regular expression syntax there when it comes to line breaks and other stuff that is interpreted special in a regex, like \, ", . and many others. Escape them!

So to sum it up: you put the regex for the boundary (--[\w]+) only for the first occurence and put a back reference to that (\1) everywhere after where you expect the same boundary (the same characters, not just the same pattern). Inbetween you can place any stuff you want, just take care to escape it properly for a regex. In Java you can do this (just for the "inner" part) with java.util.Pattern.quote(String)

Update 2: When your body does not contain line breaks but just separates the parts with spaces, you can try this modified regex:

^(--[\w]+)\s+(?:Content-Disposition: form-data; name=\"\w+?\"\s+Content-Type: text/plain;charset=UTF-8\s+Content-Length: \d+? [\w,]+ \1(?:-- $|\s+))+
cyberbrain
  • 3,433
  • 1
  • 12
  • 22
0

@cyberbrain. Thanks for looking into this.

I am trying to mock post request with multipart - form data , where the post body looks like i have shown below (where the boundary value changes on every run) . so , i am trying to use regex only for boundary part .Any pointers will be really helpful.

I tried the regex you have suggested but it didnt work . Actual Request -

{
"method":"POST"
"path":"/abc/xyz"
"headers":{...}
"keepAlive":true
"secure":false
"body":"--y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54 Content-Disposition: form-data; name="dataset" Content-Type: text/plain;charset=UTF-8 Content-Length: 14 drug --y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54 Content-Disposition: form-data; name="searchQuery" Content-Type: text/plain;charset=UTF-8 Content-Length: 6 cancer --y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54 Content-Disposition: form-data; name="queryLanguage" Content-Type: text/plain;charset=UTF-8 Content-Length: 4 ssql --y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54 Content-Disposition: form-data; name="returnFields" Content-Type: text/plain;charset=UTF-8 Content-Length: 7 Id,Name --y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54 Content-Disposition: form-data; name="returnLimit" Content-Type: text/plain;charset=UTF-8 Content-Length: 1 1 --y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54 Content-Disposition: form-data; name="offset" Content-Type: text/plain;charset=UTF-8 Content-Length: 1 0 --y_My4VSoa71UaoRG6KF4DM_MZAP7AKDz54-- "
}

mock request i gave like this -

mockServerClient
.when(
      request()
        .withMethod("POST")
//      .withHeaders(
//         new Header("Content-Type", "multipart/form-data"))
        .withPath("/abc/xyz")
        .withBody(regex("(--[\\w]+) Content-Disposition: form-data; name=\"dataset\" Content-Type: text/plain;charset=UTF-8 Content-Length: 14 drug (--[\\w]+) Content-Disposition: form-data; name=\"searchQuery\" Content-Type: text/plain;charset=UTF-8 Content-Length: 6 cancer (--[\\w]+) Content-Disposition: form-data; name=\"queryLanguage\" Content-Type: text/plain;charset=UTF-8 Content-Length: 4 ssql (--[\\w]+) Content-Disposition: form-data; name=\"returnFields\" Content-Type: text/plain;charset=UTF-8 Content-Length: 7 Id,Name (--[\\w]+) Content-Disposition: form-data; name=\"returnLimit\" Content-Type: text/plain;charset=UTF-8 Content-Length: 1 1 (--[\\w]+) Content-Disposition: form-data; name=\"offset\" Content-Type: text/plain;charset=UTF-8 Content-Length: 1 0 (--[\\w]+)-- "))
)

**and the expectation set by Mock Server as- ** -

"httpRequest":{
"method":"POST"
"path":"/abc/xyz"
"body":{
"type":"REGEX"
"regex":"(--[\w]+) Content-Disposition: form-data; name="dataset" Content-Type: text/plain;charset=UTF-8 Content-Length: 14 drug (--[\w]+) Content-Disposition: form-data; name="searchQuery" Content-Type: text/plain;charset=UTF-8 Content-Length: 6 cancer (--[\w]+) Content-Disposition: form-data; name="queryLanguage" Content-Type: text/plain;charset=UTF-8 Content-Length: 4 ssql (--[\w]+) Content-Disposition: form-data; name="returnFields" Content-Type: text/plain;charset=UTF-8 Content-Length: 7 Id,Name (--[\w]+) Content-Disposition: form-data; name="returnLimit" Content-Type: text/plain;charset=UTF-8 Content-Length: 1 1 (--[\w]+) Content-Disposition: form-data; name="offset" Content-Type: text/plain;charset=UTF-8 Content-Length: 1 0 (--[\w]+)-- "
}
}
  • I updated my answer with a hopefully better explanation, how to proceed if you try "to use regex only for boundary part", and another update if your body doesn't contain linebreaks but just spaces instead (as your "Actual Request" here suggests) – cyberbrain Aug 23 '22 at 13:40
0

Try this!

String regex = "--[\\w-]+\\sContent-Disposition: form-data; name=\"[^\"]+\"\\sContent-Type: text/plain;charset=UTF-8\\sContent-Length: \\d+\\s[\\s\\S]*?--[\\w-]+--\\s";
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 10 '23 at 20:02