The new function is a simple one-way transaction whereby the client application can upload a file, in the form of a soap attachment, to a web remote server, so that it can be further processed by that server.
My application already uses Indy components for other web functionality, so I suppose that the leanest solution would be to use IndySoap for this additional feature. However it seems to me that IndySoap is a) not too well documented, b) few examples are to be found, and c) it might not yet be very stable.
The alternative is to use an HttpRio object, which is better documented. However, I guess that having both Indy and HttpRio in the same application a) will cause code bloat, and b) might cause unforeseen ghost interactions between the two code stacks.
Does anyone have any recommendations?
Regards,
AndrewFG
Well if I were you (and I was in your situation about 2-3 months ago) I would use indysoap. As to your concerns about it:
a) I found it adequately documented, not great but good enough. But I got all the info I needed from the Indy newsgroup where Grahame Grieves (the programmer of indysoap) answerred my questions within 24 hrs and provided solutions for the problems
b) probably true, but see a.
c) we have been using it (for both server and clients) for two weeks after its 1.0 release and I have yet to find a bug. Furthermore Indysoap's performance is way faster. And I have found indysoap a lot easier to change to your specific needs (the main reason for us to choose Indysoap even though we didn't use Indy before). We started out using HttpRio but once we found Indysoap and started using it we never looked back. (and no, I'm not part of the indysoap development team ;) )
I certainly wouldn't recommend using the two together.
> I want to add some simple soap client functionality to an existing
> application, and am looking for advice about the best components to
> use.
>
> The new function is a simple one-way transaction whereby the client
> application can upload a file, in the form of a soap attachment, to a
> web remote server, so that it can be further processed by that server.
>
> My application already uses Indy components for other web
> functionality, so I suppose that the leanest solution would be to use
> IndySoap for this additional feature. However it seems to me that
> IndySoap is a) not too well documented, b) few examples are to be
> found, and c) it might not yet be very stable.
a. I wrote the doco, so I won't comment about that.
But contributions are welcome
b. agree, but contributions are welcome
c. I see it as stable. we have extensive code in production
>
> The alternative is to use an HttpRio object, which is better
> documented. However, I guess that having both Indy and HttpRio in
> the same application a) will cause code bloat, and b) might cause
> unforeseen ghost interactions between the two code stacks.
a. No, not really. Either soap library will cause significant
code bloat, but the httprio stack and the indysoap stack are
the least significant part of this. Note that you can use
indysoap with wininet not indy, and this is how httprio works
b. not at all
you should make your decision based on the soap functionality.
I'm happy to see that IndySoap has already been recommended by
someone else
Grahame
You can use Indy HttpClient to send the file across to the server (using
multipart/form-data). This will be faster too. Indy already has this
functionality built into.
You might want to check out a tutorial on my web site in the TCP/IP section
that shows you how to do this.
--
Shiv R. Kumar
The Delphi Apostle
http://www.matlus.com
I decided to write my client using Indy, and I now have it completed...
Shiv mentioned using the Indy multipart/form-data object, but I found that to be somewhat off track for the multipart/related functionality that I needed. So I wrote my own new mime multipart descendent of TMemoryStream to assemble the mime parts; then I pass that to the regular TIdHttp.Post(url, stream) method.
Regards,
AndrewFG
"Shiv Kumar" <sh...@erols.com> wrote in message news:3f5a...@newsgroups.borland.com...
I saw your tutorial, but I ended up writing my own code instead -- see below.
Thanks anyway.
Regards,
AndrewFG
----
type
{
TMultiPartMimeStream:
A stream that creates a multi part mime stream
}
TMultiPartMimeStream = class(TMemoryStream)
private
fNextPartStart : Int64;
public
procedure AddPart(aStream : TMemoryStream; aContentID, aContentType : string);
end;
const
soap_Type = 'text/xml';
crlf = #13#10;
dashdash = '--';
mime_boundary = 'yourname:mime-boundary';
mime_type = 'multipart/related';
mime_content_type_header = 'Content-Type: ';
mime_content_type_value = mime_type + '; boundary=' + mime_boundary + '; type=' + soap_type;
mime_main_header = 'MIME Version: 1.0' + crlf + mime_content_type_header + mime_content_type_value + crlf;
mime_main_footer = crlf + dashdash + mime_boundary + dashdash + crlf;
mime_part_header_fmt = crlf + dashdash + mime_boundary + crlf + mime_content_type_header + '%s' + crlf +
'Content-ID: <%s>' + crlf + crlf;
procedure TMultiPartMimeStream.AddPart(aStream : TMemoryStream; aContentID, aContentType : string);
{
Add a mime part to a stream
- aStream contains the data to be added
- aContentID and aContentType contain the content ID and type
Status: FULLY TESTED
}
var
s : string;
begin
// write the main header
if Position = 0 then
begin
s := mime_main_header;
Write(s[1], length(s));
fNextPartStart := Position;
end;
// go to the next part start position
Position := fNextPartStart;
// write the part header
s := Format(mime_part_header_fmt, [aContentType, aContentID]);
Write(s[1], length(s));
// save the payload
aStream.SaveToStream(self);
// save the position for the start of the next part
fNextPartStart := Position;
// always write the footer; if there is a subsequent part, it will overwrite this
s := mime_main_footer;
Write(s[1], length(s));
end;
"Shiv Kumar" <sh...@erols.com> wrote in message news:3f5f5608$1...@newsgroups.borland.com...
Martijn Brinkers