comp.lang.ada
 help / color / mirror / Atom feed
From: "Rego, P." <pvrego@gmail.com>
Subject: Re: Simple parse from https website
Date: Thu, 2 Apr 2020 11:27:27 -0700 (PDT)
Date: 2020-04-02T11:27:27-07:00	[thread overview]
Message-ID: <16db176e-7625-4c0a-bcb4-4968981065f5@googlegroups.com> (raw)
In-Reply-To: <r656l2$qot$1@gioia.aioe.org>

> 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.

Omg... (almost) Perfect(!lol)...just discovered that GNAT.Sockets has a signature change, some subpackages are no more exposed (like GNAT.SOCKETS.Server). I am using GNAT Community 2019.

Builder results
        17:6 file "g-scstma.ads" not found
        6:6 file "g-socser.ads" not found
        7:6 file "g-socser.ads" not found
        18:6 file "g-socser.ads" not found
        8:6 file "openssl.ads" not found
        9:6 file "parsers.ads" not found
        10:6 file "parsers.ads" not found
        19:6 file "parsers.ads" not found
        20:6 file "stack_storage.ads" not found
        11:6 file "strings_edit.ads" not found
        12:6 file "strings_edit.ads" not found
        13:6 file "strings_edit.ads" not found
        14:6 file "strings_edit.ads" not found
        15:6 file "test_http_servers.ads" not found


  reply	other threads:[~2020-04-02 18:27 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
2020-04-02 18:27       ` Rego, P. [this message]
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