2020-11-15 10:34:48 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-03-22 07:20:56 +00:00
|
|
|
"context"
|
2020-11-15 10:34:48 +00:00
|
|
|
"encoding/base64"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2021-02-15 20:35:05 +00:00
|
|
|
"path"
|
2020-11-15 10:34:48 +00:00
|
|
|
"strings"
|
2021-07-12 14:19:28 +00:00
|
|
|
|
|
|
|
"github.com/microcosm-cc/bluemonday"
|
2020-11-15 10:34:48 +00:00
|
|
|
)
|
|
|
|
|
2021-07-12 14:19:28 +00:00
|
|
|
const defaultSearchPath = "/search"
|
2020-11-15 10:34:48 +00:00
|
|
|
const searchPlaceholder = "{search}"
|
|
|
|
|
2021-06-06 12:39:42 +00:00
|
|
|
func (a *goBlog) serveSearch(w http.ResponseWriter, r *http.Request) {
|
2021-07-27 10:51:08 +00:00
|
|
|
blog := r.Context().Value(blogKey).(string)
|
|
|
|
servePath := r.Context().Value(pathKey).(string)
|
2021-03-22 07:20:56 +00:00
|
|
|
err := r.ParseForm()
|
|
|
|
if err != nil {
|
2021-06-06 12:39:42 +00:00
|
|
|
a.serveError(w, r, err.Error(), http.StatusBadRequest)
|
2021-03-22 07:20:56 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if q := r.Form.Get("q"); q != "" {
|
2021-07-12 14:19:28 +00:00
|
|
|
// Clean query
|
|
|
|
q = htmlText([]byte(bluemonday.StrictPolicy().Sanitize(q)))
|
|
|
|
// Redirect to results
|
2021-03-22 07:20:56 +00:00
|
|
|
http.Redirect(w, r, path.Join(servePath, searchEncode(q)), http.StatusFound)
|
|
|
|
return
|
2020-11-15 10:34:48 +00:00
|
|
|
}
|
2021-06-06 12:39:42 +00:00
|
|
|
a.render(w, r, templateSearch, &renderData{
|
2021-03-22 07:20:56 +00:00
|
|
|
BlogString: blog,
|
2021-06-10 20:09:50 +00:00
|
|
|
Canonical: a.getFullAddress(servePath),
|
2021-03-22 07:20:56 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-06-06 12:39:42 +00:00
|
|
|
func (a *goBlog) serveSearchResult(w http.ResponseWriter, r *http.Request) {
|
|
|
|
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
|
2021-07-27 10:51:08 +00:00
|
|
|
path: r.Context().Value(pathKey).(string) + "/" + searchPlaceholder,
|
2021-03-22 07:20:56 +00:00
|
|
|
})))
|
2020-11-15 10:34:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func searchEncode(search string) string {
|
|
|
|
return url.PathEscape(strings.ReplaceAll(base64.StdEncoding.EncodeToString([]byte(search)), "/", "_"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func searchDecode(encoded string) string {
|
|
|
|
encoded, err := url.PathUnescape(encoded)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
encoded = strings.ReplaceAll(encoded, "_", "/")
|
|
|
|
db, err := base64.StdEncoding.DecodeString(encoded)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return string(db)
|
|
|
|
}
|