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);
220 curl_easy_setopt(self->locals.
handle, CURLOPT_HEADERDATA, self);
222 curl_easy_setopt(self->locals.
handle, CURLOPT_XFERINFOFUNCTION,
progress);
223 curl_easy_setopt(self->locals.
handle, CURLOPT_XFERINFODATA, self);
227 curl_easy_setopt(self->locals.
handle, CURLOPT_POSTFIELDS, body->
bytes);
228 curl_easy_setopt(self->locals.
handle, CURLOPT_POSTFIELDSIZE, body->
length);
231 struct curl_slist *httpHeaders = NULL;
244 curl_easy_setopt(self->locals.
handle, CURLOPT_HTTPHEADER, httpHeaders);
250 curl_easy_setopt(self->locals.
handle, CURLOPT_POST,
true);
253 curl_easy_setopt(self->locals.
handle, CURLOPT_PUT,
true);
256 curl_easy_setopt(self->locals.
handle, CURLOPT_CUSTOMREQUEST,
"DELETE");
259 curl_easy_setopt(self->locals.
handle, CURLOPT_NOBODY,
true);
274 switch (self->
state) {
290 if (self->locals.
handle) {
291 curl_easy_cleanup(self->locals.
handle);
292 self->locals.
handle = NULL;
301#pragma mark - Class lifecycle
330 .name =
"URLSessionTask",
334 .interfaceSize =
sizeof(URLSessionTaskInterface),
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,...)
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.
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 void requestHeaders_enumerator(const Dictionary *dictionary, ident obj, ident key, ident data)
A helper to populate the request headers list for CURL.
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...
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.
URL session tasks are handles to pending URL operations.
@ URLSESSIONTASK_RESUMING
@ URLSESSIONTASK_SUSPENDING
@ URLSESSIONTASK_SUSPENDED
@ URLSESSIONTASK_COMPLETED
@ URLSESSIONTASK_CANCELING
void(* URLSessionTaskCompletion)(URLSessionTask *task, _Bool success)
A function pointer for URLSessionTask completion.
#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.
Condition * init(Condition *self)
Initializes this Condition.
size_t length
The length of bytes.
uint8_t * bytes
The bytes.
Immutable key-value stores.
void enumerateObjectsAndKeys(const Dictionary *self, DictionaryEnumerator enumerator, ident data)
Enumerate the pairs of this Dictionary with the given function.
void error(const Log *self, const char *fmt,...)
Log an error message.
MutableData * data(void)
Returns a new MutableData.
MutableDictionary * dictionary(void)
Returns a new MutableDictionary.
Object is the root Class of The Objectively Class hierarchy.
Class * _Object(void)
The Object archetype.
Object * copy(const Object *self)
Creates a shallow copy of this Object.
void dealloc(Object *self)
Frees all resources held by this Object.
void cancel(Operation *self)
Cancels this Operation, allowing it to complete immediately.
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.
void setValueForHTTPHeaderField(URLREquest *self, const char *value, const char *field)
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.
Dictionary * httpHeaders
The HTTP headers added to every HTTP URLRequest.
A management context for loading resources via URLs.
URLSessionConfiguration * configuration
The session configuration.
URL session tasks are handles to pending URL operations.
URLSessionTask * initWithRequestInSession(URLSessionTask *, struct URLRequest *, struct URLSession *, URLSessionTaskCompletion)
Initializes this task with the given URLRequest.
struct URLResponse * response
The response.
ident requestHeaders
HTTP headers, in libcurl list structure.
ident handle
The backing libcurl handle.
void setup(URLSessionTask *)
Sets up this task.
void resume(URLSessionTask *)
Starts or resumes this task.
void suspend(URLSessionTask *)
Suspends this task.
void execute(URLSessionTask *)
Executes this task synchronously, on the calling thread.
char * error
The error buffer.
Class * _URLSessionTask(void)
The URLSessionTask archetype.
struct URLRequest * request
The request.
void teardown(URLSessionTask *)
Tears down this task.
struct URLSession * session
The session.
URLSessionTaskState state
The state.
URLSessionTaskCompletion completion
The completion function.