2017-07-14 73 views
6

下一页Python代码转换Python来Delphi代码

from urllib.request import Request, urlopen 
import urllib 
import json 

#ID access to API 
TOKEN = "{YOUR_API_TOKEN}" # e.g.: "f03c3c76cc853ee690b879909c9c6f2a" 
url = "https://cloudpanel-api.1and1.com/v1" 

def _setStatusServer(id, content): 
    #Configure the request 
    _command = url + "/servers/" + id + "/status/action" 
    _method = 'PUT' 
    request = Request(_command, data=content.encode(encoding='utf_8'), 
        headers={'X-TOKEN':TOKEN, 'content- 
        type':'application/json'}, 
        method=_method) 

    #Try to get the response 
    try: 
    response = urlopen(request) 
    content = response.read() 
    return (content.decode()) 
    #Fetch error 
    except urllib.error.URLError as e: 
     return("Error " + str(e.code) + ":" + e.reason) 

    #PARAMETERS 
    id = "{YOUR_SERVER_ID}" # e.g.: "5340033E7FBBC308BC329414A0DF3C20" 
    action = "REBOOT" 
    method = "SOFTWARE" 

    data = json.dumps({'action':action, 'method':method}) 

    #REBOOT server 
    print(_setStatusServer(id, data)) 

我已转换为帕斯卡代码

function TWFServerSetState.ExecuteCommand(id, ip_id, Content: string): string; 
var 
    HTTP: TIdHTTP; 
    Command: string; 
    InputStream: TStringStream; 
    ResponseStream: TStringStream; 

    str: string; 
begin 
    Result := ''; 
    HTTP := TIdHTTP.Create(); 
    try 
    HTTP.Request.ContentEncoding := 'UTF-8'; 
    HTTP.Request.CustomHeaders.AddValue('X-TOKEN', Token); 
    HTTP.Request.CustomHeaders.AddValue('content-type', 'application/json'); 
    HTTP.Request.ContentType := 'application/json'; 
    Command := GetAddress + '/servers/' + id + '/status/action'; 

    str := '{"method": "' + Content + '", "action": "' + ip_id + '"}'; 
    str := TIdEncoderMIME.EncodeString(STR, IndyUTF8Encoding); 
    InputStream := TStringStream.Create(str, TEncoding.UTF8); 
    ResponseStream := TStringStream.Create('', TEncoding.UTF8, false); 
    try 
     HTTP.Put(Command, InputStream, ResponseStream); 
     Result := ResponseStream.DataString; 
    finally 
     ResponseStream.Free; 
     InputStream.Free; 
    end; 
    finally 
    HTTP.Free; 
    end; 
end; 

但是,Python代码执行的结果是OK。 执行的Delphi代码返回

“HTTP/1.1 406不可接受”

任何建议其中I在转换作出错误?

基于mjn建议,我删除了Mime编码,并更改了两个代码中的测试URL。从httpbin服务器上的Python代码的要求是:

{'X-token': {token}, 'Content-type': 'application/json'} 
{ 
    "args": {}, 
    "data": "{\"method\": \"SOFTWARE\", \"action\": \"REBOOT\"}", 
    "files": {}, 
    "form": {}, 
    "headers": { 
    "Accept-Encoding": "identity", 
    "Connection": "close", 
    "Content-Length": "42", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/3.4", 
    "X-Token": "token" 
    }, 
    "json": { 
    "action": "REBOOT", 
    "method": "SOFTWARE" 
    }, 
    "origin": "24.135.167.155", 
    "url": "http://httpbin.org/put" 
} 

从Delphi代码

{ 
    "args": {}, 
    "data": "{\"method\": \"SOFTWARE\", \"action\": \"REBOOT\"}", 
    "files": {}, 
    "form": {}, 
    "headers": { 
    "Accept-Encoding": "identity", 
    "Connection": "close", 
    "Content-Length": "42", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/3.0 (compatible; Indy Library)", 
    "X-Token": "token" 
    }, 
    "json": { 
    "action": "REBOOT", 
    "method": "SOFTWARE" 
    }, 
    "origin": "176.67.200.136", 
    "url": "http://httpbin.org/put" 
} 

在此先感谢

博扬

+1

看来你需要添加一个接受:头。 –

+1

做一些调试。比较两个请求。他们有什么不同。 –

+0

@大卫:我做到了,我没有看到任何区别 –

回答

2

你的Delphi代码不发送JSON数据相同Python代码的方式。代码中有几个逻辑和编码错误。

正确的代码应该看起来更像这个:

function TWFServerSetState.ExecuteCommand(const ServerID, Action, Method: string): string; 
var 
    HTTP: TIdHTTP; 
    Url: string; 
    InputStream: TStringStream; 
    str: string; 
begin 
    Result := ''; 
    HTTP := TIdHTTP.Create; 
    try 
    HTTP.Request.CustomHeaders.AddValue('X-TOKEN', Token); 
    HTTP.Request.ContentType := 'application/json'; 
    Url := GetAddress + '/servers/' + ServerID + '/status/action'; 
    str := '{"method": "' + Method + '", "action": "' + Action + '"}'; 
    InputStream := TStringStream.Create(str, TEncoding.UTF8); 
    try 
     try 
     Result := HTTP.Put(Url, InputStream); 
     except 
     on e: EIdHTTPProtocolException do 
      Result := 'Error ' + IntToStr(e.ErrorCode) + ':' + e.Message; 
     end; 
    finally 
     InputStream.Free; 
    end; 
    finally 
    HTTP.Free; 
    end; 
end; 

然后,你可以这样调用:

var 
    id, action, method: string; 
begin 
    id := '{YOUR_SERVER_ID}'; // e.g.: "5340033E7FBBC308BC329414A0DF3C20" 
    action := 'REBOOT'; 
    method := 'SOFTWARE'; 
    ExecuteCommand(id, action, method); 
end; 
+0

感谢您的回答。我已经写了不同的参数名称,因为这个类是其中一个子类,它们都有不同的参数名称。真正唯一的问题是在 HTTP.Request.CustomHeaders.AddValue('content-type','application/json'); HTTP.Request.ContentType:='application/json'; ,因为服务器看起来像'application/json','application/json',并且不接受这个ContentType。 httpbin.org/put只写了ContentType ='application/json'一次,但真正的服务器没有这样看。其他被“addopted”正确。 –

+0

@bojangavrilovic那么,当Python代码没有,并且你将Content-Encoding标头设置为无效值时,你是base64编码的JSON数据。这些都加上了一个非常畸形的请求。 –