1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp
#pragma once
#include <string>
#include <list>
#include <map>
#include <set>
#include "common/ceph_time.h"
#include "rgw_common.h"
using ceph::crypto::SHA1;
struct req_state;
#define RGW_OBJ_TORRENT "rgw.torrent"
#define ANNOUNCE "announce"
#define ANNOUNCE_LIST "announce-list"
#define COMMENT "comment"
#define CREATED_BY "created by"
#define CREATION_DATE "creation date"
#define ENCODING "encoding"
#define LENGTH "length"
#define NAME "name"
#define PIECE_LENGTH "piece length"
#define PIECES "pieces"
#define INFO_PIECES "info"
#define GET_TORRENT "torrent"
class TorrentBencode
{
public:
TorrentBencode() {}
~TorrentBencode() {}
//control characters
void bencode_dict(bufferlist& bl) { bl.append('d'); }
void bencode_list(bufferlist& bl) { bl.append('l'); }
void bencode_end(bufferlist& bl) { bl.append('e'); }
//single values
void bencode(int value, bufferlist& bl)
{
bl.append('i');
char info[100] = { 0 };
sprintf(info, "%d", value);
bl.append(info, strlen(info));
bencode_end(bl);
}
//single values
void bencode(const std::string& str, bufferlist& bl)
{
bencode_key(str, bl);
}
//dictionary elements
void bencode(const std::string& key, int value, bufferlist& bl)
{
bencode_key(key, bl);
bencode(value, bl);
}
//dictionary elements
void bencode(const std::string& key, const std::string& value, bufferlist& bl)
{
bencode_key(key, bl);
bencode(value, bl);
}
//key len
void bencode_key(const std::string& key, bufferlist& bl)
{
int len = key.length();
char info[100] = { 0 };
sprintf(info, "%d:", len);
bl.append(info, strlen(info));
bl.append(key.c_str(), len);
}
};
/* torrent file struct */
class seed
{
private:
struct
{
int piece_length; // each piece length
bufferlist sha1_bl; // save sha1
std::string name; // file name
off_t len; // file total bytes
}info;
std::string announce; // tracker
std::string origin; // origin
time_t create_date{0}; // time of the file created
std::string comment; // comment
std::string create_by; // app name and version
std::string encoding; // if encode use gbk rather than gtf-8 use this field
uint64_t sha_len; // sha1 length
bool is_torrent; // flag
bufferlist bl; // bufflist ready to send
req_state *s{nullptr};
rgw::sal::Driver* driver{nullptr};
SHA1 h;
TorrentBencode dencode;
public:
seed();
~seed();
int get_params();
void init(req_state *p_req, rgw::sal::Driver* _driver);
int get_torrent_file(rgw::sal::Object* object,
uint64_t &total_len,
ceph::bufferlist &bl_data,
rgw_obj &obj);
off_t get_data_len();
bool get_flag();
void set_create_date(ceph::real_time& value);
void set_info_name(const std::string& value);
void update(bufferlist &bl);
int complete(optional_yield y);
private:
void do_encode ();
void set_announce();
void set_exist(bool exist);
void set_info_pieces(char *buff);
void sha1(SHA1 *h, bufferlist &bl, off_t bl_len);
int save_torrent_file(optional_yield y);
};
|