appium-webdriveragent 16.5.1 → 16.7.0

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/WebDriverAgent.xcodeproj/project.pbxproj +48 -300
  3. package/WebDriverAgentLib/Info.plist +2 -2
  4. package/WebDriverAgentLib/Routing/{WatchOS/FBWatchHTTPServer.h → FBHTTPServer.h} +11 -7
  5. package/WebDriverAgentLib/Routing/{WatchOS/FBWatchHTTPServer.m → FBHTTPServer.m} +26 -13
  6. package/WebDriverAgentLib/Routing/FBTCPSocket.h +17 -45
  7. package/WebDriverAgentLib/Routing/FBTCPSocket.m +16 -95
  8. package/WebDriverAgentLib/Routing/FBWebServer.h +1 -1
  9. package/WebDriverAgentLib/Routing/FBWebServer.m +5 -55
  10. package/WebDriverAgentLib/Routing/{WatchOS/RouteRequest.h → RouteRequest.h} +2 -4
  11. package/WebDriverAgentLib/Routing/{WatchOS/RouteResponse.h → RouteResponse.h} +2 -2
  12. package/WebDriverAgentLib/Utilities/FBMjpegServer.h +7 -0
  13. package/WebDriverAgentLib/Utilities/FBMjpegServer.m +15 -16
  14. package/WebDriverAgentTests/IntegrationTests_watchOS/IntegrationTests_watchOS-Bridging-Header.h +2 -0
  15. package/WebDriverAgentTests/IntegrationTests_watchOS/WDAMjpegStreamingIntegrationTests.swift +81 -0
  16. package/package.json +1 -1
  17. package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncSocket.h +0 -1220
  18. package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncSocket.m +0 -8786
  19. package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncUdpSocket.h +0 -1036
  20. package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncUdpSocket.m +0 -5868
  21. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Categories/DDNumber.h +0 -12
  22. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Categories/DDNumber.m +0 -88
  23. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Categories/DDRange.h +0 -56
  24. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Categories/DDRange.m +0 -100
  25. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPConnection.h +0 -109
  26. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPConnection.m +0 -2281
  27. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPLogging.h +0 -122
  28. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPMessage.h +0 -53
  29. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPMessage.m +0 -357
  30. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPResponse.h +0 -149
  31. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPServer.h +0 -126
  32. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/HTTPServer.m +0 -372
  33. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/LICENSE +0 -18
  34. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Responses/HTTPDataResponse.h +0 -13
  35. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Responses/HTTPDataResponse.m +0 -83
  36. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Responses/HTTPErrorResponse.h +0 -9
  37. package/WebDriverAgentLib/Vendor/CocoaHTTPServer/Responses/HTTPErrorResponse.m +0 -38
  38. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/HTTPResponseProxy.h +0 -13
  39. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/HTTPResponseProxy.m +0 -84
  40. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/LICENSE +0 -19
  41. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/Route.h +0 -18
  42. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/Route.m +0 -11
  43. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RouteRequest.h +0 -16
  44. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RouteRequest.m +0 -50
  45. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RouteResponse.h +0 -20
  46. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RouteResponse.m +0 -66
  47. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RoutingConnection.h +0 -5
  48. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RoutingConnection.m +0 -142
  49. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RoutingHTTPServer.h +0 -55
  50. package/WebDriverAgentLib/Vendor/RoutingHTTPServer/RoutingHTTPServer.m +0 -303
  51. /package/WebDriverAgentLib/Routing/{WatchOS/RouteRequest.m → RouteRequest.m} +0 -0
  52. /package/WebDriverAgentLib/Routing/{WatchOS/RouteResponse.m → RouteResponse.m} +0 -0
@@ -15,11 +15,11 @@
15
15
  <key>CFBundlePackageType</key>
16
16
  <string>FMWK</string>
17
17
  <key>CFBundleShortVersionString</key>
