Created
December 28, 2014 17:15
-
-
Save awilliams/14f8982ea3a922144d80 to your computer and use it in GitHub Desktop.
π© server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HTTP server which periodically emits a message, in this case, "π© ". | |
// | |
// Idea taken from http://robpike.io/ | |
// Test with: curl -i -N http://localhost:8080 | |
package main | |
import ( | |
"fmt" | |
"io" | |
"log" | |
"net/http" | |
"time" | |
) | |
const ( | |
addr = ":8080" | |
interval = 2 // seconds | |
output = "π© " | |
) | |
func main() { | |
http.HandleFunc("/", handler) | |
log.Printf("Starting server on %s", addr) | |
if err := http.ListenAndServe(addr, nil); err != nil { | |
log.Fatal("ListenAndServe error: ", err) | |
} | |
} | |
// handler hijacks the HTTP connection and periodically sends a "chunked" message | |
func handler(w http.ResponseWriter, req *http.Request) { | |
hj, ok := w.(http.Hijacker) | |
if !ok { | |
http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError) | |
return | |
} | |
conn, bufrw, err := hj.Hijack() | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
defer conn.Close() | |
if err = writeChunkedHeader(bufrw); err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
bufrw.Flush() | |
chunk := []byte(fmt.Sprintf("%x\r\n%s\r\n", len(output), output)) | |
for _ = range time.NewTicker(interval * time.Second).C { | |
if _, err = bufrw.Write(chunk); err != nil { | |
return | |
} | |
bufrw.Flush() | |
} | |
} | |
const ( | |
headerTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT" | |
header = `HTTP/1.1 200 OK | |
Date: %s | |
Content-Type: text/plain; charset=UTF-8 | |
Transfer-Encoding: chunked | |
` | |
) | |
// writeChunckedHeader returns an HTTP 1.1 header with transfer encoding set to chunked. | |
func writeChunkedHeader(w io.Writer) error { | |
_, err := w.Write([]byte( | |
fmt.Sprintf(header, time.Now().UTC().Format(headerTimeFormat)), | |
)) | |
return err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment