2

I'm writing a Delphi-based Windows server for a tablet-based HTML client.

Most files are served out unprocessed, as you would expect of a web server, but a handful of special keywords are being interpreted as special commands that interface with other software on the server.

Most of the time, everything is fine. But then, seemingly at random, I'd get an access violation, and it would be while trying to retrieve one of the GET parameters.

This was driving me mad, so I encapsulated the entire thing down into a function and just started testing for the existence of the TIdHTTPRequestInfo data (shown here as the public property Request inside the class):

function TELSCommand.GETValue(key:AnsiString):AnsiString;
begin
    if not Assigned(Request) then begin
        Log.e('WHERE IS REQUEST?');
        Result := '';
        Exit;
    end;

    if not Assigned(Request.Params) then begin
        Log.e('WHERE IS REQUEST PARAMS?');
        Result := '';
        Exit;
    end;

    if (Request.Params.IndexOfName(key) >= 0) then
        Result := Request.Params.Values[key]
    else
        Result := '';
end;

I didn't actually expect either of the two Assigned() checks to get triggered, but, randomly, the second one will get tripped, and I'll see "WHERE IS REQUEST PARAMS?" in my log file after hitting F5 (slowly, I'm not hammering the server).

When I throw down a breakpoint inside the block and inspect the value of Request when it hits that point, the entire TIdHTTPRequestInfo structure is filled with default, empty data. If I check the browser to see what request it sent, it's what I would expect... (generally just a request for "/details?id=222", for example).

I should note that I'm developing on Windows 7 64-bit, so I'm constantly paranoid of things like this being caused by it. More than once I've hit snags that turned out to be because of 64-bit wackiness.

Additional info: Indy 9, Delphi 2007.

Hopefully this was clear enough to understand. I'm not looking for specific answers, since I haven't provided nearly enough; I'm just looking for suggestions on where to go from here. Much appreciated! :)

TobyD
  • 161
  • 1
  • 6
  • If you're really "not looking for specific answers," then you're in the wrong place — I've voted to close as *not a real question*. You have the Indy source code, so keep on debugging. Find the place where `Params` is supposed to get assigned. Step through to see how that happens. Compare with a failure case to see what's different. If you're paranoid about the OS, then use a VM to test on a "simpler" platform. – Rob Kennedy Aug 08 '11 at 20:36
  • Sounds like you need to add a lot of trace message logging and do some difficult debugging. Are you using SOAP+WSDL wrappers? – Warren P Aug 08 '11 at 23:30
  • 2
    I suggest you use a packet sniffer, such as Wireshark, or attach one of Indy's own `TIdLog...` components to `TIdHTTP`, to see what the actual request/response data actually looks like, and then you can trace through Indy's code to see how it would be handled. One of Indy's strong features is the ability to capture and playback raw data for debugging. You can use `TIdLogFile` or `TIdLogStream` to capture the inbound data, then attach a `TIdIOHandlerStream` to play it back without having to connect to the real server. – Remy Lebeau Aug 09 '11 at 07:37
  • I had a more experienced Delphi/Indy coder here at work go over it, and he's pretty sure the problem is internal state being stomped by thread timing issues. I'm not terribly experienced with threads, so I was thinking rather 'serially' when I wrote what I did. He's going to rework my server logic and I'll have to use this as a learning experience. :) Thanks for the tips, everyone. You rock. – TobyD Aug 16 '11 at 21:02

1 Answers1

2

RequestInfo.Params is created in the Constructor and there's a FreeAndNil() in the Destructor so once the Request is Free'd, the Assigned() will fail on this property.

Given that, and based on the confused info of your scenario, I would assume you have some threading issues where you are referencing a dangling Request instance that isn't yet NIL'ed but the Params property has been. Sometimes you get lucky and it works, and sometimes it blows an AV.

Alternately, you are manually NIL'ing the .Params property somehow in your code. Perhaps you are passing this TStringList object around and something else is releasing it accidentally. Indy won't be free'ing this until the Request is done.

All and all, you are correct as you haven't provided enough information and the question should probably be closed.

Darian Miller
  • 7,808
  • 3
  • 43
  • 62