in sessions/sessions.go [313:456]
func Handler(localBackend *backends.Backend, remoteBackend *backends.Backend) http.Handler {
// Sessions and kernels within the session map are in their backend form
sessions := newCollection(localBackend, remoteBackend)
go func() {
for {
if err := sessions.Update(); err != nil {
log.Printf("Failure updating the sessions list: %v", err)
}
time.Sleep(30 * time.Second)
}
}()
getMethod := func(w http.ResponseWriter, r *http.Request) {
sessionID := strings.TrimPrefix(r.URL.Path, APIPath+"/")
sess, ok := sessions.Get(sessionID)
if !ok {
http.NotFound(w, r)
return
}
resp, err := json.Marshal(&sess)
if err != nil {
util.Log(r, fmt.Sprintf("Failure marshalling the session response: %v", err))
http.Error(w, "failure marshalling the session", util.HTTPStatusCode(err))
return
}
w.Write(resp)
}
listMethod := func(w http.ResponseWriter, r *http.Request) {
resp, err := json.Marshal(sessions.List())
if err != nil {
util.Log(r, fmt.Sprintf("Failure marshalling the list sessions response: %v", err))
http.Error(w, "failure marshalling the list of sessions", util.HTTPStatusCode(err))
return
}
w.Write(resp)
}
insertMethod := func(w http.ResponseWriter, r *http.Request) {
reqBytes, err := ioutil.ReadAll(r.Body)
r.Body.Close()
if err != nil {
errorMsg := fmt.Sprintf("failure reading the request body: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, util.HTTPStatusCode(err))
return
}
var sess resources.Session
if err := json.Unmarshal(reqBytes, &sess); err != nil {
errorMsg := fmt.Sprintf("failure parsing the request body: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, util.HTTPStatusCode(err))
return
}
util.Log(r, fmt.Sprintf("Creating a new kernel for the session: %q", string(reqBytes)))
newSession, err := sessions.Insert("", &sess)
if err != nil {
util.Log(r, err)
http.Error(w, err.Error(), util.HTTPStatusCode(err))
return
}
respBytes, err := json.Marshal(newSession)
if err != nil {
errorMsg := fmt.Sprintf("failure marshalling session response: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, util.HTTPStatusCode(err))
return
}
w.WriteHeader(http.StatusCreated)
w.Write(respBytes)
}
deleteMethod := func(w http.ResponseWriter, r *http.Request) {
sessionID := strings.TrimPrefix(r.URL.Path, APIPath+"/")
if ok := sessions.Delete(sessionID); !ok {
http.NotFound(w, r)
return
}
w.WriteHeader(http.StatusNoContent)
}
patchMethod := func(w http.ResponseWriter, r *http.Request) {
subPath := strings.TrimPrefix(r.URL.Path, APIPath+"/")
sessionID := strings.Split(subPath, "/")[0]
reqBytes, err := ioutil.ReadAll(r.Body)
r.Body.Close()
if err != nil {
errorMsg := fmt.Sprintf("failure reading the request body: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, util.HTTPStatusCode(err))
return
}
var sess resources.Session
if err := json.Unmarshal(reqBytes, &sess); err != nil {
errorMsg := fmt.Sprintf("failure parsing the request body: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, http.StatusBadRequest)
return
}
updatedSession, err := sessions.Patch(r, sessionID, &sess)
if err != nil {
errorMsg := fmt.Sprintf("failure patching the session: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, util.HTTPStatusCode(err))
return
}
respBytes, err := json.Marshal(updatedSession)
if err != nil {
errorMsg := fmt.Sprintf("failure marshalling the return session: %v", err)
util.Log(r, errorMsg)
http.Error(w, errorMsg, util.HTTPStatusCode(err))
return
}
util.Log(r, fmt.Sprintf("Updated session: %q\n", string(respBytes)))
w.WriteHeader(http.StatusOK)
w.Write(respBytes)
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
if r.URL.Path == APIPath {
listMethod(w, r)
} else {
getMethod(w, r)
}
return
}
if r.URL.Path == APIPath {
if r.Method != http.MethodPost {
errorMsg := fmt.Sprintf("unsupported method %q", r.Method)
util.Log(r, errorMsg)
http.Error(w, errorMsg, http.StatusMethodNotAllowed)
return
}
insertMethod(w, r)
return
}
if r.Method == http.MethodDelete {
deleteMethod(w, r)
return
}
if r.Method == http.MethodPut || r.Method == http.MethodPatch {
patchMethod(w, r)
return
}
errorMsg := fmt.Sprintf("unsupported method %q", r.Method)
util.Log(r, errorMsg)
http.Error(w, errorMsg, http.StatusMethodNotAllowed)
})
}