1 // Copyright (c) 2011 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.
5 #include "net/base/net_util.h"
11 #include "base/file_path.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/string_piece.h"
14 #include "base/string_util.h"
15 #include "base/sys_string_conversions.h"
16 #include "base/threading/thread_restrictions.h"
17 #include "base/utf_string_conversions.h"
18 #include "googleurl/src/gurl.h"
19 #include "net/base/escape.h"
20 #include "net/base/ip_endpoint.h"
21 #include "net/base/net_errors.h"
25 bool FileURLToFilePath(const GURL
& url
, FilePath
* file_path
) {
26 *file_path
= FilePath();
27 std::wstring
& file_path_str
= const_cast<std::wstring
&>(file_path
->value());
28 file_path_str
.clear();
34 std::string host
= url
.host();
36 // URL contains no host, the path is the filename. In this case, the path
37 // will probably be preceeded with a slash, as in "/C:/foo.txt", so we
38 // trim out that here.
40 size_t first_non_slash
= path
.find_first_not_of("/\\");
41 if (first_non_slash
!= std::string::npos
&& first_non_slash
> 0)
42 path
.erase(0, first_non_slash
);
44 // URL contains a host: this means it's UNC. We keep the preceeding slash
48 path
.append(url
.path());
53 std::replace(path
.begin(), path
.end(), '/', '\\');
55 // GURL stores strings as percent-encoded UTF-8, this will undo if possible.
56 path
= UnescapeURLComponent(path
,
57 UnescapeRule::SPACES
| UnescapeRule::URL_SPECIAL_CHARS
);
59 if (!IsStringUTF8(path
)) {
60 // Not UTF-8, assume encoding is native codepage and we're done. We know we
61 // are giving the conversion function a nonempty string, and it may fail if
62 // the given string is not in the current encoding and give us an empty
63 // string back. We detect this and report failure.
64 file_path_str
= base::SysNativeMBToWide(path
);
65 return !file_path_str
.empty();
67 file_path_str
.assign(UTF8ToWide(path
));
69 // We used to try too hard and see if |path| made up entirely of
70 // the 1st 256 characters in the Unicode was a zero-extended UTF-16.
71 // If so, we converted it to 'Latin-1' and checked if the result was UTF-8.
72 // If the check passed, we converted the result to UTF-8.
73 // Otherwise, we treated the result as the native OS encoding.
74 // However, that led to http://crbug.com/4619 and http://crbug.com/14153
78 bool GetNetworkList(NetworkInterfaceList
* networks
) {
79 // GetAdaptersAddresses() may require IO operations.
80 base::ThreadRestrictions::AssertIOAllowed();
82 IP_ADAPTER_ADDRESSES info_temp
;
85 // First get number of networks.
86 ULONG result
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, &info_temp
, &len
);
87 if (result
!= ERROR_BUFFER_OVERFLOW
) {
88 // There are 0 networks.
92 scoped_array
<char> buf(new char[len
]);
93 IP_ADAPTER_ADDRESSES
*adapters
=
94 reinterpret_cast<IP_ADAPTER_ADDRESSES
*>(buf
.get());
95 result
= GetAdaptersAddresses(AF_UNSPEC
, 0, NULL
, adapters
, &len
);
96 if (result
!= NO_ERROR
) {
97 LOG(ERROR
) << "GetAdaptersAddresses failed: " << result
;
101 for (IP_ADAPTER_ADDRESSES
*adapter
= adapters
; adapter
!= NULL
;
102 adapter
= adapter
->Next
) {
103 // Ignore the loopback device.
104 if (adapter
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) {
108 IP_ADAPTER_UNICAST_ADDRESS
* address
;
109 for (address
= adapter
->FirstUnicastAddress
; address
!= NULL
;
110 address
= address
->Next
) {
111 int family
= address
->Address
.lpSockaddr
->sa_family
;
112 if (family
== AF_INET
|| family
== AF_INET6
) {
114 if (endpoint
.FromSockAddr(address
->Address
.lpSockaddr
,
115 address
->Address
.iSockaddrLength
)) {
116 std::string name
= adapter
->AdapterName
;
117 networks
->push_back(NetworkInterface(name
, endpoint
.address()));