| 247 | std::string IBackupContainer::lastOpenError; |
| 248 | |
| 249 | std::vector<std::string> IBackupContainer::getURLFormats() { |
| 250 | return { |
| 251 | #ifdef BUILD_AZURE_BACKUP |
| 252 | BackupContainerAzureBlobStore::getURLFormat(), |
| 253 | #endif |
| 254 | BackupContainerLocalDirectory::getURLFormat(), |
| 255 | BackupContainerS3BlobStore::getURLFormat(), |
| 256 | }; |
| 257 | } |
| 258 | |
| 259 | // Get an IBackupContainer based on a container URL string |
| 260 | Reference<IBackupContainer> IBackupContainer::openContainer(const std::string& url, |
| 261 | const Optional<std::string>& proxy, |
| 262 | const Optional<std::string>& encryptionKeyFileName) { |
| 263 | static std::map<std::string, Reference<IBackupContainer>> m_cache; |
| 264 | |
| 265 | Reference<IBackupContainer>& r = m_cache[url]; |
| 266 | if (r) |
| 267 | return r; |
| 268 | |
| 269 | try { |
| 270 | StringRef u(url); |
| 271 | if (u.startsWith("file://"_sr)) { |
| 272 | r = makeReference<BackupContainerLocalDirectory>(url, encryptionKeyFileName); |
| 273 | } else if (u.startsWith("blobstore://"_sr)) { |
| 274 | std::string resource; |
| 275 | |
| 276 | // The URL parameters contain blobstore endpoint tunables as well as possible backup-specific options. |
| 277 | S3BlobStoreEndpoint::ParametersT backupParams; |
| 278 | Reference<S3BlobStoreEndpoint> bstore = |
| 279 | S3BlobStoreEndpoint::fromString(url, proxy, &resource, &lastOpenError, &backupParams); |
| 280 | |
| 281 | if (resource.empty()) |
| 282 | throw backup_invalid_url(); |
| 283 | for (auto c : resource) |
| 284 | if (!isalnum(c) && c != '_' && c != '-' && c != '.' && c != '/') |
| 285 | throw backup_invalid_url(); |
| 286 | r = makeReference<BackupContainerS3BlobStore>(bstore, resource, backupParams, encryptionKeyFileName); |
| 287 | } |
| 288 | #ifdef BUILD_AZURE_BACKUP |
| 289 | else if (u.startsWith("azure://"_sr)) { |
| 290 | u.eat("azure://"_sr); |
| 291 | auto address = u.eat("/"_sr); |
| 292 | if (address.endsWith(std::string(azure::storage_lite::constants::default_endpoint_suffix))) { |
| 293 | CODE_PROBE(true, "Azure backup url with standard azure storage account endpoint"); |
| 294 | // <account>.<service>.core.windows.net/<resource_path> |
| 295 | auto endPoint = address.toString(); |
| 296 | auto accountName = address.eat("."_sr).toString(); |
| 297 | auto containerName = u.eat("/"_sr).toString(); |
| 298 | r = makeReference<BackupContainerAzureBlobStore>( |
| 299 | endPoint, accountName, containerName, encryptionKeyFileName); |
| 300 | } else { |
| 301 | // resolve the network address if necessary |
| 302 | std::string endpoint(address.toString()); |
| 303 | Optional<NetworkAddress> parsedAddress = NetworkAddress::parseOptional(endpoint); |
| 304 | if (!parsedAddress.present()) { |
| 305 | try { |
| 306 | auto hostname = Hostname::parse(endpoint); |
nothing calls this directly
no test coverage detected