OpenSimMirror/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpHelper.cs

119 lines
4.2 KiB
C#

using System;
using System.Web;
namespace OSHttpServer
{
/// <summary>
/// Generic helper functions for HTTP
/// </summary>
public static class HttpHelper
{
/// <summary>
/// An empty URI
/// </summary>
public static readonly Uri EmptyUri = new Uri("http://localhost/");
/// <summary>
/// Parses a query string.
/// </summary>
/// <param name="queryString">Query string (URI encoded)</param>
/// <returns>A <see cref="HttpInput"/> object if successful; otherwise <see cref="HttpInput.Empty"/></returns>
/// <exception cref="ArgumentNullException"><c>queryString</c> is null.</exception>
/// <exception cref="FormatException">If string cannot be parsed.</exception>
public static HttpInput ParseQueryString(string queryString)
{
if (queryString == null)
throw new ArgumentNullException("queryString");
if (queryString == string.Empty)
return HttpInput.Empty;
HttpInput input = new HttpInput("QueryString");
queryString = queryString.TrimStart('?', '&');
// a simple value.
if (queryString.IndexOf("&") == -1 && !queryString.Contains("%3d") && !queryString.Contains("%3D") && !queryString.Contains("="))
{
input.Add(string.Empty, queryString);
return input;
}
int state = 0;
int startpos = 0;
string name = null;
for (int i = 0; i < queryString.Length; ++i)
{
int newIndexPos;
if (state == 0 && IsEqual(queryString, ref i, out newIndexPos))
{
name = queryString.Substring(startpos, i - startpos);
i = newIndexPos;
startpos = i + 1;
++state;
}
else if (state == 1 && IsAmp(queryString, ref i, out newIndexPos))
{
Add(input, name, queryString.Substring(startpos, i - startpos));
i = newIndexPos;
startpos = i + 1;
state = 0;
name = null;
}
}
if (state == 0 && !input.GetEnumerator().MoveNext())
throw new FormatException("Not a valid query string: " + queryString);
if (startpos <= queryString.Length)
{
if (name != null)
Add(input, name, queryString.Substring(startpos, queryString.Length - startpos));
else
Add(input, string.Empty, queryString.Substring(startpos, queryString.Length - startpos));
}
return input;
}
private static bool IsEqual(string queryStr, ref int index, out int outIndex)
{
outIndex = index;
if (queryStr[index] == '=')
return true;
if (queryStr[index] == '%' && queryStr.Length > index + 2 && queryStr[index + 1] == '3'
&& (queryStr[index + 2] == 'd' || queryStr[index + 2] == 'D'))
{
outIndex += 2;
return true;
}
return false;
}
private static bool IsAmp(string queryStr, ref int index, out int outIndex)
{
outIndex = index;
if (queryStr[index] == '%' && queryStr.Length > index + 2 && queryStr[index + 1] == '2' &&
queryStr[index + 2] == '6')
outIndex += 2;
else if (queryStr[index] == '&')
{
if (queryStr.Length > index + 4
&& (queryStr[index + 1] == 'a' || queryStr[index + 1] == 'A')
&& (queryStr[index + 2] == 'm' || queryStr[index + 2] == 'M')
&& (queryStr[index + 3] == 'p' || queryStr[index + 3] == 'P')
&& queryStr[index + 4] == ';')
outIndex += 4;
}
else
return false;
return true;
}
private static void Add(IHttpInput input, string name, string value)
{
input.Add(HttpUtility.UrlDecode(name), HttpUtility.UrlDecode(value));
}
}
}