Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for #231 Support for LinkedIn Field-Selector Notation #250

Merged
merged 3 commits into from
May 9, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions RestSharp.IntegrationTests/oAuth1Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,20 @@ public void Properly_Encodes_Parameter_Names()

Assert.Equal("name%5Bfirst%5D", sortedParams[0].Name);
}

[Fact]
public void Use_RFC_3986_Encoding_For_Auth_Signature_Base()
{
// reserved characters for 2396 and 3986
var reserved2396Characters = new[] { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," }; // http://www.ietf.org/rfc/rfc2396.txt
var additionalReserved3986Characters = new[] { "!", "*", "'", "(", ")" }; // http://www.ietf.org/rfc/rfc3986.txt
var reservedCharacterString = string.Join( string.Empty, reserved2396Characters.Union( additionalReserved3986Characters ) );

// act
var escapedString = OAuthTools.UrlEncodeRelaxed( reservedCharacterString );

// assert
Assert.Equal( "%3B%2F%3F%3A%40%26%3D%2B%24%2C%21%2A%27%28%29", escapedString );
}
}
}
30 changes: 28 additions & 2 deletions RestSharp/Authenticators/OAuth/OAuthTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,42 @@ public static string GetTimestamp(DateTime dateTime)
return timestamp.ToString();
}

/// <summary>
/// The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986.
/// </summary>
/// <seealso cref="http://stackoverflow.com/questions/846487/how-to-get-uri-escapedatastring-to-comply-with-rfc-3986" />
private static readonly string[] UriRfc3986CharsToEscape = new[] { "!", "*", "'", "(", ")" };

/// <summary>
/// URL encodes a string based on section 5.1 of the OAuth spec.
/// Namely, percent encoding with [RFC3986], avoiding unreserved characters,
/// upper-casing hexadecimal characters, and UTF-8 encoding for text value pairs.
/// </summary>
/// <param name="value"></param>
/// <param name="value">The value to escape.</param>
/// <returns>The escaped value.</returns>
/// <remarks>
/// The <see cref="Uri.EscapeDataString"/> method is <i>supposed</i> to take on
/// RFC 3986 behavior if certain elements are present in a .config file. Even if this
/// actually worked (which in my experiments it <i>doesn't</i>), we can't rely on every
/// host actually having this configuration element present.
/// </remarks>
/// <seealso cref="http://oauth.net/core/1.0#encoding_parameters" />
/// <seealso cref="http://stackoverflow.com/questions/846487/how-to-get-uri-escapedatastring-to-comply-with-rfc-3986" />
public static string UrlEncodeRelaxed(string value)
{
return Uri.EscapeDataString(value);
// Start with RFC 2396 escaping by calling the .NET method to do the work.
// This MAY sometimes exhibit RFC 3986 behavior (according to the documentation).
// If it does, the escaping we do that follows it will be a no-op since the
// characters we search for to replace can't possibly exist in the string.
StringBuilder escaped = new StringBuilder(Uri.EscapeDataString(value));

// Upgrade the escaping to RFC 3986, if necessary.
for (int i = 0; i < UriRfc3986CharsToEscape.Length; i++) {
escaped.Replace(UriRfc3986CharsToEscape[i], Uri.HexEscape(UriRfc3986CharsToEscape[i][0]));
}

// Return the fully-RFC3986-escaped string.
return escaped.ToString();
}

/// <summary>
Expand Down