aws_24.0.0_2b75fe6d/src/core/aws-url.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
------------------------------------------------------------------------------
--                              Ada Web Server                              --
--                                                                          --
--                     Copyright (C) 2000-2021, AdaCore                     --
--                                                                          --
--  This library is free software;  you can redistribute it and/or modify   --
--  it under terms of the  GNU General Public License  as published by the  --
--  Free Software  Foundation;  either version 3,  or (at your  option) any --
--  later version. This library is distributed in the hope that it will be  --
--  useful, but WITHOUT ANY WARRANTY;  without even the implied warranty of --
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    --
--                                                                          --
--  As a special exception under Section 7 of GPL version 3, you are        --
--  granted additional permissions described in the GCC Runtime Library     --
--  Exception, version 3.1, as published by the Free Software Foundation.   --
--                                                                          --
--  You should have received a copy of the GNU General Public License and   --
--  a copy of the GCC Runtime Library Exception along with this program;    --
--  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see   --
--  <http://www.gnu.org/licenses/>.                                         --
--                                                                          --
--  As a special exception, if other files instantiate generics from this   --
--  unit, or you link this unit with other files to produce an executable,  --
--  this  unit  does not  by itself cause  the resulting executable to be   --
--  covered by the GNU General Public License. This exception does not      --
--  however invalidate any other reasons why the executable file  might be  --
--  covered by the  GNU Public License.                                     --
------------------------------------------------------------------------------

pragma Ada_2012;

with Ada.Strings.Maps;
with Ada.Strings.Unbounded;

with AWS.Parameters;

package AWS.URL is

   use Ada;
   use Ada.Strings.Unbounded;

   --  The general URL form as described in RFC2616 is:
   --
   --  http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
   --
   --  Note also that there are different RFC describing URL like the 2616 and
   --  1738 but they use different terminologies. Here we try to follow the
   --  names used in RFC2616 but we have implemented some extensions at the
   --  end of this package. For example the way Path and File are separated or
   --  the handling of user/password which is explicitly not allowed in the
   --  RFC but are used and supported in many browsers. Here are the extended
   --  URL supported:
   --
   --  http://user:pass@www.here.com:80/dir1/dir2/xyz.html?p=8&x=doh#anchor
   --   |                    |       | |          |       |         |
   --   protocol             host port path       file   parameters fragment
   --
   --                                  <--  pathname  -->

   type Object is private;

   URL_Error : exception;

   Default_FTP_Port   : constant := 21;
   Default_HTTP_Port  : constant := 80;
   Default_HTTPS_Port : constant := 443;

   function Parse
     (URL            : String;
      Check_Validity : Boolean := True;
      Normalize      : Boolean := False) return Object;
   --  Parse an URL and return an Object representing this URL. It is then
   --  possible to extract each part of the URL with the services bellow.
   --  Raises URL_Error if Check_Validity is true and the URL reference a
   --  resource above the web root directory.

   procedure Normalize (URL : in out Object);
   --  Removes all occurrences to parent directory ".." and current directory
   --  ".". Raises URL_Error if the URL reference a resource above the Web
   --  root directory.

   function Is_Valid (URL : Object) return Boolean;
   --  Returns True if the URL is valid (does not reference directory above
   --  the Web root).

   function URL (URL : Object) return String;
   --  Returns full URL string, this can be different to the URL passed if it
   --  has been normalized.

   function Protocol_Name (URL : Object) return String;
   --  Returns "http" or "https" depending on the protocol used by URL

   function Host
     (URL : Object; IPv6_Brackets : Boolean := False) return String;
   --  Returns the hostname in IPv6 breakets if necessary

   function Port (URL : Object) return Positive;
   --  Returns the port as a positive

   function Port (URL : Object) return String;
   --  Returns the port as a string

   function Port_Not_Default (URL : Object) return String;
   --  Returns the port image (preceded by character ':') if it is not the
   --  default port. Returns the empty string otherwise.

   function Abs_Path (URL : Object) return String;
   --  Returns the absolute path. This is the complete resource reference
   --  without the query part.

   function Query (URL : Object) return String;
   --  Returns the Query part of the URL or the empty string if none was
   --  specified. Note that character '?' is not part of the Query and is
   --  therefore not returned.

   --
   --  Below are extended API not part of the RFC 2616 URL specification
   --

   function User (URL : Object) return String;
   --  Returns user name part of the URL. Returns the empty string if user was
   --  not specified.

   function Password (URL : Object) return String;
   --  Returns user's password part of the URL. Returns the empty string if
   --  password was not specified.

   function Server_Name
     (URL : Object; IPv6_Brackets : Boolean := False) return String
     renames Host;

   function Security (URL : Object) return Boolean;
   --  Returns True if it is a Secure HTTP (HTTPS) URL

   function Path (URL : Object) return String;
   --  Returns the Path (including the leading slash). If Encode is True then
   --  the URL will be encoded using the Encode routine.

   function File (URL : Object) return String;
   --  Returns the File. If Encode is True then the URL will be encoded using
   --  the Encode routine. Not that by File here we mean the latest part of
   --  the URL, it could be a real file or a diretory into the filesystem.
   --  Parent and current directories are part of the path.

   function Parameters (URL : Object) return String;
   --  Returns the Parameters (including the starting ? character). If Encode
   --  is True then the URL will be encoded using the Encode routine.

   function Pathname (URL : Object) return String renames Abs_Path;

   function Pathname_And_Parameters (URL : Object) return String;
   --  Returns the pathname and the parameters. This is equivalent to:
   --  Pathname & Parameters.

   function Parameter
     (URL : Object; Name : String; N : Positive := 1) return String
     with Inline;
   --  Returns the Nth value associated with Key into Table. Returns
   --  the emptry string if key does not exist.

   function Parameters (URL : Object) return AWS.Parameters.List with Inline;
   --  Return the parameter list associated with the URL

   function Fragment (URL : Object) return String with Inline;
   --  Return the part after the # sign (included)

   --
   --  URL Resolution
   --

   function Resolve (URL : Object; Base_URL : Object) return Object;
   --  Resolve an URL relative to a Base_URL. Uses RFC 3986, section 5.2
   --  algorithm.

   function Resolve (URL : String; Base_URL : String) return String;
   --  Resolve an URL relatively to a Base_URL. Same function as above, but
   --  working with Strings.

   --
   --  URL Encoding and Decoding
   --

   Parameters_Encoding_Set : constant Strings.Maps.Character_Set;
   --  Encoding set enought for HTTP parameters

   Default_Encoding_Set : constant Strings.Maps.Character_Set;
   --  Encoding set enought for all URL parts

   function Encode
     (Str          : String;
      Encoding_Set : Strings.Maps.Character_Set := Default_Encoding_Set)
      return String;
   --  Encode Str into a URL-safe form. Many characters are forbiden into an
   --  URL and needs to be encoded. A character is encoded by %XY where XY is
   --  the character's ASCII hexadecimal code. For example a space is encoded
   --  as %20.

   function Decode (Str : String) return String;
   --  This is the opposite of Encode above

   function Decode (Str : Unbounded_String) return Unbounded_String;

