using System.Net.Http.Headers;
using RobotNet10.Script.IO;
namespace RobotNet10.ScriptEngine.IO;
///
/// Implementation of HTTP connection using HttpClient.
///
public class HttpConnection : IHttpConnection
{
private readonly HttpClient _httpClient;
private bool _disposed;
public string BaseUrl { get; }
public bool IsConnected { get; private set; }
public HttpConnection(string baseUrl, TimeSpan? timeout = null)
{
BaseUrl = baseUrl.TrimEnd('/');
_httpClient = new HttpClient
{
BaseAddress = new Uri(BaseUrl),
Timeout = timeout ?? TimeSpan.FromSeconds(30)
};
IsConnected = false;
}
public async Task ConnectAsync()
{
// HTTP doesn't require explicit connection, but we can verify connectivity
try
{
var response = await _httpClient.GetAsync("/");
IsConnected = true;
}
catch
{
IsConnected = false;
throw;
}
}
public Task DisconnectAsync()
{
IsConnected = false;
return Task.CompletedTask;
}
public async Task GetAsync(string path, Dictionary? headers = null)
{
EnsureConnected();
using var request = new HttpRequestMessage(HttpMethod.Get, path);
AddHeaders(request, headers);
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
public async Task PostAsync(string path, string content, string contentType = "application/json", Dictionary? headers = null)
{
EnsureConnected();
using var request = new HttpRequestMessage(HttpMethod.Post, path);
request.Content = new StringContent(content);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
AddHeaders(request, headers);
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
public async Task PutAsync(string path, string content, string contentType = "application/json", Dictionary? headers = null)
{
EnsureConnected();
using var request = new HttpRequestMessage(HttpMethod.Put, path);
request.Content = new StringContent(content);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
AddHeaders(request, headers);
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
public async Task DeleteAsync(string path, Dictionary? headers = null)
{
EnsureConnected();
using var request = new HttpRequestMessage(HttpMethod.Delete, path);
AddHeaders(request, headers);
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private static void AddHeaders(HttpRequestMessage request, Dictionary? headers)
{
if (headers != null)
{
foreach (var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
}
private void EnsureConnected()
{
if (!IsConnected)
{
throw new InvalidOperationException("HTTP connection is not connected. Call ConnectAsync() first.");
}
}
public void Dispose()
{
if (!_disposed)
{
_httpClient?.Dispose();
IsConnected = false;
_disposed = true;
}
GC.SuppressFinalize(this);
}
}