| Author | Message | 
		
		  | dsteinmann | 
			  
				|  Posted: Wed Dec 09, 2015 4:08 am    Post subject: POST multipart/form-data with HTTPRequestNode |   |  | 
		
		  | Novice
 
 
 Joined: 09 Dec 2015Posts: 15
 
 
 | 
			  
				| The flow creates a MIME multipart/form-data message and send it via HTTPRequestNode. Problem is that the target server does not accept the request complaining about wrong boundaries. 
 The message is generated like this:
 
 
   
	| Code: |  
	| DECLARE CONTENT BLOB ASBITSTREAM(InputRoot.XMLNSC, InputProperties.Encoding, InputProperties.CodedCharSetId);
 SET OutputRoot.Properties.CodedCharSetId = 1208;
 SET OutputRoot.Properties.ContentType = 'multipart/form-data; boundary=----------------------12a063b587462211';
 SET OutputRoot.HTTPRequestHeader.Accept = '*/*';
 CREATE LASTCHILD OF OutputRoot DOMAIN('MIME');
 CREATE LASTCHILD OF OutputRoot.MIME TYPE Name NAME 'Parts';
 CREATE LASTCHILD OF OutputRoot.MIME.Parts TYPE Name NAME 'Part';
 DECLARE P1 REFERENCE TO OutputRoot.MIME.Parts.Part;
 CREATE FIELD P1."Content-Type" TYPE NameValue VALUE 'application/xml';
 CREATE FIELD P1."Content-Disposition" TYPE NameValue VALUE 'form-data; name="REQUEST"';
 CREATE LASTCHILD OF P1 TYPE Name NAME 'Data';
 CREATE LASTCHILD OF P1.Data DOMAIN('BLOB') PARSE(CONTENT);
 
 |  
 The target server does not like the extra empty line after the HTTP header and the first boundary.
 
 If I create the multipart/form-data request in the BLOB domain, the target server is happy:
 
 
   
	| Code: |  
	| DECLARE CR BLOB CAST(X'0D0A' AS BLOB);
 SET OutputRoot.Properties.CodedCharSetId = 1208;
 SET OutputRoot.HTTPRequestHeader."Content-Type" = 'multipart/form-data; boundary=TheBoundary';
 SET OutputRoot.HTTPRequestHeader.Accept = '*/*';
 DECLARE body BLOB '';
 SET body = body || CAST('--TheBoundary' AS BLOB CCSID 1208);
 SET body = body || CR || CAST('Content-Disposition: form-data; name="REQUEST"' AS BLOB CCSID 1208);
 SET body = body || CR || CAST('Content-Type: application/xml' AS BLOB CCSID 1208);
 SET body = body || CR || CR || ASBITSTREAM(InputRoot.XMLNSC, InputProperties.Encoding, InputProperties.CodedCharSetId);
 SET body = body || CR || CAST('--TheBoundary' AS BLOB CCSID 1208);
 SET body = body || CR;
 SET OutputRoot.BLOB.BLOB = body;
 
 |  
 Does someone know how I can create the MIME message so this extra empty line after the HTTP Headers disappears?
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | dsteinmann | 
			  
				|  Posted: Wed Dec 09, 2015 4:10 am    Post subject: |   |  | 
		
		  | Novice
 
 
 Joined: 09 Dec 2015Posts: 15
 
 
 | 
			  
				| Sorry, I could not post how the HTTP Request looks on the wire (captured with Wireshark), because the forum did not allow me to enter URLs/links. |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | smdavies99 | 
			  
				|  Posted: Wed Dec 09, 2015 4:32 am    Post subject: |   |  | 
		
		  |  Jedi Council
 
 
 Joined: 10 Feb 2003Posts: 6076
 Location: Somewhere over the Rainbow this side of Never-never land.
 
 | 
			  
				| Now that you have posted twice why not try to post the url/links again. 
 The restriction is there to stop automated spam bots crapping all over the site.
 _________________
 WMQ User since 1999
 MQSI/WBI/WMB/'Thingy' User since 2002
 Linux user since 1995
 
 Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | dsteinmann | 
			  
				|  Posted: Wed Dec 09, 2015 8:38 am    Post subject: |   |  | 
		
		  | Novice
 
 
 Joined: 09 Dec 2015Posts: 15
 
 
 | 
			  
				| 
   
	| Quote: |  
	| Now that you have posted twice why not try to post the url/links again.
 
 |  Good point!
 
 Here is the problem message on the wire created by the MIME domain with the two empty lines between HTTP header:
 
 
   
	| Code: |  
	| POST /services/KMS/response.cfm HTTP/1.1
 Host: secure.intrum.ch
 ...
 Accept: */*
 Content-Type: multipart/form-data; boundary=------------------------12a063b587462211
 
 
 --------------------------12a063b587462211
 Content-Disposition: form-data; name="REQUEST"
 Content-Type: application/xml
 
 <n:request xmlns:n="http://www.intrum.ch/schema">
 ...
 
 |  And here the good message on the wire created by the BLOB domain:
 
 
   
	| Code: |  
	| POST /services/KMS/response.cfm HTTP/1.1
 Host: secure.intrum.ch
 ...
 Accept: */*
 Content-Type: multipart/form-data; boundary=TheBoundary
 
 --TheBoundary
 Content-Disposition: form-data; name="REQUEST"
 Content-Type: application/xml
 
 <n:request xmlns:n="http://www.intrum.ch/schema">
 ...
 
 |  The length or characters used in the boundary string have no influence; no matter what I use there are always two lines between HTTP header and boundary string in the MIME domain.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | fjb_saper | 
			  
				|  Posted: Wed Dec 09, 2015 9:01 am    Post subject: |   |  | 
		
		  |  Grand High Poobah
 
 
 Joined: 18 Nov 2003Posts: 20767
 Location: LI,NY
 
 | 
			  
				| Looks to me like your boundary string : 12a063b587462211 might end with a CRLF. But then that same CRLF is not recognized and introduces an extra blank line that causes the problem??  _________________
 MQ & Broker admin
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | dsteinmann | 
			  
				|  Posted: Wed Dec 09, 2015 1:52 pm    Post subject: |   |  | 
		
		  | Novice
 
 
 Joined: 09 Dec 2015Posts: 15
 
 
 | 
			  
				| I don't add this additional CRLF (see top of my post for complete code): 
 
   
	| Code: |  
	| SET OutputRoot.Properties.ContentType = 'multipart/form-data; boundary=----------------------12a063b587462211';
 
 |  |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | maurito | 
			  
				|  Posted: Thu Dec 10, 2015 12:41 am    Post subject: |   |  | 
		
		  | Partisan
 
 
 Joined: 17 Apr 2014Posts: 358
 
 
 | 
			  
				| 
   
	| dsteinmann wrote: |  
	| I don't add this additional CRLF (see top of my post for complete code): 
 
   
	| Code: |  
	| SET OutputRoot.Properties.ContentType = 'multipart/form-data; boundary=----------------------12a063b587462211';
 
 |  |  
 but you are not generating the same message with ESQL.
 Try generating EXACTLY the same message with ESQL, i.e
 
 
 
   
	| Code: |  
	| SET OutputRoot.Properties.ContentType = 'multipart/form-data; boundary=TheBoundary';
 
 |  
 That probably will work, and if it does, then you are a lot closer to working out why.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | dsteinmann | 
			  
				|  Posted: Thu Dec 10, 2015 2:38 am    Post subject: |   |  | 
		
		  | Novice
 
 
 Joined: 09 Dec 2015Posts: 15
 
 
 | 
			  
				| 
   
	| maurito wrote: |  
	| That probably will work, and if it does, then you are a lot closer to working out why.
 |  
 As I wrote previously ("The length or characters used in the boundary string have no influence"), the type boundary string does not matter.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | maurito | 
			  
				|  Posted: Thu Dec 10, 2015 3:14 am    Post subject: |   |  | 
		
		  | Partisan
 
 
 Joined: 17 Apr 2014Posts: 358
 
 
 | 
			  
				| 
   
	| dsteinmann wrote: |  
	| 
   
	| maurito wrote: |  
	| That probably will work, and if it does, then you are a lot closer to working out why.
 |  
 As I wrote previously ("The length or characters used in the boundary string have no influence"), the type boundary string does not matter.
 |  But the contents may have an influence. In your ESQL the field starts with "--" and in the BLOB it does not.
 
 If you want to say : it does not work in ESQL but it does with BLOB, you need to prove it with EXACTLY the same message. Otherwise your statement is invalid.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | dsteinmann | 
			  
				|  Posted: Thu Dec 10, 2015 3:27 am    Post subject: |   |  | 
		
		  | Novice
 
 
 Joined: 09 Dec 2015Posts: 15
 
 
 | 
			  
				| Ok, I did the test again. Here is the ESQL code: 
 
   
	| Code: |  
	| DECLARE CONTENT BLOB ASBITSTREAM(InputRoot.XMLNSC, InputProperties.Encoding, InputProperties.CodedCharSetId);
 SET OutputRoot.Properties.CodedCharSetId = 1208;
 SET OutputRoot.Properties.ContentType = 'multipart/form-data; boundary=TheBoundary';
 SET OutputRoot.HTTPRequestHeader.Accept = '*/*';
 CREATE LASTCHILD OF OutputRoot DOMAIN('MIME');
 CREATE LASTCHILD OF OutputRoot.MIME TYPE Name NAME 'Parts';
 CREATE LASTCHILD OF OutputRoot.MIME.Parts TYPE Name NAME 'Part';
 DECLARE P1 REFERENCE TO OutputRoot.MIME.Parts.Part;
 CREATE FIELD P1."Content-Type" TYPE NameValue VALUE 'application/xml';
 CREATE FIELD P1."Content-Disposition" TYPE NameValue VALUE 'form-data; name="REQUEST"';
 CREATE LASTCHILD OF P1 TYPE Name NAME 'Data';
 CREATE LASTCHILD OF P1.Data DOMAIN('BLOB') PARSE(CONTENT);
 
 |  And here is what I captured with Wireshark:
 
 
   
	| Code: |  
	| POST /services/KMS/response.cfm HTTP/1.1
 Content-Length: 614
 Accept: */*
 Content-Type: multipart/form-data; boundary=TheBoundary
 Host: secure.intrum.ch
 SOAPAction: ""
 Connection: Keep-Alive
 
 
 --TheBoundary
 Content-Type: application/xml
 Content-Disposition: form-data; name="REQUEST"
 
 <n:request xmlns:n="http://www.intrum.ch/schema">
 ...
 
 |  There are 2 empty lines between the last HTTP header and the first boundary. But the target server (secure.intrum.ch) expects exactly 1 empty line.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  | maurito | 
			  
				|  Posted: Thu Dec 10, 2015 3:33 am    Post subject: |   |  | 
		
		  | Partisan
 
 
 Joined: 17 Apr 2014Posts: 358
 
 
 | 
			  
				| 
   
	| dsteinmann wrote: |  
	| Ok, I did the test again. Here is the ESQL code: 
 
   
	| Code: |  
	| DECLARE CONTENT BLOB ASBITSTREAM(InputRoot.XMLNSC, InputProperties.Encoding, InputProperties.CodedCharSetId);
 SET OutputRoot.Properties.CodedCharSetId = 1208;
 SET OutputRoot.Properties.ContentType = 'multipart/form-data; boundary=TheBoundary';
 SET OutputRoot.HTTPRequestHeader.Accept = '*/*';
 CREATE LASTCHILD OF OutputRoot DOMAIN('MIME');
 CREATE LASTCHILD OF OutputRoot.MIME TYPE Name NAME 'Parts';
 CREATE LASTCHILD OF OutputRoot.MIME.Parts TYPE Name NAME 'Part';
 DECLARE P1 REFERENCE TO OutputRoot.MIME.Parts.Part;
 CREATE FIELD P1."Content-Type" TYPE NameValue VALUE 'application/xml';
 CREATE FIELD P1."Content-Disposition" TYPE NameValue VALUE 'form-data; name="REQUEST"';
 CREATE LASTCHILD OF P1 TYPE Name NAME 'Data';
 CREATE LASTCHILD OF P1.Data DOMAIN('BLOB') PARSE(CONTENT);
 
 |  And here is what I captured with Wireshark:
 
 
   
	| Code: |  
	| POST /services/KMS/response.cfm HTTP/1.1
 Content-Length: 614
 Accept: */*
 Content-Type: multipart/form-data; boundary=TheBoundary
 Host: secure.intrum.ch
 SOAPAction: ""
 Connection: Keep-Alive
 
 
 --TheBoundary
 Content-Type: application/xml
 Content-Disposition: form-data; name="REQUEST"
 
 <n:request xmlns:n="http://www.intrum.ch/schema">
 ...
 
 |  There are 2 empty lines between the last HTTP header and the first boundary. But the target server (secure.intrum.ch) expects exactly 1 empty line.
 |  time for a PMR then.
 |  | 
		
		  | Back to top |  | 
		
		  |  | 
		
		  |  |