PDA

Ver la Versión Completa : post a web


oscarac
27-04-2023, 03:17:59
buenas tardes
mediante postman puedo logearme a esta pagina (me genera un token)

https://zona-api.aris.com.pe/v1/user/signin

en la zona del body (form-data) coloco las credenciales user y password y se conecta

como podria hacelo en delphi?

estuve intentando con indy http

procedure TForm5.Login(name: string; Pass: string);
var
Params: TStringList;
begin
Params := TStringList.Create;
try
Params.Add('user='+name);
Params.Add('pass='+pass);

Memo1.Text := IdHTTP1.Post('https://zona-api.aris.com.pe/v1/user/signin', Params);
finally
Params.Free;
end;
end;

pero me aparace un mensaje de iohandler value is not valid

me dan una mano?

porque luego de logearme debo enviar un archivo a otra direccion

Neftali [Germán.Estévez]
27-04-2023, 08:49:31
No comentas con qué versión de Delphi estás trabajando. Si es con una de las últimas versiones, mejor utilizar los componentes REST (RESTClient, RESTResponse y RESTRequest).
Si es así, utiliza RESTDebugger, la aplicación que viene con Delphi (similar a Postman, pero más sencilla). Si consigues conectarte con RESTDebugger, esta misma utilidad te genera los componentes configurados para que los pegues en tu aplicación y realizar la conexión.

Si estás utilizando una versión antigua, las Indy son una buena opción. Pero como estás conectando a un https, necesitas un componente adicional para gestionar la conexión segura (TIdSSLIOHandlerSocketOpenSSL).

Si buscas en los foros por TIdSSLIOHandlerSocketOpenSSL, encontrarás muchos hilos con código, donde puedes ver cómo se utiliza:
https://www.clubdelphi.com/foros/showpost.php?p=531364&postcount=6
https://www.clubdelphi.com/foros/showthread.php?t=92982

oscarac
27-04-2023, 14:48:11
hola buenos dias
gracias por responder, como siempre tú, un capo es estos temas
estuve revisando y si, el problema es el https:
incluso estuve haciendo unas pruebas en php con curl, pero tampoco funcionaba, y era actualizar el certificado del curl, y ya pudo funcionar

pero quiero hacerlo en delphi, por cierto uso la version xe7

colocaré mis avances y espero contar con tu ayuda, gracias

oscarac
27-04-2023, 21:05:46
encontré un ejemplo, pero me esta apareciendo un error indicando que las librerias no estan cargadas
"could not load SSL library", en la linea
IdHTTP1.Post('https://zona-api.aris.com.pe/v1/user/signin', S, M);

busque aqui
http://delphiaccess.com/foros/index.php/topic/4138-error-en-indy-10-could-not-load-ssl-library/

descargue las librerias las copie en la carpeta de la aplicacion y nada... sigue lo mismo


unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdMultipartFormData,IdSSLOpenSSL,
Vcl.StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP;

type
TForm1 = class(TForm)
IdHTTP1: TIdHTTP;
Button1: TButton;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var S: TStringList;
M: TStream;
lHTTP: TIdHTTP;
begin
S := TStringList.Create;
M := TMemoryStream.Create;
try
S.Values['user'] := 'usuario';
S.Values['password'] := 'clave';
lHTTP := TIdHTTP.Create;

IdHTTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdHTTP1.Request.ContentType := 'multipart/form-data';
IdHTTP1.Post('https://zona-api.aris.com.pe/v1/user/signin', S, M);
Memo1.Lines.Add(Format('Response Code: %d', [IdHTTP1.ResponseCode]));
Memo1.Lines.Add(Format('Response Text: %s', [IdHTTP1.ResponseText]));

M.Position := 0;
S.LoadFromStream(M);
Memo1.Lines.AddStrings(S);
finally
S.Free;
M.Free;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
begin
///
IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(self);
with idSSLIOHandlerSocketOpenSSL1 do
begin
SSLOptions.Method := sslvSSLv2;
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 0;
//host := '';
end;
IdHTTP1 := TIdHTTP.Create(Self);
with IdHTTP1 do
begin
IOHandler := IdSSLIOHandlerSocketOpenSSL1;
AllowCookies := True;
ProxyParams.BasicAuthentication := False;
ProxyParams.ProxyPort := 0;
Request.ContentLength := -1;
Request.ContentRangeEnd := 0;
Request.ContentRangeStart := 0;
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];
end;
end;

end.

Neftali [Germán.Estévez]
28-04-2023, 09:03:59
encontré un ejemplo, pero me esta apareciendo un error indicando que las librerias no estan cargadas
"could not load SSL library", en la linea
IdHTTP1.Post('https://zona-api.aris.com.pe/v1/user/signin', S, M);

descargue las librerias las copie en la carpeta de la aplicacion y nada... sigue lo mismo



Revisa que has descargado todos los ficheros necesarios.
También revisa que estás con la versión necesaria, la mayoría de estos problemas vienen por incompatibilidad entre versiones de 32/64 bits.

oscarac
28-04-2023, 15:29:30
Como siempre tenias la razon
en delphi agregue la plataforma de 64 bits y ya no me da el error de libreria

pero tengo un problema

cuando me conecto via POSTMAN, los datos del user y password los coloco en el body, como le indico a delhi en que "pestaña" (si lo igualo con postamn) colocar el user y password?

imagino que se debe parametrizar en la parte del create (segun mi ejemplo)
with idSSLIOHandlerSocketOpenSSL1 do
begin
SSLOptions.Method := sslvSSLv2;
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 0;
//host := '';
end;
IdHTTP1 := TIdHTTP.Create(Self);
with IdHTTP1 do
begin
IOHandler := IdSSLIOHandlerSocketOpenSSL1;
AllowCookies := True;
ProxyParams.BasicAuthentication := False;
ProxyParams.ProxyPort := 0;
Request.ContentLength := -1;
Request.ContentRangeEnd := 0;
Request.ContentRangeStart := 0;
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];

para que sirve esto?

SSLOptions.Method := sslvSSLv2;

veo que hay otras opciones sslvSSLv23 por ejemplo

oscarac
28-04-2023, 16:08:12
*ACTUALIZACION*

probé usando los componentes REST (en 64 bits)
use rest debugger copie los componentes y aparece el siguiente mensaje

1
{"success":true,"statusCode":200,"status":200,"data":{"mensaje":"Falta parametros requeridos","data":null,"status":400}}

sin embargo en postman aparecen estos

