Integrated methods to parse query string

This commit is contained in:
sta 2014-06-03 11:34:18 +09:00
parent fa01992fa1
commit dd3cd23ac3
5 changed files with 37 additions and 97 deletions

View File

@ -337,12 +337,12 @@ namespace WebSocketSharp.Net
/// Gets the query string included in the request.
/// </summary>
/// <value>
/// A <see cref="NameValueCollection"/> that contains the query string parameters
/// included in the request.
/// A <see cref="NameValueCollection"/> that contains the query string parameters.
/// </value>
public NameValueCollection QueryString {
get {
return _queryString ?? (_queryString = HttpUtility.ParseQueryStringSimply (_url.Query));
return _queryString ??
(_queryString = HttpUtility.ParseQueryStringInternally (_url.Query, Encoding.UTF8));
}
}

View File

@ -675,57 +675,33 @@ namespace WebSocketSharp.Net
return res;
}
internal static void ParseQueryString (
string query, Encoding encoding, NameValueCollection result)
internal static NameValueCollection ParseQueryStringInternally (string query, Encoding encoding)
{
if (query.Length == 0)
return;
int len;
if (query == null || (len = query.Length) == 0 || (len == 1 && query [0] == '?'))
return new NameValueCollection (1);
var decoded = HtmlDecode (query);
var decodedLength = decoded.Length;
var namePos = 0;
var first = true;
while (namePos <= decodedLength) {
var valuePos = -1;
var valueEnd = -1;
for (int q = namePos; q < decodedLength; q++) {
if (valuePos == -1 && decoded [q] == '=') {
valuePos = q + 1;
}
else if (decoded [q] == '&') {
valueEnd = q;
break;
}
}
if (query [0] == '?')
query = query.Substring (1);
if (first) {
first = false;
if (decoded [namePos] == '?')
namePos++;
}
var res = new QueryStringCollection ();
var components = query.Split ('&');
foreach (var component in components) {
var i = component.IndexOf ('=');
if (i > -1) {
var name = UrlDecode (component.Substring (0, i), encoding);
var val = component.Length > i + 1
? UrlDecode (component.Substring (i + 1), encoding)
: String.Empty;
string name;
if (valuePos == -1) {
name = null;
valuePos = namePos;
res.Add (name, val);
}
else {
name = UrlDecode (decoded.Substring (namePos, valuePos - namePos - 1), encoding);
res.Add (null, UrlDecode (component, encoding));
}
if (valueEnd < 0) {
namePos = -1;
valueEnd = decoded.Length;
}
else {
namePos = valueEnd + 1;
}
var value = UrlDecode (decoded.Substring (valuePos, valueEnd - valuePos), encoding);
result.Add (name, value);
if (namePos == -1)
break;
}
return res;
}
internal static string UrlDecodeInternally (
@ -1074,7 +1050,10 @@ namespace WebSocketSharp.Net
public static NameValueCollection ParseQueryString (string query)
{
return ParseQueryString (query, Encoding.UTF8);
if (query == null)
throw new ArgumentNullException ("query");
return ParseQueryStringInternally (query, Encoding.UTF8);
}
public static NameValueCollection ParseQueryString (string query, Encoding encoding)
@ -1082,50 +1061,10 @@ namespace WebSocketSharp.Net
if (query == null)
throw new ArgumentNullException ("query");
var len = query.Length;
if (len == 0 || (len == 1 && query [0] == '?'))
return new NameValueCollection (1);
if (query [0] == '?')
query = query.Substring (1);
if (encoding == null)
encoding = Encoding.UTF8;
throw new ArgumentNullException ("encoding");
var res = new QueryStringCollection ();
ParseQueryString (query, encoding, res);
return res;
}
// Used by HttpListenerRequest and TcpListenerWebSocketContext.
public static NameValueCollection ParseQueryStringSimply (string query)
{
int len;
if (query == null || (len = query.Length) == 0 || (len == 1 && query [0] == '?'))
return new NameValueCollection (1);
if (query [0] == '?')
query = query.Substring (1);
var res = new QueryStringCollection ();
var components = query.Split ('&');
foreach (var component in components) {
var i = component.IndexOf ('=');
if (i > -1) {
var name = UrlDecode (component.Substring (0, i), Encoding.UTF8);
var val = component.Length > i + 1
? UrlDecode (component.Substring (i + 1), Encoding.UTF8)
: String.Empty;
res.Add (name, val);
}
else {
res.Add (null, UrlDecode (component, Encoding.UTF8));
}
}
return res;
return ParseQueryStringInternally (query, encoding);
}
public static string UrlDecode (string s)

View File

@ -168,10 +168,10 @@ namespace WebSocketSharp.Net.WebSockets
}
/// <summary>
/// Gets the query string variables included in the request.
/// Gets the query string included in the request.
/// </summary>
/// <value>
/// A <see cref="NameValueCollection"/> that contains the query string variables.
/// A <see cref="NameValueCollection"/> that contains the query string parameters.
/// </value>
public override NameValueCollection QueryString {
get {

View File

@ -32,6 +32,7 @@ using System.Collections.Specialized;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Text;
namespace WebSocketSharp.Net.WebSockets
{
@ -183,16 +184,16 @@ namespace WebSocketSharp.Net.WebSockets
}
/// <summary>
/// Gets the query string variables included in the request.
/// Gets the query string included in the request.
/// </summary>
/// <value>
/// A <see cref="NameValueCollection"/> that contains the query string variables.
/// A <see cref="NameValueCollection"/> that contains the query string parameters.
/// </value>
public override NameValueCollection QueryString {
get {
return _queryString ??
(_queryString =
HttpUtility.ParseQueryStringSimply (_uri != null ? _uri.Query : null));
(_queryString = HttpUtility.ParseQueryStringInternally (
_uri != null ? _uri.Query : null, Encoding.UTF8));
}
}

View File

@ -119,10 +119,10 @@ namespace WebSocketSharp.Net.WebSockets
public abstract string Origin { get; }
/// <summary>
/// Gets the query string variables included in the request.
/// Gets the query string included in the request.
/// </summary>
/// <value>
/// A <see cref="NameValueCollection"/> that contains the query string variables.
/// A <see cref="NameValueCollection"/> that contains the query string parameters.
/// </value>
public abstract NameValueCollection QueryString { get; }