1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/service/net/service_url_request_context_getter.h"
6
7#if defined(OS_POSIX) && !defined(OS_MACOSX)
8#include <sys/utsname.h>
9#endif
10
11#include "base/compiler_specific.h"
12#include "base/message_loop/message_loop_proxy.h"
13#include "base/strings/stringprintf.h"
14#include "base/sys_info.h"
15#include "chrome/common/chrome_version_info.h"
16#include "chrome/service/service_process.h"
17#include "net/proxy/proxy_config_service.h"
18#include "net/proxy/proxy_service.h"
19#include "net/url_request/url_request_context_builder.h"
20
21namespace {
22// Copied from webkit/glue/user_agent.cc. We don't want to pull in a dependency
23// on webkit/glue which also pulls in the renderer. Also our user-agent is
24// totally different from the user-agent used by the browser, just the
25// OS-specific parts are common.
26std::string BuildOSCpuInfo() {
27  std::string os_cpu;
28
29#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
30  int32 os_major_version = 0;
31  int32 os_minor_version = 0;
32  int32 os_bugfix_version = 0;
33  base::SysInfo::OperatingSystemVersionNumbers(&os_major_version,
34                                               &os_minor_version,
35                                               &os_bugfix_version);
36#endif
37#if defined(OS_POSIX) && !defined(OS_MACOSX)
38  // Should work on any Posix system.
39  struct utsname unixinfo;
40  uname(&unixinfo);
41
42  std::string cputype;
43  // special case for biarch systems
44  if (strcmp(unixinfo.machine, "x86_64") == 0 &&
45      sizeof(void*) == sizeof(int32)) {  // NOLINT
46    cputype.assign("i686 (x86_64)");
47  } else {
48    cputype.assign(unixinfo.machine);
49  }
50#endif
51
52  base::StringAppendF(
53      &os_cpu,
54#if defined(OS_WIN)
55      "Windows NT %d.%d",
56      os_major_version,
57      os_minor_version
58#elif defined(OS_MACOSX)
59      "Intel Mac OS X %d_%d_%d",
60      os_major_version,
61      os_minor_version,
62      os_bugfix_version
63#elif defined(OS_CHROMEOS)
64      "CrOS %s %d.%d.%d",
65      cputype.c_str(),  // e.g. i686
66      os_major_version,
67      os_minor_version,
68      os_bugfix_version
69#else
70      "%s %s",
71      unixinfo.sysname,  // e.g. Linux
72      cputype.c_str()    // e.g. i686
73#endif
74  );  // NOLINT
75
76  return os_cpu;
77}
78
79// Returns the default user agent.
80std::string MakeUserAgentForServiceProcess() {
81  std::string user_agent;
82  chrome::VersionInfo version_info;
83  if (!version_info.is_valid()) {
84    DLOG(ERROR) << "Unable to create chrome::VersionInfo object";
85  }
86  std::string extra_version_info;
87  if (!version_info.IsOfficialBuild())
88    extra_version_info = "-devel";
89  base::StringAppendF(&user_agent,
90                      "Chrome Service %s(%s)%s %s ",
91                      version_info.Version().c_str(),
92                      version_info.LastChange().c_str(),
93                      extra_version_info.c_str(),
94                      BuildOSCpuInfo().c_str());
95  return user_agent;
96}
97
98}  // namespace
99
100ServiceURLRequestContextGetter::ServiceURLRequestContextGetter()
101    : user_agent_(MakeUserAgentForServiceProcess()),
102      network_task_runner_(
103          g_service_process->io_thread()->message_loop_proxy()) {
104  // TODO(sanjeevr): Change CreateSystemProxyConfigService to accept a
105  // MessageLoopProxy* instead of MessageLoop*.
106  DCHECK(g_service_process);
107  proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(
108      g_service_process->io_thread()->message_loop_proxy(),
109      g_service_process->file_thread()->message_loop_proxy()));
110}
111
112net::URLRequestContext*
113ServiceURLRequestContextGetter::GetURLRequestContext() {
114  if (!url_request_context_.get()) {
115    net::URLRequestContextBuilder builder;
116    builder.set_user_agent(user_agent_);
117    builder.set_accept_language("en-us,fr");
118    builder.set_proxy_config_service(proxy_config_service_.release());
119    builder.set_throttling_enabled(true);
120    url_request_context_.reset(builder.Build());
121  }
122  return url_request_context_.get();
123}
124
125scoped_refptr<base::SingleThreadTaskRunner>
126ServiceURLRequestContextGetter::GetNetworkTaskRunner() const {
127  return network_task_runner_;
128}
129
130ServiceURLRequestContextGetter::~ServiceURLRequestContextGetter() {}
131