使用 Indy 对 IP-based 主机的 HTTP 获取请求
HTTP Get request to IP-based host using Indy
我有一些 Delphi 连接到 servlet 的代码,我正在尝试从 TIdTCPClient 切换到 TIdHTTP。
我这样连接到servlet
try
lHTTP := TIdHTTP.Create( nil );
responseStream := TMemoryStream.Create;
lHTTP.Get(HttpMsg, responseStream);
SetString( html, PAnsiChar(responseStream.Memory), responseStream.Size);
AnotarMensaje( odDepurar, 'IMPFIS: Impresora fiscal reservada ' + html );
其中 HttpMsg 是 localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector
我得到的只是
GET localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector HTTP/1.1
Content-Type: text/html
Accept: text/html, */*
User-Agent: Mozilla/3.0 (compatible; Indy Library)
HTTP/1.1 400 Bad Request
我之前的HTTP对话框是这样的
GET /QRSRPServer/PedirImpresion?usuarioDMS=hector HTTP/1.1
Host: localhost:6080
HTTP/1.1 200 OK
因此,我尝试添加主机 header,此主机为:localhost:6080
try
lHTTP := TIdHTTP.Create( nil );
lHTTP.Host := Host;
responseStream := TMemoryStream.Create;
lHTTP.Get(HttpMsg, responseStream);
SetString( html, PAnsiChar(responseStream.Memory), responseStream.Size);
AnotarMensaje( odDepurar, 'IMPFIS: Impresora fiscal reservada ' + html );
然后我得到
Socket Error # 11004
这比我想象的要容易。我假设有一个包含端口的 "host" 参数就足够了,但是查看 Wireshark 捕获我发现它正在通过标准 HTTP 端口发送所有内容。
所以这成功了
try
lHTTP := TIdHTTP.Create( nil );
lHTTP.Host := GatewayIp;
lHTTP.Port := GatewayPuerto;
responseStream := TMemoryStream.Create;
lHTTP.Request.CustomHeaders.Clear;
lHTTP.Request.CustomHeaders.Add('Host: ' + Host );
lHTTP.Get(HttpMsg, responseStream);
SetString( html, PAnsiChar(responseStream.Memory), responseStream.Size);
AnotarMensaje( odDepurar, 'IMPFIS: Impresora fiscal reservada ' + html );
Where HttpMsg is localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector
HttpMsg
必须 以 http://
或 https://
:
开头
http://localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector
当 TIdHTTP
解析 URL 并发现缺少的协议方案时,您应该得到一个 EIdUnknownProtocol
异常。
TIdHTTP
应该始终发送 Host
header,但尤其是对于 HTTP 1.1 请求,但您声称不是。这就是您收到 Bad Request
错误的原因,因为 HTTP 1.1 服务器需要拒绝省略 header.
的 HTTP 1.1 请求
您还声称 TIdHTTP
在 GET
行中包含主机和端口值。 ONLY 一次是通过 HTTP 代理连接到主机时,但我根本没有看到您配置 TIdHTTP.ProxyParams
属性。
简而言之,TIdHTTP
不应该像您声称的那样行事。
正确的解决方案是确保将 完整 URL 传递给 TIdHTTP.Get()
.
附带说明一下,您的代码要求 html
为 AnsiString
。您应该将其更改为标准 string
(在 D2007 及更早版本中为 AnsiString
)并让 TIdHTTP
return 为您提供 string
,然后您就不会不再需要 TMemoryStream
:
html := lHTTP.Get(HttpMsg);
我有一些 Delphi 连接到 servlet 的代码,我正在尝试从 TIdTCPClient 切换到 TIdHTTP。
我这样连接到servlet
try
lHTTP := TIdHTTP.Create( nil );
responseStream := TMemoryStream.Create;
lHTTP.Get(HttpMsg, responseStream);
SetString( html, PAnsiChar(responseStream.Memory), responseStream.Size);
AnotarMensaje( odDepurar, 'IMPFIS: Impresora fiscal reservada ' + html );
其中 HttpMsg 是 localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector
我得到的只是
GET localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector HTTP/1.1
Content-Type: text/html
Accept: text/html, */*
User-Agent: Mozilla/3.0 (compatible; Indy Library)
HTTP/1.1 400 Bad Request
我之前的HTTP对话框是这样的
GET /QRSRPServer/PedirImpresion?usuarioDMS=hector HTTP/1.1
Host: localhost:6080
HTTP/1.1 200 OK
因此,我尝试添加主机 header,此主机为:localhost:6080
try
lHTTP := TIdHTTP.Create( nil );
lHTTP.Host := Host;
responseStream := TMemoryStream.Create;
lHTTP.Get(HttpMsg, responseStream);
SetString( html, PAnsiChar(responseStream.Memory), responseStream.Size);
AnotarMensaje( odDepurar, 'IMPFIS: Impresora fiscal reservada ' + html );
然后我得到
Socket Error # 11004
这比我想象的要容易。我假设有一个包含端口的 "host" 参数就足够了,但是查看 Wireshark 捕获我发现它正在通过标准 HTTP 端口发送所有内容。
所以这成功了
try
lHTTP := TIdHTTP.Create( nil );
lHTTP.Host := GatewayIp;
lHTTP.Port := GatewayPuerto;
responseStream := TMemoryStream.Create;
lHTTP.Request.CustomHeaders.Clear;
lHTTP.Request.CustomHeaders.Add('Host: ' + Host );
lHTTP.Get(HttpMsg, responseStream);
SetString( html, PAnsiChar(responseStream.Memory), responseStream.Size);
AnotarMensaje( odDepurar, 'IMPFIS: Impresora fiscal reservada ' + html );
Where HttpMsg is
localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector
HttpMsg
必须 以 http://
或 https://
:
http://localhost:6080/QRSRPServer/PedirImpresion?usuarioDMS=hector
当 TIdHTTP
解析 URL 并发现缺少的协议方案时,您应该得到一个 EIdUnknownProtocol
异常。
TIdHTTP
应该始终发送 Host
header,但尤其是对于 HTTP 1.1 请求,但您声称不是。这就是您收到 Bad Request
错误的原因,因为 HTTP 1.1 服务器需要拒绝省略 header.
您还声称 TIdHTTP
在 GET
行中包含主机和端口值。 ONLY 一次是通过 HTTP 代理连接到主机时,但我根本没有看到您配置 TIdHTTP.ProxyParams
属性。
简而言之,TIdHTTP
不应该像您声称的那样行事。
正确的解决方案是确保将 完整 URL 传递给 TIdHTTP.Get()
.
附带说明一下,您的代码要求 html
为 AnsiString
。您应该将其更改为标准 string
(在 D2007 及更早版本中为 AnsiString
)并让 TIdHTTP
return 为您提供 string
,然后您就不会不再需要 TMemoryStream
:
html := lHTTP.Get(HttpMsg);