appium-webdriveragent 16.13.1 → 16.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [16.13.2](https://github.com/appium/WebDriverAgent/compare/v16.13.1...v16.13.2) (2026-09-30)
2
+
3
+ ### Bug Fixes
4
+
5
+ * process received HTTP bytes before handling EOF ([#1277](https://github.com/appium/WebDriverAgent/issues/1277)) ([203fc4f](https://github.com/appium/WebDriverAgent/commit/203fc4f012ab1d90caf0127fe85f119ad85cb0e8))
6
+
1
7
  ## [16.13.1](https://github.com/appium/WebDriverAgent/compare/v16.13.0...v16.13.1) (2026-09-30)
2
8
 
3
9
  ### Performance Improvements
@@ -15,11 +15,11 @@
15
15
  <key>CFBundlePackageType</key>
16
16
  <string>FMWK</string>
17
17
  <key>CFBundleShortVersionString</key>
18
- <string>16.13.1</string>
18
+ <string>16.13.2</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>16.13.1</string>
22
+ <string>16.13.2</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -340,18 +340,28 @@ static const int64_t FBStaleConnectionSweepIntervalSec = 10;
340
340
 
341
341
  - (void)didClientDisconnect:(nw_connection_t)client
342
342
  {
343
- BOOL isAwaitingResponse;
344
- @synchronized (self.connectionBuffers) {
345
- isAwaitingResponse = [self.connectionsAwaitingResponse containsObject:client];
346
- [self.connectionBuffers removeObjectForKey:client];
347
- [self.pendingRequestHeaders removeObjectForKey:client];
348
- [self.incompleteRequestStarts removeObjectForKey:client];
349
- }
350
- // A client that only stopped sending may still read the response to its in-flight request, so
351
- // that response's send completion closes the connection instead (it finds no buffer left).
352
- if (!isAwaitingResponse) {
353
- nw_connection_cancel(client);
354
- }
343
+ // EOF must follow every receive already queued for this client. Otherwise it can
344
+ // remove the buffer before those bytes have even been appended and parsed.
345
+ __weak typeof(self) weakSelf = self;
346
+ dispatch_async(self.bufferProcessingQueue, ^{
347
+ __strong typeof(weakSelf) strongSelf = weakSelf;
348
+ if (nil == strongSelf) {
349
+ nw_connection_cancel(client);
350
+ return;
351
+ }
352
+ BOOL isAwaitingResponse;
353
+ @synchronized (strongSelf.connectionBuffers) {
354
+ isAwaitingResponse = [strongSelf.connectionsAwaitingResponse containsObject:client];
355
+ [strongSelf.connectionBuffers removeObjectForKey:client];
356
+ [strongSelf.pendingRequestHeaders removeObjectForKey:client];
357
+ [strongSelf.incompleteRequestStarts removeObjectForKey:client];
358
+ }
359
+ // A client that only stopped sending may still read the response to its in-flight request, so
360
+ // that response's send completion closes the connection instead (it finds no buffer left).
361
+ if (!isAwaitingResponse) {
362
+ nw_connection_cancel(client);
363
+ }
364
+ });
355
365
  }
356
366
 
357
367
  - (void)client:(nw_connection_t)client didReceiveData:(NSData *)data
@@ -14,6 +14,7 @@
14
14
  #import <unistd.h>
15
15
 
16
16
  #import "FBHTTPServer.h"
17
+ #import "FBTCPSocket.h"
17
18
 
18
19
  static atomic_int gFramingProbeHits;
19
20
 
@@ -242,6 +243,32 @@ static NSString *FBCompleteResponse(NSData *data)
242
243
  XCTAssertEqual([self serverSocketCountSettlingAt:baseline], baseline);
243
244
  }
244
245
 
246
+ - (void)testEofWaitsForPreviouslyReceivedBytesToBeParsed
247
+ {
248
+ FBHTTPServer *server = [FBHTTPServer new];
249
+ __block NSUInteger calls = 0;
250
+ [server get:@"/probe" withBlock:^(RouteRequest *request, RouteResponse *response) {
251
+ calls++;
252
+ }];
253
+ dispatch_queue_t queue = [server valueForKey:@"bufferProcessingQueue"];
254
+ nw_connection_t client = nw_connection_create(nw_endpoint_create_host("127.0.0.1", "1"),
255
+ nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION));
256
+ id<FBTCPSocketDelegate> delegate = (id)server;
257
+ [delegate didClientConnect:client];
258
+ dispatch_suspend(queue);
259
+ @try {
260
+ NSData *data = [@"GET /probe HTTP/1.1\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding];
261
+ [delegate client:client didReceiveData:data];
262
+ [delegate didClientDisconnect:client];
263
+ } @finally {
264
+ dispatch_resume(queue);
265
+ }
266
+ dispatch_sync(queue, ^{});
267
+ XCTAssertEqual(calls, 1u);
268
+ [server stop:YES];
269
+ nw_connection_cancel(client);
270
+ }
271
+
245
272
  - (void)testHalfClosedClientGetsItsResponseAndIsThenClosed
246
273
  {
247
274
  // A client may shut down its sending side right after the request and wait for the response.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "16.13.1",
3
+ "version": "16.13.2",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "keywords": [
6
6
  "Appium",