Skip to content

Commit

Permalink
smtp, feat: compatible with outlook.office365.com.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed Aug 11, 2022
1 parent 5dfe3d0 commit 3722974
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
2 changes: 2 additions & 0 deletions fibjs/include/Smtp.h
Expand Up @@ -16,6 +16,7 @@ class Smtp : public Smtp_base {
public:
Smtp()
: m_timeout(0)
, m_tls(false)
{
}

Expand All @@ -39,6 +40,7 @@ class Smtp : public Smtp_base {
public:
int32_t m_timeout;
obj_ptr<Stream_base> m_conn;
bool m_tls;
obj_ptr<BufferedStream_base> m_stmBuffered;
};

Expand Down
91 changes: 89 additions & 2 deletions fibjs/src/net/Smtp.cpp
Expand Up @@ -183,13 +183,17 @@ result_t Smtp::connect(exlib::string url, AsyncEvent* ac)
m_pThis->m_stmBuffered->set_EOL("\r\n");

m_stmBuffered = m_pThis->m_stmBuffered;
m_pThis->m_tls = true;

return next();
}

virtual int32_t recv_ok()
{
if (m_u->m_protocol == "ssl:")
if (m_u->m_protocol == "ssl:") {
m_pThis->m_tls = true;
return next();
}

return next(m_tls ? ssl_handshake : starttls);
}
Expand Down Expand Up @@ -243,7 +247,90 @@ result_t Smtp::command(exlib::string cmd, exlib::string arg, AsyncEvent* ac)

result_t Smtp::hello(exlib::string hostname, AsyncEvent* ac)
{
return command("HELO", hostname, ac);
class asyncHello : public asyncSmtp {
public:
asyncHello(Smtp* pThis, exlib::string hostname, AsyncEvent* ac)
: asyncSmtp(pThis, ac)
, m_hostname(hostname)
, step(0)
{
next(hello);
}

public:
ON_STATE(asyncHello, hello)
{
exlib::string s("HELO ", 5);

s.append(m_hostname);
s.append("\r\n", 2);

m_buf = new Buffer(s);
return m_stmBuffered->write(m_buf, next(ok));
}

ON_STATE(asyncHello, starttls)
{
m_buf = new Buffer("STARTTLS\r\n");
return m_stmBuffered->write(m_buf, next(ok));
}

ON_STATE(asyncHello, ssl_handshake)
{
obj_ptr<SslSocket> ss = new SslSocket();
obj_ptr<Stream_base> conn = m_pThis->m_conn;
m_pThis->m_conn = ss;

if (g_ssl.m_crt && g_ssl.m_key) {
result_t hr = ss->setCert("", g_ssl.m_crt, g_ssl.m_key);
if (hr < 0)
return hr;
}

return ss->connect(conn, "", m_temp, next(ssl_connected));
}

ON_STATE(asyncHello, ssl_connected)
{
m_pThis->m_stmBuffered = new BufferedStream(m_pThis->m_conn);
m_pThis->m_stmBuffered->set_EOL("\r\n");

m_stmBuffered = m_pThis->m_stmBuffered;
m_pThis->m_tls = true;

step = 0;
return next(hello);
}

virtual int32_t recv_ok()
{
switch (step) {
case 0:
if (m_pThis->m_tls)
break;
step++;
return next(starttls);
case 1:
step++;
return next(ssl_handshake);
}
return next();
}

private:
exlib::string m_hostname;
obj_ptr<Buffer> m_buf;
int32_t step;
int32_t m_temp;
};

if (!m_conn)
return CHECK_ERROR(CALL_E_INVALID_CALL);

if (ac->isSync())
return CHECK_ERROR(CALL_E_NOSYNC);

return (new asyncHello(this, hostname, ac))->post(0);
}

result_t Smtp::login(exlib::string username, exlib::string password,
Expand Down

0 comments on commit 3722974

Please sign in to comment.