Fix escaping of reserved characters.
3 files changed, 29 insertions(+), 14 deletions(-)

M src/oauth-tokens.adb
M src/oauth.adb
M src/twitter.adb
M src/oauth-tokens.adb +10 -7
@@ 238,7 238,8 @@ package body OAuth.Tokens is
       Temp_Token : constant String := To_String (Context.Token);
       Temp_Secret : constant String := To_String (Context.Token_Secret);
       Params : OAuth.Parameter_List.List := Parameters;
-      OAuth_Params : OAuth.Parameter_List.List := Parameters;
+      OAuth_Params : OAuth.Parameter_List.List;
+      OAuth_Params_Copy : OAuth.Parameter_List.List;
       Digest_Val : SHA.Digest;
       Base_Str : Unbounded_String;
       Ctx : HMAC_SHA.HMAC_Context;

          
@@ 255,10 256,12 @@ package body OAuth.Tokens is
             OAuth.Timestamp,
             To_String (Context.Key) & URL),
          Version      => "1.0");
-      OAuth.Parameter_Sorting.Sort (OAuth_Params);
+      OAuth_Params_Copy := OAuth_Params;
+      OAuth.Parameter_Sorting.Sort (OAuth_Params_Copy);
       OAuth.Parameter_Sorting.Sort (Params);
-      OAuth.Parameter_Sorting.Merge (Target => Params, Source => OAuth_Params);
+      OAuth.Parameter_Sorting.Merge (Target => Params, Source => OAuth_Params_Copy);
       Base_Str := +(OAuth.Create_Base_String (Method, URL, Params));
+      Put_Line ("Base string: " & To_String (Base_Str));
 
       HMAC_SHA.Initialize
         (Key     => To_String (Context.Secret) & "&" & Temp_Secret,

          
@@ 268,12 271,12 @@ package body OAuth.Tokens is
       HMAC_SHA.Finalize (Result => Digest_Val,
                          Context => Ctx);
       Sig := +(String (SHA.Strings.B64_From_SHA (Digest_Val)));
-      OAuth.Parameter_List.Append (Params, (Key => +"oauth_signature",
+      OAuth.Parameter_List.Append (OAuth_Params, (Key => +"oauth_signature",
                                             Value => Sig));
-      OAuth.Parameter_List.Prepend (Params, (Key => +"realm",
+      OAuth.Parameter_List.Prepend (OAuth_Params, (Key => +"realm",
                                             Value => +""));
-      OAuth.Parameter_Sorting.Sort (Params);
-      Header := +(OAuth.Params_To_Header (Params));
+      OAuth.Parameter_Sorting.Sort (OAuth_Params);
+      Header := +(OAuth.Params_To_Header (OAuth_Params));
    end Access_Token_Header;
 
 end OAuth.Tokens;

          
M src/oauth.adb +16 -6
@@ 16,15 16,24 @@ package body OAuth is
 
    function URL_Encode (Str : String) return String is
       Reserved : constant String := ":/?#[]@!$&'()*+,;= %";
+
+      -- unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
+      -- ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E),
+      -- underscore (%5F), or tilde (%7E)
       function Is_Reserved (Char : Character) return Boolean is
       begin
-         for I in Reserved'Range loop
-            if Char = Reserved (I) then
+         case Character'Pos(Char) is
+            when 16#41#..16#5A#
+               | 16#61#..16#7A#
+               | 16#30#..16#39#
+               | 16#2D#
+               | 16#2E#
+               | 16#5F#
+               | 16#7E# =>
+               return False;
+            when others =>
                return True;
-            end if;
-         end loop;
-
-         return False;
+         end case;
       end Is_Reserved;
 
       function Escape (Char : Character) return String is

          
@@ 35,6 44,7 @@ package body OAuth is
          Low  : Unsigned_8 := Val and 16#0F#;
 
          Hex_Digits : String := "0123456789ABCDEF";
+         -- Hex_Digits : String := "0123456789abcdef";
       begin
          return "%" & Hex_Digits (1 + Integer (High)) &
            Hex_Digits (1 + Integer (Low));

          
M src/twitter.adb +3 -1
@@ 146,17 146,19 @@ package body Twitter is
       Result : Charbuf.Char_Buffer;
       R_Code : Long_Integer;
    begin
+      Put_Line ("UPDATING STATUS");
       Parameter_List.Append (Extra_Params,
         (To_Unbounded_String ("status"),
           To_Unbounded_String (Message)));
       Tokens.Access_Token_Header
         (Manager.C, Update_Address, "POST", Extra_Params, OAuth_Header);
       Put_Line ("Header: " & To_String (OAuth_Header));
+      Put_Line ("Fields: " & "status=" & OAuth.URL_Encode (Message));
       HTTP.Post_Page
         (URL => Update_Address,
          Header_Key => "Authorization",
          Header_Value => To_String (OAuth_Header),
-         Fields => "status=" & Message,
+         Fields => "status=" & OAuth.URL_Encode (Message),
          Contents => Result,
          Response_Code => R_Code);
       if R_Code /= 200 then