2
{"success":true,"statusCode":200,"status":200,"data":{"mensaje":"credenciales","data":{"tk":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2ODI2ODgyNTMsImlzcyI6ImN1Ym9yb2pvIiwibmJmIjoxNjgyNjg 4MjUzLCJleHAiOjE2ODc4NzIyNTMsImRhdGEiOnsiaWQiOjEwMDksIm5hbWUiOiJDb25jZXNpb25hcmlvIn19.gwl7llmglpMA57 F_s88XAz-gQ9vbqo3cmG_foJZa-LIxkNB2pBZXe1Gi4UjZjtbNOgGNWE075outIM42ZTQD8A"},"status":200}}

En postman si los parametros (user y password) los coloco en header aparece el mensaje 1, debo colocar los parametros en el body usando form/data

la pregunta es... esas especificaciones como las coloco el delphi ya sea usando indy o rest ???

pgranados
28-04-2023, 17:07:44
*ACTUALIZACION*

probé usando los componentes REST (en 64 bits)
use rest debugger copie los componentes y aparece el siguiente mensaje

1
{"success":true,"statusCode":200,"status":200,"data":{"mensaje":"Falta parametros requeridos","data":null,"status":400}}

sin embargo en postman aparecen estos

2
{"success":true,"statusCode":200,"status":200,"data":{"mensaje":"credenciales","data":{"tk":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2ODI2ODgyNTMsImlzcyI6ImN1Ym9yb2pvIiwibmJmIjoxNjgyNjg 4MjUzLCJleHAiOjE2ODc4NzIyNTMsImRhdGEiOnsiaWQiOjEwMDksIm5hbWUiOiJDb25jZXNpb25hcmlvIn19.gwl7llmglpMA57 F_s88XAz-gQ9vbqo3cmG_foJZa-LIxkNB2pBZXe1Gi4UjZjtbNOgGNWE075outIM42ZTQD8A"},"status":200}}

En postman si los parametros (user y password) los coloco en header aparece el mensaje 1, debo colocar los parametros en el body usando form/data

la pregunta es... esas especificaciones como las coloco el delphi ya sea usando indy o rest ???

Mándanos tu request formado en postman y tu request formado en restdebugger para poder ayudarte mejor

oscarac
29-04-2023, 00:05:38
resolvi el problema usando REST

les dejo los pasos que usé quizá le sirva a alguien q tenga el mismo problema

en RestClient / params - > coloque el user y el password con sus valores (en kind colocar pkGetorPost) en cada uno de los parametros
RestCliente / ContentType - > multipart/form-data

RestRequest / Method -> rmPost

y listo

soy feliz

{"success":true,"statusCode":200,"status":200,"data":{"mensaje":"credenciales","data":{"tk":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2ODI3MTk0OTksImlzcyI6ImN1Ym9yb2pvIiwibmJmIjoxNjgyNzE 5NDk5LCJleHAiOjE2ODc5MDM0OTksImRhdGEiOnsiaWQiOjEwMDksIm5hbWUiOiJDb25jZXNpb25hcmlvIn19.bX6vMTbA1EbXaO 3S4D16v6KD_zcfmLRdZ5jmHFe4ZboR2IE_-zWfooT2TCVWQMdwnt54-fQA14usMEofE6TVJQ"},"status":200}}


ahora a averiguar como subir un archivo a esa web.....

Neftali [Germán.Estévez]
02-05-2023, 09:48:35
ahora a averiguar como subir un archivo a esa web.....

En el componente TREStRequest tienes la propiedad Body (https://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Client.TCustomRESTRequest.TBody)y utilizando esa propiedad puedes realizar un Add de un fichero (https://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Client.TCustomRESTRequest.TBody.Add) por ejemplo:

...

var
Contenido:TStream;
...
RESTRequest1.Body.Add(Contenido, TRESTContentType.ctAPPLICATION_XML);

Con esto añades un XML al envío (previa carga del XML en el Stream Contenido).

oscarac
09-05-2023, 20:17:33
gracias por responder.....
estuve haciendo las pruebas via postman y ya funciona....
el tema aqui en delphi es....
uso compronentes REST para conectarme y obtener el token
debo usar otros componentes rest para enviar el archivo? asumo que si
el archivo que pretendo enviar en un txt

Neftali [Germán.Estévez]
09-05-2023, 20:38:32
el tema aqui en delphi es....
uso compronentes REST para conectarme y obtener el token
debo usar otros componentes rest para enviar el archivo? asumo que si
el archivo que pretendo enviar en un txt

Esto es como plantear ¿Debo usar 2 componentes de TQuery para un INSERT y un SELECT o puedo usar el mismo?
Pues efectivamente puedes hacer las 2 cosas, según lo que te interese por comodidad, legibilidad, facilidad,...

* Si usas un sólo componente lo configuras para la primera operación y luego para la segunda.
* Si usas 2 diferentes, pues ya puedes tener configurado cada uno con sus propiedades.

En la segunda tendrás menos código seguramente, pero ambas son igual de buenas, dependiendo de los que prefieras hacer. Vamos que va a gustos la cosa... :p:p

oscarac
09-05-2023, 21:10:11
exactamente, pero como los parametros los obtuve de restrequest, entonces no conozco el contenido al 100%

podrias ayudarme en una explicacion paso a paso como usar 2 componentes (teniendo en cuenta que en el primero ya logré la conexion y tengo el token)

varTk := JsonValue.GetValue<string>('data.data.tk'); aqui tengo el token
tengo un archivo de texto en d:\archivos\
quiero enviarlos
segun veo en postman debo usar
bearer token
content-type forma-data
en el body un key de nombre archivo tipo file y en el value el nombre del archivo

como replico esto en delphi?


primera vez q estoy usando rest, no he tenido experiencias previas...

oscarac
09-05-2023, 22:09:58
actualizacion :

agregue el componente

OAuth2Authenticator
en el restclient2 asocie el componente en la propiedad "authenticator"

cambie el Token Type = ttBEARER

ya se conecta al repositorio donde debo colocar el archivo....

ahora investigar como subir el archivo de texto

oscarac
12-05-2023, 15:24:30
continuo con mi problema

con esta parte me conecto al endpoint

RESTRequest1.Execute;
jValue := RESTResponse1.JSONValue;
Memo1.Text := jValue.ToString;
Branch := jValue.ToString;

st := Memo1.text;
JSonValue := TJSonObject.ParseJSONValue(Branch);
Label1.Caption := JSonValue.GetValue<string>('data.mensaje');
Label2.Caption := JSonValue.GetValue<string>('data.data.tk');
OAuth2Authenticator1.AccessToken := JSonValue.GetValue<string>('data.data.tk');


este es el archivo q quiero enviar
localfile := 'd:\desarrollo\concesiones\servicial\aris\envios\LURIN-09052023.txt';

primer intento fallido
{ jsRequest := TJSONObject.Create();
jsRequest.AddPair('file', 'archivo');
jsRequest.AddPair('value', localfile);
RESTRequest2.AddBody(jsRequest);
}


segundo intento fallikdo
RESTRequest2.AddParameter('archivo', localfile, TRESTRequestParameterKind.pkREQUESTBODY);


tercer intento fallido
// RESTClient2.Params.AddItem('name', 'file', TRESTRequestParameterKind.pkGETorPOST, [], TRESTContentType.ctMULTIPART_FORM_DATA);
// RESTClient2.Params.AddItem('archivo', localfile, TRESTRequestParameterKind.pkGETorPOST, [],


cuarto intento fallido
//st:=('{"archivo": ' + localfile + '}');
//RESTRequest2.AddBody(st);


quinto intento fallido
{RESTClient2.Params.AddItem; //Adds a new Parameter Item
RESTClient2.Params.Items[0].name := 'archivo'; //sets the name of the parameter. In this case, since i need to use 'data=' on the request, the parameter name is data.
RESTClient2.Params.Items[0].Value := localfile; //Adds the value of the parameter, in this case, the XML data.
RESTClient2.Params.Items[0].ContentType := ctMULTIPART_FORM_DATA; //sets the content type.
RESTClient2.Params.Items[0].Kind := pkGETorPOST; //sets the kind of request that will be executed.
}

RESTRequest2.Execute;
Memo2.Lines.Add(RESTResponse2.Content);
JSonValue.Free;

mi razonamiento es el siguiente....
si en postman coloco el archivo en el body (form-data)
el key es "archivo" y el value es el nombre del archivo

el tema es que el archivo es de tipo "file"

creo que casi todo esta bien.... incluso cuando pruebo con postman (sin enviar el archivo o archivo vacio) me devuelve el mismo mensaje que en delphi, parece que solo tengo que descubrir como meter en el body del request los parametros

o será que ya me hice un mundo en la cabeza.. y no puedo ver la solución

oscarac
12-05-2023, 15:31:46
;551367']En el componente TREStRequest tienes la propiedad Body (https://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Client.TCustomRESTRequest.TBody)y utilizando esa propiedad puedes realizar un Add de un fichero (https://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Client.TCustomRESTRequest.TBody.Add) por ejemplo:

...

var
Contenido:TStream;
...
RESTRequest1.Body.Add(Contenido, TRESTContentType.ctAPPLICATION_XML);

Con esto añades un XML al envío (previa carga del XML en el Stream Contenido).

creo que la solución esta aquí, me explicas como cargar un txt en el Dtream porfa?

Neftali [Germán.Estévez]
15-05-2023, 08:48:47
Hay varias formas, puedes probar esta:

stream2 := TStringStream.Create(System.Utf8ToAnsi(s1.DataString), TEncoding.ANSI);

oscarac
15-05-2023, 15:21:41
Averigue un poco mas y estoy asignando los valores de forma manual
la conexion inicial para obtener el token, funciona....
la conexion a la web donde debo colocar el archivo funciona....
lo que hasta ahora no puedo lograr es subir el archivo...
quisiera entender la logica...

esto es lo q he avanzado


localfile := 'd:\desarrollo\concesiones\servicial\aris\envios\LURIN-09052023.txt';

try
// CLiente
RCCredenciales.ResetToDefaults;
RCCredenciales.BaseURL := 'https://zona-api.aris.com.pe/v1/user/signin';
RCCredenciales.Accept := 'application/json, text/plain; q=0.9, text/html;q=0.8,';
RCCredenciales.AddParameter('user', 'usuario');
RCCredenciales.AddParameter('password', '**************');

RQCredenciales.Method := TRESTRequestMethod.rmPOST;
RQCredenciales.Execute;

// Ya se conectó a la web

jValue := RRCredenciales.JSONValue;
Branch := jValue.ToString;
JSonValue := TJSonObject.ParseJSONValue(Branch);

// Chapo El Token y lo coloco en el Auth2
oAUTHRQ.AccessToken := JSonValue.GetValue<string>('data.data.tk');
oAUTHRQ.TokenType := TOAuth2TokenType.ttBEARER;
Memo1.Text := Branch;

RCFile.ResetToDefaults;
RCFile.BaseURL := 'https://zona-api.aris.com.pe/v1/concesionario/masivo';
RCFile.Accept := '*/*';

//Set Content-Type to text/plain
RQFile.Params.AddHeader('Content-Type', 'multipart/form-data');


//// aqui es donde me pierdo y no logro entender como adjuntar el archivo
/// ni decirle a delphi que tiene key y value
/// l key debe ser "archivo" y el value el nombre del archivo

//Set Request Body to FileStream
try
_file := TStringStream.Create(System.Utf8ToAnsi(localfile), TEncoding.ANSI);
finally

end;
RQFile.ClearBody;
RQFile.AddParameter('archivo',localfile);
RQFile.AddBody(_file, TRESTContentType.ctTEXT_PLAIN);

RCFile.Authenticator := oAUTHRQ;
RQFile.Execute;
jValue := RRFile.JSONValue;
Memo2.Text := jValue.ToString;



// Continuar con la segunda Conexion

finally

end;


me gustaria mucho ENTENDER como es el proceso.....
si me das una mano seria genial
gracias

pgranados
15-05-2023, 16:50:41
Neftali te comenta que utilices:
RESTRequest1.Body.Add

Pero tu utilizas:

RQFile.AddParameter('archivo',localfile);
RQFile.AddBody(_file, TRESTContentType.ctTEXT_PLAIN);


Si la petición ya la lograste utilizando alguna herramienta como PostMan o directamente el RestDebugger compara tu request formado en estas herramientas contra el tuyo formado manualmente para identificar donde esta el problema.

En otro punto, veo que en el codigo cargas un archivo .txt pero en los comentarios tambien mencionan un archivo .xml

¿Que archivo vas a cargar? Saludos.

oscarac
15-05-2023, 17:57:00
hola gracias por responder

estuve viendo el tema que me recomendp Netfali

para eso estoy usando el TStream y "cargandolo" en el body


RQFile.ClearBody;
RQFile.AddParameter('archivo',localfile);
RQFile.AddBody(_file, TRESTContentType.ctTEXT_PLAIN);


en restdeguger no encuentro una forma de subir el txt (es el unico archivo q quiero subir.. no hay xml)

uso addbody porque en el restrequest no hay un body.add

pgranados
15-05-2023, 18:00:27
hola gracias por responder

estuve viendo el tema que me recomendp Netfali

para eso estoy usando el TStream y "cargandolo" en el body


RQFile.ClearBody;
RQFile.AddParameter('archivo',localfile);
RQFile.AddBody(_file, TRESTContentType.ctTEXT_PLAIN);


en restdeguger no encuentro una forma de subir el txt (es el unico archivo q quiero subir.. no hay xml)

uso addbody porque en el restrequest no hay un body.add

Vete a Tools y luego RestDebugger y en request puedes agregar el body manulamente, luego de agregar todos los params y el body envia el request y ya teniendo exito copia los componentes a tu form y modifica los parametros que siempre cambiaran

oscarac
15-05-2023, 18:59:34
eso estoy intentando hacer
pero si te das cuenta
primero debo obtener un token de esta direccion

https://zona-api.aris.com.pe/v1/user/signin

una vez obtenido ese token (no encuentro forma de replicar eso en restdebugger)

necesito subir el archivo...

oscarac
16-05-2023, 19:27:22
asi esta configurado en postman.. y funciona

ya estoy a punto de tirar la toalla :(


https://i.postimg.cc/bvWJV9T1/postman.png

oscarac
16-05-2023, 20:21:23
asi esta configurado en postman.. y funciona

ya estoy a punto de tirar la toalla :(


https://i.postimg.cc/bvWJV9T1/postman.png
https://i.postimg.cc/bvWJV9T1/postman.png

Neftali [Germán.Estévez]
17-05-2023, 08:23:38
una vez obtenido ese token (no encuentro forma de replicar eso en restdebugger)
necesito subir el archivo...


Dentro de los parámetros del RESTDebugger puedes definir uno como BODY. Prueba con ese.


https://i.imgur.com/VHfXcGY.png


De todas formas, si ves que con es RESTDebugger no lo consigues no pasa nada, ves directamente a los componentes.

¿Al intentar añadir el fichero tal y como hemos comentado antes (usando Stream) qué error te da?

oscarac
17-05-2023, 16:15:04
buenos dias
tengo una respuesta del servidoer indicando que el archivo esta vacio
esa respuesta me da, cuando no envio el archivo, porque si lo recibe la respuesta seria otra

mi restdebugger no esta funcionando, aparece un mensaje de error

ahora.. en postman en el body, el parametro llamado "archivo" es de tipo file... hay tipo texto tambien, pero con ese no funciona, debe ser tipo file...... creo que por ahi va la cosa...

esto es lo que tengo

unit frmMain_f;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
IPPeerClient, Vcl.StdCtrls, REST.Client, Data.Bind.Components,
Data.Bind.ObjectScope, system.JSON, REST.Authenticator.OAuth, REST.Types;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
RCCredenciales: TRESTClient;
RQCredenciales: TRESTRequest;
RRCredenciales: TRESTResponse;
Label2: TLabel;
Memo2: TMemo;
RRFile: TRESTResponse;
RQFile: TRESTRequest;
RCFile: TRESTClient;
oAUTHRQ: TOAuth2Authenticator;
procedure Button1Click(Sender: TObject);
private
function MemoryStreamToString(M: TMemoryStream): string;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
jValue: TJSONValue; // Respuesta del Request
JSonValue: TJSonValue;
Branch: string;
_file: TMemoryStream;
localfile: string;
param: TRESTRequestParameter;
begin
localfile := 'd:\desarrollo\concesiones\servicial\aris\envios\LURIN-09052023.txt';

try
// CLiente
RCCredenciales.ResetToDefaults;
RCCredenciales.BaseURL := 'https://zona-api.aris.com.pe/v1/user/signin';
RCCredenciales.Accept := 'application/json, text/plain; q=0.9, text/html;q=0.8,';
RCCredenciales.AddParameter('user', 'user');
RCCredenciales.AddParameter('password', '******************');

// Request
RQCredenciales.Method := TRESTRequestMethod.rmPOST;
RQCredenciales.Execute;

// Ya se conectó a la web

jValue := RRCredenciales.JSONValue;
Branch := jValue.ToString;
JSonValue := TJSonObject.ParseJSONValue(Branch);

// Chapo El Token y lo coloco en el Auth2
oAUTHRQ.AccessToken := JSonValue.GetValue<string>('data.data.tk');
oAUTHRQ.TokenType := TOAuth2TokenType.ttBEARER;
Memo1.Text := Branch;

RCFile.ResetToDefaults;
RCFile.Params.Clear;
RCFile.BaseURL := 'https://zona-api.aris.com.pe/v1/concesionario/masivo';
RCFile.Accept := 'text/plain';
RCFile.Authenticator := oAUTHRQ;

//RQFile.ClearBody;
RQFile.Method := TRESTRequestMethod.rmPOST;

_file := TMemoryStream.Create();
_file.LoadFromFile(localfile);
_file.Position := 0;


param := RQFile.Params.AddItem;
RQFile.Params[0].name := 'archivo';
RQFile.Params[0].value := MemoryStreamToString(_file);
RQFile.Params[0].kind := pkGETorPOST;
RQFile.Params[0].ContentType := ctTEXT_PLAIN;
RQFile.Params[0].Options := [poDoNotEncode];

RQFile.Execute;
jValue := RRFile.JSONValue;
Memo2.Text := jValue.ToString;

finally

end;
end;

function TForm1.MemoryStreamToString(M: TMemoryStream): string;
begin
SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char));
end;

end.

Neftali [Germán.Estévez]
17-05-2023, 17:46:54
Tal vez me he perdido algo, pero sigo echando en falta que pruebes a cargar el fichero en el Body.
Con este código:


//RQFile.ClearBody;
RQFile.Method := TRESTRequestMethod.rmPOST;
_file := TMemoryStream.Create();
_file.LoadFromFile(localfile);
_file.Position := 0;
param := RQFile.Params.AddItem;
RQFile.Params[0].name := 'archivo';
RQFile.Params[0].value := MemoryStreamToString(_file);


Creo que lo estás intentando cargar como parámetro.
Intenta cargarlo en el Body con esto:


var
Contenido: TStringStream;
begin
...
//RQFile.ClearBody;
RQFile.Method := TRESTRequestMethod.rmPOST;
// Creamos el stream
Contenido := TStringStream.Create;
try
// Cargamos el cntenido del fichero en el TStream
Contenido.LoadFromFile('Fichero.xml'); // aquí tu fichero
// Añadirlo al Body
RQFile.Body.Add(Contenido, TRESTContentType.ctTEXT_PLAIN);
// => Prueba a cambiar el segundo porámetro por diferentes tipos según lo que estás enviando

// ejecutar la peticion
RQFile.Execute;
jValue := RRFile.JSONValue;
Memo2.Text := jValue.ToString
finally
contenido.Free;
...
end;


Está claro que si en el PostMan te está funcionando en el Body, aquí debes usar la propiedad Body para enviarlo.
https://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Client.TCustomRESTRequest.Body

oscarac
17-05-2023, 19:05:34
;551517']Tal vez me he perdido algo, pero sigo echando en falta que pruebes a cargar el fichero en el Body.
Con este código:


//RQFile.ClearBody;
RQFile.Method := TRESTRequestMethod.rmPOST;
_file := TMemoryStream.Create();
_file.LoadFromFile(localfile);
_file.Position := 0;
param := RQFile.Params.AddItem;
RQFile.Params[0].name := 'archivo';
RQFile.Params[0].value := MemoryStreamToString(_file);


Creo que lo estás intentando cargar como parámetro.
Intenta cargarlo en el Body con esto:


var
Contenido: TStringStream;
begin
...
//RQFile.ClearBody;
RQFile.Method := TRESTRequestMethod.rmPOST;
// Creamos el stream
Contenido := TStringStream.Create;
try
// Cargamos el cntenido del fichero en el TStream
Contenido.LoadFromFile('Fichero.xml'); // aquí tu fichero
// Añadirlo al Body
RQFile.Body.Add(Contenido, TRESTContentType.ctTEXT_PLAIN);
// => Prueba a cambiar el segundo porámetro por diferentes tipos según lo que estás enviando

// ejecutar la peticion
RQFile.Execute;
jValue := RRFile.JSONValue;
Memo2.Text := jValue.ToString
finally
contenido.Free;
...
end;


Está claro que si en el PostMan te está funcionando en el Body, aquí debes usar la propiedad Body para enviarlo.
https://docwiki.embarcadero.com/Libraries/Sydney/en/REST.Client.TCustomRESTRequest.Body

E la version Xe7 no tengo el body.add

oscarac
17-05-2023, 21:04:14
al final cambié a Indy.... y funcionó

les dejo el codigo por si alguien lo necesita

unit frmMain_f;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
IdMultipartFormData, IdSSLOpenSSL, IdSSLOpenSSLHeaders, Vcl.StdCtrls,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, system.json;

type
TForm1 = class(TForm)
IndCredenciales: TIdHTTP;
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
IndCredencialesSSL: TIdSSLIOHandlerSocketOpenSSL;
Memo2: TMemo;
IndFile: TIdHTTP;
IndFileSSL: TIdSSLIOHandlerSocketOpenSSL;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
//lHTTP: TIdHTTP;
datosPost: TIdMultiPartFormDataStream;
URL: string;
response, tk, localfile: string;
respuesta: TJSONValue;
RequestBody: TStream;

begin
localfile := 'd:\desarrollo\concesiones\servicial\aris\envios\LURIN-09052023.txt';
try

//Conexion Endpoint Primario
URL := 'https://zona-api.aris.com.pe/v1/user/signin';


datosPost := TIdMultiPartFormDataStream.Create;
datosPost.AddFormField('user', 'user');
datosPost.AddFormField('password', '***********');
response := IndCredenciales.Post(URL, datosPost);
Memo1.Text := response;
respuesta := TJSonObject.ParseJSONValue(response);
tk := respuesta.GetValue<string>('data.data.tk');
Label1.Caption := tk;
datosPost.Free;
// Ya estoy conectado

// Conexion EndPoint Archivo
// enviar archivo
URL := 'https://zona-api.aris.com.pe/v1/concesionario/masivo';
IndFile.Request.CustomHeaders.FoldLines := False;
indFile.Request.CustomHeaders.Add('Authorization:Bearer ' + tk);
datosPost := TIdMultiPartFormDataStream.Create;
datosPost.AddFile('archivo', localfile, 'multipart/form-data');
Response := IndFile.Post(URL, datosPost);
Memo2.Text := response;
datosPost.Free;

finally
end;
end;


end.

Neftali [Germán.Estévez]
18-05-2023, 08:25:36
E la version Xe7 no tengo el body.add
:eek::eek:
Raro que no tenga nada similar para enviar algo en el cuerpo de la petición.

al final cambié a Indy.... y funcionó
les dejo el codigo por si alguien lo necesita


Gracias.
^\||/^\||/^\||/

oscarac
16-12-2023, 05:25:03
al final cambié a Indy.... y funcionó

les dejo el codigo por si alguien lo necesita

unit frmMain_f;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
IdMultipartFormData, IdSSLOpenSSL, IdSSLOpenSSLHeaders, Vcl.StdCtrls,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, system.json;

type
TForm1 = class(TForm)
IndCredenciales: TIdHTTP;
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
IndCredencialesSSL: TIdSSLIOHandlerSocketOpenSSL;
Memo2: TMemo;
IndFile: TIdHTTP;
IndFileSSL: TIdSSLIOHandlerSocketOpenSSL;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
//lHTTP: TIdHTTP;
datosPost: TIdMultiPartFormDataStream;
URL: string;
response, tk, localfile: string;
respuesta: TJSONValue;
RequestBody: TStream;

begin
localfile := 'd:\desarrollo\concesiones\servicial\aris\envios\LURIN-09052023.txt';
try

//Conexion Endpoint Primario
URL := 'https://zona-api.aris.com.pe/v1/user/signin';


datosPost := TIdMultiPartFormDataStream.Create;
datosPost.AddFormField('user', 'user');
datosPost.AddFormField('password', '***********');
response := IndCredenciales.Post(URL, datosPost);
Memo1.Text := response;
respuesta := TJSonObject.ParseJSONValue(response);
tk := respuesta.GetValue<string>('data.data.tk');
Label1.Caption := tk;
datosPost.Free;
// Ya estoy conectado

// Conexion EndPoint Archivo
// enviar archivo
URL := 'https://zona-api.aris.com.pe/v1/concesionario/masivo';
IndFile.Request.CustomHeaders.FoldLines := False;
indFile.Request.CustomHeaders.Add('Authorization:Bearer ' + tk);
datosPost := TIdMultiPartFormDataStream.Create;
datosPost.AddFile('archivo', localfile, 'multipart/form-data');
Response := IndFile.Post(URL, datosPost);
Memo2.Text := response;
datosPost.Free;

finally
end;
end;


end.


buenas noches....este tema lo hice porque un cliente queria que se suba informacion a su repositorio en la web y me dá curiosidad saber como es que lo hace... (no hablo del subir la información porque eso ya se solucionó), es decir... como prepara su hosting en la dirección https://zona-api.aris.com.pe/v1/concesionario/masivo para procesar la informacion que recibe...

alguien me entendió?

Casimiro Notevi
16-12-2023, 12:01:49
alguien me entendió? Creo que no :confused:

oscarac
17-12-2023, 01:21:30
Creo que no :confused:

jajajaj casimiro...
la idea que tengo es....
subir data a una base de datos en la web, pero hacerlo a traves de un webservice que este validado con un token, para que solo las personas autorizadas puedan subir esa información

Casimiro Notevi
17-12-2023, 14:15:10
Es que es una pregunta muy general, dices que "cómo preparar su hosting para procesar la información que recibe".
Depende, ¿qué información? ¿ficheros? ¿datos en base de datos? ...

Neftali [Germán.Estévez]
18-12-2023, 15:41:59
No se si te refieres a la parte del WebsService.
Por ejemplo, aquí tienes un WebService explicado paso a paso en PHP:
https://neftali.clubdelphi.com/25-generacion-del-webservice-en-php/

En este caso recibe unos parámetros y con ellos hace una consulta (y devuelve los resultados), pero en lugar de eso puedes recibir un fichero en el cuerpo de la petición y con eso insertarlo en la Base de Datos.

¿Te refieres a eso?

oscarac
19-12-2023, 04:43:04
;553632']No se si te refieres a la parte del WebsService.
Por ejemplo, aquí tienes un WebService explicado paso a paso en PHP:
https://neftali.clubdelphi.com/25-generacion-del-webservice-en-php/

En este caso recibe unos parámetros y con ellos hace una consulta (y devuelve los resultados), pero en lugar de eso puedes recibir un fichero en el cuerpo de la petición y con eso insertarlo en la Base de Datos.

¿Te refieres a eso?

claro, algo como esto, pero en lugar de leer datos, quiero escribir datos

Neftali [Germán.Estévez]
19-12-2023, 10:13:40
claro, algo como esto, pero en lugar de leer datos, quiero escribir datos


Pues es un código similar al que tienes ahí, pero en lugar de lanzar un SELECT y retornar datos, puedes "montar" y lanzar un INSERT o un UPDATE.