cesanta / mongoose

Embedded Web Server

Home Page:https://mongoose.ws

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The meaning of "n <= 0" judgment in iolog function

xielingsen opened this issue · comments

I'm using mongoose 7.12.
I encountered a problem that the connection will be closed after every request. After tracing, it was found that it was because mg_mgr_poll called read_conn, and read_conn did not obtain data after calling mg_io_recv. If iolog found n=-1, it would set c->is_closing = 1, causing the connection to close. I want to know the reason for doing this? Just because there is no data obtained when polling does not mean that the connection is intended to be closed, right?

This is the code:

mongoose/src/sock.c

Lines 244 to 258 in 06f8238

static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
long n = 0;
if (c->is_udp) {
union usa usa;
socklen_t slen = tousa(&c->rem, &usa);
n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
if (n > 0) tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin));
} else {
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
if (MG_SOCK_RESET(n)) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}

recv() reports error by returning negative value. If that's EAGAIN, we do not regard this is as an error. In other cases, we do: check errno, which gets printed by read_conn().

This is the code:

mongoose/src/sock.c

Lines 244 to 258 in 06f8238

static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
long n = 0;
if (c->is_udp) {
union usa usa;
socklen_t slen = tousa(&c->rem, &usa);
n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
if (n > 0) tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin));
} else {
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
if (MG_SOCK_RESET(n)) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}

recv() reports error by returning negative value. If that's EAGAIN, we do not regard this is as an error. In other cases, we do: check errno, which gets printed by read_conn().

I found that this issue was from mg_send.
Let's change the example "http-server" to:

   if (mg_http_match_uri(hm, "/test")) {
      char buffer[256];
      mg_printf(c,
                "HTTP/1.1 200 OK \r\n"
                "Content-Type: application/octet-stream\r\n"
                "Content-Length: %u\r\n"
                "\r\n",
                256);

      mg_send(c, buffer, 256);
    } else {

Then the client can get the response successfully when accessing http://127.0.0.1/test for the first time, but it will definitely fail on the second access because the client continues to use the last connection and mongoose has closed the connection.

@xielingsen please stop wasting yours and our time reporting false issues.