/*################################################################################### # # Embperl - Copyright (c) 1997-2005 Gerald Richter / ECOS # # You may distribute under the terms of either the GNU General Public # License or the Artistic License, as specified in the Perl README file. # For use with Apache httpd and mod_perl, see also Apache copyright. # # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. # # $Id$ # ###################################################################################*/ #include "../ep.h" #include "../epmacro.h" /* ------------------------------------------------------------------------ */ /* */ /*! Provider that reads input from file */ /* */ typedef struct tProviderCurl { tProvider Provider ; const char * sURL ; /**< URL to fetch */ } tProviderCurl ; /* ------------------------------------------------------------------------- * * sproxyReq * * do http/https etc. request * * ----------------------------------------------------------------------- */ static int sproxyReqAuthHdr (/*in*/ const char * sURL, /*in*/ const char * sUsername, /*in*/ const char * sPassword, /*in*/ struct curl_slist * pHdr, /*in*/ void * pDataFunc, /*in*/ void * pBodyData, /*in*/ void * pHdrData) { CURL *curl; CURLcode res; int nStatus ; char sError [CURL_ERROR_SIZE+1] ; char buf [MAXUSERIDLEN * 2 + 2] ; if (sproxyOptVerbose) printf ("--> Request URL: %s\n", sURL) ; if (!(curl = curl_easy_init())) { fprintf (stderr, "Cannot init curl\n") ; return -1 ; } curl_easy_setopt(curl, CURLOPT_URL, sURL); if (sUsername && sPassword) { int l ; buf[MAXUSERIDLEN] = '\0' ; strncpy (buf, sUsername, MAXUSERIDLEN) ; l = strlen (buf) ; strcat (buf, ":") ; strncpy (buf + l + 1, sPassword, MAXUSERIDLEN) ; buf[MAXUSERIDLEN+ l + 1] = '\0' ; curl_easy_setopt(curl, CURLOPT_USERPWD, buf); } curl_easy_setopt(curl, CURLOPT_URL, sURL); if (pHdr) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHdr); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sError); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); if (pDataFunc) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, pDataFunc); if (!pBodyData) curl_easy_setopt(curl, CURLOPT_NOBODY, 1); else curl_easy_setopt(curl, CURLOPT_FILE, pBodyData); if (pHdrData) { curl_easy_setopt(curl, CURLOPT_WRITEHEADER, pHdrData); } } /*curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);*/ if ((res = curl_easy_perform(curl))) { fprintf (stderr, "Curl-Error (#%d): %s\n", res, sError) ; /* return res ; */ } else { res = curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &nStatus); } curl_easy_cleanup(curl); return res != 0?res:(nStatus == 200?0:nStatus) ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderCurl_New */ /* */ /*! * \_en * Creates a new file provider and fills it with data from the hash pParam * The resulting provider is put into the cache structure * * @param r Embperl request record * @param pItem CacheItem which holds the output of the provider * @param pProviderClass Provider class record * @param pParam Parameter Hash * filename name of file * @return error code * \endif * * \_de * Erzeugt einen neue Provider der daten aus Dateien ließt. Der ein Zeiger * auf den resultierenden Provider wird in die Cachestrutr eingefügt * * @param r Embperl request record * @param pItem CacheItem welches die Ausgabe des Providers * speichert * @param pProviderClass Provider class record * @param pParam Parameter Hash * filename Dateiname * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderCurl_New (/*in*/ req * r, /*in*/ tCacheItem * pItem, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pParam) { int rc ; tProviderCurl * pNew ; if ((rc = Provider_New (r, sizeof(tProviderCurl), pItem, pProviderClass, pParam)) != ok) return rc ; pNew = (tProviderCurl *)pItem -> pProvider ; pNew -> sFilename = GetHashValueStrDup (pParam, "filename", NULL) ; pItem -> sExpiresFilename = pNew -> sFilename ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderCurl_AppendKey */ /* */ /*! * \_en * Append it's key to the keystring. If it depends on anything it must * call Cache_AppendKey for any dependency. * The file provider appends the filename * * @param r Embperl request record * @param pProviderClass Provider class record * @param pParam Parameter Hash * filename name of file * @param pKey Key to which string should be appended * @return error code * \endif * * \_de * Hängt ein eigenen Schlüssel an den Schlüsselstring an. Wenn irgednwelche * Abhänigkeiten bestehen, muß Cache_AppendKey für alle Abhänigkeiten aufgerufen * werden. * Der File Provider hängt den Dateinamen an. * * @param r Embperl request record * @param pProviderClass Provider class record * @param pParam Parameter Hash * filename Dateiname * @param pKey Schlüssel zu welchem hinzugefügt wird * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderCurl_AppendKey (/*in*/ req * r, /*in*/ tProviderClass * pProviderClass, /*in*/ HV * pParam, /*i/o*/ SV * pKey) { const char * sFilename = GetHashValueStr (pParam, "filename", "") ; const char * sDir = "" ; /* is it a relative filename? -> append path */ if (!(sFilename[0] == '/' #ifdef WIN32 || sFilename[0] == '\\' || (isalpha(sFilename[0]) && sFilename[1] == ':' && (sFilename[2] == '\\' || sFilename[2] == '/')) #endif )) { sDir = r -> sCWD ; } sv_catpvf (pKey, ":%s%s%s", sDir, *sDir?"/":"", sFilename) ; return ok ; } /* ------------------------------------------------------------------------ */ /* */ /* ProviderCurl_GetContentSV */ /* */ /*! * \_en * Get the whole content from the provider. * The file provider reads the whole file into memory * * @param r Embperl request record * @param pProvider The provider record * @param pData Returns the content * @return error code * \endif * * \_de * Holt den gesamt Inhalt vom Provider. * Der File Provider ließt die komplette Datei. * * @param r Embperl request record * @param pProvider The provider record * @param pData Liefert den Inhalt * @return Fehlercode * \endif * * ------------------------------------------------------------------------ */ static int ProviderCurl_GetContentSV (/*in*/ req * r, /*in*/ tProvider * pProvider, /*in*/ SV * * pData) { size_t nSize = pProvider -> pCache -> FileStat.st_size ; int rc = ReadHTML(r, (char *)((tProviderCurl *)pProvider) -> sFilename, &nSize, pData) ; if (rc == ok) SvREFCNT_inc (*pData) ; return rc ; } /* ------------------------------------------------------------------------ */ tProviderClass ProviderClassCurl = { "text/*", &ProviderCurl_New, &ProviderCurl_AppendKey, &ProviderCurl_GetContentSV, NULL, NULL, NULL, } ;