Use sock in fastcgi
This commit is contained in:
@ -15,7 +15,6 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
// TODO use pipes for stdin, stdout, stderr in FastCGI
|
// TODO use pipes for stdin, stdout, stderr in FastCGI
|
||||||
|
|
||||||
@ -28,20 +27,14 @@ char *fastcgi_add_param(char *buf, const char *key, const char *value) {
|
|||||||
ptr[0] = (char) (key_len & 0x7F);
|
ptr[0] = (char) (key_len & 0x7F);
|
||||||
ptr++;
|
ptr++;
|
||||||
} else {
|
} else {
|
||||||
ptr[0] = (char) (0x80 | (key_len >> 24));
|
*((int *) ptr) = htonl(0x80000000 | key_len);
|
||||||
ptr[1] = (char) ((key_len >> 16) & 0xFF);
|
|
||||||
ptr[2] = (char) ((key_len >> 8) & 0xFF);
|
|
||||||
ptr[3] = (char) (key_len & 0xFF);
|
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
if (val_len <= 127) {
|
if (val_len <= 127) {
|
||||||
ptr[0] = (char) (val_len & 0x7F);
|
ptr[0] = (char) (val_len & 0x7F);
|
||||||
ptr++;
|
ptr++;
|
||||||
} else {
|
} else {
|
||||||
ptr[0] = (char) (0x80 | (val_len >> 24));
|
*((int *) ptr) = htonl(0x80000000 | val_len);
|
||||||
ptr[1] = (char) ((val_len >> 16) & 0xFF);
|
|
||||||
ptr[2] = (char) ((val_len >> 8) & 0xFF);
|
|
||||||
ptr[3] = (char) (val_len & 0xFF);
|
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +46,33 @@ char *fastcgi_add_param(char *buf, const char *key, const char *value) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fastcgi_send_data(fastcgi_cnx_t *cnx, unsigned char type, unsigned short len, void *data) {
|
||||||
|
// build header
|
||||||
|
FCGI_Header header = {
|
||||||
|
.version = FCGI_VERSION_1,
|
||||||
|
.type = type,
|
||||||
|
.requestId = htons(cnx->req_id),
|
||||||
|
.contentLength = htons(len),
|
||||||
|
.paddingLength = 0,
|
||||||
|
.reserved = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// send FastCGI header with MSG_MORE flag
|
||||||
|
if (sock_send_x(&cnx->socket, &header, sizeof(header), (len != 0) ? MSG_MORE : 0) == -1) {
|
||||||
|
error("Unable to send to FastCGI socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send data (if available)
|
||||||
|
if (sock_send_x(&cnx->socket, data, len, 0) == -1) {
|
||||||
|
error("Unable to send to FastCGI socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return bytes sent totally
|
||||||
|
return len + (int) sizeof(header);
|
||||||
|
}
|
||||||
|
|
||||||
int fastcgi_init(fastcgi_cnx_t *conn, int mode, unsigned int req_num, const sock *client, const http_req *req, const http_uri *uri) {
|
int fastcgi_init(fastcgi_cnx_t *conn, int mode, unsigned int req_num, const sock *client, const http_req *req, const http_uri *uri) {
|
||||||
conn->mode = mode;
|
conn->mode = mode;
|
||||||
conn->req_id = (req_num + 1) & 0xFFFF;
|
conn->req_id = (req_num + 1) & 0xFFFF;
|
||||||
@ -60,45 +80,32 @@ int fastcgi_init(fastcgi_cnx_t *conn, int mode, unsigned int req_num, const sock
|
|||||||
conn->out_off = 0;
|
conn->out_off = 0;
|
||||||
conn->webroot = uri->webroot;
|
conn->webroot = uri->webroot;
|
||||||
|
|
||||||
int fcgi_sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
conn->socket.enc = 0;
|
||||||
if (fcgi_sock < 0) {
|
if ((conn->socket.socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||||
error("Unable to create unix socket");
|
error("Unable to create unix socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
conn->socket = fcgi_sock;
|
|
||||||
|
|
||||||
struct sockaddr_un sock_addr = {AF_UNIX};
|
struct sockaddr_un sock_addr = { AF_UNIX };
|
||||||
if (conn->mode == FASTCGI_BACKEND_PHP) {
|
if (conn->mode == FASTCGI_BACKEND_PHP) {
|
||||||
snprintf(sock_addr.sun_path, sizeof(sock_addr.sun_path) - 1, "%s", PHP_FPM_SOCKET);
|
strcpy(sock_addr.sun_path, PHP_FPM_SOCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect(conn->socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) {
|
if (connect(conn->socket.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) != 0) {
|
||||||
error("Unable to connect to unix socket of FastCGI socket");
|
error("Unable to connect to unix socket of FastCGI socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FCGI_Header header = {
|
FCGI_BeginRequestBody begin = {
|
||||||
.version = FCGI_VERSION_1,
|
.role = htons(FCGI_RESPONDER),
|
||||||
.requestId = htons(conn->req_id),
|
.flags = 0,
|
||||||
.paddingLength = 0,
|
.reserved = {0},
|
||||||
.reserved = 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
header.type = FCGI_BEGIN_REQUEST;
|
if (fastcgi_send_data(conn, FCGI_BEGIN_REQUEST, sizeof(begin), &begin) == -1)
|
||||||
header.contentLength = htons(sizeof(FCGI_BeginRequestBody));
|
return -1;
|
||||||
FCGI_BeginRequestRecord begin = {
|
|
||||||
header,
|
|
||||||
{.roleB1 = (FCGI_RESPONDER >> 8) & 0xFF, .roleB0 = FCGI_RESPONDER & 0xFF, .flags = 0}
|
|
||||||
};
|
|
||||||
if (send(conn->socket, &begin, sizeof(begin), 0) != sizeof(begin)) {
|
|
||||||
error("Unable to send to FastCGI socket");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
char param_buf[4096];
|
|
||||||
char buf0[256];
|
|
||||||
char *param_ptr = param_buf + sizeof(header);
|
|
||||||
|
|
||||||
|
char param_buf[4096], buf0[256], *param_ptr = param_buf;
|
||||||
param_ptr = fastcgi_add_param(param_ptr, "REDIRECT_STATUS", "CGI");
|
param_ptr = fastcgi_add_param(param_ptr, "REDIRECT_STATUS", "CGI");
|
||||||
param_ptr = fastcgi_add_param(param_ptr, "DOCUMENT_ROOT", uri->webroot);
|
param_ptr = fastcgi_add_param(param_ptr, "DOCUMENT_ROOT", uri->webroot);
|
||||||
param_ptr = fastcgi_add_param(param_ptr, "GATEWAY_INTERFACE", "CGI/1.1");
|
param_ptr = fastcgi_add_param(param_ptr, "GATEWAY_INTERFACE", "CGI/1.1");
|
||||||
@ -170,39 +177,18 @@ int fastcgi_init(fastcgi_cnx_t *conn, int mode, unsigned int req_num, const sock
|
|||||||
param_ptr = fastcgi_add_param(param_ptr, buf0, http_field_get_value(f));
|
param_ptr = fastcgi_add_param(param_ptr, buf0, http_field_get_value(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short param_len = param_ptr - param_buf - sizeof(header);
|
if (fastcgi_send_data(conn, FCGI_PARAMS, param_ptr - param_buf, param_buf) == -1)
|
||||||
header.type = FCGI_PARAMS;
|
return -1;
|
||||||
header.contentLength = htons(param_len);
|
|
||||||
memcpy(param_buf, &header, sizeof(header));
|
|
||||||
if (send(conn->socket, param_buf, param_len + sizeof(header), 0) != param_len + sizeof(header)) {
|
|
||||||
error("Unable to send to FastCGI socket");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.type = FCGI_PARAMS;
|
if (fastcgi_send_data(conn, FCGI_PARAMS, 0, NULL) == -1)
|
||||||
header.contentLength = htons(0);
|
return -1;
|
||||||
if (send(conn->socket, &header, sizeof(header), 0) != sizeof(header)) {
|
|
||||||
error("Unable to send to FastCGI socket");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fastcgi_close_stdin(fastcgi_cnx_t *conn) {
|
int fastcgi_close_stdin(fastcgi_cnx_t *conn) {
|
||||||
FCGI_Header header = {
|
if (fastcgi_send_data(conn, FCGI_STDIN, 0, NULL) == -1)
|
||||||
.version = FCGI_VERSION_1,
|
return -1;
|
||||||
.type = FCGI_STDIN,
|
|
||||||
.requestId = htons(conn->req_id),
|
|
||||||
.contentLength = htons(0),
|
|
||||||
.paddingLength = 0,
|
|
||||||
.reserved = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
if (send(conn->socket, &header, sizeof(header), 0) != sizeof(header)) {
|
|
||||||
error("Unable to send to FastCGI socket");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -282,8 +268,7 @@ int fastcgi_header(fastcgi_cnx_t *conn, http_res *res, char *err_msg) {
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = recv(conn->socket, &header, sizeof(header), 0);
|
if (sock_recv_x(&conn->socket, &header, sizeof(header), 0) == -1) {
|
||||||
if (ret != sizeof(header)) {
|
|
||||||
res->status = http_get_status(500);
|
res->status = http_get_status(500);
|
||||||
sprintf(err_msg, "Unable to communicate with FastCGI socket.");
|
sprintf(err_msg, "Unable to communicate with FastCGI socket.");
|
||||||
error("Unable to receive from FastCGI socket");
|
error("Unable to receive from FastCGI socket");
|
||||||
@ -292,8 +277,7 @@ int fastcgi_header(fastcgi_cnx_t *conn, http_res *res, char *err_msg) {
|
|||||||
req_id = ntohs(header.requestId);
|
req_id = ntohs(header.requestId);
|
||||||
content_len = ntohs(header.contentLength);
|
content_len = ntohs(header.contentLength);
|
||||||
content = malloc(content_len + header.paddingLength);
|
content = malloc(content_len + header.paddingLength);
|
||||||
ret = recv(conn->socket, content, content_len + header.paddingLength, 0);
|
if (sock_recv_x(&conn->socket, content, content_len + header.paddingLength, 0) == -1) {
|
||||||
if (ret != (content_len + header.paddingLength)) {
|
|
||||||
res->status = http_get_status(500);
|
res->status = http_get_status(500);
|
||||||
sprintf(err_msg, "Unable to communicate with FastCGI socket.");
|
sprintf(err_msg, "Unable to communicate with FastCGI socket.");
|
||||||
error("Unable to receive from FastCGI socket");
|
error("Unable to receive from FastCGI socket");
|
||||||
@ -307,16 +291,14 @@ int fastcgi_header(fastcgi_cnx_t *conn, http_res *res, char *err_msg) {
|
|||||||
|
|
||||||
if (header.type == FCGI_END_REQUEST) {
|
if (header.type == FCGI_END_REQUEST) {
|
||||||
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
||||||
int app_status = (body->appStatusB3 << 24) | (body->appStatusB2 << 16) | (body->appStatusB1 << 8) |
|
int app_status = ntohl(body->appStatus);
|
||||||
body->appStatusB0;
|
|
||||||
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
||||||
error("FastCGI protocol error: %i", body->protocolStatus);
|
error("FastCGI protocol error: %i", body->protocolStatus);
|
||||||
}
|
}
|
||||||
if (app_status != 0) {
|
if (app_status != 0) {
|
||||||
error("FastCGI app terminated with exit code %i", app_status);
|
error("FastCGI app terminated with exit code %i", app_status);
|
||||||
}
|
}
|
||||||
close(conn->socket);
|
sock_close(&conn->socket);
|
||||||
conn->socket = 0;
|
|
||||||
free(content);
|
free(content);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (header.type == FCGI_STDERR) {
|
} else if (header.type == FCGI_STDERR) {
|
||||||
@ -379,7 +361,7 @@ int fastcgi_send(fastcgi_cnx_t *conn, sock *client, int flags) {
|
|||||||
long ret;
|
long ret;
|
||||||
char buf0[256], *content, *ptr;
|
char buf0[256], *content, *ptr;
|
||||||
int len;
|
int len;
|
||||||
unsigned short req_id, content_len;
|
unsigned short content_len;
|
||||||
|
|
||||||
if (conn->out_buf != NULL && conn->out_len > conn->out_off) {
|
if (conn->out_buf != NULL && conn->out_len > conn->out_off) {
|
||||||
content = conn->out_buf;
|
content = conn->out_buf;
|
||||||
@ -389,23 +371,18 @@ int fastcgi_send(fastcgi_cnx_t *conn, sock *client, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = recv(conn->socket, &header, sizeof(header), 0);
|
if ((sock_recv_x(&conn->socket, &header, sizeof(header), 0)) == -1) {
|
||||||
if (ret < 0) {
|
|
||||||
error("Unable to receive from FastCGI socket");
|
error("Unable to receive from FastCGI socket");
|
||||||
return -1;
|
return -1;
|
||||||
} else if (ret != sizeof(header)) {
|
|
||||||
error("Unable to receive from FastCGI socket: received len (%li) != header len (%li)", ret, sizeof(header));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req_id = ntohs(header.requestId);
|
|
||||||
content_len = ntohs(header.contentLength);
|
content_len = ntohs(header.contentLength);
|
||||||
content = malloc(content_len + header.paddingLength);
|
content = malloc(content_len + header.paddingLength);
|
||||||
ptr = content;
|
ptr = content;
|
||||||
|
|
||||||
long rcv_len = 0;
|
long rcv_len = 0;
|
||||||
while (rcv_len < content_len + header.paddingLength) {
|
while (rcv_len < content_len + header.paddingLength) {
|
||||||
ret = recv(conn->socket, content + rcv_len, content_len + header.paddingLength - rcv_len, 0);
|
ret = sock_recv(&conn->socket, content + rcv_len, content_len + header.paddingLength - rcv_len, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error("Unable to receive from FastCGI socket");
|
error("Unable to receive from FastCGI socket");
|
||||||
free(content);
|
free(content);
|
||||||
@ -416,16 +393,14 @@ int fastcgi_send(fastcgi_cnx_t *conn, sock *client, int flags) {
|
|||||||
|
|
||||||
if (header.type == FCGI_END_REQUEST) {
|
if (header.type == FCGI_END_REQUEST) {
|
||||||
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
||||||
int app_status = (body->appStatusB3 << 24) | (body->appStatusB2 << 16) | (body->appStatusB1 << 8) |
|
int app_status = ntohl(body->appStatus);
|
||||||
body->appStatusB0;
|
|
||||||
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
||||||
error("FastCGI protocol error: %i", body->protocolStatus);
|
error("FastCGI protocol error: %i", body->protocolStatus);
|
||||||
}
|
}
|
||||||
if (app_status != 0) {
|
if (app_status != 0) {
|
||||||
error("FastCGI app terminated with exit code %i", app_status);
|
error("FastCGI app terminated with exit code %i", app_status);
|
||||||
}
|
}
|
||||||
close(conn->socket);
|
sock_close(&conn->socket);
|
||||||
conn->socket = 0;
|
|
||||||
free(content);
|
free(content);
|
||||||
|
|
||||||
if (flags & FASTCGI_CHUNKED) {
|
if (flags & FASTCGI_CHUNKED) {
|
||||||
@ -457,29 +432,24 @@ int fastcgi_dump(fastcgi_cnx_t *conn, char *buf, long len) {
|
|||||||
long ret;
|
long ret;
|
||||||
char buf0[256];
|
char buf0[256];
|
||||||
char *content, *ptr = buf;
|
char *content, *ptr = buf;
|
||||||
unsigned short req_id, content_len;
|
unsigned short content_len;
|
||||||
|
|
||||||
if (conn->out_buf != NULL && conn->out_len > conn->out_off) {
|
if (conn->out_buf != NULL && conn->out_len > conn->out_off) {
|
||||||
ptr += snprintf(ptr, len, "%.*s", conn->out_len - conn->out_off, conn->out_buf + conn->out_off);
|
ptr += snprintf(ptr, len, "%.*s", conn->out_len - conn->out_off, conn->out_buf + conn->out_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = recv(conn->socket, &header, sizeof(header), 0);
|
if (sock_recv_x(&conn->socket, &header, sizeof(header), 0) == -1) {
|
||||||
if (ret < 0) {
|
|
||||||
error("Unable to receive from FastCGI socket");
|
error("Unable to receive from FastCGI socket");
|
||||||
return -1;
|
return -1;
|
||||||
} else if (ret != sizeof(header)) {
|
|
||||||
error("Unable to receive from FastCGI socket: received len (%li) != header len (%li)", ret, sizeof(header));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req_id = ntohs(header.requestId);
|
|
||||||
content_len = ntohs(header.contentLength);
|
content_len = ntohs(header.contentLength);
|
||||||
content = malloc(content_len + header.paddingLength);
|
content = malloc(content_len + header.paddingLength);
|
||||||
|
|
||||||
long rcv_len = 0;
|
long rcv_len = 0;
|
||||||
while (rcv_len < content_len + header.paddingLength) {
|
while (rcv_len < content_len + header.paddingLength) {
|
||||||
ret = recv(conn->socket, content + rcv_len, content_len + header.paddingLength - rcv_len, 0);
|
ret = sock_recv(&conn->socket, content + rcv_len, content_len + header.paddingLength - rcv_len, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error("Unable to receive from FastCGI socket");
|
error("Unable to receive from FastCGI socket");
|
||||||
free(content);
|
free(content);
|
||||||
@ -490,16 +460,14 @@ int fastcgi_dump(fastcgi_cnx_t *conn, char *buf, long len) {
|
|||||||
|
|
||||||
if (header.type == FCGI_END_REQUEST) {
|
if (header.type == FCGI_END_REQUEST) {
|
||||||
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
||||||
int app_status = (body->appStatusB3 << 24) | (body->appStatusB2 << 16) | (body->appStatusB1 << 8) |
|
int app_status = ntohl(body->appStatus);
|
||||||
body->appStatusB0;
|
|
||||||
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
||||||
error("FastCGI protocol error: %i", body->protocolStatus);
|
error("FastCGI protocol error: %i", body->protocolStatus);
|
||||||
}
|
}
|
||||||
if (app_status != 0) {
|
if (app_status != 0) {
|
||||||
error("FastCGI app terminated with exit code %i", app_status);
|
error("FastCGI app terminated with exit code %i", app_status);
|
||||||
}
|
}
|
||||||
close(conn->socket);
|
sock_close(&conn->socket);
|
||||||
conn->socket = 0;
|
|
||||||
free(content);
|
free(content);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -517,50 +485,31 @@ int fastcgi_dump(fastcgi_cnx_t *conn, char *buf, long len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int fastcgi_receive(fastcgi_cnx_t *conn, sock *client, unsigned long len) {
|
int fastcgi_receive(fastcgi_cnx_t *conn, sock *client, unsigned long len) {
|
||||||
unsigned long rcv_len = 0;
|
|
||||||
char *buf[16384];
|
char *buf[16384];
|
||||||
long ret;
|
|
||||||
FCGI_Header header = {
|
|
||||||
.version = FCGI_VERSION_1,
|
|
||||||
.type = FCGI_STDIN,
|
|
||||||
.requestId = htons(conn->req_id),
|
|
||||||
.contentLength = htons(0),
|
|
||||||
.paddingLength = 0,
|
|
||||||
.reserved = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
while (rcv_len < len) {
|
for (long to_send = (long) len, ret; to_send > 0; to_send -= ret) {
|
||||||
ret = sock_recv(client, buf, sizeof(buf), 0);
|
if ((ret = sock_recv(client, buf, (to_send > sizeof(buf)) ? sizeof(buf) : to_send, 0)) <= 0) {
|
||||||
if (ret <= 0) {
|
|
||||||
error("Unable to receive");
|
error("Unable to receive");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcv_len += ret;
|
if (fastcgi_send_data(conn, FCGI_STDIN, ret, buf) == -1)
|
||||||
header.contentLength = htons(ret);
|
return -1;
|
||||||
if (send(conn->socket, &header, sizeof(header), 0) != sizeof(header)) goto err;
|
|
||||||
if (send(conn->socket, buf, ret, 0) != ret) {
|
|
||||||
err:
|
|
||||||
error("Unable to send to FastCGI socket");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fastcgi_receive_chunked(fastcgi_cnx_t *conn, sock *client) {
|
int fastcgi_receive_chunked(fastcgi_cnx_t *conn, sock *client) {
|
||||||
long ret;
|
for (long ret;;) {
|
||||||
unsigned long next_len;
|
if ((ret = sock_get_chunk_header(client)) < 0) {
|
||||||
|
return (int) ret;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
if ((ret = fastcgi_receive(conn, client, ret)) < 0)
|
||||||
ret = sock_get_chunk_header(client);
|
return (int) ret;
|
||||||
if (ret < 0) return (int) ret;
|
|
||||||
|
|
||||||
next_len = ret;
|
|
||||||
if (next_len <= 0) break;
|
|
||||||
|
|
||||||
ret = fastcgi_receive(conn, client, next_len);
|
|
||||||
if (ret < 0) return (int) ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int mode;
|
int mode;
|
||||||
int socket;
|
sock socket;
|
||||||
|
int in, out, err;
|
||||||
unsigned short req_id;
|
unsigned short req_id;
|
||||||
const char *webroot;
|
const char *webroot;
|
||||||
char *out_buf;
|
char *out_buf;
|
||||||
|
@ -251,8 +251,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
if (header_len < 0)
|
if (header_len < 0)
|
||||||
return (int) -header_len;
|
return (int) -header_len;
|
||||||
|
|
||||||
rcv_len = sock_recv(client, buf, header_len, 0);
|
if (sock_recv_x(client, buf, header_len, 0) == -1)
|
||||||
if (rcv_len != header_len)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -54,8 +54,7 @@ typedef struct {
|
|||||||
#define FCGI_NULL_REQUEST_ID 0
|
#define FCGI_NULL_REQUEST_ID 0
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char roleB1;
|
unsigned short role;
|
||||||
unsigned char roleB0;
|
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
unsigned char reserved[5];
|
unsigned char reserved[5];
|
||||||
} FCGI_BeginRequestBody;
|
} FCGI_BeginRequestBody;
|
||||||
@ -78,10 +77,7 @@ typedef struct {
|
|||||||
#define FCGI_FILTER 3
|
#define FCGI_FILTER 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char appStatusB3;
|
unsigned int appStatus;
|
||||||
unsigned char appStatusB2;
|
|
||||||
unsigned char appStatusB1;
|
|
||||||
unsigned char appStatusB0;
|
|
||||||
unsigned char protocolStatus;
|
unsigned char protocolStatus;
|
||||||
unsigned char reserved[3];
|
unsigned char reserved[3];
|
||||||
} FCGI_EndRequestBody;
|
} FCGI_EndRequestBody;
|
||||||
|
@ -549,7 +549,7 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu
|
|||||||
}
|
}
|
||||||
ptr = pos0 + 2;
|
ptr = pos0 + 2;
|
||||||
}
|
}
|
||||||
sock_recv(&proxy->proxy, buffer, header_len, 0);
|
sock_recv_x(&proxy->proxy, buffer, header_len, 0);
|
||||||
|
|
||||||
ret = proxy_response_header(req, res, conf);
|
ret = proxy_response_header(req, res, conf);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -654,7 +654,7 @@ int proxy_send(proxy_ctx_t *proxy, sock *client, unsigned long len_to_send, int
|
|||||||
if (finish_comp) goto finish;
|
if (finish_comp) goto finish;
|
||||||
}
|
}
|
||||||
if (ret <= 0) break;
|
if (ret <= 0) break;
|
||||||
if (flags & PROXY_CHUNKED) sock_recv(&proxy->proxy, buffer, 2, 0);
|
if (flags & PROXY_CHUNKED) sock_recv_x(&proxy->proxy, buffer, 2, 0);
|
||||||
} while ((flags & PROXY_CHUNKED) && len_to_send > 0);
|
} while ((flags & PROXY_CHUNKED) && len_to_send > 0);
|
||||||
|
|
||||||
if (ret <= 0) return -1;
|
if (ret <= 0) return -1;
|
||||||
|
@ -107,13 +107,17 @@ long sock_send(sock *s, void *buf, unsigned long len, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long sock_send_x(sock *s, void *buf, unsigned long len, int flags) {
|
long sock_send_x(sock *s, void *buf, unsigned long len, int flags) {
|
||||||
long sent = 0;
|
for (long ret, sent = 0; sent < len; sent += ret) {
|
||||||
for (long ret; sent < len; sent += ret) {
|
if ((ret = sock_send(s, (unsigned char *) buf + sent, len - sent, flags)) <= 0) {
|
||||||
ret = sock_send(s, (unsigned char *) buf + sent, len - sent, flags);
|
if (errno == EINTR) {
|
||||||
if (ret <= 0)
|
errno = 0, ret = 0;
|
||||||
return ret;
|
continue;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return sent;
|
}
|
||||||
|
}
|
||||||
|
return (long) len;
|
||||||
}
|
}
|
||||||
|
|
||||||
long sock_recv(sock *s, void *buf, unsigned long len, int flags) {
|
long sock_recv(sock *s, void *buf, unsigned long len, int flags) {
|
||||||
@ -134,6 +138,20 @@ long sock_recv(sock *s, void *buf, unsigned long len, int flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sock_recv_x(sock *s, void *buf, unsigned long len, int flags) {
|
||||||
|
for (long ret, rcv = 0; rcv < len; rcv += ret) {
|
||||||
|
if ((ret = sock_recv(s, (unsigned char *) buf + rcv, len - rcv, flags)) <= 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
errno = 0, ret = 0;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (long) len;
|
||||||
|
}
|
||||||
|
|
||||||
long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len) {
|
long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len) {
|
||||||
long ret;
|
long ret;
|
||||||
unsigned long send_len = 0;
|
unsigned long send_len = 0;
|
||||||
@ -213,16 +231,24 @@ long sock_get_chunk_header(sock *s) {
|
|||||||
char buf[16];
|
char buf[16];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = sock_recv(s, buf, sizeof(buf), MSG_PEEK);
|
if ((ret = sock_recv(s, buf, sizeof(buf) - 1, MSG_PEEK)) <= 0) {
|
||||||
if (ret <= 0) return -2;
|
if (errno == EINTR) {
|
||||||
else if (ret < 2) continue;
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (ret < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
buf[ret] = 0;
|
||||||
|
|
||||||
ret = sock_parse_chunk_header(buf, ret, &len);
|
if ((ret = sock_parse_chunk_header(buf, ret, &len)) == -2)
|
||||||
if (ret == -2) return -1;
|
return -1;
|
||||||
} while (ret < 0);
|
} while (ret < 0);
|
||||||
|
|
||||||
if (sock_recv(s, buf, len, 0) != len)
|
if (sock_recv_x(s, buf, len, 0) == -1)
|
||||||
return -2;
|
return -1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ long sock_send_x(sock *s, void *buf, unsigned long len, int flags);
|
|||||||
|
|
||||||
long sock_recv(sock *s, void *buf, unsigned long len, int flags);
|
long sock_recv(sock *s, void *buf, unsigned long len, int flags);
|
||||||
|
|
||||||
|
long sock_recv_x(sock *s, void *buf, unsigned long len, int flags);
|
||||||
|
|
||||||
long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len);
|
long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len);
|
||||||
|
|
||||||
long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len);
|
long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len);
|
||||||
|
@ -36,13 +36,9 @@ int ws_calc_accept_key(const char *key, char *accept_key) {
|
|||||||
int ws_recv_frame_header(sock *s, ws_frame *frame) {
|
int ws_recv_frame_header(sock *s, ws_frame *frame) {
|
||||||
unsigned char buf[12];
|
unsigned char buf[12];
|
||||||
|
|
||||||
long ret = sock_recv(s, buf, 2, 0);
|
if (sock_recv_x(s, buf, 2, 0) == -1) {
|
||||||
if (ret < 0) {
|
|
||||||
error("Unable to receive from socket");
|
error("Unable to receive from socket");
|
||||||
return -1;
|
return -1;
|
||||||
} else if (ret != 2) {
|
|
||||||
error("Unable to receive 2 bytes from socket");
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short bits = (buf[0] << 8) | buf[1];
|
unsigned short bits = (buf[0] << 8) | buf[1];
|
||||||
@ -61,13 +57,9 @@ int ws_recv_frame_header(sock *s, ws_frame *frame) {
|
|||||||
remaining += 8;
|
remaining += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sock_recv(s, buf, remaining, 0);
|
if (sock_recv_x(s, buf, remaining, 0) == -1) {
|
||||||
if (ret < 0) {
|
|
||||||
error("Unable to receive from socket");
|
error("Unable to receive from socket");
|
||||||
return -1;
|
return -1;
|
||||||
} else if (ret != remaining) {
|
|
||||||
error("Unable to receive correct number of bytes from socket");
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 126) {
|
if (len == 126) {
|
||||||
|
@ -38,7 +38,8 @@ static int fastcgi_handler_1(client_ctx_t *ctx, fastcgi_cnx_t *fcgi_cnx) {
|
|||||||
sock *client = &ctx->socket;
|
sock *client = &ctx->socket;
|
||||||
char *err_msg = ctx->err_msg;
|
char *err_msg = ctx->err_msg;
|
||||||
|
|
||||||
fcgi_cnx->socket = 0;
|
fcgi_cnx->socket.socket = 0;
|
||||||
|
fcgi_cnx->socket.enc = 0;
|
||||||
fcgi_cnx->req_id = 0;
|
fcgi_cnx->req_id = 0;
|
||||||
fcgi_cnx->r_addr = ctx->socket.addr;
|
fcgi_cnx->r_addr = ctx->socket.addr;
|
||||||
fcgi_cnx->r_host = (ctx->host[0] != 0) ? ctx->host : NULL;
|
fcgi_cnx->r_host = (ctx->host[0] != 0) ? ctx->host : NULL;
|
||||||
@ -144,9 +145,8 @@ static int fastcgi_handler_2(client_ctx_t *ctx, fastcgi_cnx_t *fcgi_cnx) {
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcgi_cnx->socket != 0) {
|
if (fcgi_cnx->socket.socket != 0) {
|
||||||
close(fcgi_cnx->socket);
|
sock_close(&fcgi_cnx->socket);
|
||||||
fcgi_cnx->socket = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user