ln.http/ln.http/HttpConnection.cs

108 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
namespace ln.http
{
public abstract class HttpConnection
{
public Listener Listener { get; }
public IPEndPoint LocalEndpoint => Listener.LocalEndpoint;
public IPEndPoint RemoteEndpoint { get; }
public Stream ConnectionStream { get; }
public string Method { get; }
//public Uri RequestUri { get; }
public HttpVersion HttpVersion { get; }
public string RequestUriLine { get; set; }
public HttpConnection(Listener listener, IPEndPoint remoteEndpoint, Stream connectionStream, string method,
String requestUriLine, HttpVersion httpVersion)
{
Listener = listener;
RemoteEndpoint = remoteEndpoint;
ConnectionStream = connectionStream;
Method = method;
RequestUriLine = requestUriLine;
HttpVersion = httpVersion;
}
public abstract void Run();
public static string ReadLine(Stream stream) => ReadLine(stream, Encoding.ASCII);
public static string ReadLine(Stream stream, Encoding encoding)
{
if (!stream.CanRead)
return null;
byte[] line = new byte[1024];
int n = 0;
int ch;
while ((ch = stream.ReadByte()) != -1)
{
switch (ch)
{
case '\r':
break;
case '\n':
return encoding.GetString(line, 0, n);
default:
line[n++] = (byte)ch;
break;
}
}
if (n > 0)
return encoding.GetString(line, 0, n);
return null;
}
public static bool ReadRequestLine(Stream stream, out string method, out string requestUri,
out HttpVersion httpVersion)
{
string requestLine = ReadLine(stream);
if (requestLine is null)
{
method = null;
requestUri = null;
httpVersion = HttpVersion.None;
return false;
}
int idxSpace1 = requestLine.IndexOf(' ');
int idxSpace2 = requestLine.IndexOf(' ', idxSpace1 + 1);
if ((idxSpace1 > 0) && (idxSpace2 > 0))
{
method = requestLine.Substring(0, idxSpace1);
requestUri = requestLine.Substring(idxSpace1 + 1, (idxSpace2 - idxSpace1 - 1));
string protocol = requestLine.Substring(idxSpace2 + 1);
httpVersion = HttpVersion.None;
if ("PRI".Equals(method) && Http2PrefaceUri.Equals(requestUri) && "HTTP/2.0".Equals(protocol))
httpVersion = HttpVersion.HTTP2;
else if ("HTTP/1.0".Equals(protocol))
httpVersion = HttpVersion.HTTP10;
else if ("HTTP/1.1".Equals(protocol))
httpVersion = HttpVersion.HTTP11;
return true;
}
method = null;
requestUri = null;
httpVersion = HttpVersion.None;
return false;
}
public abstract void SendResponse(HttpRequestContext requestContext);
private static string Http2PrefaceUri = "*";
}
}