mirror of
https://github.com/tsl0922/ttyd.git
synced 2025-12-24 20:54:21 +01:00
132 lines
4.2 KiB
C
132 lines
4.2 KiB
C
#include "server.h"
|
|
#include "html.h"
|
|
|
|
int
|
|
check_auth(struct lws *wsi) {
|
|
if (server->credential == NULL)
|
|
return 0;
|
|
|
|
int hdr_length = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_AUTHORIZATION);
|
|
char buf[hdr_length + 1];
|
|
int len = lws_hdr_copy(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_AUTHORIZATION);
|
|
if (len > 0) {
|
|
// extract base64 text from authorization header
|
|
char *ptr = &buf[0];
|
|
char *token, *b64_text = NULL;
|
|
int i = 1;
|
|
while ((token = strsep(&ptr, " ")) != NULL) {
|
|
if (strlen(token) == 0)
|
|
continue;
|
|
if (i++ == 2) {
|
|
b64_text = strdup(token);
|
|
break;
|
|
}
|
|
}
|
|
if (b64_text != NULL && strcmp(b64_text, server->credential) == 0)
|
|
return 0;
|
|
}
|
|
|
|
unsigned char buffer[1024 + LWS_PRE], *p, *end;
|
|
p = buffer + LWS_PRE;
|
|
end = p + sizeof(buffer) - LWS_PRE;
|
|
|
|
if (lws_add_http_header_status(wsi, HTTP_STATUS_UNAUTHORIZED, &p, end))
|
|
return 1;
|
|
if (lws_add_http_header_by_token(wsi,
|
|
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
|
|
(unsigned char *) "Basic realm=\"ttyd\"",
|
|
18, &p, end))
|
|
return 1;
|
|
if (lws_add_http_header_content_length(wsi, 0, &p, end))
|
|
return 1;
|
|
if (lws_finalize_http_header(wsi, &p, end))
|
|
return 1;
|
|
if (lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS) < 0)
|
|
return 1;
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
|
|
unsigned char buffer[4096 + LWS_PRE], *p, *end;
|
|
char buf[256];
|
|
int n;
|
|
|
|
switch (reason) {
|
|
case LWS_CALLBACK_HTTP:
|
|
lwsl_notice("lws_http_serve: %s\n", in);
|
|
|
|
{
|
|
char name[100], rip[50];
|
|
lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi), name,
|
|
sizeof(name), rip, sizeof(rip));
|
|
sprintf(buf, "%s (%s)", name, rip);
|
|
lwsl_notice("HTTP connect from %s\n", buf);
|
|
}
|
|
|
|
if (len < 1) {
|
|
lws_return_http_status(wsi, HTTP_STATUS_BAD_REQUEST, NULL);
|
|
goto try_to_reuse;
|
|
}
|
|
|
|
// TODO: this doesn't work for websocket
|
|
switch (check_auth(wsi)) {
|
|
case 1:
|
|
return 1;
|
|
case -1:
|
|
goto try_to_reuse;
|
|
case 0:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// if a legal POST URL, let it continue and accept data
|
|
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI))
|
|
return 0;
|
|
|
|
if (strcmp((const char *) in, "/")) {
|
|
lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
|
|
goto try_to_reuse;
|
|
}
|
|
|
|
p = buffer + LWS_PRE;
|
|
end = p + sizeof(buffer) - LWS_PRE;
|
|
|
|
if (lws_add_http_header_status(wsi, 200, &p, end))
|
|
return 1;
|
|
if (lws_add_http_header_by_token(wsi,
|
|
WSI_TOKEN_HTTP_CONTENT_TYPE,
|
|
(unsigned char *) "text/html",
|
|
9, &p, end))
|
|
return 1;
|
|
if (lws_add_http_header_content_length(wsi, index_html_len, &p, end))
|
|
return 1;
|
|
if (lws_finalize_http_header(wsi, &p, end))
|
|
return 1;
|
|
n = lws_write(wsi, buffer + LWS_PRE, p - (buffer + LWS_PRE), LWS_WRITE_HTTP_HEADERS);
|
|
if (n < 0) {
|
|
return 1;
|
|
}
|
|
|
|
n = lws_write_http(wsi, index_html, index_html_len);
|
|
if (n < 0)
|
|
return 1;
|
|
goto try_to_reuse;
|
|
case LWS_CALLBACK_HTTP_WRITEABLE:
|
|
lwsl_info("LWS_CALLBACK_HTTP_WRITEABLE\n");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
|
|
/* if we're on HTTP1.1 or 2.0, will keep the idle connection alive */
|
|
try_to_reuse:
|
|
if (lws_http_transaction_completed(wsi))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|