Skip to content

Commit

Permalink
vlib: fix tcp_test.v
Browse files Browse the repository at this point in the history
Test that: the listen_tcp method should not accept
.unix af.; and it indeed fails when invoked like so.

Remove $windows specific code from tcp.c.v,
that on surface inspection seems to be invalid.

Fix server_test.v to use 127.0.0.1 when connecting
to the HTTP server, as Windows does not accept
a connection to 0.0.0.0 (it works on Linux/BSD.)
  • Loading branch information
hholst80 committed Jan 5, 2024
1 parent 7d29afe commit 3dd955e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 65 deletions.
21 changes: 12 additions & 9 deletions vlib/net/address.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,20 @@ pub fn resolve_addrs_fuzzy(addr string, @type SocketType) ![]Addr {

// resolve_ipaddrs converts the given `addr`, `family` and `typ` to a list of addresses
pub fn resolve_ipaddrs(addr string, family AddrFamily, typ SocketType) ![]Addr {
address, port := split_address(addr)!
mut address, port := split_address(addr)!

if addr[0] == `:` {
if address.starts_with('[') && address.ends_with(']') {
address = address[1..address.len - 1]
}

// This is to allow a ":8080" shorthand notation similar to HTTPie
// [URL shortcuts for localhost](https://httpie.io/docs/cli/url-shortcuts-for-localhost)
// and (net.Dial)(https://pkg.go.dev/net#Dial) in Go.
if address == '' {
match family {
.ip6 {
return [new_ip6(port, net.addr_ip6_any)]
}
.ip, .unspec {
return [new_ip(port, net.addr_ip_any)]
}
else {}
.ip6 { return [new_ip6(port, net.addr_ip6_any)] }
.ip, .unspec { return [new_ip(port, net.addr_ip_any)] }
.unix { error('unix address must not be empty') }
}
}

Expand Down
13 changes: 7 additions & 6 deletions vlib/net/http/server_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,21 @@ fn test_server_custom_handler() {
}
t := spawn server.listen_and_serve()
server.wait_till_running()!
x := http.fetch(url: 'http://${server.addr}/endpoint?abc=xyz', data: 'my data')!
x := http.fetch(url: 'http://127.0.0.1:${cport}/endpoint?abc=xyz', data: 'my data')!
assert x.body == 'my data, /endpoint?abc=xyz'
assert x.status_code == 200
assert x.status_msg == 'OK'
assert x.http_version == '1.1'
y := http.fetch(url: 'http://${server.addr}/another/endpoint', data: 'abcde')!
y := http.fetch(url: 'http://127.0.0.1:${cport}/another/endpoint', data: 'abcde')!
assert y.body == 'abcde, /another/endpoint'
assert y.status_code == 200
assert x.status_msg == 'OK'
assert y.status() == .ok
assert y.http_version == '1.1'
//
http.fetch(url: 'http://${server.addr}/something/else')!
http.fetch(url: 'http://127.0.0.1:${cport}/something/else')!
//
big_url := 'http://${server.addr}/redirect_to_big'
big_url := 'http://127.0.0.1:${cport}/redirect_to_big'
mut progress_calls := &ProgressCalls{}
z := http.fetch(
url: big_url
Expand Down Expand Up @@ -174,7 +174,7 @@ fn test_server_custom_handler() {
assert progress_calls.chunks[0].bytestr().starts_with('HTTP/1.1 301 Moved permanently')
assert progress_calls.chunks[1].bytestr().starts_with('HTTP/1.1 200 OK')
assert progress_calls.chunks.last().bytestr().contains('xyz def')
assert progress_calls.redirected_to == ['http://${server.addr}/big']
assert progress_calls.redirected_to == ['http://127.0.0.1:${cport}/big']
//
server.stop()
t.wait()
Expand Down Expand Up @@ -232,7 +232,8 @@ fn test_my_counting_handler_on_random_port() {
on_running: fn (mut server http.Server) {
spawn fn (mut server http.Server) {
log.warn('server started')
url := 'http://${server.addr}/count'
_, server_port := net.split_address(server.addr) or { panic(err) }
url := 'http://127.0.0.1:${server_port}/count'
log.info('fetching from url: ${url}')
for _ in 0 .. 5 {
x := http.fetch(url: url, data: 'my data') or { panic(err) }
Expand Down
9 changes: 0 additions & 9 deletions vlib/net/tcp.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@ mut:

pub fn dial_tcp(oaddress string) !&TcpConn {
mut address := oaddress
$if windows {
// resolving 0.0.0.0 to localhost, works on linux and macos, but not on windows, so try to emulate it:
if address.starts_with(':::') {
address = address.replace_once(':::', 'localhost:')
}
if address.starts_with('0.0.0.0:') {
address = address.replace_once('0.0.0.0:', 'localhost:')
}
}
addrs := resolve_addrs_fuzzy(address, .tcp) or {
return error('${err.msg()}; could not resolve address ${address} in dial_tcp')
}
Expand Down
86 changes: 45 additions & 41 deletions vlib/net/tcp_test.v
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
// vtest flaky: true
// vtest retry: 8
import net
import os

const test_port = 45123

fn handle_conn(mut c net.TcpConn) {
fn handle_conn(mut c net.TcpConn) ! {
for {
mut buf := []u8{len: 100, init: 0}
read := c.read(mut buf) or {
println('Server: connection dropped')
return
eprintln('Server: connection dropped')
return err
}
c.write(buf[..read]) or {
println('Server: connection dropped')
return
eprintln('Server: connection dropped')
return err
}
}
}
Expand All @@ -24,40 +21,46 @@ fn one_shot_echo_server(mut l net.TcpListener, ch_started chan int) ! {
ch_started <- 1
mut new_conn := l.accept() or { return error('could not accept') }
eprintln(' > new_conn: ${new_conn}')
handle_conn(mut new_conn)
new_conn.close() or {}
handle_conn(mut new_conn)!
new_conn.close()!
}

fn echo(address string) ! {
mut c := net.dial_tcp(address)!
defer {
c.close() or {}
}

println('local: ' + c.addr()!.str())
println(' peer: ' + c.peer_addr()!.str())
eprintln('local: ' + c.addr()!.str())
eprintln(' peer: ' + c.peer_addr()!.str())

data := 'Hello from vlib/net!'
c.write_string(data)!
mut buf := []u8{len: 4096}
read := c.read(mut buf) or { panic(err) }
read := c.read(mut buf)!
assert read == data.len
for i := 0; i < read; i++ {
assert buf[i] == data[i]
}
println('Got "${buf.bytestr()}"')
c.close()!
}

fn test_tcp_ip6() {
eprintln('\n>>> ${@FN}')
address := 'localhost:${test_port}'
mut l := net.listen_tcp(.ip6, ':${test_port}') or { panic(err) }
saddr := ':${test_port}'
addr := '[::1]:${test_port}'
mut l := net.listen_tcp(.ip6, saddr)!
dump(l)
start_echo_server(mut l)
echo(address) or { panic(err) }
l.close() or {}
// ensure there is at least one new socket created before the next test
l = net.listen_tcp(.ip6, ':${test_port + 1}') or { panic(err) }
echo(addr)!
l.close()!
}

fn test_tcp_ip6_localhost() {
eprintln('\n>>> ${@FN}')
address := '[::1]:${test_port}'
mut l := net.listen_tcp(.ip6, address)!
dump(l)
start_echo_server(mut l)
echo(address)!
l.close()!
}

fn start_echo_server(mut l net.TcpListener) {
Expand All @@ -68,31 +71,32 @@ fn start_echo_server(mut l net.TcpListener) {

fn test_tcp_ip() {
eprintln('\n>>> ${@FN}')
address := 'localhost:${test_port}'
mut l := net.listen_tcp(.ip, address) or { panic(err) }
saddr := ':${test_port}'
addr := '127.0.0.1:${test_port}'
mut l := net.listen_tcp(.ip, saddr)!
dump(l)
start_echo_server(mut l)
echo(address) or { panic(err) }
l.close() or {}
echo(addr)!
l.close()!
}

fn test_tcp_unix() {
fn test_tcp_ip_localhost() {
eprintln('\n>>> ${@FN}')
// TODO(emily):
// whilst windows supposedly supports unix sockets
// this doesnt work (wsaeopnotsupp at the call to bind())
$if !windows {
address := os.real_path('tcp-test.sock')
// address := 'tcp-test.sock'
println('${address}')
address := '127.0.0.1:${test_port}'
mut l := net.listen_tcp(.ip, address)!
dump(l)
start_echo_server(mut l)
echo(address)!
l.close()!
}

mut l := net.listen_tcp(.unix, address) or { panic(err) }
start_echo_server(mut l)
echo(address) or { panic(err) }
l.close() or {}
fn test_tcp_unix() {
eprintln('\n>>> ${@FN}')
address := 'tcp-test.sock'
eprintln('${address}')

os.rm(address) or { panic('failed to remove socket file') }
}
mut l := net.listen_tcp(.unix, address) or { return }
assert false
}

fn testsuite_end() {
Expand Down

0 comments on commit 3dd955e

Please sign in to comment.