Ben Copsey

Added a global user agent, which can still be selectively overwritten by setting it per request

Many thanks to Garrett Bjerkhoel for the code and patience in getting this merged (I've slightly adapted his original take on this)

Conflicts:

	Classes/ASIHTTPRequest.m
... ... @@ -192,6 +192,9 @@ typedef void (^ASIDataBlock)(NSData *data);
NSString *username;
NSString *password;
// Global User-Agent for requests unless one is provided for a specific request
NSString *userAgent;
// Domain used for NTLM authentication
NSString *domain;
... ... @@ -794,6 +797,7 @@ typedef void (^ASIDataBlock)(NSData *data);
// Will be used as a user agent if requests do not specify a custom user agent
// Is only used when you have specified a Bundle Display Name (CFDisplayBundleName) or Bundle Name (CFBundleName) in your plist
+ (NSString *)defaultUserAgentString;
+ (void)setDefaultUserAgentString:(NSString *)agent;
#pragma mark mime-type detection
... ... @@ -890,6 +894,7 @@ typedef void (^ASIDataBlock)(NSData *data);
@property (retain) NSString *username;
@property (retain) NSString *password;
@property (retain) NSString *userAgent;
@property (retain) NSString *domain;
@property (retain) NSString *proxyUsername;
... ...
... ... @@ -26,6 +26,8 @@
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.8-56 2011-02-06";
static NSString *defaultUserAgent = nil;
NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
static NSString *ASIHTTPRequestRunLoopMode = @"ASIHTTPRequestRunLoopMode";
... ... @@ -64,7 +66,6 @@ static NSError *ASITooMuchRedirectionError;
static NSMutableArray *bandwidthUsageTracker = nil;
static unsigned long averageBandwidthUsedPerSecond = 0;
// These are used for queuing persistent connections on the same connection
// Incremented every time we specify we want a new connection
... ... @@ -122,19 +123,14 @@ static NSDate *throttleWakeUpTime = nil;
static id <ASICacheDelegate> defaultCache = nil;
// Used for tracking when requests are using the network
static unsigned int runningRequestCount = 0;
// You can use [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO] if you want to manage it yourself
// Alternatively, override showNetworkActivityIndicator / hideNetworkActivityIndicator
// By default this does nothing on Mac OS X, but again override the above methods for a different behaviour
static BOOL shouldUpdateNetworkActivityIndicator = YES;
//**Queue stuff**/
// The thread all requests will run on
// Hangs around forever, but will be blocked unless there are requests underway
static NSThread *networkThread = nil;
... ... @@ -1038,7 +1034,10 @@ static NSOperationQueue *sharedQueue = nil;
// Build and set the user agent string if the request does not already have a custom user agent specified
if (![[self requestHeaders] objectForKey:@"User-Agent"]) {
NSString *userAgentString = [ASIHTTPRequest defaultUserAgentString];
NSString *userAgentString = [self userAgent];
if (!userAgentString) {
userAgentString = [ASIHTTPRequest defaultUserAgentString];
}
if (userAgentString) {
[self addRequestHeader:@"User-Agent" value:userAgentString];
}
... ... @@ -4088,6 +4087,13 @@ static NSOperationQueue *sharedQueue = nil;
+ (NSString *)defaultUserAgentString
{
// If we already have a default user agent set, return that
if (defaultUserAgent) {
return defaultUserAgent;
}
// Otherwise, create a new user agent string (we'll save it for later reuse)
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
// Attempt to find a name for this application
... ... @@ -4143,9 +4149,17 @@ static NSOperationQueue *sharedQueue = nil;
#endif
// Takes the form "My Application 1.0 (Macintosh; Mac OS X 10.5.7; en_GB)"
return [NSString stringWithFormat:@"%@ %@ (%@; %@ %@; %@)", appName, appVersion, deviceName, OSName, OSVersion, locale];
[self setDefaultUserAgentString:[NSString stringWithFormat:@"%@ %@ (%@; %@ %@; %@)", appName, appVersion, deviceName, OSName, OSVersion, locale]];
return defaultUserAgent;
}
+ (void)setDefaultUserAgentString:(NSString *)agent
{
[defaultUserAgent release];
defaultUserAgent = [agent copy];
}
#pragma mark mime-type detection
+ (NSString *)mimeTypeForFileAtPath:(NSString *)path
... ... @@ -4306,7 +4320,6 @@ static NSOperationQueue *sharedQueue = nil;
+ (unsigned long)maxUploadReadLength
{
[bandwidthThrottlingLock lock];
// We'll split our bandwidth allowance into 4 (which is the default for an ASINetworkQueue's max concurrent operations count) to give all running requests a fighting chance of reading data this cycle
... ... @@ -4656,6 +4669,7 @@ static NSOperationQueue *sharedQueue = nil;
@synthesize username;
@synthesize password;
@synthesize userAgent;
@synthesize domain;
@synthesize proxyUsername;
@synthesize proxyPassword;
... ...
... ... @@ -380,14 +380,41 @@
BOOL success = [[request responseString] isEqualToString:[ASIHTTPRequest defaultUserAgentString]];
GHAssertTrue(success,@"Failed to set the correct user agent");
}
// Now test specifying a custom user agent
NSString *customUserAgent = @"Ferdinand Fuzzworth's Magic Tent of Mystery";
// Test specifying a custom user-agent for a single request
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
[request addRequestHeader:@"User-Agent" value:@"Ferdinand Fuzzworth's Magic Tent of Mystery"];
[request addRequestHeader:@"User-Agent" value:customUserAgent];
[request startSynchronous];
BOOL success = [[request responseString] isEqualToString:@"Ferdinand Fuzzworth's Magic Tent of Mystery"];
GHAssertTrue(success,@"Failed to set the correct user agent");
BOOL success = [[request responseString] isEqualToString:customUserAgent];
GHAssertTrue(success,@"Failed to set the correct user-agent for a single request");
// Test again using userAgent
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
[request setUserAgent:customUserAgent];
[request startSynchronous];
success = [[request responseString] isEqualToString:customUserAgent];
GHAssertTrue(success,@"Failed to set the correct user-agent for a single request");
// Test again to ensure user-agent not reused
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
[request startSynchronous];
success = ![[request responseString] isEqualToString:customUserAgent];
GHAssertTrue(success,@"Re-used a user agent when we shouldn't have done so");
// Test setting a custom default user-agent string
[ASIHTTPRequest setDefaultUserAgentString:customUserAgent];
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
[request startSynchronous];
success = [[request responseString] isEqualToString:customUserAgent];
GHAssertTrue(success,@"Failed to set the correct user-agent when using a custom default");
[ASIHTTPRequest setDefaultUserAgentString:nil];
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
[request startSynchronous];
success = ![[request responseString] isEqualToString:customUserAgent];
GHAssertTrue(success,@"Failed to clear a custom default user-agent");
}
- (void)testAutomaticRedirection
... ...