2010-03-26 23:29:11 +00:00
|
|
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
|
|
|
// vim: ts=8 sw=2 smarttab
|
|
|
|
/*
|
|
|
|
* Ceph - scalable distributed file system
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
|
|
|
|
*
|
|
|
|
* This is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software
|
|
|
|
* Foundation. See file COPYING.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2010-06-12 13:04:11 +00:00
|
|
|
#ifndef CEPH_RGW_COMMON_H
|
|
|
|
#define CEPH_RGW_COMMON_H
|
2009-07-18 00:49:59 +00:00
|
|
|
|
|
|
|
#include "fcgiapp.h"
|
|
|
|
|
|
|
|
#include <openssl/md5.h>
|
|
|
|
#include <string>
|
|
|
|
#include <map>
|
|
|
|
#include "include/types.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
#define SERVER_NAME "RGWFS"
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
#define RGW_ATTR_PREFIX "user.rgw."
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
#define RGW_ATTR_ACL RGW_ATTR_PREFIX "acl"
|
|
|
|
#define RGW_ATTR_ETAG RGW_ATTR_PREFIX "etag"
|
2010-03-11 22:49:27 +00:00
|
|
|
#define RGW_ATTR_BUCKETS RGW_ATTR_PREFIX "buckets"
|
2009-08-07 17:46:29 +00:00
|
|
|
#define RGW_ATTR_META_PREFIX RGW_ATTR_PREFIX "x-amz-meta-"
|
|
|
|
#define RGW_ATTR_CONTENT_TYPE RGW_ATTR_PREFIX "content_type"
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2010-03-26 23:29:11 +00:00
|
|
|
#define USER_INFO_VER 2
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
typedef void *RGWAccessHandle;
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Store error returns for output at a different point in the program */
|
2009-08-07 17:46:29 +00:00
|
|
|
struct rgw_err {
|
2009-07-18 00:49:59 +00:00
|
|
|
const char *num;
|
|
|
|
const char *code;
|
|
|
|
const char *message;
|
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
rgw_err() : num(NULL), code(NULL), message(NULL) {}
|
2009-07-18 00:49:59 +00:00
|
|
|
};
|
|
|
|
|
2010-03-11 22:49:27 +00:00
|
|
|
/* Helper class used for XMLArgs parsing */
|
2009-07-18 00:49:59 +00:00
|
|
|
class NameVal
|
|
|
|
{
|
|
|
|
string str;
|
|
|
|
string name;
|
|
|
|
string val;
|
|
|
|
public:
|
|
|
|
NameVal(string nv) : str(nv) {}
|
|
|
|
|
|
|
|
int parse();
|
|
|
|
|
|
|
|
string& get_name() { return name; }
|
|
|
|
string& get_val() { return val; }
|
|
|
|
};
|
|
|
|
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Stores the XML arguments associated with the HTTP request in req_state*/
|
2009-07-18 00:49:59 +00:00
|
|
|
class XMLArgs
|
|
|
|
{
|
|
|
|
string str, empty_str;
|
|
|
|
map<string, string> val_map;
|
|
|
|
string sub_resource;
|
|
|
|
public:
|
|
|
|
XMLArgs() {}
|
|
|
|
XMLArgs(string s) : str(s) {}
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Set the arguments; as received */
|
2009-07-18 00:49:59 +00:00
|
|
|
void set(string s) { val_map.clear(); sub_resource.clear(); str = s; }
|
2010-03-11 22:49:27 +00:00
|
|
|
/** parse the received arguments */
|
2009-07-18 00:49:59 +00:00
|
|
|
int parse();
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Get the value for a specific argument parameter */
|
2009-07-18 00:49:59 +00:00
|
|
|
string& get(string& name);
|
|
|
|
string& get(const char *name);
|
2010-03-11 22:49:27 +00:00
|
|
|
/** see if a parameter is contained in this XMLArgs */
|
2009-07-18 00:49:59 +00:00
|
|
|
bool exists(const char *name) {
|
|
|
|
map<string, string>::iterator iter = val_map.find(name);
|
|
|
|
return (iter != val_map.end());
|
|
|
|
}
|
|
|
|
string& get_sub_resource() { return sub_resource; }
|
|
|
|
};
|
|
|
|
|
|
|
|
enum http_op {
|
|
|
|
OP_GET,
|
|
|
|
OP_PUT,
|
|
|
|
OP_DELETE,
|
|
|
|
OP_HEAD,
|
|
|
|
OP_UNKNOWN,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct fcgx_state {
|
|
|
|
FCGX_ParamArray envp;
|
|
|
|
FCGX_Stream *in;
|
|
|
|
FCGX_Stream *out;
|
|
|
|
FCGX_Stream *err;
|
|
|
|
};
|
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
class RGWAccessControlPolicy;
|
2009-07-18 00:49:59 +00:00
|
|
|
|
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
struct RGWUserInfo
|
2009-07-18 00:49:59 +00:00
|
|
|
{
|
2010-05-07 21:33:42 +00:00
|
|
|
uint64_t auid;
|
2009-07-18 00:49:59 +00:00
|
|
|
string user_id;
|
|
|
|
string secret_key;
|
|
|
|
string display_name;
|
|
|
|
string user_email;
|
|
|
|
|
2010-03-26 23:29:11 +00:00
|
|
|
RGWUserInfo() : auid(0) {}
|
|
|
|
|
2009-07-18 00:49:59 +00:00
|
|
|
void encode(bufferlist& bl) const {
|
|
|
|
__u32 ver = USER_INFO_VER;
|
|
|
|
::encode(ver, bl);
|
2010-03-26 23:29:11 +00:00
|
|
|
::encode(auid, bl);
|
2009-07-18 00:49:59 +00:00
|
|
|
::encode(user_id, bl);
|
|
|
|
::encode(secret_key, bl);
|
|
|
|
::encode(display_name, bl);
|
|
|
|
::encode(user_email, bl);
|
|
|
|
}
|
|
|
|
void decode(bufferlist::iterator& bl) {
|
|
|
|
__u32 ver;
|
|
|
|
::decode(ver, bl);
|
2010-03-26 23:29:11 +00:00
|
|
|
if (ver >= 2) ::decode(auid, bl);
|
|
|
|
else auid = CEPH_AUTH_UID_DEFAULT;
|
2009-07-18 00:49:59 +00:00
|
|
|
::decode(user_id, bl);
|
|
|
|
::decode(secret_key, bl);
|
|
|
|
::decode(display_name, bl);
|
|
|
|
::decode(user_email, bl);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear() {
|
|
|
|
user_id.clear();
|
|
|
|
secret_key.clear();
|
|
|
|
display_name.clear();
|
|
|
|
user_email.clear();
|
2010-03-26 23:29:11 +00:00
|
|
|
auid = CEPH_AUTH_UID_DEFAULT;
|
2009-07-18 00:49:59 +00:00
|
|
|
}
|
|
|
|
};
|
2009-08-07 17:46:29 +00:00
|
|
|
WRITE_CLASS_ENCODER(RGWUserInfo)
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Store all the state necessary to complete and respond to an HTTP request*/
|
2009-07-18 00:49:59 +00:00
|
|
|
struct req_state {
|
|
|
|
struct fcgx_state *fcgx;
|
|
|
|
http_op op;
|
|
|
|
bool content_started;
|
|
|
|
int indent;
|
|
|
|
const char *path_name;
|
|
|
|
string path_name_url;
|
|
|
|
const char *host;
|
|
|
|
const char *method;
|
|
|
|
const char *query;
|
|
|
|
const char *length;
|
|
|
|
const char *content_type;
|
|
|
|
bool err_exist;
|
2009-08-07 17:46:29 +00:00
|
|
|
struct rgw_err err;
|
2009-07-18 00:49:59 +00:00
|
|
|
|
|
|
|
XMLArgs args;
|
|
|
|
|
|
|
|
const char *bucket;
|
|
|
|
const char *object;
|
|
|
|
|
|
|
|
const char *host_bucket;
|
|
|
|
|
|
|
|
string bucket_str;
|
|
|
|
string object_str;
|
|
|
|
|
|
|
|
map<string, string> x_amz_map;
|
|
|
|
|
|
|
|
vector<pair<string, string> > x_amz_meta;
|
|
|
|
|
2009-08-07 17:46:29 +00:00
|
|
|
RGWUserInfo user;
|
|
|
|
RGWAccessControlPolicy *acl;
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2009-07-20 23:41:25 +00:00
|
|
|
string canned_acl;
|
|
|
|
const char *copy_source;
|
|
|
|
const char *http_auth;
|
|
|
|
|
2009-07-18 00:49:59 +00:00
|
|
|
req_state() : acl(NULL) {}
|
|
|
|
};
|
|
|
|
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Store basic data on an object */
|
2009-08-07 17:46:29 +00:00
|
|
|
struct RGWObjEnt {
|
2009-07-18 00:49:59 +00:00
|
|
|
std::string name;
|
|
|
|
size_t size;
|
|
|
|
time_t mtime;
|
|
|
|
char etag[MD5_DIGEST_LENGTH * 2 + 1];
|
|
|
|
|
|
|
|
void encode(bufferlist& bl) const {
|
2010-01-27 21:34:46 +00:00
|
|
|
__u8 struct_v = 1;
|
|
|
|
::encode(struct_v, bl);
|
2010-05-07 21:33:42 +00:00
|
|
|
uint64_t s = size;
|
2009-10-06 17:05:57 +00:00
|
|
|
__u32 mt = mtime;
|
|
|
|
::encode(name, bl);
|
|
|
|
::encode(s, bl);
|
|
|
|
::encode(mt, bl);
|
2009-07-18 00:49:59 +00:00
|
|
|
}
|
|
|
|
void decode(bufferlist::iterator& bl) {
|
2010-01-27 21:34:46 +00:00
|
|
|
__u8 struct_v;
|
|
|
|
::decode(struct_v, bl);
|
2009-10-06 17:05:57 +00:00
|
|
|
__u32 mt;
|
2010-05-07 21:33:42 +00:00
|
|
|
uint64_t s;
|
2009-07-18 00:49:59 +00:00
|
|
|
::decode(name, bl);
|
2009-10-06 17:05:57 +00:00
|
|
|
::decode(s, bl);
|
|
|
|
::decode(mt, bl);
|
|
|
|
size = s;
|
|
|
|
mtime = mt;
|
2009-07-18 00:49:59 +00:00
|
|
|
}
|
|
|
|
};
|
2009-08-07 17:46:29 +00:00
|
|
|
WRITE_CLASS_ENCODER(RGWObjEnt)
|
2009-07-18 00:49:59 +00:00
|
|
|
|
2009-07-20 23:41:25 +00:00
|
|
|
static inline void buf_to_hex(const unsigned char *buf, int len, char *str)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
str[0] = '\0';
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
sprintf(&str[i*2], "%02x", (int)buf[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-11 22:49:27 +00:00
|
|
|
/** */
|
2009-07-18 00:49:59 +00:00
|
|
|
extern int parse_time(const char *time_str, time_t *time);
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Check if a user has a permission on that ACL */
|
2009-08-07 17:46:29 +00:00
|
|
|
extern bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm);
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Check if the req_state's user has the necessary permissions
|
|
|
|
* to do the requested action */
|
2009-07-20 23:41:25 +00:00
|
|
|
extern bool verify_permission(struct req_state *s, int perm);
|
2010-03-11 22:49:27 +00:00
|
|
|
/** Convert an input URL into a sane object name
|
|
|
|
* by converting %-escaped strings into characters, etc*/
|
2009-07-20 23:41:25 +00:00
|
|
|
extern bool url_decode(string& src_str, string& dest_str);
|
2009-07-18 00:49:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
#endif
|