From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 2002:a37:648:: with SMTP id 69mr5089104qkg.353.1585852048377; Thu, 02 Apr 2020 11:27:28 -0700 (PDT) X-Received: by 2002:aca:4403:: with SMTP id r3mr291759oia.84.1585852048114; Thu, 02 Apr 2020 11:27:28 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!news.uzoreto.com!feeder1.cambriumusenet.nl!feed.tweak.nl!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Thu, 2 Apr 2020 11:27:27 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: google-groups.googlegroups.com; posting-host=179.35.31.165; posting-account=TRgI1QoAAABSsYi-ox3Pi6N-JEKKU0cu NNTP-Posting-Host: 179.35.31.165 References: <7dc6d888-696c-4936-b678-66e1c8198449@googlegroups.com> <1751295b-bd07-4a29-8181-2a24764e1644@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <16db176e-7625-4c0a-bcb4-4968981065f5@googlegroups.com> Subject: Re: Simple parse from https website From: "Rego, P." Injection-Date: Thu, 02 Apr 2020 18:27:28 +0000 Content-Type: text/plain; charset="UTF-8" Xref: reader01.eternal-september.org comp.lang.ada:58286 Date: 2020-04-02T11:27:27-07:00 List-Id: > 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