// NewFileServer returns a server that serves files.
NewFileServer returns a server that serves files.
// NewFileServer returns a server that serves files .
func (f *HTTPServerFactory) NewFileServer(rootRelativePath string) (net.Listener, *http.Server, error) {
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return nil, nil, err
	}
	mux := &http.ServeMux{}
	mux.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodGet {
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}
		path := r.URL.Query()["path"][0]
		file, err := os.Open(path)
		if err != nil {
			panic(fmt.Errorf("error opening requested file: %w", err))
		}
		defer file.Close()
		w.WriteHeader(http.StatusOK)
		if _, err := io.Copy(w, file); err != nil {
			panic(fmt.Errorf("error copying requested file: %w", err))
		}
	})
	mux.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet:
			port := listener.Addr().(*net.TCPAddr).Port
			path := filepath.Join(rootRelativePath, r.Header.Get(file.FileUploadNameHeader))
			uploadInfo := &struct {
				Method, URL string
				Headers     http.Header
			}{
				Method: http.MethodPut,
				URL:    fmt.Sprintf("http://localhost:%d/upload?path=%s", port, path),
			}
			payload, err := json.Marshal(uploadInfo)
			if err != nil {
				panic(fmt.Errorf("error marshaling file server upload info response: %w", err))
			}
			if _, err := w.Write(payload); err != nil {
				panic(fmt.Errorf("error writing file server upload info response: %w", err))
			}
		case http.MethodPut:
			file, err := os.Create(r.URL.Query()["path"][0])
			if err != nil {
				panic(fmt.Errorf("error creating file for upload in file server: %w", err))
			}
			defer file.Close()
			if _, err := io.Copy(file, r.Body); err != nil {
				panic(fmt.Errorf("error copying uploaded file for file server: %w", err))
			}
			w.WriteHeader(http.StatusOK)
		default:
			w.WriteHeader(http.StatusMethodNotAllowed)
		}
	})
	server := &http.Server{
		Handler: mux,
	}
	go f.serveAndPanicOnError(server, listener, "dummy")
	return listener, server, nil
}
func ( f * HTTPServerFactory ) NewFileServer ( rootRelativePath string ) ( net . Listener , * http . Server , error ) { listener , err := net . Listen ( " " , " " ) if err != nil { return nil , nil , err } mux := & http . ServeMux { } mux . HandleFunc ( " " , func ( w http . ResponseWriter , r * http . Request ) { if r . Method != http . MethodGet { w . WriteHeader ( http . StatusMethodNotAllowed ) return } path := r . URL . Query ( ) [ " " ] [ 0 ] file , err := os . Open ( path ) if err != nil { panic ( fmt . Errorf ( " " , err ) ) } defer file . Close ( ) w . WriteHeader ( http . StatusOK ) if _ , err := io . Copy ( w , file ) ; err != nil { panic ( fmt . Errorf ( " " , err ) ) } } ) mux . HandleFunc ( " " , func ( w http . ResponseWriter , r * http . Request ) { switch r . Method { case http . MethodGet : port := listener . Addr ( ) . ( * net . TCPAddr ) . Port path := filepath . Join ( rootRelativePath , r . Header . Get ( file . FileUploadNameHeader ) ) uploadInfo := & struct { Method , URL string Headers http . Header } { Method : http . MethodPut , URL : fmt . Sprintf ( " " , port , path ) , } payload , err := json . Marshal ( uploadInfo ) if err != nil { panic ( fmt . Errorf ( " " , err ) ) } if _ , err := w . Write ( payload ) ; err != nil { panic ( fmt . Errorf ( " " , err ) ) } case http . MethodPut : file , err := os . Create ( r . URL . Query ( ) [ " " ] [ 0 ] ) if err != nil { panic ( fmt . Errorf ( " " , err ) ) } defer file . Close ( ) if _ , err := io . Copy ( file , r . Body ) ; err != nil { panic ( fmt . Errorf ( " " , err ) ) } w . WriteHeader ( http . StatusOK ) default : w . WriteHeader ( http . StatusMethodNotAllowed ) } } ) server := & http . Server { Handler : mux , } go f . serveAndPanicOnError ( server , listener , " " ) return listener , server , nil }
NewFileServer returns a server that serves files.
NewFileServer returns a server that serves files .
// create listener at a random port // create server and mux