18
- <string>16.5.1</string>
18
+ <string>16.7.0</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>16.5.1</string>
22
+ <string>16.7.0</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -6,13 +6,11 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
 
9
- // RoutingHTTPServer/CocoaHTTPServer need BSD sockets (via GCDAsyncSocket), which watchOS
10
- // forbids - see FBTCPSocket.h/.m. This is a minimal HTTP/1.1 server on top of the watchOS
11
- // FBTCPSocket, mirroring just enough of RoutingHTTPServer's API for FBWebServer.m to swap
12
- // servers with a single #if TARGET_OS_WATCH.
9
+ // A minimal HTTP/1.1 server on top of FBTCPSocket (Network.framework-backed on every platform,
10
+ // since watchOS forbids BSD sockets outright - see FBTCPSocket.h/.m).
13
11
  //
14
12
  // No chunked encoding, range requests, or pipelining - just request line + headers +
15
- // Content-Length body, and ":param" path matching like RoutingHTTPServer.m.
13
+ // Content-Length body, and ":param" path matching.
16
14
 
17
15
  @import Foundation;
18
16
 
@@ -21,7 +19,7 @@
21
19
 
22
20
  NS_ASSUME_NONNULL_BEGIN
23
21
 
24
- @interface FBWatchHTTPServer : NSObject
22
+ @interface FBHTTPServer : NSObject
25
23
 
26
24
  /*! The port the server is (or will be) listening on */
27
25
  @property (nonatomic) uint16_t port;
@@ -40,9 +38,15 @@ NS_ASSUME_NONNULL_BEGIN
40
38
  */
41
39
  - (void)setDefaultHeader:(NSString *)field value:(NSString *)value;
42
40
 
41
+ /**
42
+ Sets the local IP address to bind the listener to. Must be called before -start:. Pass nil (the
43
+ default) to listen on all interfaces.
44
+ */
45
+ - (void)setInterface:(nullable NSString *)interface;
46
+
43
47
  /**
44
48
  Registers a route handler for the given HTTP method and path pattern (":param" segments are
45
- captured into the request's `params`, matching RoutingHTTPServer's convention).
49
+ captured into the request's `params`).
46
50
  */
47
51
  - (void)handleMethod:(NSString *)method
48
52
  withPath:(NSString *)path
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
 
9
- #import "FBWatchHTTPServer.h"
9
+ #import "FBHTTPServer.h"
10
10
 
11
11
  #import "FBConfiguration.h"
12
12
  #import "FBTCPSocket.h"
@@ -28,29 +28,30 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
28
28
  return (NSData * _Nonnull)[string dataUsingEncoding:NSUTF8StringEncoding];
29
29
  }
30
30
 
31
- @interface FBWatchHTTPRoute : NSObject
31
+ @interface FBHTTPRoute : NSObject
32
32
  @property (nonatomic, copy) NSString *verb;
33
33
  @property (nonatomic, strong) NSRegularExpression *regex;
34
34
  @property (nonatomic, copy, nullable) NSArray<NSString *> *keys;
35
35
  @property (nonatomic, copy) void (^block)(RouteRequest *request, RouteResponse *response);
36
36
  @end
37
37
 
38
- @implementation FBWatchHTTPRoute
38
+ @implementation FBHTTPRoute
39
39
  @end
40
40
 
41
41
 
42
- @interface FBWatchHTTPServer () <FBTCPSocketDelegate>
42
+ @interface FBHTTPServer () <FBTCPSocketDelegate>
43
43
 
44
44
  @property (nonatomic, nullable, strong) FBTCPSocket *socket;
45
- @property (nonatomic, strong) NSMutableArray<FBWatchHTTPRoute *> *routes;
45
+ @property (nonatomic, strong) NSMutableArray<FBHTTPRoute *> *routes;
46
46
  @property (nonatomic, strong) NSMutableDictionary<NSString *, NSString *> *defaultHeaders;
