Skip to content

Instantly share code, notes, and snippets.

@dtjm
Last active December 26, 2015 13:48
Show Gist options
  • Select an option

  • Save dtjm/7160539 to your computer and use it in GitHub Desktop.

Select an option

Save dtjm/7160539 to your computer and use it in GitHub Desktop.
SendGrid cover letter
<html>
<head>
<meta charset='utf-8'>
<title>EHLO SendGrid</title>
<style type="text/css">
body {
background-color: #eee;
color: #222;
font-family: "Courier", monospace;
font-size: 16px;
margin: 0;
padding: 40px 0;f
}
body > p {
margin: 1em 40px;
width: 600px;
}
.scroller {
background: #111;
box-shadow: 0 4px 20px black;
height: 400px;
overflow: auto;
margin: 2em 0;
min-width: 800px;
max-width: 90%;
}
.scroller:-webkit-full-screen {
background: black;
width: 100%;
height: 100%;
}
.tx {
color: green;
float: left;
overflow-x: hidden;
padding: 10px;
min-width: 380px;
width: 47%
}
#recv {
color: orange;
}
div.log {
overflow-x: auto;
}
div.log div {
border-top: 1px dotted #040;
font-size: 13px;
height: 13px;
padding: 5px 0;
margin-top: 5px;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
</head>
<body>
<p><em>Send an email to
<strong>test@sendgrid.autumncloud.net</strong> and watch the
action here.</em> (Works best in Chrome or Safari)</p>
<p><a href="#" class="fullscreen">Enter full screen</a></p>
<div class="scroller">
<div class="tx" id="send">
<strong>SEND</strong>
<div class="log">
</div>
</div>
<div class="tx" id="recv">
<strong>RECV</strong>
<div class="log">
</div>
</div>
</div>
<p>
<a href="/main.go">SMTP-to-HTML server source code</a>
</p>
<script>
var blink = function(selector) {
var el = document.querySelector(selector);
var oldVisibility = el.style.visibility;
var intervalID = setInterval(function(){
if (el.style.visibility !== 'hidden') {
el.style.visibility = 'hidden';
} else {
el.style.visibility = oldVisibility;
}
}, 50);
setTimeout(function(){
clearInterval(intervalID);
el.style.visibility = oldVisibility;
}, 500);
};
var fullscreen = function() {
var scroller = document.querySelector('.scroller');
if (scroller.webkitRequestFullscreen) {
scroller.webkitRequestFullscreen();
}
if (scroller.mozRequestFullScreen) {
scroller.mozRequestFullScreen();
}
};
var fsEl = document.querySelector("a.fullscreen");
fsEl.addEventListener("click", function(){
fullscreen();
return false;
});
var log = function(elId, msg) {
var parent = document.getElementById(elId);
var logEl = parent.querySelector('.log');
var entry = document.createElement('div');
entry.textContent = msg;
logEl.appendChild(entry);
};
var scrollToBottom = function() {
var scroller = document.querySelector('.scroller');
scroller.scrollTop = scroller.scrollHeight;
};
var sendHandler = function(e) {
blink("#send strong");
log("send", e.data);
log("recv", "");
scrollToBottom();
};
var recvHandler = function(e) {
blink("#recv strong");
log("send", "");
log("recv", e.data);
scrollToBottom();
};
var eventSource = new EventSource('/eventstream');
eventSource.addEventListener('send', sendHandler, false);
eventSource.addEventListener('recv', recvHandler, false);
blink("#recv strong");
blink("#send strong");
</script>
</body>
</html>
package main
import (
"bufio"
"fmt"
"io"
"net/http"
"log"
"net"
"time"
)
var domain string = "sendgrid.autumncloud.net"
var connID int = 0
var writers []http.ResponseWriter
var quitters []chan bool
type envelope struct {
greeted bool
receivingData bool
connID int
conn net.Conn
reader *bufio.Reader
}
func checkErr(err error, conn net.Conn) {
if netErr, ok := err.(net.Error); ok && netErr.Timeout() && conn != nil {
fmt.Fprintf(conn, "QUIT sendgrid.autumncloud.net Timeout: %v\r\n", err.Error())
conn.Close()
}
if err != nil {
log.Printf("%v", err)
}
}
func timeout(conn net.Conn, duration time.Duration) {
conn.SetDeadline(time.Now().Add(duration))
}
func handleConn(conn net.Conn) {
log.Printf("==%d: Accepted connection from %v", connID, conn.RemoteAddr())
e := envelope{
false,
false,
connID,
conn,
bufio.NewReader(conn),
}
// Send opening greeting
greeting := fmt.Sprintf("220 %s SMTP", domain)
e.send(greeting)
for !e.greeted {
err := e.handleHELO()
if err != nil {
log.Printf("E:%d: %s", e.connID, err.Error())
return
}
}
for {
err := e.handleNextLine()
if err != nil {
log.Printf("E:%d: %s", e.connID, err.Error())
return
}
}
}
func (e *envelope) handleNextLine() error {
line, err := e.reader.ReadString('\n')
if err != nil {
return err
}
e.logRecv(line)
if !e.receivingData && len(line) < 4 {
fmt.Fprintf(e.conn, "500 Syntax error, command unrecognized\r\n")
e.logSend("500 Syntax error, command unrecognized")
return nil
}
if !e.receivingData && len(line) >= 4 && line[:4] == "HELP" {
e.send("214-Hello SendGrid!")
e.send("214-For more information about this server")
e.send("214 go to http://sendgrid.autumncloud.net")
return nil
}
if !e.receivingData && len(line) >= 4 && line[:4] == "DATA" {
e.receivingData = true
log.Printf("==%d: Receiving data", e.connID)
e.send("354 Start mail input; end with <CRLF>.<CRLF>")
return nil
}
if !e.receivingData && len(line) >= 4 && line[:4] == "QUIT" {
e.conn.Close()
log.Printf("==%d: Closing connection", e.connID)
return io.EOF
}
if e.receivingData && line == ".\r\n" {
e.receivingData = false
log.Printf("==%d: Data block end", e.connID)
}
if !e.receivingData {
e.send("250 OK")
}
return nil
}
func (e *envelope) handleHELO() error {
// Get next line
// timeout(e.conn, 0)
line, err := e.reader.ReadString('\n')
if err != nil {
return err
}
// checkErr(err, e.conn)
e.logRecv(line)
if len(line) < 4 {
e.send("500 Syntax error, command unrecognized")
return nil
}
if line[:4] != "HELO" {
e.send("500 Aren't you going to say HELO?")
return nil
}
// HELO has been received, send 250 ACK
e.send(fmt.Sprintf("250 %s", domain))
e.greeted = true
return nil
}
func (e *envelope) logRecv(line string) {
log.Printf("R:%d: %s", e.connID, line)
writeEvent("recv", line)
}
func (e *envelope) logSend(line string) {
log.Printf("S:%d: %s", e.connID, line)
writeEvent("send", line)
}
func (e *envelope) send(line string) {
fmt.Fprintf(e.conn, "%s\r\n", line)
e.logSend(line)
}
func writeEvent(event, data string) {
for i := 0; i < len(writers); i++ {
w := writers[i]
if w == nil {
continue
}
_, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", event, data)
if err != nil {
writers[i] = nil
quitters[i] <- true
}
if flusher, ok := w.(http.Flusher); ok {
flusher.Flush()
}
}
}
func main() {
addr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:25")
checkErr(err, nil)
l, err := net.ListenTCP("tcp", addr)
if err != nil {
log.Fatalf("Failed to listen on %v", addr)
}
log.Printf("Listening to smtp://%v", addr)
writers = make([]http.ResponseWriter, 0, 0)
quitters = make([]chan bool, 0, 0)
http.HandleFunc("/eventstream", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Opening eventstream")
w.Header().Set("Content-Type", "text/event-stream")
writers = append(writers, w)
quit := make(chan bool)
quitters = append(quitters, quit)
<-quit
log.Printf("Closing eventstream")
})
http.HandleFunc("/api/event_notification", func(w http.ResponseWriter,
r *http.Request) {
/*var b bytes.Buffer*/
log.Printf("===")
log.Printf("=== INCOMING EVENT ===")
log.Printf("%s %s %s", r.Method, r.RequestURI, r.Proto)
/*r.Header.Write(&b)*/
r.ParseForm()
for k, v := range r.Form {
log.Printf("\t%s = %s", k, v)
}
/*log.Printf("%s", b.String())*/
/*s, _ := ioutil.ReadAll(r.Body)*/
/*log.Printf("%s", string(s))*/
})
go func() {
log.Printf("Listening to http://127.0.0.1:5656")
http.ListenAndServe("127.0.0.1:5656", nil)
}()
for {
conn, err := l.AcceptTCP()
if err != nil {
log.Printf("AcceptTCP error: %s", err.Error())
}
connID++
go handleConn(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment