summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_torrent.h
blob: bf2e2217c25317c7524382da5428efb554f03e62 (plain)
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);
};