comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Simple parse from https website
Date: Thu, 2 Apr 2020 19:16:19 +0200
Date: 2020-04-02T19:16:19+02:00	[thread overview]
Message-ID: <r656l2$qot$1@gioia.aioe.org> (raw)
In-Reply-To: 1751295b-bd07-4a29-8181-2a24764e1644@googlegroups.com

On 2020-04-02 16:48, Rego, P. wrote:

> Ops...not, just testing more simpler cases. I am trying to get the data from
> https://poloniex.com/public?command=returnTicker
> 
> Just tried with google to check if it's problem from polo ticker. But the exception was the same.

No, that site looks OK. I modified my OpenSSL HTTP client. I just added 
JSON parser and procedure Dump to print the JSON object:

----------------------------- test_https_openssl_json_client.adb -----
with Ada.Exceptions;               use Ada.Exceptions;
with Ada.Text_IO;                  use Ada.Text_IO;
with Ada.Streams;                  use Ada.Streams;
--with GNAT.Exception_Traces;      use GNAT.Exception_Traces;
with GNAT.Sockets.Server.Handles;  use GNAT.Sockets.Server.Handles;
with GNAT.Sockets.Server.OpenSSL;  use GNAT.Sockets.Server.OpenSSL;
with OpenSSL;                      use OpenSSL;
with Parsers.JSON;                 use Parsers.JSON;
with Parsers.JSON.String_Source;   use Parsers.JSON.String_Source;
with Strings_Edit.Integers;        use Strings_Edit.Integers;
with Strings_Edit.Quoted;          use Strings_Edit.Quoted;
with Strings_Edit.Streams;         use Strings_Edit.Streams;
with Strings_Edit.Long_Floats;     use Strings_Edit.Long_Floats;
with Test_HTTP_Servers.OpenSSL;    use Test_HTTP_Servers.OpenSSL;

with GNAT.Sockets.Connection_State_Machine.HTTP_Client.Signaled;
with GNAT.Sockets.Server.Pooled;
with Parsers.String_Source;
with Stack_Storage;

procedure Test_HTTPS_OpenSSL_JSON_Client is
    use GNAT.Sockets.Connection_State_Machine.HTTP_Client.Signaled;

    Address : constant String := "poloniex.com";
    Path    : constant String := "public?command=returnTicker";
    Port    : constant := 443;

    procedure Dump (Prefix : String; Value : JSON_Value) is
    begin
       case Value.JSON_Type is
          when JSON_Boolean =>
             Put_Line (Prefix & Boolean'Image (Value.Condition));
          when JSON_Null =>
             Put_Line (Prefix & "null");
          when JSON_Number =>
             Put_Line (Prefix & Image (Value.Value));
          when JSON_String =>
             Put_Line (Prefix & Quote (Value.Text.all));
          when JSON_Array =>
             Put_Line (Prefix & "(");
             for Index in Value.Sequence'Range loop
                Dump (Prefix & "   ", Value.Sequence (Index));
             end loop;
             Put_Line (Prefix & ")");
          when JSON_Object =>
             Put_Line (Prefix & "{");
             for Index in Value.Map'Range loop
                Put_Line (Prefix & "   " & Value.Map (Index).Name.all & 
"=");
                Dump (Prefix & "      ", Value.Map (Index).Value);
             end loop;
             Put_Line (Prefix & "}");
       end case;
    end Dump;
begin
    declare
       Factory : aliased HTTPS_OpenSSL_Factory
                         (  Request_Length  => 200,
                            Input_Size      => 40,
                            Output_Size     => 1024,
                            Decoded_Size    => 40,
                            Max_Connections => 100
                         );
    begin
       Set_Default_Verify_Paths (Factory, Client_Context);
       declare
          Message   : aliased String_Stream (1024 * 100);
          Server    : aliased GNAT.Sockets.Server.
                              Connections_Server (Factory'Access, 0);
          Reference : GNAT.Sockets.Server.Handles.Handle;
       begin
          Put_Line ("HTTP client started");
          Set
          (  Reference,
             new HTTP_Session_Signaled
                 (  Server'Unchecked_Access,
                    200,
                    512,
                    1024
          )      );
          declare
             Client : HTTP_Session_Signaled renames
                      HTTP_Session_Signaled (Ptr (Reference).all);
          begin
             Connect (Client, Address, Port);
             Get
             (  Client,
                "https://" & Address & "/" & Path,
                Message'Unchecked_Access
             );
             Wait (Client, False);
             Put_Line
             (  Image (Get_Response_Code (Client))
             &  " "
             &  Get_Response_Reason (Client)
             &  " Message >>>>>>>>>>>>>>>>>>>>"
             );
             declare
                Content : aliased String := Get (Message);
                Source  : aliased Parsers.String_Source.
                                  Source (Content'Access);
                Arena   : aliased Stack_Storage.Pool (1024, 10);
                Data    : constant JSON_Value :=
                                   Parse (Source'Access, Arena'Access);
             begin
                Dump ("", Data);
             end;
             Put_Line ("<<<<<<<<<<<<<<<<<<<< Message");
          end;
          Put_Line ("HTTP client stopping");
       end;
    end;
exception
    when Error : others =>
       Put_Line ("Error: " & Exception_Information (Error));
end Test_HTTPS_OpenSSL_JSON_Client;
----------------------------- test_https_openssl_json_client.adb -----

It connects fine and spills lots of garbage like:

   ...
    USDT_SNX=
       {
          id=
             290.9999999999999
          last=
             "0.00000000"
          lowestAsk=
             "0.00000000"
          highestBid=
             "0.00000000"
          percentChange=
             "0.00000000"
          baseVolume=
             "0.00000000"
          quoteVolume=
             "0.00000000"
          isFrozen=
             "0"
          high24hr=
             "0.00000000"
          low24hr=
             "0.00000000"
       }
    TRX_SNX=
       {
          id=
             292.0000000000000
          last=
             "0.00000000"
          lowestAsk=
             "0.00000000"
          highestBid=
             "0.00000000"
          percentChange=
             "0.00000000"
     ...

and so on. Funny enough, they put numbers as strings, so it seems.

It is not very efficient as written. You see, the code it accumulates 
all response in a string stream buffer. Then takes a string from that. 
Then it parses the obtained string into a JSON object. So it is two 
copies too many. One could parse the response on the fly without 
accumulating it whole in the memory. But it would mean more efforts.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

  reply	other threads:[~2020-04-02 17:16 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-02 13:58 Simple parse from https website Rego, P.
2020-04-02 14:24 ` Egil H H
2020-04-02 14:44   ` Rego, P.
2020-04-03  9:35     ` Björn Lundin
2020-04-03 12:04       ` Rego, P.
2020-04-02 14:42 ` Dmitry A. Kazakov
2020-04-02 14:48   ` Rego, P.
2020-04-02 17:16     ` Dmitry A. Kazakov [this message]
2020-04-02 18:27       ` Rego, P.
2020-04-02 19:05         ` Dmitry A. Kazakov
2020-04-02 19:34           ` Rego, P.
2020-04-03  5:19             ` Jere
2020-04-03 12:13               ` Rego, P.
2020-04-03 12:30                 ` Rego, P.
2020-04-03 12:49                   ` Dmitry A. Kazakov
2020-04-03  6:47             ` Dmitry A. Kazakov
2020-04-03 12:42               ` Rego, P.
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox