I am struggling to know how to access the response to an Indy POST request. I post the data either as JSON or paramstring. My code when using JSON is as follows.
params := TStringList.Create;
try
params.Text :=
'{'
+ format ('"client_secret":"%s",', [FilesFrm.ClientSecret])
+ format ('"client_id":"%s",', [FilesFrm.ClientId])
+ '"grant_type":"authorization_code",'
+ '"redirect_uri":"http://localhost:8080",'
+ format ('"code":"%s"', [fCode])
+ '}';
idLogFile1.Active := true;
// Make sure it uses HTTP 1.1, not 1.0
IdHTTP1.HTTPOptions := IdHTTP1.HTTPOptions + [hoKeepOrigProtocol];
IdHTTP1.Request.ContentType := 'application/json';
IdHttp1.Request.Accept := 'application/vnd.hmrc.1.0+json';
try
result := IdHTTP1.Post (
'https://test-api.service.hmrc.gov.uk/oauth/token',
params);
except
on E: Exception do
memo1.lines.add (E.ClassName + ': ' + E.message);
end;
memo1.Lines.add (result);
memo1.Lines.add (idHTTP1.ResponseText);
finally
params.free;
end;
The result of printing out result and RepsonseText is just
EIdHTTPProtocolException: HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
However, because I have a TidLogFile component attached to the TidHTTP, I can see what actually arrives, which is the following.
Recv 2/1/2019 7:56:07 AM: HTTP/1.1 400 Bad Request<EOL>
Content-Type: application/json<EOL>
Content-Length: 72<EOL>
Cache-Control: no-cache,no-store,etc, etc...
; Secure; HTTPOnly<EOL><EOL>
{"error":"invalid_request","error_description":"grant_type is required"}
Aside from the fact that grant_type appears to be in the original request data, I would like to be able to access the JSON response at the end, since "grant_type_is_required" is much more helpful than "Bad request", but I cannot find where it is.
I have subsequently found Response.ContentLength, which contains the value 72, and Response.ContentStream, which should in theory contain the 72 bytes of data, but produces access violations when I try to extract the data.
len := idHTTP1.Response.ContentLength;
memo1.Lines.Add(format ('Length = %d', [len]));
if assigned (idHTTP1.Response.ContentStream) then
begin
//idHTTP1.Response.ContentStream.Position := 0;
result := ReadStringFromStream (idHTTP1.Response.ContentStream, len);
end;
memo1.lines.add (result);
In addition to mjn42's answer, which is technically correct, TIdHTTP also has optional hoNoProtocolErrorException and hoWantProtocolErrorContent flags in its HTTPOptions property, which you can enable to avoid the EIdHTTPProtocolException being raised and to populate your result variable with error data, respectively:
params := TStringStream.Create(
'{'
+ format ('"client_secret":"%s",', [FilesFrm.ClientSecret])
+ format ('"client_id":"%s",', [FilesFrm.ClientId])
+ '"grant_type":"authorization_code",'
+ '"redirect_uri":"http://localhost:8080",'
+ format ('"code":"%s"', [fCode])
+ '}',
TEncoding.UTF8);
try
IdLogFile1.Active := true;
// Make sure it uses HTTP 1.1, not 1.0,
// and disable EIdHTTPProtocolException on errors
IdHTTP1.ProtocolVersion := pv1_1;
IdHTTP1.HTTPOptions := IdHTTP1.HTTPOptions + [hoKeepOrigProtocol, hoNoProtocolErrorException, hoWantProtocolErrorContent];
IdHTTP1.Request.ContentType := 'application/json';
IdHTTP1.Request.Accept := 'application/vnd.hmrc.1.0+json';
try
result := IdHTTP1.Post('https://test-api.service.hmrc.gov.uk/oauth/token', params);
except
on E: Exception do begin
Memo1.Lines.Add(E.ClassName + ': ' + E.message);
raise;
end;
end;
Memo1.Lines.Add(result);
finally
params.Free;
end;
Here is an example which shows how the HTTP body can be accessed.
The body can be accessed if you catch the EIdHTTPProtocolException exception.
on E: EIdHTTPProtocolException do
begin
WriteLn(E.Message);
WriteLn(E.ErrorMessage);
end;
Full example code:
program JSONPostExample;
{$APPTYPE CONSOLE}
uses
IdHTTP, IdGlobal, SysUtils, Classes;
var
HTTP: TIdHTTP;
RequestBody: TStream;
ResponseBody: string;
begin
HTTP := TIdHTTP.Create;
try
try
RequestBody := TStringStream.Create('{"日本語":42}',
TEncoding.UTF8);
try
HTTP.Request.Accept := 'application/json';
HTTP.Request.ContentType := 'application/json';
ResponseBody := HTTP.Post('https://httpbin.org/post',
RequestBody);
WriteLn(ResponseBody);
WriteLn(HTTP.ResponseText);
finally
RequestBody.Free;
end;
except
on E: EIdHTTPProtocolException do
begin
WriteLn(E.Message);
WriteLn(E.ErrorMessage);
end;
on E: Exception do
begin
WriteLn(E.Message);
end;
end;
finally
HTTP.Free;
end;
ReadLn;
ReportMemoryLeaksOnShutdown := True;
end.
Note that you must not use a TStringList for the POST body. That version of TIdHTTP.Post() formats the data according to the application/x-www-form-urlencoded media type, which is not appropriate for JSON and will corrupt it.
Related
I am trying to read from a tcp connection which contains HTTP/2 data. Below is the code for reading HEADERS frame -
framer := http2.NewFramer(conn, conn)
frame, _ := framer.ReadFrame()
fmt.Printf("fh type: %s\n", frame.Header().Type)
fmt.Printf("fh type: %d\n", frame.Header().Type)
fmt.Printf("fh flag: %d\n", frame.Header().Flags)
fmt.Printf("fh length: %d\n", frame.Header().Length)
fmt.Printf("fh streamid: %d\n", frame.Header().StreamID)
headersframe := (frame1.(*http2.HeadersFrame))
fmt.Printf("stream ended? %v\n", headersframe.StreamEnded())
fmt.Printf("block fragment: %x\n", headersframe.HeaderBlockFragment())
I send request using curl as -
curl -v https://127.0.0.1:8000/ -k --http2
This is the output I get (after reading connection preface and SETTINGS), if I read from the conn using above code -
fh type: HEADERS
fh type: 1
fh flag: 5
fh length: 30
fh streamid: 1
stream ended? true
block fragment: 828487418a089d5c0b8170dc6c4d8b7a8825b650c3abb6f2e053032a2f2a
I understand the ouput, except the block fragment part and how to decode it into ascii string? I want to know the protocol/method/url path information.
The "header block fragment" is encoded using HPACK.
Go has an implementation to encode and decode HPACK, so you don't have to write your own.
You can find here an example of using both the encoder and decoder Go API.
I figured it out using Go hpack library (https://godoc.org/golang.org/x/net/http2/hpack) -
decoder := hpack.NewDecoder(2048, nil)
hf, _ := decoder.DecodeFull(headersframe.HeaderBlockFragment())
for _, h := range hf {
fmt.Printf("%s\n", h.Name + ":" + h.Value)
}
This prints -
:method:GET
:path:/
:scheme:https
:authority:127.0.0.1:5252
user-agent:curl/7.58.0
accept:*/*
I'm trying to send a POST request at Firebase via HTTP, either in code or with the REST Debugger, but it returns an error:
HTTP/1.1 401 The request was missing an Authentification Key (FCM Token). Please, refer to section "Authentification" of the FCM documentation, at https=//firebase.google.com/docs
Using the Postman extension from Chrome, it works.
This is the code:
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
IdHTTP, IdIOHandler, IdIOHandlerStream,
IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdSSLOpenSSLHeaders_Static,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.ScrollBox, FMX.Memo,
IdGlobal, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdServerIOHandler, IdCoderMIME;
begin
try
IdIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
IdIOHandler.ReadTimeout := IdTimeoutInfinite;
IdIOHandler.ConnectTimeout := IdTimeoutInfinite;
IdHTTP := TIdHTTP.Create(nil);
try
idHttp.Request.Clear;
idHttp.Request.CustomHeaders.Clear;
idHttp.Request.ContentType := 'application/json';
idhttp.Request.Charset := 'UTF-8';
IdHTTP.IOHandler := IdIOHandler;
IdHTTP.ReadTimeout := IdTimeoutInfinite;
IdHTTP.Request.Connection := 'Keep-Alive';
IdIOHandler.SSLOptions.Method := sslvSSLv23;
IdHTTP.Request.Method := 'POST';
IdHTTP.Request.CustomHeaders.Values['Authorization:key'] := 'AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';
jsonString := '{"to" : "APA91bFJSdGW_yrX7p_TNKZ4k0OpdXTQM6xdd7BUsslk6zSvZlBmoAnfvyX-nBm4DYY-xxxxx......",' +
'"data" : {' +
'"Nick" : "Teste de Push",' +
'"body" : "Corpo do push",' +
'"Room" : "Apenas um teste"' +
'},}';
JsonToSend := TStringStream.Create(jsonString);
try
response := IdHTTP.Post('https://fcm.googleapis.com/fcm/send', JsonToSend);
response := response.Replace(Char(#10), '');
except
on E:EIdHTTPProtocolException do
memo1.Lines.Insert(0, e.ErrorMessage);
end;
memo1.Lines.Insert(0, response);
finally
IdHTTP.Free;
end;
finally
IdIOHandler.Free;
end;
end;
Your Delphi code is not assigning the Authentication request header correctly. You need to change this:
IdHTTP.Request.CustomHeaders.Values['Authorization:key'] := 'AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';
To this instead:
IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'key=AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';
You should set the IdHTTP.Request.BasicAuthentication property to false as well.
Aside from that, since you are setting the Request.Charset property to UTF-8, you should construct the TStringStream to match:
JsonToSend := TStringStream.Create(jsonString, TEncoding.UTF8);
With that said, try the following code:
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.ScrollBox, FMX.Memo,
IdGlobal, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL
{$IFDEF IOS}
, IdSSLOpenSSLHeaders_Static
{$ENDIF}
;
...
begin
IdHTTP := TIdHTTP.Create(nil);
try
IdIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
IdIOHandler.SSLOptions.Method := sslvSSLv23;
IdHTTP.IOHandler := IdIOHandler;
IdHTTP.Request.ContentType := 'application/json';
IdHTTP.Request.Charset := 'UTF-8';
IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'key=AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';
jsonString := '{"to" : "APA91bFJSdGW_yrX7p_TNKZ4k0OpdXTQM6xdd7BUsslk6zSvZlBmoAnfvyX-nBm4DYY-xxxxx......",' +
'"data" : {' +
'"Nick" : "Teste de Push",' +
'"body" : "Corpo do push",' +
'"Room" : "Apenas um teste"' +
'},}';
JsonToSend := TStringStream.Create(jsonString, TEncoding.UTF8);
try
response := IdHTTP.Post('https://fcm.googleapis.com/fcm/send', JsonToSend);
response := response.Replace(#10, '');
except
on E: EIdHTTPProtocolException do
response := e.ErrorMessage;
end;
Memo1.Lines.Insert(0, response);
finally
IdHTTP.Free;
end;
end;
We are getting the ORA-29270:too many open HTTP requests when try to execute the Below Procedure. Please let us know where and all we need to close the Request and Response , Please provide one of the Procedure example how we can handle the exception. and all the request should process Properly.
BEGIN
l_http_request := utl_http.begin_request (p_url, 'POST');
BEGIN
-- build the request by using utl_http.set_header() and utl_http.write_text()
-- ...
-- process the request and get the response:
l_http_response := utl_http.get_response (l_http_request);
WHEN OTHERS THEN
--- utl_http.end_response(http_resp);
error_code := '91';
error_desc := SQLERRM || ' Unhandled Exception';
END;
BEGIN
LOOP
-- read the response using utl_http.read_line()
-- ...
END LOOP;
-- Complete the request and response, and close the network connection
utl_http.end_response(l_http_response);
EXCEPTION
when utl_http.end_of_body then
utl_http.end_response(http_resp);
WHEN error_out THEN
NULL;
WHEN OTHERS THEN
--- utl_http.end_response(http_resp);
error_code := '91';
error_desc := SQLERRM || ' Unhandled Exception';
END;
END;
Hello: I happen to be addressing the same error in my own code. I fixed mine by adding utl_http.end_response(l_http_response) - which you already have.
But I notice you use two different arguments in your end_response call. Try changing
utl_http.end_response(http_resp);
to
utl_http.end_response(l_http_response);
in your exception block. I hope this helps. Cheers, Hawk
Usually, I use the following structure to send POST request with contents of varchar2 and numbers .. etc.
content := '{"Original File Name":"'||V_HOMEBANNER_1_EN_NAME(indx)||'"}';
url := 'https://api.appery.io/rest/1/db/Names';
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
UTL_HTTP.set_header(req, 'X-Appery-Database-Id', '5f2dac54b02cc6402dbe');
utl_http.set_header(req, 'content-type', 'application/json');
UTL_HTTP.set_header(req, 'X-Appery-Session-Token', sessionToken);
utl_http.set_header(req, 'Content-Length', LENGTH(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
BEGIN
LOOP
utl_http.read_line(res, buffer);
END LOOP;
utl_http.end_response(res);
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(res);
END;
And It works just fine. However, now I want to send/upload a blob files (images of jpg) into some MongoDB collection called 'Files' (so url := ttps://api.appery.io/rest/1/db/Files). The collection guide has the following cURL as a general advice :
curl -X POST \
-H "X-Appery-Database-Id: 5f2dac54b02cc6402dbe" \
-H "X-Appery-Session-Token: <session_token>" \
-H "Content-Type: <content_type>" \
--data-binary '<file_content>' \
https://api.appery.io/rest/1/db/files/<file_name>
But I could not translate this cURL into PL/SQL request. Specifically, the part (--data-binary '')
I have these BLOB files in Oracle table and they are stored with their names as follows:
+-----------+--------------+
| File_Name | File_content |
+-----------+--------------+
| PIC_1.jpg | BLOB |
| PIC_2.jpg | BLOB |
| PIC_3.jpg | BLOB |
+-----------+--------------+
My question, how to upload these images into the targeted URL?
Inspired by this blog advised by #JeffreyKemp, I go it working by only replacing write_text() with write_raw() in order to send content body as BLOB (Requested by the API).
The following code is the critical part of my function with the changes needed:
content := V_HOMEBANNER_1_EN(indx);
file_name := 'test.jpg';
url := 'https://api.appery.io/rest/1/db/files/'||file_name;
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
UTL_HTTP.set_header(req, 'X-Appery-Database-Id', '53fae4b02cc4021dbe');
UTL_HTTP.set_header(req, 'X-Appery-Session-Token', sessionToken);
utl_http.set_header(req, 'content-type', 'image/jpeg');
req_length := DBMS_LOB.getlength(CONTENT);
DBMS_OUTPUT.PUT_LINE(req_length);
--IF MSG DATA UNDER 32KB LIMIT:
IF req_length <= 32767
THEN
begin
utl_http.set_header(req, 'Content-Length', req_length);
utl_http.write_raw(req, content);
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end;
--IF MSG DATA MORE THAN 32KB
ELSIF req_length >32767
THEN
BEGIN
DBMS_OUTPUT.PUT_LINE(req_length);
utl_http.set_header(req, 'Transfer-Encoding', 'Chunked');
WHILE (offset < req_length)
LOOP
DBMS_LOB.read(content, amount, offset, buffer);
utl_http.write_raw(req, buffer);
offset := offset + amount;
END LOOP;
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end;
END IF;
l_http_response := UTL_HTTP.get_response(req);
UTL_HTTP.read_text(l_http_response, response_body, 32767);
UTL_HTTP.end_response(l_http_response);
Tried and tested for both greater and smaller than 32KB images/jpg.
I need to program an application with Delphi that goes into this site and uses the form to get an .dat file.
http://www.bmfbovespa.com.br/BancoTitulosBTC/PosicoesEmAberto.aspx?Idioma=pt-br
Via browser I just click on the second "buscar" and get the file automatically.
This is what I got so far:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, idHTTP, Classes, MSHTML, SHDocVw, Httpapp, System.Variants, idURI;
var
http: TIdHttp;
url: string;
code: integer;
parameters: TStringList;
Response: TStringStream;
Resultado: string;
MS: TMemoryStream;
begin
url := 'http://www.bmfbovespa.com.br/BancoTitulosBTC/PosicoesEmAberto.aspx?Idioma=pt-br';
http := TIdHTTP.Create(nil);
parameters := TStringList.Create;
Response := TStringStream.Create;
MS := TMemoryStream.Create;
try
try
Parameters.Add('__EVENTTARGET=');
Parameters.Add('__EVENTARGUMENT=');
Parameters.Add('__VIEWSTATE=/wEPDwUKMTI5NDMyNjQ4NA8WAh4QdGlwb1Bvc2ljYW9BdGl2bwspc1RpcG9Qb3NpY2Fv'+
'QXRpdm8sIEJvdmVzcGEuU2l0ZUJtZkJvdmVzcGEuQmFuY29UaXR1bG9zQlRDLldlYiwgVmVyc2lvbj0x'+
'LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwAFgJmDw8WCB4Ebm9kZQUk'+
'YjViNDhlNjYtZTMwMC00NTMzLTgwYzktMzI2NmM5ZDY2ODBiHgpQYXJlbnROb2RlBUsvcHQtYnIvc2Vy'+
'dmljb3MvZW1wcmVzdGltby1kZS1hdGl2b3MvZW1wcmVzdGltby1kZS1hdGl2b3MuYXNweD9JZGlvbWE9'+
'cHQtYnIeC0N1cnJlbnROb2RlBTMvYmFuY290aXR1bG9zYnRjL3Bvc2ljb2VzZW1hYmVydG8uYXNweD9'+
'JZGlvbWE9cHQtYnIeCkN1cnJlbnRVcmwFMy9CYW5jb1RpdHVsb3NCVEMvUG9zaWNvZXNFbUFiZXJ0by5'+
'hc3B4P0lkaW9tYT1wdC1icmQWAgIDD2QWAgIBD2QWCgIBD2QWCAIDDxYCHgdWaXNpYmxlaGQCDA8WBh4'+
'Hb25jbGljawUQdGhpcy52YWx1ZSA9ICcnOx4Gb25ibHVyBTFpZih0aGlzLnZhbHVlID09ICcnKSB7dGh'+
'pcy52YWx1ZT0gbm9tZVRleHRCdXNjYTt9HgpvbmtleXByZXNzBSRyZXR1cm4ga2V5UHJlc3NQZXNxdWl'+
'zYSh0aGlzLGV2ZW50KTtkAg0PDxYCHg1PbkNsaWVudENsaWNrBRxyZXR1cm4gVmVyaWZpY2FyQ2FtcG9'+
'CdXNjYSgpZGQCDg8WAh4EVGV4dAWXMzxkaXYgaWQ9J21lbnUnPjx1bCBpZD0nbWVudUhvcml6Jz48bGk'+
'gaWQ9J2FibWZib3Zlc3BhJz48YSBocmVmPScjJyBjbGFzcz0nYWJtZmJvdmVzcGEnIGlkPSdsaW5rQWJ'+
'tZic+PGltZyBzcmM9Jy9zaGFyZWQvY3NzL2ltZy90cmFuc3AuZ2lmJyAvPjwvYT48dWwgb25tb3VzZW9'+
'2ZXI9ImxpbmtBYm1mLmNsYXNzTmFtZT0nYWJtZmJvdmVzcGFob3Zlcic7IiBvbm1vdXNlb3V0PSJsaW'+
'5rQWJtZi5jbGFzc05hbWU9J2FibWZib3Zlc3BhJzsiPjxsaT48YSBocmVmPScvcHQtYnIvaW50cm9zL2'+
'ludHJvLXNvYnJlLWEtYm9sc2EuYXNweCcgdGFyZ2V0PScnPk8gcXVlIGEgQm9sc2EgZmF6PC9hPjwvbG'+
'k+PGxpPjxhIGhyZWY9Jy9wdC1ici9hLWJtZmJvdmVzcGEvdmlzaXRhcy1hLWJvbHNhL3Zpc2l0YXMtYS'+
'1ib2xzYS5hc3B4JyB0YXJnZXQ9Jyc+VmlzaXRlIGEgQm9sc2E8L2E+PC9saT48bGk+PGEgaHJlZj0nL3'+
'B0LWJyL2EtYm1mYm92ZXNwYS91bmlkYWRlcy91bmlkYWRlcy5hc3B4JyB0YXJnZXQ9Jyc+Tm9zc2FzIH'+
'VuaWRhZGVzPC9hPjwvbGk+PGxpPjxhIGhyZWY9Jy9wdC1ici9hLWJtZmJvdmVzcGEvc3VzdGVudGFiaW'+
'xpZGFkZS5hc3B4JyB0YXJnZXQ9Jyc+U3VzdGVudGFiaWxpZGFkZTwvYT48L2xpPjxsaT48YSBocmVmPS'+
'dodHRwOi8vd3d3Lmluc3RpdHV0b2JtZmJvdmVzcGEub3JnLmJyL3B0LWJyL2hvbWUuYXNwJyB0YXJnZX'+
'Q9J19ibGFuayc+SW5zdGl0dXRvIEJNJkZCT1ZFU1BBPC9hPjwvbGk+PGxpPjxhIGhyZWY9Jy9wdC1ici'+
'9hLWJtZmJvdmVzcGEvdHJhYmFsaGUtY29ub3Njby90cmFiYWxoZS1jb25vc2NvLmFzcHgnIHRhcmdldD'+
'0nJz5UcmFiYWxoZSBuYSBCb2xzYTwvYT48L2xpPjxsaT48YSBocmVmPScvc2FsYS1kZS1pbXByZW5zYS'+
'9zYWxhaW1wcmVuc2EuYXNweD9pZGlvbWE9cHQtYnInIHRhcmdldD0nJz5TYWxhIGRlIEltcHJlbnNhPC'+
'9hPjwvbGk+PC91bD48L2xpPjxsaSBpZD0nbWVyY2Fkbyc+PGEgaHJlZj0nIycgY2xhc3M9J21lcmNhZ'+
'G9zJyBpZD0nbGlua01lcmNhZG8nPjxpbWcgc3JjPScvc2hhcmVkL2Nzcy9pbWcvdHJhbnNwLmdpZicgL'+
'z48L2E+PHVsIG9ubW91c2VvdmVyPSJsaW5rTWVyY2Fkby5jbGFzc05hbWU9J21lcmNhZG9zaG92ZXInO'+
'yIgb25tb3VzZW91dD0ibGlua01lcmNhZG8uY2xhc3NOYW1lPSdtZXJjYWRvcyc7Ij48bGk+PGEgaHJlZ'+
'j0nL3B0LWJyL21lcmNhZG9zL2Fjb2VzLmFzcHgnIHRhcmdldD0nJz5Bw6fDtWVzIDwvYT48L2xpPjxsa'+
'T48YSBocmVmPScvcHQtYnIvbWVyY2Fkb3MvbWVyY2Fkb3JpYXMtZS1mdXR1cm9zLmFzcHgnIHRhcmdld'+
'D0nJz5NZXJjYWRvcmlhcyBlIEZ1dHVyb3M8L2E+PC9saT48bGk+PGEgaHJlZj0nL3B0LWJyL2ludHJvcy'+
'9pbnRyby1jYW1iaW8uYXNweCcgdGFyZ2V0PScnPkPDom1iaW88L2E+PC9saT48bGk+PGEgaHJlZj0nL3B'+
'0LWJyL2ludHJvcy9pbnRyby1hdGl2b3MuYXNweCcgdGFyZ2V0PScnPkF0aXZvczwvYT48L2xpPjxsaT'+
'48YSBocmVmPScvcHQtYnIvaW50cm9zL2ludHJvLWZ1bmRvcy5hc3B4JyB0YXJnZXQ9Jyc+RnVuZG9zIC'+
'8gRVRGczwvYT48L2xpPjxsaT48YSBocmVmPScvUmVuZGEtRml4YS9SZW5kYUZpeGEuYXNweCcgdGFyZ2'+
'V0PScnPlJlbmRhIEZpeGE8L2E+PC9saT48bGk+PGEgaHJlZj0nL3B0LWJyL2ludHJvcy9pbnRyby1vd'+
'XRyb3MtdGl0dWxvcy5hc3B4JyB0YXJnZXQ9Jyc+T3V0cm9zIFTDrXR1bG9zPC9hPjwvbGk+PC91bD48L'+
'2xpPjxsaSBpZD0nY2VudHJvZGVpbmZvcm1hY29lcyc+PGEgaHJlZj0nIycgY2xhc3M9J2NlbnRyb2Rla'+
'W5mb3JtYWNvZXMnIGlkPSdsaW5rQ2VudHJvJz48aW1nIHNyYz0nL3NoYXJlZC9jc3MvaW1nL3RyYW5zc'+
'C5naWYnIC8+PC9hPjx1bCBvbm1vdXNlb3Zlcj0ibGlua0NlbnRyby5jbGFzc05hbWU9J2NlbnRyb2Rla'+
'W5mb3JtYWNvZXNob3Zlcic7IiBvbm1vdXNlb3V0PSJsaW5rQ2VudHJvLmNsYXNzTmFtZT0nY2VudHJvZ'+
'GVpbmZvcm1hY29lcyc7Ij48bGk+PGEgaHJlZj0nL3B0LWJyL2VkdWNhY2lvbmFsL2N1cnNvcy9jdXJzb'+
'3MuYXNweCcgdGFyZ2V0PScnPkN1cnNvczwvYT48L2xpPjxsaT48YSBocmVmPScvcHQtYnIvZWR1Y2Fja'+
'W9uYWwvc2ltdWxhZG9yZXMvc2ltdWxhZG9yZXMuYXNweCcgdGFyZ2V0PScnPlNpbXVsYWRvcmVzPC9hP'+
'jwvbGk+PGxpPjxhIGhyZWY9Jy9wdC1ici9lZHVjYWNpb25hbC9vcmNhbWVudG8tcGVzc29hbC5hc3B4J'+
'yB0YXJnZXQ9Jyc+T3LDp2FtZW50byBwZXNzb2FsPC9hPjwvbGk+PGxpPjxhIGhyZWY9Jy9zaGFyZWQva'+
'WZyYW1lLmFzcHg/aWRpb21hPXB0LWJyJnVybD1odHRwOi8vd3d3LmJtZmJvdmVzcGEuY29tLmJyL3B0L'+
'WJyL2VkdWNhY2lvbmFsL2VkdWNhci9Gb3JtSW5zY3JpY2FvUGFsZXN0cmFBY2Vzc29JbnN0LmFzcCc'+
'gdGFyZ2V0PScnPlBhbGVz');
Parameters.Add('__EVENTVALIDATION=/wEWMAKU1bzjDAKatY+lDgLz2ISXCALR05XvBgKW'+
'jICHCwKn1oTUCwLzhvO8BQLzht/hDALzhsuGBALzhteEAQLzhsOpCALzhq/ODwLzhpvzBgLzhqfxAwL'+
'zhpOWCwLzhv+6AgLzhuvfCQLzhvfdBgLzhuOCDgLzhs+nBQLzhrvMDALzhsfKCQLzhrNvAvOGn5QIAv'+
'OGi7kPAvOGl7cMAvOGg9wDAvOG74ALAvOG26UCAvOG56MPAvOG08gGAvOGv+0NAo3a1W8CjNrVbwKP2'+
'tVvAo7a1W8CidrVbwKI2tVvAova1W8CitrVbwKV2tVvApTa1W8CpqKfswMCrqXL7AcChv7z9w4C4/vLv'+
'gUCo/HJ+QsCtLPk8g6HXv3ITGyMQJG6GJIiOc0sGh7cpg==');
Parameters.Add('ctl00$ucTopo$btnBusca=Busca');
Parameters.Add('ctl00$menuBOVESPASecundario=');
Parameters.Add('ctl00$contentPlaceHolderConteudo$tabPosicaoEmAberto={"State":{},"TabState":{"ctl00_contentPlaceHolderConteudo_tabPosicaoEmAberto_tabAcoes":{"Selected":true}}}');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaData$txtConsultaData=2014-07-22');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaData$txtConsultaData$dateInput=2014-07-22-00-00-00');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaData_txtConsultaData_calendar_SD=[]');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaData_txtConsultaData_calendar_AD=[[2014,5,22],[2014,7,22],[2014,7,22]]');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaEmpresa=');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaDataDownload$txtConsultaDataDownload=2014-07-02');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaDataDownload$txtConsultaDataDownload$dateInput=2014-07-02-00-00-00');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaDataDownload_txtConsultaDataDownload_calendar_SD=[]');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaDataDownload_txtConsultaDataDownload_calendar_AD=[[2014,5,22],[2014,7,22],[2014,7,22]]');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$btnBuscarArquivos=Buscar');
Parameters.Add('ctl00$contentPlaceHolderConteudo$mpgPaginas_Selected=0');
Parameters.Add('cboAgentesCorretorasNome=#');
Parameters.Add('cboAgentesCorretorasCodigo=#');
http.HandleRedirects := true;
http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36';
http.AllowCookies := True;
http.Request.ContentType := 'application/x-www-form-urlencoded';
http.Post(url,Parameters,Response);
MS.SaveToFile('C:\teste.dat');
except
WriteLn(IntToStr(code));
finally
http.Free();
FreeAndNil(parameters);
FreeAndNil(response);
ReadLn;
end;
end.
I don't know how to get the file or even if I sending the right parameters.
Any suggetions?
Thanks in advance!
EDIT:
I fount out that the ViewState and the EventValidation parameters change from time to time, so now I got this:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, idHTTP, Classes, MSHTML, SHDocVw, Httpapp, System.Variants, idURI;
function ExtractHiddenParameter(const ParameterName: string; const Request: string): string;
const
PrefixMask = 'input type="hidden" name="%s" id="%s" value="';
Suffix = '" />';
var
Prefix: string;
PrefixLength: Integer;
PrefixPosition: Integer;
SuffixPosition: Integer;
begin
Prefix := Format(PrefixMask, [ParameterName, ParameterName]);
PrefixPosition := Pos(Prefix, Request);
if PrefixPosition = 0 then
Result := ''
else
begin
PrefixLength := Length(Prefix);
Result := Copy(Request,
PrefixPosition + PrefixLength,
1 + Length(Request) - PrefixPosition - PrefixLength);
SuffixPosition := Pos(Suffix, Result);
if SuffixPosition = 0 then
Result := ''
else
Delete(Result, SuffixPosition, 1 + Length(Result) - SuffixPosition);
end;
end;
var
http: TIdHttp;
url: string;
getRequest: string;
code: integer;
parameters: TStringList;
Response: TStringStream;
Resultado: string;
sViewState: string;
sEventValidation: string;
MS: TMemoryStream;
begin
url := 'http://www.bmfbovespa.com.br/BancoTitulosBTC/PosicoesEmAberto.aspx?Idioma=pt-br';
http := TIdHTTP.Create(nil);
parameters := TStringList.Create;
Response := TStringStream.Create;
MS := TMemoryStream.Create;
try
try
http.ProxyParams.ProxyServer := 'proxy-scl';
http.ProxyParams.ProxyPort := 3128;
http.HandleRedirects := true;
http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36';
http.AllowCookies := True;
getRequest := http.Get(url);
sViewState := ExtractHiddenParameter('__VIEWSTATE', getRequest);
sEventValidation := ExtractHiddenParameter('__EVENTVALIDATION', getRequest);
Parameters.Add('__EVENTTARGET=');
Parameters.Add('__EVENTARGUMENT=');
Parameters.Add('__VIEWSTATE='+sViewState);
Parameters.Add('__EVENTVALIDATION'+sEventValidation);
Parameters.Add('ctl00$ucTopo$btnBusca=Busca');
Parameters.Add('ctl00$menuBOVESPASecundario=');
Parameters.Add('ctl00$contentPlaceHolderConteudo$tabPosicaoEmAberto={"State":{},"TabState":{"ctl00_contentPlaceHolderConteudo_tabPosicaoEmAberto_tabAcoes":{"Selected":true}}}');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaData$txtConsultaData=2014-07-22');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaData$txtConsultaData$dateInput=2014-07-22-00-00-00');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaData_txtConsultaData_calendar_SD=[]');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaData_txtConsultaData_calendar_AD=[[2014,5,22],[2014,7,22],[2014,7,22]]');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaDataDownload$txtConsultaDataDownload=2014-07-02');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$txtConsultaDataDownload$txtConsultaDataDownload$dateInput=2014-07-02-00-00-00');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaDataDownload_txtConsultaDataDownload_calendar_SD=[]');
Parameters.Add('ctl00_contentPlaceHolderConteudo_acoes_txtConsultaDataDownload_txtConsultaDataDownload_calendar_AD=[[2014,5,22],[2014,7,22],[2014,7,22]]');
Parameters.Add('ctl00$contentPlaceHolderConteudo$acoes$btnBuscarArquivos=Buscar');
Parameters.Add('ctl00$contentPlaceHolderConteudo$mpgPaginas_Selected=0');
Parameters.Add('cboAgentesCorretorasNome=#');
Parameters.Add('cboAgentesCorretorasCodigo=#');
http.Head(url);
code := http.ResponseCode;
http.Request.ContentType := 'application/x-www-form-urlencoded';
http.Post(url,Parameters,Response);
MS.SaveToFile('C:\teste.dat');
except
on E: EIdHTTPProtocolException do
code := http.ResponseCode;
end;
WriteLn(IntToStr(code));
finally
http.Free();
FreeAndNil(parameters);
FreeAndNil(response);
ReadLn;
end;
end.
You were very close.
just change the line
MS.SaveToFile('C:\teste.dat');
into
Response.SaveToFile('C:\teste.dat');
you can remove the TMemoryStream from your code, it is not needed