Search code examples
delphiindydatasnap

Internal Server Error calling a Datasnap server using Indy


I have set up a very basic DataSnap Server Application (Delphi XE3), containing the 2 sample methods, EchoString and ReverseString. I have added authentication so that only if the user calling the method is called "standard", they have access to the ReverseString method.

procedure TServerContainer1.DSAuthenticationManager1UserAuthenticate(
Sender: TObject; const Protocol, Context, User, Password: string;
var valid: Boolean; UserRoles: TStrings);
begin
  valid := (User <> '');

  if (SameText(User, 'standard') = True) then
  begin
    UserRoles.Add('standard');
  end;
end;

type
TServerMethods1 = class(TDSServerModule)
private
  { Private declarations }
public
  { Public declarations }
  function EchoString(Value: string): string;
  [TRoleAuth('standard')]
  function ReverseString(Value: string): string;
end;

If I call this method from a browser directly, e.g.

http://localhost:8080/datasnap/rest/TServerMethods1/ReverseString/TestFromBrowser

then I get the expected response (after the browser's default login prompt, in which I enter an invalid user, e.g. Jason):

{"error":"jason is not authorized to perform the requested action."}

However, if I call it from a Delphi client application using Indy (TIdHTTP):

IdHTTP1.Request.BasicAuthentication := True;
IdHTTP1.Request.Username := 'jason';
IdHTTP1.Request.Password := 'jason';

Label2.Caption := IdHTTP1.Get('http://localhost:8080/datasnap/rest/TServerMethods1/ReverseString/TestFromDelphi');

I get this response:

HTTP/1.1 500 Internal Server Error

How can I avoid the error and receive the same RESTful response that I got in the browser? I have been trying to figure out how to view the HTTP request sent by the browser vs that sent by Indy but haven't managed it, even using Ethereal.


Solution

  • I have been able to establish what is going on. Using Wireshark and Rawcap (to capture local loopback requests), I can see that even though the browser is showing the meaningful message:

    {"error":"jason is not authorized to perform the requested action."}
    

    it is also returning an HTTP 500 Internal Server Error. However, the meaningful response text is also returned as part of this response, which is being displayed by the browser.

    Response from Browser

    Checking the Indy HTTP response, it is the same; the actual response code is a 500, but the text I want to display is also being returned.

    enter image description here

    This is accessible by capturing the EIdHTTPProtocolException and accessing its ErrorMessage property.