diff --git a/main.go b/main.go index c50efbe..a7aee4f 100644 --- a/main.go +++ b/main.go @@ -79,7 +79,7 @@ func test() { []string{"https://lemmy.world/c/dude", "/lemmy.local/c/dude@lemmy.world", "/c/dude@lemmy.world"}, []string{"https://lemmy.world/u/dude", "/lemmy.local/u/dude@lemmy.world", "/u/dude@lemmy.world"}, []string{"https://lemmy.world/u/dude@lemmy.world", "/lemmy.local/u/dude@lemmy.world", "/u/dude@lemmy.world"}, - []string{"https://lemmy.world/post/123", "/lemmy.world/post/123", "https://lemmy.world/post/123"}, + []string{"https://lemmy.world/post/123", "/lemmy.local/post/123@lemmy.world", "/post/123@lemmy.world"}, []string{"/post/123", "/lemmy.local/post/123", "/post/123"}, []string{"/comment/123", "/lemmy.local/comment/123", "/comment/123"}, []string{"https://lemmy.local/comment/123", "/lemmy.local/comment/123", "/comment/123"}, @@ -88,7 +88,7 @@ func test() { output := LemmyLinkRewrite(`href="`+url[0]+`"`, "lemmy.local", "") success := (output == (`href="` + url[1] + `"`)) if !success { - fmt.Println("\n!!!! Link rewrite failure !!!!") + fmt.Println("\n!!!! multi instance link rewrite failure !!!!") fmt.Println(url) fmt.Println(output) fmt.Println("") @@ -96,6 +96,7 @@ func test() { output = LemmyLinkRewrite(`href="`+url[0]+`"`, ".", "lemmy.local") success = (output == (`href="` + url[2] + `"`)) if !success { + fmt.Println("\n!!!! single instance link rewrite failure !!!!") fmt.Println(success, url) fmt.Println(output) fmt.Println("") diff --git a/routes.go b/routes.go index 8ff74d1..7f690f1 100644 --- a/routes.go +++ b/routes.go @@ -167,21 +167,21 @@ func LemmyLinkRewrite(input string, host string, lemmy_domain string) (body stri // community bangs body = RegReplace(body, `!([a-zA-Z0-9]+)@([a-zA-Z0-9\.\-]+)([ \n\r]+|<\/p>)`, `!$1@$2 `) // localize community and user links - body = RegReplace(body, `href="https:\/\/([a-zA-Z0-9\.\-]+)\/((c|u)\/.*?)"`, `href="/$2@$1"`) + body = RegReplace(body, `href="https:\/\/([a-zA-Z0-9\.\-]+)\/((c|u|comment|post)\/.*?)"`, `href="/$2@$1"`) // remove extra instance tag body = RegReplace(body, `href="(https:\/)?(\/[a-zA-Z0-9\.\-]+)?\/((c|u)\/[a-zA-Z0-9]+@[a-zA-Z0-9\.\-]+)@([a-zA-Z0-9\.\-]+)"`, `href="/$3"`) if lemmy_domain == "" { // add domain to relative links - body = RegReplace(body, `href="\/(c\/[a-zA-Z0-9\-]+"|(post|comment)\/\d+"|(c|u)\/(.*?)")`, `href="/`+host+`/$1`) + body = RegReplace(body, `href="\/((c|u|post|comment)\/(.*?)")`, `href="/`+host+`/$1`) // convert links to relative - body = RegReplace(body, `href="https:\/\/([a-zA-Z0-9\.\-]+\/(c\/[a-zA-Z0-9]+"|(post|comment)\/\d+"|u\/(.*?)"))`, `href="/$1`) + body = RegReplace(body, `href="https:\/\/([a-zA-Z0-9\.\-]+\/((c|u|post|comment)\/[a-zA-Z0-9]+"))`, `href="/$1`) } else { // convert local links to relative - body = RegReplace(body, `href="https:\/\/`+lemmy_domain+`\/(c\/[a-zA-Z0-9]+"|(post|comment)\/\d+"|u\/(.*?)")`, `href="/$1`) + body = RegReplace(body, `href="https:\/\/`+lemmy_domain+`\/(c\/[a-zA-Z0-9]+"|(c|u|post|comment)\/(.*?)")`, `href="/$1`) body = RegReplace(body, `href="(.*)@`+lemmy_domain+`"`, `href="$1"`) } // remove redundant instance tag - re := regexp.MustCompile(`href="\/([a-zA-Z0-9\.\-]+)\/(c|u)\/(.*?)@(.*?)"`) + re := regexp.MustCompile(`href="\/([a-zA-Z0-9\.\-]+)\/(c|u|post|comment)\/(.*?)@(.*?)"`) matches := re.FindAllStringSubmatch(body, -1) for _, match := range matches { if match[1] == match[4] { @@ -416,12 +416,67 @@ func GetFrontpage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) } } +func ResolveId(r *http.Request, class string, id string, host string) string { + remoteAddr := r.RemoteAddr + if r.Header.Get("CF-Connecting-IP") != "" { + remoteAddr = r.Header.Get("CF-Connecting-IP") + } + client := http.Client{Transport: NewAddHeaderTransport(remoteAddr)} + c, err := lemmy.NewWithClient("https://"+host, &client) + if err != nil { + return "" + } + idn, _ := strconv.Atoi(id) + if class == "post" { + resp, err := c.Post(context.Background(), types.GetPost{ + ID: types.NewOptional(idn), + }) + if err != nil { + return "" + } + return resp.PostView.Post.ApID + } + resp, err := c.Comment(context.Background(), types.GetComment{ + ID: idn, + }) + if err != nil { + return "" + } + return resp.CommentView.Comment.ApID +} + func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { state, err := Initialize(ps.ByName("host"), r) if err != nil { Render(w, "index.html", state) return } + if path := strings.Split(ps.ByName("postid"), "@"); len(path) > 1 { + apid := ResolveId(r, "post", path[0], path[1]) + if apid != "" { + resp, err := state.Client.ResolveObject(context.Background(), types.ResolveObject{ + Q: apid, + }) + if err != nil { + dest := apid + if os.Getenv("LEMMY_DOMAIN") == "" { + dest = RegReplace(dest, `https:\/\/([a-zA-Z0-9\.\-]+\/post\/\d+)`, `/$1`) + } + http.Redirect(w, r, dest, 302) + return + } + post, _ := resp.Post.Value() + if post.Post.ID > 0 { + dest := RegReplace(r.URL.String(), `(([a-zA-Z0-9\.\-]+)?/post/)([a-zA-Z0-9\-\.@]+)`, `$1`) + dest += strconv.Itoa(post.Post.ID) + http.Redirect(w, r, dest, 302) + return + } else { + http.Redirect(w, r, apid, 302) + return + } + } + } m, _ := url.ParseQuery(r.URL.RawQuery) if len(m["edit"]) > 0 { state.Op = "edit_post" @@ -438,6 +493,32 @@ func GetComment(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { Render(w, "index.html", state) return } + if path := strings.Split(ps.ByName("commentid"), "@"); len(path) > 1 { + apid := ResolveId(r, "comment", path[0], path[1]) + if apid != "" { + resp, err := state.Client.ResolveObject(context.Background(), types.ResolveObject{ + Q: apid, + }) + if err != nil { + dest := apid + if os.Getenv("LEMMY_DOMAIN") == "" { + dest = RegReplace(dest, `https:\/\/([a-zA-Z0-9\.\-]+\/comment\/\d+)`, `/$1`) + } + http.Redirect(w, r, dest, 302) + return + } + comment, _ := resp.Comment.Value() + if comment.Comment.ID > 0 { + dest := RegReplace(r.URL.String(), `(([a-zA-Z0-9\.\-]+)?/comment/)([a-zA-Z0-9\-\.@]+)`, `$1`) + dest += strconv.Itoa(comment.Comment.ID) + http.Redirect(w, r, dest, 302) + return + } else { + http.Redirect(w, r, apid, 302) + return + } + } + } m, _ := url.ParseQuery(r.URL.RawQuery) if len(m["reply"]) > 0 { state.Op = "reply" diff --git a/state.go b/state.go index ed3ad28..cdaa921 100644 --- a/state.go +++ b/state.go @@ -596,22 +596,22 @@ func (state *State) GetPost(postid int) { }) if err != nil { state.Status = http.StatusInternalServerError + state.Error = err return - } else { - state.Posts = []Post{Post{ - PostView: resp.PostView, - State: state, - }} - if state.CommentID > 0 && len(state.Posts) > 0 { - state.Posts[0].Rank = -1 - } - state.CommunityName = resp.PostView.Community.Name - cresp := types.GetCommunityResponse{ - CommunityView: resp.CommunityView, - Moderators: resp.Moderators, - } - state.Community = &cresp } + state.Posts = []Post{Post{ + PostView: resp.PostView, + State: state, + }} + if state.CommentID > 0 && len(state.Posts) > 0 { + state.Posts[0].Rank = -1 + } + state.CommunityName = resp.PostView.Community.Name + cresp := types.GetCommunityResponse{ + CommunityView: resp.CommunityView, + Moderators: resp.Moderators, + } + state.Community = &cresp } func (state *State) GetCommunity(communityName string) {