How to rebuild Indy 10 which comes with Delphi XE2? - delphi

In Delphi XE2 I'm using Indy 10. I made a small change to one of the units IdHTTPWebBrokerBridge and to take effect, I need to re-build indy. I can't find this in any search, I keep getting results for installing it from scratch - but nothing about re-building what comes with Delphi.
How do I re-build Indy 10?

IdHTTPWebBrokerBridge.pas is included in the Indy release, but it is not actually used by Indy itself. It is used internally by Embarcadero when using Indy inside of DataSnap, and thus is not compiled into Indy itself in any way. So there is no need to recompile Indy itself (unless you want to upgrade it, but be sure to take note of the warnings in the install instructions). You can submit a bug fix to Indy's developers so it is included in future releases, but that will not address your problem in XE2 since DataSnap cannot be recompiled. But if you are using static linking in your project, you could try simply adding the modified IdHTTPWebBrokerBridge.pas file directly into your app.

Related

Delphis ZLib Interface not initialized

When working with Delphi XE2 I have the following problem:
When I try to compress a response from IdHTTPServer that should be sent to a client, I am not able to do this. The IdCompressorZLib.CompressHTTPDeflate or IdCompressorZLib.CompressStream functions always stop with the error ZLib Error (-6). This means that Delphi does not find a library with the expected version. ZLIB_VERSION is set to 1.2.5 in my environment.
My question is what I have to do to get it working?
OK, I've fired up XE2 and can reproduce what you report. It would seem that Embarcadero have blundered when building Indy for XE2. There is a mismatch between the zlib version of the linked objects, and the zlib version that is passed to the zlib initialization functions. Nothing you can do with what they shipped can work around that flaw.
Your options, as I see it:
Fix the version of Indy that was supplied with XE2. This will involve modifying the Indy source files and fixing the version mismatch. And then linking the modified Indy units to your application. Not impossible, but possibly a little awkward.
Use the latest version of Indy, obtained from the Indy project repo. You'll then have the latest and greatest Indy.
Use a different zlib library. For example the zlib library that ships with Delphi is known to work. I know you had trouble with this when I suggested it in a comment, but I for one have used it without trouble.
Use a different version of Delphi. Not a great option, but I'm including it for completeness.

Indy10 SSL Failure First Time Connecting

