C_OPTS=-Wall -Wextra -pedantic\r
C_OPTS+=-I src/\r
C_OPTS+=-I ext/olm/include/\r
+C_OPTS+=-I ext/mjson/src\r
C_OPTS+=src/matrix.c\r
+C_OPTS+=src/matrix_http_curl.c\r
+C_OPTS+=ext/mjson/src/mjson.c\r
+C_OPTS+=-l curl\r
\r
-out/examples/%: examples/%.c\r
+out/examples/%: examples/%.c src/*\r
$(CC) -o out/examples/$* examples/$*.c $(C_OPTS)\r
\r
\r
#include <stdio.h>\r
#include <matrix.h>\r
+#include <curl/curl.h>\r
\r
-#define SERVER FixedBuf("matrix.org")\r
-#define USERNAME FixedBuf("@pscho:matrix.org")\r
-#define PASSWORD FixedBuf("abcde")\r
+#define SERVER "https://matrix.org"\r
+#define USERNAME "pscho"\r
+#define PASSWORD "Wc23EbmB9G3faMq"\r
+#define DISPLAYNAME "MatrixClient"\r
\r
\r
int\r
-main(\r
- int argc,\r
- char **argv)\r
+main()\r
{\r
MatrixClient client;\r
- MatrixClientInit(&client, SERVER);\r
+ MatrixClientInit(&client, SERVER, strlen(SERVER));\r
+ \r
+ curl_global_init(CURL_GLOBAL_DEFAULT);\r
+ client.httpUserData = (void *)curl_easy_init();\r
\r
MatrixClientLoginPassword(&client,\r
- USERNAME,\r
- PASSWORD);\r
+ USERNAME, strlen(USERNAME),\r
+ PASSWORD, strlen(PASSWORD),\r
+ DISPLAYNAME, strlen(DISPLAYNAME));\r
\r
- static char accessTokenCharBuffer[ACCESS_TOKEN_LEN];\r
- FixedBuffer accessTokenBuffer = { accessTokenCharBuffer, ACCESS_TOKEN_LEN, 0 };\r
- MatrixClientGetAccessToken(&client, &accessTokenBuffer);\r
- printf("Access Token: %.*s\n", accessTokenBuffer.len, (char *)accessTokenBuffer.ptr);\r
+ printf("Access Token: %.*s\n", client.accessTokenLen, client.accessTokenBuffer);\r
+ printf("Device ID: %.*s\n", client.deviceIdLen, client.deviceIdBuffer);\r
+ printf("Expires in (ms): %.*s\n", client.expireMsLen, client.expireMsBuffer);\r
+ printf("Refresh Token: %.*s\n", client.refreshTokenLen, client.refreshTokenBuffer);\r
+ \r
+ curl_easy_cleanup((CURL *)client.httpUserData);\r
+ curl_global_cleanup();\r
\r
return 0;\r
}
\ No newline at end of file
#include "matrix.h"\r
\r
+#include <mjson.h>\r
+\r
+\r
+#define LOGIN_REQUEST_SIZE 1024\r
+#define LOGIN_RESPONSE_SIZE 1024\r
+#define LOGIN_URL "/_matrix/client/v3/login"\r
+\r
\r
bool\r
MatrixClientInit(\r
MatrixClient * client,\r
- FixedBuffer server\r
+ char * server, int serverLen\r
) {\r
+ strcpy_s(\r
+ client->server,\r
+ SERVER_SIZE,\r
+ server\r
+ );\r
+ client->serverLen = serverLen;\r
\r
+ return true;\r
}\r
\r
+// https://spec.matrix.org/v1.6/client-server-api/#post_matrixclientv3login\r
bool\r
MatrixClientLoginPassword(\r
MatrixClient * client,\r
- FixedBuffer username,\r
- FixedBuffer password\r
+ char * username, int usernameLen,\r
+ char * password, int passwordLen,\r
+ char * displayName, int displayNameLen\r
) {\r
+ static char requestBuffer[LOGIN_REQUEST_SIZE];\r
\r
-}\r
+ int requestLen =\r
+ mjson_snprintf(requestBuffer, LOGIN_REQUEST_SIZE,\r
+ "{"\r
+ "\"type\": \"m.login.password\","\r
+ "\"identifier\": {"\r
+ "\"type\": \"m.id.user\","\r
+ "\"user\": \"%.*s\""\r
+ "},"\r
+ "\"password\": \"%.*s\","\r
+ "\"initial_device_display_name\": \"%.*s\""\r
+ "}",\r
+ usernameLen, username,\r
+ passwordLen, password,\r
+ displayNameLen, displayName);\r
+ \r
+ static char responseBuffer[LOGIN_RESPONSE_SIZE];\r
+ int responseLen;\r
+ bool result =\r
+ MatrixHttpPost(client,\r
+ LOGIN_URL,\r
+ requestBuffer, requestLen,\r
+ responseBuffer, LOGIN_RESPONSE_SIZE, &responseLen);\r
+ \r
+ if (!result)\r
+ return false;\r
\r
-bool\r
-MatrixClientGetAccessToken(\r
- MatrixClient * client,\r
- FixedBuffer * outBuffer\r
-) {\r
+ client->accessTokenLen =\r
+ mjson_get_string(responseBuffer, responseLen,\r
+ "$.access_token",\r
+ client->accessTokenBuffer, ACCESS_TOKEN_SIZE);\r
+ client->deviceIdLen =\r
+ mjson_get_string(responseBuffer, responseLen,\r
+ "$.device_id",\r
+ client->deviceIdBuffer, DEVICE_ID_SIZE);\r
+ client->expireMsLen =\r
+ mjson_get_string(responseBuffer, responseLen,\r
+ "$.expires_in_ms",\r
+ client->expireMsBuffer, EXPIRE_MS_SIZE);\r
+ client->refreshTokenLen =\r
+ mjson_get_string(responseBuffer, responseLen,\r
+ "$.refresh_token",\r
+ client->refreshTokenBuffer, REFRESH_TOKEN_SIZE);\r
\r
+ return true;\r
}\r
+\r
\r
#include <olm/olm.h>\r
\r
-#include "fixedbuffer.h"\r
\r
\r
+// TODO: fix\r
+#define SERVER_SIZE 20\r
+#define ACCESS_TOKEN_SIZE 40\r
+#define DEVICE_ID_SIZE 20\r
+#define EXPIRE_MS_SIZE 20\r
+#define REFRESH_TOKEN_SIZE 20\r
+#define MAX_URL_LEN 128\r
\r
-#define ACCESS_TOKEN_LEN 20 // TODO: fix\r
\r
typedef struct MatrixClient {\r
- OlmAccount * olmAcc;\r
- char accessToken[ACCESS_TOKEN_LEN];\r
+ void * httpUserData;\r
+ OlmAccount * olmAccount;\r
+ OlmSession * olmSession;\r
+ char server[SERVER_SIZE]; int serverLen;\r
+ char accessTokenBuffer[ACCESS_TOKEN_SIZE]; int accessTokenLen;\r
+ char deviceIdBuffer[DEVICE_ID_SIZE]; int deviceIdLen;\r
+ char expireMsBuffer[EXPIRE_MS_SIZE]; int expireMsLen;\r
+ char refreshTokenBuffer[REFRESH_TOKEN_SIZE]; int refreshTokenLen;\r
} MatrixClient;\r
\r
bool\r
MatrixClientInit(\r
MatrixClient * client,\r
- FixedBuffer server\r
+ char * server, int serverLen\r
);\r
\r
bool\r
MatrixClientLoginPassword(\r
MatrixClient * client,\r
- FixedBuffer username,\r
- FixedBuffer password\r
+ char * username, int usernameLen,\r
+ char * password, int passwordLen,\r
+ char * displayName, int displayNameLen\r
);\r
\r
bool\r
-MatrixClientGetAccessToken(\r
+MatrixHttpPost(\r
MatrixClient * client,\r
- FixedBuffer * outBuffer\r
+ const char * url,\r
+ char * requestBuffer, int requestLen,\r
+ char * outResponseBuffer, int outResponseCap, int * outResponseLen\r
);\r
\r
#endif\r
--- /dev/null
+#include "matrix.h"\r
+\r
+#include <curl/curl.h>\r
+\r
+\r
+\r
+typedef struct {\r
+ char * ptr;\r
+ int cap;\r
+ int len;\r
+} WriteStr;\r
+\r
+// typedef struct {\r
+// Str str;\r
+// size_t pos;\r
+// } ReadStr;\r
+\r
+size_t curlWriteString(char *ptr, size_t size, size_t nmemb, void *userdata) {\r
+ WriteStr *writeStr = (WriteStr *)userdata;\r
+\r
+ int toWrite = (int)size*nmemb;\r
+\r
+ int writable = writeStr->cap - writeStr->len;\r
+ int gonnaWrite = writable < (toWrite) ? writable : (toWrite);\r
+\r
+ for (int i = 0; i < gonnaWrite; i++)\r
+ {\r
+ int offset = writeStr->len;\r
+ writeStr->ptr[i+offset] = ptr[i];\r
+ }\r
+\r
+ writeStr->len += gonnaWrite;\r
+\r
+ return gonnaWrite;\r
+}\r
+// size_t curlReadString(char *dst, size_t size, size_t nmemb, void *userdata) {\r
+// ReadStr *readStr = (ReadStr *)userdata;\r
+\r
+// size_t copyAmount = size*nmemb;\r
+// if (copyAmount > (readStr->str.len - readStr->pos)) {\r
+// copyAmount = (readStr->str.len - readStr->pos);\r
+// }\r
+\r
+// memcpy(dst, readStr->str.str + readStr->pos, copyAmount);\r
+// readStr->pos += copyAmount;\r
+// return copyAmount;\r
+// }\r
+\r
+CURLcode\r
+curlPerform(CURL *curl) {\r
+ // struct curl_slist *list = NULL;\r
+ // list = curl_slist_append(list, uTokenHeaderStr);\r
+ \r
+ // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);\r
+ \r
+ CURLcode result = curl_easy_perform(curl);\r
+\r
+ // curl_slist_free_all(list);\r
+\r
+ return result;\r
+}\r
+\r
+\r
+\r
+bool\r
+MatrixHttpPost(\r
+ MatrixClient * client,\r
+ const char * url,\r
+ char * requestBuffer, int requestLen,\r
+ char * outResponseBuffer, int outResponseCap, int * outResponseLen\r
+) {\r
+ CURL *curl = (CURL *)client->httpUserData;\r
+\r
+ CURLcode res;\r
+ \r
+ if(curl) {\r
+ int urlLen = strlen(url);\r
+\r
+ char fullUrl[MAX_URL_LEN];\r
+ for (int i = 0; i < client->serverLen; i++)\r
+ fullUrl[i] = client->server[i];\r
+ for (int i = 0; i < urlLen; i++)\r
+ fullUrl[client->serverLen+i] = url[i];\r
+ fullUrl[client->serverLen+urlLen] = '\0';\r
+ curl_easy_setopt(curl, CURLOPT_URL, fullUrl);\r
+ \r
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);\r
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBuffer);\r
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestLen);\r
+ \r
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);\r
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);\r
+\r
+ WriteStr writeStr = {\r
+ outResponseBuffer,\r
+ outResponseCap,\r
+ 0\r
+ };\r
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteString);\r
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &writeStr);\r
+\r
+ res = curlPerform(curl);\r
+\r
+ *outResponseLen = writeStr.len;\r
+\r
+ if(res != CURLE_OK)\r
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",\r
+ curl_easy_strerror(res));\r
+ }\r
+ \r
+\r
+ return res == CURLE_OK;\r
+}
\ No newline at end of file