Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/pkg/curlinterface/src/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 20.5.2025 mit Größe 6 kB image not shown  

Quelle  curl.c   Sprache: C

 
//
// curlInterface: Simple Web Access
//

#include "gap_all.h" // GAP headers

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

#undef PACKAGE
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_URL
#undef PACKAGE_VERSION

#include "pkgconfig.h"    // our own autoconf results

#if !defined(GAP_KERNEL_MAJOR_VERSION) || GAP_KERNEL_MAJOR_VERSION < 7
#define CONST_CSTR_STRING(x) CSTR_STRING(x)
#endif

size_t write_string(char * ptr, size_t size, size_t nmemb, void * outstream)
{
    Obj buf = (Obj)outstream;
    UInt len = GET_LEN_STRING(buf);
    UInt newlen = len + size * nmemb;
    GROW_STRING(buf, newlen);
    SET_LEN_STRING(buf, newlen);
    memcpy(CSTR_STRING(buf) + len, ptr, size * nmemb);
    return size * nmemb;
}

Obj FuncCURL_REQUEST(Obj self, Obj input_list)
{
    CURL *     curl;
    CURLcode   res;
    Obj        in_string = MakeString("");
    Obj        errorstring = 0;
    curl_off_t len;
    char       urlbuf[4096] = { 0 };
    char *     typebuf = NULL;

    const int n = LEN_PLIST(input_list);
    GAP_ASSERT(n == 8);    // paranoia check, GAP enforces this

    Obj URL = ELM_PLIST(input_list, 1);
    if (!IS_STRING_REP(URL)) {
        URL = CopyToStringRep(URL);
    }

    Obj type = ELM_PLIST(input_list, 2);
    if (!IS_STRING_REP(type)) {
        type = CopyToStringRep(type);
    }

    Obj out_string = ELM_PLIST(input_list, 3);
    if (!IS_STRING_REP(out_string)) {
        out_string = CopyToStringRep(out_string);
    }

    // copy URL into a buffer, as the GAP string could be moved
    // by a garbage collection triggered by write_string
    len = GET_LEN_STRING(URL) + 1;
    if (len > sizeof(urlbuf)) {
        ErrorMayQuit("CURL_REQUEST: must be less than %d chars",
                     sizeof(urlbuf), 0L);
    }
    memcpy(urlbuf, CONST_CSTR_STRING(URL), len);

    res = curl_global_init(CURL_GLOBAL_DEFAULT);
    if (res != 0) {
        ErrorMayQuit("CURL_REQUEST: failed to initialize libcurl (error %d)",
                     (Int)res, 0L);
    }

    curl = curl_easy_init();
    if (curl) {
        char errbuf[CURL_ERROR_SIZE];
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);

        curl_easy_setopt(curl, CURLOPT_URL, urlbuf);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_string);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, in_string);
        curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1L);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "curlInterface/GAP package");

        Obj verifyCert = ELM_PLIST(input_list, 4);
        Obj verbose = ELM_PLIST(input_list, 5);
        Obj followRedirect = ELM_PLIST(input_list, 6);
        Obj failOnError = ELM_PLIST(input_list, 7);
        Int maxTime = Int_ObjInt(ELM_PLIST(input_list, 8));

        if (verbose == True)
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        if (followRedirect == True)
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

        if (failOnError == True)
            curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);

        if (maxTime != 0)
            curl_easy_setopt(curl, CURLOPT_TIMEOUT, maxTime);

        if (strcmp(CONST_CSTR_STRING(type), "GET") == 0) {
            // simply download from the URL
            curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        }
        else if (strcmp(CONST_CSTR_STRING(type), "POST") == 0) {
            // send a string to the URL
            len = GET_LEN_STRING(out_string); // no null character
            curl_easy_setopt(curl, CURLOPT_POST, 1L);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, len);
            curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS,
                             CONST_CSTR_STRING(out_string));
            // using COPYPOSTFIELDS copies the data right now
        }
        else if (strcmp(CONST_CSTR_STRING(type), "HEAD") == 0) {
            // only get headers, without body
            curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
        }
        else {
            // custom request e.g. DELETE
            len = GET_LEN_STRING(type) + 1; // include null character
            typebuf = (char *) malloc(len);
            memcpy(typebuf, CONST_CSTR_STRING(type), len);
            curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, typebuf);
        }

        if (verifyCert == True) {
            //
            // If you want to connect to a site who isn't using a certificate
            // that is signed by one of the certs in the CA bundle you have,
            // you can skip the verification of the server's certificate. This
            // makes the connection A LOT LESS SECURE.
            //
            // If you have a CA cert for the server stored someplace else than
            // in the default bundle, then the CURLOPT_CAPATH option might
            // come handy for you.
            //
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);

            //
            // If the site you're connecting to uses a different host name
            // that what they have mentioned in their server certificate's
            // commonName (or subjectAltName) fields, libcurl will refuse to
            // connect. You can skip this check, but this will make the
            // connection less secure.
            //
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
        }

        // Perform the request, res will get the return code
        res = curl_easy_perform(curl);

        // Check for errors
        if (res != CURLE_OK) {
            if (*errbuf)
                errorstring = MakeImmString(errbuf);
            else
                errorstring = MakeImmString(curl_easy_strerror(res));
        }

        // always cleanup
        curl_easy_cleanup(curl);
    }

    curl_global_cleanup();
    free(typebuf);

    Obj prec = NEW_PREC(2);
    SET_LEN_PREC(prec, 2);
    SET_RNAM_PREC(prec, 1, RNamName("success"));
    if (errorstring) {
        SET_ELM_PREC(prec, 1, False);
        SET_RNAM_PREC(prec, 2, RNamName("error"));
        SET_ELM_PREC(prec, 2, errorstring);
    }
    else {
        SET_ELM_PREC(prec, 1, True);
        SET_RNAM_PREC(prec, 2, RNamName("result"));
        SET_ELM_PREC(prec, 2, in_string);
    }
    CHANGED_BAG(prec);
    return prec;
}

Obj FuncCURL_VERSION(Obj self)
{
    return MakeImmString(curl_version());
}

// Table of functions to export
static StructGVarFunc GVarFuncs[] = {
    GVAR_FUNC(CURL_REQUEST, 8,
              "url, type, out_string, verifyCert, verbose, followRedirect, failOnError, maxTime"),
    GVAR_FUNC(CURL_VERSION, 0, ""),
    { 0 }
};

// initialise kernel data structures
static Int InitKernel(StructInitInfo * module)
{
    InitHdlrFuncsFromTable(GVarFuncs);

    return 0;
}

// initialise library data structures
static Int InitLibrary(StructInitInfo * module)
{
    InitGVarFuncsFromTable(GVarFuncs);

    return 0;
}

// table of init functions
static StructInitInfo module = {
    .type = MODULE_DYNAMIC,
    .name = "curl",
    .initKernel = InitKernel,
    .initLibrary = InitLibrary,
};

StructInitInfo * Init__Dynamic(void)
{
    return &module;
}

88%


¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.