On Fri, 5 May 2017 21:09:21 +0300
Evgeny Grin <[email protected]> wrote:
> Hi José,
>
> Shouldn't be any change.
> Could you provide minimal example?
>
Hi Evgeny,
I was busy yesterday but I now have an example showing the regression.
I send it attached. I tested it against current master version
(917342b3fb0547523f2b4c6e607bb2ffd9cacdfd) and against version 0.9.49
(aka libmicrohttpd.so.12.37.0). The former doesn't work, the later
does.
How to test:
gcc -o tmhd tmhd.c -lmicrohttpd && ./tmhd
LD_PRELOAD=somewhere/libmicrohttpd.so.12.37.0 ./tmhd
And:
curl -i localhost:7878/index
What is bad? No reply is sent in the bad case, "curl" command doesn't
return. In the good case, it returns immediately as:
> curl -i localhost:7878/index
HTTP/1.1 403 Forbidden
Connection: Keep-Alive
Content-Length: 0
Date: Wed, 10 May 2017 07:29:11 GMT
To circumvent it, you can replace #if 0 with #if 1, leading to call
MHD_run one more time. So there is a workaround.
My feeling is that this is a typical use case and it should work with
only one call to MHD_run. I also think that providing a way to resume a
connection and sending the pending data without having to call MHD_run
would help (but is not required).
Best regards
José
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <poll.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <microhttpd.h>
static struct MHD_Connection *con = NULL;
static int access_handler(
void *cls,
struct MHD_Connection *connection,
const char *url,
const char *methodstr,
const char *version,
const char *upload_data,
size_t *upload_data_size,
void **recordreq)
{
con = connection;
MHD_suspend_connection (connection);
return MHD_YES;
}
int main(int ac, char **av)
{
int rc;
struct MHD_Daemon *httpd;
const union MHD_DaemonInfo *info;
struct pollfd pfd;
struct MHD_Response *response = MHD_create_response_from_buffer(0, "forbidden", MHD_RESPMEM_PERSISTENT);
httpd = MHD_start_daemon(
MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_TCP_FASTOPEN | MHD_USE_DEBUG | MHD_USE_SUSPEND_RESUME,
7878, /* port */
NULL, NULL,
access_handler, NULL, /* Http Request Call back + extra attribute */
MHD_OPTION_END); /* options-end */
if (httpd == NULL) {
fprintf(stderr, "can't start");
return 1;
}
info = MHD_get_daemon_info(httpd, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY);
if (info == NULL) {
MHD_stop_daemon(httpd);
fprintf(stderr, "can't get poll info");
return 1;
}
pfd.fd = info->listen_fd;
pfd.events = POLLIN;
for (;;) {
poll(&pfd, 1, -1);
MHD_run(httpd);
if (con) {
MHD_resume_connection(con);
MHD_queue_response(con, MHD_HTTP_FORBIDDEN, response);
con = NULL;
MHD_run(httpd);
#if 0 /* change to 1 to get the correct behaviour */
MHD_run(httpd);
#endif
}
}
return 0;
}