ホームページ  >  記事  >  バックエンド開発  >  PHP は統合メールボックス ログインのプロキシ実装を前進させます (swoole)

PHP は統合メールボックス ログインのプロキシ実装を前進させます (swoole)

WBOY
WBOYオリジナル
2016-06-13 12:27:42988ブラウズ

PHP 进行统一邮箱登陆的代理实现(swoole)

  在工作的过程中,经常会有很多应用有发邮件的需求,这个时候需要在每个应用中配置smtp服务器。一旦公司调整了smtp服务器的配置,比如修改了密码等,这个时候对于维护的人员来说要逐一修改应用中smtp的配置。这样的情况虽然不多见,但遇上了还是很头痛的一件事情。

 

  知道了问题,解决起来就有了方向。于是就有了自己开发一个简单的smtp代理的想法,这个代理主要的功能(参照问题)主要是:

    1.接受指定IP应用的smtp请求;

    2.应用不需要知道smtp的用户和密码;

    3.转发应用的smtp请求。

 

  开发的环境:Linux,php(swoole);

  代码如下:

16f086cec199e61e2d963c5ca764f997server = <span style="color: #0000ff;">new</span> swoole_server(<span style="color: #800080;">$host</span>,<span style="color: #800080;">$port</span>,self::<span style="color: #800080;">$server_mode</span>,<span style="color: #800080;">$flag</span><span style="color: #000000;">);        </span><span style="color: #800080;">$this</span>->host = <span style="color: #800080;">$host</span><span style="color: #000000;">;        </span><span style="color: #800080;">$this</span>->port = <span style="color: #800080;">$port</span><span style="color: #000000;">;        </span><span style="color: #800080;">$this</span>->setting = <span style="color: #0000ff;">array</span><span style="color: #000000;">(                </span>'backlog' => 128,                'dispatch_mode' => 2,<span style="color: #000000;">        );    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> daemonize(){        </span><span style="color: #800080;">$this</span>->setting['daemonize'] = 1<span style="color: #000000;">;    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getConnectionInfo(<span style="color: #800080;">$fd</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server->connection_info(<span style="color: #800080;">$fd</span><span style="color: #000000;">);    }        </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 启动服务进程     * @param array $setting     * @throws Exception     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> run(<span style="color: #800080;">$setting</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">()){        </span><span style="color: #800080;">$this</span>->setting = <span style="color: #008080;">array_merge</span>(<span style="color: #800080;">$this</span>->setting,<span style="color: #800080;">$setting</span><span style="color: #000000;">);        </span><span style="color: #008000;">//</span><span style="color: #008000;">不使用swoole的默认日志</span>        <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['log_file'<span style="color: #000000;">])){            self</span>::<span style="color: #800080;">$log_file</span> = <span style="color: #800080;">$this</span>->setting['log_file'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['log_file'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['max_connection'<span style="color: #000000;">])){            </span><span style="color: #800080;">$this</span>->max_connection = <span style="color: #800080;">$this</span>->setting['max_connection'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['max_connection'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_host'<span style="color: #000000;">])){            </span><span style="color: #800080;">$this</span>->smtp_host = <span style="color: #800080;">$this</span>->setting['smtp_host'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_host'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_port'<span style="color: #000000;">])){            </span><span style="color: #800080;">$this</span>->smtp_port = <span style="color: #800080;">$this</span>->setting['smtp_port'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_port'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_user'<span style="color: #000000;">])){            </span><span style="color: #800080;">$this</span>->smtp_user = <span style="color: #800080;">$this</span>->setting['smtp_user'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_user'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_pass'<span style="color: #000000;">])){            </span><span style="color: #800080;">$this</span>->smtp_pass = <span style="color: #800080;">$this</span>->setting['smtp_pass'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_pass'<span style="color: #000000;">]);        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_from'<span style="color: #000000;">])){            </span><span style="color: #800080;">$this</span>->smtp_from = <span style="color: #800080;">$this</span>->setting['smtp_from'<span style="color: #000000;">];            </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_from'<span style="color: #000000;">]);        }            </span><span style="color: #800080;">$this</span>->server->set(<span style="color: #800080;">$this</span>-><span style="color: #000000;">setting);        </span><span style="color: #800080;">$version</span> = <span style="color: #008080;">explode</span>('.',<span style="color: #000000;"> SWOOLE_VERSION);        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$version</span>[0] == 1 && <span style="color: #800080;">$version</span>[1] 1e7c438afd183dbf6e975c8350587f3dserver->on('start',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onMasterStart'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('shutdown',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onMasterStop'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('ManagerStart',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onManagerStart'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('ManagerStop',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onManagerStop'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('WorkerStart',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onWorkerStart'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('WorkerStop',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onWorkerStop'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('WorkerError',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onWorkerError'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('Connect',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onConnect'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('Receive',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onReceive'<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>->server->on('Close',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onClose'<span style="color: #000000;">));                    </span><span style="color: #800080;">$this</span>->server-><span style="color: #000000;">start();    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">log</span>(<span style="color: #800080;">$msg</span>,<span style="color: #800080;">$level</span> = 'debug',<span style="color: #800080;">$flush</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(DEBUG_ON){            </span><span style="color: #800080;">$log</span> = <span style="color: #008080;">date</span>('Y-m-d H:i:s').' ['.<span style="color: #800080;">$level</span>."]\t" .<span style="color: #800080;">$msg</span>."\n"<span style="color: #000000;">;            </span><span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(self::<span style="color: #800080;">$log_file</span><span style="color: #000000;">)){                </span><span style="color: #800080;">$debug_file</span> = <span style="color: #008080;">dirname</span>(self::<span style="color: #800080;">$log_file</span>).'/debug.log'<span style="color: #000000;">;                </span><span style="color: #008080;">file_put_contents</span>(<span style="color: #800080;">$debug_file</span>, <span style="color: #800080;">$log</span>,<span style="color: #000000;">FILE_APPEND);                </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">filesize</span>(<span style="color: #800080;">$debug_file</span>) > 10485760){<span style="color: #008000;">//</span><span style="color: #008000;">10M</span>                    <span style="color: #008080;">unlink</span>(<span style="color: #800080;">$debug_file</span><span style="color: #000000;">);                }            }            </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$log</span><span style="color: #000000;">;        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$level</span> != 'debug'<span style="color: #000000;">){            </span><span style="color: #008000;">//</span><span style="color: #008000;">日志记录</span>            <span style="color: #800080;">$this</span>->queue[] = <span style="color: #008080;">date</span>('Y-m-d H:i:s')."\t[".<span style="color: #800080;">$level</span>."]\t".<span style="color: #800080;">$msg</span><span style="color: #000000;">;        }        </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">count</span>(<span style="color: #800080;">$this</span>->queue)>10 && !<span style="color: #0000ff;">empty</span>(self::<span style="color: #800080;">$log_file</span>) || <span style="color: #800080;">$flush</span><span style="color: #000000;">){            </span><span style="color: #0000ff;">if</span> (<span style="color: #008080;">filesize</span>(self::<span style="color: #800080;">$log_file</span>) > 209715200){ <span style="color: #008000;">//</span><span style="color: #008000;">200M</span>                <span style="color: #008080;">rename</span>(self::<span style="color: #800080;">$log_file</span>,self::<span style="color: #800080;">$log_file</span>.'.'.<span style="color: #008080;">date</span>('His'<span style="color: #000000;">));            }            </span><span style="color: #800080;">$logs</span> = ''<span style="color: #000000;">;            </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>->queue <span style="color: #0000ff;">as</span> <span style="color: #800080;">$q</span><span style="color: #000000;">){                </span><span style="color: #800080;">$logs</span> .= <span style="color: #800080;">$q</span>."\n"<span style="color: #000000;">;            }            </span><span style="color: #008080;">file_put_contents</span>(self::<span style="color: #800080;">$log_file</span>, <span style="color: #800080;">$logs</span>,<span style="color: #000000;">FILE_APPEND);            </span><span style="color: #800080;">$this</span>->queue = <span style="color: #0000ff;">array</span><span style="color: #000000;">();        }    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> shutdown(){        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server-><span style="color: #000000;">shutdown();    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> close(<span style="color: #800080;">$fd</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> send(<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$data</span><span style="color: #000000;">){        </span><span style="color: #800080;">$data</span> = <span style="color: #008080;">strtr</span>(<span style="color: #800080;">$data</span>,<span style="color: #0000ff;">array</span>("\n" => "", "\0" => "", "\r" => ""<span style="color: #000000;">));        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> C]\t" . <span style="color: #800080;">$data</span><span style="color: #000000;">);        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server->send(<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$data</span>.self::<span style="color: #000000;">EOF);    }            </span><span style="color: #008000;">/*</span><span style="color: #008000;">+++++++++++++++++++++++++++++++++++++++++++++++++++++++++     + 事件回调    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++</span><span style="color: #008000;">*/</span>        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onMasterStart(<span style="color: #800080;">$serv</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">;        swoole_set_process_name(</span>'php '.<span style="color: #800080;">$argv</span>[0].': master -host='.<span style="color: #800080;">$this</span>->host.' -port='.<span style="color: #800080;">$this</span>-><span style="color: #000000;">port);        </span><span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->setting['pid_file'<span style="color: #000000;">])){            </span><span style="color: #008080;">file_put_contents</span>(self::<span style="color: #800080;">$pid_file</span>, <span style="color: #800080;">$serv</span>-><span style="color: #000000;">master_pid);        }        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Master started.'<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onMasterStop(<span style="color: #800080;">$serv</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->setting['pid_file'<span style="color: #000000;">])){            </span><span style="color: #008080;">unlink</span>(self::<span style="color: #800080;">$pid_file</span><span style="color: #000000;">);        }        </span><span style="color: #800080;">$this</span>->shm-><span style="color: #000000;">delete();        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Master stop.'<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onManagerStart(<span style="color: #800080;">$serv</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">;        swoole_set_process_name(</span>'php '.<span style="color: #800080;">$argv</span>[0].': manager'<span style="color: #000000;">);        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Manager started.'<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onManagerStop(<span style="color: #800080;">$serv</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Manager stop.'<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onWorkerStart(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$worker_id</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">;        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$worker_id</span> >= <span style="color: #800080;">$serv</span>->setting['worker_num'<span style="color: #000000;">]) {            swoole_set_process_name(</span>"php {<span style="color: #800080;">$argv</span>[0]}: worker [task]"<span style="color: #000000;">);        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {            swoole_set_process_name(</span>"php {<span style="color: #800080;">$argv</span>[0]}: worker [{<span style="color: #800080;">$worker_id</span>}]"<span style="color: #000000;">);        }        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("Worker {<span style="color: #800080;">$worker_id</span>} started."<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onWorkerStop(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$worker_id</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("Worker {<span style="color: #800080;">$worker_id</span>} stop."<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onWorkerError(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$worker_id</span>,<span style="color: #800080;">$worker_pid</span>,<span style="color: #800080;">$exit_code</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("Worker {<span style="color: #800080;">$worker_id</span>} error:{<span style="color: #800080;">$exit_code</span>}."<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onConnect(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$from_id</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">count</span>(<span style="color: #800080;">$this</span>->server->connections) 47a89b7a2c122dfa8d80fd30a58109ec<span style="color: #000000;">max_connection){            </span><span style="color: #800080;">$info</span> = <span style="color: #800080;">$this</span>->getConnectionInfo(<span style="color: #800080;">$fd</span><span style="color: #000000;">);            </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->isIpAllow(<span style="color: #800080;">$info</span>['remote_ip'<span style="color: #000000;">])){                </span><span style="color: #008000;">//</span><span style="color: #008000;">建立服务器连接</span>                <span style="color: #800080;">$cli</span> = <span style="color: #0000ff;">new</span> Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); <span style="color: #008000;">//</span><span style="color: #008000;">异步非阻塞</span>                <span style="color: #800080;">$cli</span>->on('connect',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerConnect'<span style="color: #000000;">));                </span><span style="color: #800080;">$cli</span>->on('receive',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerReceive'<span style="color: #000000;">));                </span><span style="color: #800080;">$cli</span>->on('error',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerError'<span style="color: #000000;">));                </span><span style="color: #800080;">$cli</span>->on('close',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerClose'<span style="color: #000000;">));                </span><span style="color: #800080;">$cli</span>->fd = <span style="color: #800080;">$fd</span><span style="color: #000000;">;                </span><span style="color: #800080;">$ip</span> = <span style="color: #008080;">gethostbyname</span>(<span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_host);                </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$cli</span>->connect(<span style="color: #800080;">$ip</span>,<span style="color: #800080;">$this</span>->smtp_port) !== <span style="color: #0000ff;">false</span><span style="color: #000000;">){                    </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>] = <span style="color: #800080;">$cli</span><span style="color: #000000;">;                    }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{                    </span><span style="color: #800080;">$this</span>->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">);                    </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Cannot connect to SMTP server. Connection #'.<span style="color: #800080;">$fd</span>.' close.'<span style="color: #000000;">);                }                            }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{                </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Blocked clinet connection, IP deny : '.<span style="color: #800080;">$info</span>['remote_ip'],'warn'<span style="color: #000000;">);                </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">);                </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection #'.<span style="color: #800080;">$fd</span>.' close.'<span style="color: #000000;">);            }        }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{            </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Blocked clinet connection, too many connections.','warn'<span style="color: #000000;">);            </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">);                    }    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onReceive(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$from_id</span>,<span style="color: #800080;">$recv_data</span><span style="color: #000000;">){        </span><span style="color: #800080;">$info</span> = <span style="color: #800080;">$this</span>->getConnectionInfo(<span style="color: #800080;">$fd</span><span style="color: #000000;">);        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P 4bf69159e86f72b49e912e89ff24ef84server->send(<span style="color: #800080;">$fd</span>,"502 Not implemented".self::<span style="color: #000000;">EOF);            </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> C]\t502 Not implemented"<span style="color: #000000;">);        }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{                        </span><span style="color: #008000;">//</span><span style="color: #008000;">重置登陆验证                    </span>            <span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/^AUTH\s+LOGIN(.*)/', <span style="color: #800080;">$recv_data</span>,<span style="color: #800080;">$m</span><span style="color: #000000;">)){                </span><span style="color: #800080;">$m</span>[1] = <span style="color: #008080;">trim</span>(<span style="color: #800080;">$m</span>[1<span style="color: #000000;">]);                </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$m</span>[1<span style="color: #000000;">])){                    </span><span style="color: #008000;">//</span><span style="color: #008000;">只发送AUTH LOGIN 接下来将发送用户名</span>                    <span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->user = <span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_user;                }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{                    </span><span style="color: #800080;">$recv_data</span> = 'AUTH LOGIN '.<span style="color: #008080;">base64_encode</span>(<span style="color: #800080;">$this</span>->smtp_user).self::<span style="color: #000000;">EOF;                    </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass = <span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_pass;                }            }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{                </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/^HELO.*|^EHLO.*/', <span style="color: #800080;">$recv_data</span><span style="color: #000000;">)){                    </span><span style="color: #800080;">$recv_data</span> = 'HELO '.<span style="color: #800080;">$this</span>->smtp_host.self::<span style="color: #000000;">EOF;                }                </span><span style="color: #008000;">//</span><span style="color: #008000;">重置密码</span>                <span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">pass)){                    </span><span style="color: #800080;">$recv_data</span> = <span style="color: #008080;">base64_encode</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass).self::<span style="color: #000000;">EOF;                    </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass = ''<span style="color: #000000;">;                }                </span><span style="color: #008000;">//</span><span style="color: #008000;">重置用户名</span>                <span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">user)){                    </span><span style="color: #800080;">$recv_data</span> = <span style="color: #008080;">base64_encode</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->user).self::<span style="color: #000000;">EOF;                    </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->user = ''<span style="color: #000000;">;                    </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass = <span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_pass;                }                                </span><span style="color: #008000;">//</span><span style="color: #008000;">重置mail from</span>                <span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/^MAIL\s+FROM:.*/', <span style="color: #800080;">$recv_data</span><span style="color: #000000;">)){                    </span><span style="color: #800080;">$recv_data</span> = 'MAIL FROM:7730fadb62ecf373a6f652e40d6cd8c0smtp_from.'>'.self::<span style="color: #000000;">EOF;                }            }                        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">isConnected()){                </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->send(<span style="color: #800080;">$recv_data</span><span style="color: #000000;">);                </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> S]\t".<span style="color: #008080;">trim</span>(<span style="color: #800080;">$recv_data</span><span style="color: #000000;">));            }        }        }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onClose(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$from_id</span><span style="color: #000000;">){        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span><span style="color: #000000;">])){            </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">isConnected()){                </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">close();                </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection on SMTP server close.'<span style="color: #000000;">);            }        }        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection #'.<span style="color: #800080;">$fd</span>.' close. Flush the logs.','debug',<span style="color: #0000ff;">true</span><span style="color: #000000;">);    }        </span><span style="color: #008000;">/*</span><span style="color: #008000;">---------------------------------------------     *      * 服务器连接事件回调     *      ----------------------------------------------</span><span style="color: #008000;">*/</span>        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerConnect(<span style="color: #800080;">$cli</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connected to SMTP server.'<span style="color: #000000;">);    }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerReceive(<span style="color: #800080;">$cli</span>,<span style="color: #800080;">$data</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P 289e824d28d0676efd417da19e58cbb4server->send(<span style="color: #800080;">$cli</span>->fd,<span style="color: #800080;">$data</span><span style="color: #000000;">)){            </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> C]\t".<span style="color: #008080;">trim</span>(<span style="color: #800080;">$data</span><span style="color: #000000;">));        }            }        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerError(<span style="color: #800080;">$cli</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$cli</span>-><span style="color: #000000;">fd);        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection on SMTP server error: '.<span style="color: #800080;">$cli</span>->errCode.' '.socket_strerror(<span style="color: #800080;">$cli</span>->errCode),'warn'<span style="color: #000000;">);            }            </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerClose(<span style="color: #800080;">$cli</span><span style="color: #000000;">){        </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection on SMTP server close.'<span style="color: #000000;">);                </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$cli</span>-><span style="color: #000000;">fd);            }        </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * IP地址过滤     * @param unknown $ip     * @return boolean     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> isIpAllow(<span style="color: #800080;">$ip</span><span style="color: #000000;">){        </span><span style="color: #800080;">$pass</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">;        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['ip']['allow'<span style="color: #000000;">])){            </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>->setting['ip']['allow'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$addr</span><span style="color: #000000;">){                </span><span style="color: #800080;">$pattern</span> = '/'.<span style="color: #008080;">str_replace</span>('*','\d+',<span style="color: #008080;">str_replace</span>('.', '\.', <span style="color: #800080;">$addr</span>)).'/'<span style="color: #000000;">;                </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>(<span style="color: #800080;">$pattern</span>, <span style="color: #800080;">$ip</span>) && !<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$addr</span><span style="color: #000000;">)){                    </span><span style="color: #800080;">$pass</span> = <span style="color: #0000ff;">true</span><span style="color: #000000;">;                    </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;                }            }        }                </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$pass</span><span style="color: #000000;">){            </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['ip']['deny'<span style="color: #000000;">])){                </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>->setting['ip']['deny'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$addr</span><span style="color: #000000;">){                    </span><span style="color: #800080;">$pattern</span> = '/'.<span style="color: #008080;">str_replace</span>('*','\d+',<span style="color: #008080;">str_replace</span>('.', '\.', <span style="color: #800080;">$addr</span>)).'/'<span style="color: #000000;">;                    </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>(<span style="color: #800080;">$pattern</span>, <span style="color: #800080;">$ip</span>) && !<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$addr</span><span style="color: #000000;">)){                        </span><span style="color: #800080;">$pass</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">;                        </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;                    }                }            }        }        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$pass</span><span style="color: #000000;">;    }    }</span><span style="color: #0000ff;">class</span> Client <span style="color: #0000ff;">extends</span><span style="color: #000000;"> swoole_client{    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * 记录当前连接     * @var unknown     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #800080;">$fd</span><span style="color: #000000;"> ;        </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$user</span> = ''<span style="color: #000000;">;        </span><span style="color: #008000;">/*</span><span style="color: #008000;">*     * smtp登陆密码     * @var unknown     </span><span style="color: #008000;">*/</span>    <span style="color: #0000ff;">public</span> <span style="color: #800080;">$pass</span> = ''<span style="color: #000000;">;}</span>

 

 

  配置文件例子:

 

  

<span style="color: #008000;">/*</span><span style="color: #008000;">* *  运行配置</span><span style="color: #008000;">*/</span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">array</span><span style="color: #000000;">(        </span>'worker_num' => 12,        'log_file' => BASE_PATH.'/logs/proxyserver.log',        'pid_file' => BASE_PATH.'/logs/proxyserver.pid',        'heartbeat_idle_time' => 300,        'heartbeat_check_interval' => 60,        'max_connection' => 50,   <br>     //配置真实的smtp信息         'smtp_host' => '',        'smtp_port' => 25,        'smtp_user' => '',        'smtp_pass' => '',        'smtp_from' => '',        'ip' => <span style="color: #0000ff;">array</span><span style="color: #000000;">(            </span>'allow' => <span style="color: #0000ff;">array</span>('192.168.0.*'),            'deny' => <span style="color: #0000ff;">array</span>('192.168.10.*','192.168.100.*'),<span style="color: #000000;">        ));</span>

  运行例子:

  

defined('BASE_PATH') or define('BASE_PATH', __DIR__);defined('DEBUG_ON') or define('DEBUG_ON', true);//服务器配置require BASE_PATH.'/CSmtpProxy.php';$settings = require BASE_PATH.'/conf/config.php';CSmtpProxy::setPidFile($settings['pid_file']);CSmtpProxy::start(function(){	global $settings;	$serv = new CSmtpProxy('0.0.0.0', 25);	$serv->daemonize();	$serv->run($settings);});

  应用配置:

  smtp host: 192.168.0.*  //指定smtpproxy 运行的服务器IP。

     port: 25

     user: xxxx  //随意填写

     pass:  xxxx  //随意填写

     from: [email protected] // 根据情况填写

 

——————————————————————————————————————————————————————

 

  存在的问题:

    1、不支持ssl模式;

    2、应用的from还是要填写正确,否则发出的邮件发件人会显示错误。

 

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。