In handling form-data it was impossible to handle, via the HTML-Form POST 
method, arbitrary parameters because lack of a filter ensured that no 
parameters were processed. Following is the fix [in source-file 
gnoga-server-connection.adb] I’ve been using, though this results in some 
constraints for processing which prevent multi-user simultaneous access 
(because post parameters are handled individually, therefore simultaneous 
submissions cannot be handled).

   overriding
   procedure Do_Body (Client : in out Gnoga_HTTP_Client) is
      use Ada.Strings.Fixed;
      use Ada.Strings.Unbounded;
      use Ada.Streams.Stream_IO;

      function "+"(Right : Unbounded_String) return String is
         (Strings_Edit.UTF8.Handling.To_UTF8 (To_String (Right))) with Inline;

      Status : Status_Line renames Get_Status_Line (Client);

      Param_List   : Unbounded_String;
      Do_Filtering : constant Boolean := On_Post_Request_Event /= null;

      Content_Type : constant String :=
        Client.Get_Header (Content_Type_Header);
      Disposition  : constant String := Client.Get_Multipart_Header
        (Content_Disposition_Header);
  begin

      if Do_Filtering then
         On_Post_Request_Event (Status.File & Status.Query, Param_List);
      end if;

      if Content_Type = "application/x-www-form-urlencoded" then
         if Do_Filtering then
            Client.Receive_Body (+Param_List);
         else
            Client.Receive_Body;
         end if;
      end if;

      if Index (Content_Type, "multipart/form-data") = Content_Type'First then

         if Index (Disposition, "form-data") = Disposition'First  then
            declare
               Field_ID : constant String := "name=""";
               File_ID  : constant String := "filename=""";

               n : constant Natural := Index (Disposition, Field_ID);
               f : constant Natural := Index (Disposition, File_ID);
            begin

               if n /= 0 then
                  declare
                     Eq : constant Natural := Index
                       (Disposition, """", n + Field_ID'Length);
                     Field_Name : constant String := Disposition
                       (n + Field_ID'Length .. Eq - 1);
                  begin -- (not Do_Filtering) or else
                     if (not Do_Filtering) or else Index (+Param_List, 
Field_Name) > 0 then

                        if f /= 0 then
                           declare
                              Eq : constant Natural := Index
                                (Disposition, """", f + File_ID'Length);
                              File_Name : constant String := Disposition
                                (f + File_ID'Length .. Eq - 1);
                           begin
                              if On_Post_File_Event = null then
                                 Gnoga.Log ("Attempt to upload file with out" &
                                              " an On_Post_File_Event set");
                              else
                                 if Is_Open (Client.Content.FS) then
                                    Close (Client.Content.FS);
                                 end if;

                                 Create (Client.Content.FS,
                                         Out_File,
                                         Gnoga.Server.Upload_Directory &
                                           File_Name & ".tmp",
                                         "Text_Translation=No");

                                 Receive_Body
                                   (Client, Stream (Client.Content.FS));

                                 On_Post_File_Event (Status.File & Status.Query,
                                                     File_Name,
                                                     File_Name & ".tmp");
                              end if;
                           end;
                        else
                           Client.Content.Text.Rewind;
                           Client.Receive_Body (Client.Content.Text'Access);
                        end if;
                     end if;
                  end;
               end if;
            end;
         end if;
      end if;
   exception
      when E : others =>
         Log ("Do_Body Error");
         Log (Ada.Exceptions.Exception_Information (E));
   end Do_Body;

There is another limitation, one where any particular parameter cannot exceed 
500 characters, this limit is set in the definition Gnoga_HTTP_Content, in the 
same source-file. Shown below.
   type Gnoga_HTTP_Content is new Content_Source with
      record
         Socket          : Socket_Type           := null;
         Connection_Type : Gnoga_Connection_Type := HTTP;
         Connection_Path : Ada.Strings.Unbounded.Unbounded_String;
         FS              : Ada.Streams.Stream_IO.File_Type;
         Input_Overflow  : String_Buffer;
         Buffer          : String_Buffer;
         Finalized       : Boolean := False;
         Text            : aliased Strings_Edit.Streams.String_Stream (500);
      end record;

I am working on a fix for this, the simplest would be to increase the 
discriminant to, say, 4096… but this merely moves the constraint to 4KB, 
instead of memory arbitrary [arguments may be made for both], so I will likely 
experiment on it to see if I can get a less-limited solution.
_______________________________________________
Gnoga-list mailing list
Gnoga-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gnoga-list

Reply via email to