Gemini protocol server in C#
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
1.8 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace pyxis.gemini.Protocol
{
public class Request
{
// 1024 meta
// 2 status code
// 1 separator space
// 2 \r\n
private const int MAX_REQUEST_LENGTH = 1024 + 2 + 1 + 2;
public string Url { private set; get; }
// TODO: Provide properties for fetching specific parts of the URL
public void setUrl(string url)
{
this.Url = url;
}
public static int Parse(byte[] data, int length, out Request request)
{
int i;
bool found_cr = false, found_lf = false;
request = null;
// Minimum request length would be 3 -- one byte url and \r\n. If it's less than that, just
// bail now. This guards against any potential bug later when we start trying to trim the
// crlf, etc.
if (length < 3)
{
return 0;
}
for (i = 0; i < length; i++)
{
if (i >= MAX_REQUEST_LENGTH)
{
throw new Exception.ProtocolViolationException(String.Format("Request length exceeded maximum: %d", MAX_REQUEST_LENGTH));
}
if (data[i] == '\r')
{
found_cr = true;
}
else if (found_cr && data[i] == '\n')
{
found_lf = true;
break;
}
else
{
found_cr = false;
found_lf = false;
}
}
if (!found_cr || !found_lf)
{
return 0;
}
request = new Request();
request.setUrl(Encoding.UTF8.GetString(data, 0, i - 2 /* trim \r\n */));
return i + 1;
}
public byte[] Serialize()
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.StreamWriter sw = new System.IO.StreamWriter(ms);
// TODO: Validate URL
sw.Write(this.Url);
sw.Write("\r\n");
sw.Close();
return ms.ToArray();
}
}
}