2
votes

I built a DataSnap server with Delphi XE2 that implements TDSHTTPService. When the inbound request comes in, TIdIOHandler.InitComponent is called in a thread before execution is handed to the method called in TServerMethods. I do not have any Indy components in the server, so DataSnap is using Indy 10 under-the-hood.

.InitComponent() sets the IO handler's max line length to a hard-coded value (FMaxLineLength := IdMaxLineLengthDefault;), which is 16384. I can't find a way to increase the value. I even tried copying the IdIOHandler Unit to the project folder and changing the constant value. But it still picks up the IdIOHandler.dcu from the Indy 10 build, and ignores the copied file in my project folder. I also tried adding a TIdIOHandlerStream component to the server project and setting its MaxLineLength to no avail.

  • Plan A = Properly set the MaxLineLength value in the DataSnap server.
  • Plan B = Somehow compile a modified IdIOHandler.pas file into my project.

Are either of these possible? I've been working on this for hours and can't find anything similar in all my searching, and can't seem to make any headway by experimenting.

2
Very strange, an HTTP entity is an arbitrary sequence of octets - maybe Indy developers thought only about HTML data? There are no "lines" in an HTML entity. You could try to uninstall Indy wholly from Delphi, and install a modified build form the available source code. Anyway the whole Datasnap stack is a bunch of ill-designed libraries, I would look for better solutions for remoting.Mad Hatter
There are two settings, the max length of a line, and whether to split the request when the max length is exceeded or to raise an exception. The defaults are 16,384 and raise an exception. It is easy to set both of these for outbound requests from the client-side. I see no way to set them for inbound requests to the DataSnap server on the server-side.James L.

2 Answers

1
votes

After recompiling all Indy packages in Delphi XE3, having changed the IdMaxLineLengthDefault constant to 512 * 1024, and working as expected after that, I began searching for the simplest solution to this problem. So, I found out this an easy workaround for this limit.

You can implement a procedure for the OnContextCreated event of the TIdHTTPWebBrokerBridge object used in the main unit of the DataSnap REST Server project. In that event, the AContext object is received, which is created for each request to the DataSnap server. So, in the code for this procedure you just have to override the default value for this property as follows:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FServer := TIdHTTPWebBrokerBridge.Create(Self);

  {Here you assign the new procedure for this event}
  FServer.OnContextCreated:= OnContextCreated; 
end;

procedure TForm1.OnContextCreated(AContext: TIdContext);
begin
   AContext.Connection.IOHandler.MaxLineLength:= 512*1024 {or whatever value you need);
end;
0
votes

Short of removing the Delphi XE2 install of Indy 10 and downloading the source, tweaking the constant values and compiling / maintaining my own build forever going forward..., I solve the issue.

I created an additional method in the DataSnap server so that I could create a record in the database with a call to the first method, and then incrementally stream the rest of the data by passing it to the second method 16k at a time -- buffering it in the DataSnap server until all parts are received. Then I update the record in the database with the fully buffered value from the DataSnap server.

Maybe not the most effective solution, but it works and it will scale as needed.