Civetweb 连接数据读取
-
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 ) {
case 2:
¦ return -1;
case 1:
¦ 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;
¦ char str[64];
¦ while (1) {
¦ ¦ int c = mg_getc(conn);
¦if (c == EOF) return 0;
¦ ¦ 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;
¦return 0;
}
¦ 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;
/* If Content-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, int len)
{
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;
¦ } else if (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. - 从打开的文件描述符中、ssl socket或者socket中读取数据,放到buf指向的空间中,最大读取的字节数为len调用成功返回实际读取到的字节数,失败则返回-1.
static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
{
int nread;
if (fp != NULL) {
¦ /* 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 to block and must pass all read bytes immediately to the
¦ ¦ client. */
¦ nread = read(fileno(fp), buf, (size_t) len);
#ifndef NO_SSL
} else if (conn->ssl != NULL) {
¦ nread = SSL_read(conn->ssl, buf, len);
#endif
} else {
¦ nread = recv(conn->client.sock, buf, (size_t) len, 0);
}
return conn->ctx->stop_flag ? -1 : nread;
}
版权声明:本文为litianze99原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。