IMAP or POP3 server implemented in PHP

我与影子孤独终老i 提交于 2019-11-29 20:03:58

问题


Is there any available implementation of POP3/IMAP server in PHP?

I am handling my e-mail service using sendgrid. I am going to store the messages on my server using files/db/whatever and now I'd like to provide full POP3 or IMAP (preferable) access for my users to their mailbox. Is there such implementation in PHP? Or is there any other possibility to run POP3/IMAP in the distributed environment of Windows Azure (assuming I have the mailboxes stored in shared blobs/tables/db)?


回答1:


Well, just to show that it is in fact possible to write a POP3 server in PHP, here it is. The server does no authentication--or pretty much anything else. It just keep sending the same message over and over. But it works. Thunderbird was able to retrieve messages from it. Totally useless, but sort of cool.

My setup is Apache 2 on Windows with PHP 5.2.

<?php

// echo something so fopen() would return
header("Content-type: text/plain");
echo "OK\n";
flush();

// listen for incoming connection
$listen_socket = socket_create_listen(110, 1);
$r = $w = $e = array($listen_socket);
$n = socket_select($r, $w, $e, 120);
$client_socket = ($n == 1) ? socket_accept($listen_socket) : null;
socket_close($listen_socket);

// spawn copy of myself
$internal_url = "http://{$_SERVER['HTTP_HOST']}:{$_SERVER['SERVER_PORT']}{$_SERVER['SCRIPT_NAME']}";
$stream_context_options = array (
    'http' => array (
        'method' => 'GET',
        'timeout' => 1
    )
);
$context = stream_context_create($stream_context_options);
if($f = fopen($internal_url, "rb", 0, $context)) {
    fclose($f);
}

if(!$client_socket) {
    // timed out
    exit;
}

// start handling the session
$read_buffer = "";
$write_buffer = "+OK POP3 server ready\r\n";
$active = true;

$messages = array(
    "From: webmaster@example.com\r\nSubject: This is a test\r\n\r\nHello world!\r\n"
);


$idle_start = time();
while(true) {
    $r = $w = $e = array($client_socket);
    $n = socket_select($r, $w, $e, 60);
    if($n) {
        if($r) {
            // read from the socket
            $read_buffer .= socket_read($client_socket, 128);
            $idle_start = time();
        }
        if($w) {
            if($write_buffer) {
                // write to the socket
                $written = socket_write($client_socket, $write_buffer);
                $write_buffer = substr($write_buffer, $written);
                $idle_start = time();
            } else if($active) {
                $now = time();
                $idle_time = $now - $idle_start;
                if($idle_time > 10) {
                    // exit if nothing happened for 10 seconds
                    break;
                } else if($idle_time > 2) {
                    // start napping when the client is too slow
                    sleep(1);
                }
            } else {
                break;
            }
        }
        if($e) {
            break;
        }
        if($read_buffer) {
            if(preg_match('/(.*?)(?:\s+(.*?))?[\r\n]+/', $read_buffer, $matches)) {
                $read_buffer = substr($read_buffer, strlen($matches[0]));
                $command = $matches[1];
                $argument = $matches[2];
                switch($command) {
                    case 'USER':
                        $username = $argument;
                        $write_buffer .= "+OK $username is welcome here\r\n";
                        break;
                    case 'PASS':
                        $message_count = count($messages);
                        $write_buffer .= "+OK mailbox has $message_count message(s)\r\n";
                        break;
                    case 'QUIT': 
                        $write_buffer .= "+OK POP3 server signing off\r\n";
                        $active = false;
                        break;
                    case 'STAT':
                        $message_count = count($messages);
                        $mailbox_size = 0;
                        foreach($messages as $message) {
                            $mailbox_size += strlen($message);
                        }
                        $write_buffer .= "+OK $message_count $mailbox_size\r\n";
                        break;
                    case 'LIST':
                        $start_index = (int) $argument;
                        $message_count = count($messages) - $start_index;
                        $total_size = 0;
                        for($i = $start_index; $i < count($messages); $i++) {
                            $total_size += strlen($messages[$i]);
                        }
                        $write_buffer .= "+OK $message_count messages ($total_size octets)\r\n";
                        for($i = $start_index; $i < count($messages); $i++) {
                            $message_id = $i + 1;
                            $message_size = strlen($messages[$i]);
                            $write_buffer .= "$message_id $message_size\r\n";
                        }
                        $write_buffer .= ".\r\n";
                        break;
                    case 'RETR':
                        $message_id = (int) $argument;
                        $message = $messages[$message_id - 1];
                        $message_size = strlen($message);
                        $write_buffer .= "+OK $message_size octets\r\n";
                        $write_buffer .= "$message\r\n";
                        $write_buffer .= ".\r\n";
                        break;
                    case 'DELE':
                        $write_buffer .= "+OK\r\n";
                        break;
                    case 'NOOP':
                        $write_buffer .= "+OK\r\n";
                        break;
                    case 'LAST':
                        $message_count = count($messages) - $start_index;
                        $write_buffer .= "+OK $message_count\r\n";
                        break;
                    case 'RSET':
                        $write_buffer .= "+OK\r\n";
                        break;
                    default:
                        $write_buffer .= "-ERR Unknown command '$command'\r\n";
                }
            }
        }
    } else {
        break;
    }
}

?>


来源:https://stackoverflow.com/questions/11968363/imap-or-pop3-server-implemented-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!