47
47
  @property (nonatomic, nullable) dispatch_queue_t routeQueue;
48
+ @property (nonatomic, copy, nullable) NSString *interface;
48
49
  // nw_connection_t isn't NSCopying, so it can't be an NSDictionary key - use NSMapTable instead.
49
50
  @property (nonatomic, strong) NSMapTable<id, NSMutableData *> *connectionBuffers;
50
51
 
51
52
  @end
52
53
 
53
- @implementation FBWatchHTTPServer
54
+ @implementation FBHTTPServer
54
55
 
55
56
  - (instancetype)init
56
57
  {
@@ -73,15 +74,20 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
73
74
  self.defaultHeaders[field] = value;
74
75
  }
75
76
 
77
+ - (void)setInterface:(nullable NSString *)interface
78
+ {
79
+ _interface = interface.copy;
80
+ }
81
+
76
82
  #pragma mark - Route registration
77
83
 
78
- - (FBWatchHTTPRoute *)compiledRouteWithPath:(NSString *)path
84
+ - (FBHTTPRoute *)compiledRouteWithPath:(NSString *)path
79
85
  {
80
- FBWatchHTTPRoute *route = [FBWatchHTTPRoute new];
86
+ FBHTTPRoute *route = [FBHTTPRoute new];
81
87
  NSMutableArray<NSString *> *keys = [NSMutableArray array];
82
88
 
83
89
  // Escape regex-significant characters before substituting :param placeholders, like
84
- // RoutingHTTPServer.m does.
90
+ // RoutingHTTPServer.m used to.
85
91
  NSRegularExpression *escapeRegex = [NSRegularExpression regularExpressionWithPattern:@"[.+()]"
86
92
  options:(NSRegularExpressionOptions)0
87
93
  error:nil];
@@ -126,7 +132,7 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
126
132
  withPath:(NSString *)path
127
133
  block:(void (^)(RouteRequest *request, RouteResponse *response))block
128
134
  {
129
- FBWatchHTTPRoute *route = [self compiledRouteWithPath:path];
135
+ FBHTTPRoute *route = [self compiledRouteWithPath:path];
130
136
  route.verb = method.uppercaseString;
131
137
  route.block = block;
132
138
  [self.routes addObject:route];
@@ -142,6 +148,7 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
142
148
  - (BOOL)start:(NSError **)error
143
149
  {
144
150
  FBTCPSocket *socket = [[FBTCPSocket alloc] initWithPort:self.port];
151
+ socket.interface = self.interface;
145
152
  socket.delegate = self;
146
153
  if (![socket startWithError:error]) {
147
154
  return NO;
@@ -239,8 +246,8 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
239
246
 
240
247
  NSUInteger contentLength = (NSUInteger)requestHeaders[@"content-length"].integerValue;
241
248
  if (contentLength > FBConfiguration.sharedInstance.httpRequestBodySizeLimit) {
242
- // Mirrors FBHTTPConnection's maxRequestBodySize enforcement on iOS/tvOS. Closes the
243
- // connection after responding, since the rest of the oversized body is still incoming.
249
+ // Mirrors CocoaHTTPServer's maxRequestBodySize enforcement. Closes the connection after
250
+ // responding, since the rest of the oversized body is still incoming.
244
251
  RouteResponse *tooLarge = [RouteResponse new];
245
252
  tooLarge.statusCode = kHTTPStatusCodeRequestEntityTooLarge;
246
253
  [tooLarge respondWithString:@"Request Entity Too Large"];
@@ -269,7 +276,7 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
269
276
  NSURLComponents *requestTarget = [NSURLComponents componentsWithString:pathAndQuery];
270
277
  NSString *path = requestTarget.path ?: pathAndQuery;
271
278
 
272
- for (FBWatchHTTPRoute *route in self.routes) {
279
+ for (FBHTTPRoute *route in self.routes) {
273
280
  if (![route.verb isEqualToString:method]) {
274
281
  continue;
275
282
  }
@@ -367,6 +374,12 @@ static NSData * _Nonnull FBUTF8Data(NSString *string)
367
374
  return @"Bad Request";
368
375
  } else if (kHTTPStatusCodeNotFound == statusCode) {
369
376
  return @"Not Found";
377
+ } else if (kHTTPStatusCodeMethodNotAllowed == statusCode) {
378
+ return @"Method Not Allowed";
379
+ } else if (kHTTPStatusCodeRequestTimeout == statusCode) {
380
+ return @"Request Timeout";
381
+ } else if (kHTTPStatusCodeRequestEntityTooLarge == statusCode) {
382
+ return @"Request Entity Too Large";
370
383
  } else if (kHTTPStatusCodeInternalServerError == statusCode) {
371
384
  return @"Internal Server Error";
372
385
  }
@@ -6,28 +6,18 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
 
9
- // TARGET_OS_WATCH must be defined before the #if below runs, or (on some older Xcode/SDK
10
- // toolchains) it silently evaluates as undefined/false here despite being true for the rest of
11
- // the translation unit - which desyncs this file's declarations from FBTCPSocket.m's own
12
- // #if TARGET_OS_WATCH branch.
13
- #import <TargetConditionals.h>
14
-
15
- #if TARGET_OS_WATCH
16
9
  @import Foundation;
17
10
  // A textual import, not `@import Network;` - older Xcode/watchOS SDK combinations (verified:
18
11
  // Xcode 15.4/watchOS 10.5) fail to expose nw_listener_t/nw_connection_t and friends through the
19
12
  // Network module map on watchOS, even though the underlying API has existed since watchOS 5.0.
13
+ // Kept unconditional (rather than gated to watchOS) since it also builds cleanly on iOS/tvOS.
20
14
  #import <Network/Network.h>
21
- #else
22
- #import "GCDAsyncSocket.h"
23
- #endif
24
15
 
25
16
  NS_ASSUME_NONNULL_BEGIN
26
17
 
27
- #if TARGET_OS_WATCH
28
-
29
- // watchOS forbids BSD sockets, so this is backed by Network.framework instead of GCDAsyncSocket -
30
- // hence a differently-shaped, push-style delegate protocol.
18
+ // Backed by Network.framework rather than BSD sockets on every platform, since watchOS forbids
19
+ // BSD sockets outright and there is no reason to keep a second, socket-based implementation
20
+ // around just for iOS/tvOS.
31
21
  @protocol FBTCPSocketDelegate <NSObject>
32
22
 
33
23
  /**
@@ -54,35 +44,6 @@ NS_ASSUME_NONNULL_BEGIN
54
44
 
55
45
  @end
56
46
 
57
- #else
58
-
59
- @protocol FBTCPSocketDelegate
60
-
61
- /**
62
- The callback which is fired on new TCP client connection
63
-
64
- @param newClient The newly connected socket
65
- */
66
- - (void)didClientConnect:(GCDAsyncSocket *)newClient;
67
-
68
- /**
69
- The callback which is fired when the TCP server receives a data from a connected client
70
-
71
- @param client The client, which sent the data
72
- */
73
- - (void)didClientSendData:(GCDAsyncSocket *)client;
74
-
75
- /**
76
- The callback which is fired when TCP client disconnects
77
-
78
- @param client The actual diconnected client
79
- */
80
- - (void)didClientDisconnect:(GCDAsyncSocket *)client;
81
-
82
- @end
83
-
84
- #endif
85
-
86
47
 
87
48
  @interface FBTCPSocket : NSObject
88
49
 
@@ -92,6 +53,19 @@ NS_ASSUME_NONNULL_BEGIN
92
53
  @property (nullable, nonatomic, assign) id<FBTCPSocketDelegate> delegate;
93
54
  #endif
94
55
 
56
+ /**
57
+ The port this socket is listening on. Equal to the port passed to -initWithPort: unless that was
58
+ 0 ("let the system assign a port"), in which case this reflects the actually assigned port once
59
+ -startWithError: has returned successfully.
60
+ */
61
+ @property (nonatomic, readonly) uint16_t port;
62
+
63
+ /**
64
+ The local IP address to bind the listener to, or nil to listen on all interfaces. Must be set
65
+ before -startWithError: is called.
66
+ */
67
+ @property (nonatomic, copy, nullable) NSString *interface;
68
+
95
69
  /**
96
70
  Creates TCP socket isntance which is going to be started on the specified port
97
71
 
@@ -113,7 +87,6 @@ NS_ASSUME_NONNULL_BEGIN
113
87
  */
114
88
  - (void)stop;
115
89
 
116
- #if TARGET_OS_WATCH
117
90
  /**
118
91
  Writes data to the given connected client
119
92
 
@@ -132,7 +105,6 @@ NS_ASSUME_NONNULL_BEGIN
132
105
  @param completion Called once the send attempt finishes
133
106
  */
134
107
  - (void)writeData:(NSData *)data toClient:(nw_connection_t)client completion:(nullable void (^)(void))completion;
135
- #endif
136
108
 
137
109
  @end
138
110
 
@@ -8,13 +8,10 @@
8
8
 
9
9
  #import "FBTCPSocket.h"
10
10
 
11
- #if TARGET_OS_WATCH
12
-
13
11
  @interface FBTCPSocket()
14
12
  @property (readonly, nonatomic) dispatch_queue_t socketQueue;
15
13
  @property (nullable, nonatomic) nw_listener_t listener;
16
14
  @property (readonly, nonatomic) NSMutableArray<nw_connection_t> *connectedClients;
17
- @property (readonly, nonatomic) uint16_t port;
18
15
  @end
19
16
 
20
17
 
@@ -38,7 +35,18 @@
38
35
  NSString *portString = [NSString stringWithFormat:@"%u", (unsigned int)self.port];
39
36
  // portString is always valid UTF8; -UTF8String is just declared nullable in general.
40
37
  const char * _Nonnull portCString = (const char * _Nonnull)portString.UTF8String;
41
- nw_listener_t listener = nw_listener_create_with_port(portCString, parameters);
38
+
39
+ nw_listener_t listener;
40
+ if (nil != self.interface) {
41
+ const char * _Nonnull interfaceCString = (const char * _Nonnull)((NSString * _Nonnull)self.interface).UTF8String;
42
+ nw_endpoint_t localEndpoint = nw_endpoint_create_host(interfaceCString, portCString);
43
+ nw_parameters_set_local_endpoint(parameters, localEndpoint);
44
+ // The port is already encoded in localEndpoint above - do not also pass it to
45
+ // nw_listener_create_with_port, which would be ambiguous.
46
+ listener = nw_listener_create(parameters);
47
+ } else {
48
+ listener = nw_listener_create_with_port(portCString, parameters);
49
+ }
42
50
  if (nil == listener) {
43
51
  if (error) {
44
52
  *error = [NSError errorWithDomain:@"FBTCPSocket"
@@ -61,6 +69,10 @@
61
69
  // if/else, not switch: -Wswitch-enum, -Wswitch-default, and -Wcovered-switch-default can't
62
70
  // all be satisfied by one switch statement at once.
63
71
  if (nw_listener_state_ready == state) {
72
+ __strong typeof(weakSelf) strongSelf = weakSelf;
73
+ if (strongSelf) {
74
+ strongSelf->_port = nw_listener_get_port(listener);
75
+ }
64
76
  dispatch_semaphore_signal(startupSemaphore);
65
77
  } else if (nw_listener_state_failed == state || nw_listener_state_cancelled == state) {
66
78
  // NSLocalizedDescriptionKey must be a string, not the underlying NSError itself, or
@@ -203,94 +215,3 @@
203
215
  }
204
216
 
205
217
  @end
206
-
207
- #else
208
-
209
- @interface FBTCPSocket()
210
- @property (readonly, nonatomic) dispatch_queue_t socketQueue;
211
- @property (readonly, nonatomic) GCDAsyncSocket *listeningSocket;
212
- @property (readonly, nonatomic) NSMutableArray *connectedClients;
213
- @property (readonly, nonatomic) uint16_t port;
214
- @end
215
-
216
-
217
- @interface FBTCPSocket(AsyncSocket) <GCDAsyncSocketDelegate>
218
-
219
- @end
220
-
221
-
222
- @implementation FBTCPSocket
223
-
224
- - (instancetype)initWithPort:(uint16_t)port
225
- {
226
- if ((self = [super init])) {
227
- _socketQueue = dispatch_queue_create("socketQueue", NULL);
228
- _listeningSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketQueue];
229
- _connectedClients = [[NSMutableArray alloc] initWithCapacity:1];
230
- _port = port;
231
- _delegate = nil;
232
- }
233
- return self;
234
- }
235
-
236
- - (BOOL)startWithError:(NSError **)error
237
- {
238
- if (![self.listeningSocket acceptOnPort:self.port error:error]) {
239
- return NO;
240
- }
241
-
242
- return YES;
243
- }
244
-
245
- - (void)stop
246
- {
247
- @synchronized(self.connectedClients) {
248
- NSArray *clients = self.connectedClients.copy;
249
- [self.connectedClients removeAllObjects];
250
- for (GCDAsyncSocket *client in clients) {
251
- [client disconnect];
252
- }
253
- }
254
-
255
- self.delegate = nil;
256
- [self.listeningSocket disconnect];
257
- }
258
-
259
- @end
260
-
261
-
262
- @implementation FBTCPSocket(AsyncSocket)
263
-
264
- - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
265
- {
266
- @synchronized(self.connectedClients) {
267
- [self.connectedClients addObject:newSocket];
268
- }
269
- id<FBTCPSocketDelegate> delegate = self.delegate;
270
- if (nil != delegate) {
271
- [delegate didClientConnect:newSocket];
272
- }
273
- }
274
-
275
- - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
276
- {
277
- id<FBTCPSocketDelegate> delegate = self.delegate;
278
- if (nil != delegate) {
279
- [delegate didClientSendData:sock];
280
- }
281
- }
282
-
283
- - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
284
- {
285
- @synchronized(self.connectedClients) {
286
- [self.connectedClients removeObject:sock];
287
- }
288
- id<FBTCPSocketDelegate> delegate = self.delegate;
289
- if (nil != delegate) {
290
- [delegate didClientDisconnect:sock];
291
- }
292
- }
293
-
294
- @end
295
-
296
- #endif
@@ -8,7 +8,7 @@
8
8
 
9
9
  #import <Foundation/Foundation.h>
10
10
 
11
- @class RouteResponse, RoutingHTTPServer, FBExceptionHandler;
11
+ @class RouteResponse, FBExceptionHandler;
12
12
  @protocol FBWebServerDelegate;
13
13
 
14
14
  NS_ASSUME_NONNULL_BEGIN
@@ -8,14 +8,9 @@
8
8
 
9
9
  #import "FBWebServer.h"
10
10
 
11
- #if TARGET_OS_WATCH
12
- #import "FBWatchHTTPServer.h"
13
- #else
14
- #import "RoutingConnection.h"
15
- #import "RoutingHTTPServer.h"
11
+ #import "FBHTTPServer.h"
16
12
  #import "FBMjpegServer.h"
17
13
  #import "FBTCPSocket.h"
18
- #endif
19
14
 
20
15
  #import "FBCommandHandler.h"
21
16
  #import "FBErrorBuilder.h"
@@ -32,36 +27,11 @@
32
27
  static NSString *const FBServerURLBeginMarker = @"ServerURLHere->";
33
28
  static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
34
29
 
35
- #if !TARGET_OS_WATCH
36
- @interface FBHTTPConnection : RoutingConnection
37
- @end
38
-
39
- @implementation FBHTTPConnection
40
-
41
- - (void)handleResourceNotFound
42
- {
43
- [FBLogger logFmt:@"Received request for %@ which we do not handle", self.requestURI];
44
- [super handleResourceNotFound];
45
- }
46
-
47
- - (UInt64)maxRequestBodySize
48
- {
49
- return FBConfiguration.sharedInstance.httpRequestBodySizeLimit;
50
- }
51
-
52
- @end
53
- #endif
54
-
55
-
56
30
  @interface FBWebServer ()
57
31
  @property (nonatomic, strong) FBExceptionHandler *exceptionHandler;
58
- #if TARGET_OS_WATCH
59
- @property (nonatomic, strong) FBWatchHTTPServer *server;
60
- #else
61
- @property (nonatomic, strong) RoutingHTTPServer *server;
32
+ @property (nonatomic, strong) FBHTTPServer *server;
62
33
  @property (nonatomic, nullable) FBTCPSocket *screenshotsBroadcaster;
63
34
  @property (nonatomic, nullable, strong) FBMjpegServer *mjpegServer;
64
- #endif
65
35
  @property (atomic, assign) BOOL keepAlive;
66
36
  @end
67
37
 
@@ -69,9 +39,7 @@ static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
69
39
 
70
40
  - (void)dealloc
71
41
  {
72
- #if !TARGET_OS_WATCH
73
42
  [self stopScreenshotsBroadcaster];
74
- #endif
75
43
  }
76
44
 
77
45
  + (NSArray<Class<FBCommandHandler>> *)collectCommandHandlerClasses
@@ -96,9 +64,7 @@ static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
96
64
  if (![self startHTTPServer]) {
97
65
  return;
98
66
  }
99
- #if !TARGET_OS_WATCH
100
67
  [self initScreenshotsBroadcaster];
101
- #endif
102
68
 
103
69
  self.keepAlive = YES;
104
70
  NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
@@ -108,30 +74,21 @@ static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
108
74
 
109
75
  - (BOOL)startHTTPServer
110
76
  {
111
- #if TARGET_OS_WATCH
112
- self.server = [[FBWatchHTTPServer alloc] init];
113
- #else
114
- self.server = [[RoutingHTTPServer alloc] init];
115
- #endif
77
+ self.server = [[FBHTTPServer alloc] init];
116
78
  [self.server setRouteQueue:dispatch_get_main_queue()];
117
79
  [self.server setDefaultHeader:@"Server" value:@"WebDriverAgent/1.0"];
118
80
  [self.server setDefaultHeader:@"Access-Control-Allow-Origin" value:@"*"];
119
81
  [self.server setDefaultHeader:@"Access-Control-Allow-Headers" value:@"Content-Type, X-Requested-With"];
120
- #if !TARGET_OS_WATCH
121
- [self.server setConnectionClass:[FBHTTPConnection self]];
122
- #endif
123
82
 
124
83
  [self registerRouteHandlers:[self.class collectCommandHandlerClasses]];
125
84
  [self registerServerKeyRouteHandlers];
126
85
 
127
86
  NSRange serverPortRange = FBConfiguration.sharedInstance.bindingPortRange;
128
87
  NSString *bindingIP = FBConfiguration.sharedInstance.bindingIPAddress;
129
- #if !TARGET_OS_WATCH
130
88
  if (bindingIP != nil) {
131
89
  [self.server setInterface:bindingIP];
132
90
  [FBLogger logFmt:@"Using custom binding IP address: %@", bindingIP];
133
91
  }
134
- #endif
135
92
 
136
93
  NSError *error;
137
94
  BOOL serverStarted = NO;
@@ -163,13 +120,13 @@ static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
163
120
  return YES;
164
121
  }
165
122
 
166
- #if !TARGET_OS_WATCH
167
123
  - (void)initScreenshotsBroadcaster
168
124
  {
169
125
  [self readMjpegSettingsFromEnv];
170
126
  self.mjpegServer = [[FBMjpegServer alloc] init];
171
127
  self.screenshotsBroadcaster = [[FBTCPSocket alloc]
172
128
  initWithPort:(uint16_t)FBConfiguration.sharedInstance.mjpegServerPort];
129
+ self.mjpegServer.socket = self.screenshotsBroadcaster;
173
130
  self.screenshotsBroadcaster.delegate = self.mjpegServer;
174
131
  NSError *error;
175
132
  if (![self.screenshotsBroadcaster startWithError:&error]) {
@@ -209,14 +166,11 @@ static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
209
166
  FBConfiguration.sharedInstance.mjpegServerScreenshotQuality = [screenshotQuality integerValue];
210
167
  }
211
168
  }
212
- #endif
213
169
 
214
170
  - (void)stopServing
215
171
  {
216
172
  [FBSession.activeSession kill];
217
- #if !TARGET_OS_WATCH
218
173
  [self stopScreenshotsBroadcaster];
219
- #endif
220
174
  if (self.server.isRunning) {
221
175
  [self.server stop:NO];
222
176
  }
@@ -225,11 +179,7 @@ static NSString *const FBServerURLEndMarker = @"<-ServerURLHere";
225
179
  self.keepAlive = NO;
226
180
  }
227
181
 
228
- #if TARGET_OS_WATCH
229
- - (BOOL)attemptToStartServer:(FBWatchHTTPServer *)server onPort:(NSInteger)port withError:(NSError **)error
230
- #else
231
- - (BOOL)attemptToStartServer:(RoutingHTTPServer *)server onPort:(NSInteger)port withError:(NSError **)error
232
- #endif
182
+ - (BOOL)attemptToStartServer:(FBHTTPServer *)server onPort:(NSInteger)port withError:(NSError **)error
233
183
  {
234
184
  server.port = (UInt16)port;
235
185
  NSError *innerError = nil;
@@ -6,10 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
 
9
- // Minimal, watchOS-only stand-in for Vendor/RoutingHTTPServer/RouteRequest.h, which is not
10
- // available on watchOS because RoutingHTTPServer/CocoaHTTPServer/CocoaAsyncSocket cannot be
11
- // built there (see FBWatchHTTPServer.h). Exposes just the surface FBWebServer's route blocks
12
- // and FBRoute.decorateRequest: read.
9
+ // A minimal request value type, exposing just the surface FBWebServer's route blocks and
10
+ // FBRoute.decorateRequest: read.
13
11
 
14
12
  @import Foundation;
15
13
 
@@ -6,8 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
 
9
- // Minimal, watchOS-only stand-in for Vendor/RoutingHTTPServer/RouteResponse.h, reproducing just
10
- // what FBRoute.m/FBResponseJSONPayload.m call on it. See FBWatchHTTPServer.h.
9
+ // A minimal response value type, exposing just the surface FBRoute.m/FBResponseJSONPayload.m
10
+ // call on it.
11
11
 
12
12
  @import Foundation;
13
13
  #import <WebDriverAgentLib/FBHTTPStatusCodes.h>
@@ -19,6 +19,13 @@ NS_ASSUME_NONNULL_BEGIN
19
19
  */
20
20
  - (instancetype)init;
21
21
 
22
+ /**
23
+ The socket that owns this instance as its delegate. Clients are bare nw_connection_t values
24
+ with no write method of their own, so frame writes are routed through
25
+ -[FBTCPSocket writeData:toClient:]. Must be set before streaming starts.
26
+ */
27
+ @property (nonatomic, weak, nullable) FBTCPSocket *socket;
28
+
22
29
  /**
23
30
  Stops screenshot broadcasting and prevents future scheduling.
24
31
  */