Lazarus

Other Languages => Spanish => Topic started by: FOV_2001 on April 16, 2021, 05:32:56 pm

Title: Consumir Web Service Seguro via HTTPS
Post by: FOV_2001 on April 16, 2021, 05:32:56 pm
Hola a todos,
Luego de semanas de escribir, probar y buscar, llego a un callejón sin salida y espero puedan ayudarme.
Desde hace mucho tengo una Librería desarrollada en Delphi funcionando correctamente, habiendo importado un WSDL, y consumiéndolo vía https.
Mi problema, surge en la migración a la misma librería en Lazarus, donde no consigo que el Web Service me responda, usando exactamente la misma configuración, la cual intentaré detallar

Code: Pascal  [Select][+][-]
  1. function TDM_S2S.Registrar_Cliente(var Parametro: ClientRegisterRQ_Type): TS2S_Registrar_Cliente_Rec;
  2. var
  3.  CCDataTest : ServicePortType;
  4.  LResultado : ClientRegisterRS;
  5.  
  6. begin
  7.   With Mod_Auxiliar do
  8.     if (Activar_Logs and (Log_Level >= L_Verbose)) then
  9.       begin
  10.         Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - URL : ' + UnicodeString(G_Server_URL));
  11.       end;
  12.  
  13.   Poll.Enabled := False; // Paro Timer para no pisar respuestas
  14.  
  15.   if Respuesta_Pendiente then // Solo a Efectos de evitar supoerposiciones de comandos
  16.     begin
  17.       With Mod_Auxiliar do
  18.         if (Activar_Logs and (Log_Level >= L_Debug)) then
  19.           begin
  20.             Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Esperando Respuesta Pendiente');
  21.           end;
  22.  
  23.       Timeout_Registro     := False;
  24.       TO_Registro.Interval := 5000;
  25.       TO_Registro.Enabled  := True;
  26.  
  27.       Repeat
  28.         Application.HandleMessage;
  29.         Demora(25);
  30.       Until ((Not Respuesta_Pendiente) OR (Timeout_Registro));
  31.  
  32.       TO_Registro.Enabled := False;
  33.     end;
  34.  
  35.   Respuesta_Pendiente  := True; // Ahora lo Congelo PAra mi
  36.  
  37.   CCDataTest := wst_CreateInstance_ServicePortType('SOAP:', 'HTTP:',G_Server_URL);
  38.  
  39.   // Revisamos Parametros
  40.     if Parametro.LocationID = '' then
  41.       begin
  42.         FDato_Valido  := True;
  43.         FResultado := S2S_ANS_Location_ID_Invalido;
  44.         LResultado := ClientRegisterRS.Create;
  45.         LResultado.ResponseDesc := 'Location_ID Invalido';
  46.         LResultado.ResponseCode := S2S_ANS_Location_ID_Invalido;
  47.         LResultado.SeqNum       := 0;
  48.  
  49.         With Mod_Auxiliar do
  50.           if (Activar_Logs and (Log_Level >= L_Info)) then
  51.             begin
  52.               Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Location ID - INVALIDO');
  53.             end;
  54.  
  55.         Result.ResponseCode := LResultado.ResponseCode;
  56.         Result.ResponseDesc := LResultado.ResponseDesc;
  57.         Result.SeqNum       := LResultado.SeqNum;
  58.         LResultado.Free;
  59.         FRe_Enter := False;
  60.         RX_TO.Enabled        := False;
  61.         Respuesta_Pendiente  := False; // Ahora lo libero
  62.         Poll.Enabled         := True; // Largo Timer
  63.         Exit;
  64.       end;
  65.  
  66.     if Parametro.SeqNumRQ = 0 then
  67.       begin
  68.         FDato_Valido  := True;
  69.         LResultado := ClientRegisterRS.Create;
  70.  
  71.         LResultado.ResponseCode := S2S_ANS_SEQ_NUM_Invalido;
  72.         LResultado.ResponseDesc := 'Secuence Number Invalido';
  73.         LResultado.SeqNum       := 0;
  74.         With Mod_Auxiliar do
  75.           if (Activar_Logs and (Log_Level >= L_Info)) then
  76.             begin
  77.               Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Seq_Num - INVALIDO');
  78.             end;
  79.  
  80.         Result.ResponseCode := LResultado.ResponseCode;
  81.         Result.ResponseDesc := LResultado.ResponseDesc;
  82.         Result.SeqNum       := LResultado.SeqNum;
  83.         LResultado.Free;
  84.         FRe_Enter := False;
  85.         RX_TO.Enabled        := False;
  86.         Respuesta_Pendiente  := False; // Ahora lo libero
  87.         Poll.Enabled         := True; // Largo Timer
  88.         Exit;
  89.       end;
  90.  
  91.     Fregistrando := True;
  92.  
  93.     With Mod_Auxiliar do
  94.       if (Activar_Logs and (Log_Level >= L_Verbose)) then
  95.         begin
  96.           Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Parametros de Conexión OK');
  97.         end;
  98.  
  99.     LResultado := ClientRegisterRS.Create;
  100.  
  101.     try
  102.       LResultado := CCDataTest.ClientRegisterRQ(Parametro);
  103.     except
  104.        on E : Exception do
  105.        begin
  106.          LResultado.ResponseDesc := UnicodeString(E.Message);
  107.          LResultado.ResponseCode := S2S_COMM_ERROR;
  108.          LResultado.SeqNum       := 0;
  109.          FStatus := S2S_COMM_ERROR;
  110.          FRe_Enter := False;
  111.          FDato_Valido  := True;
  112.          With Mod_Auxiliar do
  113.            if (Activar_Logs and (Log_Level >= L_Info)) then
  114.              begin
  115.                Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Exception : ' + UnicodeString(E.Message));
  116.              end;
  117.          Respuesta_Pendiente := False;
  118.  
  119.          Result.ResponseCode := LResultado.ResponseCode;
  120.          Result.ResponseDesc := LResultado.ResponseDesc;
  121.          Result.SeqNum       := LResultado.SeqNum;
  122.          LResultado.Free;
  123.          exit;
  124.        end;
  125.     end;
  126.  
  127.     Respuesta_Pendiente := False;
  128.     FRegistrando        := False;
  129.     RX_TO.Enabled       := False;
  130.  
  131.     Result.ResponseCode := LResultado.ResponseCode;
  132.     Result.ResponseDesc := LResultado.ResponseDesc;
  133.     Result.SeqNum       := LResultado.SeqNum;
  134.     LResultado.Free;
  135.  
  136.     FDato_Valido  := True;
  137.     FResultado    := Result.ResponseCode;
  138.     FRe_Enter     := False;
  139.  
  140.     With Mod_Auxiliar do
  141.       if (Activar_Logs and (Log_Level >= L_Debug)) then
  142.         begin
  143.           Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Response Code : ' + UnicodeString(IntToStr(Result.ResponseCode)));
  144.           Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - Response Desc : ' + Result.ResponseDesc);
  145.         end;
  146.  
  147.     if (Result.ResponseCode = 0) AND (FResultado = 0) then
  148.       begin
  149.         FStatus := S2S_REGISTRADO;
  150.         Equipo.Seq_Num := Result.SeqNum;
  151.         With Mod_Auxiliar do
  152.           if (Activar_Logs and (Log_Level >= L_Debug)) then
  153.             begin
  154.               Registro_Log(Archivo_Logs, Prefix,'Registrar_Cliente - REGISTRADO OK');
  155.             end;
  156.       end
  157.     else
  158.       if FStatus > 0 then
  159.         begin
  160.           FStatus := S2S_DESREGISTRADO;
  161.           With Mod_Auxiliar do
  162.             if (Activar_Logs and (Log_Level >= L_Info)) then
  163.               begin
  164.                 Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - DESREGISTRADO');
  165.                 Registro_Log(Archivo_Logs,Prefix,'Registrar_Cliente - ResponseCode : ' + UnicodeString(IntToStr(FResultado)));
  166.               end;
  167.         end;
  168.  
  169.     Poll.Enabled := True;  // Habilito Timer de Polling nuevamente
  170.     Respuesta_Pendiente  := False;
  171. end;
  172.  

