Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wip chunkfix #35

Open
wants to merge 3 commits into
base: ceph-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/civetweb.h
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,9 @@ mg_download(const char *host,
/* Close the connection opened by mg_download(). */
CIVETWEB_API void mg_close_connection(struct mg_connection *conn);

CIVETWEB_API void mg_set_must_close(struct mg_connection *conn, int f);



#if defined(MG_LEGACY_INTERFACE)
/* File upload functionality. Each uploaded file gets saved into a temporary
Expand Down
71 changes: 47 additions & 24 deletions src/civetweb.c
Original file line number Diff line number Diff line change
Expand Up @@ -6090,41 +6090,58 @@ mg_read(struct mg_connection *conn, void *buf, size_t len)

} else {
/* fetch a new chunk */
int i = 0;
int i;
char lenbuf[64];
char *end = 0;
unsigned long chunkSize = 0;
int in_count = 1;
int c, lastc;

for (i = 0; i < ((int)sizeof(lenbuf) - 1); i++) {
for (c = 0, i = 0; ; ) {
conn->content_len++;
lenbuf[i] = mg_getc(conn);
if ((i > 0) && (lenbuf[i] == '\r')
&& (lenbuf[i - 1] != '\r')) {
continue;
lastc = c;
c = mg_getc(conn);
if (c == 0) {
return -1;
}
if ((i > 1) && (lenbuf[i] == '\n')
&& (lenbuf[i - 1] == '\r')) {
lenbuf[i + 1] = 0;
chunkSize = strtoul(lenbuf, &end, 16);
if (chunkSize == 0) {
/* regular end of content */
conn->is_chunked = 3;
}
else if (lastc == '\r' && c == '\n') {
break;
}
if (!isxdigit(lenbuf[i])) {
else if (!in_count)
;
else if (c == ';' || c == '\r') {
in_count = 0;
} else if (!isxdigit(c)) {
/* illegal character for chunk length */
return -1;
} else if (i >= ((int)sizeof(lenbuf) - 1)) {
/* waaay too long */
return -1;
} else {
lenbuf[i++] = c;
}
}
if ((end == NULL) || (*end != '\r')) {
/* chunksize not set correctly */
if (!i) {
/* no chunksize, error */
return -1;
}
lenbuf[i] = 0;
chunkSize = strtoul(lenbuf, &end, 16);
if (i != end - lenbuf) {
/* can't happen, except maybe erange? */
return -1;
}
if (chunkSize == 0) {
/* regular end of content */
conn->is_chunked = 3;
conn->content_len += 2;
c = mg_read_inner(conn, lenbuf, 2);
if (c != 2 || lenbuf[0] != '\r' || lenbuf[1] != '\n') {
/* Protcol violation */
return -1;
}
break;
}

conn->chunk_remainder = chunkSize;
}
}
Expand Down Expand Up @@ -14851,6 +14868,12 @@ mg_close_connection(struct mg_connection *conn)
#endif /* defined(USE_WEBSOCKET) */
}

void
mg_set_must_close(struct mg_connection *conn, int f)
{
conn->must_close = f;
}


/* Only for memory statistics */
static struct mg_context common_client_context;
Expand Down Expand Up @@ -15384,6 +15407,12 @@ get_request(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)

/* Message is a valid request */
if ((cl = get_header(conn->request_info.http_headers,
conn->request_info.num_headers,
"Transfer-Encoding")) != NULL
&& !mg_strcasecmp(cl, "chunked")) {
conn->is_chunked = 1;
conn->content_len = -1; /* unknown content length */
} else if ((cl = get_header(conn->request_info.http_headers,
conn->request_info.num_headers,
"Content-Length")) != NULL) {
/* Request/response has content length set */
Expand All @@ -15401,12 +15430,6 @@ get_request(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
}
/* Publish the content length back to the request info. */
conn->request_info.content_length = conn->content_len;
} else if ((cl = get_header(conn->request_info.http_headers,
conn->request_info.num_headers,
"Transfer-Encoding")) != NULL
&& !mg_strcasecmp(cl, "chunked")) {
conn->is_chunked = 1;
conn->content_len = -1; /* unknown content length */
} else if (get_http_method_info(conn->request_info.request_method)
->request_has_body) {
/* POST or PUT request without content length set */
Expand Down