Skip to main content
Solved

HTTP connector form-data

  • 2 July 2024
  • 9 replies
  • 121 views

I want to connect our ERP with Documizers/Docuflow using their API. In short: the first step is to create a workspace, the second is filling that workspace with data.
I use Postman to test step 1:
 

The ID that returns I can use in step 2.

How do I translate this Postman-POST to the HTTP-connector POST?
No matter what I try, Indicium is returning error 400: Bad request.
My return-parameter http_result_id is filled with:
{"":{"Failed to read the request form. Invalid header line:     "]}
in stead of an ID.

This is how I activate the HTTP-connector:
 

And this is the content of http_body:

set @http_body=
--ItemID
'
--abcde12345
Content-Disposition: form-data; name="ProcessName"

Koffieadvies
--abcde12345
Content-Disposition: form-data; name="File.Name"

pdw
--abcde12345
Content-Disposition: form-data; name="File.Extension"

.txt
--abcde12345
Content-Disposition: form-data; name="File.Content"; filename="123.txt"

123
abcde12345--
'

The API needs a file (with is an empty one).
I also tried just sending the processname, but it still returns Bad request .

Does it make a difference if I use the HTTP-connector in a systemflow or in a procesflow, triggered by a task ?
Anyone has an idea ?

This topic has been closed for comments

9 replies

Userlevel 6
Badge +4

Hello @Peter de Wit 

It’s a little bit hard to judge at face value, but I can at least see one thing that’s definitely wrong and some other things that might be wrong.

So first of all, what’s definitely wrong is that the final boundary does not have the -- prefix. Every boundary must be prefixed by -- and the final boundary must also have a suffix of --.

Another thing is that the section header for the file content does not specify a Content-Type. I’m not entirely certain that this is necessary, but I would definitely have expected it to be there.

So this part:

--abcde12345
Content-Disposition: form-data; name="File.Content"; filename="123.txt"

123

 Should look like this:

--abcde12345
Content-Disposition: form-data; name="File.Content"; filename="123.txt"
Content-Type: text/plain

123

Finally, the new lines after the starting quotation mark and before the closing quotation mark are included in the value of the request body now. This might not matter either, but to be safe, it would better to remove these.

So, without having tested this, here is an improved version that might solve your problem:

set @http_body = '--abcde12345
Content-Disposition: form-data; name="ProcessName"

Koffieadvies
--abcde12345
Content-Disposition: form-data; name="File.Name"

pdw
--abcde12345
Content-Disposition: form-data; name="File.Extension"

.txt
--abcde12345
Content-Disposition: form-data; name="File.Content"; filename="123.txt"
Content-Type: text/plain

123
--abcde12345--';

As for your question

Does it make a difference if I use the HTTP-connector in a systemflow or in a procesflow, triggered by a task ?

No, this does not make a difference, not in this sense anyway.

 

I hope this helps.

Badge +4

Hi Vincent, thanks for your rapid response. The missing suffix -- at then end was bad but didn't do the tric. I copy/paste your improved version into my parameter but the response is still the same.
I read in an earlier post that hidden characters could cause damage so I hexed then content using Ultra Edit. I can not delete the first 0D 0A, it's coming back when I paste it back into my parameter.
Can you judge my case better now ? 😉

 

Userlevel 4
Badge +11

Maybe look at this sending a pdf with the http connector | Thinkwise Community (thinkwisesoftware.com)

You may want to try a varbinary if you don't already.

Userlevel 6
Badge +4

Hello @Peter de Wit,

It looks like I was mistaken in my last point, the new lines at the start and at the end are actually necessary - when following the spec strictly.

So this would be the correct value then:

set @http_body = '
--abcde12345
Content-Disposition: form-data; name="ProcessName"

Koffieadvies
--abcde12345
Content-Disposition: form-data; name="File.Name"

pdw
--abcde12345
Content-Disposition: form-data; name="File.Extension"

.txt
--abcde12345
Content-Disposition: form-data; name="File.Content"; filename="123.txt"
Content-Type: text/plain

123
--abcde12345--
';

In your Ultra Edit hex view the 0D 0A at the start is a new line (a carriage return and a line feed). So the 0D 0A at the start should actually be correct, but there should also be a 0A 0D at the end. I do have some doubts that this will actually fix the problem because typically I don’t think servers are that strict regarding the leading and trailing new lines. However, I also don’t see anything else wrong, so it’s my best guess at the moment.

Possibly a better option though is to look at using a varbinary process variable for the Content input parameter, and constructing the varbinary data yourself, as shown in this topic here:

https://community.thinkwisesoftware.com/questions%2Dconversations%2D78/example%2Drest%2Dapi%2Dmultipart%2Dform%2Dusing%2Dmsxml2%2Dxmlhttp%2D2229?postid=10087#post10087

This has worked in the past and gives you more control over the exact contents of the data (i.e. you’re no longer at the mercy of hidden characters in text editors and such).

If this doesn’t work, can you verify that the Bad Request response that you are getting is still the same (the same error message). It’s possible that something else has gone wrong.

Badge +4

Hi Vincent (& Hugo 😀), i read this post and tried to avoid this more complex way. I am not dealing with a file (with content) so why use varbinary ? And another reason, with Postman it seems to work with plain text according to the different languages in Code snippet….
But, I need this step so I'll give it a try. I only have to varbinary the content-parameter using the example  ?

Userlevel 6
Badge +4

Hello @Peter de Wit,

