Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 登录名/密码无效的Indy TIdHTTP URI_Delphi_Uri_Url Encoding_Indy10 - Fatal编程技术网

Delphi 登录名/密码无效的Indy TIdHTTP URI

Delphi 登录名/密码无效的Indy TIdHTTP URI,delphi,uri,url-encoding,indy10,Delphi,Uri,Url Encoding,Indy10,我正在写一篇文章,以与特定的。该过程的一部分需要URI中的登录凭据,例如: http://user:pass_with_#_sign@address:port/somespecificpath/ 我正在使用Indy的TIdHTTP.Get将请求发送到设备。但是,密码由“#”字符组成。如果使用普通密码将此URI放置在任何浏览器中,则#字符会将其丢弃。因此,我需要将密码的#编码为%23 http://user:pass_with_%23_sign@address:port/somespecific

我正在写一篇文章,以与特定的。该过程的一部分需要URI中的登录凭据,例如:

http://user:pass_with_#_sign@address:port/somespecificpath/
我正在使用Indy的
TIdHTTP.Get
将请求发送到设备。但是,密码由“#”字符组成。如果使用普通密码将此URI放置在任何浏览器中,则
#
字符会将其丢弃。因此,我需要将密码的
#
编码为
%23

http://user:pass_with_%23_sign@address:port/somespecificpath/
当我将此URI粘贴到任何浏览器中时,它会成功登录并执行它所需的操作。但是,当我将完全相同的URI传递到
TIdHTTP.Get
时,它不会成功登录,因此只要密码包含
#
(或
%23
),我就无法执行任何操作。将密码更改为不包含
#
的解决方案太草率了。Indy一定是把这个URI/密码弄乱了

这是Indy中的一个bug,还是我还需要做些什么来让Indy接受这样一个编码密码


更新

我在其中一个摄像头上添加了一个新帐户,用户名和密码没有任何需要编码的特殊字符,身份验证仍然不起作用。似乎Indy完全从URI中剥离了登录凭据,甚至没有发送这些凭据。接下来我需要做的是监视实际发送的URI


更新2

我通过WireShark进行了数据包捕获,并验证了凭据
…用户:pass@...
甚至没有发送-它们从Indy实际发送的URI中剥离出来


更新3

TLama建议我在使用浏览器时捕获发送的内容。我尝试了这个,而且确信即使在使用浏览器时,捕获也不会显示这些登录凭据。。。即使它可以在浏览器中工作。因此,我必须找出另一种方法来确定是否发送了这些凭据


更新4

我尝试(在看到雷米的答案之前)在
Request.Username
Request.Password
中提供这些凭证,而不是在URI中,但仍然没有成功。我不断从设备上得到“未经授权”的回复


更新5

除本段外,本节未提及与用户认证方式相关的内容:

Grandstream视频监控API(应用程序编程接口)支持HTTP 1.0协议(RFC1945)。本文档通过支持的GET/POST方法详细解释了客户端函数的参数。用户需要管理员权限才能检索或设置参数

在这一点上,我确实将
TIdHTTP
协议版本切换到了
1.0


更新6

希望最后的更新需要。。。我对浏览器(Chrome)和
TIdHTTP
之间的数据包捕获进行了另一次比较。Chrome实际上发送了两个请求,第一个请求没有任何凭据,但在第二个请求中,在标题
Authorization:Basic…
credentials:User:Pass
中有一个节点,而使用
TIdHTTP
只发送一个没有这些凭据的请求


更新7

7是一个幸运数字:-)我刚刚意识到,我向设备发出的第一个请求返回“Unauthorized”,但我发出的所有后续请求(使用相同的
TIdHTTP
实例)都成功了!因此,回到我之前的更新,就像我在浏览器捕获中看到的一样,它需要第二次重复请求才能工作。

#
是URL片段之前的URL中的非法字符,这就是为什么在URL的其他区域使用时必须将其编码为
%23

用户名/密码实际上不是真实URL的一部分,这就是为什么当
TIdHTTP
将URL发送到服务器时,用户名/密码会被剥离(监控任何web浏览器的流量,您将看到同样的情况发生)

要对
TIdHTTP
使用HTTP身份验证,您需要使用
TIdHTTP.Request.Username
TIdHTTP.Request.Password
属性(并且不需要对值进行URL编码),例如:

如果您传递的URL中包含编码的用户名/密码,
TIdHTTP
将去除这些值,并将它们移动到
Request.username
Request.password
属性中,但它们将保持原始编码格式,例如:

IdHTTP1.Get('http://user:pass_with_%23_sign@address:port/somespecificpath/')
// this will set Request.Username to 'user',
// Request.Password to 'pass_with_%23_sign', and
// send a request for 'http://address:port/somespecificpath/'
如果给您一个编码URL作为开始,您可以使用
TIdURI
类在调用
TIdHTTP.Get()
之前手动解码它,例如:

var
  RequestUrl: string;
  Uri: TIdURI;
begin
  RequestUrl := 'http://user:pass_with_%23_sign@address:port/somespecificpath/';
  ...
  Uri := TIdURI.Create(RequestURL);
  try
    IdHTTP1.Request.Username := TIdURI.URLDecode(Uri.UserName);
    IdHTTP1.Request.Password := TIdURI.URLDecode(Uri.Password);
    RequestURL := Uri.URI;
  finally
    Uri.Free;
  end;
  IdHTTP1.Get(RequestUrl);
  ...
end;
更新:无论哪种方式,请确保您拥有适当的
IdAuthentication…
单元,或
IdAllAuthentications
单元,在您的
中,uses
子句启用Indy的HTTP身份验证类供
TIdHTTP
使用。

#
是URL中片段部分之前的URL中的非法字符,这就是为什么在URL的其他区域使用时必须将其编码为
%23

用户名/密码实际上不是真实URL的一部分,这就是为什么当
TIdHTTP
将URL发送到服务器时,用户名/密码会被剥离(监控任何web浏览器的流量,您将看到同样的情况发生)

要对
TIdHTTP
使用HTTP身份验证,您需要使用
TIdHTTP.Request.Username
TIdHTTP.Request.Password
属性(并且不需要对值进行URL编码),例如:

如果您传递的URL中包含编码的用户名/密码,
TIdHTTP
将去除这些值,并将它们移动到
Request.username
Request.passwordvar
  RequestUrl: string;
  Uri: TIdURI;
begin
  RequestUrl := 'http://user:pass_with_%23_sign@address:port/somespecificpath/';
  ...
  Uri := TIdURI.Create(RequestURL);
  try
    IdHTTP1.Request.Username := TIdURI.URLDecode(Uri.UserName);
    IdHTTP1.Request.Password := TIdURI.URLDecode(Uri.Password);
    RequestURL := Uri.URI;
  finally
    Uri.Free;
  end;
  IdHTTP1.Get(RequestUrl);
  ...
end;
FWeb.Get(U);
FWeb.Get(U, R);