Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.09.12;
Скачать: [xml.tar.bz2];

Вниз

Обмен сообщениями в формате XML по протоколу HTTPS   Найти похожие ветки 

 
Igor_VM   (2010-05-12 16:19) [0]

Добрый день, возникла необходимость в реализации программы для отправки xml-сообщений (и приёма ответа) по протоколу https через интернет. Предполагается, что взаимодействие происходит посредством вызова методов интерфейса, реализованного в виде Web-сервиса. Для защищенного обмена данными между web-сервисом и предполаемым ПО используется протокол SSL, который обеспечивает аутентификацию web-сервера и аутентификацию клиента (посредством клиентских SSL-сертификатов), а так же шифрование передаваемых данных.
Также из описания:
Доступ к web-сервису осуществляется по протоколам: SOAP 1.1, SOAP 1.2, каждый из которых в качестве базового транспортного уровня использует HTTPS.
Взаимодействие с Web-сервисом http-входа описано согласно спецификации WSDL. В SOAP пакетах должна применяться кодировка UTF-8.
Интерфейс http-входа поддерживает один метод Transaction. Методу передается XML, содержащий элемент ... с атрибутом ... и т.д.

Т.е. сам веб-сервис уже функционирует. Моя проблема это отправлять туда xml-сообщения с помощью модуля, которые предстоит написать.

Просьба кто сталкивался с подобными разработками поделиться соображениями, с чего начать, какие компоненты использовать и др. информацию. Заранее спасибо.


 
Плохиш ©   (2010-05-12 16:27) [1]


> Просьба кто сталкивался с подобными разработками поделиться
> соображениями, с чего начать

С чтения "Developer guide" раздел про разработку web-services.


 
Dennis I. Komarov ©   (2010-05-12 17:44) [2]


> Плохиш ©   (12.05.10 16:27) [1]

Дык, он вроде как уже фунцикулирует...


> Igor_VM   (12.05.10 16:19)  

ИМХО начать с изучения транспорта, т.е. HTTP, SSL, HTTPS


 
Медвежонок Пятачок ©   (2010-05-12 17:50) [3]

ИМХО начать с изучения транспорта

А может тогда уж начать с изучения что такое электрический ток и как он течет по проводам?

:)

PS
посетить страницу описания сервиса.
взять шаблон xml запроса.
заполнить его данными.
создать экземпляр xmlhttprequest"a
выполнить send, получить и разобрать респонс.


 
Igor_VM   (2010-05-12 18:04) [4]

А можно с этого места по-подробнее:
"...создать экземпляр xmlhttprequest"a
выполнить send, получить и разобрать респонс" ? :) Шаблон xml-запроса у меня есть и заполнить данными не проблема.


 
Медвежонок Пятачок ©   (2010-05-12 18:15) [5]

uses MSXML2_TLB;
....

var xmlhttp : IXMLHTTPRequest;
   xResp   : IXMLDOMDOcument2;  
