Skip to content

Commit f4692c4

Browse files
committed
RSCBC-147: Add support for http(s):// in connection string
1 parent b8e4731 commit f4692c4

File tree

2 files changed

+107
-11
lines changed

2 files changed

+107
-11
lines changed

sdk/couchbase-connstr/src/lib.rs

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,26 +198,44 @@ pub async fn resolve(
198198
conn_spec: ConnSpec,
199199
dns_config: impl Into<Option<DnsConfig>>,
200200
) -> error::Result<ResolvedConnSpec> {
201-
let (default_port, has_explicit_scheme, use_ssl) = if let Some(scheme) = &conn_spec.scheme {
201+
if let Some(scheme) = &conn_spec.scheme {
202202
match scheme.as_str() {
203-
"couchbase" => (DEFAULT_MEMD_PORT, true, false),
204-
"couchbases" => (DEFAULT_SSL_MEMD_PORT, true, true),
203+
"couchbase" => {
204+
handle_couchbase_scheme(conn_spec, dns_config, DEFAULT_MEMD_PORT, true, false).await
205+
}
206+
"couchbases" => {
207+
handle_couchbase_scheme(conn_spec, dns_config, DEFAULT_SSL_MEMD_PORT, true, true)
208+
.await
209+
}
205210
"couchbase2" => {
206-
return handle_couchbase2_scheme(conn_spec);
211+
handle_couchbase2_scheme(conn_spec)
212+
}
213+
"http" => handle_http_scheme(conn_spec, DEFAULT_LEGACY_HTTP_PORT, true, false).await,
214+
"https" => handle_http_scheme(conn_spec, DEFAULT_LEGACY_HTTPS_PORT, true, true).await,
215+
"" => {
216+
handle_couchbase_scheme(conn_spec, dns_config, DEFAULT_MEMD_PORT, false, false)
217+
.await
207218
}
208-
"" => (DEFAULT_MEMD_PORT, false, false),
209219
_ => {
210-
return Err(ErrorKind::InvalidArgument {
220+
Err(ErrorKind::InvalidArgument {
211221
msg: "unrecognized scheme".to_string(),
212222
arg: "scheme".to_string(),
213223
}
214-
.into());
224+
.into())
215225
}
216226
}
217227
} else {
218-
(DEFAULT_MEMD_PORT, false, false)
219-
};
228+
handle_couchbase_scheme(conn_spec, dns_config, DEFAULT_MEMD_PORT, false, false).await
229+
}
230+
}
220231

232+
async fn handle_couchbase_scheme(
233+
conn_spec: ConnSpec,
234+
dns_config: impl Into<Option<DnsConfig>>,
235+
default_port: u16,
236+
has_explicit_scheme: bool,
237+
use_ssl: bool,
238+
) -> error::Result<ResolvedConnSpec> {
221239
if let Some(srv_record) = conn_spec.srv_record() {
222240
match lookup_srv(
223241
&srv_record.scheme,
@@ -358,6 +376,80 @@ fn handle_couchbase2_scheme(conn_spec: ConnSpec) -> error::Result<ResolvedConnSp
358376
})
359377
}
360378

379+
async fn handle_http_scheme(
380+
conn_spec: ConnSpec,
381+
default_port: u16,
382+
has_explicit_scheme: bool,
383+
use_ssl: bool,
384+
) -> error::Result<ResolvedConnSpec> {
385+
if conn_spec.hosts.is_empty() {
386+
let (memd_port, http_port) = if use_ssl {
387+
(DEFAULT_SSL_MEMD_PORT, DEFAULT_LEGACY_HTTPS_PORT)
388+
} else {
389+
(DEFAULT_MEMD_PORT, DEFAULT_LEGACY_HTTP_PORT)
390+
};
391+
392+
return Ok(ResolvedConnSpec {
393+
use_ssl,
394+
memd_hosts: vec![Address {
395+
host: "127.0.0.1".to_string(),
396+
port: memd_port,
397+
}],
398+
http_hosts: vec![Address {
399+
host: "127.0.0.1".to_string(),
400+
port: http_port,
401+
}],
402+
couchbase2_host: None,
403+
srv_record: None,
404+
options: conn_spec.options,
405+
});
406+
}
407+
408+
let mut memd_hosts = vec![];
409+
let mut http_hosts = vec![];
410+
for address in conn_spec.hosts {
411+
if let Some(port) = &address.port {
412+
if !has_explicit_scheme && address.port != Some(default_port) {
413+
return Err(ErrorKind::InvalidArgument {
414+
msg: "ambiguous port without scheme".to_string(),
415+
arg: "port".to_string(),
416+
}
417+
.into());
418+
}
419+
420+
http_hosts.push(Address {
421+
host: address.host,
422+
port: *port,
423+
});
424+
} else {
425+
let (memd_port, http_port) = if use_ssl {
426+
(DEFAULT_SSL_MEMD_PORT, DEFAULT_LEGACY_HTTPS_PORT)
427+
} else {
428+
(DEFAULT_MEMD_PORT, DEFAULT_LEGACY_HTTP_PORT)
429+
};
430+
431+
memd_hosts.push(Address {
432+
host: address.host.clone(),
433+
port: memd_port,
434+
});
435+
436+
http_hosts.push(Address {
437+
host: address.host,
438+
port: http_port,
439+
});
440+
}
441+
}
442+
443+
Ok(ResolvedConnSpec {
444+
use_ssl,
445+
memd_hosts,
446+
http_hosts,
447+
couchbase2_host: None,
448+
srv_record: None,
449+
options: conn_spec.options,
450+
})
451+
}
452+
361453
async fn lookup_srv(
362454
scheme: &str,
363455
proto: &str,

sdk/couchbase-core/tests/common/default_agent_options.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ pub async fn create_default_options(config: TestSetupConfig) -> AgentOptions {
2323
};
2424

2525
AgentOptions::new(
26-
SeedConfig::new().memd_addrs(config.memd_addrs.clone()),
26+
SeedConfig::new()
27+
.memd_addrs(config.memd_addrs.clone())
28+
.http_addrs(config.http_addrs.clone()),
2729
Authenticator::PasswordAuthenticator(PasswordAuthenticator {
2830
username: config.username.clone(),
2931
password: config.password.clone(),
@@ -48,7 +50,9 @@ pub async fn create_options_without_bucket(config: TestSetupConfig) -> AgentOpti
4850
};
4951

5052
AgentOptions::new(
51-
SeedConfig::new().memd_addrs(config.memd_addrs.clone()),
53+
SeedConfig::new()
54+
.memd_addrs(config.memd_addrs.clone())
55+
.http_addrs(config.http_addrs.clone()),
5256
Authenticator::PasswordAuthenticator(PasswordAuthenticator {
5357
username: config.username.clone(),
5458
password: config.password.clone(),

0 commit comments

Comments
 (0)