summaryrefslogtreecommitdiff
path: root/inc/request.h
blob: 9e3a477076e46482ccd0f44d679eaf042472c2be (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
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
/** **************************************************************************
 * request.h
 * 
 * Copyright 2008 Bryan Ischo <bryan@ischo.com>
 * 
 * This file is part of libs3.
 * 
 * libs3 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, version 3 of the License.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of this library and its programs with the
 * OpenSSL library, and distribute linked combinations including the two.
 *
 * libs3 is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License version 3
 * along with libs3, in a file named COPYING.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 ************************************************************************** **/

#ifndef REQUEST_H
#define REQUEST_H

#include "libs3.h"
#include "error_parser.h"
#include "response_headers_handler.h"
#include "util.h"

// Describes a type of HTTP request (these are our supported HTTP "verbs")
typedef enum
{
    HttpRequestTypeGET,
    HttpRequestTypeHEAD,
    HttpRequestTypePUT,
    HttpRequestTypeCOPY,
    HttpRequestTypeDELETE
} HttpRequestType;


// This completely describes a request.  A RequestParams is not required to be
// allocated from the heap and its lifetime is not assumed to extend beyond
// the lifetime of the function to which it has been passed.
typedef struct RequestParams
{
    // Request type, affects the HTTP verb used
    HttpRequestType httpRequestType;

    // Bucket context for request
    S3BucketContext bucketContext;

    // Key, if any
    const char *key;

    // Query params - ready to append to URI (i.e. ?p1=v1?p2=v2)
    const char *queryParams;

    // sub resource, like ?acl, ?location, ?torrent, ?logging
    const char *subResource;

    // If this is a copy operation, this gives the source bucket
    const char *copySourceBucketName;

    // If this is a copy operation, this gives the source key
    const char *copySourceKey;

    // Get conditions
    const S3GetConditions *getConditions;

    // Start byte
    uint64_t startByte;

    // Byte count
    uint64_t byteCount;

    // Put properties
    const S3PutProperties *putProperties;

    // Callback to be made when headers are available.  Might not be called.
    S3ResponsePropertiesCallback *propertiesCallback;

    // Callback to be made to supply data to send to S3.  Might not be called.
    S3PutObjectDataCallback *toS3Callback;

    // Number of bytes total that readCallback will supply
    int64_t toS3CallbackTotalSize;

    // Callback to be made that supplies data read from S3.
    // Might not be called.
    S3GetObjectDataCallback *fromS3Callback;

    // Callback to be made when request is complete.  This will *always* be
    // called.
    S3ResponseCompleteCallback *completeCallback;

    // Data passed to the callbacks
    void *callbackData;
} RequestParams;


// This is the stuff associated with a request that needs to be on the heap
// (and thus live while a curl_multi is in use).
typedef struct Request
{
    // These put the request on a doubly-linked list of requests in a
    // request context, *if* the request is in a request context (else these
    // will both be 0)
    struct Request *prev, *next;

    // The status of this Request, as will be reported to the user via the
    // complete callback
    S3Status status;

    // The HTTP code returned by the S3 server, if it is known.  Would rather
    // not have to keep track of this but S3 doesn't always indicate its
    // errors the same way
    int httpResponseCode;

    // The HTTP headers to use for the curl request
    struct curl_slist *headers;

    // The CURL structure driving the request
    CURL *curl;

    // libcurl requires that the uri be stored outside of the curl handle
    char uri[MAX_URI_SIZE + 1];

    // Callback to be made when headers are available.  Might not be called.
    S3ResponsePropertiesCallback *propertiesCallback;

    // Callback to be made to supply data to send to S3.  Might not be called.
    S3PutObjectDataCallback *toS3Callback;

    // Number of bytes total that readCallback has left to supply
    int64_t toS3CallbackBytesRemaining;

    // Callback to be made that supplies data read from S3.
    // Might not be called.
    S3GetObjectDataCallback *fromS3Callback;

    // Callback to be made when request is complete.  This will *always* be
    // called.
    S3ResponseCompleteCallback *completeCallback;

    // Data passed to the callbacks
    void *callbackData;

    // Handler of response headers
    ResponseHeadersHandler responseHeadersHandler;

    // This is set to nonzero after the properties callback has been made
    int propertiesCallbackMade;

    // Parser of errors
    ErrorParser errorParser;
} Request;


// Request functions
// ----------------------------------------------------------------------------

// Initialize the API
S3Status request_api_initialize(const char *userAgentInfo, int flags,
                                const char *hostName);

// Deinitialize the API
void request_api_deinitialize();

// Perform a request; if context is 0, performs the request immediately;
// otherwise, sets it up to be performed by context.
void request_perform(const RequestParams *params, S3RequestContext *context);

// Called by the internal request code or internal request context code when a
// curl has finished the request
void request_finish(Request *request);

// Convert a CURLE code to an S3Status
S3Status request_curl_code_to_status(CURLcode code);


#endif /* REQUEST_H */