Cuando analizo los logs, siempre me encuentro con esta EXCEPCION

[vie 16 abr, 11:32:27.822] : - S2S - Version de DLL    : 4.0.153.2661
[vie 16 abr, 11:32:27.826] : - S2S - Plataforma        : i386 - Win32
[vie 16 abr, 11:32:27.827] : - S2S - Fecha Compilacion : 2021/04/15 - 16:24:48
[vie 16 abr, 11:32:27.828] : - S2S - Datos de Conexion : https:////XXXXXXXX:8443/YYYYYYYYY/Service
[vie 16 abr, 11:32:27.828] : - S2S - Registrando Cliente
[vie 16 abr, 11:32:27.830] : - S2S - Registrar_Cliente - Exception : HTTP Request to https://XXXXXXXX:8443/YYYYYYYYY/Service -> failed.

Insisto en que con  la otra libreria en Delphi, la respuesta es correcta en tiempo y forma.

Por otro lado, el Servicio fue importado via la utilidad Web Services Tool Kit.

Mi sospecha está orientada a esta instrucción, pero la verdad ya he probado de todo y sigo sin poder conectarme.

  CCDataTest := wst_CreateInstance_ServicePortType('SOAP:', 'HTTP:',G_Server_URL);

Donde:
  G_Server_URL = "https:////XXXXXXXX:8443/YYYYYYYYY/Service";

Como controladores de Protocolo he usado, en ambos casos sin éxito:
     indy_http_protocol y  fpc_http_protocol

Finalmente, un último comentario, el HTTP funciona SIN NINGÚN INCONVENIENTE.

Es lo único que me imposibilita la migración de plataforma, con lo cual toda ayuda o comentario seria de suma utilidad.

Agradezco desde ya el tiempo.

Title: Re: Consumir Web Service Seguro via HTTPS
Post by: GAN on April 17, 2021, 05:37:48 am
Hola, no soy especialista en el tema, pero envío archivos vía FTP sin problemas usando las unidades ftpsend, blcksock de Synapse.
En otro programa, para leer páginas webs utilizo las unidades fphttpclient (RTL) y openssl (Synapse).
Synapse comenzó con Delphi y hace rato es compatible con Free Pascal.

Saludos.
Title: Re: Consumir Web Service Seguro via HTTPS
Post by: FOV_2001 on April 19, 2021, 04:35:37 pm
Hola GAN, gracias por tu tiempo.

Lamentablemente el WEB SERVICE lado Server, no lo hice yo, y no tengo mas remedio que consumirlo. No puedo usar otro metodo. y Via Synapse, estoy bastante lego. Asi que estoy tratando de seguir pasos mas o menos parecidos a los que uso en Delphi.

Como dije, mi experiencia viene de ahi, y funciona perfecto. Esto sin duda debe ser una tonteria, pero la verdad es que ya no se donde buscar.

De cualquier forma voy a investigar el tema.

Te agradezco nuevamente tu tiempo
Title: Re: Consumir Web Service Seguro via HTTPS
Post by: FOV_2001 on April 19, 2021, 05:49:49 pm
GAN buenas tardes,

Luego de seguir tu consejo, Synapse tiene su openSSL, y llego a otro callejón.

el OpenSSL lo tengo instalado pero al instanciar
      SYNAPSE_RegisterHTTP_Transport();

No encuentro como habilitar la etapa de encripcion y decirle que la use.

Sinb dua me has mostrado una idea a descubrir.

De cualquier manera, debido a lo basico de mi problema agradezco te hayas tomado el tiempo de darme una mano.

Seguiré buscando

GRACIAS
Title: Re: Consumir Web Service Seguro via HTTPS
Post by: GAN on April 19, 2021, 10:18:53 pm
Qué tal FOV_2001, sí te recomendé Synapse por ese tema OpenSSL además que era el que te faltaba probar.
En mi caso, el uso limitado que le doy y los pocos conocimientos que tengo en el tema, sé que la unidad debe estar presente, creo que la usa "internamente" Synapse, pero "creo", ahí hay que buscar documentación, no queda otra.

Algunos links:
Synapse How to: http://synapse.ararat.cz/doku.php/public:howto (http://synapse.ararat.cz/doku.php/public:howto)
Synapse TCP/IP client and server (foro): https://forum.lazarus.freepascal.org/index.php/topic,48677.0.html (https://forum.lazarus.freepascal.org/index.php/topic,48677.0.html)
Wiki Lazarus / Free Pascal: https://wiki.lazarus.freepascal.org/Synapse (https://wiki.lazarus.freepascal.org/Synapse)

Suerte!
Title: Re: Consumir Web Service Seguro via HTTPS
Post by: mosquito on June 10, 2021, 10:43:53 am
Quote
Lamentablemente el WEB SERVICE lado Server, no lo hice yo, y no tengo mas remedio que consumirlo. No puedo usar otro metodo. y Via Synapse, estoy bastante lego.

Hola FOV, aunque no hayas escrito el Server, supongo que sabrás su comportamiento (formato de la req y la res, headers, etc)

Para la REQUEST: En mi opinión lo más sencillo sería usar fpHttpClient (acepta casi todos los verbos http + TLS + no external libs + keep-alive + full control de los Headers en ambas direcciones).

Para parsear la RESPONSE: Sin recurrir a librerías externas de nuevo tienes un arsenal en la RTL, FCL. (json, xml, csv, raw, etc)

Sesiones Standard con fpHttpClient sin problemas.
Sesiones avanzadas (JWT,0Auth, etc) quizás aquí si hay que pensar si usar otra librería de networking o sólo la libreria JWT(gitHub) .
Crypto: en la RTL otro arsenal.

Si tienes urgencia en desplegar, mientras implementas todo esto, puedes colocar el ejecutable de CURL junto al programa y usar TProcess para capturar, con el añadido de poder escribir en el STDIN de CURL, lo cual ahorra mucho tiempo de formateo de la request (por ejemplo en un POST-JSON). (poco elegante pero muy potente)  8-)   
 
TinyPortal © 2005-2018