преобразование Python в код Delphi

следующий код python

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

Я преобразован в код pascal

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 в порядке. Выполнение кода Delphi возвращает

"HTTP / 1.1 406 неприемлемо"

любое предложение, где я сделал ошибку в обращении?

на основе предложения mjn я удалил кодировку Mime и изменил url для тестирования в обоих кодах. Запрос из кода python на сервере httpbin есть:

{'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 ответов


ваш код 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;