func (s *Server) discoverHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if util.HandleCORS(w, r) { return } endpoints, err := s.discover(strings.ToLower(mux.Vars(r)["service"]), r) if err != nil { s.opts.Log.Error("%s: discover failed for %s (%s): %s", r.RemoteAddr, r.Host, r.URL, err) http.Error(w, err.Error(), http.StatusBadRequest) return } p, err := json.Marshal(endpoints) if err != nil { s.opts.Log.Error("%s: discover failed for %s (%s): %s", r.RemoteAddr, r.Host, r.URL, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Length", strconv.Itoa(len(p))) w.Header().Set("Content-Type", "application/json") w.Write(p) } }
func (p *Proxy) serveConn(conn net.Conn) { req, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { p.Log.Error("%s: error reading initial request: %s", conn.RemoteAddr(), err) conn.Close() return } rec := httptest.NewRecorder() if util.HandleCORS(rec, req) { resp := &http.Response{ Status: http.StatusText(rec.Code), StatusCode: rec.Code, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Header: rec.HeaderMap, Close: true, } if rec.Body != nil { resp.Body = ioutil.NopCloser(rec.Body) resp.ContentLength = int64(rec.Body.Len()) } if err := resp.Write(conn); err != nil { p.Log.Error("%s: error writing CORS reply: %s", conn.RemoteAddr(), err) } conn.Close() return } target, err := net.DialTimeout("tcp", p.targetAddr, 30*time.Second) if err != nil { p.writeError("dialing target", err, conn) conn.Close() return } if err = req.Write(target); err != nil { p.writeError("writing initial request to target", err, conn) nonil(target.Close(), conn.Close()) return } go io.Copy(conn, target) go io.Copy(target, conn) }