Cita:
Empezado por Toñico
Hola a todos.
Antes que nada pido disculpas si cometo algún error ya que es mi primer mensaje en este foro.
Necesito vuestra ayuda porque estoy bloqueado.
Estoy intentando enviar a Bizcaia un fichero LROE 240 y para ello estoy utilizando Delphi 10.3 Rio y los componentes Indy HTTP y TIdSSLIOHandlerSocketOpenSSL.
El fichero que estoy enviando es un gzip que contiene el xml según la documentación.
|
Esta es mi forma de hacerlo con INDY pero en Delphi 2007, tampoco creo que varié mucho.
"cuerpo" es el cuerpo del envío, previamente convertido ya a GZIP.
"data" son los datos de la empresa a pasar en JSON.
"datosCertificado" no es más que un "record" con los datos que necesito del certificado.
Observa que no envío "content-length" en la cabecera, lo quité porque si lo mandaba, daba error.
Espero que te sirva para encontrar el problema.
Código:
function IndyPostBatuz(cuerpo: TMemoryStream; data: string; datosCertificado: TDatosCertificado): IXMLDocument;
var IdHTTP: TIdHTTP;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
rGetCertificado: TGetCertificado;
sRespuesta, slXML: TStringList;
msRespuesta: TMemoryStream;
sXML, sTipo, sCodigo, sMensaje: string;
begin
rGetCertificado := TGetCertificado.Create;
IdHTTP := TIdHTTP.Create(nil);
result := TXMLDocument.Create(nil);
try
// Configuramos la cabecera específica para Bizkaia
IdHTTP.Request.CustomHeaders.AddValue('Accept-Encoding', 'gzip');
IdHTTP.Request.CustomHeaders.AddValue('Content-Encoding', 'gzip');
//IdHTTP.Request.CustomHeaders.AddValue('Content-Length', IntToStr(cuerpo.Size)); // Finalmente, este dato no es necesario mandarlo, aparte de que si lo mandamos, da error
IdHTTP.Request.CustomHeaders.AddValue('Content-Type', 'application/octet-stream');
IdHTTP.Request.CustomHeaders.AddValue('eus-bizkaia-n3-version', '1.0');
IdHTTP.Request.CustomHeaders.AddValue('eus-bizkaia-n3-content-type', 'application/xml');
IdHTTP.Request.CustomHeaders.AddValue('eus-bizkaia-n3-data', data);
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
LHandler.sslOptions.Method := sslvTLSv1_2;
LHandler.sslOptions.SSLVersions := [sslvTLSv1_2];
LHandler.SSLOptions.CertFile := rDatosCertificado.RutaCertificado; // Certificado de dispositivo a usar
LHandler.SSLOptions.KeyFile := rDatosCertificado.RutaCertificado; // Certificado de dispositivo a usar (el mismo que cerfile)
LHandler.OnGetPassword := rGetCertificado.hServidorGetPassword; // Cuando se solicite la clave, el evento se encarga de aportarla
IdHTTP.IOHandler := LHandler;
sRespuesta := TStringList.Create; // La respuesta la recogemos en un stringlist;
msRespuesta := TMemoryStream.Create; // Stream que va a recoger el contenido en gzip. Desgraciadamente, Indy no tiene un Post en el que tanto petición como respuesta puedan ser Stream.
try
sRespuesta.Append(IdHTTP.Post(xrTicketbai.URL, cuerpo, IndyTextEncoding_UTF8)); // Enviamos la petición y la recogemos en un StringList;
except
on E:Exception do
begin
ShowMessage(E.message);
end;
end;
sTipo := idHTTP.Response.RawHeaders.Values['eus-bizkaia-n3-tipo-respuesta']; // Tipo de Respuesta. Si todo ha ido bien, es "Correcto"
sCodigo := idHTTP.Response.RawHeaders.Values['eus-bizkaia-n3-codigo-respuesta']; // Si sTipo no es "Correcto" entonce viene el código de error
sMensaje := idHTTP.Response.RawHeaders.Values['eus-bizkaia-n3-mensaje-respuesta']; // y el mensaje de error correspondiente
sIdentificativoBatuz := idHTTP.Response.RawHeaders.Values['eus-bizkaia-n3-identificativo']; // Aquí recogemos el identificativo, que viene en la cabecera de la respuesta
if sCodigo <> '' then
begin
ShowMessage('Tipo de respuesta: '+sTipo+#13#10+
'Codigo de respuesta: '+sCodigo+#13#10+
'Mensaje de respuesta: '+sMensaje);
end;
sRespuesta.SaveToStream(msRespuesta); // Grabamos la respuesta en un Stream de memoria.
if msRespuesta.Size > 0 then
begin
msRespuesta.Position := 0; // Importante posicionarse en 0, para que se pueda descomprimir correctamente
sXML := gZipToxmlModeloStream(msRespuesta); // Descomprimimos el stream de la respuesta en un string
try
result.Active := False;
result.XML.Clear;
result.XML.Text := LimpiaRespuesta(sXML); // Pasamos el string de la respuesta a un txmldocument
finally
FreeAndNil(msRespuesta);
end;
end;
finally
LHandler.Free;
end;
finally
IdHTTP.Disconnect;
IdHTTP.Free;
end;
end;