I'm having a very similar problem to the one posed in this problem (having to connect twice on first load because of a "problem" loading the SSL dlls), except I'm pretty sure I'm using the latest version of Indy so the solutions proposed there do not solve my problem.
I am using Delphi7, and I selected not to install Indy from the Delphi7 installer since that version is incredibly obsolute. I did install Indy9 from latest SVN source before downloading and installing Indy10 (from SVN source), but I reconfigured the IDE and project settings to use the new Indy10 components/paths instead of Indy9. Clearly the project is using Indy10 to build as there are quite a number of methods I had to change to match all the Indy10 signatures to even compile.
My SVN repository for Indy10 is checked out from: https://svn.atozed.com:444/svn/Indy10/trunk/Lib and shows last commit revision of 4972, about 2 weeks ago--this does not look like "some really old version of Indy10".
I have downloaded OpenSSL 1.0.1e for Win32 from the binary build at http://opendec.wordpress.com/ (the location recommended from that other stackoverflow question I mentioned earlier) and put it in the same folder as my built .exe
Here's the code I'm using right now to open an SSL connection:
try
POP.Connect(Server,Port,Protocol,UserName,Password,TimeOut);
Except
on e : EIdOSSLCouldNotLoadSSLLibrary do
begin
ShowMessage('Failed to load: ' + WhichFailedToLoad());
POP.Connect(Server,Port,Protocol,UserName,Password,TimeOut);
end;
end;
BUT... this is causing an EIdOSSLCouldNotLoadSSLLibrary exception, and adding WhichFailedToLoad shows the exact same list of components, that would suggest it's expecting the "indy specific" version of OpenSSL:
But Wait a minute... Remy answered in the linked question that "Indy 10 was updated to no longer require the custom-built DLLs anymore. It now uses the standardized OpenSSL DLLs as-is." So why would it be complaining that it needs Indy specific functions?
How could I troubleshoot why it's failing to connect the first time/saying it needs functions I understand not to be needed anymore? Is my expectation that it should not be looking for indy specific functions incorrect?
My guess, confirmed in the comments to the question, is that your compiler is finding Indy 9 and not Indy 10 to build your project.
The things can go ever worst, because your IDE may be using one version in design time and the compiler may be using a different version. In fact the IDE and the compiler are different parts of the chain and you can broke the original synchronization between both. Because that, I'll explain both cases and, as I explain later, you have to change both.
The IDE and design time
Design time packages are loaded by the IDE to create objects while you're working, show you the properties of that objects in the object inspector, create the form DFM files and get the method firm to be used when you resort to the IDE to generate pascal code to respond to events.
For the IDE you can check what version you're using in design time by right clicking on any Indy component, as shown in the image.
To change the version you're using in design time, go to Component\Install packages and check the correct version in the list. You cannot load Indy 9 and Indy 10 at the same time.
The compiler and run time
The compiler uses the Library path to look for the units you use in your project that are not part of the project itself, and compile that code along with yours to produce the executable.
To check what Indy version was linked into your executable, you can resort to the Version property present on all INdy components, for example:
ShowMessage('Indy version: ' + MyIndyComponent.Version);
To change what the compiler finds first, you have to change the paths. You can do it from inside the IDE. In modern Delphi you could check in Tools\Options\Delphi options\Library\Library path\ and Project\Options\Delphi compiler\Search path\ (I just don't remember where the options were in D7).
The Indy 9/10 case
Indy introduced interface breaking changes that makes impossible to compile a project written for Indy 9 using Indy 10. In fact, the administrators of the project doesn't wait for a major release to break the code compatibility and you expect to be forced to adjust your code when you upgrade to any minor version if it happens to have a different interface.
Because of that, you're definitely using Indy 9 in both, at compile/run time and IDE/design time, so you have to adjust both in your environment. After that, be prepared to re-write part of your code to adjust. Once you understand what changed and learn how to adapt, the change is fairly simple. The details are out of the scope of this answer, but there's enough information in the Internet for you to figure out how to do it.

Is it possible to recompile the DataSnap packages in Delphi XE with a new/different version of Indy?

Okay -- we have an interesting problem.
Some background:
Our main application uses Indy 10. However, we take the Indy 10
source and fix bugs in it, recompile, and install our own set of Indy
components.
We are migrating to Delphi XE and want to start using DataSnap.
DataSnap requires the "official, shipping" version of Indy which is
incompatible with our customized version of Indy.
Our DataSnap servers will be separate applications, but since we
have our own Indy installed in the IDE, we can't "cross the streams".
Okay, therefore, we are unable to use Delphi XE's DataSnap out of the
box because of this compatibility issue.
So my questions is this:
Is it possible to recompile the DataSnap packages in Delphi XE with a new/different version of Indy?
Your thoughts gratefully accepted.
The common belief is No, that's not possible due to not all sources being provided by Embarcadero and some of these sources are reliant on the build of Indy as shipped. (Which is extremely frustrating to end users as the version of Indy that ships with Delphi is out of date relatively quickly and sometimes the version selected at the time is not necessarily a very good one.)
See related SO question:
Is it possible to use Indy 10.5.8.0 in Delphi XE and DataSnap?
Also see the Indy project page:
http://www.indyproject.org/Sockets/Docs/indy10Installation.de.aspx
which states:
Note: In D/CB/RAD 2009+, DataSnap uses
Indy 10 internally. Installing a new
version of Indy will render DataSnap
unusable, as it will not be able to
load the Indy packages anymore.
DataSnap is compiled against the Indy
packages that ship with the IDE, and
DataSnap cannot be recompiled by end
users. If you need to use DataSnap,
then you will need to maintain the
original Indy 10 packages for use in
DataSnap projects.
It's been said that the next version should hopefully allow for easier updates of Indy.
If all DataSnap source is included, is of course possible using some kind of PE executable analisys program to detect which classes and units are used in BPL (as BPLs are just customized DLLs). An very easy one to use is provided with GExperts.
In BPLs, the exports list lines from GExperts\PE Information have an format like #xp$#[nn][UnitName]#[TypeName] (for types) and #[UnitName]{#[Type>]}#[Unit global element like procedures or variables] (for the rest).
You can save that list to a file and GREP to get an list of Units used on a BPL.
Real Examples (vcl140.bpl):
#$xp$11Forms#TForm
#Appevnts#TCustomApplicationEvents#Activate
#Clipbrd#Clipboard

Why is Indy 9 included with Delphi 2009? Is it safe to use?

Why is there an Indy9 folder (The default install folder of C:\Program Files\CodeGear\RAD Studio\6.0\source\Indy contains subdirectories for "Indy9" and "Indy10") Why are both versions installed? What is using Indy9? I didn't think it had been updated for 2009...is Indy9 now safe to use with Delphi 2009?
There is an opened QC report about this, but it's only visible to QC sysops.
The status of "open" typically means that it's accepted that this is a bug, rather than by design.
Remy Lebeau - one of the Indy developers - said this:
The 2009 installer does ship with the
Indy 9 source code, but it is not
selectable during install. There is a
note in the documentation that Indy 9
can be installed manually if needed.
But keep in mind that Indy 9 has not
been updated to actually support 2009.
At the moment, I am not sure if it
will be.
There are some changes in Indy 9 (from the 2007 version) so that it will compile under Delphi 2009 (a few String to AnsiString changes), but based on my tests it doesn't work. It tries to, but does not connect. If you want I can give you the changes that have been added for Unicode support, but I don't believe they are sufficient.
I can't really answer why. I could conjecture a few reasons, but I do not have any insider information.
Is it safe to use? YMMV. There is a lot to Indy, so there may be some parts that work fine for your project. Even a simple test with the TIdTCPClient resulted in Socket Error #11004 every time. Same for TIdHTTP. It seems like I tried the MD5 previously and it just got garbage, but I am not sure on that one.
Answer: It was included by mistake (assumption), and it is not safe to use (based on limited tests).
That is unfortunate, because Indy 10 has issues too, and I have some legacy apps that use Indy 9.
Indy9 is there for compatibility. There were some breaking changes in Indy10 (your code that was written against Indy9 may not compile under Indy10) so you have the option of continuing to use Indy9 (I think the installer prompts and asks what Indy you want to use - at least it did with D2007).
Update: Okay a few people have correctly commented that Indy9 wont compile with D2009 (because of the new Unicode support), so I guess I don't know why it is there.
My guess, it was in the source tree, and was automatically included by installer.
Keep in mind that the source files are not used unless you tell Delphi to recompile them.
If you do not have the Enterprise version you will not even have these folders.

What is the proper way to update Delphi 2009's default installation of Indy 10?

Since Indy is now built-into the install process of Delphi 2009... is there a proper way to 'remove' it so it can be upgraded to the latest from the SVN repo? There isn't an automated option to remove it as far as I'm aware.
The dcu files for Indy are stored separately from the other Delphi units. To stop using them, simply remove that directory from the search path, library path, etc., and remove the source files from the browse path.
You can remove the design-time packages the same as any other design-time packages. Remove them from the IDE configuration, and then delete the bpl and dcp files. (If you just delete the files, you may get errors when you next start the IDE since it won't find the expected files.)
Once the Indy components no longer appear on the Tool Palette, the packages no longer appear on the package list, and compiling a project that references Indy units fails with a "can't find used unit" error, you're ready to start installing the latest version.
As Rob already said: Just remove the direcories from Delphi's configuration. An additional step is required though: After each update, make sure they have not been added again! Some of the Delphi 2007 updates apparently did that and I missed it for quite a while until I stumbled upon a bug that I already thought fixed.
I didn't use Delphi 2009, but in older versions of Delphi the installation of Indy components was optional. So you could try launching the setup for Delphi 2009 and see if there is an option to "Add/Remove features" or something similar and use it to remove Indy.
Also, you can customize which packages should be loaded in a project, so you can simply deselect the Indy 10 one and add the one from SVN on a per-project basis (you can also configure the default configuration for projects).
PS. Indy rocks! :-)

Resources