Last active
February 22, 2016 16:46
-
-
Save peeyushsrj/2eb4a2783dad679fc57b to your computer and use it in GitHub Desktop.
Implementation of prerender.io service in golang
This file contains 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
package main | |
import ( | |
"fmt" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"strings" | |
"time" | |
"gopkg.in/mgo.v2" | |
"gopkg.in/mgo.v2/bson" | |
"github.com/gorilla/mux" | |
) | |
//Set host in putintoCache | |
type cachePage struct { | |
Url string | |
Content string | |
LastModified time.Time | |
} | |
var cachePages *mgo.Collection | |
func prerenderHandler(w http.ResponseWriter, r *http.Request) { | |
requestPath := strings.TrimSuffix(r.URL.String(), "?escaped_fragment_=") | |
content := serveCache(requestPath) | |
fmt.Fprint(w, content) | |
} | |
func putintoCache(url string) string { | |
//Request to prerender server | |
host := "localhost" | |
requestUrl := "http://" + host + ":3000/http://" + host + url | |
//Inserting in db | |
cpage := cachePage{} | |
cpage.Url = url | |
cpage.Content, cpage.LastModified = downloadPage(requestUrl) | |
err := cachePages.Insert(&cpage) | |
if err != nil { | |
log.Fatal(err) | |
} | |
return cpage.Content | |
} | |
func downloadPage(requestUrl string) (string, time.Time) { | |
resp, err := http.Get(requestUrl) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer resp.Body.Close() | |
//lastmodDate := resp.Header.Get("Last-Modified") | |
lastModDate := time.Now() | |
b, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
log.Fatal(err) | |
} | |
return string(b), lastModDate | |
} | |
func serveCache(url string) string { | |
page := cachePage{} | |
err := cachePages.Find(bson.M{"url": url}).One(&page) | |
cacheDurationSeconds := time.Now().Unix() - page.LastModified.Unix() | |
cacheDurationDays := cacheDurationSeconds / 60 * 60 * 24 | |
if err != nil { | |
return putintoCache(url) //if not found in db | |
} else if cacheDurationDays > 1 { | |
return putintoCache(url) | |
} else { | |
return page.Content | |
} | |
} | |
func routePathHandler(w http.ResponseWriter, r *http.Request) { | |
http.ServeFile(w, r, "public/index.html") | |
} | |
func hello(w http.ResponseWriter, r *http.Request) { | |
fmt.Fprint(w, "hello") | |
} | |
func main() { | |
session, err := mgo.Dial("localhost") | |
if err != nil { | |
log.Fatal(err) | |
} | |
cachePages = session.DB("cache").C("pages") | |
r := mux.NewRouter() | |
r.Queries("escaped_fragment_", "").HandlerFunc(prerenderHandler) | |
//r.PathPrefix("/public").Handler(http.StripPrefix("/public", http.FileServer(http.Dir("public/")))) | |
r.Path("/hello").HandlerFunc(hello) | |
r.Path("/index").HandlerFunc(routePathHandler) | |
r.Path("/new").HandlerFunc(routePathHandler) | |
r.Path("/index/new").HandlerFunc(routePathHandler) | |
r.PathPrefix("/").Handler(http.FileServer(http.Dir("public/"))) | |
err = http.ListenAndServe(":80", r) | |
if err != nil { | |
log.Fatal(err) | |
} | |
//When not using cache we can just redirect crawler | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment