108 lines
2.9 KiB
C#
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();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|