github.com/raychaser/docker@v1.5.0/engine/http.go (about) 1 package engine 2 3 import ( 4 "net/http" 5 "path" 6 ) 7 8 // ServeHTTP executes a job as specified by the http request `r`, and sends the 9 // result as an http response. 10 // This method allows an Engine instance to be passed as a standard http.Handler interface. 11 // 12 // Note that the protocol used in this method is a convenience wrapper and is not the canonical 13 // implementation of remote job execution. This is because HTTP/1 does not handle stream multiplexing, 14 // and so cannot differentiate stdout from stderr. Additionally, headers cannot be added to a response 15 // once data has been written to the body, which makes it inconvenient to return metadata such 16 // as the exit status. 17 // 18 func (eng *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) { 19 var ( 20 jobName = path.Base(r.URL.Path) 21 jobArgs, exists = r.URL.Query()["a"] 22 ) 23 if !exists { 24 jobArgs = []string{} 25 } 26 w.Header().Set("Job-Name", jobName) 27 for _, arg := range jobArgs { 28 w.Header().Add("Job-Args", arg) 29 } 30 job := eng.Job(jobName, jobArgs...) 31 job.Stdout.Add(w) 32 job.Stderr.Add(w) 33 // FIXME: distinguish job status from engine error in Run() 34 // The former should be passed as a special header, the former 35 // should cause a 500 status 36 w.WriteHeader(http.StatusOK) 37 // The exit status cannot be sent reliably with HTTP1, because headers 38 // can only be sent before the body. 39 // (we could possibly use http footers via chunked encoding, but I couldn't find 40 // how to use them in net/http) 41 job.Run() 42 }