add request util to properly use flareresolver
Some checks failed
Build and publish the docker image / build (push) Failing after 1m22s
Some checks failed
Build and publish the docker image / build (push) Failing after 1m22s
Signed-off-by: ngn <ngn@ngn.tf>
This commit is contained in:
parent
4e8606c44a
commit
2f160a8649
@ -2,6 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"anonymousoverflow/config"
|
||||
"anonymousoverflow/src/utils"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -45,9 +46,8 @@ func Ratelimit() gin.HandlerFunc {
|
||||
|
||||
// if they exceed 30 requests in 1 minute, return a 429
|
||||
if val.(int) > 30 {
|
||||
c.HTML(429, "home.html", gin.H{
|
||||
utils.Render(c, 429, "home", gin.H{
|
||||
"errorMessage": "You have exceeded the request limit. Please try again in a minute.",
|
||||
"version": config.Version,
|
||||
})
|
||||
c.Abort()
|
||||
return
|
||||
|
@ -1,7 +1,6 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"anonymousoverflow/config"
|
||||
"anonymousoverflow/src/utils"
|
||||
"fmt"
|
||||
"regexp"
|
||||
@ -11,11 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func GetHome(c *gin.Context) {
|
||||
theme := utils.GetThemeFromEnv()
|
||||
c.HTML(200, "home.html", gin.H{
|
||||
"version": config.Version,
|
||||
"theme": theme,
|
||||
})
|
||||
utils.Render(c, 200, "home", nil)
|
||||
}
|
||||
|
||||
type urlConversionRequest struct {
|
||||
@ -62,7 +57,7 @@ func PostHome(c *gin.Context) {
|
||||
body := urlConversionRequest{}
|
||||
|
||||
if err := c.ShouldBind(&body); err != nil {
|
||||
c.HTML(400, "home.html", gin.H{
|
||||
utils.Render(c, 400, "home", gin.H{
|
||||
"errorMessage": "Invalid request body",
|
||||
})
|
||||
return
|
||||
@ -71,10 +66,8 @@ func PostHome(c *gin.Context) {
|
||||
translated := translateUrl(body.URL)
|
||||
|
||||
if translated == "" {
|
||||
theme := utils.GetThemeFromEnv()
|
||||
c.HTML(400, "home.html", gin.H{
|
||||
utils.Render(c, 400, "home", gin.H{
|
||||
"errorMessage": "Invalid stack overflow/exchange URL",
|
||||
"theme": theme,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package routes
|
||||
|
||||
import (
|
||||
"anonymousoverflow/src/types"
|
||||
"anonymousoverflow/src/utils"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
@ -51,33 +51,15 @@ func GetImage(c *gin.Context) {
|
||||
}
|
||||
|
||||
// download the image
|
||||
var resp *resty.Response = nil
|
||||
client := resty.New()
|
||||
|
||||
if flareurl := os.Getenv("FLARERESOLVER"); flareurl == "" {
|
||||
resp, err = client.R().Get(claims.ImageURL)
|
||||
} else {
|
||||
client.R().SetHeader("Content-Type", "application/json")
|
||||
client.R().SetBody(struct {
|
||||
Cmd string `json:"cmd"`
|
||||
Url string `json:"url"`
|
||||
MaxTimeout int `json:"maxTimeout"`
|
||||
}{
|
||||
Cmd: "request.get",
|
||||
Url: claims.ImageURL,
|
||||
MaxTimeout: 60000,
|
||||
})
|
||||
resp, err = client.R().Post(claims.ImageURL)
|
||||
}
|
||||
|
||||
body, _, headers, err := utils.GET(claims.ImageURL)
|
||||
if err != nil {
|
||||
c.AbortWithStatus(500)
|
||||
return
|
||||
}
|
||||
|
||||
// set the content type
|
||||
c.Header("Content-Type", resp.Header().Get("Content-Type"))
|
||||
c.Header("Content-Type", headers.Get("Content-Type"))
|
||||
|
||||
// write the image to the response
|
||||
c.Writer.Write(resp.Body())
|
||||
c.Writer.Write(body)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"anonymousoverflow/config"
|
||||
"anonymousoverflow/src/utils"
|
||||
"fmt"
|
||||
|
||||
@ -14,16 +13,16 @@ func ChangeOptions(c *gin.Context) {
|
||||
switch name {
|
||||
case "images":
|
||||
text := "disabled"
|
||||
|
||||
if c.MustGet("disable_images").(bool) {
|
||||
text = "enabled"
|
||||
}
|
||||
|
||||
c.SetCookie("disable_images", fmt.Sprintf("%t", !c.MustGet("disable_images").(bool)), 60*60*24*365*10, "/", "", false, true)
|
||||
theme := utils.GetThemeFromEnv()
|
||||
c.HTML(200, "home.html", gin.H{
|
||||
utils.Render(c, 200, "home", gin.H{
|
||||
"successMessage": "Images are now " + text,
|
||||
"version": config.Version,
|
||||
"theme": theme,
|
||||
})
|
||||
|
||||
default:
|
||||
c.String(400, "400 Bad Request")
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package routes
|
||||
import (
|
||||
"anonymousoverflow/config"
|
||||
"anonymousoverflow/src/utils"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
@ -15,7 +16,6 @@ import (
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
var codeBlockRegex = regexp.MustCompile(`(?s)<pre><code>(.+?)<\/code><\/pre>`)
|
||||
@ -32,7 +32,7 @@ func ViewQuestion(c *gin.Context) {
|
||||
|
||||
questionId := c.Param("id")
|
||||
if _, err := strconv.Atoi(questionId); err != nil {
|
||||
c.HTML(400, "home.html", gin.H{
|
||||
utils.Render(c, 400, "home", gin.H{
|
||||
"errorMessage": "Invalid question ID",
|
||||
"version": config.Version,
|
||||
})
|
||||
@ -53,44 +53,37 @@ func ViewQuestion(c *gin.Context) {
|
||||
}
|
||||
|
||||
soLink := fmt.Sprintf("https://%s/questions/%s/%s?answertab=%s", domain, questionId, params.QuestionTitle, params.SoSortValue)
|
||||
body, code, _, err := utils.GET(soLink)
|
||||
|
||||
resp, err := fetchQuestionData(soLink)
|
||||
|
||||
if resp.StatusCode() != 200 {
|
||||
c.HTML(500, "home.html", gin.H{
|
||||
"errorMessage": fmt.Sprintf("Received a non-OK status code %d", resp.StatusCode()),
|
||||
"version": config.Version,
|
||||
if code != 200 {
|
||||
utils.Render(c, 500, "home", gin.H{
|
||||
"errorMessage": fmt.Sprintf("Received a non-OK status code %d", code),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
respBody := resp.String()
|
||||
|
||||
respBodyReader := strings.NewReader(respBody)
|
||||
respBodyReader := bytes.NewReader(body)
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(respBodyReader)
|
||||
if err != nil {
|
||||
c.HTML(500, "home.html", gin.H{
|
||||
utils.Render(c, 500, "home", gin.H{
|
||||
"errorMessage": "Unable to parse question data",
|
||||
"version": config.Version,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
newFilteredQuestion, err := extractQuestionData(doc, domain)
|
||||
if err != nil {
|
||||
c.HTML(500, "home.html", gin.H{
|
||||
utils.Render(c, 500, "home", gin.H{
|
||||
"errorMessage": "Failed to extract question data",
|
||||
"version": config.Version,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
answers, err := extractAnswersData(doc, domain)
|
||||
if err != nil {
|
||||
c.HTML(500, "home.html", gin.H{
|
||||
utils.Render(c, 500, "home", gin.H{
|
||||
"errorMessage": "Failed to extract answer data",
|
||||
"version": config.Version,
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -101,18 +94,14 @@ func ViewQuestion(c *gin.Context) {
|
||||
imagePolicy = "'self'"
|
||||
}
|
||||
|
||||
theme := utils.GetThemeFromEnv()
|
||||
|
||||
c.HTML(200, "question.html", gin.H{
|
||||
utils.Render(c, 200, "question", gin.H{
|
||||
"question": newFilteredQuestion,
|
||||
"answers": answers,
|
||||
"imagePolicy": imagePolicy,
|
||||
"currentUrl": fmt.Sprintf("%s%s", os.Getenv("APP_URL"), c.Request.URL.Path),
|
||||
"sortValue": params.SoSortValue,
|
||||
"domain": domain,
|
||||
"theme": theme,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
type viewQuestionInputs struct {
|
||||
@ -127,9 +116,8 @@ func parseAndValidateParameters(c *gin.Context) (inputs viewQuestionInputs, err
|
||||
|
||||
questionId := c.Param("id")
|
||||
if _, err = strconv.Atoi(questionId); err != nil {
|
||||
c.HTML(400, "home.html", gin.H{
|
||||
utils.Render(c, 400, "home", gin.H{
|
||||
"errorMessage": "Invalid question ID",
|
||||
"version": config.Version,
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -155,29 +143,6 @@ func parseAndValidateParameters(c *gin.Context) (inputs viewQuestionInputs, err
|
||||
return
|
||||
}
|
||||
|
||||
// fetchQuestionData sends the request to StackOverflow.
|
||||
func fetchQuestionData(soLink string) (*resty.Response, error) {
|
||||
flareurl := ""
|
||||
client := resty.New()
|
||||
|
||||
if flareurl = os.Getenv("FLARERESOLVER"); flareurl == "" {
|
||||
return client.R().Get(soLink)
|
||||
}
|
||||
|
||||
client.R().SetHeader("Content-Type", "application/json")
|
||||
client.R().SetBody(struct {
|
||||
Cmd string `json:"cmd"`
|
||||
Url string `json:"url"`
|
||||
MaxTimeout int `json:"maxTimeout"`
|
||||
}{
|
||||
Cmd: "request.get",
|
||||
Url: soLink,
|
||||
MaxTimeout: 60000,
|
||||
})
|
||||
|
||||
return client.R().Post(flareurl)
|
||||
}
|
||||
|
||||
// extractQuestionData parses the HTML document and extracts question data.
|
||||
func extractQuestionData(doc *goquery.Document, domain string) (question types.FilteredQuestion, err error) {
|
||||
// Extract the question title.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"anonymousoverflow/src/utils"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -31,14 +32,14 @@ func RedirectShortenedOverflowURL(c *gin.Context) {
|
||||
}
|
||||
resp, err := client.R().Get(fmt.Sprintf("https://%s/a/%s/%s", domain, id, answerId))
|
||||
if err != nil {
|
||||
c.HTML(400, "home.html", gin.H{
|
||||
utils.Render(c, 400, "home", gin.H{
|
||||
"errorMessage": "Unable to fetch stack overflow URL",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if resp.StatusCode() != 302 {
|
||||
c.HTML(400, "home.html", gin.H{
|
||||
utils.Render(c, 400, "home", gin.H{
|
||||
"errorMessage": fmt.Sprintf("Unexpected HTTP status from origin: %d", resp.StatusCode()),
|
||||
})
|
||||
return
|
||||
|
24
src/utils/render.go
Normal file
24
src/utils/render.go
Normal file
@ -0,0 +1,24 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"anonymousoverflow/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Render(c *gin.Context, code int, temp string, _data ...gin.H) {
|
||||
var data gin.H = nil
|
||||
|
||||
if len(_data) > 0 {
|
||||
data = _data[0]
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
data = gin.H{}
|
||||
}
|
||||
|
||||
data["version"] = config.Version
|
||||
data["theme"] = GetThemeFromEnv()
|
||||
|
||||
c.HTML(code, temp+".html", data)
|
||||
}
|
63
src/utils/request.go
Normal file
63
src/utils/request.go
Normal file
@ -0,0 +1,63 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
// https://github.com/FlareSolverr/FlareSolverr#-requestget
|
||||
type request struct {
|
||||
Cmd string `json:"cmd"`
|
||||
Url string `json:"url"`
|
||||
MaxTimeout int `json:"maxTimeout"`
|
||||
}
|
||||
|
||||
type solution struct {
|
||||
Status int `json:"status"`
|
||||
Response []byte `json:"response"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Solution solution `json:"solution"`
|
||||
}
|
||||
|
||||
func GET(url string) ([]byte, int, http.Header, error) {
|
||||
var (
|
||||
client *resty.Client = resty.New()
|
||||
res *resty.Response = nil
|
||||
frurl string = ""
|
||||
err error
|
||||
)
|
||||
|
||||
if frurl = os.Getenv("FLARERESOLVER"); frurl == "" {
|
||||
if res, err := client.R().Get(url); err != nil {
|
||||
return nil, 0, nil, err
|
||||
} else {
|
||||
return res.Body(), res.StatusCode(), res.Header(), nil
|
||||
}
|
||||
}
|
||||
|
||||
client.R().SetHeader("Content-Type", "application/json")
|
||||
client.R().SetBody(request{
|
||||
Cmd: "request.get",
|
||||
Url: url,
|
||||
MaxTimeout: 60000,
|
||||
})
|
||||
client.R().SetResult(&response{})
|
||||
|
||||
if res, err = client.R().Post(url); err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
|
||||
response := res.Result().(*response)
|
||||
headers := http.Header{}
|
||||
|
||||
for k, v := range response.Solution.Headers {
|
||||
headers.Add(k, v)
|
||||
}
|
||||
|
||||
return response.Solution.Response, response.Solution.Status, headers, nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user