Skip to content

Commit f4cb566

Browse files
Change HttpClientBase.ExecutePost to match upstream better and drop Newtonsoft.Json dependency (#1212)
* Change HttpClientBase.ExecutePost to match upstream better and drop Newtonsoft.Json dependency * Code cleanup of HttpClientBase and HttpReplicator, remove NewtonsoftJson dependency version --------- Co-authored-by: Paul Irwin <paulirwin@gmail.com>
1 parent 5b48701 commit f4cb566

File tree

6 files changed

+46
-51
lines changed

6 files changed

+46
-51
lines changed

.build/dependencies.props

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
<MorfologikPolishPackageVersion>$(MorfologikFsaPackageVersion)</MorfologikPolishPackageVersion>
6666
<MorfologikStemmingPackageVersion>$(MorfologikFsaPackageVersion)</MorfologikStemmingPackageVersion>
6767
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
68-
<NewtonsoftJsonPackageVersion>13.0.1</NewtonsoftJsonPackageVersion>
6968
<NUnit3TestAdapterPackageVersion>4.6.0</NUnit3TestAdapterPackageVersion>
7069
<NUnitPackageVersion>3.14.0</NUnitPackageVersion>
7170
<RandomizedTestingGeneratorsPackageVersion>2.7.8</RandomizedTestingGeneratorsPackageVersion>

src/Lucene.Net.Replicator/Http/HttpClientBase.cs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
using Lucene.Net.Diagnostics;
22
using Lucene.Net.Support;
3-
using Newtonsoft.Json;
4-
using Newtonsoft.Json.Linq;
53
using System;
64
using System.IO;
75
using System.Linq;
86
using System.Net;
97
using System.Net.Http;
10-
using System.Text;
118
using System.Threading;
129
using System.Threading.Tasks;
10+
#nullable enable
1311

1412
namespace Lucene.Net.Replicator.Http
1513
{
@@ -47,7 +45,7 @@ public abstract class HttpClientBase : IDisposable
4745
/// Default request timeout for this client (100 seconds).
4846
/// <see cref="Timeout"/>.
4947
/// </summary>
50-
public readonly static TimeSpan DEFAULT_TIMEOUT = TimeSpan.FromSeconds(100); // LUCENENET: This was DEFAULT_SO_TIMEOUT in Lucene, using .NET's default timeout value of 100 instead of 61 seconds
48+
public static readonly TimeSpan DEFAULT_TIMEOUT = TimeSpan.FromSeconds(100); // LUCENENET: This was DEFAULT_SO_TIMEOUT in Lucene, using .NET's default timeout value of 100 instead of 61 seconds
5149

5250
// TODO compression?
5351

@@ -56,7 +54,8 @@ public abstract class HttpClientBase : IDisposable
5654
/// </summary>
5755
protected string Url { get; private set; }
5856

59-
private volatile bool isDisposed = false;
57+
private volatile bool isDisposed;
58+
6059
private readonly HttpClient httpc;
6160

6261
/// <summary>
@@ -73,7 +72,7 @@ public abstract class HttpClientBase : IDisposable
7372
/// <param name="port">The port to be used to connect on.</param>
7473
/// <param name="path">The path to the replicator on the host.</param>
7574
/// <param name="messageHandler">Optional, The HTTP handler stack to use for sending requests, defaults to <c>null</c>.</param>
76-
protected HttpClientBase(string host, int port, string path, HttpMessageHandler messageHandler = null)
75+
protected HttpClientBase(string host, int port, string path, HttpMessageHandler? messageHandler = null)
7776
: this(NormalizedUrl(host, port, path), messageHandler)
7877
{
7978
}
@@ -88,7 +87,7 @@ protected HttpClientBase(string host, int port, string path, HttpMessageHandler
8887
/// <param name="url">The full url, including with host, port and path.</param>
8988
/// <param name="messageHandler">Optional, The HTTP handler stack to use for sending requests.</param>
9089
//Note: LUCENENET Specific
91-
protected HttpClientBase(string url, HttpMessageHandler messageHandler = null)
90+
protected HttpClientBase(string url, HttpMessageHandler? messageHandler = null)
9291
: this(url, new HttpClient(messageHandler ?? new HttpClientHandler()) { Timeout = DEFAULT_TIMEOUT })
9392
{
9493
}
@@ -97,7 +96,7 @@ protected HttpClientBase(string url, HttpMessageHandler messageHandler = null)
9796
/// Creates a new <see cref="HttpClientBase"/> with the given <paramref name="url"/> and <see cref="HttpClient"/>.
9897
/// </summary>
9998
/// <remarks>
100-
/// This allows full controll over how the <see cref="HttpClient"/> is created,
99+
/// This allows full control over how the <see cref="HttpClient"/> is created,
101100
/// prefer the <see cref="HttpClientBase(string, HttpMessageHandler)"/> over this unless you know you need the control of the <see cref="HttpClient"/>.
102101
/// </remarks>
103102
/// <param name="url"></param>
@@ -138,8 +137,11 @@ protected void EnsureOpen()
138137
private static string NormalizedUrl(string host, int port, string path)
139138
{
140139
if (string.IsNullOrEmpty(path))
140+
{
141141
path = "/";
142-
return string.Format("http://{0}:{1}{2}", host, port, path);
142+
}
143+
144+
return $"http://{host}:{port}{path}";
143145
}
144146

145147
/// <summary>
@@ -174,15 +176,13 @@ protected virtual void ThrowKnownError(HttpResponseMessage response)
174176
/// <b>Internal:</b> Execute a request and return its result.
175177
/// The <paramref name="parameters"/> argument is treated as: name1,value1,name2,value2,...
176178
/// </summary>
177-
protected virtual HttpResponseMessage ExecutePost(string request, object entity, params string[] parameters)
179+
protected virtual HttpResponseMessage ExecutePost(string request, HttpContent content, params string[]? parameters)
178180
{
179181
EnsureOpen();
180182

181-
//.NET Note: No headers? No ContentType?... Bad use of Http?
182-
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, QueryString(request, parameters));
183+
var req = new HttpRequestMessage(HttpMethod.Post, QueryString(request, parameters));
183184

184-
req.Content = new StringContent(JToken.FromObject(entity, JsonSerializer.Create())
185-
.ToString(Formatting.None), Encoding.UTF8, "application/json");
185+
req.Content = content;
186186

187187
return Execute(req);
188188
}
@@ -191,30 +191,29 @@ protected virtual HttpResponseMessage ExecutePost(string request, object entity,
191191
/// <b>Internal:</b> Execute a request and return its result.
192192
/// The <paramref name="parameters"/> argument is treated as: name1,value1,name2,value2,...
193193
/// </summary>
194-
protected virtual HttpResponseMessage ExecuteGet(string request, params string[] parameters)
194+
protected virtual HttpResponseMessage ExecuteGet(string request, params string[]? parameters)
195195
{
196196
EnsureOpen();
197197

198-
//Note: No headers? No ContentType?... Bad use of Http?
199-
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, QueryString(request, parameters));
198+
var req = new HttpRequestMessage(HttpMethod.Get, QueryString(request, parameters));
199+
200200
return Execute(req);
201201
}
202202

203203
private HttpResponseMessage Execute(HttpRequestMessage request)
204204
{
205205
//.NET Note: Bridging from Async to Sync, this is not ideal and we could consider changing the interface to be Async or provide Async overloads
206206
// and have these Sync methods with their caveats.
207-
HttpResponseMessage response = httpc.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false).GetAwaiter().GetResult();
207+
var response = httpc.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false).GetAwaiter().GetResult();
208208
VerifyStatus(response);
209209
return response;
210210
}
211211

212-
private string QueryString(string request, params string[] parameters)
212+
private string QueryString(string request, params string[]? parameters)
213213
{
214-
return parameters is null
215-
? string.Format("{0}/{1}", Url, request)
216-
: string.Format("{0}/{1}?{2}", Url, request, string
217-
.Join("&", parameters.Select(WebUtility.UrlEncode).InPairs((key, val) => string.Format("{0}={1}", key, val))));
214+
return parameters is null || parameters.Length == 0
215+
? $"{Url}/{request}"
216+
: $"{Url}/{request}?{string.Join("&", parameters.Select(WebUtility.UrlEncode).InPairs((key, val) => $"{key}={val}"))}";
218217
}
219218

220219
/// <summary>
@@ -257,8 +256,12 @@ public virtual Stream GetResponseStream(HttpResponseMessage response) // LUCENEN
257256
public virtual Stream GetResponseStream(HttpResponseMessage response, bool consume) // LUCENENET: This was ResponseInputStream in Lucene
258257
{
259258
Stream result = response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
259+
260260
if (consume)
261+
{
261262
result = new ConsumingStream(result);
263+
}
264+
262265
return result;
263266
}
264267

@@ -284,7 +287,7 @@ protected virtual T DoAction<T>(HttpResponseMessage response, Func<T> call)
284287
/// </summary>
285288
protected virtual T DoAction<T>(HttpResponseMessage response, bool consume, Func<T> call)
286289
{
287-
Exception th = null;
290+
Exception? th /* = null */;
288291
try
289292
{
290293
return call();
@@ -303,20 +306,13 @@ protected virtual T DoAction<T>(HttpResponseMessage response, bool consume, Func
303306
{
304307
if (consume)
305308
{
306-
try
307-
{
308-
ConsumeQuietly(response);
309-
}
310-
finally
311-
{
312-
// ignoring on purpose
313-
}
309+
ConsumeQuietly(response);
314310
}
315311
}
316312
}
317313
if (Debugging.AssertsEnabled) Debugging.Assert(th != null); // extra safety - if we get here, it means the Func<T> failed
318314
Util.IOUtils.ReThrow(th);
319-
return default; // silly, if we're here, IOUtils.reThrow always throws an exception
315+
return default!; // silly, if we're here, IOUtils.reThrow always throws an exception
320316
}
321317

322318
/// <summary>
@@ -346,7 +342,7 @@ private static void ConsumeQuietly(HttpResponseMessage response)
346342
{
347343
try
348344
{
349-
response.Content?.Dispose(); // LUCENENET: Force a flush and and dispose the underlying stream
345+
response.Content?.Dispose(); // LUCENENET: Force a flush and dispose the underlying stream
350346
}
351347
catch (Exception ioe) when (ioe.IsIOException())
352348
{
@@ -418,8 +414,11 @@ public override int EndRead(IAsyncResult asyncResult)
418414
Consume(res);
419415
return res;
420416
}
417+
421418
public override long Seek(long offset, SeekOrigin origin) => input.Seek(offset, origin);
419+
422420
public override void SetLength(long value) => input.SetLength(value);
421+
423422
public override void Write(byte[] buffer, int offset, int count) => input.Write(buffer, offset, count);
424423

425424
private void Consume(int zeroOrMinusOne)

src/Lucene.Net.Replicator/Http/HttpReplicator.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.IO;
44
using System.Net.Http;
5+
#nullable enable
56

67
namespace Lucene.Net.Replicator.Http
78
{
@@ -34,7 +35,7 @@ public class HttpReplicator : HttpClientBase, IReplicator
3435
/// Creates a new <see cref="HttpReplicator"/> with the given host, port and path.
3536
/// <see cref="HttpClientBase(string, int, string, HttpMessageHandler)"/> for more details.
3637
/// </summary>
37-
public HttpReplicator(string host, int port, string path, HttpMessageHandler messageHandler = null)
38+
public HttpReplicator(string host, int port, string path, HttpMessageHandler? messageHandler = null)
3839
: base(host, port, path, messageHandler)
3940
{
4041
}
@@ -44,7 +45,7 @@ public HttpReplicator(string host, int port, string path, HttpMessageHandler mes
4445
/// <see cref="HttpClientBase(string, HttpMessageHandler)"/> for more details.
4546
/// </summary>
4647
//Note: LUCENENET Specific
47-
public HttpReplicator(string url, HttpMessageHandler messageHandler = null)
48+
public HttpReplicator(string url, HttpMessageHandler? messageHandler = null)
4849
: this(url, new HttpClient(messageHandler ?? new HttpClientHandler()) { Timeout = DEFAULT_TIMEOUT })
4950
{
5051
}
@@ -62,26 +63,28 @@ public HttpReplicator(string url, HttpClient client)
6263
/// <summary>
6364
/// Checks for updates at the remote host.
6465
/// </summary>
65-
public virtual SessionToken CheckForUpdate(string currentVersion)
66+
public virtual SessionToken? CheckForUpdate(string? currentVersion)
6667
{
67-
string[] parameters = null;
68+
string[]? parameters = null;
6869
if (currentVersion != null)
70+
{
6971
parameters = new[] { ReplicationService.REPLICATE_VERSION_PARAM, currentVersion };
72+
}
7073

71-
HttpResponseMessage response = base.ExecuteGet(ReplicationService.ReplicationAction.UPDATE.ToString(), parameters);
74+
var response = base.ExecuteGet(nameof(ReplicationService.ReplicationAction.UPDATE), parameters);
7275
return DoAction(response, () =>
7376
{
74-
using DataInputStream inputStream = new DataInputStream(GetResponseStream(response));
77+
using var inputStream = new DataInputStream(GetResponseStream(response));
7578
return inputStream.ReadByte() == 0 ? null : new SessionToken(inputStream);
7679
});
7780
}
7881

7982
/// <summary>
80-
/// Obtains the given file from it's source at the remote host.
83+
/// Obtains the given file from its source at the remote host.
8184
/// </summary>
8285
public virtual Stream ObtainFile(string sessionId, string source, string fileName)
8386
{
84-
HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.OBTAIN.ToString(),
87+
var response = ExecuteGet(nameof(ReplicationService.ReplicationAction.OBTAIN),
8588
ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId,
8689
ReplicationService.REPLICATE_SOURCE_PARAM, source,
8790
ReplicationService.REPLICATE_FILENAME_PARAM, fileName);
@@ -102,9 +105,9 @@ public virtual void Publish(IRevision revision)
102105
/// </summary>
103106
public virtual void Release(string sessionId)
104107
{
105-
HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.RELEASE.ToString(), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
108+
var response = ExecuteGet(nameof(ReplicationService.ReplicationAction.RELEASE), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
106109
// do not remove this call: as it is still validating for us!
107-
DoAction<object>(response, () => null);
110+
DoAction<object?>(response, () => null);
108111
}
109112
}
110113
}

src/Lucene.Net.Replicator/Http/ReplicationService.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using J2N.Text;
33
using Lucene.Net.Diagnostics;
44
using Lucene.Net.Replicator.Http.Abstractions;
5-
using Newtonsoft.Json;
65
using System;
76
using System.Collections.Generic;
87
using System.IO;

src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747

4848
<ItemGroup>
4949
<PackageReference Include="J2N" Version="$(J2NPackageVersion)" />
50-
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
5150
</ItemGroup>
5251

5352
<ItemGroup Condition=" '$(TargetFramework)' == 'net462' ">

src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@
6363

6464
<Import Project="$(SolutionDir).build/TestReferences.Common.targets" />
6565

66-
<ItemGroup>
67-
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
68-
</ItemGroup>
69-
7066
<ItemGroup Condition="$(TargetFramework.StartsWith('net8.')) Or $(TargetFramework.StartsWith('net9.'))">
7167
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostPackageVersion)" />
7268
</ItemGroup>

0 commit comments

Comments
 (0)