This file is indexed.

/usr/include/leatherman/curl/client.hpp is in libleatherman-dev 1.4.0+dfsg-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
/**
* @file
* Declares the HTTP client.
*/
#pragma once

#include <leatherman/util/scoped_resource.hpp>
#include <leatherman/locale/locale.hpp>
#include "request.hpp"
#include "response.hpp"
#include <curl/curl.h>
#include <boost/optional.hpp>
#include <boost/filesystem.hpp>
#include <boost/nowide/cstdio.hpp>
#include "export.h"


namespace leatherman { namespace curl {

    /**
     * Resource for a cURL handle.
     */
    struct LEATHERMAN_CURL_EXPORT curl_handle : util::scoped_resource<CURL*>
    {
        /**
         * Constructs a cURL handle.
         */
        curl_handle();

     private:
        static void cleanup(CURL* curl);
    };

    /**
     * Resource for a cURL linked-list.
     */
    struct LEATHERMAN_CURL_EXPORT curl_list : util::scoped_resource<curl_slist*>
    {
        /**
         * Constructs a curl_list.
         */
        curl_list();

        /**
         * Appends the given string onto the list.
         * @param value The string to append onto the list.
         */
        void append(std::string const& value);

     private:
        static void cleanup(curl_slist* list);
    };

    /**
     * Resource for a cURL escaped string.
     */
    struct LEATHERMAN_CURL_EXPORT curl_escaped_string : util::scoped_resource<char const*>
    {
        /**
         * Constructs a cURL escaped string.
         * @param handle The cURL handle to use to perform the escape.
         * @param str The string to escape.
         */
        curl_escaped_string(curl_handle const& handle, std::string const& str);

     private:
        static void cleanup(char const* str);
    };

    /**
     * Resource for a temporary file used during download
     */
    struct LEATHERMAN_CURL_NO_EXPORT download_temp_file
    {
        /**
         * Constructs a temporary file that will be used to store the downloaded file's
         * contents.
         * @param req The HTTP request.
         * @param file_path The file path that this temporary file's contents will be written to.
         * @param perms The (optional) permissions of the downloaded file.
         */
        download_temp_file(request const& req, std::string const& file_path, boost::optional<boost::filesystem::perms> perms);

        ~download_temp_file();

        /*
         * Returns the underlying file pointer.
         */
        FILE* get_fp();

        /*
         * Writes the temporary file's contents to its file path.
         */
        void write();

        /*
         * Writes the temporary file's contents to the body of the
         * given response.
         * @param response The HTTP response to write the contents to
         */
        void write(response& res);

     private:
        void close_fp();
        void cleanup();
        FILE* _fp;
        request _req;
        std::string _file_path;
        boost::filesystem::path _temp_path;
    };

    /**
     * The exception for HTTP.
     */
    struct LEATHERMAN_CURL_EXPORT http_exception : std::runtime_error
    {
        /**
         * Constructs an http_exception.
         * @param message The exception message.
         */
        http_exception(std::string const& message) :
            runtime_error(message)
        {
        }
    };

    /**
     * The exception for HTTP requests.
     */
    struct LEATHERMAN_CURL_EXPORT http_request_exception : http_exception
    {
        /**
         * Constructs an http_request_exception.
         * @param req The HTTP request that caused the exception.
         * @param message The exception message.
         */
        http_request_exception(request req, std::string const &message) :
            http_exception(message),
            _req(std::move(req))
        {
        }

        /**
         * Gets the request associated with the exception
         * @return Returns the request associated with the exception.
         */
        request const& req() const
        {
            return _req;
        }

     private:
        request _req;
    };

    /**
     * The exception for curl_easy_setopt errors.
     */
    struct LEATHERMAN_CURL_EXPORT http_curl_setup_exception : http_request_exception
    {
        /**
         * Constructs an http_curl_setup_exception.
         * @param req The HTTP request that caused the exception.
         * @param message The exception message.
         * @param curl_opt The CURL option that failed.
         */
        http_curl_setup_exception(request req, CURLoption curl_opt, std::string const &message) :
            http_request_exception(req, message),
            _curl_opt(std::move(curl_opt))
        {
        }

        /**
         * Gets the CURL option associated with the exception
         * @return Returns the CURL option associated with the exception.
         */
        CURLoption const& curl_opt() const
        {
            return _curl_opt;
        }


     private:
        CURLoption _curl_opt;
    };

    /**
     * The exception for HTTP file download server-side errors.
     */
    struct LEATHERMAN_CURL_EXPORT http_file_download_exception : http_request_exception
    {
        /**
         * Constructs an http_file_download_exception.
         * @param request The request that caused the exception
         * @param file_path The file that was meant to be downloaded
         * @param message The exception message.
         */
        http_file_download_exception(request req, std::string file_path, std::string const &message) :
          http_request_exception(req, message),
          _file_path(std::move(file_path))
        {
        }

        /**
         * Gets the file_path associated with the exception
         * @return Returns the file_path associated with the exception.
         */
        std::string const& file_path() const
        {
            return _file_path;
        }

     private:
        std::string _file_path;
    };

    /**
     * The exception for HTTP file download file operation errors.
     */
    struct LEATHERMAN_CURL_EXPORT http_file_operation_exception : http_request_exception
    {
        /**
         * Constructs an http_file_operation_exception.
         * @param request The request that caused the exception
         * @param file_path The file that was meant to be downloaded
         * @param message The exception message.
         */
        http_file_operation_exception(request req, std::string file_path, std::string const &message) : http_file_operation_exception(req, file_path, "", message)
        {
        }

        /**
         * Constructs an http_file_operation_exception.
         * @param request The request that caused the exception
         * @param file_path The file that was meant to be downloaded
         * @param temp_path The path to the temporary file that wasn't successfully cleaned up.
         * @param message The exception message.
         */
        http_file_operation_exception(request req, std::string file_path, std::string temp_path, std::string const &message) :
            http_request_exception(req, message),
            _file_path(file_path),
            _temp_path(std::move(temp_path))
        {
        }

        /**
         * Gets the file_path associated with the exception
         * @return Returns the file_path associated with the exception.
         */
        std::string const& file_path() const
        {
            return _file_path;
        }

        /**
         * Gets the temp_path associated with the exception
         * @return Returns the temp_path associated with the exception.
         */
        std::string const& temp_path() const
        {
            return _temp_path;
        }

     private:
        std::string _file_path;
        std::string _temp_path;
    };

    /**
     * Implements a client for HTTP.
     * Note: this class is not thread-safe.
     */
    struct LEATHERMAN_CURL_EXPORT client
    {
        /**
         * Constructs an HTTP client.
         */
        client();

        /**
         * Moves the given client into this client.
         * @param other The client to move into this client.
         */
        client(client&& other);

        /**
         * Moves the given client into this client.
         * @param other The client to move into this client.
         * @return Returns this client.
         */
        client& operator=(client&& other);

        /**
         * Performs a GET with the given request.
         * @param req The HTTP request to perform.
         * @return Returns the HTTP response.
         */
        response get(request const& req);

        /**
         * Performs a POST with the given request.
         * @param req The HTTP request to perform.
         * @return Returns the HTTP response.
         */
        response post(request const& req);

        /**
         * Performs a PUT with the given request.
         * @param req The HTTP request to perform.
         * @return Returns the HTTP response.
         */
        response put(request const& req);

        /**
         * Downloads the file from the specified url.
         * Throws http_file_download_exception if anything goes wrong.
         * @param req The HTTP request to perform.
         * @param file_path The file that the downloaded contents will be written to.
         * @param perms The file permissions to apply when writing to file_path.
         *              On Windows this only toggles read-only.
         */
        void download_file(request const& req,
                           std::string const& file_path,
                           boost::optional<boost::filesystem::perms> perms = {});

        /**
         * Downloads the file from the specified url.
         * Throws http_file_download_exception if anything goes wrong.
         * @param req The HTTP request to perform.
         * @param file_path The file that the downloaded contents will be written to.
         * @param response The HTTP response. The body will only be included if the response status is >= 400.
         * @param perms The file permissions to apply when writing to file_path.
         *              On Windows this only toggles read-only.
         */
        void download_file(request const& req,
                           std::string const& file_path,
                           response& res,
                           boost::optional<boost::filesystem::perms> perms = {});

        /**
         * Sets the path to the CA certificate file.
         * @param cert_file The path to the CA certificate file.
         */
        void set_ca_cert(std::string const& cert_file);

        /**
         * Set client SSL certificate and key.
         * @param client_cert The path to the client's certificate file.
         * @param client_key The path to the client's key file.
         */
        void set_client_cert(std::string const& client_cert, std::string const& client_key);

        /**
         * Set and limit what protocols curl will support
         * @param client_protocols bitmask of CURLPROTO_*
         *        (see more: http://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html)
         */
        void set_supported_protocols(long client_protocols);

     private:
        client(client const&) = delete;
        client& operator=(client const&) = delete;

        enum struct http_method
        {
            get,
            put,
            post
        };

        struct context
        {
            context(request const& req, response& res) :
                req(req),
                res(res),
                read_offset(0)
            {
            }

            request const& req;
            response& res;
            size_t read_offset;
            curl_list request_headers;
            std::string response_buffer;
        };

        std::string _ca_cert;
        std::string _client_cert;
        std::string _client_key;
        long _client_protocols = CURLPROTO_ALL;

        response perform(http_method method, request const& req);
        void download_file_helper(request const& req,
                                  std::string const& file_path,
                                  boost::optional<response&> res = {},
                                  boost::optional<boost::filesystem::perms> perms = {});

        LEATHERMAN_CURL_NO_EXPORT void set_method(context& ctx, http_method method);
        LEATHERMAN_CURL_NO_EXPORT void set_url(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_headers(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_cookies(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_body(context& ctx, http_method method);
        LEATHERMAN_CURL_NO_EXPORT void set_timeouts(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_header_write_callbacks(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_write_callbacks(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_write_callbacks(context& ctx, FILE* fp);
        LEATHERMAN_CURL_NO_EXPORT void set_client_info(context &ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_ca_info(context& ctx);
        LEATHERMAN_CURL_NO_EXPORT void set_client_protocols(context& ctx);

        template <typename ParamType>
        LEATHERMAN_CURL_NO_EXPORT void curl_easy_setopt_maybe(
            context &ctx,
            CURLoption option,
            ParamType const& param
        ) {
            auto result = curl_easy_setopt(_handle, option, param);
            if (result != CURLE_OK) {
                throw http_curl_setup_exception(ctx.req, option, leatherman::locale::_("Failed setting up libcurl. Reason: {1}", curl_easy_strerror(result)));
            }
        }

        static size_t read_body(char* buffer, size_t size, size_t count, void* ptr);
        static int seek_body(void* ptr, curl_off_t offset, int origin);
        static size_t write_header(char* buffer, size_t size, size_t count, void* ptr);
        static size_t write_body(char* buffer, size_t size, size_t count, void* ptr);
        static size_t write_file(char *buffer, size_t size, size_t count, void* ptr);
        static int debug(CURL* handle, curl_infotype type, char* data, size_t size, void* ptr);

        curl_handle _handle;

    protected:
        /**
         * Returns a reference to a cURL handle resource used in the request.
         * This is primarily exposed for testing.
         * @return Returns a const reference to the cURL handle resource.
         */
        curl_handle const& get_handle();
    };

}}  // namespace leatherman::curl