22 #include <openssl/ssl.h> 27 #include <sys/socket.h> 28 #include <netinet/in.h> 29 #include <arpa/inet.h> 37 static string format_error() {
40 len = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
41 nullptr, WSAGetLastError(), 0, (LPTSTR)&buffer, 0,
nullptr);
43 return string(
"Unknown error message");
46 const char *text = (
const char *)buffer;
47 while (len > 0 && isspace(text[len - 1])) {
51 string result(text, len);
56 #define format_error() strerror(errno) 65 BioPtr(
const URLSpec &url) : _connecting(false) {
73 if (!filename.empty()) {
74 if (filename[0] ==
'/' || filename[0] ==
'\\') {
86 _bio = BIO_new_file(filename.c_str(),
"rb");
96 struct addrinfo hints, *res =
nullptr;
97 memset(&hints, 0,
sizeof(hints));
98 hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
99 hints.ai_family = support_ipv6 ? AF_UNSPEC : AF_INET;
100 hints.ai_socktype = SOCK_STREAM;
103 int result = getaddrinfo(_server_name.c_str(),
nullptr, &hints, &res);
107 if (result == EAI_SYSTEM && errno != 0) {
108 errmsg = strerror(errno);
112 errmsg = gai_strerror(result);
114 downloader_cat.error()
115 <<
"Failed to resolve " << url.
get_server() <<
": " << errmsg <<
"\n";
118 nassertv(res !=
nullptr && res->ai_addr !=
nullptr);
124 DWORD bufsize =
sizeof(buf);
125 WSAAddressToStringA(res->ai_addr, res->ai_addrlen,
nullptr, buf, &bufsize);
127 if (res->ai_addr->sa_family == AF_INET) {
128 inet_ntop(AF_INET, (
char *)&((sockaddr_in *)res->ai_addr)->sin_addr, buf,
sizeof(buf));
130 }
else if (res->ai_addr->sa_family == AF_INET6) {
131 inet_ntop(AF_INET6, (
char *)&((sockaddr_in6 *)res->ai_addr)->sin6_addr, buf,
sizeof(buf));
138 if (downloader_cat.is_debug()) {
139 downloader_cat.debug()
140 <<
"Resolved " << url.
get_server() <<
" to " << buf <<
"\n";
144 int fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP);
146 downloader_cat.error()
147 <<
"Failed to create socket: " << format_error() <<
"\n";
154 nassertv(res->ai_addrlen <=
sizeof(_addr));
155 memcpy(&_addr, res->ai_addr, res->ai_addrlen);
156 _addrlen = res->ai_addrlen;
160 if (_addr.ss_family == AF_INET) {
161 ((sockaddr_in &)_addr).sin_port = htons(_port);
162 }
else if (_addr.ss_family == AF_INET6) {
163 ((sockaddr_in6 &)_addr).sin6_port = htons(_port);
166 _bio = BIO_new_socket(fd, 1);
174 set_nbio(
bool nbio) {
175 if (_bio ==
nullptr) {
180 BIO_get_fd(_bio, &fd);
181 nassertv_always(fd >= 0);
183 BIO_socket_nbio(fd, nbio);
191 if (_bio ==
nullptr) {
196 BIO_get_fd(_bio, &fd);
197 nassertr(fd >= 0,
false);
201 result = BIO_sock_error(fd);
203 result = ::connect(fd, (sockaddr *)&_addr, _addrlen);
205 if (result != 0 && BIO_sock_should_retry(-1)) {
208 BIO_set_flags(_bio, BIO_FLAGS_SHOULD_RETRY);
213 BIO_clear_retry_flags(_bio);
217 downloader_cat.warning()
218 <<
"Failed to connect to " << _server_name <<
" port " << _port
219 <<
": " << format_error() <<
"\n";
230 should_retry()
const {
231 return (_bio !=
nullptr) && BIO_should_retry(_bio);
239 if (_bio !=
nullptr) {
240 if (downloader_cat.is_debug() && !_server_name.empty()) {
241 downloader_cat.debug()
242 <<
"Dropping connection to " << _server_name <<
" port " << _port <<
"\n";
250 #endif // HAVE_OPENSSL A container for a URL, e.g.
static std::string unquote(const std::string &source)
Reverses the operation of quote(): converts escaped characters of the form "%xx" to their ascii equiv...
get_scheme
Returns the scheme specified by the URL, or empty string if no scheme is specified.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
std::string get_fullpath() const
Returns the entire filename: directory, basename, extension.
get_path
Returns the path specified by the URL, or "/" if no path is specified.
bool is_local() const
Returns true if the filename is local, e.g.
get_port
Returns the port number specified by the URL, or the default port if not specified.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_server
Returns the server name specified by the URL, if any.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...