1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-05 16:55:50 +03:00

use filters consistently

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1901502 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Covener
2022-06-01 12:36:13 +00:00
parent ea2c3409f6
commit 11a3fcbf9e

View File

@@ -2228,23 +2228,20 @@ static int lua_websocket_greet(lua_State *L)
return 0; return 0;
} }
static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer, static apr_status_t lua_websocket_readbytes(conn_rec* c,
apr_off_t len) apr_bucket_brigade *brigade,
char* buffer, apr_off_t len)
{ {
apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc); apr_size_t delivered;
apr_status_t rv; apr_status_t rv;
rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES, rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES,
APR_BLOCK_READ, len); APR_BLOCK_READ, len);
if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) {
if (!APR_BRIGADE_EMPTY(brigade)) { delivered = len;
apr_bucket* bucket = APR_BRIGADE_FIRST(brigade); rv = apr_brigade_flatten(brigade, buffer, &delivered);
const char* data = NULL; if ((rv == APR_SUCCESS) && (delivered < len)) {
apr_size_t data_length = 0; rv = APR_INCOMPLETE;
rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ);
if (rv == APR_SUCCESS) {
memcpy(buffer, data, len);
}
apr_bucket_delete(bucket);
} }
} }
apr_brigade_cleanup(brigade); apr_brigade_cleanup(brigade);
@@ -2274,35 +2271,28 @@ static int lua_websocket_peek(lua_State *L)
static int lua_websocket_read(lua_State *L) static int lua_websocket_read(lua_State *L)
{ {
apr_socket_t *sock;
apr_status_t rv; apr_status_t rv;
int do_read = 1; int do_read = 1;
int n = 0; int n = 0;
apr_size_t len = 1;
apr_size_t plen = 0; apr_size_t plen = 0;
unsigned short payload_short = 0; unsigned short payload_short = 0;
apr_uint64_t payload_long = 0; apr_uint64_t payload_long = 0;
unsigned char *mask_bytes; unsigned char *mask_bytes;
char byte; char byte;
int plaintext; apr_bucket_brigade *brigade;
conn_rec* c;
request_rec *r = ap_lua_check_request_rec(L, 1); request_rec *r = ap_lua_check_request_rec(L, 1);
plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1; c = r->connection;
mask_bytes = apr_pcalloc(r->pool, 4); mask_bytes = apr_pcalloc(r->pool, 4);
sock = ap_get_conn_socket(r->connection);
brigade = apr_brigade_create(r->pool, c->bucket_alloc);
while (do_read) { while (do_read) {
do_read = 0; do_read = 0;
/* Get opcode and FIN bit */ /* Get opcode and FIN bit */
if (plaintext) { rv = lua_websocket_readbytes(c, brigade, &byte, 1);
rv = apr_socket_recv(sock, &byte, &len);
}
else {
rv = lua_websocket_readbytes(r->connection, &byte, 1);
}
if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) {
unsigned char ubyte, fin, opcode, mask, payload; unsigned char ubyte, fin, opcode, mask, payload;
ubyte = (unsigned char)byte; ubyte = (unsigned char)byte;
@@ -2312,12 +2302,7 @@ static int lua_websocket_read(lua_State *L)
opcode = ubyte & 0xf; opcode = ubyte & 0xf;
/* Get the payload length and mask bit */ /* Get the payload length and mask bit */
if (plaintext) { rv = lua_websocket_readbytes(c, brigade, &byte, 1);
rv = apr_socket_recv(sock, &byte, &len);
}
else {
rv = lua_websocket_readbytes(r->connection, &byte, 1);
}
if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) {
ubyte = (unsigned char)byte; ubyte = (unsigned char)byte;
/* Mask is the first bit */ /* Mask is the first bit */
@@ -2328,40 +2313,25 @@ static int lua_websocket_read(lua_State *L)
/* Extended payload? */ /* Extended payload? */
if (payload == 126) { if (payload == 126) {
len = 2; rv = lua_websocket_readbytes(c, brigade,
if (plaintext) { (char*) &payload_short, 2);
/* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
rv = apr_socket_recv(sock, (char*) &payload_short, &len);
}
else {
rv = lua_websocket_readbytes(r->connection,
(char*) &payload_short, 2);
}
payload_short = ntohs(payload_short);
if (rv == APR_SUCCESS) { if (rv != APR_SUCCESS) {
plen = payload_short;
}
else {
return 0; return 0;
} }
plen = ntohs(payload_short);
} }
/* Super duper extended payload? */ /* Super duper extended payload? */
if (payload == 127) { if (payload == 127) {
len = 8; rv = lua_websocket_readbytes(c, brigade,
if (plaintext) { (char*) &payload_long, 8);
rv = apr_socket_recv(sock, (char*) &payload_long, &len);
} if (rv != APR_SUCCESS) {
else {
rv = lua_websocket_readbytes(r->connection,
(char*) &payload_long, 8);
}
if (rv == APR_SUCCESS) {
plen = ap_ntoh64(&payload_long);
}
else {
return 0; return 0;
} }
plen = ap_ntoh64(&payload_long);
} }
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
"Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s",
@@ -2370,46 +2340,27 @@ static int lua_websocket_read(lua_State *L)
mask ? "on" : "off", mask ? "on" : "off",
fin ? "This is a final frame" : "more to follow"); fin ? "This is a final frame" : "more to follow");
if (mask) { if (mask) {
len = 4; rv = lua_websocket_readbytes(c, brigade,
if (plaintext) { (char*) mask_bytes, 4);
rv = apr_socket_recv(sock, (char*) mask_bytes, &len);
}
else {
rv = lua_websocket_readbytes(r->connection,
(char*) mask_bytes, 4);
}
if (rv != APR_SUCCESS) { if (rv != APR_SUCCESS) {
return 0; return 0;
} }
} }
if (plen < (HUGE_STRING_LEN*1024) && plen > 0) { if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
apr_size_t remaining = plen; apr_size_t remaining = plen;
apr_size_t received;
apr_off_t at = 0;
char *buffer = apr_palloc(r->pool, plen+1); char *buffer = apr_palloc(r->pool, plen+1);
buffer[plen] = 0; buffer[plen] = 0;
if (plaintext) { rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
while (remaining > 0) {
received = remaining; if (rv != APR_SUCCESS) {
rv = apr_socket_recv(sock, buffer+at, &received); return 0;
if (received > 0 ) {
remaining -= received;
at += received;
}
}
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack",
at);
}
else {
rv = lua_websocket_readbytes(r->connection, buffer,
remaining);
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\
"pushed to Lua stack",
remaining);
} }
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"Websocket: Frame contained %" APR_SIZE_T_FMT \
" bytes, pushed to Lua stack", remaining);
if (mask) { if (mask) {
for (n = 0; n < plen; n++) { for (n = 0; n < plen; n++) {
buffer[n] ^= mask_bytes[n%4]; buffer[n] ^= mask_bytes[n%4];
@@ -2421,14 +2372,25 @@ static int lua_websocket_read(lua_State *L)
return 2; return 2;
} }
/* Decide if we need to react to the opcode or not */ /* Decide if we need to react to the opcode or not */
if (opcode == 0x09) { /* ping */ if (opcode == 0x09) { /* ping */
char frame[2]; char frame[2];
plen = 2; apr_bucket *b;
frame[0] = 0x8A; frame[0] = 0x8A;
frame[1] = 0; frame[1] = 0;
apr_socket_send(sock, frame, &plen); /* Pong! */
/* Pong! */
b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, b);
rv = ap_pass_brigade(c->output_filters, brigade);
apr_brigade_cleanup(brigade);
if (rv != APR_SUCCESS) {
return 0;
}
do_read = 1; do_read = 1;
} }
} }