Strictly speaking it should not be necessary to use a varbinary, however, it does give you a great deal of control over the exact bytes that are sent and you can be certain that there are no hidden characters or extra white spaces. Furthermore, it also bypasses Indicium’s own text to binary conversion and any encoding issues that might arise there (in the end both Postman and Indicium must convert the text to binary data at some point). So, since the problem in your case isn’t immediately obvious, this will eliminate a few causes.

I’ve written out the varbinary solution for you. Using the code below, all you have to do is change the http_body process variable to a varbinary(max) (or a large enough varbinary). As far as I can tell, this should yield the exact same bytes, so I’m not necessarily expecting this to work, but as said earlier, it eliminates a few more variables that might be causing trouble here. If you want to double check what you will be sending, you can simply convert it back to varchar in a select.

declare @line_break varbinary(2) = 0x0D0A;
declare @separator varbinary(100) = convert(varbinary(100), '--abcde12345');
declare @final_separator varbinary(100) = convert(varbinary(100), '--abcde12345--');
declare @content_disposition_start varbinary(200) = convert(varbinary(200), 'Content-Disposition: form-data; name="');
declare @content_disposition_file_name varbinary(100) = convert(varbinary(100), '"; filename="');
declare @content_disposition_end varbinary(4) = convert(varbinary(4), '"');
declare @content_type varbinary(100) = convert(varbinary(100), 'Content-Type: text/plain');

set @http_body =
@line_break +
@separator + @line_break +
@content_disposition_start + convert(varbinary(100), 'ProcessName') + @content_disposition_end + @line_break +
@line_break +
convert(varbinary(100), 'Koffieadvies') +

@line_break +
@separator + @line_break +
@content_disposition_start + convert(varbinary(100), 'File.Name') + @content_disposition_end + @line_break +
@line_break +
convert(varbinary(100), 'pdw') +

@line_break +
@separator + @line_break +
@content_disposition_start + convert(varbinary(100), 'File.Extension') + @content_disposition_end + @line_break +
@line_break +
convert(varbinary(100), '.txt') +

@line_break +
@separator + @line_break +
@content_disposition_start + convert(varbinary(100), 'File.Content') + @content_disposition_file_name + convert(varbinary(100), '123.txt') + @content_disposition_end + @line_break +
@content_type + @line_break +
@line_break +
convert(varbinary(100), '123') +

@line_break + @final_separator +
@line_break;

If this doesn’t work however, I would recommend recreating the request in the Insomnia REST client, which is a tool similar to Postman, and then have a look at the Timeline tab after sending the request, which will show you the exact request body that is being sent. I did a small test and saw this result, which shows no leading or trailing line breaks and also no extra line breaks between the headers and the data. If you can get the request to work in Insomnia, it really should be straightforward to get it to work in Indicium as well.

I hope this helps.

Badge +4

Hi Vincent,

Thanx for the time/effort you put in this issue ! 💪🏻

But yesterday I already tried the varbinary-option as below. I changed the first part of the body and got a proper result so this part looks OK !: {"file.Content":["Content is verplicht."]}

declare @line_break varbinary(2) = 0x0D0A;
declare @separator varbinary(100) = convert(varbinary(100), '--abcde12345');
declare @final_separator varbinary(100) = convert(varbinary(100), '--abcde12345--'); 

set @http_body_varbin =
@line_break + -- Follow each separator with a line break
@separator + -- Start each block with the multipart separator
@line_break + -- Follow each separator with a line break
convert(varbinary(max), 'Content-Disposition: form-data; name="ProcessName"')+
@line_break +
@line_break +
convert(varbinary(max),'Koffieadvies') +
@line_break +
@separator + -- Start each block with the multipart separator
@line_break + -- Follow each separator with a line break
convert(varbinary(max), 'Content-Disposition: form-data; name="File.Name"')+
@line_break +
@line_break +
convert(varbinary(max),'pdw') +
@line_break +
@separator + -- Start each block with the multipart separator
@line_break + -- Follow each separator with a line break
convert(varbinary(max), 'Content-Disposition: form-data; name="File.Extension"')+
@line_break +
@line_break +
convert(varbinary(max),'.txt') +
@line_break +
@final_separator -- The final separator should the the separator plus two additional dashes at the end
/*
@separator + 
@line_break +
convert(varbinary(max), 'Content-Disposition: form-data; name="File.Content"; filename="123.txt"') +
@line_break +
convert(varbinary(max), 'Content-Type: text/plain') +
@line_break +
@line_break +
convert(varbinary(max),'123.txt') +
@final_separator -- The final separator should the the separator plus two additional dashes at the end

*/

But when I add the file content by removing /* & */ and remove then first final_separator this error is  back again: 
{"":["Failed to read the request form. Unexpected end of Stream, the content may have already been read by another component. "]}

I'm getting close, the problem seems to be in the last part.
Any idea before I try to start debugging with Insomnia ?

Userlevel 6
Badge +4

Hello @Peter de Wit,

You are missing a @line_break here between the data and the @final_separator:

convert(varbinary(max),'123.txt') +
@final_separator -- The final separator should the the separator plus two additional dashes at the end

 

And this probably goes without saying, but just to be sure, you need to remove your previous @final_separator when removing the /* */ comment markers, so you don't have two @final_separators.

I hope this helps.

Badge +4

Goooooodmorning Vincent,

One final word to say: YYYIIIIIIIIIHAAAAAAAAAAAH ! 😁

{"id":2746,"displayName":"pdw"}   🏆

 

Ready now for the next chapter, thanx !