Skip to content

Commit

Permalink
Рефакторинг запросов аучлибы
Browse files Browse the repository at this point in the history
  • Loading branch information
JoCat committed Jul 11, 2021
1 parent 53affea commit 46c30b2
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 184 deletions.
69 changes: 67 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"colors": "^1.4.0",
"lodash": "^4.17.21",
"p-map": "^5.0.0",
"raw-body": "^2.4.1",
"reflect-metadata": "^0.1.13",
"semver": "^7.3.5",
"source-map-support": "^0.5.19",
Expand Down
4 changes: 2 additions & 2 deletions src/api/WebServerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as path from "path"
import { LogHelper } from "../helpers/LogHelper"
import { StorageHelper } from "../helpers/StorageHelper"
import { App } from "../LauncherServer"
import { WebRequestManager } from "./webserver/WebRequestManager"
import { ExtendedIncomingMessage, ExtendedServerResponse, WebRequestManager } from "./webserver/WebRequestManager"

export class WebServerManager {
public webServer: http.Server | https.Server
Expand Down Expand Up @@ -43,7 +43,7 @@ export class WebServerManager {

private requestListener(req: http.IncomingMessage, res: http.ServerResponse): void {
if (req.url.startsWith("/files")) return this.fileListing(req.url, res)
this.requestsManager.getRequest(req, res)
this.requestsManager.getRequest(req as ExtendedIncomingMessage, res as ExtendedServerResponse)
}

private fileListing(url: string, res: http.ServerResponse): void {
Expand Down
72 changes: 52 additions & 20 deletions src/api/webserver/WebRequestManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { IncomingMessage, ServerResponse } from "http"

import { JsonHelper } from "@root/helpers/JsonHelper"
import getRawBody from "raw-body"

import { AbstractRequest } from "./requests/AbstractRequest"
import { ProfilesRequest } from "./requests/authlib/accountsHost/ProfilesRequest"
import { PrivelegesRequest } from "./requests/authlib/servicesHost/PrivelegesRequest"
Expand All @@ -22,29 +25,58 @@ export class WebRequestManager {
this.requests.push(request)
}

getRequest(req: IncomingMessage, res: ServerResponse): void {
res.setHeader("Content-Type", "application/json; charset=utf-8")

const request = this.requests.find((e) => e.url.test(req.url))
async getRequest(req: ExtendedIncomingMessage, res: ExtendedServerResponse): Promise<void> {
const request = this.requests.find((r) => r.url.test(req.url))
// нижние 2 обработчика корректны для api.mojang.com и authserver.mojang.com
if (request === undefined)
return res
.writeHead(404)
.end(
AbstractRequest.returnError(
"Not Found",
"The server has not found anything matching the request URI"
)
)
return res.writeHead(404).end(
JsonHelper.toJSON({
error: "Not Found",
errorMessage: "The server has not found anything matching the request URI",
})
)
if (request.method !== req.method)
return res
.writeHead(405)
.end(
AbstractRequest.returnError(
"Method Not Allowed",
"The method specified in the request is not allowed for the resource identified by the request URI"
)
)
return res.writeHead(405).end(
JsonHelper.toJSON({
error: "Method Not Allowed",
errorMessage:
"The method specified in the request is not allowed for the resource identified by the request URI",
})
)

// Привет, кастомные обработчики
req.query = new URLSearchParams(req.url.split("?")[1])

res.error = (code = 400, error?: string, errorMessage?: string) => {
res.writeHead(code).json({ error, errorMessage })
}

res.json = (data: object) => {
res.setHeader("Content-Type", "application/json; charset=utf-8")
res.end(JsonHelper.toJSON(data))
}

if (req.method === "POST") {
if (!req.headers["content-type"] || !req.headers["content-type"].includes("application/json"))
return res.error(400, "Invalid content-type header")

try {
req.body = await getRawBody(req, { limit: "500kb", encoding: "utf-8" })
} catch (error) {
return res.error(error.status || 400, error.message)
}
}

request.emit(req, res)
}
}

export class ExtendedIncomingMessage extends IncomingMessage {
query: URLSearchParams
body?: string
}

export class ExtendedServerResponse extends ServerResponse {
error: (code?: number, error?: string, errorMessage?: string) => void
json: (data: object) => void
}
29 changes: 0 additions & 29 deletions src/api/webserver/requests/AbstractRequest.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,17 @@
import { IncomingMessage, ServerResponse } from "http"

import { JsonHelper } from "../../../helpers/JsonHelper"

export abstract class AbstractRequest {
abstract readonly url: RegExp
abstract readonly method: string

abstract emit(req: IncomingMessage, res: ServerResponse): PromiseOr<void>

protected parseQuery(url: string): URLSearchParams {
return new URLSearchParams(url.split("?")[1])
}

protected isEmptyQuery(query: URLSearchParams): boolean {
return query.toString().length === 0
}

public returnError(error: string, errorMessage?: string): string {
return JsonHelper.toJSON({ error, errorMessage })
}
// КХЪ Похоже что нужно рефакторить некоторе говно
public static returnError(error: string, errorMessage?: string): string {
return JsonHelper.toJSON({ error, errorMessage })
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
protected isInvalidValue(param: any): boolean {
return typeof param !== "string" || param.trim().length === 0
}

protected getPostData(req: IncomingMessage): Promise<string> {
return new Promise((resolve, reject) => {
let data = ""
req.on("data", (chunk) => {
data += chunk
})
req.on("end", () => {
resolve(data)
})
req.on("error", (error) => {
reject(error)
})
})
}
}
28 changes: 8 additions & 20 deletions src/api/webserver/requests/authlib/accountsHost/ProfilesRequest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { IncomingMessage, ServerResponse } from "http"

import { ExtendedIncomingMessage, ExtendedServerResponse } from "@root/api/webserver/WebRequestManager"
import { JsonHelper } from "@root/helpers/JsonHelper"
import { App } from "@root/LauncherServer"

Expand All @@ -9,31 +8,20 @@ export class ProfilesRequest extends AbstractRequest {
method = "POST"
url = /^\/authlib\/profiles\/minecraft$/

async emit(req: IncomingMessage, res: ServerResponse): Promise<void> {
let data: any = await this.getPostData(req)
res.statusCode = 400
async emit(req: ExtendedIncomingMessage, res: ExtendedServerResponse): Promise<void> {
let data: string[]

try {
data = JsonHelper.fromJSON(data)
data = JsonHelper.fromJSON(req.body)
} catch (error) {
return res.end(this.returnError("BadRequestException"))
return res.error(400, "BadRequestException")
}

if (!Array.isArray(data) || data.length === 0) return res.end(this.returnError("BadRequestException"))
if (!Array.isArray(data) || data.length === 0) return res.error(400, "BadRequestException")

if (data.length > 10)
return res.end(
this.returnError("IllegalArgumentException", "Not more that 10 profile name per call is allowed.")
)

let users
try {
users = await App.AuthManager.getAuthProvider().profiles(data)
} catch (error) {
return res.end()
}
return res.error(400, "IllegalArgumentException", "Not more that 10 profile name per call is allowed.")

res.statusCode = 200
res.end(JsonHelper.toJSON(users))
res.json(await App.AuthManager.getAuthProvider().profiles(data))
}
}
Loading

0 comments on commit 46c30b2

Please sign in to comment.