Skip to content

Instantly share code, notes, and snippets.

@iphoting
Created May 18, 2012 07:43
Show Gist options
  • Save iphoting/2723811 to your computer and use it in GitHub Desktop.
Save iphoting/2723811 to your computer and use it in GitHub Desktop.
RESTful PHP Mail Interface
#!/usr/bin/env php
<?php
$ss = 'changeit';
$rand = mt_rand();
$input = array(
"shared" => sha1($ss . $rand),
"salt" => $rand,
"to" => 'test@test.com',
"subject" => "This is a test subject.",
"message" => "Hello,\nThis is a test message.\nBye!",
"additional_headers" => "From: <testsubject@test.com>"
);
echo urlencode(base64_encode(serialize($input))) . "\n";
<?php
# A RESTful interface dispatcher to php's mail() function.
#
# input - A urlencoded base64_encoded serialised array of the following keys:
#
# to - The receivers of the email message; must comply with RFC 2822.
# Examples:
# - user@example.com
# - user@example.com, anotheruser@example.com
# - User <user@example.com>
# - User <user@example.com>, Another User
# <anotheruser@example.com>
#
# subject - Subject of the email to be sent. Must satisfy RFC 2047.
#
# message - Message to be sent, separate new lines with LF (\n).
# Each line should not be longer than 70 characters.
#
# additional_headers - Additional Headers: String to be inserted
# at the end of the email header. Recommended
# to set 'From: <email@host.com>' here.
# Separate multiple headers with CRLF (\r\n).
#
# shared - A sha1() hash of $ss concat with mt_rand().
#
# salt - The value of mt_rand() used above.
#
# Example
#
# $ss = 'change to match server script';
# $rand = mt_rand();
#
# $input = array(
# "shared" => sha1($ss . $rand),
# "salt" => $rand,
# "to" => "test@test.com",
# "subject" => "This is a test subject.",
# "message" => "Hello,\nThis is a test message.\nBye!",
# "additional_headers" => "From: <testsubject@test.com>"
# );
#
# $ch = curl_init('http://server/path/to/rest-mail.php');
# curl_setopt($ch, CURLOPT_POST, 1);
# $post_data = 'input=' . urlencode(base64_encode(serialize($input)));
# curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
#
# //curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
# //curl_setopt($ch, CURLOPT_HEADER, TRUE);
# curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
#
# $resp = curl_exec($ch);
# $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
# $errno = curl_errno($ch);
#
# curl_close($ch);
#
# if($errno !== 0 || $code != 200) {
# // Graceful degradation of errors.
# echo "Mail sending failed.";
# if($errno !== 0) {
# echo "\nCurl Error: " . $errno)
# }
#
# if(!empty($code)) {
# echo "\nServer Code: " . $code;
# }
#
# if(!empty($resp)) {
# echo "\nServer said: " . $resp;
# }
# } else {
# // Success.
# echo "Mail Sent!";
# }
#
# Returns HTTP status codes:
# - 200 for success.
# - 400 for bad request.
# - 403 for invalid pre-shared secret.
# - 500 for internal server error.
#
// The Shared Secret.
$ss = 'changeit';
/* GET //
// check for input parameter and it's not empty.
if(!isset($_GET['input']) || empty($_GET['input'])) {
HTTPStatus(400);
exit("Bad Request");
}
// $_GET are already decoded. Just unserialize input param.
$input = unserialize(base64_decode($_GET['input']));
// END GET */
// POST //
// check for input parameter and it's not empty.
if(!isset($_POST['input']) || empty($_POST['input'])) {
HTTPStatus(400);
exit("Bad Request");
}
// $_POST are already decoded. Just unserialize input param.
$input = unserialize(base64_decode($_POST['input']));
// END POST //
if($input === FALSE) {
// unserialize error, bad request.
HTTPStatus(400);
exit("Bad Request");
}
// check for pre-shared secret.
if(!isset($input['shared']) || !isset($input['salt']) || empty($input['shared']) || empty($input['salt'])) {
// Missing shared secret.
HTTPStatus(403);
exit("Forbidden");
} elseif($input['shared'] !== sha1($ss . $input['salt'])) {
// Invalid shared secret.
HTTPStatus(403);
exit("Forbidden");
}
// Looks good! Call mail.
//if(print_r($input)) {
if(mail($input['to'], $input['subject'], $input['message'], $input['additional_headers'])) {
// successful, return status 200.
exit("OK");
} else {
// return error code 500.
HTTPStatus(500);
exit("Internal Server Error");
}
# Emits a specified HTTP Status code via header().
#
# num - The HTTP status code to be emitted.
#
# Example:
#
# HTTPStatus(400);
#
# Returns nothing.
#
function HTTPStatus($num) {
$http = array(
100 => 'HTTP/1.1 100 Continue',
101 => 'HTTP/1.1 101 Switching Protocols',
200 => 'HTTP/1.1 200 OK',
201 => 'HTTP/1.1 201 Created',
202 => 'HTTP/1.1 202 Accepted',
203 => 'HTTP/1.1 203 Non-Authoritative Information',
204 => 'HTTP/1.1 204 No Content',
205 => 'HTTP/1.1 205 Reset Content',
206 => 'HTTP/1.1 206 Partial Content',
300 => 'HTTP/1.1 300 Multiple Choices',
301 => 'HTTP/1.1 301 Moved Permanently',
302 => 'HTTP/1.1 302 Found',
303 => 'HTTP/1.1 303 See Other',
304 => 'HTTP/1.1 304 Not Modified',
305 => 'HTTP/1.1 305 Use Proxy',
307 => 'HTTP/1.1 307 Temporary Redirect',
400 => 'HTTP/1.1 400 Bad Request',
401 => 'HTTP/1.1 401 Unauthorized',
402 => 'HTTP/1.1 402 Payment Required',
403 => 'HTTP/1.1 403 Forbidden',
404 => 'HTTP/1.1 404 Not Found',
405 => 'HTTP/1.1 405 Method Not Allowed',
406 => 'HTTP/1.1 406 Not Acceptable',
407 => 'HTTP/1.1 407 Proxy Authentication Required',
408 => 'HTTP/1.1 408 Request Time-out',
409 => 'HTTP/1.1 409 Conflict',
410 => 'HTTP/1.1 410 Gone',
411 => 'HTTP/1.1 411 Length Required',
412 => 'HTTP/1.1 412 Precondition Failed',
413 => 'HTTP/1.1 413 Request Entity Too Large',
414 => 'HTTP/1.1 414 Request-URI Too Large',
415 => 'HTTP/1.1 415 Unsupported Media Type',
416 => 'HTTP/1.1 416 Requested Range Not Satisfiable',
417 => 'HTTP/1.1 417 Expectation Failed',
500 => 'HTTP/1.1 500 Internal Server Error',
501 => 'HTTP/1.1 501 Not Implemented',
502 => 'HTTP/1.1 502 Bad Gateway',
503 => 'HTTP/1.1 503 Service Unavailable',
504 => 'HTTP/1.1 504 Gateway Time-out',
505 => 'HTTP/1.1 505 HTTP Version Not Supported',
);
header($http[$num], true, $num);
}
#!/usr/bin/env php
<?php
# Tool to create RESTful mail sending requests.
#
# Usage Notes:
# Edit the fields in the array below, the server url and then run the script.
#
$ss = 'changeit';
$rand = mt_rand();
$input = array(
"shared" => sha1($ss . $rand),
"salt" => $rand,
"to" => "test@test.com",
"subject" => "This is a test subject.",
"message" => "Hello,\nThis is a test message.\nBye!",
"additional_headers" => "From: <testsubject@test.com>"
);
/* GET //
$ch = curl_init('http://localhost/~ubuntu/rest-mail.php?input=' . urlencode(base64_encode(serialize($input))));
// END GET */
// POST //
$ch = curl_init('http://localhost/~ubuntu/rest-mail.php');
curl_setopt($ch, CURLOPT_POST, 1);
$post_data = 'input=' . urlencode(base64_encode(serialize($input)));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// END POST //
//curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
//curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$errno = curl_errno($ch);
curl_close($ch);
if($errno !== 0 || $code != 200) {
// Graceful degradation of errors.
echo "Mail sending failed.";
if($errno !== 0) {
echo "\nCurl Error: " . _curl_error_text($errno);
}
if(!empty($code)) {
echo "\nServer Code: " . $code;
}
if(!empty($resp)) {
echo "\nServer said: " . $resp;
}
} else {
// Success.
echo "Mail Sent!";
}
echo "\n";
# Convert curl error numbers to text.
function _curl_error_text($code) {
$error_codes = array(
1 => 'CURLE_UNSUPPORTED_PROTOCOL',
2 => 'CURLE_FAILED_INIT',
3 => 'CURLE_URL_MALFORMAT',
4 => 'CURLE_URL_MALFORMAT_USER',
5 => 'CURLE_COULDNT_RESOLVE_PROXY',
6 => 'CURLE_COULDNT_RESOLVE_HOST',
7 => 'CURLE_COULDNT_CONNECT',
8 => 'CURLE_FTP_WEIRD_SERVER_REPLY',
9 => 'CURLE_REMOTE_ACCESS_DENIED',
11 => 'CURLE_FTP_WEIRD_PASS_REPLY',
13 => 'CURLE_FTP_WEIRD_PASV_REPLY',
14 =>'CURLE_FTP_WEIRD_227_FORMAT',
15 => 'CURLE_FTP_CANT_GET_HOST',
17 => 'CURLE_FTP_COULDNT_SET_TYPE',
18 => 'CURLE_PARTIAL_FILE',
19 => 'CURLE_FTP_COULDNT_RETR_FILE',
21 => 'CURLE_QUOTE_ERROR',
22 => 'CURLE_HTTP_RETURNED_ERROR',
23 => 'CURLE_WRITE_ERROR',
25 => 'CURLE_UPLOAD_FAILED',
26 => 'CURLE_READ_ERROR',
27 => 'CURLE_OUT_OF_MEMORY',
28 => 'CURLE_OPERATION_TIMEDOUT',
30 => 'CURLE_FTP_PORT_FAILED',
31 => 'CURLE_FTP_COULDNT_USE_REST',
33 => 'CURLE_RANGE_ERROR',
34 => 'CURLE_HTTP_POST_ERROR',
35 => 'CURLE_SSL_CONNECT_ERROR',
36 => 'CURLE_BAD_DOWNLOAD_RESUME',
37 => 'CURLE_FILE_COULDNT_READ_FILE',
38 => 'CURLE_LDAP_CANNOT_BIND',
39 => 'CURLE_LDAP_SEARCH_FAILED',
41 => 'CURLE_FUNCTION_NOT_FOUND',
42 => 'CURLE_ABORTED_BY_CALLBACK',
43 => 'CURLE_BAD_FUNCTION_ARGUMENT',
45 => 'CURLE_INTERFACE_FAILED',
47 => 'CURLE_TOO_MANY_REDIRECTS',
48 => 'CURLE_UNKNOWN_TELNET_OPTION',
49 => 'CURLE_TELNET_OPTION_SYNTAX',
51 => 'CURLE_PEER_FAILED_VERIFICATION',
52 => 'CURLE_GOT_NOTHING',
53 => 'CURLE_SSL_ENGINE_NOTFOUND',
54 => 'CURLE_SSL_ENGINE_SETFAILED',
55 => 'CURLE_SEND_ERROR',
56 => 'CURLE_RECV_ERROR',
58 => 'CURLE_SSL_CERTPROBLEM',
59 => 'CURLE_SSL_CIPHER',
60 => 'CURLE_SSL_CACERT',
61 => 'CURLE_BAD_CONTENT_ENCODING',
62 => 'CURLE_LDAP_INVALID_URL',
63 => 'CURLE_FILESIZE_EXCEEDED',
64 => 'CURLE_USE_SSL_FAILED',
65 => 'CURLE_SEND_FAIL_REWIND',
66 => 'CURLE_SSL_ENGINE_INITFAILED',
67 => 'CURLE_LOGIN_DENIED',
68 => 'CURLE_TFTP_NOTFOUND',
69 => 'CURLE_TFTP_PERM',
70 => 'CURLE_REMOTE_DISK_FULL',
71 => 'CURLE_TFTP_ILLEGAL',
72 => 'CURLE_TFTP_UNKNOWNID',
73 => 'CURLE_REMOTE_FILE_EXISTS',
74 => 'CURLE_TFTP_NOSUCHUSER',
75 => 'CURLE_CONV_FAILED',
76 => 'CURLE_CONV_REQD',
77 => 'CURLE_SSL_CACERT_BADFILE',
78 => 'CURLE_REMOTE_FILE_NOT_FOUND',
79 => 'CURLE_SSH',
80 => 'CURLE_SSL_SHUTDOWN_FAILED',
81 => 'CURLE_AGAIN',
82 => 'CURLE_SSL_CRL_BADFILE',
83 => 'CURLE_SSL_ISSUER_ERROR',
84 => 'CURLE_FTP_PRET_FAILED',
84 => 'CURLE_FTP_PRET_FAILED',
85 => 'CURLE_RTSP_CSEQ_ERROR',
86 => 'CURLE_RTSP_SESSION_ERROR',
87 => 'CURLE_FTP_BAD_FILE_LIST',
88 => 'CURLE_CHUNK_FAILED'
);
return $error_codes[$code];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment