User-Agent changes to use my product name

Hi,


I've created an application and set the User-Agent string like so:



class GlobalUtils: NSObject {
    static let UserAgentString : String = "HttpClientSample"
    static let UserAgentVersion : String = "1.0"
}
let config = URLSessionConfiguration.default
        config.httpAdditionalHeaders = ["User-Agent": "\(GlobalUtils.UserAgentVersion)/\(GlobalUtils.UserAgentVersion)"]
        let defaultSession : URLSession = URLSession(configuration: config, delegate: self.CurrentSession!, delegateQueue: OperationQueue.main)

However, I find that sometimes the user-agent appears to be in the format as


$CFBundleName$/$Version$ CFNetwork/976 Darwin/18.20.0


Do you know in what cases this would occur and how to control this behavior? When this occurs my HTTP requests don't go through the proxy server because they don't match my User-Agent.


Thanks,

Dave

Answered by DTS Engineer in 351660022

Thanks for the clarification.

Are you sure that the problematic request was from a task created in your session? It’s very easy to accidentally reference

URLSession.shared
rather than
self.defaultSession
(or whatever) and you’ll see this behaviour.

How reproducible is this?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Is that project using macros for those strings in Build Settings ~ Info.plist, or are they hardcoded?

However, I find that sometimes the user-agent appears to be in the format as

Are you saying that you literally see a dollars sign (

$
) in the user agent string? Or are you using the stuff delimited by dollars signs as a placeholder just for this example?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Sorry for the confusion. What I see is the name of the value for "Product Name", but what I want to see is what I set via code. For example, say my product was named "Ews Editor", but I wanted my User-Agent to be "HttpSampleClient". What I see when this happens is Ews Editor/1 CFNetwork/976 Darwin/18.20.0 instead of what I expect it to be (since I set the Session Configuration to use a specific User-Agent) HttpClientSample/1 CFNetwork/976 Darwin/18.20.0


Now this is sort of a contrived example, but it's what I'm seeing.


Now why this matters, is because I should be able to progammaticaly control what the User-Agent is when the HTTP requests are made.

Accepted Answer

Thanks for the clarification.

Are you sure that the problematic request was from a task created in your session? It’s very easy to accidentally reference

URLSession.shared
rather than
self.defaultSession
(or whatever) and you’ll see this behaviour.

How reproducible is this?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi,

I'm not referencing URLSession.shared. I have posted the code I'm using in the original thread. I can reproduce it on demand.

Thanks,
Dave

I can reproduce it on demand.

But earlier you wrote:

However, I find that sometimes the user-agent appears to be in the format

Does that mean that you can reproduce the problem eventually, but you might have to run the program a bunch of times? If not, please clarify.

Also, under what circumstances are you reproducing this?

I have posted the code I'm using in the original thread.

In order to set a baseline, I took your code and put it into a new test project. I then fleshed it out to actually run a request. Here’s the resulting property and method on my view controller.

var session: URLSession!

func start() {
    if self.session == nil {
        let config = URLSessionConfiguration.default
        config.requestCachePolicy = .reloadIgnoringLocalCacheData
        config.httpAdditionalHeaders = ["User-Agent": "HelloCruelWorld"]
        self.session = URLSession(configuration: config, delegate: nil, delegateQueue: .main)
    }
    NSLog("task start")
    let url = URL(string: "http://127.0.0.1:12345")!
    let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
    self.session.dataTask(with: request) { (data, response, error) in
        if let error = error as NSError? {
            NSLog("task transport error %@ / %d", error.domain, error.code)
            return
        }
        let response = response as! HTTPURLResponse
        let data = data!
        NSLog("task finished with status %d, bytes %d", response.statusCode, data.count)
    }.resume()
}

I then started a dummy server in Terminal:

$ nc -l 12345

Next I ran my code in the iOS 12.1 simulator from Xcode 10.1, and here’s the request I get:

GET / HTTP/1.1
Host: 127.0.0.1:12345
Accept: */*
Accept-Language: en-us
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: HelloCruelWorld

So putting a user agent in

httpAdditionalHeaders
works, at least in some circumstances. If you can help narrow down the circumstances where it fails, that’d be grand.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo,


Thanks for your help here! I was able to identify that the "errant" User-Agent was coming out of a library that I depended on. It was spinning up a new defaultSession and that was leading to the problem.


Thanks for your help,
Dave

User-Agent changes to use my product name
 
 
Q