Commit 38d80593 authored by Sergey Lyubka's avatar Sergey Lyubka

Passing mg_connection to pull() function, in order to give it access to the stop status

parent 941500f9
...@@ -1372,11 +1372,11 @@ static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, ...@@ -1372,11 +1372,11 @@ static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf,
// Read from IO channel - opened file descriptor, socket, or SSL descriptor. // Read from IO channel - opened file descriptor, socket, or SSL descriptor.
// Return number of bytes read. // Return number of bytes read.
static int pull(FILE *fp, SOCKET sock, SSL *ssl, char *buf, int len) { static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len) {
int nread; int nread;
if (ssl != NULL) { if (conn->ssl != NULL) {
nread = SSL_read(ssl, buf, len); nread = SSL_read(conn->ssl, buf, len);
} else if (fp != NULL) { } else if (fp != NULL) {
// Use read() instead of fread(), because if we're reading from the CGI // Use read() instead of fread(), because if we're reading from the CGI
// pipe, fread() may block until IO buffer is filled up. We cannot afford // pipe, fread() may block until IO buffer is filled up. We cannot afford
...@@ -1385,7 +1385,7 @@ static int pull(FILE *fp, SOCKET sock, SSL *ssl, char *buf, int len) { ...@@ -1385,7 +1385,7 @@ static int pull(FILE *fp, SOCKET sock, SSL *ssl, char *buf, int len) {
if (ferror(fp)) if (ferror(fp))
nread = -1; nread = -1;
} else { } else {
nread = recv(sock, buf, (size_t) len, 0); nread = recv(conn->client.sock, buf, (size_t) len, 0);
} }
return nread; return nread;
...@@ -1428,7 +1428,7 @@ int mg_read(struct mg_connection *conn, void *buf, size_t len) { ...@@ -1428,7 +1428,7 @@ int mg_read(struct mg_connection *conn, void *buf, size_t len) {
// We have returned all buffered data. Read new data from the remote socket. // We have returned all buffered data. Read new data from the remote socket.
while (len > 0) { while (len > 0) {
n = pull(NULL, conn->client.sock, conn->ssl, (char *) buf, (int) len); n = pull(NULL, conn, (char *) buf, (int) len);
if (n <= 0) { if (n <= 0) {
break; break;
} }
...@@ -2685,14 +2685,14 @@ static int parse_http_response(char *buf, int len, struct mg_request_info *ri) { ...@@ -2685,14 +2685,14 @@ static int parse_http_response(char *buf, int len, struct mg_request_info *ri) {
// buffer (which marks the end of HTTP request). Buffer buf may already // buffer (which marks the end of HTTP request). Buffer buf may already
// have some data. The length of the data is stored in nread. // have some data. The length of the data is stored in nread.
// Upon every read operation, increase nread by the number of bytes read. // Upon every read operation, increase nread by the number of bytes read.
static int read_request(FILE *fp, SOCKET sock, SSL *ssl, char *buf, int bufsiz, static int read_request(FILE *fp, struct mg_connection *conn,
int *nread) { char *buf, int bufsiz, int *nread) {
int request_len, n = 0; int request_len, n = 0;
do { do {
request_len = get_request_len(buf, *nread); request_len = get_request_len(buf, *nread);
if (request_len == 0 && if (request_len == 0 &&
(n = pull(fp, sock, ssl, buf + *nread, bufsiz - *nread)) > 0) { (n = pull(fp, conn, buf + *nread, bufsiz - *nread)) > 0) {
*nread += n; *nread += n;
} }
} while (*nread <= bufsiz && request_len == 0 && n > 0); } while (*nread <= bufsiz && request_len == 0 && n > 0);
...@@ -2794,7 +2794,7 @@ static int forward_body_data(struct mg_connection *conn, FILE *fp, ...@@ -2794,7 +2794,7 @@ static int forward_body_data(struct mg_connection *conn, FILE *fp,
if ((int64_t) to_read > conn->content_len - conn->consumed_content) { if ((int64_t) to_read > conn->content_len - conn->consumed_content) {
to_read = (int) (conn->content_len - conn->consumed_content); to_read = (int) (conn->content_len - conn->consumed_content);
} }
nread = pull(NULL, conn->client.sock, conn->ssl, buf, to_read); nread = pull(NULL, conn, buf, to_read);
if (nread <= 0 || push(fp, sock, ssl, buf, nread) != nread) { if (nread <= 0 || push(fp, sock, ssl, buf, nread) != nread) {
break; break;
} }
...@@ -3033,8 +3033,10 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog) { ...@@ -3033,8 +3033,10 @@ static void handle_cgi_request(struct mg_connection *conn, const char *prog) {
// Do not send anything back to client, until we buffer in all // Do not send anything back to client, until we buffer in all
// HTTP headers. // HTTP headers.
data_len = 0; data_len = 0;
headers_len = read_request(out, INVALID_SOCKET, NULL, struct mg_connection fake;
buf, sizeof(buf), &data_len); fake.client.sock = INVALID_SOCKET;
fake.ssl = NULL;
headers_len = read_request(out, &fake, buf, sizeof(buf), &data_len);
if (headers_len <= 0) { if (headers_len <= 0) {
send_http_error(conn, 500, http_500_error, send_http_error(conn, 500, http_500_error,
"CGI program sent malformed HTTP headers: [%.*s]", "CGI program sent malformed HTTP headers: [%.*s]",
...@@ -3844,10 +3846,10 @@ static void reset_per_request_attributes(struct mg_connection *conn) { ...@@ -3844,10 +3846,10 @@ static void reset_per_request_attributes(struct mg_connection *conn) {
conn->must_close = 0; conn->must_close = 0;
} }
static void close_socket_gracefully(SOCKET sock) { static void close_socket_gracefully(struct mg_connection *conn) {
char buf[MG_BUF_LEN]; char buf[MG_BUF_LEN];
struct linger linger; struct linger linger;
int n; int n, sock = conn->client.sock;
// Set linger option to avoid socket hanging out after close. This prevent // Set linger option to avoid socket hanging out after close. This prevent
// ephemeral port exhaust problem under high QPS. // ephemeral port exhaust problem under high QPS.
...@@ -3865,7 +3867,7 @@ static void close_socket_gracefully(SOCKET sock) { ...@@ -3865,7 +3867,7 @@ static void close_socket_gracefully(SOCKET sock) {
// when server decide to close the connection; then when client // when server decide to close the connection; then when client
// does recv() it gets no data back. // does recv() it gets no data back.
do { do {
n = pull(NULL, sock, NULL, buf, sizeof(buf)); n = pull(NULL, conn, buf, sizeof(buf));
} while (n > 0); } while (n > 0);
// Now we know that our FIN is ACK-ed, safe to close // Now we know that our FIN is ACK-ed, safe to close
...@@ -3879,7 +3881,7 @@ static void close_connection(struct mg_connection *conn) { ...@@ -3879,7 +3881,7 @@ static void close_connection(struct mg_connection *conn) {
} }
if (conn->client.sock != INVALID_SOCKET) { if (conn->client.sock != INVALID_SOCKET) {
close_socket_gracefully(conn->client.sock); close_socket_gracefully(conn);
} }
} }
...@@ -3948,8 +3950,7 @@ FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path, ...@@ -3948,8 +3950,7 @@ FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
} else { } else {
mg_printf(newconn, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", url + n, host); mg_printf(newconn, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", url + n, host);
data_length = 0; data_length = 0;
req_length = read_request(NULL, newconn->client.sock, req_length = read_request(NULL, newconn, buf, buf_len, &data_length);
newconn->ssl, buf, buf_len, &data_length);
if (req_length <= 0) { if (req_length <= 0) {
cry(fc(ctx), "%s(%s): invalid HTTP reply", __func__, url); cry(fc(ctx), "%s(%s): invalid HTTP reply", __func__, url);
} else if (parse_http_response(buf, req_length, ri) <= 0) { } else if (parse_http_response(buf, req_length, ri) <= 0) {
...@@ -3967,8 +3968,7 @@ FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path, ...@@ -3967,8 +3968,7 @@ FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
} }
// Read the rest of the response and write it to the file. Do not use // Read the rest of the response and write it to the file. Do not use
// mg_read() cause we didn't set newconn->content_len properly. // mg_read() cause we didn't set newconn->content_len properly.
while (fp && (data_length = pull(NULL, newconn->client.sock, newconn->ssl, while (fp && (data_length = pull(0, newconn, buf2, sizeof(buf2))) > 0) {
buf2, sizeof(buf2))) > 0) {
if (fwrite(buf2, 1, data_length, fp) != (size_t) data_length) { if (fwrite(buf2, 1, data_length, fp) != (size_t) data_length) {
cry(fc(ctx), "%s: fwrite(%s): %s", __func__, path, strerror(ERRNO)); cry(fc(ctx), "%s: fwrite(%s): %s", __func__, path, strerror(ERRNO));
fclose(fp); fclose(fp);
...@@ -4020,8 +4020,7 @@ static void process_new_connection(struct mg_connection *conn) { ...@@ -4020,8 +4020,7 @@ static void process_new_connection(struct mg_connection *conn) {
do { do {
reset_per_request_attributes(conn); reset_per_request_attributes(conn);
conn->request_len = read_request(NULL, conn->client.sock, conn->ssl, conn->request_len = read_request(NULL, conn, conn->buf, conn->buf_size,
conn->buf, conn->buf_size,
&conn->data_len); &conn->data_len);
assert(conn->data_len >= conn->request_len); assert(conn->data_len >= conn->request_len);
if (conn->request_len == 0 && conn->data_len == conn->buf_size) { if (conn->request_len == 0 && conn->data_len == conn->buf_size) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment