1 /******************************************************************************
2 * $Id: PortChecker.m 11617 2011-01-01 20:42:14Z livings124 $
4 * Copyright (c) 2006-2011 Transmission authors and contributors
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
25 #import "PortChecker.h"
27 #define CHECKER_URL(port) [NSString stringWithFormat: @"http://portcheck.transmissionbt.com/%d", port]
28 #define CHECK_FIRE 3.0
30 @interface PortChecker (Private)
32 - (void) startProbe: (NSTimer *) timer;
34 - (void) callBackWithStatus: (port_status_t) status;
38 @implementation PortChecker
40 - (id) initForPort: (NSInteger) portNumber delay: (BOOL) delay withDelegate: (id) delegate
42 if ((self = [super init]))
46 fStatus = PORT_STATUS_CHECKING;
48 fTimer = [NSTimer scheduledTimerWithTimeInterval: CHECK_FIRE target: self selector: @selector(startProbe:)
49 userInfo: [NSNumber numberWithInteger: portNumber] repeats: NO];
61 [fConnection release];
62 [fPortProbeData release];
66 - (port_status_t) status
79 - (void) connection: (NSURLConnection *) connection didReceiveResponse: (NSURLResponse *) response
81 [fPortProbeData setLength: 0];
84 - (void) connection: (NSURLConnection *) connection didReceiveData: (NSData *) data
86 [fPortProbeData appendData: data];
89 - (void) connection: (NSURLConnection *) connection didFailWithError: (NSError *) error
91 NSLog(@"Unable to get port status: connection failed (%@)", [error localizedDescription]);
92 [self callBackWithStatus: PORT_STATUS_ERROR];
95 - (void) connectionDidFinishLoading: (NSURLConnection *) connection
97 NSString * probeString = [[NSString alloc] initWithData: fPortProbeData encoding: NSUTF8StringEncoding];
98 [fPortProbeData release];
103 if ([probeString isEqualToString: @"1"])
104 [self callBackWithStatus: PORT_STATUS_OPEN];
105 else if ([probeString isEqualToString: @"0"])
106 [self callBackWithStatus: PORT_STATUS_CLOSED];
109 NSLog(@"Unable to get port status: invalid response (%@)", probeString);
110 [self callBackWithStatus: PORT_STATUS_ERROR];
112 [probeString release];
116 NSLog(@"Unable to get port status: invalid data received");
117 [self callBackWithStatus: PORT_STATUS_ERROR];
123 @implementation PortChecker (Private)
125 - (void) startProbe: (NSTimer *) timer
129 NSURLRequest * portProbeRequest = [NSURLRequest requestWithURL: [NSURL URLWithString: CHECKER_URL([[timer userInfo] integerValue])]
130 cachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval: 15.0];
132 if ((fConnection = [[NSURLConnection alloc] initWithRequest: portProbeRequest delegate: self]))
133 fPortProbeData = [[NSMutableData alloc] init];
136 NSLog(@"Unable to get port status: failed to initiate connection");
137 [self callBackWithStatus: PORT_STATUS_ERROR];
141 - (void) callBackWithStatus: (port_status_t) status
145 if (fDelegate && [fDelegate respondsToSelector: @selector(portCheckerDidFinishProbing:)])
146 [fDelegate performSelectorOnMainThread: @selector(portCheckerDidFinishProbing:) withObject: self waitUntilDone: NO];