begin
xmlhttp := CoXMLHTTP.Create;
xmlhttp.open("POST",<WEB_SERVICE_URL>,False,EmptyParam,EmptyParam);
//опционально изменяем хедер если сервису оно надо
//xmlhttp.setRequestHeader(<field_name>,<field_value>);
xmlhttp.send(<XML_REQUEST_BODY>);
xResp := CoDomDocument.Create;
xResp.async := false;
if xResp.LoadXml(xmlhttp.responseText) then  
 ShowMessage("вуаля"#13#10 + xResp.xml);
end;


 
Плохиш ©   (2010-05-12 23:21) [6]


> Dennis I. Komarov ©   (12.05.10 17:44) [2]
>
>
> > Плохиш ©   (12.05.10 16:27) [1]
>
> Дык, он вроде как уже фунцикулирует...

Вообще-то там описано и создание клиентов, да и совсем удивительная вещь, для некоторых, как импортировать в свой проект wsdl.
Но потратить полчаса на беглый просмотр не по пацански, интересней часами на форуме сидеть, может и задача сама рассосётся...


 
Igor_VM   (2010-06-01 10:48) [7]

Добрый день, пока возникает except на отправке xmlhttp.send(<XML_REQUEST_BODY>); - "системная ошибка -2146697208". Предполагаю, что из-за того, что не подгружен файл сертификата (*.pfx). Подскажите, плз, как его использовать? Спасибо.


 
Palladin ©   (2010-06-01 12:11) [8]

правой кнопкой в проводнике его использовать...

...эти люди, ЧП, пишут такие серьезные вещи, к которым их и на километр подпускать нельзя...


 
Медвежонок Пятачок ©   (2010-06-01 12:15) [9]

Предполагаю, что из-за того, что не подгружен файл сертификата (*.pfx).

Предполагаю, что это ошибочное предположение.
xmlhttp работает так же как и ие.
Для ие сертификат должен быть в системном хранилище и должен быть связан со своим приватным контейнером.
А связанным он может быть только будучи в системном хранилище.


 
Igor_VM   (2010-06-01 13:44) [10]

Сертификат подгружен через мастер сертификатов. Если указаний на его использование в коде не должно быть, то как определить что именно за системная ошибка?


 
Igor_VM   (2010-06-01 13:57) [11]

Если я отправляю xmlhttp.send(null); с пустыми параметрами, то получаю ответ. Видимо, сертификат ни при чём.


 
Медвежонок Пятачок ©   (2010-06-01 15:43) [12]

Ты: Предполагаю, что из-за того, что не подгружен файл сертификата (*.pfx).

Я : Предполагаю, что это ошибочное предположение.

Снова ты: Видимо, сертификат ни при чём.


 
Igor_VM   (2010-06-01 16:07) [13]

Да, спасибо. На пустой запрос приходит ответ "
<?xml version="1.0"?>
<...Server was unable to process request. ---> Root element is missing...".

На непустой системная ошибка. Код ниже:


var
  xmlhttp : IXMLHTTPRequest;
  xReq    : IXMLDOMDOcument;
  xResp   : IXMLDOMDOcument;
begin

 xReq := CoDomDocument.Create;
 xReq.async := false;
 xReq.LoadXML("C:\...\filename.xml");

 xmlhttp := CoXMLHTTP.Create;
 xmlhttp.open("POST","web_service_url",False,EmptyParam,EmptyParam);

 try
   xmlhttp.send(xReq);
//    xmlhttp.send(null);
  except
   ShowMessage("Err!");
 end;

 xResp := CoDomDocument.Create;
 xResp.async := false;

 if xResp.LoadXml(xmlhttp.responseText) then
   ShowMessage(xResp.xml);

 xmlhttp.abort;

end;


Как можно определить из-за чего появляется системная ошибка?


 
Медвежонок Пятачок ©   (2010-06-01 16:09) [14]

Root element is missing.....


 
Медвежонок Пятачок ©   (2010-06-01 16:25) [15]

xReq    : IXMLDOMDOcument;
....
xmlhttp.send(xReq);

Интересно, зачем посылать серверу экземпляр IXMLDOMDOcument?
Оно ему надо?


 
Igor_VM   (2010-06-02 14:43) [16]

Понял. Я по всякому пробовал - создавал XMLDocument  и отправлял:
xmlhttp.send(XMLDocument.XML.CommaText);
, а также прописывал в коде саму xml-ку внутри функции. Результат был такой же. А как корректно, есть какой-нить пример (на форуме я похожего не обнаружил)?


 
Медвежонок Пятачок ©   (2010-06-02 15:53) [17]

какой в задницу комматекст?

посылаемый контент должен остаться валидным xml документом.


 
Медвежонок Пятачок ©   (2010-06-02 15:54) [18]

xReq.xml и все.


 
Igor_VM   (2010-06-02 16:30) [19]

:) спасиб, теперь отправляется xmlhttp.readyState = 4, но статус 400, т.е. видимо ошибка загрузки документа, соответственно ответа не получаю.


 
Медвежонок Пятачок ©   (2010-06-02 16:48) [20]

0 - Unitialized
1 - Loading
2 - Loaded
3 - Interactive
4 - Complete


 
Медвежонок Пятачок ©   (2010-06-02 16:49) [21]

а что возвращено в statusText?


 
Igor_VM   (2010-06-02 17:04) [22]

