mirror of
https://github.com/tsl0922/ttyd.git
synced 2026-01-09 12:24:21 +01:00
server: add auth proxy support
This commit is contained in:
64
src/http.c
64
src/http.c
@@ -11,35 +11,36 @@ enum { AUTH_OK, AUTH_FAIL, AUTH_ERROR };
|
||||
static char *html_cache = NULL;
|
||||
static size_t html_cache_len = 0;
|
||||
|
||||
static int check_auth(struct lws *wsi, struct pss_http *pss) {
|
||||
if (server->credential == NULL) return AUTH_OK;
|
||||
|
||||
char buf[256];
|
||||
int len = lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_AUTHORIZATION);
|
||||
if (len >= 7 && strstr(buf, "Basic ")) {
|
||||
if (!strcmp(buf + 6, server->credential)) return AUTH_OK;
|
||||
}
|
||||
|
||||
static int send_unauthorized(struct lws *wsi, unsigned int code, enum lws_token_indexes header) {
|
||||
unsigned char buffer[1024 + LWS_PRE], *p, *end;
|
||||
p = buffer + LWS_PRE;
|
||||
end = p + sizeof(buffer) - LWS_PRE;
|
||||
|
||||
char *body = strdup("401 Unauthorized\n");
|
||||
size_t n = strlen(body);
|
||||
|
||||
if (lws_add_http_header_status(wsi, HTTP_STATUS_UNAUTHORIZED, &p, end) ||
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
|
||||
(unsigned char *)"Basic realm=\"ttyd\"", 18, &p, end) ||
|
||||
lws_add_http_header_content_length(wsi, n, &p, end) ||
|
||||
lws_finalize_http_header(wsi, &p, end) ||
|
||||
if (lws_add_http_header_status(wsi, code, &p, end) ||
|
||||
lws_add_http_header_by_token(wsi, header, (unsigned char *)"Basic realm=\"ttyd\"", 18, &p, end) ||
|
||||
lws_add_http_header_content_length(wsi, 0, &p, end) || lws_finalize_http_header(wsi, &p, end) ||
|
||||
lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS) < 0)
|
||||
return AUTH_ERROR;
|
||||
return AUTH_FAIL;
|
||||
|
||||
pss->buffer = pss->ptr = body;
|
||||
pss->len = n;
|
||||
lws_callback_on_writable(wsi);
|
||||
return lws_http_transaction_completed(wsi) ? AUTH_FAIL : AUTH_ERROR;
|
||||
}
|
||||
|
||||
return AUTH_FAIL;
|
||||
static int check_auth(struct lws *wsi, struct pss_http *pss) {
|
||||
if (server->auth_header != NULL) {
|
||||
if (lws_hdr_custom_length(wsi, server->auth_header, strlen(server->auth_header)) > 0) return AUTH_OK;
|
||||
return send_unauthorized(wsi, HTTP_STATUS_PROXY_AUTH_REQUIRED, WSI_TOKEN_HTTP_PROXY_AUTHENTICATE);
|
||||
}
|
||||
|
||||
if(server->credential != NULL) {
|
||||
char buf[256];
|
||||
int len = lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_AUTHORIZATION);
|
||||
if (len >= 7 && strstr(buf, "Basic ")) {
|
||||
if (!strcmp(buf + 6, server->credential)) return AUTH_OK;
|
||||
}
|
||||
return send_unauthorized(wsi, HTTP_STATUS_UNAUTHORIZED, WSI_TOKEN_HTTP_WWW_AUTHENTICATE);
|
||||
}
|
||||
|
||||
return AUTH_OK;
|
||||
}
|
||||
|
||||
static bool accept_gzip(struct lws *wsi) {
|
||||
@@ -89,8 +90,7 @@ static void access_log(struct lws *wsi, const char *path) {
|
||||
lwsl_notice("HTTP %s - %s\n", path, rip);
|
||||
}
|
||||
|
||||
int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in,
|
||||
size_t len) {
|
||||
int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
|
||||
struct pss_http *pss = (struct pss_http *)user;
|
||||
unsigned char buffer[4096 + LWS_PRE], *p, *end;
|
||||
char buf[256];
|
||||
@@ -118,8 +118,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
|
||||
size_t n = sprintf(buf, "{\"token\": \"%s\"}", credential);
|
||||
if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end) ||
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
|
||||
(unsigned char *)"application/json;charset=utf-8", 30, &p,
|
||||
end) ||
|
||||
(unsigned char *)"application/json;charset=utf-8", 30, &p, end) ||
|
||||
lws_add_http_header_content_length(wsi, (unsigned long)n, &p, end) ||
|
||||
lws_finalize_http_header(wsi, &p, end) ||
|
||||
lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS) < 0)
|
||||
@@ -134,11 +133,9 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
|
||||
// redirects `/base-path` to `/base-path/`
|
||||
if (strcmp(pss->path, endpoints.parent) == 0) {
|
||||
if (lws_add_http_header_status(wsi, HTTP_STATUS_FOUND, &p, end) ||
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_LOCATION,
|
||||
(unsigned char *)endpoints.index,
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_LOCATION, (unsigned char *)endpoints.index,
|
||||
(int)strlen(endpoints.index), &p, end) ||
|
||||
lws_add_http_header_content_length(wsi, 0, &p, end) ||
|
||||
lws_finalize_http_header(wsi, &p, end) ||
|
||||
lws_add_http_header_content_length(wsi, 0, &p, end) || lws_finalize_http_header(wsi, &p, end) ||
|
||||
lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS) < 0)
|
||||
return 1;
|
||||
goto try_to_reuse;
|
||||
@@ -157,15 +154,14 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
|
||||
char *output = (char *)index_html;
|
||||
size_t output_len = index_html_len;
|
||||
if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end) ||
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
|
||||
(const unsigned char *)content_type, 9, &p, end))
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (const unsigned char *)content_type, 9, &p,
|
||||
end))
|
||||
return 1;
|
||||
#ifdef LWS_WITH_HTTP_STREAM_COMPRESSION
|
||||
if (!uncompress_html(&output, &output_len)) return 1;
|
||||
#else
|
||||
if (accept_gzip(wsi)) {
|
||||
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_ENCODING,
|
||||
(unsigned char *)"gzip", 4, &p, end))
|
||||
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_ENCODING, (unsigned char *)"gzip", 4, &p, end))
|
||||
return 1;
|
||||
} else {
|
||||
if (!uncompress_html(&output, &output_len)) return 1;
|
||||
|
||||
Reference in New Issue
Block a user