author | Michael Krelin <hacker@klever.net> | 2013-02-13 22:38:54 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2013-02-13 22:38:54 (UTC) |
commit | d6545bd95153a5e41cdae441643f4e4a0af94a49 (patch) (unidiff) | |
tree | 51e1ae7f4a3cba4de21e9c62b28c55d414064566 | |
parent | dd545573337e3c54ad4c2c64d72f750ad03aa2c9 (diff) | |
download | iii-d6545bd95153a5e41cdae441643f4e4a0af94a49.zip iii-d6545bd95153a5e41cdae441643f4e4a0af94a49.tar.gz iii-d6545bd95153a5e41cdae441643f4e4a0af94a49.tar.bz2 |
introduce mimewriter classess for gsoap mime streaming
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | src/eyetil.cc | 10 | ||||
-rw-r--r-- | src/eyetil.h | 22 |
2 files changed, 32 insertions, 0 deletions
diff --git a/src/eyetil.cc b/src/eyetil.cc index 6ccc4ae..fba8724 100644 --- a/src/eyetil.cc +++ b/src/eyetil.cc | |||
@@ -130,64 +130,74 @@ static void make_path_for_template(const std::string& p,mode_t m) { | |||
130 | } | 130 | } |
131 | } | 131 | } |
132 | } | 132 | } |
133 | 133 | ||
134 | tmpdir_t::tmpdir_t(const std::string& dt) : dir(dt) { | 134 | tmpdir_t::tmpdir_t(const std::string& dt) : dir(dt) { |
135 | make_path_for_template(dt,0777); | 135 | make_path_for_template(dt,0777); |
136 | if(!mkdtemp((char*)dir.data())) | 136 | if(!mkdtemp((char*)dir.data())) |
137 | throw std::runtime_error("failed to mkdtmp()"); | 137 | throw std::runtime_error("failed to mkdtmp()"); |
138 | } | 138 | } |
139 | tmpdir_t::~tmpdir_t() { | 139 | tmpdir_t::~tmpdir_t() { |
140 | assert(!dir.empty()); | 140 | assert(!dir.empty()); |
141 | if(rmdir(dir.c_str())) { | 141 | if(rmdir(dir.c_str())) { |
142 | syslog(LOG_WARNING,"Failed to remove '%s' directory",dir.c_str()); | 142 | syslog(LOG_WARNING,"Failed to remove '%s' directory",dir.c_str()); |
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
146 | std::string tmpdir_t::get_file(const std::string& f) { | 146 | std::string tmpdir_t::get_file(const std::string& f) { |
147 | std::string::size_type ls = f.rfind('/'); | 147 | std::string::size_type ls = f.rfind('/'); |
148 | return dir+'/'+( | 148 | return dir+'/'+( |
149 | (ls==std::string::npos) | 149 | (ls==std::string::npos) |
150 | ? f | 150 | ? f |
151 | : f.substr(ls+1) | 151 | : f.substr(ls+1) |
152 | ); | 152 | ); |
153 | } | 153 | } |
154 | 154 | ||
155 | tarchive_t::tarchive_t(void *p,size_t s) : a(archive_read_new()), e(0) { | 155 | tarchive_t::tarchive_t(void *p,size_t s) : a(archive_read_new()), e(0) { |
156 | if(!a) throw std::runtime_error("failed to archive_read_new()"); | 156 | if(!a) throw std::runtime_error("failed to archive_read_new()"); |
157 | if(archive_read_support_format_tar(a)) { | 157 | if(archive_read_support_format_tar(a)) { |
158 | archive_read_finish(a); | 158 | archive_read_finish(a); |
159 | throw std::runtime_error("failed to archive_read_support_format_tar()"); | 159 | throw std::runtime_error("failed to archive_read_support_format_tar()"); |
160 | } | 160 | } |
161 | if(archive_read_open_memory(a,p,s)) { | 161 | if(archive_read_open_memory(a,p,s)) { |
162 | archive_read_finish(a); | 162 | archive_read_finish(a); |
163 | throw std::runtime_error("failed to archive_read_open_memory()"); | 163 | throw std::runtime_error("failed to archive_read_open_memory()"); |
164 | } | 164 | } |
165 | } | 165 | } |
166 | tarchive_t::~tarchive_t() { | 166 | tarchive_t::~tarchive_t() { |
167 | assert(a); | 167 | assert(a); |
168 | archive_read_finish(a); | 168 | archive_read_finish(a); |
169 | } | 169 | } |
170 | 170 | ||
171 | bool tarchive_t::read_next_header() { | 171 | bool tarchive_t::read_next_header() { |
172 | assert(a); | 172 | assert(a); |
173 | return archive_read_next_header(a,&e)==ARCHIVE_OK; | 173 | return archive_read_next_header(a,&e)==ARCHIVE_OK; |
174 | } | 174 | } |
175 | 175 | ||
176 | std::string tarchive_t::entry_pathname() { | 176 | std::string tarchive_t::entry_pathname() { |
177 | assert(a); assert(e); | 177 | assert(a); assert(e); |
178 | return archive_entry_pathname(e); | 178 | return archive_entry_pathname(e); |
179 | } | 179 | } |
180 | 180 | ||
181 | bool tarchive_t::read_data_into_fd(int fd) { | 181 | bool tarchive_t::read_data_into_fd(int fd) { |
182 | assert(a); | 182 | assert(a); |
183 | return archive_read_data_into_fd(a,fd)==ARCHIVE_OK; | 183 | return archive_read_data_into_fd(a,fd)==ARCHIVE_OK; |
184 | } | 184 | } |
185 | 185 | ||
186 | 186 | ||
187 | binary_t integrity_digest(const void *ptr,size_t size,const std::string& ukey) { | 187 | binary_t integrity_digest(const void *ptr,size_t size,const std::string& ukey) { |
188 | md5_digester rv; | 188 | md5_digester rv; |
189 | std::transform( (block512_t*)ptr, ((block512_t*)ptr)+size/sizeof(block512_t), | 189 | std::transform( (block512_t*)ptr, ((block512_t*)ptr)+size/sizeof(block512_t), |
190 | rv.updater<uint16_t>(), block512_t::tcpcksum ); | 190 | rv.updater<uint16_t>(), block512_t::tcpcksum ); |
191 | rv.update( binary_t(ukey) ); | 191 | rv.update( binary_t(ukey) ); |
192 | return rv.final(); | 192 | return rv.final(); |
193 | } | 193 | } |
194 | |||
195 | mimewrite_tarfile::mimewrite_tarfile(tmpdir_t& d) { | ||
196 | f.open((fn=d.get_file("the-tarfile.tar")).c_str(),std::ios_base::in|std::ios_base::out|std::ios_base::trunc|std::ios_base::binary); | ||
197 | } | ||
198 | mimewrite_tarfile::~mimewrite_tarfile() { | ||
199 | unlink(fn.c_str()); | ||
200 | } | ||
201 | int mimewrite_tarfile::write(const char *buf,size_t len) { | ||
202 | return f.write(buf,len) ? (idigest.update(buf,len),SOAP_OK) : SOAP_ERR; | ||
203 | } | ||
diff --git a/src/eyetil.h b/src/eyetil.h index 8784cb4..64948d0 100644 --- a/src/eyetil.h +++ b/src/eyetil.h | |||
@@ -1,116 +1,138 @@ | |||
1 | #ifndef __EYETIL_H | 1 | #ifndef __EYETIL_H |
2 | #define __EYETIL_H | 2 | #define __EYETIL_H |
3 | 3 | ||
4 | #include <vector> | 4 | #include <vector> |
5 | #include <string> | 5 | #include <string> |
6 | #include <fstream> | ||
6 | #include <archive.h> | 7 | #include <archive.h> |
7 | #include <archive_entry.h> | 8 | #include <archive_entry.h> |
8 | #include "openssl/md5.h" | 9 | #include "openssl/md5.h" |
10 | #include "soapH.h" | ||
9 | 11 | ||
10 | struct throwable_exit { | 12 | struct throwable_exit { |
11 | int rc; | 13 | int rc; |
12 | throwable_exit(int rc_) : rc(rc_) { } | 14 | throwable_exit(int rc_) : rc(rc_) { } |
13 | }; | 15 | }; |
14 | 16 | ||
15 | class binary_t : public std::vector<unsigned char> { | 17 | class binary_t : public std::vector<unsigned char> { |
16 | public: | 18 | public: |
17 | binary_t() { } | 19 | binary_t() { } |
18 | binary_t(size_type n) : std::vector<unsigned char>(n) { } | 20 | binary_t(size_type n) : std::vector<unsigned char>(n) { } |
19 | binary_t(const std::string& h) { from_hex(h); } | 21 | binary_t(const std::string& h) { from_hex(h); } |
20 | binary_t(const void *d,size_t s) { from_data(d,s); } | 22 | binary_t(const void *d,size_t s) { from_data(d,s); } |
21 | 23 | ||
22 | binary_t& from_hex(const std::string& h); | 24 | binary_t& from_hex(const std::string& h); |
23 | binary_t& from_data(const void *d,size_t s); | 25 | binary_t& from_data(const void *d,size_t s); |
24 | binary_t& make_nonce(); | 26 | binary_t& make_nonce(); |
25 | 27 | ||
26 | std::string hex() const; | 28 | std::string hex() const; |
27 | binary_t md5() const; | 29 | binary_t md5() const; |
28 | }; | 30 | }; |
29 | 31 | ||
30 | struct md5_digester { | 32 | struct md5_digester { |
31 | MD5_CTX ctx; | 33 | MD5_CTX ctx; |
32 | md5_digester() { init(); } | 34 | md5_digester() { init(); } |
33 | 35 | ||
34 | void init(); | 36 | void init(); |
35 | void update(const void *d,size_t l); | 37 | void update(const void *d,size_t l); |
36 | binary_t final(); | 38 | binary_t final(); |
37 | 39 | ||
38 | template<typename T> | 40 | template<typename T> |
39 | void update(const T& x) { update(&x,sizeof(x)); } | 41 | void update(const T& x) { update(&x,sizeof(x)); } |
40 | 42 | ||
41 | template<typename T> | 43 | template<typename T> |
42 | struct update_iterator : public std::iterator<std::output_iterator_tag,T,void,T*,T&> { | 44 | struct update_iterator : public std::iterator<std::output_iterator_tag,T,void,T*,T&> { |
43 | md5_digester *d; | 45 | md5_digester *d; |
44 | update_iterator(md5_digester *d_) : d(d_) { } | 46 | update_iterator(md5_digester *d_) : d(d_) { } |
45 | update_iterator(const update_iterator& x) : d(x.d) { } | 47 | update_iterator(const update_iterator& x) : d(x.d) { } |
46 | 48 | ||
47 | update_iterator& operator*() { return *this; } | 49 | update_iterator& operator*() { return *this; } |
48 | update_iterator& operator++() { return *this; } | 50 | update_iterator& operator++() { return *this; } |
49 | update_iterator& operator++(int) { return *this; } | 51 | update_iterator& operator++(int) { return *this; } |
50 | 52 | ||
51 | update_iterator& operator=(const T& x) { | 53 | update_iterator& operator=(const T& x) { |
52 | d->update(x); return *this; | 54 | d->update(x); return *this; |
53 | } | 55 | } |
54 | }; | 56 | }; |
55 | 57 | ||
56 | template<typename T> | 58 | template<typename T> |
57 | update_iterator<T> updater() { | 59 | update_iterator<T> updater() { |
58 | return update_iterator<T>(this); | 60 | return update_iterator<T>(this); |
59 | } | 61 | } |
60 | 62 | ||
61 | }; | 63 | }; |
62 | template<> inline void md5_digester::update<binary_t>(const binary_t& x) { | 64 | template<> inline void md5_digester::update<binary_t>(const binary_t& x) { |
63 | update((const unsigned char*)&(x.front()),x.size()); | 65 | update((const unsigned char*)&(x.front()),x.size()); |
64 | } | 66 | } |
65 | 67 | ||
66 | #pragma pack(1) | 68 | #pragma pack(1) |
67 | struct block512_t { | 69 | struct block512_t { |
68 | enum { words = 512 / sizeof(uint16_t) }; | 70 | enum { words = 512 / sizeof(uint16_t) }; |
69 | uint16_t data[words]; | 71 | uint16_t data[words]; |
70 | 72 | ||
71 | inline uint8_t *dptr(size_t o) { return ((uint8_t*)this)+o; } | 73 | inline uint8_t *dptr(size_t o) { return ((uint8_t*)this)+o; } |
72 | 74 | ||
73 | static uint16_t tcpcksum(block512_t& data); | 75 | static uint16_t tcpcksum(block512_t& data); |
74 | }; | 76 | }; |
75 | #pragma pack() | 77 | #pragma pack() |
76 | 78 | ||
77 | struct integrity_digester { | 79 | struct integrity_digester { |
78 | md5_digester md5; | 80 | md5_digester md5; |
79 | size_t data_size; | 81 | size_t data_size; |
80 | block512_t data; | 82 | block512_t data; |
81 | 83 | ||
82 | integrity_digester() : data_size(0) { } | 84 | integrity_digester() : data_size(0) { } |
83 | void update(const void *d,size_t s); | 85 | void update(const void *d,size_t s); |
84 | binary_t final(const std::string& ukey); | 86 | binary_t final(const std::string& ukey); |
85 | }; | 87 | }; |
86 | 88 | ||
87 | 89 | ||
88 | class tmpdir_t { | 90 | class tmpdir_t { |
89 | public: | 91 | public: |
90 | std::string dir; | 92 | std::string dir; |
91 | 93 | ||
92 | tmpdir_t(const std::string& dt); | 94 | tmpdir_t(const std::string& dt); |
93 | ~tmpdir_t(); | 95 | ~tmpdir_t(); |
94 | 96 | ||
95 | std::string get_file(const std::string& f); | 97 | std::string get_file(const std::string& f); |
96 | }; | 98 | }; |
97 | 99 | ||
98 | class tarchive_t { | 100 | class tarchive_t { |
99 | public: | 101 | public: |
100 | struct archive *a; | 102 | struct archive *a; |
101 | struct archive_entry *e; | 103 | struct archive_entry *e; |
102 | 104 | ||
103 | tarchive_t(void *p,size_t s); | 105 | tarchive_t(void *p,size_t s); |
104 | ~tarchive_t(); | 106 | ~tarchive_t(); |
105 | 107 | ||
106 | bool read_next_header(); | 108 | bool read_next_header(); |
107 | 109 | ||
108 | std::string entry_pathname(); | 110 | std::string entry_pathname(); |
109 | 111 | ||
110 | bool read_data_into_fd(int fd); | 112 | bool read_data_into_fd(int fd); |
111 | }; | 113 | }; |
112 | 114 | ||
115 | struct mimewrite_base { | ||
116 | virtual ~mimewrite_base() { } | ||
117 | |||
118 | virtual int write(const char *buf,size_t len) = 0; | ||
119 | virtual void close() = 0; | ||
120 | }; | ||
121 | struct mimewrite_string : public mimewrite_base { | ||
122 | std::string str; | ||
123 | int write(const char *buf,size_t len) { str.append(buf,len); return SOAP_OK; }; | ||
124 | void close() { } | ||
125 | }; | ||
126 | struct mimewrite_tarfile : public mimewrite_base { | ||
127 | std::string fn; | ||
128 | std::fstream f; | ||
129 | integrity_digester idigest; | ||
130 | mimewrite_tarfile(tmpdir_t& d); | ||
131 | ~mimewrite_tarfile(); | ||
132 | int write(const char *buf,size_t len); | ||
133 | void close() { } | ||
134 | }; | ||
113 | binary_t integrity_digest(const void *ptr,size_t size, | 135 | binary_t integrity_digest(const void *ptr,size_t size, |
114 | const std::string& ukey); | 136 | const std::string& ukey); |
115 | 137 | ||
116 | #endif /* __EYETIL_H */ | 138 | #endif /* __EYETIL_H */ |