将 C#/.NET、ruby 或 Python 代码转换为 Delphi Indy v10
Converting C#/.NET, ruby or Python code to Delphi Indy v10
我需要使用名为 pushover (https://pushover.net/) 的消息服务,我正在尝试转换以其他编程语言发布的示例代码以用于 Delphi XE7/Indy10。
我在 Delphi 中使用了以下代码,我总是得到:"HTTP/1.1 400 Bad Request".
Procedure SendMessage;
var ...
begin
IdHTTP:=TIdHTTP.Create(nil);
IdHTTP.HandleRedirects:=True;
Resp := TStringStream.Create('', TEncoding.UTF8);
sURL :='https://api.pushover.net/1/messages.json?';
postdata := 'token=aiJSSS3167JLrPAAye9srpEz27RDJ2Rm&user=uDXXXFCASKgqLGzzuJLMdf2Ymyr5dP&message=This is a Text&title=Test'
sFPRvalue := idhttp.URL.ParamsEncode(postdata,IndyTextEncoding_UTF8);
Sl:=IntToStr(length(postdata));
s:=sURL+sFPRvalue;
try
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
SSL1.SSLOptions.Method := sslvSSLv23;
IdHTTP.IOHandler := SSL1;
IdHttp.Request.CustomHeaders.AddValue('Content-Type','application/x-www-form-urlencoded');
IdHttp.Request.CustomHeaders.AddValue('Content-Length',sl);
strres := IdHTTP.Post(s,Resp);
finally
SSl1.Free;
end;
finally
Resp.Free;
end;
end;
以下是店主服务发布的样本:
C#
var parameters = new NameValueCollection {
{ "token", "APP_TOKEN" },
{ "user", "USER_KEY" },
{ "message", "hello world" }
};
using (var client = new WebClient())
{
client.UploadValues("https://api.pushover.net/1/messages.json", parameters);
}
Python
import http.client, urllib
conn = http.client.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json",
urllib.parse.urlencode({
"token": "APP_TOKEN",
"user": "USER_KEY",
"message": "hello world",
}), { "Content-type": "application/x-www-form-urlencoded" })
conn.getresponse()
Ruby
require "net/https"
url = URI.parse("https://api.pushover.net/1/messages.json")
req = Net::HTTP::Post.new(url.path)
req.set_form_data({
:token => "APP_TOKEN",
:user => "USER_KEY",
:message => "hello world",
})
res = Net::HTTP.new(url.host, url.port)
res.use_ssl = true
res.verify_mode = OpenSSL::SSL::VERIFY_PEER
res.start {|http| http.request(req) }
问题是您调用了 TIdHTTP.Post()
的错误重载版本,并且您正在以错误的方式格式化其参数数据。您需要使用 Post()
的重载版本,它将 TStrings
作为输入,让它为您编码 post 数据,并将 return 响应数据编码为 String
,例如:
IdHTTP := TIdHTTP.Create(nil);
try
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
SSL1.SSLOptions.Method := sslvTLSv1;
IdHTTP.IOHandler := SSL1;
IdHTTP.HandleRedirects := True;
IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
PostData := TStringList.Create;
try
PostData.Add('token=aiJSSS3167JLrPAAye9srpEz27RDJ2Rm');
PostData.Add('user=uDXXXFCASKgqLGzzuJLMdf2Ymyr5dP');
PostData.Add('message=This is a Text');
PostData.Add('title=Test');
try
strres := IdHTTP.Post('https://api.pushover.net/1/messages.json', PostData);
except
on E: EIdHTTPProtocolException do
begin
if (E.ErrorCode div 100) = 4 then
begin
// use E.ErrorMessage as needed...
end else begin
raise;
end;
end;
end;
finally
PostData.Free;
end;
finally
IdHTTP.Free;
end;
我需要使用名为 pushover (https://pushover.net/) 的消息服务,我正在尝试转换以其他编程语言发布的示例代码以用于 Delphi XE7/Indy10。
我在 Delphi 中使用了以下代码,我总是得到:"HTTP/1.1 400 Bad Request".
Procedure SendMessage;
var ...
begin
IdHTTP:=TIdHTTP.Create(nil);
IdHTTP.HandleRedirects:=True;
Resp := TStringStream.Create('', TEncoding.UTF8);
sURL :='https://api.pushover.net/1/messages.json?';
postdata := 'token=aiJSSS3167JLrPAAye9srpEz27RDJ2Rm&user=uDXXXFCASKgqLGzzuJLMdf2Ymyr5dP&message=This is a Text&title=Test'
sFPRvalue := idhttp.URL.ParamsEncode(postdata,IndyTextEncoding_UTF8);
Sl:=IntToStr(length(postdata));
s:=sURL+sFPRvalue;
try
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
SSL1.SSLOptions.Method := sslvSSLv23;
IdHTTP.IOHandler := SSL1;
IdHttp.Request.CustomHeaders.AddValue('Content-Type','application/x-www-form-urlencoded');
IdHttp.Request.CustomHeaders.AddValue('Content-Length',sl);
strres := IdHTTP.Post(s,Resp);
finally
SSl1.Free;
end;
finally
Resp.Free;
end;
end;
以下是店主服务发布的样本:
C#
var parameters = new NameValueCollection {
{ "token", "APP_TOKEN" },
{ "user", "USER_KEY" },
{ "message", "hello world" }
};
using (var client = new WebClient())
{
client.UploadValues("https://api.pushover.net/1/messages.json", parameters);
}
Python
import http.client, urllib
conn = http.client.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json",
urllib.parse.urlencode({
"token": "APP_TOKEN",
"user": "USER_KEY",
"message": "hello world",
}), { "Content-type": "application/x-www-form-urlencoded" })
conn.getresponse()
Ruby
require "net/https"
url = URI.parse("https://api.pushover.net/1/messages.json")
req = Net::HTTP::Post.new(url.path)
req.set_form_data({
:token => "APP_TOKEN",
:user => "USER_KEY",
:message => "hello world",
})
res = Net::HTTP.new(url.host, url.port)
res.use_ssl = true
res.verify_mode = OpenSSL::SSL::VERIFY_PEER
res.start {|http| http.request(req) }
问题是您调用了 TIdHTTP.Post()
的错误重载版本,并且您正在以错误的方式格式化其参数数据。您需要使用 Post()
的重载版本,它将 TStrings
作为输入,让它为您编码 post 数据,并将 return 响应数据编码为 String
,例如:
IdHTTP := TIdHTTP.Create(nil);
try
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
SSL1.SSLOptions.Method := sslvTLSv1;
IdHTTP.IOHandler := SSL1;
IdHTTP.HandleRedirects := True;
IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
PostData := TStringList.Create;
try
PostData.Add('token=aiJSSS3167JLrPAAye9srpEz27RDJ2Rm');
PostData.Add('user=uDXXXFCASKgqLGzzuJLMdf2Ymyr5dP');
PostData.Add('message=This is a Text');
PostData.Add('title=Test');
try
strres := IdHTTP.Post('https://api.pushover.net/1/messages.json', PostData);
except
on E: EIdHTTPProtocolException do
begin
if (E.ErrorCode div 100) = 4 then
begin
// use E.ErrorMessage as needed...
end else begin
raise;
end;
end;
end;
finally
PostData.Free;
end;
finally
IdHTTP.Free;
end;