Bad Request


 
Медвежонок Пятачок ©   (2010-06-02 17:08) [23]

значит серверу не нравится твой запрос. он может быть валидным xml, но не соответсвовать формату. либо он и валидный и соответствует, но послан не туда куда надо


 
Igor_VM   (2010-06-02 18:08) [24]

Я узнавал, что видят в логах в моих запросах - как оказалось пустые запросы. Можно ли проверить корректность xml-загрузки таким образом?:
procedure TMainForm.Button1Click(Sender: TObject);
var
  xReq    : IXMLDOMDOcument;
begin
  xReq := CoDomDocument.Create;
  xReq.loadxml("C:\My_Docs\Tasks\Projects\Web-Client\XML\auth.xml");
  MemoXML.Text := xReq.Text;
end;

Если да, то в мемо действительно пустое. Из-за чего это может быть?


 
Медвежонок Пятачок ©   (2010-06-02 18:09) [25]

Ошибка здесь
xReq.loadxml("C:\My_Docs\Tasks\Projects\Web-Client\XML\auth.xml");


 
Медвежонок Пятачок ©   (2010-06-02 18:25) [26]

>Из-за чего это может быть?

Вот смотри, я у тебя тоже спрошу:

Имею вот такой код:
ShowMessage("c:\myfolder\myfile.txt");

При этом ожидаю, что на экране выскочит сообщение с текстом, который содержится внутри "c:\myfolder\myfile.txt".

но вместо этого почему-то мне выводится мессадж с текстом (буквально таким) :

"c:\myfolder\myfile.txt"

Из за чего это может быть?


 
АВМ   (2010-06-03 09:29) [27]

Надо так:
xReq.load("C:\My_Docs\Tasks\Projects\Web-Client\XML\auth.xml");

А в xReq.loadxml в качестве параметра надо подсовывать содержимое xml-файла


 
Igor_VM   (2010-06-03 09:54) [28]

Я понял, но системная ошибка всё-равно осталась ("системная ошибка -2146697208"). Эту xml я пробывал открывать через xml-notepad, IE и др. - никаких проблем. Кто-то в курсе что это за ошибка?


 
Медвежонок Пятачок ©   (2010-06-03 10:04) [29]

покажи пролог из C:\My_Docs\Tasks\Projects\Web-Client\XML\auth.xml

какая там кодировка?


 
Igor_VM   (2010-06-03 10:08) [30]

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http:/..." xmlns:xsi="http:/..." xmlns:xsd="http:/...">
 <soap:Body>
   <Transaction xmlns="https:/.../">
     <HostRequest operation="auth">
       <termType>2</termType>
       <termID>00012200</termID>
       <reqNum>8980</reqNum>
       <reqDateTime>20100531163000</reqDateTime>
       <merchantCode>MTS</merchantCode>
       <reqID>9160000000</reqID>
       <sum>1</sum>
       <currency>810</currency>
     </HostRequest>
   </Transaction>
 </soap:Body>
</soap:Envelope>


 
Медвежонок Пятачок ©   (2010-06-03 10:14) [31]

тогда все нормально.

было подозрение что там windows-1251 + данные в 1251
в этом случае, так как xmlhttp не в курсе, что посылается xml, рассматривает весь контент как просто строку.
он переколбасит все что в 1251 в утф, а в прологе останется "windows-1251", так как эта строка в латинице.
в результате на сервер придет ерунда.

но здесь очевидно не тот случай.
надо искать 10 отличий между тем что описано в сервисе и тем что ему посылается


 
Плохиш ©   (2010-06-03 12:15) [32]

Хм, т.е. попросить делфи импорировать wsdl так и не догадались? Зачем они нужны лёгкие пути...


 
Igor_VM   (2010-06-03 12:45) [33]


> попросить делфи импорировать wsdl так и не догадались?

Если можно подробнее, был бы оч признателен?


 
Медвежонок Пятачок ©   (2010-06-03 13:13) [34]

у него же транспорт другой.
а пойдешь стандартным и легким - встанет вопрос как прикрутить ssl

хотя импортнуть все же стоит. для посмотреть.


 
Плохиш ©   (2010-06-03 23:53) [35]


