rgw/rgw_http_client.cc \
rgw/rgw_swift.cc \
rgw/rgw_swift_auth.cc \
+ rgw/rgw_mongoose.cc \
+ mongoose/mongoose.c \
rgw/rgw_main.cc
radosgw_LDADD = $(LIBRGW) $(LIBRGW_DEPS) -lresolv $(CEPH_GLOBAL)
bin_PROGRAMS += radosgw
rgw/rgw_usage.h \
rgw/rgw_user.h \
rgw/rgw_bucket.h \
- rgw/rgw_keystone.h
+ rgw/rgw_keystone.h \
+ rgw/rgw_mongoose.h \
+ mongoose/mongoose.h
#include "include/types.h"
+#include "rgw_common.h"
+
class RGWClientIO {
bool account;
size_t bytes_received;
protected:
+ RGWEnv env;
+
+ virtual void init_env(CephContext *cct) = 0;
+
virtual int write_data(const char *buf, int len) = 0;
virtual int read_data(char *buf, int max) = 0;
virtual ~RGWClientIO() {}
RGWClientIO() : account(false), bytes_sent(0), bytes_received(0) {}
+ void init(CephContext *cct) {
+ init_env(cct);
+ }
+
int print(const char *format, ...);
int write(const char *buf, int len);
virtual void flush() = 0;
int read(char *buf, int max, int *actual);
- virtual const char **envp() = 0;
+ virtual int send_status(const char *status, const char *status_name) = 0;
+ virtual int send_100_continue() = 0;
+ virtual int complete_header() = 0;
+
+ RGWEnv& get_env() { return env; }
void set_account(bool _account) {
account = _account;
if (pos >= 0) {
request_params = request_uri.substr(pos + 1);
request_uri = request_uri.substr(0, pos);
+ } else {
+ request_params = env->get("QUERY_STRING", "");
}
host = env->get("HTTP_HOST");
}
{
x_meta_map.clear();
- map<string, string>& m = env->get_map();
- map<string, string>::iterator iter;
+ map<string, string, ltstr_nocase>& m = env->get_map();
+ map<string, string, ltstr_nocase>::iterator iter;
for (iter = m.begin(); iter != m.end(); ++iter) {
const char *prefix;
const string& header_name = iter->first;
#include "rgw_acl.h"
#include "rgw_cors.h"
#include "rgw_quota.h"
+#include "rgw_string.h"
#include "cls/version/cls_version_types.h"
#include "include/rados/librados.hpp"
class RGWConf;
class RGWEnv {
- std::map<string, string> env_map;
+ std::map<string, string, ltstr_nocase> env_map;
public:
RGWConf *conf;
RGWEnv();
~RGWEnv();
+ void init(CephContext *cct);
void init(CephContext *cct, char **envp);
+ void set(const char *name, const char *val);
const char *get(const char *name, const char *def_val = NULL);
int get_int(const char *name, int def_val = 0);
bool get_bool(const char *name, bool def_val = 0);
bool exists_prefix(const char *prefix);
void remove(const char *name);
- void set(const char *name, const char *val);
- std::map<string, string>& get_map() { return env_map; }
+
+ std::map<string, string, ltstr_nocase>& get_map() { return env_map; }
};
class RGWConf {
delete conf;
}
+void RGWEnv::init(CephContext *cct)
+{
+ conf->init(cct, this);
+}
+
+void RGWEnv::set(const char *name, const char *val)
+{
+ if (!val)
+ val = "";
+ env_map[name] = val;
+
+ dout(0) << "RGWEnv::set(): " << name << ": " << val << dendl;
+}
+
void RGWEnv::init(CephContext *cct, char **envp)
{
const char *p;
env_map[name] = val;
}
- conf->init(cct, this);
+ init(cct);
}
const char *RGWEnv::get(const char *name, const char *def_val)
{
- map<string, string>::iterator iter = env_map.find(name);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.find(name);
if (iter == env_map.end())
return def_val;
int RGWEnv::get_int(const char *name, int def_val)
{
- map<string, string>::iterator iter = env_map.find(name);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.find(name);
if (iter == env_map.end())
return def_val;
bool RGWEnv::get_bool(const char *name, bool def_val)
{
- map<string, string>::iterator iter = env_map.find(name);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.find(name);
if (iter == env_map.end())
return def_val;
size_t RGWEnv::get_size(const char *name, size_t def_val)
{
- map<string, string>::iterator iter = env_map.find(name);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.find(name);
if (iter == env_map.end())
return def_val;
bool RGWEnv::exists(const char *name)
{
- map<string, string>::iterator iter = env_map.find(name);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.find(name);
return (iter != env_map.end());
}
if (env_map.empty() || prefix == NULL)
return false;
- map<string, string>::iterator iter = env_map.lower_bound(prefix);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.lower_bound(prefix);
if (iter == env_map.end())
return false;
return (strncmp(iter->first.c_str(), prefix, strlen(prefix)) == 0);
}
-void RGWEnv::set(const char *name, const char *val)
-{
- env_map[name] = val;
-}
-
void RGWEnv::remove(const char *name)
{
- map<string, string>::iterator iter = env_map.find(name);
+ map<string, string, ltstr_nocase>::iterator iter = env_map.find(name);
if (iter != env_map.end())
env_map.erase(iter);
}
FCGX_FFlush(fcgx->out);
}
-const char **RGWFCGX::envp()
+void RGWFCGX::init_env(CephContext *cct)
{
- return (const char **)fcgx->envp;
+ env.init(cct, (char **)fcgx->envp);
}
+
+int RGWFCGX::send_status(const char *status, const char *status_name)
+{
+ return print("Status: %s\n", status);
+}
+
+int RGWFCGX::send_100_continue()
+{
+ int r = send_status("100", "Continue");
+ if (r >= 0) {
+ flush();
+ }
+ return r;
+}
+
+int RGWFCGX::complete_header()
+{
+ return print("\r\n");
+}
+
{
FCGX_Request *fcgx;
protected:
+ 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();
public:
RGWFCGX(FCGX_Request *_fcgx) : fcgx(_fcgx) {}
void flush();
- const char **envp();
};
{ ERR_BAD_URL, 412, "Bad URL" },
};
+struct rgw_http_status_code {
+ int code;
+ const char *name;
+};
+
+const static struct rgw_http_status_code http_codes[] = {
+ { 100, "Continue" },
+ { 200, "OK" },
+ { 201, "Created" },
+ { 202, "Accepted" },
+ { 204, "No Content" },
+ { 205, "Reset Content" },
+ { 206, "Partial Content" },
+ { 207, "Multi Status" },
+ { 208, "Already Reported" },
+ { 300, "Multiple Choices" },
+ { 302, "Found" },
+ { 303, "See Other" },
+ { 304, "Not Modified" },
+ { 305, "User Proxy" },
+ { 306, "Switch Proxy" },
+ { 307, "Temporary Redirect" },
+ { 308, "Permanent Redirect" },
+ { 400, "Bad Request" },
+ { 401, "Unauthorized" },
+ { 402, "Payment Required" },
+ { 403, "Forbidden" },
+ { 404, "Not Found" },
+ { 405, "Method Not Allowed" },
+ { 406, "Not Acceptable" },
+ { 407, "Proxy Authentication Required" },
+ { 408, "Request Timeout" },
+ { 409, "Conflict" },
+ { 410, "Gone" },
+ { 411, "Length Required" },
+ { 412, "Precondition Failed" },
+ { 413, "Request Entity Too Large" },
+ { 414, "Request-URI Too Long" },
+ { 415, "Unsupported Media Type" },
+ { 416, "Requested Range Not Satisfiable" },
+ { 417, "Expectation Failed" },
+ { 422, "Unprocessable Entity" },
+ { 500, "Internal Server Error" },
+ { 0, NULL },
+};
+
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
static inline const struct rgw_http_errors *search_err(int err_no, const struct rgw_http_errors *errs, int len)
#include "rgw_log.h"
#include "rgw_tools.h"
#include "rgw_resolve.h"
+#include "rgw_mongoose.h"
+
+#include "mongoose/mongoose.h"
#include <map>
#include <string>
struct RGWRequest
{
- FCGX_Request fcgx;
uint64_t id;
struct req_state *s;
string req_str;
}
};
+
+struct RGWFCGXRequest : public RGWRequest {
+ FCGX_Request fcgx;
+};
+
+struct RGWProcessEnv {
+ RGWRados *store;
+ RGWREST *rest;
+ OpsLogSocket *olog;
+};
+
class RGWProcess {
RGWRados *store;
OpsLogSocket *olog;
- deque<RGWRequest *> m_req_queue;
+ deque<RGWFCGXRequest *> m_req_queue;
ThreadPool m_tp;
Throttle req_throttle;
RGWREST *rest;
int sock_fd;
- struct RGWWQ : public ThreadPool::WorkQueue<RGWRequest> {
+ RGWProcessEnv *process_env;
+
+ struct RGWWQ : public ThreadPool::WorkQueue<RGWFCGXRequest> {
RGWProcess *process;
RGWWQ(RGWProcess *p, time_t timeout, time_t suicide_timeout, ThreadPool *tp)
- : ThreadPool::WorkQueue<RGWRequest>("RGWWQ", timeout, suicide_timeout, tp), process(p) {}
+ : ThreadPool::WorkQueue<RGWFCGXRequest>("RGWWQ", timeout, suicide_timeout, tp), process(p) {}
- bool _enqueue(RGWRequest *req) {
+ bool _enqueue(RGWFCGXRequest *req) {
process->m_req_queue.push_back(req);
perfcounter->inc(l_rgw_qlen);
dout(20) << "enqueued request req=" << hex << req << dec << dendl;
_dump_queue();
return true;
}
- void _dequeue(RGWRequest *req) {
+ void _dequeue(RGWFCGXRequest *req) {
assert(0);
}
bool _empty() {
return process->m_req_queue.empty();
}
- RGWRequest *_dequeue() {
+ RGWFCGXRequest *_dequeue() {
if (process->m_req_queue.empty())
return NULL;
- RGWRequest *req = process->m_req_queue.front();
+ RGWFCGXRequest *req = process->m_req_queue.front();
process->m_req_queue.pop_front();
dout(20) << "dequeued request req=" << hex << req << dec << dendl;
_dump_queue();
perfcounter->inc(l_rgw_qlen, -1);
return req;
}
- void _process(RGWRequest *req) {
+ void _process(RGWFCGXRequest *req) {
perfcounter->inc(l_rgw_qactive);
process->handle_request(req);
process->req_throttle.put(1);
perfcounter->inc(l_rgw_qactive, -1);
}
void _dump_queue() {
- deque<RGWRequest *>::iterator iter;
+ deque<RGWFCGXRequest *>::iterator iter;
if (process->m_req_queue.empty()) {
dout(20) << "RGWWQ: empty" << dendl;
return;
uint64_t max_req_id;
public:
- RGWProcess(CephContext *cct, RGWRados *rgwstore, OpsLogSocket *_olog, int num_threads, RGWREST *_rest)
- : store(rgwstore), olog(_olog), m_tp(cct, "RGWProcess::m_tp", num_threads),
+ RGWProcess(CephContext *cct, RGWProcessEnv *pe, int num_threads)
+ : store(pe->store), olog(pe->olog), m_tp(cct, "RGWProcess::m_tp", num_threads),
req_throttle(cct, "rgw_ops", num_threads * 2),
- rest(_rest), sock_fd(-1),
+ rest(pe->rest), sock_fd(-1),
req_wq(this, g_conf->rgw_op_thread_timeout,
g_conf->rgw_op_thread_suicide_timeout, &m_tp),
max_req_id(0) {}
void run();
- void handle_request(RGWRequest *req);
+ void handle_request(RGWFCGXRequest *req);
void close_fd() {
if (sock_fd >= 0)
m_tp.start();
for (;;) {
- RGWRequest *req = new RGWRequest;
+ RGWFCGXRequest *req = new RGWFCGXRequest;
req->id = ++max_req_id;
dout(10) << "allocated request req=" << hex << req << dec << dendl;
FCGX_InitRequest(&req->fcgx, sock_fd, 0);
return rgw_log_intent(store, s, obj, intent);
}
-void RGWProcess::handle_request(RGWRequest *req)
+void RGWProcess::handle_request(RGWFCGXRequest *req)
{
FCGX_Request *fcgx = &req->fcgx;
int ret;
- RGWEnv rgw_env;
RGWFCGX client_io(fcgx);
+ client_io.init(g_ceph_context);
+
req->log_init();
dout(1) << "====== starting new request req=" << hex << req << dec << " =====" << dendl;
perfcounter->inc(l_rgw_req);
- rgw_env.init(g_ceph_context, fcgx->envp);
+ RGWEnv& rgw_env = client_io.get_env();
struct req_state *s = req->init_state(g_ceph_context, &rgw_env);
s->obj_ctx = store->create_context(s);
delete req;
}
+
+static int mongoose_callback(struct mg_event *event) {
+ RGWProcessEnv *pe = (RGWProcessEnv *)event->user_data;
+ RGWRados *store = pe->store;
+ RGWREST *rest = pe->rest;
+ OpsLogSocket *olog = pe->olog;
+
+ if (event->type != MG_REQUEST_BEGIN)
+ return 0;
+
+ RGWRequest *req = new RGWRequest;
+ int ret;
+ RGWMongoose client_io(event);
+
+ client_io.init(g_ceph_context);
+
+ req->log_init();
+
+ dout(1) << "====== starting new request req=" << hex << req << dec << " =====" << dendl;
+ perfcounter->inc(l_rgw_req);
+
+ RGWEnv& rgw_env = client_io.get_env();
+
+ struct req_state *s = req->init_state(g_ceph_context, &rgw_env);
+ s->obj_ctx = store->create_context(s);
+ store->set_intent_cb(s->obj_ctx, call_log_intent);
+
+ s->req_id = store->unique_id(req->id);
+
+ req->log(s, "initializing");
+
+ RGWOp *op = NULL;
+ int init_error = 0;
+ bool should_log = false;
+ RGWRESTMgr *mgr;
+ RGWHandler *handler = rest->get_handler(store, s, &client_io, &mgr, &init_error);
+ if (init_error != 0) {
+ abort_early(s, NULL, init_error);
+ goto done;
+ }
+
+ should_log = mgr->get_logging();
+
+ req->log(s, "getting op");
+ op = handler->get_op(store);
+ if (!op) {
+ abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED);
+ goto done;
+ }
+ req->op = op;
+
+ req->log(s, "authorizing");
+ ret = handler->authorize();
+ if (ret < 0) {
+ dout(10) << "failed to authorize request" << dendl;
+ abort_early(s, op, ret);
+ goto done;
+ }
+
+ if (s->user.suspended) {
+ dout(10) << "user is suspended, uid=" << s->user.user_id << dendl;
+ abort_early(s, op, -ERR_USER_SUSPENDED);
+ goto done;
+ }
+ req->log(s, "reading permissions");
+ ret = handler->read_permissions(op);
+ if (ret < 0) {
+ abort_early(s, op, ret);
+ goto done;
+ }
+
+ req->log(s, "init op");
+ ret = op->init_processing();
+ if (ret < 0) {
+ abort_early(s, op, ret);
+ goto done;
+ }
+
+ req->log(s, "verifying op mask");
+ ret = op->verify_op_mask();
+ if (ret < 0) {
+ abort_early(s, op, ret);
+ goto done;
+ }
+
+ req->log(s, "verifying op permissions");
+ ret = op->verify_permission();
+ if (ret < 0) {
+ if (s->system_request) {
+ dout(2) << "overriding permissions due to system operation" << dendl;
+ } else {
+ abort_early(s, op, ret);
+ goto done;
+ }
+ }
+
+ req->log(s, "verifying op params");
+ ret = op->verify_params();
+ if (ret < 0) {
+ abort_early(s, op, ret);
+ goto done;
+ }
+
+ if (s->expect_cont)
+ dump_continue(s);
+
+ req->log(s, "executing");
+ op->execute();
+ op->complete();
+done:
+ if (should_log) {
+ rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
+ }
+
+ int http_ret = s->err.http_ret;
+
+ req->log_format(s, "http status=%d", http_ret);
+
+ if (handler)
+ handler->put_op(op);
+ rest->put_handler(handler);
+ store->destroy_context(s->obj_ctx);
+
+ dout(1) << "====== req done req=" << hex << req << dec << " http_status=" << http_ret << " ======" << dendl;
+ delete req;
+
+// Mark as processed
+ return 1;
+}
+
#ifdef HAVE_CURL_MULTI_WAIT
static void check_curl()
{
olog->init(g_conf->rgw_ops_log_socket_path);
}
- pprocess = new RGWProcess(g_ceph_context, store, olog, g_conf->rgw_thread_pool_size, &rest);
+ struct mg_context *ctx;
+ const char *options[] = {"listening_ports", "8080", NULL};
+
+ RGWProcessEnv pe = { store, &rest, olog };
+
+ ctx = mg_start((const char **)&options, &mongoose_callback, &pe);
+ assert(ctx);
+
+ RGWProcess *pprocess = new RGWProcess(g_ceph_context, &pe, g_conf->rgw_thread_pool_size);
init_async_signal_handler();
register_async_signal_handler(SIGHUP, sighup_handler);
sighandler_alrm = signal(SIGALRM, godown_alarm);
pprocess->run();
+
+ mg_stop(ctx);
+
derr << "shutting down" << dendl;
unregister_async_signal_handler(SIGHUP, sighup_handler);
--- /dev/null
+
+#include <string.h>
+
+#include "mongoose/mongoose.h"
+#include "rgw_mongoose.h"
+
+
+#define dout_subsys ceph_subsys_rgw
+
+int RGWMongoose::write_data(const char *buf, int len)
+{
+ if (!sent_header) {
+ header_data.append(buf, len);
+ return 0;
+ }
+ dout(0) << buf << dendl;
+ return mg_write(event->conn, buf, len);
+}
+
+RGWMongoose::RGWMongoose(mg_event *_event) : event(_event), sent_header(false) {
+}
+
+int RGWMongoose::read_data(char *buf, int len)
+{
+ return mg_read(event->conn, buf, len);
+}
+
+void RGWMongoose::flush()
+{
+}
+
+void RGWMongoose::init_env(CephContext *cct)
+{
+ env.init(cct);
+ struct mg_request_info *info = event->request_info;
+ 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;
+ }
+
+ 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 */
+}
+
+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(event->conn, buf, sizeof(buf) - 1);
+}
+
+int RGWMongoose::complete_header()
+{
+ header_data.append("\r\n");
+
+ sent_header = true;
+
+ return write_data(header_data.c_str(), header_data.length());
+}
--- /dev/null
+#ifndef CEPH_RGW_MONGOOSE_H
+#define CEPH_RGW_MONGOOSE_H
+
+#include "rgw_client_io.h"
+
+
+struct mg_event;
+struct mg_connection;
+
+
+class RGWMongoose : public RGWClientIO
+{
+ mg_event *event;
+
+ bufferlist header_data;
+
+ bool sent_header;
+
+protected:
+ 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();
+
+public:
+ RGWMongoose(mg_event *_event);
+ void flush();
+};
+
+
+#endif
store = _store;
s = _s;
- if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
- const char *p;
- const char **envp = cio->envp();
- for (int i=0; (p = envp[i]); ++i) {
- ldout(s->cct, 20) << p << dendl;
- }
- }
-
return 0;
}
#include "rgw_rest_s3.h"
#include "rgw_swift_auth.h"
#include "rgw_cors_s3.h"
+#include "rgw_http_errors.h"
#include "rgw_client_io.h"
#include "rgw_resolve.h"
map<string, string> rgw_to_http_attrs;
static map<string, string> generic_attrs_map;
+map<int, const char *> http_status_names;
/*
* make attrs look_like_this
generic_attrs_map[http_header] = rgw_attr;
}
+
+ for (const struct rgw_http_status_code *h = http_codes; h->code; h++) {
+ http_status_names[h->code] = h->name;
+ }
}
-static void dump_status(struct req_state *s, const char *status)
+static void dump_status(struct req_state *s, const char *status, const char *status_name)
{
- int r = s->cio->print("Status: %s\n", status);
+ int r = s->cio->send_status(status, status_name);
if (r < 0) {
- ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
+ ldout(s->cct, 0) << "ERROR: s->cio->send_status() returned err=" << r << dendl;
}
}
{
char buf[32];
snprintf(buf, sizeof(buf), "%d", s->err.http_ret);
- dump_status(s, buf);
+ dump_status(s, buf, http_status_names[s->err.http_ret]);
}
void dump_errno(struct req_state *s, int err)
{
char buf[32];
snprintf(buf, sizeof(buf), "%d", err);
- dump_status(s, buf);
+ dump_status(s, buf, http_status_names[s->err.http_ret]);
}
void dump_content_length(struct req_state *s, uint64_t len)
s->formatter->close_section();
dump_content_length(s, s->formatter->get_len());
}
- int r = s->cio->print("Content-type: %s\r\n\r\n", content_type);
+ int r = s->cio->print("Content-type: %s\r\n", content_type);
if (r < 0) {
ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
}
+ r = s->cio->complete_header();
+ if (r < 0) {
+ ldout(s->cct, 0) << "ERROR: s->cio->complete_header() returned err=" << r << dendl;
+ }
+
s->cio->set_account(true);
rgw_flush_formatter_and_reset(s, s->formatter);
}
void dump_continue(struct req_state *s)
{
- dump_status(s, "100");
- s->cio->flush();
+ s->cio->send_100_continue();
}
void dump_range(struct req_state *s, uint64_t ofs, uint64_t end, uint64_t total)
int RGWRESTSimpleRequest::sign_request(RGWAccessKey& key, RGWEnv& env, req_info& info)
{
- map<string, string>& m = env.get_map();
+ map<string, string, ltstr_nocase>& m = env.get_map();
map<string, string>::iterator i;
for (i = m.begin(); i != m.end(); ++i) {
return ret;
}
- map<string, string>& m = new_env.get_map();
+ map<string, string, ltstr_nocase>& m = new_env.get_map();
map<string, string>::iterator iter;
for (iter = m.begin(); iter != m.end(); ++iter) {
headers.push_back(make_pair<string, string>(iter->first, iter->second));
}
}
-static void add_grants_headers(map<int, string>& grants, map<string, string>& attrs, map<string, string>& meta_map)
+static void add_grants_headers(map<int, string>& grants, map<string, string, ltstr_nocase>& attrs, map<string, string>& meta_map)
{
struct grant_type_to_header *t;
new_info.request_uri = new_info.script_uri;
new_info.effective_uri = new_info.effective_uri;
- map<string, string>& m = new_env.get_map();
+ map<string, string, ltstr_nocase>& m = new_env.get_map();
map<string, bufferlist>::iterator bliter;
/* merge send headers */
return ret;
}
- map<string, string>& m = new_env.get_map();
+ map<string, string, ltstr_nocase>& m = new_env.get_map();
map<string, string>::iterator iter;
for (iter = m.begin(); iter != m.end(); ++iter) {
headers.push_back(make_pair<string, string>(iter->first, iter->second));
*req = new RGWRESTStreamReadRequest(cct, url, cb, NULL, ¶ms);
map<string, string> extra_headers;
if (info) {
- map<string, string>& orig_map = info->env->get_map();
+ map<string, string, ltstr_nocase>& orig_map = info->env->get_map();
/* add original headers that start with HTTP_X_AMZ_ */
#define SEARCH_AMZ_PREFIX "HTTP_X_AMZ_"