Move to fasthttp for improved performance
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/valyala/fasthttp"
|
||||
"zxq.co/ripple/rippleapi/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type response404 struct {
|
||||
@@ -11,12 +13,17 @@ type response404 struct {
|
||||
}
|
||||
|
||||
// Handle404 handles requests with no implemented handlers.
|
||||
func Handle404(c *gin.Context) {
|
||||
c.Header("X-Real-404", "yes")
|
||||
c.IndentedJSON(404, response404{
|
||||
func Handle404(c *fasthttp.RequestCtx) {
|
||||
c.Response.Header.Add("X-Real-404", "yes")
|
||||
data, err := json.MarshalIndent(response404{
|
||||
ResponseBase: common.ResponseBase{
|
||||
Code: 404,
|
||||
},
|
||||
Cats: surpriseMe(),
|
||||
})
|
||||
}, "", "\t")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.SetStatusCode(404)
|
||||
c.Write(data)
|
||||
}
|
||||
|
@@ -2,8 +2,6 @@ package v1
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"zxq.co/ripple/rippleapi/common"
|
||||
)
|
||||
@@ -51,10 +49,10 @@ type beatmapSetStatusData struct {
|
||||
// the beatmap ranked status is frozen. Or freezed. Freezed best meme 2k16
|
||||
func BeatmapSetStatusPOST(md common.MethodData) common.CodeMessager {
|
||||
var req beatmapSetStatusData
|
||||
md.RequestData.Unmarshal(&req)
|
||||
md.Unmarshal(&req)
|
||||
|
||||
var miss []string
|
||||
if req.BeatmapsetID == 0 && req.BeatmapID == 0 {
|
||||
if req.BeatmapsetID <= 0 && req.BeatmapID <= 0 {
|
||||
miss = append(miss, "beatmapset_id or beatmap_id")
|
||||
}
|
||||
if len(miss) != 0 {
|
||||
@@ -84,32 +82,14 @@ func BeatmapSetStatusPOST(md common.MethodData) common.CodeMessager {
|
||||
SET ranked = ?, ranked_status_freezed = ?
|
||||
WHERE beatmapset_id = ?`, req.RankedStatus, req.Frozen, param)
|
||||
|
||||
var x = make(map[string]interface{}, 1)
|
||||
if req.BeatmapID != 0 {
|
||||
x["bb"] = req.BeatmapID
|
||||
if req.BeatmapID > 0 {
|
||||
md.Ctx.Request.URI().QueryArgs().SetUint("bb", req.BeatmapID)
|
||||
} else {
|
||||
x["s"] = req.BeatmapsetID
|
||||
md.Ctx.Request.URI().QueryArgs().SetUint("s", req.BeatmapsetID)
|
||||
}
|
||||
md.C.Request.URL = genURL(x)
|
||||
return getMultipleBeatmaps(md)
|
||||
}
|
||||
|
||||
func genURL(d map[string]interface{}) *url.URL {
|
||||
var s string
|
||||
for k, v := range d {
|
||||
if s != "" {
|
||||
s += "&"
|
||||
}
|
||||
s += k + "=" + url.QueryEscape(fmt.Sprintf("%v", v))
|
||||
}
|
||||
u := new(url.URL)
|
||||
if len(d) == 0 {
|
||||
return u
|
||||
}
|
||||
u.RawQuery = s
|
||||
return u
|
||||
}
|
||||
|
||||
// BeatmapGET retrieves a beatmap.
|
||||
func BeatmapGET(md common.MethodData) common.CodeMessager {
|
||||
beatmapID := common.Int(md.Query("b"))
|
||||
|
@@ -78,7 +78,7 @@ type submitRequestData struct {
|
||||
// BeatmapRankRequestsSubmitPOST submits a new beatmap for ranking approval.
|
||||
func BeatmapRankRequestsSubmitPOST(md common.MethodData) common.CodeMessager {
|
||||
var d submitRequestData
|
||||
err := md.RequestData.Unmarshal(&d)
|
||||
err := md.Unmarshal(&d)
|
||||
if err != nil {
|
||||
return ErrBadJSON
|
||||
}
|
||||
@@ -91,9 +91,6 @@ func BeatmapRankRequestsSubmitPOST(md common.MethodData) common.CodeMessager {
|
||||
if !limit.NonBlockingRequest("rankrequest:u:"+strconv.Itoa(md.ID()), 5) {
|
||||
return common.SimpleResponse(429, "You may only try to request 5 beatmaps per minute.")
|
||||
}
|
||||
if !limit.NonBlockingRequest("rankrequest:ip:"+md.C.ClientIP(), 8) {
|
||||
return common.SimpleResponse(429, "You may only try to request 8 beatmaps per minute from the same IP.")
|
||||
}
|
||||
|
||||
// find out from BeatmapRankRequestsStatusGET if we can submit beatmaps.
|
||||
statusRaw := BeatmapRankRequestsStatusGET(md)
|
||||
|
@@ -134,7 +134,7 @@ func FriendsAddPOST(md common.MethodData) common.CodeMessager {
|
||||
var u struct {
|
||||
User int `json:"user"`
|
||||
}
|
||||
md.RequestData.Unmarshal(&u)
|
||||
md.Unmarshal(&u)
|
||||
return addFriend(md, u.User)
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ func FriendsDelPOST(md common.MethodData) common.CodeMessager {
|
||||
var u struct {
|
||||
User int `json:"user"`
|
||||
}
|
||||
md.RequestData.Unmarshal(&u)
|
||||
md.Unmarshal(&u)
|
||||
return delFriend(md, u.User)
|
||||
}
|
||||
|
||||
|
@@ -14,7 +14,7 @@ type setAllowedData struct {
|
||||
// UserManageSetAllowedPOST allows to set the allowed status of an user.
|
||||
func UserManageSetAllowedPOST(md common.MethodData) common.CodeMessager {
|
||||
data := setAllowedData{}
|
||||
if err := md.RequestData.Unmarshal(&data); err != nil {
|
||||
if err := md.Unmarshal(&data); err != nil {
|
||||
return ErrBadJSON
|
||||
}
|
||||
if data.Allowed < 0 || data.Allowed > 2 {
|
||||
|
@@ -62,7 +62,7 @@ type userSettingsData struct {
|
||||
// UsersSelfSettingsPOST allows to modify information about the current user.
|
||||
func UsersSelfSettingsPOST(md common.MethodData) common.CodeMessager {
|
||||
var d userSettingsData
|
||||
md.RequestData.Unmarshal(&d)
|
||||
md.Unmarshal(&d)
|
||||
|
||||
// input sanitisation
|
||||
*d.UsernameAKA = common.SanitiseString(*d.UsernameAKA)
|
||||
|
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"zxq.co/ripple/rippleapi/common"
|
||||
"zxq.co/ripple/rippleapi/limit"
|
||||
"zxq.co/ripple/schiavolib"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type tokenNewInData struct {
|
||||
@@ -37,7 +37,7 @@ type tokenNewResponse struct {
|
||||
func TokenNewPOST(md common.MethodData) common.CodeMessager {
|
||||
var r tokenNewResponse
|
||||
data := tokenNewInData{}
|
||||
err := md.RequestData.Unmarshal(&data)
|
||||
err := md.Unmarshal(&data)
|
||||
if err != nil {
|
||||
return ErrBadJSON
|
||||
}
|
||||
@@ -80,7 +80,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
|
||||
}
|
||||
privileges := common.UserPrivileges(privilegesRaw)
|
||||
|
||||
if !limit.NonBlockingRequest(fmt.Sprintf("loginattempt:%d:%s", r.ID, md.C.ClientIP()), 5) {
|
||||
if !limit.NonBlockingRequest(fmt.Sprintf("loginattempt:%d:%s", r.ID, md.ClientIP()), 5) {
|
||||
return common.SimpleResponse(429, "You've made too many login attempts. Try again later.")
|
||||
}
|
||||
|
||||
|
@@ -5,9 +5,9 @@ import (
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
||||
"zxq.co/ripple/ocl"
|
||||
"zxq.co/ripple/rippleapi/common"
|
||||
)
|
||||
@@ -71,8 +71,7 @@ type userPutsMultiUserData struct {
|
||||
}
|
||||
|
||||
func userPutsMulti(md common.MethodData) common.CodeMessager {
|
||||
q := md.C.Request.URL.Query()
|
||||
|
||||
pm := md.Ctx.Request.URI().QueryArgs().PeekMulti
|
||||
// query composition
|
||||
wh := common.
|
||||
Where("users.username_safe = ?", common.SafeUsername(md.Query("nname"))).
|
||||
@@ -83,10 +82,10 @@ func userPutsMulti(md common.MethodData) common.CodeMessager {
|
||||
Where("users_stats.country = ?", md.Query("country")).
|
||||
Where("users_stats.username_aka = ?", md.Query("name_aka")).
|
||||
Where("privileges_groups.name = ?", md.Query("privilege_group")).
|
||||
In("users.id", q["ids"]...).
|
||||
In("users.username_safe", safeUsernameBulk(q["names"])...).
|
||||
In("users_stats.username_aka", q["names_aka"]...).
|
||||
In("users_stats.country", q["countries"]...)
|
||||
In("users.id", pm("ids")...).
|
||||
In("users.username_safe", safeUsernameBulk(pm("names"))...).
|
||||
In("users_stats.username_aka", pm("names_aka")...).
|
||||
In("users_stats.country", pm("countries")...)
|
||||
|
||||
var extraJoin string
|
||||
if md.Query("privilege_group") != "" {
|
||||
@@ -130,13 +129,19 @@ func userPutsMulti(md common.MethodData) common.CodeMessager {
|
||||
|
||||
// UserSelfGET is a shortcut for /users/id/self. (/users/self)
|
||||
func UserSelfGET(md common.MethodData) common.CodeMessager {
|
||||
md.C.Request.URL.RawQuery = "id=self&" + md.C.Request.URL.RawQuery
|
||||
md.Ctx.Request.URI().SetQueryString("id=self")
|
||||
return UsersGET(md)
|
||||
}
|
||||
|
||||
func safeUsernameBulk(us []string) []string {
|
||||
for i, u := range us {
|
||||
us[i] = common.SafeUsername(u)
|
||||
func safeUsernameBulk(us [][]byte) [][]byte {
|
||||
for _, u := range us {
|
||||
for idx, v := range u {
|
||||
if v == ' ' {
|
||||
u[idx] = '_'
|
||||
continue
|
||||
}
|
||||
u[idx] = byte(unicode.ToLower(rune(v)))
|
||||
}
|
||||
}
|
||||
return us
|
||||
}
|
||||
@@ -341,7 +346,7 @@ func UserSelfUserpagePOST(md common.MethodData) common.CodeMessager {
|
||||
var d struct {
|
||||
Data *string `json:"data"`
|
||||
}
|
||||
md.RequestData.Unmarshal(&d)
|
||||
md.Unmarshal(&d)
|
||||
if d.Data == nil {
|
||||
return ErrMissingField("data")
|
||||
}
|
||||
@@ -350,7 +355,7 @@ func UserSelfUserpagePOST(md common.MethodData) common.CodeMessager {
|
||||
if err != nil {
|
||||
md.Err(err)
|
||||
}
|
||||
md.C.Request.URL.RawQuery += "&id=" + strconv.Itoa(md.ID())
|
||||
md.Ctx.URI().SetQueryString("id=self")
|
||||
return UserUserpageGET(md)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user