Skip to content

Commit a19cbcf

Browse files
committed
Customized HTTP useragent support:
- users can set their own userAgent in overlaybd.json - the default value of UA is overlaybd/${version_no}-${commitID} Signed-off-by: Yifan Yuan <tuji.yyf@alibaba-inc.com>
1 parent 94933f9 commit a19cbcf

File tree

11 files changed

+86
-14
lines changed

11 files changed

+86
-14
lines changed

CMake/Findphoton.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set(PHOTON_ENABLE_EXTFS ON)
55
FetchContent_Declare(
66
photon
77
GIT_REPOSITORY https://github.com/alibaba/PhotonLibOS.git
8-
GIT_TAG v0.6.16
8+
GIT_TAG v0.6.17
99
)
1010

1111
if(BUILD_TESTING)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ Default configure file `overlaybd.json` is installed to `/etc/overlaybd/`.
209209
| prefetchConfig.concurrency | Prefetch concurrency for reloading trace, `16` is default |
210210
| certConfig.certFile | The path for SSL/TLS client certificate file |
211211
| certConfig.keyFile | The path for SSL/TLS client key file |
212+
| userAgent | customized userAgent to identify HTTP request. default value is package version like 'overlaybd/1.1.14-6c449832' |
213+
212214

213215
> NOTE: `download` is the config for background downloading. After an overlaybd device is lauched, a background task will be running to fetch the whole blobs into local directories. After downloading, I/O requests are directed to local files. Unlike other options, download config is reloaded when a device launching.
214216

src/config.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@
1717

1818
#include <string>
1919
#include <vector>
20+
#include "version.h"
2021
#include "overlaybd/config_util.h"
2122

22-
#define MACROTOSTR(x) #x
23-
#define PRINTMACRO(x) MACROTOSTR(x)
24-
static const char OVERLAYBD_VERSION[] = PRINTMACRO(OVERLAYBD_VER);
25-
2623
namespace ImageConfigNS {
2724
const int MAX_LAYER_CNT = 256;
2825

@@ -157,6 +154,7 @@ struct GlobalConfig : public ConfigUtils::Config {
157154
APPCFG_PARA(logConfig, LogConfig);
158155
APPCFG_PARA(prefetchConfig, PrefetchConfig);
159156
APPCFG_PARA(certConfig, CertConfig);
157+
APPCFG_PARA(userAgent, std::string, OVERLAYBD_VERSION);
160158
};
161159

162160
struct AuthConfig : public ConfigUtils::Config {

src/example_config/overlaybd.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@
3535
"updateInterval": 60000000
3636
},
3737
"enableAudit": true,
38-
"auditPath": "/var/log/overlaybd-audit.log"
38+
"auditPath": "/var/log/overlaybd-audit.log",
39+
"registryFsVersion": "v2"
3940
}

src/image_service.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ int ImageService::init() {
349349

350350
global_fs.underlay_registryfs = registryfs_creator(
351351
{this, &ImageService::reload_auth}, cafile, 30UL * 1000000,
352-
global_conf.certConfig().certFile().c_str(), global_conf.certConfig().keyFile().c_str());
352+
global_conf.certConfig().certFile().c_str(), global_conf.certConfig().keyFile().c_str(), global_conf.userAgent().c_str());
353353
if (global_fs.underlay_registryfs == nullptr) {
354354
LOG_ERROR_RETURN(0, -1, "create registryfs failed.");
355355
}

src/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
#include "version.h"
1617
#include "image_file.h"
1718
#include "image_service.h"
1819
#include <photon/common/alog.h>

src/overlaybd/registryfs/registryfs.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,12 @@ inline IFile *RegistryFSImpl::open(const char *pathname, int) {
528528
}
529529

530530
IFileSystem *new_registryfs_v1(PasswordCB callback, const char *caFile, uint64_t timeout,
531-
const char *cert_file, const char *key_file) {
531+
const char *cert_file, const char *key_file, const char *__) {
532532
if (!callback)
533533
LOG_ERROR_RETURN(EINVAL, nullptr, "password callback not set");
534+
if (__ != nullptr) {
535+
LOG_WARN("customized UA is unsupported");
536+
}
534537
return new RegistryFSImpl(callback, caFile ? caFile : "", timeout,
535538
cert_file ? cert_file : "", key_file ? key_file : "");
536539
}

src/overlaybd/registryfs/registryfs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ photon::fs::IFileSystem *new_registryfs_v1(PasswordCB callback,
3232
const char *caFile = nullptr,
3333
uint64_t timeout = -1,
3434
const char *cert_file = nullptr,
35-
const char *key_file = nullptr);
35+
const char *key_file = nullptr,
36+
const char *__ = nullptr);
3637

3738
photon::fs::IFileSystem *new_registryfs_v2(PasswordCB callback,
3839
const char *caFile = nullptr,
3940
uint64_t timeout = -1,
4041
const char *cert_file = nullptr,
41-
const char *key_file = nullptr);
42+
const char *key_file = nullptr,
43+
const char *customized_ua = nullptr);
4244

4345
photon::fs::IFile* new_registry_uploader(photon::fs::IFile *lfile,
4446
std::string &upload_url,

src/overlaybd/registryfs/registryfs_v2.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
#include "../../version.h"
1617
#include "registryfs.h"
1718

19+
1820
#include <sys/stat.h>
1921
#include <sys/types.h>
2022
#include <unistd.h>
@@ -124,12 +126,17 @@ class RegistryFSImpl_v2 : public RegistryFS {
124126
}
125127

126128
RegistryFSImpl_v2(PasswordCB callback, const char *caFile, uint64_t timeout,
127-
photon::net::TLSContext *ctx)
129+
photon::net::TLSContext *ctx, const char *ua)
128130
: m_callback(callback), m_caFile(caFile), m_timeout(timeout), m_tls_ctx(ctx),
129131
m_meta_size(kMinimalMetaLife), m_scope_token(kMinimalTokenLife),
130132
m_url_info(kMinimalAUrlLife) {
131133

132134
m_client = nullptr;
135+
if (ua == nullptr) {
136+
m_useragent = OVERLAYBD_VERSION;
137+
} else {
138+
m_useragent = ua;
139+
}
133140
this->refresh_client();
134141
}
135142

@@ -286,6 +293,8 @@ class RegistryFSImpl_v2 : public RegistryFS {
286293
delete m_client;
287294
}
288295
m_client = new_http_client(nullptr, m_tls_ctx);
296+
LOG_INFO("set user agent: `", m_useragent);
297+
m_client->set_user_agent(m_useragent);
289298
}
290299

291300
int refresh_token(const estring &url, estring &token) {
@@ -309,6 +318,7 @@ class RegistryFSImpl_v2 : public RegistryFS {
309318
PasswordCB m_callback;
310319
estring m_accelerate;
311320
estring m_caFile;
321+
estring m_useragent;
312322
uint64_t m_timeout;
313323
photon::net::TLSContext *m_tls_ctx;
314324
photon::net::http::Client *m_client;
@@ -523,14 +533,14 @@ inline IFile *RegistryFSImpl_v2::open(const char *pathname, int) {
523533
}
524534

525535
IFileSystem *new_registryfs_v2(PasswordCB callback, const char *caFile, uint64_t timeout,
526-
const char *cert_file, const char *key_file) {
536+
const char *cert_file, const char *key_file, const char *customized_ua) {
527537
if (!callback)
528538
LOG_ERROR_RETURN(EINVAL, nullptr, "password callback not set");
529539
auto ctx = new_tls_context_from_file(cert_file, key_file);
530540
if (!ctx) {
531541
LOG_ERRNO_RETURN(0, nullptr, "failed to new tls context");
532542
}
533-
return new RegistryFSImpl_v2(callback, caFile ? caFile : "", timeout, ctx);
543+
return new RegistryFSImpl_v2(callback, caFile ? caFile : "", timeout, ctx, customized_ua);
534544
}
535545

536546
class RegistryUploader : public VirtualFile {
@@ -727,7 +737,7 @@ class RegistryUploader : public VirtualFile {
727737
photon::init(photon::INIT_EVENT_DEFAULT, photon::INIT_IO_NONE);
728738
DEFER(photon::fini());
729739
m_upload_fs = new RegistryFSImpl_v2({this, &RegistryUploader::load_auth},
730-
"", m_timeout, m_tls_ctx);
740+
"", m_timeout, m_tls_ctx, nullptr);
731741
DEFER({ delete m_upload_fs; });
732742
m_http_client_ts = photon::now;
733743
::posix_memalign(&m_upload_buf, 4096, 1024 * 1024);

src/test/image_service_test.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@
2424
#include "photon/net/socket.h"
2525
#include "photon/io/fd-events.h"
2626
#include "photon/net/curl.h"
27+
#include "../version.h"
28+
#include <photon/net/http/client.h>
29+
2730

2831
#include <fcntl.h>
2932

3033
#include "../image_service.cpp"
3134

35+
char *test_ua = nullptr;
36+
3237
photon::net::ISocketServer *new_server(std::string ip, uint16_t port) {
3338
auto server = photon::net::new_tcp_socket_server();
3439
server->timeout(1000UL*1000);
@@ -112,6 +117,51 @@ TEST(ImageTest, enableMetrics) {
112117
delete is;
113118
}
114119

120+
121+
int ua_check_handler(void*, photon::net::http::Request &req, photon::net::http::Response &resp, std::string_view) {
122+
auto ua = req.headers["User-Agent"];
123+
LOG_DEBUG(VALUE(ua));
124+
EXPECT_EQ(ua, test_ua);
125+
resp.set_result(200);
126+
LOG_INFO("expected UA: `", test_ua);
127+
std::string str = "success";
128+
resp.headers.content_length(7);
129+
resp.write((void*)str.data(), str.size());
130+
return 0;
131+
}
132+
133+
134+
TEST(http_client, user_agent) {
135+
auto tcpserver = photon::net::new_tcp_socket_server();
136+
DEFER(delete tcpserver);
137+
tcpserver->bind(18731);
138+
tcpserver->listen();
139+
auto server = photon::net::http::new_http_server();
140+
DEFER(delete server);
141+
server->add_handler({nullptr, &ua_check_handler});
142+
tcpserver->set_handler(server->get_connection_handler());
143+
tcpserver->start_loop();
144+
145+
test_ua = "mytestUA";
146+
147+
std::string target_get = "http://localhost:18731/file";
148+
auto client = photon::net::http::new_http_client();
149+
client->set_user_agent(test_ua);
150+
DEFER(delete client);
151+
auto op = client->new_operation(photon::net::http::Verb::GET, target_get);
152+
DEFER(delete op);
153+
op->req.headers.content_length(0);
154+
client->call(op);
155+
EXPECT_EQ(op->status_code, 200);
156+
std::string buf;
157+
buf.resize(op->resp.headers.content_length());
158+
op->resp.read((void*)buf.data(), op->resp.headers.content_length());
159+
LOG_DEBUG(VALUE(buf));
160+
EXPECT_EQ(true, buf == "success");
161+
}
162+
163+
164+
115165
int main(int argc, char** argv) {
116166
photon::init(photon::INIT_EVENT_DEFAULT, photon::INIT_IO_DEFAULT);
117167
DEFER(photon::fini(););

0 commit comments

Comments
 (0)