@@ -47,10 +47,16 @@ @interface FBWebServer ()
4747@property (nonatomic , strong ) RoutingHTTPServer *server;
4848@property (atomic , assign ) BOOL keepAlive;
4949@property (nonatomic , nullable ) FBTCPSocket *screenshotsBroadcaster;
50+ @property (nonatomic , nullable , strong ) FBMjpegServer *mjpegServer;
5051@end
5152
5253@implementation FBWebServer
5354
55+ - (void )dealloc
56+ {
57+ [self stopScreenshotsBroadcaster ];
58+ }
59+
5460+ (NSArray <Class<FBCommandHandler>> *)collectCommandHandlerClasses
5561{
5662 NSArray *handlersClasses = FBClassesThatConformsToProtocol (@protocol (FBCommandHandler));
@@ -97,7 +103,7 @@ - (void)startHTTPServer
97103 [self .server setInterface: bindingIP];
98104 [FBLogger logFmt: @" Using custom binding IP address: %@ " , bindingIP];
99105 }
100-
106+
101107 NSError *error;
102108 BOOL serverStarted = NO ;
103109
@@ -117,31 +123,42 @@ - (void)startHTTPServer
117123 [FBLogger logFmt: @" Last attempt to start web server failed with error %@ " , [error description ]];
118124 abort ();
119125 }
120-
126+
121127 NSString *serverHost = bindingIP ?: ([XCUIDevice sharedDevice ].fb_wifiIPAddress ?: @" 127.0.0.1" );
122128 [FBLogger logFmt: @" %@ http://%@ :%d %@ " , FBServerURLBeginMarker, serverHost, [self .server port ], FBServerURLEndMarker];
123129}
124130
125131- (void )initScreenshotsBroadcaster
126132{
127133 [self readMjpegSettingsFromEnv ];
134+ self.mjpegServer = [[FBMjpegServer alloc ] init ];
128135 self.screenshotsBroadcaster = [[FBTCPSocket alloc ]
129136 initWithPort: (uint16_t )FBConfiguration.mjpegServerPort];
130- self.screenshotsBroadcaster .delegate = [[FBMjpegServer alloc ] init ] ;
137+ self.screenshotsBroadcaster .delegate = self. mjpegServer ;
131138 NSError *error;
132139 if (![self .screenshotsBroadcaster startWithError: &error]) {
133140 [FBLogger logFmt: @" Cannot init screenshots broadcaster service on port %@ . Original error: %@ " , @(FBConfiguration.mjpegServerPort), error.description];
141+ [self .mjpegServer stopStreaming ];
142+ self.mjpegServer = nil ;
134143 self.screenshotsBroadcaster = nil ;
135144 }
136145}
137146
138147- (void )stopScreenshotsBroadcaster
139148{
140149 if (nil == self.screenshotsBroadcaster ) {
150+ self.mjpegServer = nil ;
141151 return ;
142152 }
143153
154+ id <FBTCPSocketDelegate> delegate = self.screenshotsBroadcaster .delegate ;
155+ if ([(NSObject *)delegate respondsToSelector: @selector (stopStreaming )]) {
156+ [(FBMjpegServer *)delegate stopStreaming ];
157+ }
158+ self.screenshotsBroadcaster .delegate = nil ;
144159 [self .screenshotsBroadcaster stop ];
160+ self.screenshotsBroadcaster = nil ;
161+ self.mjpegServer = nil ;
145162}
146163
147164- (void )readMjpegSettingsFromEnv
@@ -164,6 +181,8 @@ - (void)stopServing
164181 if (self.server .isRunning ) {
165182 [self .server stop: NO ];
166183 }
184+ self.server = nil ;
185+ self.exceptionHandler = nil ;
167186 self.keepAlive = NO ;
168187}
169188
@@ -192,10 +211,15 @@ - (BOOL)attemptToStartServer:(RoutingHTTPServer *)server onPort:(NSInteger)port
192211
193212- (void )registerRouteHandlers : (NSArray *)commandHandlerClasses
194213{
214+ __weak typeof (self) weakSelf = self;
195215 for (Class <FBCommandHandler> commandHandler in commandHandlerClasses) {
196216 NSArray *routes = [commandHandler routes ];
197217 for (FBRoute *route in routes) {
198218 [self .server handleMethod: route.verb withPath: route.path block: ^(RouteRequest *request, RouteResponse *response) {
219+ __strong typeof (weakSelf) strongSelf = weakSelf;
220+ if (nil == strongSelf) {
221+ return ;
222+ }
199223 NSDictionary *arguments = [NSJSONSerialization JSONObjectWithData: request.body options: NSJSONReadingMutableContainers error: NULL ];
200224 FBRouteRequest *routeParams = [FBRouteRequest
201225 routeRequestWithURL: request.url
@@ -209,7 +233,7 @@ - (void)registerRouteHandlers:(NSArray *)commandHandlerClasses
209233 [route mountRequest: routeParams intoResponse: response];
210234 }
211235 @catch (NSException *exception) {
212- [self handleException: exception forResponse: response];
236+ [strongSelf handleException: exception forResponse: response];
213237 }
214238 }];
215239 }
@@ -237,9 +261,14 @@ - (void)registerServerKeyRouteHandlers
237261 [response respondWithString: calibrationPage];
238262 }];
239263
264+ __weak typeof (self) weakSelf = self;
240265 [self .server get: @" /wda/shutdown" withBlock: ^(RouteRequest *request, RouteResponse *response) {
266+ __strong typeof (weakSelf) strongSelf = weakSelf;
267+ if (nil == strongSelf) {
268+ return ;
269+ }
241270 [response respondWithString: @" Shutting down" ];
242- [self .delegate webServerDidRequestShutdown: self ];
271+ [strongSelf .delegate webServerDidRequestShutdown: strongSelf ];
243272 }];
244273
245274 [self registerRouteHandlers: @[FBUnknownCommands.class]];
0 commit comments