u
This commit is contained in:
@@ -70,6 +70,12 @@ int64_t HttpRequest::get_query_int64(const std::string& key, int64_t def) const
|
|||||||
// HttpResponse
|
// HttpResponse
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static const char* CORS_HEADERS =
|
||||||
|
"Access-Control-Allow-Origin: *\r\n"
|
||||||
|
"Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n"
|
||||||
|
"Access-Control-Allow-Headers: Content-Type, Authorization\r\n"
|
||||||
|
"Access-Control-Max-Age: 86400\r\n";
|
||||||
|
|
||||||
void HttpResponse::send_json(int code, const json& body) {
|
void HttpResponse::send_json(int code, const json& body) {
|
||||||
if (headers_sent) return;
|
if (headers_sent) return;
|
||||||
status_code = code;
|
status_code = code;
|
||||||
@@ -80,6 +86,7 @@ void HttpResponse::send_json(int code, const json& body) {
|
|||||||
"Content-Type: application/json; charset=utf-8\r\n"
|
"Content-Type: application/json; charset=utf-8\r\n"
|
||||||
"Content-Length: " + std::to_string(body_str.size()) + "\r\n"
|
"Content-Length: " + std::to_string(body_str.size()) + "\r\n"
|
||||||
"Connection: keep-alive\r\n"
|
"Connection: keep-alive\r\n"
|
||||||
|
+ std::string(CORS_HEADERS) +
|
||||||
"\r\n"
|
"\r\n"
|
||||||
+ body_str;
|
+ body_str;
|
||||||
|
|
||||||
@@ -95,6 +102,7 @@ void HttpResponse::send_binary(int code, const std::vector<uint8_t>& data, const
|
|||||||
"Content-Type: " + content_type + "\r\n"
|
"Content-Type: " + content_type + "\r\n"
|
||||||
"Content-Length: " + std::to_string(data.size()) + "\r\n"
|
"Content-Length: " + std::to_string(data.size()) + "\r\n"
|
||||||
"Connection: keep-alive\r\n"
|
"Connection: keep-alive\r\n"
|
||||||
|
+ std::string(CORS_HEADERS) +
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
session_write_binary(session, header, data);
|
session_write_binary(session, header, data);
|
||||||
@@ -108,6 +116,7 @@ void HttpResponse::send_empty(int code) {
|
|||||||
std::string resp = "HTTP/1.1 " + std::to_string(code) + " " + reason_phrase(code) + "\r\n"
|
std::string resp = "HTTP/1.1 " + std::to_string(code) + " " + reason_phrase(code) + "\r\n"
|
||||||
"Content-Length: 0\r\n"
|
"Content-Length: 0\r\n"
|
||||||
"Connection: keep-alive\r\n"
|
"Connection: keep-alive\r\n"
|
||||||
|
+ std::string(CORS_HEADERS) +
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
session_write(session, resp);
|
session_write(session, resp);
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ void Router::dispatch(tls_session* sess, PairingStore& pairing, const json& conf
|
|||||||
full_url += "?" + req.query_string;
|
full_url += "?" + req.query_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.method == "OPTIONS") {
|
||||||
|
resp.send_empty(204);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string route_key = req.method + " " + req.path;
|
std::string route_key = req.method + " " + req.path;
|
||||||
auto it = routes_.find(route_key);
|
auto it = routes_.find(route_key);
|
||||||
if (it != routes_.end()) {
|
if (it != routes_.end()) {
|
||||||
|
|||||||
17
src/http.js
17
src/http.js
@@ -13,11 +13,19 @@ export function readBody(req) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CORS_HEADERS = {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
||||||
|
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
||||||
|
'Access-Control-Max-Age': '86400',
|
||||||
|
};
|
||||||
|
|
||||||
export function sendJson(res, statusCode, body) {
|
export function sendJson(res, statusCode, body) {
|
||||||
const responseBody = JSON.stringify(body);
|
const responseBody = JSON.stringify(body);
|
||||||
res.writeHead(statusCode, {
|
res.writeHead(statusCode, {
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Content-Length': Buffer.byteLength(responseBody),
|
'Content-Length': Buffer.byteLength(responseBody),
|
||||||
|
...CORS_HEADERS,
|
||||||
});
|
});
|
||||||
res.end(responseBody);
|
res.end(responseBody);
|
||||||
}
|
}
|
||||||
@@ -26,10 +34,19 @@ export function sendBinary(res, statusCode, buffer, contentType) {
|
|||||||
res.writeHead(statusCode, {
|
res.writeHead(statusCode, {
|
||||||
'Content-Type': contentType,
|
'Content-Type': contentType,
|
||||||
'Content-Length': buffer.length,
|
'Content-Length': buffer.length,
|
||||||
|
...CORS_HEADERS,
|
||||||
});
|
});
|
||||||
res.end(buffer);
|
res.end(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sendCorsPreflight(res) {
|
||||||
|
res.writeHead(204, {
|
||||||
|
'Content-Length': 0,
|
||||||
|
...CORS_HEADERS,
|
||||||
|
});
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
|
||||||
export function normalizePath(pathname) {
|
export function normalizePath(pathname) {
|
||||||
return pathname.replace(/^\/api(?=\/v1\/)/, '');
|
return pathname.replace(/^\/api(?=\/v1\/)/, '');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { endpoints } from './endpoints/index.js';
|
import { endpoints } from './endpoints/index.js';
|
||||||
import { normalizePath, readBody, sendJson } from './http.js';
|
import { normalizePath, readBody, sendCorsPreflight, sendJson } from './http.js';
|
||||||
|
|
||||||
function buildConfig(config = {}) {
|
function buildConfig(config = {}) {
|
||||||
return {
|
return {
|
||||||
@@ -18,6 +18,10 @@ export function createJtlPosServer(pairingStore, config = {}) {
|
|||||||
const routes = new Map(endpoints.map((endpoint) => [`${endpoint.method} ${endpoint.path}`, endpoint]));
|
const routes = new Map(endpoints.map((endpoint) => [`${endpoint.method} ${endpoint.path}`, endpoint]));
|
||||||
|
|
||||||
async function handle(req, res) {
|
async function handle(req, res) {
|
||||||
|
if (req.method === 'OPTIONS') {
|
||||||
|
return sendCorsPreflight(res);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url, 'https://localhost');
|
const url = new URL(req.url, 'https://localhost');
|
||||||
const pathname = normalizePath(url.pathname);
|
const pathname = normalizePath(url.pathname);
|
||||||
const routeKey = `${req.method} ${pathname}`;
|
const routeKey = `${req.method} ${pathname}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user