summaryrefslogtreecommitdiff
path: root/registration.c
blob: d63f08727a5daad716338d35e89e37e476338e7d (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
#include <stdlib.h>
#include <string.h>
#include <interchange.h>

#ifdef DEBUG
#ifdef __ANDROID__
#include <android/log.h>
#else
#include <stdio.h>
#endif
#endif

#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>

#else
#include <threads.h>
#include <curl/curl.h>

struct container {
	CURL *curl;
	void (*handler)(interchange_response *);
	interchange_response *response;
};

static size_t append(char *data, size_t size, size_t nmemb, interchange_response *response)
{
	size_t realsize = size * nmemb;
	response->data = realloc(response->data, response->numBytes + realsize + 1);
	memcpy(&(response->data[response->numBytes]), data, realsize);
	response->numBytes += realsize;
	response->data[response->numBytes] = '\0';
	return realsize;
}

static int async(void *arg)
{
	int ret = thrd_success;
	struct container *container = (struct container *)arg;
	CURLcode res = curl_easy_perform(container->curl);
	if (res == CURLE_OK)
		container->handler(container->response);
	else {
		ret = thrd_error;
#ifdef DEBUG
		const char *error = curl_easy_strerror(res);
#ifdef __ANDROID__
		__android_log_print(ANDROID_LOG_ERROR, "namatoko.so", "%s", error);
#else
		fprintf(stderr, "%s\n", error);
#endif
#endif
	}
	curl_easy_cleanup(container->curl);
	free(container);
	curl_global_cleanup();
	return ret;
}
#endif

void sign_up(const char *brand, const char *certificate, void (*handler)(interchange_response *))
{
	char *data = malloc(strlen(brand) + 1);
	strcpy(data, brand);
#ifdef __EMSCRIPTEN__
	(void)certificate;
	emscripten_fetch_attr_t attr;
	emscripten_fetch_attr_init(&attr);
	attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
	strcpy(attr.requestMethod, "POST");
	attr.userData = data;
	attr.requestData = data;
	attr.requestDataSize = strlen(data);
	attr.onsuccess = handler;
	attr.onerror = interchange_free_response;
	emscripten_fetch(&attr, "registration");
#else
	curl_global_init(CURL_GLOBAL_SSL);
	CURL *curl = curl_easy_init();
	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
	if (certificate)
		curl_easy_setopt(curl, CURLOPT_CAINFO, certificate);
#ifdef DEBUG
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#endif
	curl_easy_setopt(curl, CURLOPT_URL, SECURE_SERVER"/registration");
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, append);
	interchange_response *response = malloc(sizeof(interchange_response));
	response->data = malloc(1);
	response->numBytes = 0;
	response->userData = data;
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
	struct container *container = malloc(sizeof(struct container));
	container->curl = curl;
	container->handler = handler;
	container->response = response;
	thrd_t thread;
	thrd_create(&thread, async, container);
#endif
}