34#define _Class _URLSessionTask
64#pragma mark - URLSessionTask
72 switch (self->
state) {
92 curl_easy_perform(self->locals.
handle);
114 self->
error = calloc(1, CURL_ERROR_SIZE);
136 switch (self->
state) {
153 struct curl_slist **headers = (
struct curl_slist **)
data;
154 *headers = curl_slist_append(*headers, header->
chars);
166 char *header = calloc(count + 1, 1);
167 memcpy(header, buffer, count);
169 char *delim = strchr(header,
':');
173 char *field = header;
174 char *value =
strtrim(delim + 1);
190static int progress(
ident self, curl_off_t bytesExpectedToReceive, curl_off_t bytesReceived,
191 curl_off_t bytesExpectedToSend, curl_off_t bytesSent) {
195 curl_easy_getinfo(this->locals.handle, CURLINFO_RESPONSE_CODE, (
long *) &this->response->httpStatusCode);
197 this->bytesExpectedToReceive = bytesExpectedToReceive;
198 this->bytesExpectedToSend = bytesExpectedToSend;
213 self->locals.
handle = curl_easy_init();
214 assert(self->locals.
handle);
216 curl_easy_setopt(self->locals.
handle, CURLOPT_ERRORBUFFER, self->
error);
217 curl_easy_setopt(self->locals.
handle, CURLOPT_FOLLOWLOCATION,
true);
224 curl_easy_setopt(self->locals.
handle, CURLOPT_TIMEOUT, config->
timeout);
227 curl_easy_setopt(self->locals.
handle, CURLOPT_LOW_SPEED_LIMIT, 1L);
228 curl_easy_setopt(self->locals.
handle, CURLOPT_LOW_SPEED_TIME, 10L);
232 curl_easy_setopt(self->locals.
handle, CURLOPT_HEADERDATA, self);
234 curl_easy_setopt(self->locals.
handle, CURLOPT_XFERINFOFUNCTION,
progress);
235 curl_easy_setopt(self->locals.
handle, CURLOPT_XFERINFODATA, self);
239 curl_easy_setopt(self->locals.
handle, CURLOPT_POSTFIELDS, body->
bytes);
240 curl_easy_setopt(self->locals.
handle, CURLOPT_POSTFIELDSIZE, body->
length);
243 struct curl_slist *httpHeaders = NULL;
256 curl_easy_setopt(self->locals.
handle, CURLOPT_HTTPHEADER, httpHeaders);
262 curl_easy_setopt(self->locals.
handle, CURLOPT_POST,
true);
265 curl_easy_setopt(self->locals.
handle, CURLOPT_PUT,
true);
268 curl_easy_setopt(self->locals.
handle, CURLOPT_CUSTOMREQUEST,
"DELETE");
271 curl_easy_setopt(self->locals.
handle, CURLOPT_CUSTOMREQUEST,
"PATCH");
274 curl_easy_setopt(self->locals.
handle, CURLOPT_NOBODY,
true);
277 curl_easy_setopt(self->locals.
handle, CURLOPT_CUSTOMREQUEST,
"OPTIONS");
292 switch (self->
state) {
308 if (self->locals.
handle) {
309 curl_easy_cleanup(self->locals.
handle);
310 self->locals.
handle = NULL;
319#pragma mark - Class lifecycle
348 .name =
"URLSessionTask",
352 .interfaceSize =
sizeof(URLSessionTaskInterface),
static Array * init(Array *self)
static void teardown(void)
Called atexit to teardown Objectively.
static void setup(void)
Called when initializing Object to setup Objectively.
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Class * _initialize(const ClassDef *def)
Initializes the given Class.
ident retain(ident obj)
Atomically increment the given Object's reference count.
#define alloc(type)
Allocate and initialize and instance of type.
#define super(type, obj, method,...)
static void enumerateObjectsAndKeys(const Dictionary *self, DictionaryEnumerator enumerator, ident data)
static Dictionary * dictionary(void)
static void error(const Log *self, const char *fmt,...)
static int request(RESTClient *self, HTTPMethod method, const char *url_string, const Data *body, Data **out_data)
char * strtrim(const char *s)
Copies the given null-terminated C string, trimming leading and trailing whitespace.
void * ident
The identity type, similar to Objective-C id.
static void setValueForHTTPHeaderField(URLRequest *self, const char *value, const char *field)
A protocol-agnostic abstraction for requesting resources via URLs.
A protocol-agnostic abstraction for receiving resources via URLs.
A management context for loading resources via URLs.
static URLSessionTask * initWithRequestInSession(URLSessionTask *self, struct URLRequest *request, struct URLSession *session, URLSessionTaskCompletion completion)
static void requestHeaders_enumerator(const Dictionary *dictionary, ident obj, ident key, ident data)
A helper to populate the request headers list for CURL.
static void resume(URLSessionTask *self)
static void cancel(URLSessionTask *self)
static void execute(URLSessionTask *self)
static int progress(ident self, curl_off_t bytesExpectedToReceive, curl_off_t bytesReceived, curl_off_t bytesExpectedToSend, curl_off_t bytesSent)
The CURLOPT_XFERINFOFUNCTION, which updates internal state and dispatches the task's progress functio...
Class * _URLSessionTask(void)
static void dealloc(Object *self)
static Object * copy(const Object *self)
static void initialize(Class *clazz)
static size_t responseHeader(char *buffer, size_t size, size_t count, void *data)
The CURLOPT_HEADERFUNCTION for parsing response headers.
static void suspend(URLSessionTask *self)
URL session tasks are handles to pending URL operations.
void(* URLSessionTaskCompletion)(URLSessionTask *task, bool success)
A function pointer for URLSessionTask completion.
@ URLSESSIONTASK_RESUMING
@ URLSESSIONTASK_SUSPENDING
@ URLSESSIONTASK_SUSPENDED
@ URLSESSIONTASK_COMPLETED
@ URLSESSIONTASK_CANCELING
#define do_once(once, block)
Executes the given block at most one time.
ClassDefs are passed to _initialize via an archetype to initialize a Class.
The runtime representation of a Class.
ident interface
The interface of the Class.
size_t length
The length of bytes.
uint8_t * bytes
The bytes.
Object is the root Class of The Objectively Class hierarchy.
void dealloc(Object *self)
Frees all resources held by this Object.
char * chars
The backing null-terminated UTF-8 encoded character array.
String * urlString
The URL String.
A protocol-agnostic abstraction for requesting resources via URLs.
HTTPMethod httpMethod
The HTTP request method.
Dictionary * httpHeaders
The HTTP request headers.
Data * httpBody
The HTTP request body, sent as POST or PUT data.
A protocol-agnostic abstraction for URLSessionTask responses.
int httpStatusCode
The HTTP response status code.
Configuration bundle for URLSession.
long connectTimeout
The timeout interval for establishing a connection, in seconds. 0 means no limit.
Dictionary * httpHeaders
The HTTP headers added to every HTTP URLRequest.
bool longPolling
If true, disables stall detection (LOW_SPEED_LIMIT / LOW_SPEED_TIME). Use for requests that legitimat...
long timeout
The timeout for the entire transfer, in seconds. 0 means no limit.
A management context for loading resources via URLs.
URLSessionConfiguration * configuration
The session configuration.
URL session tasks are handles to pending URL operations.
struct URLResponse * response
The response.
ident requestHeaders
HTTP headers, in libcurl list structure.
ident handle
The backing libcurl handle.
void resume(URLSessionTask *)
Starts or resumes this task.
char * error
The error buffer.
struct URLRequest * request
The request.
struct URLSession * session
The session.
URLSessionTaskState state
The state.
URLSessionTaskCompletion completion
The completion function.