package webcontroller import ( "encoding/json" "errors" "fmt" "net/http" "net/url" "strings" "fornaxian.tech/log" "fornaxian.tech/nova_server/api" "fornaxian.tech/pixeldrain_api_client/pixelapi" "fornaxian.tech/util" "github.com/julienschmidt/httprouter" ) func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request, p httprouter.Params) { var td = wc.newTemplateData(r) var pdapi = wc.api.RealIP(util.RemoteAddress(r)).RealAgent(r.UserAgent()) // Prevent search engines from indexing this page for privacy reasons w.Header().Set("X-Robots-Tag", "noindex, nofollow") // The user and the node are embedded in the page so the JS doesn't have to // request them again. When a request fails the JS requests it again and // shows the error if apikey, err := wc.getAPIKey(r); err == nil { pdapi = pdapi.Login(apikey) _ = pdapi.GetJSON("user", &td.User) } else { td.User = json.RawMessage("null") } // A shared link can have the password of the directory in it var path = strings.TrimPrefix(p.ByName("path"), "/") var err = pdapi.GetJSON( "filesystem/"+url.PathEscape(path)+"?stat&password="+ url.QueryEscape(r.URL.Query().Get("password")), &td.Node, ) if apiErr, ok := errors.AsType[pixelapi.Error](err); ok { // Set the proper response code for the error message switch apiErr.StatusCode { case "not_found", "path_not_found": w.WriteHeader(http.StatusNotFound) case "forbidden", "permission_denied": w.WriteHeader(http.StatusForbidden) case "unavailable_for_legal_reasons": w.WriteHeader(http.StatusUnavailableForLegalReasons) case "authentication_required": http.Redirect(w, r, "/login", http.StatusSeeOther) return } } else if err != nil { log.Error("Failed to get path: %s", err) w.WriteHeader(http.StatusInternalServerError) } else { var node api.FilesystemPath if err = json.Unmarshal(td.Node, &node); err != nil { panic(fmt.Errorf("decode filesystem path: %w", err)) } td.Title = fmt.Sprintf("%s ~ Nova", node.Path[node.BaseIndex].Name) td.OGData = wc.metadataFromFilesystem(r, node) } wc.renderPage(w, r, td) }