2015-04-22 4 views
0

Мне нужно использовать службу сообщений с именем pushover (https://pushover.net/), и я пытаюсь преобразовать образец кода, размещенный на другом языке программирования, для использования с Delphi XE7/Indy10.Преобразование кода C# /. NET, ruby ​​или Python в Delphi Indy v10

Я использовал следующий код в 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() 

Рубин

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) } 

ответ

2

Проблема в том, что вы вызываете неправильную перегруженную версию TIdHTTP.Post(), и вы форматируете ее данные параметров неверным способом. Вы должны использовать перегруженную версию Post(), которая принимает в качестве входных данных TStrings, пусть кодировать почтовые данные для вас, и возвращают данные ответа как 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; 
+0

Спасибо Реми. Он работает очень хорошо. Откуда вы знаете метод SSLOptions? И если я хочу опубликовать URL-адрес, такой как PostData ('url = myurl'), нужно ли мне кодировать url? –

+0

Реми, служба сообщений сообщила: «Если какой-либо вход был недействителен, вы получите статус HTTP 4xx с объектом JSON или узлом XML, содержащим код состояния чего-то другого, кроме 1, и массив ошибок, детализирующий, какие параметры были недействительными. {«пользователь»: «недопустимый», «ошибки»: [«Идентификатор пользователя недействителен»], «статус»: 0, «запрос»: «3c0b5952fba0ab27805159217077c177«} ». Когда я получаю HTTP 400 Errror, приложение прерывается, и я никогда не смогу получить это сообщение. Как я могу получить это сообщение об ошибке после ошибки HTPP 400? –

+0

Что касается значения 'SSLOptions.Method', я читаю [это объявление] (http://updates.pushover.net/post/100158741542/api-sslv3-support-disabled). Что касается URL-кодирования URL-адреса в данных сообщения, я не знаю точно, но я подозреваю, что да. Вам придется попробовать и посмотреть, что произойдет. Что касается ошибки 4xx, заверните 'Post()' в 'try/except', чтобы поймать исключение' EIdHTTPProtocolException', JSON/XML будет находиться в свойстве 'ErrorMessage'. Я обновил свой ответ, чтобы показать это. –