int dirfd;
};
+enum afb_hsrv_state {
+ hsrv_idle = 0,
+ hsrv_run,
+ hsrv_rerun
+};
+
struct afb_hsrv {
unsigned refcount;
+ enum afb_hsrv_state state;
struct hsrv_handler *handlers;
struct MHD_Daemon *httpd;
struct upoll *upoll;
static void reply_error(struct MHD_Connection *connection, unsigned int status)
{
- char *buffer;
- int length;
- struct MHD_Response *response;
-
- length = asprintf(&buffer, "<html><body>error %u</body></html>", status);
- if (length > 0)
- response = MHD_create_response_from_buffer((unsigned)length, buffer, MHD_RESPMEM_MUST_FREE);
- else {
- buffer = "<html><body>error</body></html>";
- response = MHD_create_response_from_buffer(strlen(buffer), buffer, MHD_RESPMEM_PERSISTENT);
- }
- if (!MHD_queue_response(connection, status, response))
- fprintf(stderr, "Failed to reply error code %u", status);
+ struct MHD_Response *response = MHD_create_response_from_buffer(0, NULL, MHD_RESPMEM_PERSISTENT);
+ MHD_queue_response(connection, status, response);
MHD_destroy_response(response);
}
if (!MHD_post_process (hreq->postform, upload_data, *upload_data_size))
goto internal_error;
} else {
- if (!afb_hreq_post_add(hreq, NULL, upload_data, *upload_data_size))
+ if (!afb_hreq_post_add(hreq, "", upload_data, *upload_data_size))
goto internal_error;
}
*upload_data_size = 0;
afb_hreq_free(hreq);
}
+static void handle_epoll_readable(struct afb_hsrv *hsrv)
+{
+ if (hsrv->state != hsrv_idle)
+ hsrv->state = hsrv_rerun;
+ else {
+ do {
+ hsrv->state = hsrv_run;
+ MHD_run(hsrv->httpd);
+ } while (hsrv->state == hsrv_rerun);
+ hsrv->state = hsrv_idle;
+ }
+};
+
static int new_client_handler(void *cls, const struct sockaddr *addr, socklen_t addrlen)
{
return MHD_YES;
MHD_OPTION_END); /* options-end */
if (httpd == NULL) {
- printf("Error: httpStart invalid httpd port: %d", (int)port);
+ fprintf(stderr, "Error: httpStart invalid httpd port: %d", (int)port);
return 0;
}
return 0;
}
- upoll = upoll_open(info->listen_fd, httpd);
+ upoll = upoll_open(info->listen_fd, hsrv);
if (upoll == NULL) {
MHD_stop_daemon(httpd);
fprintf(stderr, "Error: connection to upoll of httpd failed");
return 0;
}
- upoll_on_readable(upoll, (void*)MHD_run);
+ upoll_on_readable(upoll, (void*)handle_epoll_readable);
hsrv->httpd = httpd;
hsrv->upoll = upoll;