使用 Indy 调用 Datasnap 服务器的内部服务器错误

Internal Server Error calling a Datasnap server using Indy

我已经设置了一个非常基本的 DataSnap 服务器应用程序 (Delphi XE3),其中包含 2 个示例方法,EchoString 和 ReverseString。我添加了身份验证,这样只有当调用该方法的用户被称为 "standard" 时,他们才能访问 ReverseString 方法。

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;

如果我直接从浏览器调用这个方法,例如

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

然后我得到了预期的响应(在浏览器的默认登录提示之后,我在其中输入了一个无效的用户,例如 Jason):

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

但是,如果我使用 Indy (TIdHTTP) 从 Delphi 客户端应用程序调用它:

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

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

我收到这样的回复:

HTTP/1.1 500 Internal Server Error

如何避免错误并收到与浏览器中相同的 RESTful 响应?我一直在尝试弄清楚如何查看浏览器发送的 HTTP 请求与 Indy 发送的 HTTP 请求,但没有成功,即使使用 Ethereal。

我已经能够确定发生了什么。使用 Wireshark 和 Rawcap(捕获本地环回请求),我可以看到即使浏览器显示了有意义的消息:

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

它还返回 HTTP 500 内部服务器错误。但是,有意义的响应文本也作为此响应的一部分返回,由浏览器显示。

检查 Indy HTTP 响应,是一样的;实际响应代码是 500,但我要显示的文本也被返回。

这可以通过捕获 EIdHTTPProtocolException 并访问它的 ErrorMessage 属性 来访问。