int mg_read(struct mg_connection *conn, void *buf, size_t len) 从conn中读取若干字节到buf指定的地址空间中,返回值是真正读取的字节数。 该函数会把已经读到mg_connection.buf中的被缓存的数据拷贝到buf中,然后在继续从connection对应的socket中读取数据,放入到buf中。
int mg_read(struct mg_connection *conn, void *buf, size_t len) {
switch ( conn->is_chunked ) {
case2:
¦ return -1;
case1:
¦ if (conn->content_len <= 0 ) conn->content_len = 0;
¦ if (conn->consumed_content < conn->content_len) return mg_read_inner(conn,buf,len);
¦ int i = 0;
¦ charstr[64];
¦ while (1) {
¦ ¦ int c = mg_getc(conn);
¦if (c == EOF) return0;
¦ ¦ if ( ! ( c == '\n' || c == '\r' ) ) {
¦ ¦ ¦ str[i++] = c;
¦ ¦ ¦ break;
¦ ¦ }
¦ }
¦ for (; i < (int)sizeof(str); i++) {
¦ ¦ int c = mg_getc(conn);
¦ ¦ if ( c == EOF ) return -1;
¦ ¦ str[i] = (char) c;
¦ ¦ if ( i > 0 && str[i] == '\n' && str[i-1] == '\r' ) break;
¦ }
¦ char *end = 0;
¦ long chunkSize = strtol(str,&end,16);
¦ if ( end != str+(i-1) ) return -1;
¦ if ( chunkSize == 0 ) {
¦conn->is_chunked = 2;
¦return0;
}
¦ conn->content_len += chunkSize;
}
return mg_read_inner(conn,buf,len);
}
int mg_read_inner(struct mg_connection *conn, void *buf, size_t len) 从conn中读取数据到buf指向的地址空间中,最多读取len个字节,最少读取该连接中剩余的content大小的字节数。
int mg_read_inner(struct mg_connection *conn, void *buf, size_t len)
{
int64_t n, buffered_len, nread;
const char *body;
/* IfContent-Length is not set for a PUT or POST request, read until socket is closed */
if (conn->consumed_content == 0 && conn->content_len == -1) {
¦ conn->content_len = INT64_MAX;
¦ conn->must_close = 1;
}
nread = 0;
if (conn->consumed_content < conn->content_len) {
¦ /* Adjust number of bytes to read. */
¦ int64_t to_read = conn->content_len - conn->consumed_content;
¦ if (to_read < (int64_t) len) {
¦ ¦ len = (size_t) to_read;
¦ }
¦ /* Return buffered data */
¦ body = conn->buf + conn->request_len + conn->consumed_content;
¦ buffered_len = (int64_t)(&conn->buf[conn->data_len] - body);
¦ if (buffered_len > 0) {
¦ ¦ if (len < (size_t) buffered_len) {
¦ ¦ ¦ buffered_len = (int64_t) len;
¦ ¦ }
¦ ¦ memcpy(buf, body, (size_t) buffered_len);
¦ ¦ len -= buffered_len;
¦ ¦ conn->consumed_content += buffered_len;
¦ ¦ nread += buffered_len;
¦ ¦ buf = (char *) buf + buffered_len;
¦ }
¦ /* We have returned all buffered data. Read new data from the remote
¦ ¦ socket. */
¦ n = pull_all(NULL, conn, (char *) buf, (int64_t) len);
¦ nread = n >= 0 ? nread + n : n;
}
return nread;
}
static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len) 从文件描述符或者conn中读取数据到buf指向的地址空间中,直到对端没有数据, 或者对端已经关闭,抑或读取len个字节,才返回,调用成功返回读取的字节数 失败返回-1.
static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, intlen)
{
int n, nread = 0;
while (len > 0 && conn->ctx->stop_flag == 0) {
¦ n = pull(fp, conn, buf + nread, len);
¦ if (n < 0) {
¦ ¦ nread = n; /* Propagate the error */
¦ ¦ break;
¦ } elseif (n == 0) {
¦ ¦ break; /* No more data to read */
¦ } else {
¦ ¦ conn->consumed_content += n;
¦ ¦ nread += n;
¦ ¦ len -= n;
¦ }
}
return nread;
}
static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len) Read from IO channel - opened file descriptor, socket, or SSL descriptor. Return negative value on error, or number of bytes read on success.