From: Yehuda Sadeh Date: Mon, 23 Dec 2013 06:16:48 +0000 (-0800) Subject: rgw: switch mongoose to civetweb X-Git-Tag: v0.78~274^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f2f74754c9a9d67e060042ebfbd91731697fe806;p=ceph.git rgw: switch mongoose to civetweb Fixes: #7054 mongoose is now GPL, using the civetweb fork instead. Signed-off-by: Yehuda Sadeh --- diff --git a/.gitmodules b/.gitmodules index 454d7165e82f..08bb24d1ff83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "src/mongoose"] path = src/mongoose url = git://github.com/ceph/mongoose.git +[submodule "src/civetweb"] + path = src/civetweb + url = git@github.com:ceph/civetweb diff --git a/src/civetweb b/src/civetweb new file mode 160000 index 000000000000..400f29c108b3 --- /dev/null +++ b/src/civetweb @@ -0,0 +1 @@ +Subproject commit 400f29c108b35fe40f7290d3fff62c6892801e13 diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am index a0388396d8c3..8e7b1337bce2 100644 --- a/src/rgw/Makefile.am +++ b/src/rgw/Makefile.am @@ -51,6 +51,8 @@ LIBRGW_DEPS += \ -lfcgi \ -ldl +CIVETWEB = civetweb + radosgw_SOURCES = \ rgw/rgw_resolve.cc \ rgw/rgw_rest.cc \ @@ -69,9 +71,10 @@ radosgw_SOURCES = \ rgw/rgw_swift.cc \ rgw/rgw_swift_auth.cc \ rgw/rgw_loadgen.cc \ - rgw/rgw_mongoose.cc \ - mongoose/mongoose.c \ + rgw/rgw_civetweb.cc \ + $(CIVETWEB)/src/civetweb.c \ rgw/rgw_main.cc +radosgw_CFLAGS = -I$(CIVETWEB)/include radosgw_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(RESOLV_LIBS) $(CEPH_GLOBAL) bin_PROGRAMS += radosgw @@ -154,6 +157,6 @@ noinst_HEADERS += \ rgw/rgw_user.h \ rgw/rgw_bucket.h \ rgw/rgw_keystone.h \ - rgw/rgw_mongoose.h \ - mongoose/mongoose.h + rgw/rgw_civetweb.h \ + civetweb/civetweb.h diff --git a/src/rgw/rgw_civetweb.cc b/src/rgw/rgw_civetweb.cc new file mode 100644 index 000000000000..a31177fb394b --- /dev/null +++ b/src/rgw/rgw_civetweb.cc @@ -0,0 +1,172 @@ + +#include + +#include "civetweb/civetweb.h" +#include "rgw_civetweb.h" + + +#define dout_subsys ceph_subsys_rgw + +int RGWMongoose::write_data(const char *buf, int len) +{ + if (!header_done) { + header_data.append(buf, len); + return 0; + } + if (!sent_header) { + data.append(buf, len); + return 0; + } + return mg_write(conn, buf, len); +} + +RGWMongoose::RGWMongoose(mg_connection *_conn, int _port) : conn(_conn), port(_port), header_done(false), sent_header(false), has_content_length(false), + explicit_keepalive(false) +{ +} + +int RGWMongoose::read_data(char *buf, int len) +{ + return mg_read(conn, buf, len); +} + +void RGWMongoose::flush() +{ +} + +int RGWMongoose::complete_request() +{ + if (!sent_header) { + if (!has_content_length) { + header_done = false; /* let's go back to writing the header */ + + if (0 && data.length() == 0) { + has_content_length = true; + print("Transfer-Enconding: %s\n", "chunked"); + data.append("0\r\n\r\n", sizeof("0\r\n\r\n")-1); + } else { + int r = send_content_length(data.length()); + if (r < 0) + return r; + } + } + + complete_header(); + } + + if (data.length()) { + int r = write_data(data.c_str(), data.length()); + if (r < 0) + return r; + data.clear(); + } + + return 0; +} + +void RGWMongoose::init_env(CephContext *cct) +{ + env.init(cct); + struct mg_request_info *info = mg_get_request_info(conn); + if (!info) + return; + + for (int i = 0; i < info->num_headers; i++) { + struct mg_request_info::mg_header *header = &info->http_headers[i]; + + if (strcasecmp(header->name, "content-length") == 0) { + env.set("CONTENT_LENGTH", header->value); + continue; + } + + if (strcasecmp(header->name, "content-type") == 0) { + env.set("CONTENT_TYPE", header->value); + continue; + } + + if (strcasecmp(header->name, "connection") == 0) { + explicit_keepalive = (strcasecmp(header->value, "keep-alive") == 0); + } + + int len = strlen(header->name) + 5; /* HTTP_ prepended */ + char buf[len + 1]; + memcpy(buf, "HTTP_", 5); + const char *src = header->name; + char *dest = &buf[5]; + for (; *src; src++, dest++) { + char c = *src; + switch (c) { + case '-': + c = '_'; + break; + default: + c = toupper(c); + break; + } + *dest = c; + } + *dest = '\0'; + + env.set(buf, header->value); + } + + env.set("REQUEST_METHOD", info->request_method); + env.set("REQUEST_URI", info->uri); + env.set("QUERY_STRING", info->query_string); + env.set("REMOTE_USER", info->remote_user); + env.set("SCRIPT_URI", info->uri); /* FIXME */ + + char port_buf[16]; + snprintf(port_buf, sizeof(port_buf), "%d", port); + env.set("SERVER_PORT", port_buf); +} + +int RGWMongoose::send_status(const char *status, const char *status_name) +{ + char buf[128]; + + if (!status_name) + status_name = ""; + + snprintf(buf, sizeof(buf), "HTTP/1.1 %s %s\n", status, status_name); + + bufferlist bl; + bl.append(buf); + bl.append(header_data); + header_data = bl; + + return 0; +} + +int RGWMongoose::send_100_continue() +{ + char buf[] = "HTTP/1.1 100 CONTINUE\r\n\r\n"; + + return mg_write(conn, buf, sizeof(buf) - 1); +} + +int RGWMongoose::complete_header() +{ + header_done = true; + + if (!has_content_length) { + return 0; + } + + if (explicit_keepalive) + header_data.append("Connection: Keep-Alive\r\n"); + + header_data.append("\r\n"); + + sent_header = true; + + return write_data(header_data.c_str(), header_data.length()); +} + +int RGWMongoose::send_content_length(uint64_t len) +{ + has_content_length = true; + char buf[21]; + snprintf(buf, sizeof(buf), "%"PRIu64, len); + return print("Content-Length: %s\n", buf); +} diff --git a/src/rgw/rgw_civetweb.h b/src/rgw/rgw_civetweb.h new file mode 100644 index 000000000000..c1df9f08a5bb --- /dev/null +++ b/src/rgw/rgw_civetweb.h @@ -0,0 +1,41 @@ +#ifndef CEPH_RGW_MONGOOSE_H +#define CEPH_RGW_MONGOOSE_H + +#include "rgw_client_io.h" + + +struct mg_connection; + + +class RGWMongoose : public RGWClientIO +{ + mg_connection *conn; + + bufferlist header_data; + bufferlist data; + + int port; + + bool header_done; + bool sent_header; + bool has_content_length; + bool explicit_keepalive; + +public: + void init_env(CephContext *cct); + + int write_data(const char *buf, int len); + int read_data(char *buf, int len); + + int send_status(const char *status, const char *status_name); + int send_100_continue(); + int complete_header(); + int complete_request(); + int send_content_length(uint64_t len); + + RGWMongoose(mg_connection *_conn, int _port); + void flush(); +}; + + +#endif diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index c8ed9146d82a..e1aa3d450007 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -53,9 +53,9 @@ #include "rgw_tools.h" #include "rgw_resolve.h" #include "rgw_loadgen.h" -#include "rgw_mongoose.h" +#include "rgw_civetweb.h" -#include "mongoose/mongoose.h" +#include "civetweb/civetweb.h" #include #include @@ -673,7 +673,7 @@ void RGWLoadGenProcess::handle_request(RGWRequest *r) } -static int mongoose_callback(struct mg_connection *conn) { +static int civetweb_callback(struct mg_connection *conn) { struct mg_request_info *req_info = mg_get_request_info(conn); RGWProcessEnv *pe = (RGWProcessEnv *)req_info->user_data; RGWRados *store = pe->store; @@ -928,7 +928,7 @@ public: struct mg_callbacks cb; memset((void *)&cb, 0, sizeof(cb)); - cb.begin_request = mongoose_callback; + cb.begin_request = civetweb_callback; ctx = mg_start(&cb, &env, (const char **)&options); if (!ctx) { @@ -1122,7 +1122,7 @@ int main(int argc, const char **argv) RGWProcessEnv fcgi_pe = { store, &rest, olog, 0 }; fe = new RGWFCGXFrontend(fcgi_pe, config); - } else if (framework == "mongoose") { + } else if (framework == "civetweb" || framework == "mongoose") { string err; int port; diff --git a/src/rgw/rgw_mongoose.cc b/src/rgw/rgw_mongoose.cc deleted file mode 100644 index 3aa493fec794..000000000000 --- a/src/rgw/rgw_mongoose.cc +++ /dev/null @@ -1,172 +0,0 @@ - -#include - -#include "mongoose/mongoose.h" -#include "rgw_mongoose.h" - - -#define dout_subsys ceph_subsys_rgw - -int RGWMongoose::write_data(const char *buf, int len) -{ - if (!header_done) { - header_data.append(buf, len); - return 0; - } - if (!sent_header) { - data.append(buf, len); - return 0; - } - return mg_write(conn, buf, len); -} - -RGWMongoose::RGWMongoose(mg_connection *_conn, int _port) : conn(_conn), port(_port), header_done(false), sent_header(false), has_content_length(false), - explicit_keepalive(false) -{ -} - -int RGWMongoose::read_data(char *buf, int len) -{ - return mg_read(conn, buf, len); -} - -void RGWMongoose::flush() -{ -} - -int RGWMongoose::complete_request() -{ - if (!sent_header) { - if (!has_content_length) { - header_done = false; /* let's go back to writing the header */ - - if (0 && data.length() == 0) { - has_content_length = true; - print("Transfer-Enconding: %s\n", "chunked"); - data.append("0\r\n\r\n", sizeof("0\r\n\r\n")-1); - } else { - int r = send_content_length(data.length()); - if (r < 0) - return r; - } - } - - complete_header(); - } - - if (data.length()) { - int r = write_data(data.c_str(), data.length()); - if (r < 0) - return r; - data.clear(); - } - - return 0; -} - -void RGWMongoose::init_env(CephContext *cct) -{ - env.init(cct); - struct mg_request_info *info = mg_get_request_info(conn); - if (!info) - return; - - for (int i = 0; i < info->num_headers; i++) { - struct mg_request_info::mg_header *header = &info->http_headers[i]; - - if (strcasecmp(header->name, "content-length") == 0) { - env.set("CONTENT_LENGTH", header->value); - continue; - } - - if (strcasecmp(header->name, "content-type") == 0) { - env.set("CONTENT_TYPE", header->value); - continue; - } - - if (strcasecmp(header->name, "connection") == 0) { - explicit_keepalive = (strcasecmp(header->value, "keep-alive") == 0); - } - - int len = strlen(header->name) + 5; /* HTTP_ prepended */ - char buf[len + 1]; - memcpy(buf, "HTTP_", 5); - const char *src = header->name; - char *dest = &buf[5]; - for (; *src; src++, dest++) { - char c = *src; - switch (c) { - case '-': - c = '_'; - break; - default: - c = toupper(c); - break; - } - *dest = c; - } - *dest = '\0'; - - env.set(buf, header->value); - } - - env.set("REQUEST_METHOD", info->request_method); - env.set("REQUEST_URI", info->uri); - env.set("QUERY_STRING", info->query_string); - env.set("REMOTE_USER", info->remote_user); - env.set("SCRIPT_URI", info->uri); /* FIXME */ - - char port_buf[16]; - snprintf(port_buf, sizeof(port_buf), "%d", port); - env.set("SERVER_PORT", port_buf); -} - -int RGWMongoose::send_status(const char *status, const char *status_name) -{ - char buf[128]; - - if (!status_name) - status_name = ""; - - snprintf(buf, sizeof(buf), "HTTP/1.1 %s %s\n", status, status_name); - - bufferlist bl; - bl.append(buf); - bl.append(header_data); - header_data = bl; - - return 0; -} - -int RGWMongoose::send_100_continue() -{ - char buf[] = "HTTP/1.1 100 CONTINUE\r\n\r\n"; - - return mg_write(conn, buf, sizeof(buf) - 1); -} - -int RGWMongoose::complete_header() -{ - header_done = true; - - if (!has_content_length) { - return 0; - } - - if (explicit_keepalive) - header_data.append("Connection: Keep-Alive\r\n"); - - header_data.append("\r\n"); - - sent_header = true; - - return write_data(header_data.c_str(), header_data.length()); -} - -int RGWMongoose::send_content_length(uint64_t len) -{ - has_content_length = true; - char buf[21]; - snprintf(buf, sizeof(buf), "%"PRIu64, len); - return print("Content-Length: %s\n", buf); -} diff --git a/src/rgw/rgw_mongoose.h b/src/rgw/rgw_mongoose.h deleted file mode 100644 index c1df9f08a5bb..000000000000 --- a/src/rgw/rgw_mongoose.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef CEPH_RGW_MONGOOSE_H -#define CEPH_RGW_MONGOOSE_H - -#include "rgw_client_io.h" - - -struct mg_connection; - - -class RGWMongoose : public RGWClientIO -{ - mg_connection *conn; - - bufferlist header_data; - bufferlist data; - - int port; - - bool header_done; - bool sent_header; - bool has_content_length; - bool explicit_keepalive; - -public: - void init_env(CephContext *cct); - - int write_data(const char *buf, int len); - int read_data(char *buf, int len); - - int send_status(const char *status, const char *status_name); - int send_100_continue(); - int complete_header(); - int complete_request(); - int send_content_length(uint64_t len); - - RGWMongoose(mg_connection *_conn, int _port); - void flush(); -}; - - -#endif