Skip to content

Commit

Permalink
fix: azure parse xml response (#333)
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Gershman <[email protected]>
  • Loading branch information
romange authored Oct 31, 2024
1 parent f1e37ab commit 6e77555
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cmake/third_party.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ add_third_party(

add_third_party(
pugixml
URL https://github.com/zeux/pugixml/archive/refs/tags/v1.13.tar.gz
URL https://github.com/zeux/pugixml/archive/refs/tags/v1.14.tar.gz
)

if (WITH_AWS)
Expand Down
2 changes: 1 addition & 1 deletion examples/gcs_demo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ int main(int argc, char** argv) {
pp->GetNextProactor()->Await([&] {
error_code ec = provider.Init();
CHECK(!ec) << "Could not load credentials " << ec.message();
provider.List();
provider.ListContainers([](std::string_view item) { CONSOLE_INFO << item << endl; });
});
} else {
pp->GetNextProactor()->Await([ctx] { Run(ctx); });
Expand Down
2 changes: 1 addition & 1 deletion util/cloud/azure/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
add_library(azure_lib azure.cc)
cxx_link(azure_lib http_client_lib strings_lib)
cxx_link(azure_lib http_client_lib strings_lib TRDP::pugixml)
54 changes: 52 additions & 2 deletions util/cloud/azure/azure.cc
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// Copyright 2024, Roman Gershman. All rights reserved.
// See LICENSE for licensing terms.

#include <absl/cleanup/cleanup.h>
#include <absl/strings/escaping.h>
#include <absl/strings/str_cat.h>

#include <boost/beast/http/string_body.hpp>
#include <pugixml.hpp>

#include "base/logging.h"
#include "util/cloud/azure/creds_provider.h"
#include "util/cloud/utils.h"
Expand Down Expand Up @@ -31,6 +35,10 @@ error_code CredsProvider::Init() {
return {};
}

auto UnexpectedError(errc code) {
return nonstd::make_unexpected(make_error_code(code));
}

void HMAC(absl::string_view key, absl::string_view msg, uint8_t dest[32]) {
// HMAC_xxx are deprecated since openssl 3.0
// Ubuntu 20.04 uses openssl 1.1.
Expand Down Expand Up @@ -80,8 +88,38 @@ string Sign(string_view account, const boost::beast::http::header<true>& req_hea
return signature;
}

void CredsProvider::List() {
io::Result<vector<string>> ParseXmlListBuckets(string_view xml_resp) {
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_buffer(xml_resp.data(), xml_resp.size());

if (!result) {
LOG(ERROR) << "Could not parse xml response " << result.description();
return UnexpectedError(errc::bad_message);
}

pugi::xml_node root = doc.child("EnumerationResults");
if (root.type() != pugi::node_element) {
LOG(ERROR) << "Could not find root node " << xml_resp;
return UnexpectedError(errc::bad_message);
}

pugi::xml_node buckets = root.child("Containers");
if (buckets.type() != pugi::node_element) {
LOG(ERROR) << "Could not find buckets node " << xml_resp;
return UnexpectedError(errc::bad_message);
}

vector<string> res;
for (pugi::xml_node bucket = buckets.child("Container"); bucket; bucket = bucket.next_sibling()) {
res.push_back(bucket.child_value("Name"));
}
return res;
}

error_code CredsProvider::ListContainers(function<void(ContainerItem)> cb) {
SSL_CTX* ctx = util::http::TlsClient::CreateSslContext();
absl::Cleanup cleanup([ctx] { util::http::TlsClient::FreeContext(ctx); });

fb2::ProactorBase* pb = fb2::ProactorBase::me();
CHECK(pb);
string endpoint = account_name_ + ".blob.core.windows.net";
Expand Down Expand Up @@ -110,8 +148,20 @@ void CredsProvider::List() {
ec = client->get()->ReadHeader(&parser);
CHECK(!ec) << ec;
DVLOG(1) << "Response: " << parser.get().base();
h2::response_parser<h2::string_body> resp(std::move(parser));
client->get()->Recv(&resp);

auto msg = resp.release();
DVLOG(1) << "Body: " << msg.body();
auto res = ParseXmlListBuckets(msg.body());
if (!res) {
return res.error();
}

util::http::TlsClient::FreeContext(ctx);
for (const auto& b : *res) {
cb(b);
}
return {};
}

} // namespace cloud::azure
Expand Down
3 changes: 2 additions & 1 deletion util/cloud/azure/creds_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class CredsProvider {
const std::string& account_name() const { return account_name_; }
const std::string& account_key() const { return account_key_; }

void List();
using ContainerItem = std::string_view;
std::error_code ListContainers(std::function<void(ContainerItem)>);

private:
std::string account_name_;
Expand Down

0 comments on commit 6e77555

Please sign in to comment.