> Igor_VM   (03.06.10 12:45) [33]
>
>
> > попросить делфи импорировать wsdl так и не догадались?
>
>
> Если можно подробнее, был бы оч признателен?

Поподробней было в [1]

> Медвежонок Пятачок ©   (03.06.10 13:13) [34]
>
> у него же транспорт другой.
> а пойдешь стандартным и легким - встанет вопрос как прикрутить
> ssl

А что там за проблемы?


 
Igor_VM   (2010-06-04 11:00) [36]

Подскажите почему не компилится получившейся после импорта wsdl модуль, ругается на "    FtermType: termType;" - [Error] gateway.pas(49): Undeclared identifier: "termType"? Подскажите как исправить ошибку? Код:

// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : https:/.../gateway.wsdl
// Encoding : utf-8
// Version  : 1.0
// (03.06.2010 16:04:24 - 1.33.2.5)
// ************************************************************************ //

unit gateway;

interface

uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;

type

 // ************************************************************************ //
 // The following types, referred to in the WSDL document are not being represented
 // in this file. They are either aliases[@] of other types represented or were referred
 // to but never[!] declared in the document. The types from the latter category
 // typically map to predefined/known XML or Borland types; however, they could also
 // indicate incorrect WSDL documents that failed to declare or import a schema type.
 // ************************************************************************ //
 // !:termType        - "https:/../"
 // !:termID          - "https:/../"
 // !:reqNum          - "https:/../"
 // !:reqDateTime     - "https:/../"
 // !:merchantCode    - "https:/../"
 // !:reqID           - "https:/../"
 // !:sum             - "https:/../"
 // !:currency        - "https:/../"
 // !:merchantData    - "https:/../"
 // !:paymentName     - "https:/../"
 // !:paymentID       - "https:/../"
 // !:respCode        - "https:/../"
 // !:confirm         - "https:/../"

 HostRequestType      = class;                 { "https:/../" }
 HostResponseType     = class;                 { "https:/../" }

 // ************************************************************************ //
 // Namespace : https:/../
 // ************************************************************************ //
 HostRequestType = class(TRemotable)
 private
   FtermType: termType;
   FtermID: termID;
   FreqNum: reqNum;
   FreqDateTime: reqDateTime;
   FmerchantCode: merchantCode;
   FreqID: reqID;
   Fsum: sum;
   Fcurrency: currency;
   FmerchantData: merchantData;
   FpaymentName: paymentName;
   FpaymentID: paymentID;
 published
   property termType: termType read FtermType write FtermType;
   property termID: termID read FtermID write FtermID;
   property reqNum: reqNum read FreqNum write FreqNum;
   property reqDateTime: reqDateTime read FreqDateTime write FreqDateTime;
   property merchantCode: merchantCode read FmerchantCode write FmerchantCode;
   property reqID: reqID read FreqID write FreqID;
   property sum: sum read Fsum write Fsum;
   property currency: currency read Fcurrency write Fcurrency;
   property merchantData: merchantData read FmerchantData write FmerchantData;
   property paymentName: paymentName read FpaymentName write FpaymentName;
   property paymentID: paymentID read FpaymentID write FpaymentID;
 end;

 // ************************************************************************ //
 // Namespace : https:/../
 // ************************************************************************ //
 HostResponseType = class(TRemotable)
 private
   FtermType: termType;
   FtermID: termID;
   FreqNum: reqNum;
   FreqDateTime: reqDateTime;
   FmerchantCode: merchantCode;
   FrespCode: respCode;
   Fconfirm: confirm;
   FmerchantData: merchantData;
 published
   property termType: termType read FtermType write FtermType;
   property termID: termID read FtermID write FtermID;
   property reqNum: reqNum read FreqNum write FreqNum;
   property reqDateTime: reqDateTime read FreqDateTime write FreqDateTime;
   property merchantCode: merchantCode read FmerchantCode write FmerchantCode;
   property respCode: respCode read FrespCode write FrespCode;
   property confirm: confirm read Fconfirm write Fconfirm;
   property merchantData: merchantData read FmerchantData write FmerchantData;
 end;

 // ************************************************************************ //
 // Namespace : https:/../
 // soapAction: https:/../
 // transport : https:/../
 // binding   : Gateway_x0020_ServiceSoap
 // service   : Gateway_x0020_Service
 // port      : Gateway_x0020_ServiceSoap
 // URL       : https:/...
 // ************************************************************************ //
 Gateway_x0020_ServiceSoap = interface(IInvokable)
 ["{E7586329-F434-629E-D77C-F83236C6A60F}"]
   function  Transaction(const HostRequest: HostRequestType): HostResponseType; stdcall;
 end;

function Gateway_x0020_ServiceSoap(UseWSDL: Boolean=System.False; Addr: string=""; HTTPRIO: THTTPRIO = nil): Gateway_x0020_ServiceSoap;

implementation

function GetGateway_x0020_ServiceSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): Gateway_x0020_ServiceSoap;
const
 defWSDL = "https:/..";
 defURL  = "https:/..";
 defSvc  = "Gateway_x0020_Service";
 defPrt  = "Gateway_x0020_ServiceSoap";
var
 RIO: THTTPRIO;
begin
 Result := nil;
 if (Addr = "") then
 begin
   if UseWSDL then
     Addr := defWSDL
   else
     Addr := defURL;
 end;
 if HTTPRIO = nil then
   RIO := THTTPRIO.Create(nil)
 else
   RIO := HTTPRIO;
 try
   Result := (RIO as Gateway_x0020_ServiceSoap);
   if UseWSDL then
   begin
     RIO.WSDLLocation := Addr;
     RIO.Service := defSvc;
     RIO.Port := defPrt;
   end else
     RIO.URL := Addr;
 finally
   if (Result = nil) and (HTTPRIO = nil) then
     RIO.Free;
 end;
end;

initialization
 InvRegistry.RegisterInterface(TypeInfo(Gateway_x0020_ServiceSoap), "https:/.../", "utf-8");
 InvRegistry.RegisterDefaultSOAPAction(TypeInfo(Gateway_x0020_ServiceSoap), "https:/...");
 RemClassRegistry.RegisterXSClass(HostRequestType, "https:/.../", "HostRequestType");
 RemClassRegistry.RegisterXSClass(HostResponseType, "https:/.../", "HostResponseType");

end.


 
Медвежонок Пятачок ©   (2010-06-04 11:05) [37]

читай комент к полученному модулю

The following types ....


 
Плохиш ©   (2010-06-04 13:57) [38]


> Igor_VM   (04.06.10 11:00) [36]
>
> Подскажите почему не компилится получившейся после импорта
> wsdl модуль, ругается на "    FtermType: termType;" - [Error]
> gateway.pas(49): Undeclared identifier: "termType"? Подскажите
> как исправить ошибку?

Или они опубликованы в другом интерфейсе этой страницы или описывать их надо ручками.


 
Igor_VM   (2010-06-04 15:56) [39]

Извиняюсь за навязчивость, а как использовать сертификаты - теперь ругается "A certificate is required to complete client authentification - URL:https:/...". Сами сертификаты были ранее подгружены.


 
Igor_VM   (2010-06-09 12:50) [40]

Последний вопрос всё ещё актуален - подскажите как использовать сертификаты?


 
Igor_VM   (2010-06-21 12:50) [41]

Подскажите правильно ли я понял, что нужно использовать IdHTTPRio? Если так, то я скачал целиком indy10 и начал последовательно подкладывать в каталог с приложением те pas-файлы, на которые ругается/ссылается при компиляции. Но сейчас не могу скомпилить проект полностью, ругается на один из модулей indy:
 [Error] IdStackConsts.pas(124): Identifier expected but "TYPE" found
 [Error] IdStackConsts.pas(137): Undeclared identifier: "TSocket"
 [Error] IdStackConsts.pas(246): Undeclared identifier: "PF_INET"
 [Error] IdStackConsts.pas(247): Undeclared identifier: "PF_INET6"
 [Error] IdStackConsts.pas(276): Identifier expected but "CONST" found
 [Error] IdStackConsts.pas(299): Undeclared identifier: "TIdSocketType"
 [Error] IdStackConsts.pas(300): Undeclared identifier: "SOCK_STREAM"
 [Error] IdStackConsts.pas(301): Undeclared identifier: "SOCK_DGRAM"
 [Error] IdStackConsts.pas(302): Undeclared identifier: "SOCK_RAW"
 [Error] IdStackConsts.pas(304): Undeclared identifier: "SOCK_RDM"
 [Error] IdStackConsts.pas(306): Undeclared identifier: "SOCK_SEQPACKET"
 [Error] IdStackConsts.pas(325): Undeclared identifier: "IPPROTO_ICMP"
 [Error] IdStackConsts.pas(326): Undeclared identifier: "IPPROTO_ICMPV6"
 [Error] IdStackConsts.pas(328): Undeclared identifier: "IPPROTO_IDP"
 [Error] IdStackConsts.pas(330): Undeclared identifier: "IPPROTO_IGMP"
 [Error] IdStackConsts.pas(332): Undeclared identifier: "IPPROTO_IP"
 [Error] IdStackConsts.pas(333): Undeclared identifier: "IPPROTO_IPV6"
 [Error] IdStackConsts.pas(335): Undeclared identifier: "IPPROTO_PUP"
 [Error] IdStackConsts.pas(336): Undeclared identifier: "IPPROTO_RAW"
 [Error] IdStackConsts.pas(337): Undeclared identifier: "IPPROTO_TCP"
 [Error] IdStackConsts.pas(338): Undeclared identifier: "IPPROTO_UDP"
 [Error] IdStackConsts.pas(339): Undeclared identifier: "IPPROTO_MAX"
 [Error] IdStackConsts.pas(365): Undeclared identifier: "SOL_SOCKET"
 [Error] IdStackConsts.pas(380): Undeclared identifier: "SO_BROADCAST"
 [Error] IdStackConsts.pas(381): Undeclared identifier: "SO_DEBUG"
 [Error] IdStackConsts.pas(382): Undeclared identifier: "SO_DONTROUTE"
 [Error] IdStackConsts.pas(383): Undeclared identifier: "SO_KEEPALIVE"
 [Error] IdStackConsts.pas(384): Undeclared identifier: "SO_LINGER"
 [Error] IdStackConsts.pas(385): Undeclared identifier: "SO_OOBINLINE"
 [Error] IdStackConsts.pas(386): Undeclared identifier: "SO_RCVBUF"
 [Error] IdStackConsts.pas(387): Undeclared identifier: "SO_REUSEADDR"
 [Error] IdStackConsts.pas(388): Undeclared identifier: "SO_SNDBUF"
 [Error] IdStackConsts.pas(389): Undeclared identifier: "SO_TYPE"
 [Error] IdStackConsts.pas(441): Undeclared identifier: "SO_RCVTIMEO"
 [Error] IdStackConsts.pas(442): Undeclared identifier: "SO_SNDTIMEO"
 [Error] IdStackConsts.pas(450): Undeclared identifier: "IP_TTL"
 [Error] IdStackConsts.pas(461): Undeclared identifier: "INADDR_ANY"
 [Error] IdStackConsts.pas(463): Undeclared identifier: "INADDR_NONE"
 [Error] IdStackConsts.pas(472): Undeclared identifier: "TCP_NODELAY"
 [Error] IdStackConsts.pas(473): Undeclared identifier: "INVALID_SOCKET"
 [Error] IdStackConsts.pas(474): Undeclared identifier: "SOCKET_ERROR"
 [Fatal Error] IdStack.pas(143): Could not compile used unit "IdStackConsts.pas"

Подскажите правильно ли я делаю и как исправить ошибку? Спасибо.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.09.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.6 MB
Время: 0.005 c
2-1276607756
ixen
2010-06-15 17:15
2010.09.12
Как закрыть программу в окне авторизации?


15-1276633802
Юрий
2010-06-16 00:30
2010.09.12
С днем рождения ! 16 июня 2010 среда


2-1276374865
AKE
2010-06-13 00:34
2010.09.12
Как нарисовать закрашенный треугольник?


2-1276668024
DROWSY
2010-06-16 10:00
2010.09.12
Access violation at address 00356273 in module designide60.bpl .


15-1276723981
KilkennyCat
2010-06-17 01:33
2010.09.12
Грамотный перевод AutoExpand?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский