Recent

Author Topic: Upload multipart POST request with Synapse does not work expected way.[SOLVED]  (Read 619 times)

OH1KH

  • Jr. Member
  • **
  • Posts: 80
I have a problem that I can not resolve. I need to send a mutipart POST request to server but it rejects my tries with Freepascal.
Using command terminal and curl the server accepts upload without problems.


If I send with curl using script:
Code: Bash  [Select][+][-]
  1. #!/bin/bash
  2.  
  3. API='api'
  4. PASS='pass'
  5. CALL='oh1kh'
  6. FILE='ex.adi'
  7. EMAIL='oh1kh@oh1kh.fi'
  8.  
  9. curl -v -i -X POST \
  10.     -F file=@${FILE} \
  11.     -F email=${EMAIL} \
  12.     -F callsign=${CALL} \
  13.     -F password=${PASS} \
  14.     -F api=${API} \
  15.     https://httpbin.org/anything
  16.  

Result is:
Code: Text  [Select][+][-]
  1. {
  2.   "args": {},
  3.   "data": "",
  4.   "files": {
  5.     "file": "<QSO_DATE:8>20260203<TIME_ON:4>0830<CALL:5>OH1KJ<BAND:3>40M<MODE:2>CW<FREQ:5>7.025<TIME_OFF:4>0830<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>\n<QSO_DATE:8>20260203<TIME_ON:4>0830<CALL:5>OH1KJ<BAND:3>30M<MODE:2>CW<FREQ:4>10.1<TIME_OFF:4>0830<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>\n<QSO_DATE:8>20260203<TIME_ON:4>0831<CALL:5>OH1KJ<BAND:3>20M<MODE:2>CW<FREQ:2>14<TIME_OFF:4>0831<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>\n"
  6.   },
  7.   "form": {
  8.     "api": "api",
  9.     "callsign": "oh1kh",
  10.     "email": "oh1kh@oh1kh.fi",
  11.     "password": "pass"
  12.   },
  13.   "headers": {
  14.     "Accept": "*/*",
  15.     "Content-Length": "1419",
  16.     "Content-Type": "multipart/form-data; boundary=------------------------191zKPATSeNPAJLX3oWkyt",
  17.     "Host": "httpbin.org",
  18.     "User-Agent": "curl/8.11.1",
  19.     "X-Amzn-Trace-Id": "Root=1-69845c03-16584d767851ee66237add89"
  20.   },
  21.   "json": null,
  22.   "method": "POST",
  23.   "origin": "84.231.202.222",
  24.   "url": "https://httpbin.org/anything"
  25. }
  26.  


And this works. File key and contents are placed in "files:{ }" part of response.
Then I use Synapse/FPC to do the same, but result from httpbin.org is not similar.

data:TStringList has the information I push to upload function :
Code: Text  [Select][+][-]
  1. file=/tmp/ClubStream.txt
  2. email=oh1kh@oh1kh.fi
  3. password=password
  4. callsign=oh1kh
  5. api=api
  6.  

And the result from httpbin.org for this is:
Code: Text  [Select][+][-]
  1. {
  2.   "args": {},
  3.   "data": "",
  4.   "files": {},
  5.   "form": {
  6.     "api": "api",
  7.     "callsign": "oh1kh",
  8.     "email": "oh1kh@oh1kh.fi",
  9.     "file": "<QSO_DATE:8>20260203<TIME_ON:4>0830<CALL:5>OH1KJ<BAND:3>40M<MODE:2>CW<FREQ:5>7.025<TIME_OFF:4>0830<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>\n<QSO_DATE:8>20260203<TIME_ON:4>0830<CALL:5>OH1KJ<BAND:3>30M<MODE:2>CW<FREQ:4>10.1<TIME_OFF:4>0830<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>\n<QSO_DATE:8>20260203<TIME_ON:4>0831<CALL:5>OH1KJ<BAND:3>20M<MODE:2>CW<FREQ:2>14<TIME_OFF:4>0831<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT",
  10.     "password": "password"
  11.   },
  12.   "headers": {
  13.     "Content-Length": "1441",
  14.     "Content-Type": "multipart/form-data; boundary=099617E5_Synapse_boundary",
  15.     "Host": "httpbin.org",
  16.     "User-Agent": "Mozilla/4.0 (X11; Linux x86_64)",
  17.     "X-Amzn-Trace-Id": "Root=1-698459c2-585a677e3a87373141193483"
  18.   },
  19.   "json": null,
  20.   "method": "POST",
  21.   "origin": "84.231.202.222",
  22.   "url": "https://httpbin.org/anything"
  23. }
  24.  

The function used for upload (part that produces key parts and upload):
Code: Pascal  [Select][+][-]
  1.  
  2.     for i:=0 to data.Count-1 do
  3.     begin
  4.       Key   := copy(data.Strings[i],1,Pos('=',data.Strings[i])-1);
  5.       Value := copy(data.Strings[i],Pos('=',data.Strings[i])+1,Length(data.Strings[i])-Pos('=',data.Strings[i])+1);
  6.  
  7.       if Key='file' then
  8.         begin
  9.           WriteStrToStream(HTTP.Document,
  10.             '--' + Bound + CRLF +
  11.             'Content-Disposition: form-data; name=' + AnsiQuotedStr(Key, '"') + CRLF +
  12.             ' filename=' + AnsiQuotedStr(Value, '"')  + CRLF+
  13.             'Content-Type: application/octet-string' + CRLF +
  14.             CRLF);
  15.           F:=TMemoryStream.Create;
  16.           F.LoadFromFile(Value);
  17.           HTTP.Document.CopyFrom(F, 0);
  18.           F.Destroy;
  19.           WriteStrToStream(HTTP.Document,CRLF);
  20.         end
  21.         else
  22.          begin
  23.           WriteStrToStream(HTTP.Document,
  24.             '--' + Bound + CRLF +
  25.             'Content-Disposition: form-data; name=' + AnsiQuotedStr(Key, '"') + CRLF +
  26.             'Content-Type: text/plain' + CRLF +
  27.             CRLF);
  28.           WriteStrToStream(HTTP.Document, Value);
  29.           WriteStrToStream(HTTP.Document,CRLF);
  30.          end;
  31.  
  32.     end;
  33.     WriteStrToStream(HTTP.Document,'--' + Bound + '--' + CRLF);
  34.  
  35.     HTTP.MimeType := 'multipart/form-data; boundary=' + Bound;
  36.     if HTTP.HTTPMethod('POST',Url) then
  37.  

If I replace "WriteStrToStream(HTTP.Document," with "write("  to see what function is doing, 
because I did not found the way to debug print contents of HTTP.Document, it looks like this:
(And note: the file contents are not shown in this debug)

Code: Text  [Select][+][-]
  1. --112ED948_Synapse_boundary
  2. Content-Disposition: form-data; name="file"
  3.  filename="/tmp/ClubStream.txt"
  4. Content-Type: application/octet-string
  5.  
  6.  
  7. --112ED948_Synapse_boundary
  8. Content-Disposition: form-data; name="email"
  9. Content-Type: text/plain
  10.  
  11. oh1kh@oh1kh.fi
  12. --112ED948_Synapse_boundary
  13. Content-Disposition: form-data; name="password"
  14. Content-Type: text/plain
  15.  
  16. password
  17. --112ED948_Synapse_boundary
  18. Content-Disposition: form-data; name="callsign"
  19. Content-Type: text/plain
  20.  
  21. oh1kh
  22. --112ED948_Synapse_boundary
  23. Content-Disposition: form-data; name="api"
  24. Content-Type: text/plain
  25.  
  26. api
  27. --112ED948_Synapse_boundary--
  28.  


It looks very good for me. I am blind for finding the error from this code!
I have tried few days with Googling and testing to resolve why the content of file goes to "form" part and not to "files" part. That seems to be the reason the server rejects my upload.

Is there anyone who could help and tell what I am doing wrong, please.
« Last Edit: February 06, 2026, 11:53:50 am by OH1KH »
--
Saku

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #1 on: February 05, 2026, 03:49:58 pm »
The problem is a missing ; in your header for the file.

Code: [Select]
Content-Disposition: form-data; name="file"
 filename="/tmp/ClubStream.txt"
Content-Type: application/octet-string
It should have a ; after name="file" because the filename on the second line needs to be 'separated' as next field.

With the separation between form-data and name= you did this correctly.


OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #2 on: February 05, 2026, 04:23:49 pm »
Thanks!
Yes, that is corrected and I made some other rewriting too.

I found better way to monitor and compare to curl output:
Code: Bash  [Select][+][-]
  1. while true; do printf '' | nc -l localhost 60006; done

That way I was able to make the content similar to curl.
But it does not work!!

Reason can be seen from previous message if you look at the file data.
One sent with Synaptic ends:
Code: Text  [Select][+][-]
  1. N<LOTW_QSL_RCVD:1>N<CONT",
One sent with curl ends:
Code: Text  [Select][+][-]
  1. N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>\n"

And that is the proper one.
For some reason Fpc/Synaptic cuts the file from end.

This is the current code
Code: Pascal  [Select][+][-]
  1.     for i:=0 to data.Count-1 do
  2.     begin
  3.  
  4.       Key   := ExtractWord(1,data.Strings[i],['=']);
  5.       Value := ExtractWord(2,data.Strings[i],['=']);
  6.  
  7.       if Key='file' then
  8.         begin
  9.           WriteStrToStream(HTTP.Document, CRLF +
  10.             'Content-Disposition: form-data; name=' + AnsiQuotedStr(Key, '"') + ';' +
  11.             ' filename=' + AnsiQuotedStr(Value, '"')  + CRLF+
  12.             'Content-Type: application/octet-stream' +  CRLF + CRLF);
  13.           F:=TMemoryStream.Create;
  14.           F.LoadFromFile(Value);
  15.           HTTP.Document.CopyFrom(F, 0);
  16.           F.Destroy;
  17.           WriteStrToStream(HTTP.Document,CRLF +CRLF + '--------------------------' +Bound);
  18.         end
  19.         else
  20.          begin
  21.           WriteStrToStream(HTTP.Document, CRLF +
  22.             'Content-Disposition: form-data; name=' + AnsiQuotedStr(Key, '"') + CRLF + CRLF);
  23.           WriteStrToStream(HTTP.Document, Value + CRLF);
  24.           WriteStrToStream(HTTP.Document, '--------------------------' + Bound );
  25.          end;
  26.  
  27.     end;
  28.     WriteStrToStream(HTTP.Document, '--' + CRLF);
  29.  
  30.     HTTP.MimeType := 'multipart/form-data; boundary=' + '--------------------------' + Bound;
  31.     if HTTP.HTTPMethod('POST',Url) then                                                      
  32.  

Instead of F :TMemoryStream I have also tested with F: TFileStream but results are same.
Adding extra CRLF to end of the file does not help. Same with LineEnding.

I have also tried HTTP.Document.CopyFrom(F, F.Size); instead of HTTP.Document.CopyFrom(F, 0);
But that does not make any change.

No more ideas....

Lazarus 4.4 (rev Unknown) FPC 3.2.2 x86_64-linux-gtk2
--
Saku

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #3 on: February 05, 2026, 04:44:13 pm »
I found better way to monitor and compare to curl output:
Code: Bash  [Select][+][-]
  1. while true; do printf '' | nc -l localhost 60006; done
Using 3 v parameters with curl (so curl -vvv) will also give you exactly what curl is sending.

No more ideas....
Feels like a flushing problem. But I've never had to do that.

But... you have this after writing the file content:
Code: [Select]
WriteStrToStream(HTTP.Document,CRLF +CRLF + '--------------------------' +Bound);Why are there two CRLF's ? Normally 1 is sufficient.

And this after everything:
Code: [Select]
WriteStrToStream(HTTP.Document, '--' + CRLF);Aren't you missing the CRLF in front of this one?

Edit: Ha, you have it after writing the field.

BTW.   F.Destroy; ??? Why not F.Free? (preferably with a try/finally around create/free.)
« Last Edit: February 05, 2026, 04:48:40 pm by rvk »

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #4 on: February 05, 2026, 04:51:51 pm »
BTW. You can also use TMimeMess and TMimePart from Synapse to do a lot of this automatically.

OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #5 on: February 05, 2026, 04:55:39 pm »
Hi !

---------------- was "just to make output similar as curl"

As the file is text I replaced a part of code like:

Code: Pascal  [Select][+][-]
  1.       if Key='file' then
  2.         begin
  3.           WriteStrToStream(HTTP.Document, CRLF +
  4.             'Content-Disposition: form-data; name=' + AnsiQuotedStr(Key, '"') + ';' +
  5.             ' filename=' + AnsiQuotedStr(Value, '"')  + CRLF+
  6.             'Content-Type: application/octet-stream' +  CRLF + CRLF);
  7.           {
  8.           F:=TMemoryStream.Create;
  9.           F.LoadFromFile(Value);
  10.           HTTP.Document.CopyFrom(F, F.Size);
  11.           F.Destroy;
  12.           }
  13.           AssignFile(FT,Value);
  14.           Reset(FT);
  15.           While not Eof(FT) do
  16.              Begin
  17.               ReadLn(FT,s);
  18.               WriteStrToStream(HTTP.Document,s);
  19.              end;
  20.  
  21.           WriteStrToStream(HTTP.Document,CRLF +CRLF + '--------------------------' +Bound);
  22.  

But the result is same!

When looking at result it is 511 bytes (ASCII text, one byte / char).
Could it be that Synaptic THTTPSend has some kind of  limitation as 512 bytes  ? (that could do 255 chars when using two byte / char)
--
Saku

OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #6 on: February 05, 2026, 05:01:19 pm »
On the other hand, elsewhere in same program is similar part of code:

Code: Pascal  [Select][+][-]
  1.  m.LoadFromFile(FileName);
  2.     http.Sock.OnStatus := @SockCallBack;
  3.     s := '--' + Bound + CRLF;
  4.     s := s + 'content-disposition: form-data; name="upfile";';
  5.     s := s + ' filename="' + FileName +'"' + CRLF;
  6.     s := s + 'Content-Type: Application/octet-string' + CRLF + CRLF;
  7.     WriteStrToStream(http.Document, s);
  8.     http.Document.CopyFrom(m, 0);
  9.     s := CRLF + '--' + Bound + '--' + CRLF;
  10.     WriteStrToStream(http.Document, s);
  11.     http.MimeType := 'multipart/form-data; boundary=' + Bound;
  12.                                                                
  13.  

That is, so far I can see, just similar case.
And I have used it with lot more longer files without problems.
--
Saku

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #7 on: February 05, 2026, 05:02:05 pm »
When looking at result it is 511 bytes (ASCII text, one byte / char).
Could it be that Synaptic THTTPSend has some kind of  limitation as 512 bytes  ? (that could do 255 chars when using two byte / char)
The WriteStrToStream for after the TTP.Document.CopyFrom (and WriteStrToStream in your while/eof) is done correctly... so there is no such limitation. in HTTP.Document. Otherwise the rest would also be cut off.

You could create a small testproject to show the problem.
Usually when doing that, you end up finding the problem yourself (and otherwise you can post it here).

OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #8 on: February 05, 2026, 07:13:00 pm »
Interesting point is that adding one line more to file
will cut 4 chrs away from last line.

Every time line is added 4chrs more will be cut from last line (4chrs per every line)
--
Saku

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #9 on: February 05, 2026, 07:36:44 pm »
Interesting point is that adding one line more to file
will cut 4 chrs away from last line.
From what kind of file are you reading?
Are you sure there is no BOM at the beginning of the file?
It would be weird that in that case the last characters are stripped but maybe the stream doesn't handle BOM files correctly.
Plus that BOM for utf-8 is 3 characters.

What if you try a different file?
Or just put something in a string and use WriteStrToStream().
Does it happen then too?

OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #10 on: February 05, 2026, 08:45:25 pm »
OK!

I made a separate test program (unit1.zip)
It works with file file.zip  and the file does not cut when sent to
Code: Bash  [Select][+][-]
  1. clear;while true; do printf '' | nc -l localhost 60006; done
  2.  

Code: Text  [Select][+][-]
  1. RE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  2.  
  3. --463F8555_Synapse_boundary
  4.  
  5.  

Then I transferred a part of unit1.pas to the other program
Code: Pascal  [Select][+][-]
  1.   try
  2.  
  3.  //this loads file before the  data.loop just like unit1.pas do
  4.     F:=TMemoryStream.Create;
  5.     F.LoadFromFile('/tmp/ClubStream.adi');
  6. //----------------------------------------------------------
  7.  
  8.     HTTP.ProxyHost := cqrini.ReadString('Program','Proxy','');
  9.     HTTP.ProxyPort := cqrini.ReadString('Program','Port','');
  10.     HTTP.UserName  := cqrini.ReadString('Program','User','');
  11.     HTTP.Password  := cqrini.ReadString('Program','Passwd','');
  12.  
  13.     WriteStrToStream(HTTP.Document,CRLF + '--' + Bound);
  14.  
  15.     for i:=0 to data.Count-1 do
  16.     begin
  17.  
  18.       Key   := ExtractWord(1,data.Strings[i],['=']);
  19.       Value := ExtractWord(2,data.Strings[i],['=']);
  20.  
  21.       if Key='file' then
  22.         begin
  23. // here is the copied part from unit1.pas
  24.           s := 'content-disposition: form-data; name="' + AnsiQuotedStr(Key, '"')  + '";';
  25.           s := s + ' filename="' + Value +'"' + CRLF;
  26.           s := s + 'Content-Type: Application/octet-string' + CRLF + CRLF;
  27.           WriteStrToStream(HTTP.Document, s);
  28.           HTTP.Document.CopyFrom(F, 0);
  29.           s := CRLF + '--' + Bound;
  30.           WriteStrToStream(HTTP.Document, s);
  31. //copy ends
  32.           {
  33.           WriteStrToStream(HTTP.Document, CRLF +
  34.             'Content-Disposition: form-data; name=' + AnsiQuotedStr(Key, '"') + ';' +
  35.             ' filename=' + AnsiQuotedStr(Value, '"')  + CRLF+
  36.             'Content-Type: application/octet-stream' +  CRLF + CRLF);
  37.  
  38.  
  39.           F.LoadFromFile(Value);
  40.           HTTP.Document.CopyFrom(F, 0);
  41.  
  42.           WriteStrToStream(HTTP.Document,CRLF +CRLF + '--' +Bound);
  43.           }
  44.         end
  45.         else    
  46.  


And quess what?
It cuts the last line like it has always done
Code: Text  [Select][+][-]
  1. RE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LO
  2. --5DA4436C_Synapse_boundary--
  3.  

Now it is bedtime.
I have spent whole day with this without any progress.
--
Saku

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #11 on: February 05, 2026, 10:44:16 pm »
I did a quick test. For me it seems to work fine. At least on Windows.
(although there are 2 blank lines after the header, it should be 1 but that's another issue which will crop up when sending to a real server)

Code: Bash  [Select][+][-]
  1. pi@space01:~ $ nc -l 192.168.2.21 60006
  2. POST / HTTP/1.0
  3. Host: 192.168.2.21:60006
  4. Keep-Alive: 300
  5. Connection: keep-alive
  6. User-Agent: Mozilla/4.0 (compatible; Synapse)
  7. Content-Type: multipart/form-data; boundary=6F64822D_Synapse_boundary
  8. Content-Length: 2224
  9. Header: content
  10.  
  11.  
  12. --6F64822D_Synapse_boundary
  13. Content-Disposition: form-data; name="api"
  14. Content-Type: text/plain
  15.  
  16. API
  17. --6F64822D_Synapse_boundary
  18. content-disposition: form-data; name="file"; filename="c:\temp\ClubStream.adi"
  19. Content-Type: Application/octet-string
  20.  
  21. <QSO_DATE:8>20260205<TIME_ON:4>1752<CALL:5>OH1KJ<BAND:3>40M<MODE:2>CW<FREQ:5>7.025<TIME_OFF:4>1752<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  22. <QSO_DATE:8>20260205<TIME_ON:4>1806<CALL:5>OH1KJ<BAND:3>20M<MODE:3>SSB<FREQ:4>14.2<TIME_OFF:4>1806<RST_SENT:2>59<RST_RCVD:2>59<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  23. <QSO_DATE:8>20260205<TIME_ON:4>1807<CALL:5>OH1KJ<BAND:3>80M<MODE:2>CW<FREQ:3>3.5<TIME_OFF:4>1807<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  24. <QSO_DATE:8>20260205<TIME_ON:4>1807<CALL:5>OH1KJ<BAND:3>10M<MODE:2>CW<FREQ:2>28<TIME_OFF:4>1807<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  25. <QSO_DATE:8>20260205<TIME_ON:4>1807<CALL:5>OH1KJ<BAND:3>17M<MODE:2>CW<FREQ:4>18.1<TIME_OFF:4>1807<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  26. <QSO_DATE:8>20260205<TIME_ON:4>1808<CALL:5>OH1KJ<BAND:3>17M<MODE:3>FT8<FREQ:4>18.1<TIME_OFF:4>1808<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  27. <QSO_DATE:8>20260205<TIME_ON:4>1809<CALL:5>OH1KJ<BAND:3>20M<MODE:3>FT8<FREQ:2>14<TIME_OFF:4>1809<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
  28.  
  29. --6F64822D_Synapse_boundary
  30. Content-Disposition: form-data; name="api"
  31. Content-Type: text/plain
  32.  
  33. API
  34.  
  35. --6F64822D_Synapse_boundary--
  36.  

Also with a test with just reading it in a TStringList just before sending the data was correct.
You can check on your end if the data you are about to send is ok.

Code: Pascal  [Select][+][-]
  1. var
  2.   Dummy: TStringList;
  3. //...
  4.     Dummy := TStringList.Create;
  5.     try
  6.       HTTP.Document.Position := 0;
  7.       Dummy.LoadFromStream(HTTP.Document);
  8.       ShowMessage(Dummy.Text);
  9.     finally
  10.       Dummy.Free;
  11.     end;
  12.     Result := HTTP.HTTPMethod('POST', URL);


Code: [Select]
[Window Title]
project1

[Content]

--6F64822D_Synapse_boundary
Content-Disposition: form-data; name="api"
Content-Type: text/plain

API
--6F64822D_Synapse_boundary
content-disposition: form-data; name="file"; filename="c:\temp\ClubStream.adi"
Content-Type: Application/octet-string

<QSO_DATE:8>20260205<TIME_ON:4>1752<CALL:5>OH1KJ<BAND:3>40M<MODE:2>CW<FREQ:5>7.025<TIME_OFF:4>1752<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
<QSO_DATE:8>20260205<TIME_ON:4>1806<CALL:5>OH1KJ<BAND:3>20M<MODE:3>SSB<FREQ:4>14.2<TIME_OFF:4>1806<RST_SENT:2>59<RST_RCVD:2>59<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
<QSO_DATE:8>20260205<TIME_ON:4>1807<CALL:5>OH1KJ<BAND:3>80M<MODE:2>CW<FREQ:3>3.5<TIME_OFF:4>1807<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
<QSO_DATE:8>20260205<TIME_ON:4>1807<CALL:5>OH1KJ<BAND:3>10M<MODE:2>CW<FREQ:2>28<TIME_OFF:4>1807<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
<QSO_DATE:8>20260205<TIME_ON:4>1807<CALL:5>OH1KJ<BAND:3>17M<MODE:2>CW<FREQ:4>18.1<TIME_OFF:4>1807<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
<QSO_DATE:8>20260205<TIME_ON:4>1808<CALL:5>OH1KJ<BAND:3>17M<MODE:3>FT8<FREQ:4>18.1<TIME_OFF:4>1808<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>
<QSO_DATE:8>20260205<TIME_ON:4>1809<CALL:5>OH1KJ<BAND:3>20M<MODE:3>FT8<FREQ:2>14<TIME_OFF:4>1809<RST_SENT:3>599<RST_RCVD:3>599<QSL_SENT:1>N<QSL_RCVD:1>N<MY_GRIDSQUARE:6>KP01tn<TX_PWR:3>100<ITUZ:2>18<CQZ:2>15<LOTW_QSL_SENT:1>N<LOTW_QSL_RCVD:1>N<CONT:2>EU<EOR>

--6F64822D_Synapse_boundary
Content-Disposition: form-data; name="api"
Content-Type: text/plain

API

--6F64822D_Synapse_boundary--

[OK]

OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #12 on: February 06, 2026, 10:50:16 am »
Yes the test works fine also here.

Thanks for debug code. I added that and it looks same as the result at localhost:60006
So the synapse does not change anything, the last line is broken already in HTTP.Document

I made another test program taking whole function from original program and added just variables needed for running the function.

Now the result is broken, just like in original program.

Please test this one, you should now see it in windows, too. I think...
--
Saku

rvk

  • Hero Member
  • *****
  • Posts: 6940
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #13 on: February 06, 2026, 11:03:51 am »
Please test this one, you should now see it in windows, too. I think...
You do know that the file you gave in this zip is cut off too??


OH1KH

  • Jr. Member
  • **
  • Posts: 80
Re: Upload multipart POST request with Synapse does not work expected way.
« Reply #14 on: February 06, 2026, 11:04:46 am »
Hi!
There is error in last test program.
In function  the F.LoadFromFile appears twice.

There should only be F.LoadFromFile(Value); and not the one where filename exist.
How ever removing that extra loadFromFile does not effect the result.

It is still broken.
18<CQZ:2>15<LOTW_QSL_SENT:1>N<LO

--463F8555_Synapse_boundary--

--
Saku

 

TinyPortal © 2005-2018