ln.http/client/HttpClientRequest.cs

108 lines
2.9 KiB
C#

using System;
using ln.types;
using System.IO;
using System.Net.Sockets;
using System.Net.Security;
namespace ln.http.client
{
public class HttpClientRequest
{
public HttpClient HttpClient { get; }
public URI URI
{
get => uri;
set
{
if (!value.Scheme.Equals("http") && !value.Scheme.Equals("https"))
throw new ArgumentOutOfRangeException(nameof(value), String.Format("unsupported url scheme: {0}", value.Scheme));
uri = value;
}
}
public HttpHeaders Headers { get; } = new HttpHeaders();
public String Method { get; set; }
URI uri;
MemoryStream contentStream;
HttpClientResponse clientResponse;
public HttpClientRequest(HttpClient httpClient, URI uri)
{
HttpClient = httpClient;
URI = uri;
Headers.Add("user-agent", "ln.http.client");
}
public Stream GetContentStream()
{
if (clientResponse != null)
throw new NotSupportedException("Request has already been executed, content stream has been disposed");
if (contentStream == null)
contentStream = new MemoryStream();
return contentStream;
}
public HttpClientResponse GetResponse()
{
if (clientResponse == null)
{
executeRequest();
}
return clientResponse;
}
private Stream OpenConnection()
{
TcpClient tcpClient = null;
SslStream sslStream = null;
try
{
tcpClient = new TcpClient();
tcpClient.ExclusiveAddressUse = false;
tcpClient.Connect(URI.Host, int.Parse(URI.Port));
if (!tcpClient.Connected)
throw new IOException(String.Format("could not connect to host {0}",uri.Host));
if (uri.Scheme.Equals("https"))
{
sslStream = new SslStream(tcpClient.GetStream());
return sslStream;
}
return tcpClient.GetStream();
} catch (Exception)
{
if (sslStream != null)
sslStream.Dispose();
if (tcpClient != null)
tcpClient.Dispose();
throw;
}
}
private void executeRequest()
{
if (contentStream.Length > 0)
{
byte[] requestContent = contentStream.ToArray();
Headers.Add("content-length", requestContent.Length.ToString());
}
Stream connectionStream = OpenConnection();
clientResponse = new HttpClientResponse(this);
contentStream.Dispose();
}
}
}