mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
net: use mut and refs as receivers consistently (#8205)
This commit is contained in:
@ -12,14 +12,14 @@ import time
|
||||
import io
|
||||
|
||||
const (
|
||||
recv_size = 128
|
||||
recv_size = 128
|
||||
)
|
||||
|
||||
enum ReplyCode {
|
||||
ready = 220
|
||||
close = 221
|
||||
auth_ok = 235
|
||||
action_ok = 250
|
||||
ready = 220
|
||||
close = 221
|
||||
auth_ok = 235
|
||||
action_ok = 250
|
||||
mail_start = 354
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ pub:
|
||||
password string
|
||||
from string
|
||||
pub mut:
|
||||
is_open bool
|
||||
is_open bool
|
||||
}
|
||||
|
||||
pub struct Mail {
|
||||
@ -54,15 +54,19 @@ pub struct Mail {
|
||||
}
|
||||
|
||||
// new_client returns a new SMTP client and connects to it
|
||||
pub fn new_client(config Client) ?Client {
|
||||
mut c := config
|
||||
c.reconnect()?
|
||||
pub fn new_client(config Client) ?&Client {
|
||||
mut c := &Client{
|
||||
...config
|
||||
}
|
||||
c.reconnect() ?
|
||||
return c
|
||||
}
|
||||
|
||||
// reconnect reconnects to the SMTP server if the connection was closed
|
||||
pub fn (mut c Client) reconnect() ? {
|
||||
if c.is_open { return error('Already connected to server') }
|
||||
if c.is_open {
|
||||
return error('Already connected to server')
|
||||
}
|
||||
|
||||
conn := net.dial_tcp('$c.server:$c.port') or { return error('Connecting to server failed') }
|
||||
c.conn = conn
|
||||
@ -76,29 +80,34 @@ pub fn (mut c Client) reconnect() ? {
|
||||
}
|
||||
|
||||
// send sends an email
|
||||
pub fn (c Client) send(config Mail) ? {
|
||||
if !c.is_open { return error('Disconnected from server') }
|
||||
pub fn (mut c Client) send(config Mail) ? {
|
||||
if !c.is_open {
|
||||
return error('Disconnected from server')
|
||||
}
|
||||
from := if config.from != '' { config.from } else { c.from }
|
||||
c.send_mailfrom(from) or { return error('Sending mailfrom failed') }
|
||||
c.send_mailto(config.to) or { return error('Sending mailto failed') }
|
||||
c.send_data() or { return error('Sending mail data failed') }
|
||||
c.send_body({ config | from: from }) or { return error('Sending mail body failed') }
|
||||
c.send_body({
|
||||
config |
|
||||
from: from
|
||||
}) or { return error('Sending mail body failed') }
|
||||
}
|
||||
|
||||
// quit closes the connection to the server
|
||||
pub fn (mut c Client) quit() ? {
|
||||
c.send_str('QUIT\r\n')
|
||||
c.expect_reply(.close)
|
||||
c.conn.close()?
|
||||
c.conn.close() ?
|
||||
c.is_open = false
|
||||
}
|
||||
|
||||
// expect_reply checks if the SMTP server replied with the expected reply code
|
||||
fn (c Client) expect_reply(expected ReplyCode) ? {
|
||||
bytes := io.read_all(reader: c.conn)?
|
||||
fn (mut c Client) expect_reply(expected ReplyCode) ? {
|
||||
bytes := io.read_all(reader: c.conn) ?
|
||||
|
||||
str := bytes.bytestr().trim_space()
|
||||
$if smtp_debug? {
|
||||
$if smtp_debug ? {
|
||||
eprintln('\n\n[RECV]')
|
||||
eprint(str)
|
||||
}
|
||||
@ -108,30 +117,32 @@ fn (c Client) expect_reply(expected ReplyCode) ? {
|
||||
if ReplyCode(status) != expected {
|
||||
return error('Received unexpected status code $status, expecting $expected')
|
||||
}
|
||||
} else { return error('Recieved unexpected SMTP data: $str') }
|
||||
} else {
|
||||
return error('Recieved unexpected SMTP data: $str')
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn (c Client) send_str(s string) ? {
|
||||
$if smtp_debug? {
|
||||
fn (mut c Client) send_str(s string) ? {
|
||||
$if smtp_debug ? {
|
||||
eprintln('\n\n[SEND START]')
|
||||
eprint(s.trim_space())
|
||||
eprintln('\n[SEND END]')
|
||||
}
|
||||
c.conn.write(s.bytes())?
|
||||
c.conn.write(s.bytes()) ?
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn (c Client) send_ehlo() ? {
|
||||
c.send_str('EHLO $c.server\r\n')?
|
||||
c.expect_reply(.action_ok)?
|
||||
fn (mut c Client) send_ehlo() ? {
|
||||
c.send_str('EHLO $c.server\r\n') ?
|
||||
c.expect_reply(.action_ok) ?
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn (c Client) send_auth() ? {
|
||||
fn (mut c Client) send_auth() ? {
|
||||
if c.username.len == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
mut sb := strings.new_builder(100)
|
||||
sb.write_b(0)
|
||||
sb.write(c.username)
|
||||
@ -139,26 +150,26 @@ fn (c Client) send_auth() ? {
|
||||
sb.write(c.password)
|
||||
a := sb.str()
|
||||
auth := 'AUTH PLAIN ${base64.encode(a)}\r\n'
|
||||
c.send_str(auth)?
|
||||
c.expect_reply(.auth_ok)?
|
||||
c.send_str(auth) ?
|
||||
c.expect_reply(.auth_ok) ?
|
||||
}
|
||||
|
||||
fn (c Client) send_mailfrom(from string) ? {
|
||||
c.send_str('MAIL FROM: <$from>\r\n')?
|
||||
c.expect_reply(.action_ok)?
|
||||
fn (mut c Client) send_mailfrom(from string) ? {
|
||||
c.send_str('MAIL FROM: <$from>\r\n') ?
|
||||
c.expect_reply(.action_ok) ?
|
||||
}
|
||||
|
||||
fn (c Client) send_mailto(to string) ? {
|
||||
c.send_str('RCPT TO: <$to>\r\n')?
|
||||
c.expect_reply(.action_ok)?
|
||||
fn (mut c Client) send_mailto(to string) ? {
|
||||
c.send_str('RCPT TO: <$to>\r\n') ?
|
||||
c.expect_reply(.action_ok) ?
|
||||
}
|
||||
|
||||
fn (c Client) send_data() ? {
|
||||
c.send_str('DATA\r\n')?
|
||||
fn (mut c Client) send_data() ? {
|
||||
c.send_str('DATA\r\n') ?
|
||||
c.expect_reply(.mail_start)
|
||||
}
|
||||
|
||||
fn (c Client) send_body(cfg Mail) ? {
|
||||
fn (mut c Client) send_body(cfg Mail) ? {
|
||||
is_html := cfg.body_type == .html
|
||||
date := cfg.date.utc_string().trim_right(' UTC') // TODO
|
||||
mut sb := strings.new_builder(200)
|
||||
@ -174,6 +185,6 @@ fn (c Client) send_body(cfg Mail) ? {
|
||||
sb.write('\r\n\r\n')
|
||||
sb.write(cfg.body)
|
||||
sb.write('\r\n.\r\n')
|
||||
c.send_str(sb.str())?
|
||||
c.expect_reply(.action_ok)?
|
||||
c.send_str(sb.str()) ?
|
||||
c.expect_reply(.action_ok) ?
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import smtp
|
||||
import time
|
||||
|
||||
// Used to test that a function call returns an error
|
||||
fn fn_errors(c smtp.Client, m smtp.Mail) bool {
|
||||
fn fn_errors(mut c smtp.Client, m smtp.Mail) bool {
|
||||
c.send(m) or { return true }
|
||||
return false
|
||||
}
|
||||
@ -14,7 +14,9 @@ fn fn_errors(c smtp.Client, m smtp.Mail) bool {
|
||||
* Created by: nedimf (07/2020)
|
||||
*/
|
||||
fn test_smtp() {
|
||||
$if !network ? { return }
|
||||
$if !network ? {
|
||||
return
|
||||
}
|
||||
|
||||
client_cfg := smtp.Client{
|
||||
server: 'smtp.mailtrap.io'
|
||||
@ -32,20 +34,57 @@ fn test_smtp() {
|
||||
body: 'Plain text'
|
||||
}
|
||||
|
||||
mut client := smtp.new_client(client_cfg) or { assert false return }
|
||||
mut client := smtp.new_client(client_cfg) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert true
|
||||
client.send(send_cfg) or { assert false return }
|
||||
client.send(send_cfg) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert true
|
||||
// client.send({ send_cfg | body_type: .html, body: '<html><h1>HTML V email!</h1></html>' }) or { assert false return }
|
||||
client.send({ send_cfg | from: 'alexander@vlang.io' }) or { assert false return }
|
||||
client.send({ send_cfg | cc: 'alexander@vlang.io,joe@vlang.io', bcc: 'spytheman@vlang.io' }) or { assert false return }
|
||||
client.send({ send_cfg | date: time.now().add_days(1000) }) or { assert false return }
|
||||
client.send({
|
||||
send_cfg |
|
||||
from: 'alexander@vlang.io'
|
||||
}) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
client.send({
|
||||
send_cfg |
|
||||
cc: 'alexander@vlang.io,joe@vlang.io'
|
||||
bcc: 'spytheman@vlang.io'
|
||||
}) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
client.send({
|
||||
send_cfg |
|
||||
date: time.now().add_days(1000)
|
||||
}) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert true
|
||||
client.quit() or { assert false return }
|
||||
client.quit() or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert true
|
||||
// This call should return an error, since the connection is closed
|
||||
if !fn_errors(client, send_cfg) { assert false return }
|
||||
client.reconnect() or { assert false return }
|
||||
client.send(send_cfg) or { assert false return }
|
||||
if !fn_errors(mut client, send_cfg) {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
client.reconnect() or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
client.send(send_cfg) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert true
|
||||
}
|
||||
|
Reference in New Issue
Block a user