Skip to content
This repository has been archived by the owner on Nov 22, 2018. It is now read-only.

Commit

Permalink
go-tour: fix app engine version, restoring online-specific content
Browse files Browse the repository at this point in the history
R=minux.ma, campoy, campoy
CC=golang-dev
https://codereview.appspot.com/7195043
  • Loading branch information
adg committed Jan 24, 2013
1 parent 53bf3f4 commit 4b0c49c
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 167 deletions.
7 changes: 3 additions & 4 deletions appengine/app.yaml → app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ runtime: go
api_version: go1

handlers:
- url: /
static_files: static/index.html
upload: static/index.html
- url: /favicon.ico
static_files: static/favicon.ico
upload: static/favicon.ico
- url: /static
static_dir: static
- url: /talks
static_dir: talks
- url: /(compile|fmt)
- url: /(|compile|fmt)
script: _go_app

nobuild_files: (solutions|prog)/.*
16 changes: 0 additions & 16 deletions appengine/README

This file was deleted.

44 changes: 0 additions & 44 deletions appengine/goplay/compile.go

This file was deleted.

50 changes: 0 additions & 50 deletions appengine/goplay/fmt.go

This file was deleted.

92 changes: 92 additions & 0 deletions gotour/appengine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build appengine

package main

import (
"bufio"
"bytes"
"fmt"
"io"
"net/http"

"appengine"
"appengine/urlfetch"
)

const runUrl = "http://golang.org/compile"

func init() {
http.HandleFunc("/", rootHandler)
http.HandleFunc("/compile", compileHandler)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if err := renderTour(w, "."); err != nil {
c.Criticalf("template render: %v", err)
}
}

func compileHandler(w http.ResponseWriter, r *http.Request) {
if err := passThru(w, r); err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "Compile server error.")
}
}

func passThru(w io.Writer, req *http.Request) error {
c := appengine.NewContext(req)
client := urlfetch.Client(c)
defer req.Body.Close()
r, err := client.Post(runUrl, req.Header.Get("Content-type"), req.Body)
if err != nil {
c.Errorf("making POST request:", err)
return err
}
defer r.Body.Close()
if _, err := io.Copy(w, r.Body); err != nil {
c.Errorf("copying response Body:", err)
return err
}
return nil
}

// prepContent returns a Reader that produces the content from the given
// Reader, but strips the prefix "#appengine: " from each line. It also drops
// any non-blank like that follows a series of 1 or more lines with the prefix.
func prepContent(in io.Reader) io.Reader {
var prefix = []byte("#appengine: ")
out, w := io.Pipe()
go func() {
r := bufio.NewReader(in)
drop := false
for {
b, err := r.ReadBytes('\n')
if err != nil && err != io.EOF {
w.CloseWithError(err)
return
}
if bytes.HasPrefix(b, prefix) {
b = b[len(prefix):]
drop = true
} else if drop {
if len(b) > 1 {
b = nil
}
drop = false
}
if len(b) > 0 {
w.Write(b)
}
if err == io.EOF {
w.Close()
return
}
}
}()
return out
}
37 changes: 0 additions & 37 deletions gotour/goplay.go

This file was deleted.

53 changes: 41 additions & 12 deletions gotour/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !appengine

package main

import (
"bytes"
"encoding/json"
"flag"
"fmt"
"go/build"
"io"
"io/ioutil"
"log"
"net"
Expand Down Expand Up @@ -41,7 +45,7 @@ var (
// a source of numbers, for naming temporary files
uniq = make(chan int)

// GOPATH containing the tour packages
// GOPATH containing the tour packages
gopath = os.Getenv("GOPATH")
)

Expand Down Expand Up @@ -83,23 +87,23 @@ func main() {
}

log.Println("Serving content from", root)

fs := http.FileServer(http.Dir(root))
http.Handle("/favicon.ico", fs)
http.Handle("/static/", fs)
http.Handle("/talks/", fs)

http.HandleFunc("/compile", compileHandler)
http.HandleFunc("/kill", killHandler)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/favicon.ico" {
fn := filepath.Join(root, "static", r.URL.Path[1:])
http.ServeFile(w, r, fn)
return
} else if r.URL.Path == "/" {
err := renderTour(w, root)
if err != nil {
if r.URL.Path == "/" {
if err := renderTour(w, root); err != nil {
log.Println(err)
}
return
}
http.Error(w, "not found", 404)
})
http.Handle("/static/", http.FileServer(http.Dir(root)))
http.Handle("/talks/", http.FileServer(http.Dir(root)))
http.HandleFunc("/kill", kill)

host, port, err := net.SplitHostPort(*httpListen)
if err != nil {
Expand Down Expand Up @@ -136,6 +140,28 @@ If you don't understand this message, hit Control-C to terminate this process.
WARNING! WARNING! WARNING!
`

type response struct {
Output string `json:"output"`
Errors string `json:"compile_errors"`
}

func compileHandler(w http.ResponseWriter, req *http.Request) {
resp := new(response)
out, err := compile(req)
if err != nil {
if len(out) > 0 {
resp.Errors = string(out) + "\n" + err.Error()
} else {
resp.Errors = err.Error()
}
} else {
resp.Output = string(out)
}
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Println(err)
}
}

var running struct {
sync.Mutex
cmd *exec.Cmd
Expand All @@ -150,7 +176,7 @@ func stopRun() {
running.Unlock()
}

func kill(w http.ResponseWriter, r *http.Request) {
func killHandler(w http.ResponseWriter, r *http.Request) {
stopRun()
}

Expand Down Expand Up @@ -286,3 +312,6 @@ func startBrowser(url string) bool {
cmd := exec.Command(args[0], append(args[1:], url)...)
return cmd.Start() == nil
}

// prepContent for the local tour simply returns the content as-is.
func prepContent(r io.Reader) io.Reader { return r }
2 changes: 1 addition & 1 deletion gotour/tour.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func renderTour(w io.Writer, root string) error {
return err
}
defer f.Close()
doc, err := present.Parse(f, source, 0)
doc, err := present.Parse(prepContent(f), source, 0)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 4b0c49c

Please sign in to comment.