1----------------------------------------------------------------------- 2-- util-http-clients -- HTTP Clients 3-- Copyright (C) 2011, 2012, 2015 Stephane Carrez 4-- Written by Stephane Carrez (Stephane.Carrez@gmail.com) 5-- 6-- Licensed under the Apache License, Version 2.0 (the "License"); 7-- you may not use this file except in compliance with the License. 8-- You may obtain a copy of the License at 9-- 10-- http://www.apache.org/licenses/LICENSE-2.0 11-- 12-- Unless required by applicable law or agreed to in writing, software 13-- distributed under the License is distributed on an "AS IS" BASIS, 14-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15-- See the License for the specific language governing permissions and 16-- limitations under the License. 17----------------------------------------------------------------------- 18 19with Ada.Finalization; 20 21with Util.Http.Cookies; 22 23-- == Client == 24-- The <tt>Util.Http.Clients</tt> package defines a set of API for an HTTP client to send 25-- requests to an HTTP server. 26-- 27-- === GET request === 28-- To retrieve a content using the HTTP GET operation, a client instance must be created. 29-- The response is returned in a specific object that must therefore be declared: 30-- 31-- Http : Util.Http.Clients.Client; 32-- Response : Util.Http.Clients.Response; 33-- 34-- Before invoking the GET operation, the client can setup a number of HTTP headers. 35-- 36-- Http.Add_Header ("X-Requested-By", "wget"); 37-- 38-- The GET operation is performed when the <tt>Get</tt> procedure is called: 39-- 40-- Http.Get ("http://www.google.com", Response); 41-- 42-- Once the response is received, the <tt>Response</tt> object contains the status of the 43-- HTTP response, the HTTP reply headers and the body. A response header can be obtained 44-- by using the <tt>Get_Header</tt> function and the body using <tt>Get_Body</tt>: 45-- 46-- Body : constant String := Response.Get_Body; 47-- 48package Util.Http.Clients is 49 50 Connection_Error : exception; 51 52 -- ------------------------------ 53 -- Http response 54 -- ------------------------------ 55 -- The <b>Response</b> type represents a response returned by an HTTP request. 56 type Response is limited new Abstract_Response with private; 57 58 -- Returns a boolean indicating whether the named response header has already 59 -- been set. 60 overriding 61 function Contains_Header (Reply : in Response; 62 Name : in String) return Boolean; 63 64 -- Returns the value of the specified response header as a String. If the response 65 -- did not include a header of the specified name, this method returns null. 66 -- If there are multiple headers with the same name, this method returns the 67 -- first head in the request. The header name is case insensitive. You can use 68 -- this method with any response header. 69 overriding 70 function Get_Header (Reply : in Response; 71 Name : in String) return String; 72 73 -- Sets a message header with the given name and value. If the header had already 74 -- been set, the new value overwrites the previous one. The containsHeader 75 -- method can be used to test for the presence of a header before setting its value. 76 overriding 77 procedure Set_Header (Reply : in out Response; 78 Name : in String; 79 Value : in String); 80 81 -- Adds a request header with the given name and value. 82 -- This method allows request headers to have multiple values. 83 overriding 84 procedure Add_Header (Reply : in out Response; 85 Name : in String; 86 Value : in String); 87 88 -- Iterate over the response headers and executes the <b>Process</b> procedure. 89 overriding 90 procedure Iterate_Headers (Reply : in Response; 91 Process : not null access 92 procedure (Name : in String; 93 Value : in String)); 94 95 -- Get the response body as a string. 96 overriding 97 function Get_Body (Reply : in Response) return String; 98 99 -- Get the response status code. 100 overriding 101 function Get_Status (Reply : in Response) return Natural; 102 103 -- ------------------------------ 104 -- Http client 105 -- ------------------------------ 106 -- The <b>Client</b> type allows to execute HTTP GET/POST requests. 107 type Client is limited new Abstract_Request with private; 108 type Client_Access is access all Client; 109 110 -- Returns a boolean indicating whether the named response header has already 111 -- been set. 112 overriding 113 function Contains_Header (Request : in Client; 114 Name : in String) return Boolean; 115 116 -- Returns the value of the specified request header as a String. If the request 117 -- did not include a header of the specified name, this method returns null. 118 -- If there are multiple headers with the same name, this method returns the 119 -- first head in the request. The header name is case insensitive. You can use 120 -- this method with any response header. 121 overriding 122 function Get_Header (Request : in Client; 123 Name : in String) return String; 124 125 -- Sets a header with the given name and value. If the header had already 126 -- been set, the new value overwrites the previous one. The containsHeader 127 -- method can be used to test for the presence of a header before setting its value. 128 overriding 129 procedure Set_Header (Request : in out Client; 130 Name : in String; 131 Value : in String); 132 133 -- Adds a header with the given name and value. 134 -- This method allows headers to have multiple values. 135 overriding 136 procedure Add_Header (Request : in out Client; 137 Name : in String; 138 Value : in String); 139 140 -- Iterate over the request headers and executes the <b>Process</b> procedure. 141 overriding 142 procedure Iterate_Headers (Request : in Client; 143 Process : not null access 144 procedure (Name : in String; 145 Value : in String)); 146 147 -- Removes all headers with the given name. 148 procedure Remove_Header (Request : in out Client; 149 Name : in String); 150 151 -- Adds the specified cookie to the request. This method can be called multiple 152 -- times to set more than one cookie. 153 procedure Add_Cookie (Http : in out Client; 154 Cookie : in Util.Http.Cookies.Cookie); 155 156 -- Execute an http GET request on the given URL. Additional request parameters, 157 -- cookies and headers should have been set on the client object. 158 procedure Get (Request : in out Client; 159 URL : in String; 160 Reply : out Response'Class); 161 162 -- Execute an http POST request on the given URL. The post data is passed in <b>Data</b>. 163 -- Additional request cookies and headers should have been set on the client object. 164 procedure Post (Request : in out Client; 165 URL : in String; 166 Data : in String; 167 Reply : out Response'Class); 168 169private 170 171 subtype Http_Request is Abstract_Request; 172 subtype Http_Request_Access is Abstract_Request_Access; 173 174 subtype Http_Response is Abstract_Response; 175 subtype Http_Response_Access is Abstract_Response_Access; 176 177 type Http_Manager is interface; 178 type Http_Manager_Access is access all Http_Manager'Class; 179 180 procedure Create (Manager : in Http_Manager; 181 Http : in out Client'Class) is abstract; 182 183 procedure Do_Get (Manager : in Http_Manager; 184 Http : in Client'Class; 185 URI : in String; 186 Reply : out Response'Class) is abstract; 187 188 procedure Do_Post (Manager : in Http_Manager; 189 Http : in Client'Class; 190 URI : in String; 191 Data : in String; 192 Reply : out Response'Class) is abstract; 193 194 Default_Http_Manager : Http_Manager_Access; 195 196 type Response is limited new Ada.Finalization.Limited_Controlled 197 and Abstract_Response with record 198 Delegate : Abstract_Response_Access; 199 end record; 200 201 -- Free the resource used by the response. 202 overriding 203 procedure Finalize (Reply : in out Response); 204 205 type Client is limited new Ada.Finalization.Limited_Controlled 206 and Abstract_Request with record 207 Manager : Http_Manager_Access; 208 Delegate : Http_Request_Access; 209 end record; 210 211 -- Initialize the client 212 overriding 213 procedure Initialize (Http : in out Client); 214 215 overriding 216 procedure Finalize (Http : in out Client); 217 218end Util.Http.Clients; 219