func handleOpen(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) userid, sessionid, err := getSession(c, r) if err != nil { sendError(w, r, "No session cookie") return } // Read the request body jreq, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Error reading request body", http.StatusInternalServerError) return } r.Body.Close() // Parse request var req openCloseRequest err = json.Unmarshal(jreq, &req) if err != nil { sendError(w, r, "Malformed JSON") return } // Load the channel infos var ch channelStruct if err = datastore.Get(c, datastore.NewKey("channel", userid+"/"+sessionid, 0, nil), &ch); err != nil { sendError(w, r, "Unknown channel: "+userid+"/"+sessionid) return } // Check if len(ch.OpenPermas) >= 10 { sendError(w, r, "Too many open channels") return } is_open := false for _, p := range ch.OpenPermas { if p == req.Perma { is_open = true break } } var perma grapher.PermaNode if !is_open { // Update channel infos ch.OpenPermas = append(ch.OpenPermas, req.Perma) _, err = datastore.Put(c, datastore.NewKey("channel", userid+"/"+sessionid, 0, nil), &ch) if err != nil { sendError(w, r, "Internal server error") return } // Repeat all blobs from this document. s := newStore(c) g := grapher.NewGrapher(userid, schema, s, s, nil) s.SetGrapher(g) ch := newChannelAPI(c, s, userid, sessionid, true, g) perma, err = g.Repeat(req.Perma, req.From) if err != nil { sendError(w, r, "Failed opening") return } fmt.Fprintf(w, `{"ok":true, "blobs":[%v]}`, strings.Join(ch.messageBuffer, ",")) } else { fmt.Fprint(w, `{"ok":true, "blobs":[]}`) } if req.MarkAsRead { if perma == nil { s := newStore(c) data, err := s.GetPermaNode(req.Perma) if err != nil { log.Printf("Err: Failed reading permanode") return } perma = grapher.NewPermaNode(nil) perma.FromMap(req.Perma, data) } markAsRead(c, userid, perma.BlobRef(), perma.SequenceNumber()-1) } }