samples: Add a curl + NSSL example.

This commit is contained in:
James Benton 2018-06-18 12:17:30 +01:00
parent 8c1943cdd7
commit 7ca4ebda05
3 changed files with 232 additions and 0 deletions

View File

@ -3,6 +3,7 @@ set(CMAKE_TOOLCHAIN_FILE $ENV{WUT_ROOT}/share/wut.toolchain.cmake)
project(samples)
include("${WUT_ROOT}/share/wut.cmake" REQUIRED)
add_subdirectory(curl)
add_subdirectory(custom_default_heap)
add_subdirectory(gx2_triangle)
add_subdirectory(helloworld)

View File

@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.2)
project(curl C)
include("${WUT_ROOT}/share/wut.cmake" REQUIRED)
add_executable(curl
main.c)
target_link_libraries(curl
whb
proc_ui
sysapp
nsysnet
nlibcurl)
wut_enable_newlib(curl)
wut_create_rpx(curl.rpx curl)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/curl.rpx"
DESTINATION "${CMAKE_INSTALL_PREFIX}")

212
samples/curl/main.c Normal file
View File

@ -0,0 +1,212 @@
#include <coreinit/thread.h>
#include <coreinit/time.h>
#include <curl/curl.h>
#include <nsysnet/socket.h>
#include <nsysnet/nssl.h>
#include <whb/proc.h>
#include <whb/log.h>
#include <whb/log_console.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MemoryStruct
{
char *memory;
size_t size;
};
static size_t
writeMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
WHBLogPrintf("WriteMemoryCallback: Not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
static int
progressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
WHBLogPrintf("ProcessCallback %f / %f", dlnow, dltotal);
WHBLogConsoleDraw();
return 0;
}
static int
debugCallback(CURL *handle,
curl_infotype type,
char *data,
size_t size,
void *userp)
{
switch(type) {
case CURLINFO_TEXT:
WHBLogPrintf("== Info: %s", data);
break;
case CURLINFO_HEADER_OUT:
WHBLogPrintf("=> Send header");
break;
case CURLINFO_DATA_OUT:
WHBLogPrintf("=> Send data");
break;
case CURLINFO_SSL_DATA_OUT:
WHBLogPrintf("=> Send SSL data");
break;
case CURLINFO_HEADER_IN:
WHBLogPrintf("<= Recv header");
break;
case CURLINFO_DATA_IN:
WHBLogPrintf("<= Recv data");
break;
case CURLINFO_SSL_DATA_IN:
WHBLogPrintf("<= Recv SSL data");
break;
}
return 0;
}
int
main(int argc, char **argv)
{
NSSLContextHandle context = -1;
CURL *curl = NULL;
int ret = 0;
int resp = 404;
struct MemoryStruct chunk;
chunk.memory = malloc(1);
chunk.size = 0;
WHBProcInit();
WHBLogConsoleInit();
WHBLogPrintf("Initialising libraries...");
socket_lib_init();
ret = NSSLInit();
if (ret < 0) {
WHBLogPrintf("NSSLInit failed with error %d.", ret);
goto exit;
}
curl = curl_easy_init();
if (!curl) {
WHBLogPrintf("curl_easy_init failed.");
goto exit;
}
context = NSSLCreateContext(0);
if (context < 0) {
WHBLogPrintf("NSSLCreateContext failed with error %d.", context);
goto exit;
}
for(int i = NSSL_SERVER_CERT_GROUP_0_FIRST; i <= NSSL_SERVER_CERT_GROUP_0_LAST; ++i) {
ret = NSSLAddServerPKI(context, i);
if (ret < 0) {
WHBLogPrintf("NSSLAddServerPKI(context, %d) failed with error %d.", i, ret);
}
}
for(int i = NSSL_SERVER_CERT_GROUP_1_FIRST; i <= NSSL_SERVER_CERT_GROUP_1_LAST; ++i) {
NSSLAddServerPKI(context, i);
if (ret < 0) {
WHBLogPrintf("NSSLAddServerPKI(context, %d) failed with error %d.", i, ret);
}
}
ret = curl_easy_setopt(curl, CURLOPT_NSSL_CONTEXT, context);
if (ret < 0) {
WHBLogPrintf("curl_easy_setopt(CURLOPT_NSSL_CONTEXT) failed with error %d.", ret);
}
curl_easy_setopt(curl, CURLOPT_URL, "https://twitter.com/realDonaldTrump");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debugCallback);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, NULL);
WHBLogConsoleDraw();
ret = curl_easy_perform(curl);
if (ret) {
WHBLogPrintf("curl_easy_perform returned %d", ret);
goto exit;
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp);
WHBLogPrintf("Response code: %d", resp);
WHBLogPrintf("chunk.size = %u", chunk.size);
// Try parse the tweet
if (chunk.size) {
// <div class="js-tweet-text-container
char *start, *end;
start = strstr(chunk.memory, "js-tweet-text-container");
if (start) {
// >
start = strchr(start, '>') + 1;
}
if (start) {
// <p ... >
start = strchr(start, '>') + 1;
}
if (start) {
end = strstr(start, "</p>");
}
if (!start || !end) {
WHBLogPrintf("Could not find tweet text");
} else {
char *pos = start;
*end = 0;
WHBLogPrintf("I am sorry you have to read this:");
// Break into lines
while (pos < end) {
char sep = *(pos + 50);
*(pos + 50) = 0;
WHBLogPrintf(pos);
*(pos + 50) = sep;
pos += 50;
}
}
}
exit:
while(WHBProcIsRunning()) {
WHBLogConsoleDraw();
OSSleepTicks(OSMillisecondsToTicks(100));
}
WHBLogPrintf("Cleaning up libraries...");
free(chunk.memory);
curl_easy_cleanup(curl);
NSSLFinish();
socket_lib_finish();
WHBLogPrintf("Exiting... good bye.");
WHBLogConsoleDraw();
OSSleepTicks(OSMillisecondsToTicks(1000));
WHBLogConsoleFree();
WHBProcShutdown();
return 0;
}