Add data closure to the cycle_callback of deferred response by etr · Pull Request #145 · etr/libhttpserver · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 74 additions & 16 deletions README.md
3 changes: 2 additions & 1 deletion examples/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
LDADD = $(top_builddir)/src/libhttpserver.la
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/
METASOURCES = AUTO
noinst_PROGRAMS = hello_world service minimal_hello_world custom_error allowing_disallowing_methods handlers hello_with_get_arg setting_headers custom_access_log basic_authentication digest_authentication minimal_https minimal_file_response minimal_deferred url_registration minimal_ip_ban benchmark_select benchmark_threads
noinst_PROGRAMS = hello_world service minimal_hello_world custom_error allowing_disallowing_methods handlers hello_with_get_arg setting_headers custom_access_log basic_authentication digest_authentication minimal_https minimal_file_response minimal_deferred url_registration minimal_ip_ban benchmark_select benchmark_threads deferred_with_accumulator

hello_world_SOURCES = hello_world.cpp
service_SOURCES = service.cpp
Expand All @@ -35,6 +35,7 @@ digest_authentication_SOURCES = digest_authentication.cpp
minimal_https_SOURCES = minimal_https.cpp
minimal_file_response_SOURCES = minimal_file_response.cpp
minimal_deferred_SOURCES = minimal_deferred.cpp
deferred_with_accumulator_SOURCES = deferred_with_accumulator.cpp
url_registration_SOURCES = url_registration.cpp
minimal_ip_ban_SOURCES = minimal_ip_ban.cpp
benchmark_select_SOURCES = benchmark_select.cpp
Expand Down
70 changes: 70 additions & 0 deletions examples/deferred_with_accumulator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
This file is part of libhttpserver
Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
*/

#include <atomic>
#include <httpserver.hpp>

using namespace httpserver;

std::atomic<int> counter;

ssize_t test_callback (std::shared_ptr<std::atomic<int> > closure_data, char* buf, size_t max) {
int reqid;
if (closure_data == nullptr) {
reqid = -1;
} else {
reqid = *closure_data;
}

// only first 5 connections can be established
if (reqid >= 5) {
return -1;
} else {
// respond corresponding request IDs to the clients
std::string str = "";
str += std::to_string(reqid) + " ";
memset(buf, 0, max);
std::copy(str.begin(), str.end(), buf);

// keep sending reqid
sleep(1);

return (ssize_t)max;
}
}

class deferred_resource : public http_resource {
public:
const std::shared_ptr<http_response> render_GET(const http_request& req) {
std::shared_ptr<std::atomic<int> > closure_data(new std::atomic<int>(counter++));
return std::shared_ptr<deferred_response<std::atomic<int> > >(new deferred_response<std::atomic<int> >(test_callback, closure_data, "cycle callback response"));
}
};

int main(int argc, char** argv) {
webserver ws = create_webserver(8080);

deferred_resource hwr;
ws.register_resource("/hello", &hwr);
ws.start(true);

return 0;
}

4 changes: 2 additions & 2 deletions examples/minimal_deferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ using namespace httpserver;

static int counter = 0;

ssize_t test_callback (char* buf, size_t max) {
ssize_t test_callback (std::shared_ptr<void> closure_data, char* buf, size_t max) {
if (counter == 2) {
return -1;
}
Expand All @@ -39,7 +39,7 @@ ssize_t test_callback (char* buf, size_t max) {
class deferred_resource : public http_resource {
public:
const std::shared_ptr<http_response> render_GET(const http_request& req) {
return std::shared_ptr<deferred_response>(new deferred_response(test_callback, "cycle callback response"));
return std::shared_ptr<deferred_response<void> >(new deferred_response<void>(test_callback, nullptr, "cycle callback response"));
}
};

Expand Down
37 changes: 2 additions & 35 deletions src/deferred_response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,44 +28,11 @@ namespace httpserver
namespace details
{

ssize_t cb(void* cls, uint64_t pos, char* buf, size_t max)
MHD_Response* get_raw_response_helper(void* cls, ssize_t (*cb)(void*, uint64_t, char*, size_t))
{
ssize_t val = static_cast<deferred_response*>(cls)->cycle_callback(buf, max);
if(val == -1)
{
static_cast<deferred_response*>(cls)->completed = true;
}

return val;
}

}

MHD_Response* deferred_response::get_raw_response()
{
if(!completed)
{
return MHD_create_response_from_callback(
MHD_SIZE_UNKNOWN,
1024,
&details::cb,
this,
NULL
);
}
else
{
return static_cast<string_response*>(this)->get_raw_response();
}
return MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 1024, cb, cls, NULL);
}

void deferred_response::decorate_response(MHD_Response* response)
{
if(completed)
{
static_cast<string_response*>(this)->decorate_response(response);
}
}

}

38 changes: 23 additions & 15 deletions src/httpserver/deferred_response.hpp
Loading