Skip to content

Commit aba84ce

Browse files
committed
Use router package instead of GET parameter for manage pages
1 parent d94a0d8 commit aba84ce

33 files changed

+105
-121
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Demo installation: https://gochan.org
1313
3. If you're using nginx, copy gochan-http.nginx, or gochan-fastcgi.nginx if `UseFastCGI` is set to true to /etc/nginx/sites-enabled/, or the appropriate folder in Windows.
1414
4. If you're using a Linux distribution with systemd, you can optionally copy gochan.service to /lib/systemd/system/gochan.service and run `systemctl enable gochan.service` to have it run on startup. Then run `systemctl start gochan.service` to start it as a background service.
1515
1. If you aren't using a distro with systemd, you can start a screen session and run `/path/to/gochan`
16-
5. Go to http://[gochan url]/manage?action=staff, log in (default username/password is admin/password), and create a new admin user (and any other staff users as necessary). Then delete the admin user for security.
16+
5. Go to http://[gochan url]/manage/staff, log in (default username/password is admin/password), and create a new admin user (and any other staff users as necessary). Then delete the admin user for security.
1717

1818
## Installation using Docker
1919
See [`docker/README.md`](docker/README.md)

build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def install(prefix="/usr", document_root="/srv/gochan", symlinks=False, js_only=
366366
print(
367367
"gochan was successfully installed. If you haven't already, you should copy\n",
368368
"sample-configs/gochan.example.json to /etc/gochan/gochan.json (modify as needed)\n",
369-
"You may also need to go to https://yourgochansite/manage?action=rebuildall to rebuild the javascript config")
369+
"You may also need to go to https://yourgochansite/manage/rebuildall to rebuild the javascript config")
370370
if gcos == "linux":
371371
print(
372372
"If your Linux distribution has systemd, you will also need to run the following commands:\n",

cmd/gochan-migration/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ the README and/or the -h command line flag before you use it.
2121
migrateCompleteTxt = `Database migration successful!
2222
To migrate the uploads for each board, move or copy the uploads to /path/to/gochan/document/root/<boardname>/src/
2323
Then copy the thumbnails to /path/to/gochan/documentroot/<boardname>/thumb/
24-
Then start the gochan server and go to http://yoursite/manage?action=rebuildall to generate the html files
24+
Then start the gochan server and go to http://yoursite/manage/rebuildall to generate the html files
2525
for the threads and board pages`
2626

2727
allowedDirActions = "Valid values are noaction, copy, and move (defaults to noaction if unset)"

cmd/gochan/server.go

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"strconv"
1111
"strings"
1212

13+
"github.com/uptrace/bunrouter"
14+
1315
"github.com/gochan-org/gochan/pkg/config"
1416
"github.com/gochan-org/gochan/pkg/gcutil"
1517
"github.com/gochan-org/gochan/pkg/manage"
@@ -18,14 +20,10 @@ import (
1820
)
1921

2022
var (
21-
server *gochanServer
23+
router *bunrouter.Router
2224
)
2325

24-
type gochanServer struct {
25-
namespaces map[string]func(http.ResponseWriter, *http.Request)
26-
}
27-
28-
func (s gochanServer) serveFile(writer http.ResponseWriter, request *http.Request) {
26+
func serveFile(writer http.ResponseWriter, request *http.Request) {
2927
systemCritical := config.GetSystemCriticalConfig()
3028
siteConfig := config.GetSiteConfig()
3129

@@ -56,7 +54,7 @@ func (s gochanServer) serveFile(writer http.ResponseWriter, request *http.Reques
5654
return
5755
}
5856
}
59-
s.setFileHeaders(filePath, writer)
57+
setFileHeaders(filePath, writer)
6058

6159
// serve the requested file
6260
fileBytes, _ = os.ReadFile(filePath)
@@ -65,7 +63,7 @@ func (s gochanServer) serveFile(writer http.ResponseWriter, request *http.Reques
6563
}
6664

6765
// set mime type/cache headers according to the file's extension
68-
func (*gochanServer) setFileHeaders(filename string, writer http.ResponseWriter) {
66+
func setFileHeaders(filename string, writer http.ResponseWriter) {
6967
extension := strings.ToLower(path.Ext(filename))
7068
switch extension {
7169
case ".png":
@@ -102,16 +100,6 @@ func (*gochanServer) setFileHeaders(filename string, writer http.ResponseWriter)
102100
}
103101
}
104102

105-
func (s gochanServer) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
106-
for name, namespaceFunction := range s.namespaces {
107-
if request.URL.Path == config.WebPath(name) {
108-
namespaceFunction(writer, request)
109-
return
110-
}
111-
}
112-
s.serveFile(writer, request)
113-
}
114-
115103
func initServer() {
116104
systemCritical := config.GetSystemCriticalConfig()
117105
siteConfig := config.GetSiteConfig()
@@ -124,8 +112,9 @@ func initServer() {
124112
Int("Port", systemCritical.Port).Send()
125113
fmt.Printf("Failed listening on %s:%d: %s", systemCritical.ListenIP, systemCritical.Port, err.Error())
126114
}
127-
server = new(gochanServer)
128-
server.namespaces = make(map[string]func(http.ResponseWriter, *http.Request))
115+
router = bunrouter.New(
116+
bunrouter.WithNotFoundHandler(bunrouter.HTTPHandlerFunc(serveFile)),
117+
)
129118

130119
// Check if Akismet API key is usable at startup.
131120
err = serverutil.CheckAkismetAPIKey(siteConfig.AkismetAPIKey)
@@ -135,22 +124,21 @@ func initServer() {
135124
fmt.Println("Got error when initializing Akismet spam protection, it will be disabled:", err)
136125
}
137126

138-
server.namespaces["captcha"] = posting.ServeCaptcha
139-
server.namespaces["manage"] = manage.CallManageFunction
140-
server.namespaces["post"] = posting.MakePost
141-
server.namespaces["util"] = utilHandler
142-
server.namespaces["example"] = func(writer http.ResponseWriter, request *http.Request) {
143-
if writer != nil {
144-
http.Redirect(writer, request, "https://www.youtube.com/watch?v=dQw4w9WgXcQ", http.StatusFound)
145-
}
146-
}
127+
router.GET(config.WebPath("/captcha"), bunrouter.HTTPHandlerFunc(posting.ServeCaptcha))
128+
router.POST(config.WebPath("/captcha"), bunrouter.HTTPHandlerFunc(posting.ServeCaptcha))
129+
router.GET(config.WebPath("/manage"), bunrouter.HTTPHandlerFunc(manage.CallManageFunction))
130+
router.GET(config.WebPath("/manage/:action"), bunrouter.HTTPHandlerFunc(manage.CallManageFunction))
131+
router.POST(config.WebPath("/manage/:action"), bunrouter.HTTPHandlerFunc(manage.CallManageFunction))
132+
router.POST(config.WebPath("/post"), bunrouter.HTTPHandlerFunc(posting.MakePost))
133+
router.GET(config.WebPath("/util"), bunrouter.HTTPHandlerFunc(utilHandler))
134+
router.POST(config.WebPath("/util"), bunrouter.HTTPHandlerFunc(utilHandler))
147135
// Eventually plugins might be able to register new namespaces or they might be restricted to something
148136
// like /plugin
149137

150138
if systemCritical.UseFastCGI {
151-
err = fcgi.Serve(listener, server)
139+
err = fcgi.Serve(listener, router)
152140
} else {
153-
err = http.Serve(listener, server)
141+
err = http.Serve(listener, router)
154142
}
155143

156144
if err != nil {

devtools/selenium_testing/runtests.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def gotoPage(driver: WebDriver, page: str):
5757

5858

5959
def isLoggedIn(driver: WebDriver):
60-
gotoPage(driver, "manage?action=login")
60+
gotoPage(driver, "manage/login")
6161
return driver.find_element(by=By.CSS_SELECTOR, value="h1#board-title").text == "Dashboard"
6262

6363

@@ -177,7 +177,7 @@ def test_makeBoard(self):
177177
if boardExists("seleniumtesting"):
178178
raise Exception("Board /seleniumtests/ already exists")
179179
loginToStaff(self.driver)
180-
gotoPage(self.driver, "manage?action=boards")
180+
gotoPage(self.driver, "manage/boards")
181181

182182
# fill out the board creation form
183183
self.driver.find_element(by=By.NAME, value="dir").\
@@ -197,7 +197,7 @@ def test_makeBoard(self):
197197

198198
makePostOnPage("seleniumtesting", self)
199199

200-
gotoPage(self.driver, "manage?action=boards")
200+
gotoPage(self.driver, "manage/boards")
201201
sel = Select(self.driver.find_element(by=By.ID, value="modifyboard"))
202202
sel.select_by_visible_text("/seleniumtesting/ - Selenium testing")
203203
self.driver.find_element(by=By.NAME, value="dodelete").click()
@@ -221,7 +221,7 @@ def test_makeThread(self):
221221
def test_moveThread(self):
222222
if not boardExists("test2"):
223223
loginToStaff(self.driver)
224-
gotoPage(self.driver, "manage?action=boards")
224+
gotoPage(self.driver, "manage/boards")
225225

226226
# fill out the board creation form
227227
self.driver.find_element(by=By.NAME, value="dir").\

frontend/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ If you want, you can install [Sass](https://sass-lang.com/install) to streamline
3131

3232
To use sass, run `./build.py sass`. If you want to minify the created css files, use the `--minify` flag. If you want sass to watch the input directory for changes as you edit and save the files, use the `--watch` flag.
3333

34-
If you are upgading from gochan 2.2, delete your html/css directory unless you have made themes that you want to keep. Then rebuild the pages. (/manage?action=rebuildall)
34+
If you are upgading from gochan 2.2, delete your html/css directory unless you have made themes that you want to keep. Then rebuild the pages. (/manage/rebuildall)
3535

3636
## Attribution
3737
The BunkerChan, Clear, and Dark themes come from the imageboard BunkerChan. Burichan is based on the theme with the same name from Kusaba X. Photon comes from nol.ch (I think?) that as far as I know no longer exists. Pipes was created by a user (Mbyte?) on Lunachan (defunct). Yotsuba and Yotsuba B are based on the themes with the same names from 4chan.

frontend/js/dom/postdropdown.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ function handleActions(action, postIDStr) {
157157
// manage stuff
158158
case "Posts from this IP":
159159
getPostInfo(postID).then(info => {
160-
window.open(`${webroot}manage?action=ipsearch&limit=100&ip=${info.ip}`);
160+
window.open(`${webroot}manage/ipsearch?limit=100&ip=${info.ip}`);
161161
}).catch(reason => {
162162
alertLightbox(`Failed getting post IP: ${reason.statusText}`, "Error");
163163
});

frontend/js/management/filebans.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import "jquery-ui/ui/unique-id";
44
import "jquery-ui/ui/keycode";
55
import "jquery-ui/ui/widgets/tabs";
66
$(() => {
7-
if(window.location.search.indexOf("?action=filebans") != 0)
7+
if(window.location.pathname != webroot + "manage/filebans")
88
return;
99
$("div#fileban-tabs").tabs();
1010
});

frontend/js/management/manage.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,15 @@ export function banFile(banType, filename, checksum, staffNote = "") {
9292
}
9393
return $.ajax({
9494
method: "POST",
95-
url: `${webroot}manage?action=filebans`,
95+
url: `${webroot}manage/filebans`,
9696
data: xhrFields
9797
});
9898
}
9999

100100
export async function initStaff() {
101101
return $.ajax({
102102
method: "GET",
103-
url: `${webroot}manage`,
104-
data: {
105-
action: "actions"
106-
},
103+
url: `${webroot}manage/actions`,
107104
async: true,
108105
cache: false,
109106
success: result => {
@@ -138,10 +135,7 @@ export async function getStaffInfo() {
138135
loginChecked = true;
139136
return $.ajax({
140137
method: "GET",
141-
url: `${webroot}manage`,
142-
data: {
143-
action: "staffinfo",
144-
},
138+
url: `${webroot}manage/staffinfo`,
145139
async: true,
146140
cache: true,
147141
dataType: "json"
@@ -158,9 +152,8 @@ export async function getStaffInfo() {
158152
export async function getPostInfo(id) {
159153
return $.ajax({
160154
method: "GET",
161-
url: `${webroot}manage`,
155+
url: `${webroot}manage/postinfo`,
162156
data: {
163-
action: "postinfo",
164157
postid: id
165158
},
166159
async: true,
@@ -191,7 +184,7 @@ export function banSelectedPost() {
191184
break;
192185
}
193186
}
194-
window.location = `${webroot}manage?action=bans&dir=${boardDir}&postid=${postID}`;
187+
window.location = `${webroot}manage/bans?dir=${boardDir}&postid=${postID}`;
195188
}
196189

197190
/**
@@ -201,7 +194,7 @@ export function banSelectedPost() {
201194
function menuItem(action, isCategory = false) {
202195
return isCategory ? $("<div/>").append($("<b/>").text(action)) : $("<div/>").append(
203196
$("<a/>").prop({
204-
href: `${webroot}manage?action=${action.id}`
197+
href: `${webroot}manage/${action.id}`
205198
}).text(action.title)
206199
);
207200
}
@@ -294,9 +287,8 @@ function updateReports(reports) {
294287
function getReports() {
295288
return $.ajax({
296289
method: "GET",
297-
url: `${webroot}manage`,
290+
url: `${webroot}manage/reports`,
298291
data: {
299-
action: "reports",
300292
json: "1"
301293
},
302294
async: true,

frontend/js/management/sections.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Make the sections table on /manage?action=boardsections sortable to make changing the list order easier
1+
// Make the sections table on /manage/boardsections sortable to make changing the list order easier
22

33
/* global webroot */
44

@@ -28,7 +28,7 @@ function applyOrderChanges() {
2828
let sectionhidden = $el.find(":nth-child(4)").html().toLowerCase() == "yes"?"on":"off";
2929
$.ajax({
3030
method: "POST",
31-
url: webroot + "manage?action=boardsections",
31+
url: webroot + "manage/boardsections",
3232
data: {
3333
updatesection: updatesection,
3434
sectionname: sectionname,
@@ -81,7 +81,7 @@ function addButtons() {
8181
}
8282

8383
$(() => {
84-
if(window.location.search.indexOf("?action=boardsections") != 0)
84+
if(window.location.pathname != webroot + "manage/boardsections")
8585
return;
8686

8787
$sectionsTable = $("table#sections");

frontend/js/types/gochan.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ declare interface ThreadPost {
9191
}
9292

9393
/**
94-
* An object representing a staff member retreived by requesting /manage?action=staffinfo
94+
* An object representing a staff member retreived by requesting /manage/staffinfo
9595
*/
9696
interface StaffInfo {
9797
/**
@@ -117,7 +117,7 @@ declare interface ThreadPost {
117117
*/
118118
interface StaffAction {
119119
/**
120-
* The GET key used when requesting /manage?action=<id>
120+
* The GET key used when requesting /manage/<id>
121121
*/
122122
id?:string;
123123
/**
@@ -142,7 +142,7 @@ interface StaffAction {
142142
}
143143

144144
/**
145-
* The result of requesting /manage?action=actions
145+
* The result of requesting /manage/actions
146146
*/
147147
declare var staffActions: StaffAction[];
148148

frontend/package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/tdewolff/minify v2.3.6+incompatible
1414
github.com/tdewolff/parse v2.3.4+incompatible // indirect
1515
github.com/tdewolff/test v1.0.7 // indirect
16+
github.com/uptrace/bunrouter v1.0.19 // indirect
1617
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64
1718
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
1819
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
44
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
55
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
66
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
7+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
78
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
89
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
910
github.com/frustra/bbcode v0.0.0-20201127003707-6ef347fbe1c8 h1:sdIsYe6Vv7KIWZWp8KqSeTl+XlF17d+wHCC4lbxFcYs=
@@ -20,15 +21,20 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
2021
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
2122
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
2223
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
24+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2325
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
2426
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
2527
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
28+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
29+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
2630
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
2731
github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs=
2832
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
2933
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
3034
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
3135
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
36+
github.com/uptrace/bunrouter v1.0.19 h1:kdN1Nl/9RDq9eBPnjS6GvNKcgiAeMxdb9DbpslLndFg=
37+
github.com/uptrace/bunrouter v1.0.19/go.mod h1:TwT7Bc0ztF2Z2q/ZzMuSVkcb/Ig/d3MQeP2cxn3e1hI=
3238
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
3339
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
3440
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
@@ -56,5 +62,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
5662
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
5763
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
5864
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
65+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
66+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
5967
layeh.com/gopher-luar v1.0.10 h1:55b0mpBhN9XSshEd2Nz6WsbYXctyBT35azk4POQNSXo=
6068
layeh.com/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=

0 commit comments

Comments
 (0)