func send(req *http.Request) (resp *http.Response, err os.Error) { addr := req.URL.Host if !hasPort(addr) { addr += ":http" } conn, err := net.Dial("tcp", addr) if err != nil { return nil, err } err = req.Write(conn) if err != nil { conn.Close() return nil, err } reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req.Method) if err != nil { conn.Close() return nil, err } r := io.Reader(reader) if n := resp.ContentLength; n != -1 { r = io.LimitReader(r, n) } resp.Body = readClose{r, conn} return }
func buildTestRequest(method string, path string, body string, headers map[string][]string, cookies []*http.Cookie) *http.Request { host := "127.0.0.1" port := "80" rawurl := "http://" + host + ":" + port + path url_, _ := url.Parse(rawurl) proto := "HTTP/1.1" if headers == nil { headers = map[string][]string{} } headers["User-Agent"] = []string{"web.go test"} if method == "POST" { headers["Content-Length"] = []string{fmt.Sprintf("%d", len(body))} if headers["Content-Type"] == nil { headers["Content-Type"] = []string{"text/plain"} } } req := http.Request{Method: method, RawURL: rawurl, URL: url_, Proto: proto, Host: host, Header: http.Header(headers), Body: ioutil.NopCloser(bytes.NewBufferString(body)), } for _, cookie := range cookies { req.AddCookie(cookie) } return &req }
func EnterRollOff(w http.ResponseWriter, r *http.Request) { id := r.URL.Path[len("/roll-off-entry/"):] fmt.Println("User wishes to enter rolloff ", id) rollingUser := ParseUser(r) entry := &RollOffEntry{User: rollingUser, Score: rand.Intn(100) + 1} for _, r := range rolloffs { fmt.Println("Checking rolloff ", r.Id) if r.Id == id { r.AddEntry(entry) for elem := room.Users.Front(); elem != nil; elem = elem.Next() { go func(e *list.Element) { var tName string u := e.Value.(*User) if u == rollingUser { tName = "templates/roll-off/user-joins.html" } else { tName = "templates/roll-off/other-user-joins.html" } t := template.Must(template.ParseFile(tName)) m := NewMessage("system", "", "system") t.Execute(m, entry) u.c <- m }(elem) } } } }
func myWidgets(w http.ResponseWriter, r *http.Request) { var err os.Error ctx := appengine.NewContext(r) page, err := template.Parse(myWidgetTemplate, nil) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } data := myWidgetData{ CSS: commonCSS(), Header: header(ctx), } data.Widget, err = LoadWidgets(ctx) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } if len(r.FormValue("ids_only")) > 0 { w.Header().Set("Content-Type", "text/plain") for _, widget := range data.Widget { fmt.Fprintln(w, widget.ID) } return } page.Execute(w, data) }
func join(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) u := user.Current(c) if u == nil { url, err := user.LoginURL(c, r.URL.String()) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } w.Header().Set("Location", url) w.WriteHeader(http.StatusFound) return } r.ParseForm() // TODO check table arg state, err := joinTable(c, r.Form["table"][0], u.String()) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } var b []byte b, err = json.Marshal(state) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } fmt.Fprintf(w, "%s", b) }
func search(c *http.Conn, r *http.Request) { query := strings.TrimSpace(r.FormValue("q")) var result SearchResult if index, timestamp := searchIndex.get(); index != nil { result.Query = query result.Hit, result.Alt, result.Illegal = index.(*Index).Lookup(query) _, ts := fsTree.get() result.Accurate = timestamp >= ts } var buf bytes.Buffer if err := searchHTML.Execute(result, &buf); err != nil { log.Stderrf("searchHTML.Execute: %s", err) } var title string if result.Hit != nil { title = fmt.Sprintf(`Results for query %q`, query) } else { title = fmt.Sprintf(`No results found for query %q`, query) } servePage(c, title, query, buf.Bytes()) }
func handleInboxItem(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) userid, _, err := getSession(c, r) if err != nil { sendError(w, r, "No session cookie") return } s := newStore(c) perma_blobref := r.FormValue("perma") item, err := s.GetInboxItem(userid, perma_blobref) if err != nil { http.Error(w, "Could not get inbox item", http.StatusInternalServerError) c.Errorf("handleInboxItem: %v", err) return } entry := make(map[string]interface{}) entry["perma"] = perma_blobref entry["seq"] = item.LastSeq err = fillInboxItem(s, perma_blobref, item.LastSeq, entry) if err != nil { fmt.Fprintf(w, `{"ok":false, "error":%v}`, err.String()) return } info, _ := json.Marshal(entry) fmt.Fprintf(w, `{"ok":true, "item":%v}`, string(info)) }
func serveFile(c *http.Conn, r *http.Request) { path := r.Url.Path // pick off special cases and hand the rest to the standard file server switch ext := pathutil.Ext(path); { case path == "/": serveHtmlDoc(c, r, "doc/root.html") case r.Url.Path == "/doc/root.html": // hide landing page from its real name http.NotFound(c, r) case ext == ".html": serveHtmlDoc(c, r, path) case ext == ".go": serveGoSource(c, path, &Styler{highlight: r.FormValue("h")}) default: // TODO: // - need to decide what to serve and what not to serve // - don't want to download files, want to see them fileServer.ServeHTTP(c, r) } }
func (h *SearchPanelHandler) getSearchPanelHtml(hr *http.Request) string { fmt.Println("\n=== SearchPanelHandler : Requete reçue ====================") fmt.Println(" URL : " + hr.RawURL) hr.ParseForm() askerId := GetFormValueAsInt(hr, "asker") mdpr := GetFormValue(hr, "mdpr") // mot de passe restreint tok := GetFormValue(hr, "tok") compteOk := false var compte *Compte db, err := h.store.Connect() if err != nil { fmt.Printf("Erreur ouverture connexion BD dans makeBestiaryExtractHtml : %s\n", err.String()) return err.String() } defer db.Close() if askerId > 0 && mdpr != "" { compteOk, compte, err = h.store.CheckCompte(db, uint(askerId), mdpr) } if !compteOk { return "Compte non authentifié" } if tok == "" { return "Demande non comprise" } amis, err := h.store.GetPartageurs(db, askerId) if err != nil { return fmt.Sprintf("Erreur récupération amis : %s\n", err.String()) } observations, err := h.store.SearchObservations(db, tok, askerId, amis) if err != nil { return fmt.Sprintf("Erreur recherche : %s\n", err.String()) } if len(observations) == 0 { return "Rien trouvé" } html := fmt.Sprintf("%d résultats :", len(observations)) html += "<table border='0' cellspacing='1' cellpadding='2' class='mh_tdborder' align='center'>" html += "<tr class=mh_tdtitre><td class=mh_tdpage><b>Dist.</b></td><td class=mh_tdpage><b>Réf.</b></td><td class=mh_tdpage><b>Nom</b></td>" html += "<td class=mh_tdpage><b>Position</b></td>" html += "<td class=mh_tdpage><b>Vu par</b></td><td class=mh_tdpage><b>Le</b></td></tr>" for _, o := range observations { t := time.SecondsToLocalTime(o.Date) var lien string if o.Type == "troll" { lien = fmt.Sprintf("<a href='javascript:EPV(%d)' class=mh_trolls_1 id=%d>%s</a>", o.Num, o.Num, o.Nom) } else if o.Type == "monstre" { lien = fmt.Sprintf("<a href='javascript:EMV(%d, 750, 550)' class=mh_monstres id=%d>%s</a>", o.Num, o.Num, o.Nom) } else { lien = o.Nom } dist := dist(compte.Troll.X, o.X, compte.Troll.Y, o.Y, compte.Troll.Z, o.Z) btnVoir := fmt.Sprintf("<a x=%d y=%d z=%d class=gogo name=zoom>%d %d %d</a>", o.X, o.Y, o.Z, o.X, o.Y, o.Z) html += fmt.Sprintf("<tr class=mh_tdpage><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td></tr>", dist, o.Num, lien, btnVoir, o.Auteur, t.Format("02/01 à 15h04")) } html += "</table>" return html }
// hello world, the web server func PageExecuteJS(w http.ResponseWriter, req *http.Request) { url := req.FormValue("url") js := req.FormValue("js") header := w.Header() if url == "" { log.Printf("ERROR: url is required. (%s)\n", url) w.WriteHeader(http.StatusInternalServerError) header.Set("Content-Type", "text/plian;charset=UTF-8;") io.WriteString(w, "Internal Server Error: please input url.\n") return } if strings.Index(url, "http") != 0 { log.Printf("ERROR: url is invalid. (%s)\n", url) w.WriteHeader(http.StatusInternalServerError) header.Set("Content-Type", "text/plian;charset=UTF-8;") io.WriteString(w, "Internal Server Error: please input valid url.\n") return } if js == "" { log.Printf("ERROR: js is required. (%s)\n", url) w.WriteHeader(http.StatusInternalServerError) header.Set("Content-Type", "text/plian;charset=UTF-8;") io.WriteString(w, "Internal Server Error: please input js.\n") return } json := ExecuteJS(url, js) if len(json) == 0 { log.Printf("ERROR: failed to execute. (%s)\n", url) json = []byte("{}") } header.Set("Content-Type", "application/json;charset=UTF-8;") w.Write(json) }
func PageInternalUpdateJson(w http.ResponseWriter, req *http.Request) { id := req.FormValue("id") updateJson := req.FormValue("json") header := w.Header() conn, err := GetConnection() c := GetExecuteCollection(conn) var ( rs ExecuteRs jsonb []byte ) execId, err := mongo.NewObjectIdHex(id) log.Printf("Search ExecuteId=%s", execId) err = c.Find(map[string]interface{}{"_id": execId}).One(&rs) if err != nil { jsonb = []byte(`{error: "Not found."}`) } else { rs.Json = updateJson err = c.Update(mongo.M{"_id": execId}, rs) if err != nil { jsonb = []byte(`{result: "failed"}`) } else { jsonb = []byte(`{result: "success"}`) } } conn.Close() header.Set("Access-Control-Allow-Origin", "*") header.Set("Content-Type", "application/json") w.Write(jsonb) }
// Returns a map of all of the oauth_* (including signature) parameters for the // given request, and the signature base string used to generate the signature. func (s *HmacSha1Signer) GetOAuthParams(request *http.Request, clientConfig *ClientConfig, userConfig *UserConfig, nonce string, timestamp string) (map[string]string, string) { request.ParseForm() oauthParams := map[string]string{ "oauth_consumer_key": clientConfig.ConsumerKey, "oauth_nonce": nonce, "oauth_signature_method": "HMAC-SHA1", "oauth_timestamp": timestamp, "oauth_version": "1.0", } tokenKey, tokenSecret := userConfig.GetToken() if tokenKey != "" { oauthParams["oauth_token"] = tokenKey } signingParams := map[string]string{} for key, value := range oauthParams { signingParams[key] = value } for key, value := range request.URL.Query() { //TODO: Support multiple parameters with the same name. signingParams[key] = value[0] } for key, value := range request.Form { //TODO: Support multiple parameters with the same name. signingParams[key] = value[0] } signingUrl := fmt.Sprintf("%v://%v%v", request.URL.Scheme, request.URL.RawAuthority, request.URL.Path) signatureParts := []string{ request.Method, url.QueryEscape(signingUrl), s.encodeParameters(signingParams)} signatureBase := strings.Join(signatureParts, "&") oauthParams["oauth_signature"] = s.GetSignature(clientConfig.ConsumerSecret, tokenSecret, signatureBase) return oauthParams, signatureBase }
func RenderTiles(w http.ResponseWriter, req *http.Request) { e := os.Remove("svg/test-surface.svg") if e != nil { os.Stderr.WriteString(e.String() + "\n") } if CurrentTiling == nil { EmptySvg(w, req) return } style := req.FormValue("style") image := cairo.NewSurface("svg/test-surface.svg", 72*4, 72*4) image.SetSourceRGB(0., 0., 0.) image.SetLineWidth(.1) image.Translate(72*2., 72*2.) image.Scale(4., 4.) if style == "edges" { image.SetSourceRGBA(0., 0., 0., 1.) CurrentTiling.DrawEdges(image) } else if style == "plain" { CurrentTiling.ColourFaces(image, zellij.OrangeBlueBrush) } else { CurrentTiling.ColourDebugFaces(image) CurrentTiling.DrawDebugEdges(image) } image.Finish() http.ServeFile(w, req, "svg/test-surface.svg") }
func uploadUser(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { // No upload; show the upload form. uploadUserTemplate.Execute(w, nil) return } f, _, err := r.FormFile("image") errors.Check(err) defer f.Close() // Grab the image data i, _, err := image.Decode(f) errors.Check(err) var key string = keyOf() // store image i = picstore.Store(key, i, 320, "userimg") i = picstore.Store(key, i, 180, "userthumb") // generate result w.Header().Set("Content-Type", "application/json") w.Header().Set("cache-control", "no-cache") w.Header().Set("Expires", "-1") fmt.Fprintf(w, "{\"profilePicUrl\":\"uimg?id="+key+"\",\"profileThumbUrl\":\"utmb?id="+key+"\"}") }
func Delete(url string) *HttpRequestBuilder { var req http.Request req.Method = "DELETE" req.Header = http.Header{} req.Header.Set("User-Agent", defaultUserAgent) return &HttpRequestBuilder{url, &req, nil, map[string]string{}} }
func authCallback(w http.ResponseWriter, r *http.Request, oldSession *Session) { // We cheat here -- font-end has direct access to the oauth data code := r.FormValue("code") context := appengine.NewContext(r) var userKey datastore.Key _, err := memcache.Gob.Get(context, "oauth-code-"+code, &userKey) if err != nil { w.Write([]byte("Invalid code")) } else { /* auth := model.NewOAuth2(&userKey) if _, err = datastore.Put(context, datastore.NewIncompleteKey(context, "Authentication", nil), auth); err != nil { context.Errorf("Error saving: %v", err) w.Write([]byte("Error saving: " + err.String())) return } // replace session cookie oldKey := datastore.NewKey(context, "Session", oldSession.Key, 0, nil) datastore.Delete(context, oldKey) session := NewSession(context) oldSession.Key = session.Key oldSession.Token = auth.Token oldSession.SetCookie(w, context) // redirect */ } }
// articlesIndex is the handler for the site's index page. // It shows up to the last 10 article summaries (all public info except // for the Body) on a single page. func articlesIndex(w http.ResponseWriter, r *http.Request) { // Get the user-entered offset, or default to a zero offset. offsetS := r.FormValue("Page") var offset int if len(offsetS) > 0 { offset64, err := strconv.Btoi64(offsetS, 10) check(err) offset = int(offset64) } else { offset = 0 } // Fetch public data from datastore, up to 10, with offset `offset * 10` c := appengine.NewContext(r) q := datastore.NewQuery("Article").Order("-Date").Filter("Public =", true).Limit(10).Offset(10 * offset) a := make([]Article, 0, 10) _, err := q.GetAll(c, &a) check(err) // Prepares the `indexTemplate.html` template t := template.New("index") t, err = t.ParseFile("templates/indexTemplate.html") check(err) // Executes the template, providing the data gathered from the datastore err = t.Execute(w, a) check(err) }
func put(w http.ResponseWriter, r *http.Request) { keyName := r.FormValue("key") value := r.FormValue("val") c := appengine.NewContext(r) key := datastore.NewKey("Entity", keyName, 0, nil) entity := new(Entity) entity.Value = value result := map[string]string{ "error": "", } if _, err := datastore.Put(c, key, entity); err != nil { result["error"] = fmt.Sprintf("%s", err) } // Set the value to speed up future reads - errors here aren't // that bad, so don't worry about them item := &memcache.Item{ Key: keyName, Value: []byte(value), } memcache.Set(c, item) bumpGeneration(c) fmt.Fprintf(w, "%s", mapToJson(result)) }
func cookieHandler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") if cn := req.FormValue("set"); cn != "" { cv, cp := req.FormValue("val"), req.FormValue("pat") trace("cookieHandler recieved cookie %s=%s; path=%s.", cn, cv, cp) w.Header().Set("Set-Cookie", fmt.Sprintf("%s=%s; Path=/de/index; Domain=my.domain.org; Secure;", cn, cv)) } if t := req.FormValue("goto"); t != "" { w.Header().Set("Location", "localhost:54123/"+t) w.WriteHeader(302) } else { w.WriteHeader(200) body := "<html><head><title>Cookies</title></head>\n<body><h1>All Submitted Cookies</h1>" for _, cookie := range req.Cookies() { body += "<div class=\"cookies\">\n" body += " <ul>\n" body += " <li>" + cookie.Name + " :: " + cookie.Value + "</li>\n" body += " </ul>\n" body += "</div>\n" } body += "</body></html>" w.Write([]byte(body)) } }
func handle(w http.ResponseWriter, r *http.Request) { // If root, show the link registration page. if r.URL.Path == "/" { switch r.Method { case "GET": w.Write([]byte(registration)) case "POST": // Get input key := r.FormValue("key") url := r.FormValue("url") // Write to db resp := make(chan bool) save <- SaveRequest{key, url, resp} _ = <-resp w.Write([]byte("ok")) } return } // Redirect user based on the path. resp := make(chan string) code := r.URL.Path[1:] lookup <- LookupRequest{code, resp} url := <-resp if url == "" { http.Error(w, "Key not found", http.StatusNotFound) return } http.Redirect(w, r, <-resp, http.StatusFound) }
func c1LoginHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if l, err := c1IsLoggedIn(c); err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } else if l { /// http.Redirect(w, r, "/", http.StatusFound) http.Redirect(w, r, "/index", http.StatusFound) return } if r.Method == "GET" { w.Write([]byte( "<html><body><form action='/c1Login' method='POST'>" + "<input type='text' name='usr'></input>" + "<input type='password' name='pwd'></input>" + "<input type='submit' value='Submit'></input>" + "</form></body></html>")) return } else if r.Method == "POST" { usr := r.FormValue("usr") pwd := r.FormValue("pwd") _, err := C1Login(c, usr, pwd) if err == C1AuthError { http.Error(w, err.String(), http.StatusUnauthorized) return } http.Redirect(w, r, "/index", http.StatusFound) /// http.Redirect(w, r, "/", http.StatusFound) } }
func loginView(req *http.Request, s *session) interface{} { rurl := req.FormValue("back") if rurl == "" { rurl = "/" } if req.FormValue("username") != "" && req.FormValue("password") != "" { user := study.GetUser(req.FormValue("username")) if user != nil && user.CheckPass(req.FormValue("password")) { s.User = user s.Admin = false if user.GetAttr("admin") == study.DBTRUE { if _, ok := config.Conf.AdminUsers[user.Username]; ok { s.Admin = true } else { user.SetAttr("admin", study.DBFALSE) } } return redirectResponse(rurl) } return giveTplData{ "ReturnTo": rurl, "Error": messages["BadUserOrPass"], } } return giveTplData{ "ReturnTo": rurl, } }
func get(w http.ResponseWriter, r *http.Request) { keyName := r.FormValue("key") c := appengine.NewContext(r) result := map[string]string{ keyName: "", "error": "", } if item, err := memcache.Get(c, keyName); err == nil { result[keyName] = fmt.Sprintf("%q", item.Value) fmt.Fprintf(w, "%s", mapToJson(result)) return } key := datastore.NewKey("Entity", keyName, 0, nil) entity := new(Entity) if err := datastore.Get(c, key, entity); err == nil { result[keyName] = entity.Value // Set the value to speed up future reads - errors here aren't // that bad, so don't worry about them item := &memcache.Item{ Key: keyName, Value: []byte(entity.Value), } memcache.Set(c, item) } else { result["error"] = fmt.Sprintf("%s", err) } fmt.Fprintf(w, "%s", mapToJson(result)) }
func AppEngineVerify(r *http.Request) string { if err := r.ParseForm(); err != nil { return "Anonymous" } token := r.FormValue("assertion") url := "https://browserid.org/verify" bodytype := "application/x-www-form-urlencoded" body := strings.NewReader("assertion=" + token + "&audience=" + r.Host) var response_body []byte c := appengine.NewContext(r) client := urlfetch.Client(c) res, err := client.Post(url, bodytype, body) if err != nil { fmt.Println("err=", err) return "Anonymous" } else { response_body, _ = ioutil.ReadAll(res.Body) res.Body.Close() } var f interface{} json.Unmarshal(response_body, &f) m := f.(map[string]interface{}) return fmt.Sprintf("%s", m["email"]) }
func handleVerify(conn http.ResponseWriter, req *http.Request) { if !(req.Method == "POST" && req.URL.Path == "/camli/sig/verify") { httputil.BadRequestError(conn, "Inconfigured handler.") return } req.ParseForm() sjson := req.FormValue("sjson") if sjson == "" { httputil.BadRequestError(conn, "Missing sjson parameter.") return } m := make(map[string]interface{}) vreq := jsonsign.NewVerificationRequest(sjson, pubKeyFetcher) if vreq.Verify() { m["signatureValid"] = 1 m["verifiedData"] = vreq.PayloadMap } else { errStr := vreq.Err.String() m["signatureValid"] = 0 m["errorMessage"] = errStr } conn.WriteHeader(http.StatusOK) // no HTTP response code fun, error info in JSON httputil.ReturnJson(conn, m) }
func handleTestForm(conn http.ResponseWriter, req *http.Request) { if !(req.Method == "POST" && req.URL.Path == "/camli/testform") { httputil.BadRequestError(conn, "Inconfigured handler.") return } multipart, err := req.MultipartReader() if multipart == nil { httputil.BadRequestError(conn, fmt.Sprintf("Expected multipart/form-data POST request; %v", err)) return } for { part, err := multipart.NextPart() if err != nil { fmt.Println("Error reading:", err) break } if part == nil { break } formName := part.FormName() fmt.Printf("New value [%s], part=%v\n", formName, part) sha1 := sha1.New() io.Copy(sha1, part) fmt.Printf("Got part digest: %x\n", sha1.Sum()) } fmt.Println("Done reading multipart body.") }
// tileHandler implements a tile renderer for use with the Google Maps JavaScript API. // See http://code.google.com/apis/maps/documentation/javascript/maptypes.html#ImageMapTypes func tileHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) x, _ := strconv.Atoi(r.FormValue("x")) y, _ := strconv.Atoi(r.FormValue("y")) z, _ := strconv.Atoi(r.FormValue("z")) w.Header().Set("Content-Type", "image/png") // Try memcache first. key := fmt.Sprintf("mandelbrot:%d/%d/%d", x, y, z) if z < maxMemcacheLevel { if item, err := memcache.Get(c, key); err == nil { w.Write(item.Value) return } } b := render(x, y, z) if z < maxMemcacheLevel { memcache.Set(c, &memcache.Item{ Key: key, Value: b, Expiration: 3600, // TTL = 1 hour }) } w.Header().Set("Content-Length", strconv.Itoa(len(b))) w.Write(b) }
func upload(req *http.Request) (*page, os.Error) { var p page p.template = "upload.html" p.html = make(map[string]interface{}) p.html["Body"] = "" // show upload form if no post if req.Method != "POST" { return &p, nil } f, fh, err := req.FormFile("upfile") if err != nil { return nil, err } else { file, err := os.Create(filesDir + "/" + fh.Filename) if err != nil { return nil, err } else { io.Copy(file, f) file.Close() p.html["Body"] = fh.Filename + " uploaded!" } f.Close() } return &p, nil }
func view(w http.ResponseWriter, r *http.Request) { id, _ := strconv.Atoi(r.FormValue("id")) c := appengine.NewContext(r) var view detail_view // グループ情報を取得 if group, err := model.GetGroup(c, id); err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } else { view.Group = group } // メンバー情報を取得 if memberlist, err := model.MemberList(c, id); err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } else { view.Member = memberlist } // 詳細画面を表示 if err := detailTemplate.Execute(w, view); err != nil { http.Error(w, err.String(), http.StatusInternalServerError) } }
func addWidget(w http.ResponseWriter, r *http.Request) { var err os.Error if fixup == nil { fixup, err = regexp.Compile(`[^A-Za-z0-9\-_. ]`) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } } ctx := appengine.NewContext(r) name := fixup.ReplaceAllString(r.FormValue("name"), "") if len(name) == 0 { http.Error(w, "Invalid/no name provided", http.StatusInternalServerError) return } widget := NewWidget(ctx, name) err = widget.Commit() if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } http.Redirect(w, r, "/widget/list", http.StatusFound) }