private

   use type Ada.Strings.Maps.Character_Set;

   type Path_Status is (Valid, Wrong);

   HTTP  : constant Unbounded_String := To_Unbounded_String ("http");
   HTTPS : constant Unbounded_String := To_Unbounded_String ("https");
   FTP   : constant Unbounded_String := To_Unbounded_String ("ftp");
   WS    : constant Unbounded_String := To_Unbounded_String ("ws");
   WSS   : constant Unbounded_String := To_Unbounded_String ("wss");

   type Object is record
      User       : Unbounded_String;
      Password   : Unbounded_String;
      Host       : Unbounded_String;
      Port       : Natural           := Default_HTTP_Port;
      Protocol   : Unbounded_String  := HTTP;
      Path       : Unbounded_String; -- Original path
      N_Path     : Unbounded_String; -- Normalized path
      File       : Unbounded_String;
      Status     : Path_Status       := Wrong;
      Parameters : aliased AWS.Parameters.List;
      Fragment   : Unbounded_String;
   end record;

   Parameters_Encoding_Set : constant Strings.Maps.Character_Set :=
                               Strings.Maps.To_Set ("&=+ <>?#%@")
                               or Strings.Maps.To_Set
                                    (Span => (Low  => Character'Val (128),
                                              High => Character'Last))
                               or Strings.Maps.To_Set
                                    (Span => (Low  => Character'First,
                                              High => Character'Val (31)));
   Default_Encoding_Set : constant Strings.Maps.Character_Set :=
                            Parameters_Encoding_Set
                            or Strings.Maps.To_Set (";/:$,""{}|\^[]`'()");

   function Decode (Str : String; In_Params : Boolean) return String;
   --  Decode URL Str. In_Params is set to True when decoding the
   --  parameters URL's fragment.

end AWS.URL;