1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge branch 'feature/attach_ws' into feature/attach_ws2

Conflicts:
	api.go
This commit is contained in:
benoitc 2013-08-07 23:30:28 +02:00
commit e2ca600fd8

149
api.go
View file

@ -1,6 +1,7 @@
package docker package docker
import ( import (
"code.google.com/p/go.net/websocket"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/dotcloud/docker/auth" "github.com/dotcloud/docker/auth"
@ -22,6 +23,8 @@ const APIVERSION = 1.4
const DEFAULTHTTPHOST string = "127.0.0.1" const DEFAULTHTTPHOST string = "127.0.0.1"
const DEFAULTHTTPPORT int = 4243 const DEFAULTHTTPPORT int = 4243
type HttpApiFunc func(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) { func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
conn, _, err := w.(http.Hijacker).Hijack() conn, _, err := w.(http.Hijacker).Hijack()
if err != nil { if err != nil {
@ -741,6 +744,53 @@ func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r
return nil return nil
} }
func wsContainersAttach(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
logs, err := getBoolParam(r.Form.Get("logs"))
if err != nil {
return err
}
stream, err := getBoolParam(r.Form.Get("stream"))
if err != nil {
return err
}
stdin, err := getBoolParam(r.Form.Get("stdin"))
if err != nil {
return err
}
stdout, err := getBoolParam(r.Form.Get("stdout"))
if err != nil {
return err
}
stderr, err := getBoolParam(r.Form.Get("stderr"))
if err != nil {
return err
}
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if _, err := srv.ContainerInspect(name); err != nil {
return err
}
h := websocket.Handler(func(ws *websocket.Conn) {
defer ws.Close()
if err := srv.ContainerAttach(name, logs, stream, stdin, stdout, stderr, ws, ws); err != nil {
utils.Debugf("Error: %s", err)
}
})
h.ServeHTTP(w, r)
return nil
}
func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil { if vars == nil {
return fmt.Errorf("Missing parameter") return fmt.Errorf("Missing parameter")
@ -911,25 +961,61 @@ func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS") w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
} }
func makeHttpHandler(srv *Server, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// log the request
utils.Debugf("Calling %s %s", localMethod, localRoute)
if logging {
log.Println(r.Method, r.RequestURI)
}
if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") {
userAgent := strings.Split(r.Header.Get("User-Agent"), "/")
if len(userAgent) == 2 && userAgent[1] != VERSION {
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], VERSION)
}
}
version, err := strconv.ParseFloat(mux.Vars(r)["version"], 64)
if err != nil {
version = APIVERSION
}
if srv.enableCors {
writeCorsHeaders(w, r)
}
if version == 0 || version > APIVERSION {
w.WriteHeader(http.StatusNotFound)
return
}
if err := handlerFunc(srv, version, w, r, mux.Vars(r)); err != nil {
utils.Debugf("Error: %s", err)
httpError(w, err)
}
}
}
func createRouter(srv *Server, logging bool) (*mux.Router, error) { func createRouter(srv *Server, logging bool) (*mux.Router, error) {
r := mux.NewRouter() r := mux.NewRouter()
m := map[string]map[string]func(*Server, float64, http.ResponseWriter, *http.Request, map[string]string) error{ m := map[string]map[string]HttpApiFunc{
"GET": { "GET": {
"/events": getEvents, "/events": getEvents,
"/info": getInfo, "/info": getInfo,
"/version": getVersion, "/version": getVersion,
"/images/json": getImagesJSON, "/images/json": getImagesJSON,
"/images/viz": getImagesViz, "/images/viz": getImagesViz,
"/images/search": getImagesSearch, "/images/search": getImagesSearch,
"/images/{name:.*}/history": getImagesHistory, "/images/{name:.*}/history": getImagesHistory,
"/images/{name:.*}/json": getImagesByName, "/images/{name:.*}/json": getImagesByName,
"/containers/ps": getContainersJSON, "/containers/ps": getContainersJSON,
"/containers/json": getContainersJSON, "/containers/json": getContainersJSON,
"/containers/{name:.*}/export": getContainersExport, "/containers/{name:.*}/export": getContainersExport,
"/containers/{name:.*}/changes": getContainersChanges, "/containers/{name:.*}/changes": getContainersChanges,
"/containers/{name:.*}/json": getContainersByName, "/containers/{name:.*}/json": getContainersByName,
"/containers/{name:.*}/top": getContainersTop, "/containers/{name:.*}/top": getContainersTop,
"/containers/{name:.*}/attach/ws": wsContainersAttach,
}, },
"POST": { "POST": {
"/auth": postAuth, "/auth": postAuth,
@ -964,37 +1050,13 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) {
utils.Debugf("Registering %s, %s", method, route) utils.Debugf("Registering %s, %s", method, route)
// NOTE: scope issue, make sure the variables are local and won't be changed // NOTE: scope issue, make sure the variables are local and won't be changed
localRoute := route localRoute := route
localMethod := method
localFct := fct localFct := fct
f := func(w http.ResponseWriter, r *http.Request) { localMethod := method
utils.Debugf("Calling %s %s from %s", localMethod, localRoute, r.RemoteAddr)
if logging { // build the handler function
log.Println(r.Method, r.RequestURI) f := makeHttpHandler(srv, logging, localMethod, localRoute, localFct)
}
if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") {
userAgent := strings.Split(r.Header.Get("User-Agent"), "/")
if len(userAgent) == 2 && userAgent[1] != VERSION {
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], VERSION)
}
}
version, err := strconv.ParseFloat(mux.Vars(r)["version"], 64)
if err != nil {
version = APIVERSION
}
if srv.enableCors {
writeCorsHeaders(w, r)
}
if version == 0 || version > APIVERSION {
w.WriteHeader(http.StatusNotFound)
return
}
if err := localFct(srv, version, w, r, mux.Vars(r)); err != nil {
httpError(w, err)
}
}
// add the new route
if localRoute == "" { if localRoute == "" {
r.Methods(localMethod).HandlerFunc(f) r.Methods(localMethod).HandlerFunc(f)
} else { } else {
@ -1003,6 +1065,7 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) {
} }
} }
} }
return r, nil return r, nil
} }