2007-12-30 17:41:49 +01:00
|
|
|
/***************************************************************************
|
|
|
|
|
2010-11-16 02:49:18 +01:00
|
|
|
CCurl.c
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-11-16 02:49:18 +01:00
|
|
|
(c) 2003-2008 Daniel Campos Fernández <dcamposf@gmail.com>
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-11-16 02:49:18 +01:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
any later version.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-11-16 02:49:18 +01:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-11-16 02:49:18 +01:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2011-06-03 02:51:09 +02:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
MA 02110-1301, USA.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
***************************************************************************/
|
2010-05-22 20:02:34 +02:00
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
#define __CCURL_C
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2011-03-30 17:24:36 +02:00
|
|
|
#include <errno.h>
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#include <curl/easy.h>
|
|
|
|
#include <curl/multi.h>
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
#include "gambas.h"
|
|
|
|
#include "CCurl.h"
|
|
|
|
#include "CProxy.h"
|
|
|
|
|
|
|
|
|
|
|
|
DECLARE_EVENT (CURL_FINISHED);
|
|
|
|
DECLARE_EVENT (CURL_ERROR);
|
|
|
|
DECLARE_EVENT (CURL_CONNECT);
|
|
|
|
DECLARE_EVENT (CURL_READ);
|
|
|
|
|
|
|
|
/*****************************************************
|
2010-11-16 02:49:18 +01:00
|
|
|
CURLM : a pointer to use curl_multi interface,
|
|
|
|
allowing asynchrnous work without using threads
|
|
|
|
in this class.
|
|
|
|
******************************************************/
|
2007-12-30 17:41:49 +01:00
|
|
|
CURLM *CCURL_multicurl;
|
2008-09-13 17:35:13 +02:00
|
|
|
int CCURL_pipe[2]={-1,-1};
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
/******************************************************
|
2010-11-16 02:49:18 +01:00
|
|
|
Events from this class
|
|
|
|
******************************************************/
|
2007-12-30 17:41:49 +01:00
|
|
|
GB_STREAM_DESC CurlStream = {
|
|
|
|
open: CCURL_stream_open,
|
|
|
|
close: CCURL_stream_close,
|
|
|
|
read: CCURL_stream_read,
|
|
|
|
write: CCURL_stream_write,
|
|
|
|
seek: CCURL_stream_seek,
|
|
|
|
tell: CCURL_stream_tell,
|
|
|
|
flush: CCURL_stream_flush,
|
|
|
|
eof: CCURL_stream_eof,
|
|
|
|
lof: CCURL_stream_lof,
|
|
|
|
handle: CCURL_stream_handle,
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
// STREAM //
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/* not allowed stream methods */
|
|
|
|
|
|
|
|
int CCURL_stream_handle(GB_STREAM *stream) { return 0;}
|
|
|
|
int CCURL_stream_open(GB_STREAM *stream, const char *path, int mode, void *data){return -1;}
|
2008-01-23 20:56:18 +01:00
|
|
|
int CCURL_stream_seek(GB_STREAM *stream, int64_t pos, int whence){ return -1;}
|
|
|
|
int CCURL_stream_tell(GB_STREAM *stream, int64_t *pos){return -1; }
|
2007-12-30 17:41:49 +01:00
|
|
|
int CCURL_stream_flush(GB_STREAM *stream) { return 0;}
|
|
|
|
int CCURL_stream_close(GB_STREAM *stream) { return -1;}
|
2008-01-23 20:56:18 +01:00
|
|
|
int CCURL_stream_write(GB_STREAM *stream, char *buffer, int len){return -1;}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-01-23 20:56:18 +01:00
|
|
|
int CCURL_stream_lof(GB_STREAM *stream, int64_t *len)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
void *_object = STREAM_TO_OBJECT(stream);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
*len = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
if ((THIS_STATUS !=4 ) && (THIS_STATUS != 0))
|
|
|
|
return -1;
|
|
|
|
|
2010-03-13 19:27:51 +01:00
|
|
|
*len = GB.StringLength(THIS->data);
|
2007-12-30 17:41:49 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2008-10-04 14:31:49 +02:00
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
int CCURL_stream_eof(GB_STREAM *stream)
|
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
void *_object = STREAM_TO_OBJECT(stream);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if ((THIS_STATUS !=4 ) && (THIS_STATUS != 0)) return -1;
|
2010-03-13 19:27:51 +01:00
|
|
|
if (!GB.StringLength(THIS->data)) return -1;
|
2007-12-30 17:41:49 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-01-23 20:56:18 +01:00
|
|
|
int CCURL_stream_read(GB_STREAM *stream, char *buffer, int len)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
void *_object = STREAM_TO_OBJECT(stream);
|
2010-03-13 19:27:51 +01:00
|
|
|
int len_data;
|
|
|
|
char *new_data;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if ((THIS_STATUS !=4 ) && (THIS_STATUS != 0)) return -1;
|
2010-03-13 19:27:51 +01:00
|
|
|
|
|
|
|
len_data = GB.StringLength(THIS->data);
|
|
|
|
|
|
|
|
if (len_data < len) return -1;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-03-13 19:27:51 +01:00
|
|
|
memcpy(buffer, THIS->data, len);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-03-13 19:27:51 +01:00
|
|
|
len_data -= len;
|
|
|
|
|
|
|
|
if (len_data > 0)
|
2010-06-05 01:48:53 +02:00
|
|
|
new_data = GB.NewString(THIS->data + len, len_data);
|
2010-03-13 19:27:51 +01:00
|
|
|
else
|
|
|
|
new_data = NULL;
|
|
|
|
|
|
|
|
GB.FreeString(&THIS->data);
|
|
|
|
THIS->data = new_data;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
####################################################################
|
|
|
|
POSTED FUNCTIONS TO RAISE EVENTS
|
|
|
|
####################################################################
|
|
|
|
********************************************************************/
|
2008-10-04 14:31:49 +02:00
|
|
|
void CCURL_raise_finished(intptr_t lParam)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
|
|
|
void *mythis;
|
|
|
|
mythis=(void*)lParam;
|
|
|
|
GB.Raise(mythis,CURL_FINISHED,0);
|
|
|
|
GB.Unref(&mythis);
|
|
|
|
}
|
2011-03-30 17:24:36 +02:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
void CCURL_raise_error(intptr_t lParam)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
|
|
|
void *mythis;
|
|
|
|
mythis=(void*)lParam;
|
|
|
|
GB.Raise(mythis,CURL_ERROR,0);
|
|
|
|
GB.Unref(&mythis);
|
|
|
|
}
|
2011-03-30 17:24:36 +02:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
void CCURL_raise_connect(intptr_t lParam)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
|
|
|
void *mythis;
|
|
|
|
mythis=(void*)lParam;
|
|
|
|
GB.Raise(mythis,CURL_CONNECT,0);
|
|
|
|
GB.Unref(&mythis);
|
|
|
|
}
|
2011-03-30 17:24:36 +02:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
void CCURL_raise_read(intptr_t lParam)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
|
|
|
void *mythis;
|
|
|
|
mythis=(void*)lParam;
|
|
|
|
GB.Raise(mythis,CURL_READ,0);
|
|
|
|
GB.Unref(&mythis);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-30 17:24:36 +02:00
|
|
|
void CCURL_Manage_ErrCode(void *_object, long ErrCode)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
|
|
|
if (THIS_FILE)
|
|
|
|
{
|
2008-02-14 12:25:00 +01:00
|
|
|
fclose(THIS_FILE);
|
|
|
|
THIS_FILE=NULL;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
2011-03-30 17:24:36 +02:00
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
switch ( ErrCode )
|
|
|
|
{
|
|
|
|
case CURLE_OK:
|
2008-10-04 14:31:49 +02:00
|
|
|
if (THIS->async)
|
2008-09-13 17:35:13 +02:00
|
|
|
{
|
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- [%p] curl_multi_remove_handle(%p)\n", THIS, THIS_CURL);
|
|
|
|
#endif
|
|
|
|
curl_multi_remove_handle(CCURL_multicurl,THIS_CURL);
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
GB.Ref(THIS);
|
|
|
|
GB.Post(CCURL_raise_finished,(long)THIS);
|
2008-09-13 17:35:13 +02:00
|
|
|
CCURL_stop(THIS);
|
2008-10-21 11:28:34 +02:00
|
|
|
THIS_STATUS = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
break;
|
2008-09-13 17:35:13 +02:00
|
|
|
default:
|
2008-10-04 14:31:49 +02:00
|
|
|
if (THIS->async)
|
2008-09-13 17:35:13 +02:00
|
|
|
{
|
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- [%p] curl_multi_remove_handle(%p)\n", THIS, THIS_CURL);
|
|
|
|
#endif
|
|
|
|
curl_multi_remove_handle(CCURL_multicurl,THIS_CURL);
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
GB.Ref(THIS);
|
|
|
|
GB.Post(CCURL_raise_error,(long)THIS);
|
2008-09-13 17:35:13 +02:00
|
|
|
CCURL_stop(THIS);
|
2008-10-21 11:28:34 +02:00
|
|
|
THIS_STATUS = -1*(1000+ErrCode);
|
2007-12-30 17:41:49 +01:00
|
|
|
break;
|
|
|
|
}
|
2011-03-30 17:24:36 +02:00
|
|
|
|
|
|
|
if (THIS->async)
|
|
|
|
GB.Unref(POINTER(&_object));
|
2008-10-04 14:31:49 +02:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
void CCURL_init_stream(void *_object)
|
|
|
|
{
|
|
|
|
THIS->stream.desc = &CurlStream;
|
|
|
|
THIS->stream.tag = THIS;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************
|
2010-11-16 02:49:18 +01:00
|
|
|
This CallBack is called each event loop by Gambas to test
|
|
|
|
the status of curl descriptors
|
|
|
|
***************************************************************/
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
static void stop_post()
|
|
|
|
{
|
|
|
|
if (CCURL_pipe[0] < 0) return;
|
|
|
|
|
2011-03-30 18:21:18 +02:00
|
|
|
GB.Watch (CCURL_pipe[0], GB_WATCH_NONE, NULL, 0);
|
2007-12-30 17:41:49 +01:00
|
|
|
close(CCURL_pipe[0]);
|
|
|
|
close(CCURL_pipe[1]);
|
|
|
|
CCURL_pipe[0]=-1;
|
|
|
|
}
|
2010-11-16 02:49:18 +01:00
|
|
|
|
2011-03-30 18:21:18 +02:00
|
|
|
static void CCURL_post_curl(intptr_t data)
|
|
|
|
{
|
|
|
|
CURLMsg *Msg;
|
|
|
|
int nread;
|
|
|
|
int post=1;
|
|
|
|
void *_object;
|
|
|
|
char *tmp;
|
|
|
|
struct timespec mywait;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
mywait.tv_sec=0;
|
|
|
|
mywait.tv_nsec=1000000;
|
|
|
|
nanosleep(&mywait,NULL);
|
|
|
|
}
|
|
|
|
while(CURLM_CALL_MULTI_PERFORM == curl_multi_perform(CCURL_multicurl,&nread));
|
|
|
|
|
|
|
|
if (!nread) post=0;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Msg=curl_multi_info_read(CCURL_multicurl,&nread);
|
|
|
|
if (!Msg) nread=0;
|
|
|
|
if (Msg)
|
|
|
|
{
|
|
|
|
curl_easy_getinfo(Msg->easy_handle,CURLINFO_PRIVATE,&tmp);
|
|
|
|
_object=(void*)tmp;
|
|
|
|
CCURL_Manage_ErrCode(THIS,Msg->data.result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (nread);
|
|
|
|
|
|
|
|
if (!post)
|
|
|
|
stop_post();
|
|
|
|
}
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
void CCURL_stop(void *_object)
|
|
|
|
{
|
|
|
|
if (THIS_FILE)
|
|
|
|
{
|
2008-02-14 12:25:00 +01:00
|
|
|
fclose(THIS_FILE);
|
|
|
|
THIS_FILE=NULL;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (THIS_CURL)
|
|
|
|
{
|
2008-09-13 17:35:13 +02:00
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- [%p] curl_multi_remove_handle(%p)\n", THIS, THIS_CURL);
|
|
|
|
#endif
|
2008-02-14 12:25:00 +01:00
|
|
|
curl_multi_remove_handle(CCURL_multicurl,THIS_CURL);
|
2008-09-13 17:35:13 +02:00
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- [%p] curl_easycleanup(%p)\n", THIS, THIS_CURL);
|
|
|
|
#endif
|
2008-02-14 12:25:00 +01:00
|
|
|
curl_easy_cleanup(THIS_CURL);
|
|
|
|
THIS_CURL=NULL;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2008-10-21 11:28:34 +02:00
|
|
|
THIS_STATUS = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2011-03-30 18:21:18 +02:00
|
|
|
static void CCURL_init_post(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
|
|
|
if (CCURL_pipe[0]!=-1) return;
|
|
|
|
|
2011-03-30 17:24:36 +02:00
|
|
|
if (pipe(CCURL_pipe))
|
|
|
|
{
|
|
|
|
fprintf(stderr, "gb.net.curl: warning: unable to create the client watching pipe: %s\n", strerror(errno));
|
|
|
|
return;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-03-30 17:24:36 +02:00
|
|
|
GB.Watch (CCURL_pipe[0], GB_WATCH_READ, CCURL_post_curl, 0);
|
2011-03-30 18:15:58 +02:00
|
|
|
if (write(CCURL_pipe[1], "1", sizeof(char)) != 1)
|
2011-03-30 17:24:36 +02:00
|
|
|
fprintf(stderr, "gb.net.curl: warning: unable to write to the client watching pipe: %s\n", strerror(errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CCURL_start_post(void *_object)
|
|
|
|
{
|
|
|
|
CCURL_init_post();
|
|
|
|
curl_multi_add_handle(CCURL_multicurl, THIS_CURL);
|
|
|
|
GB.Ref(THIS);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************
|
2010-11-16 02:49:18 +01:00
|
|
|
FTP User ( User:Password format )
|
|
|
|
*********************************************/
|
2007-12-30 17:41:49 +01:00
|
|
|
BEGIN_PROPERTY ( CCURL_sUser )
|
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
|
|
|
{
|
|
|
|
GB.ReturnString(THIS->user.user);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (THIS_STATUS > 0)
|
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
GB.Error ("User property is read-only while working");
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
2010-11-16 02:49:18 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
if ( THIS->user.user ) GB.FreeString ( &(THIS->user.user) );
|
|
|
|
GB.StoreString(PROP(GB_STRING), &(THIS->user.user) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
BEGIN_PROPERTY( CCURL_Async )
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
GB.ReturnBoolean(THIS->async);
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (THIS_STATUS > 0)
|
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
GB.Error ("Async property is read-only while working");
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
2010-11-16 02:49:18 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
THIS->async = VPROP(GB_BOOLEAN);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
BEGIN_PROPERTY( CCURL_TimeOut )
|
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
|
|
|
{
|
|
|
|
GB.ReturnInteger(THIS->TimeOut);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (THIS_STATUS > 0)
|
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
GB.Error ("Timeout property is read-only while working");
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
2010-11-16 02:49:18 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if (VPROP(GB_INTEGER)<0)
|
|
|
|
THIS->TimeOut=0;
|
|
|
|
else
|
|
|
|
THIS->TimeOut=VPROP(GB_INTEGER);
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
BEGIN_PROPERTY ( CCURL_Password )
|
|
|
|
|
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
|
|
|
{
|
|
|
|
GB.ReturnString(THIS->user.pwd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (THIS_STATUS > 0)
|
|
|
|
{
|
2008-10-04 14:31:49 +02:00
|
|
|
GB.Error ("User property is read-only while working");
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
2010-11-16 02:49:18 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
if ( THIS->user.pwd ) GB.FreeString ( &(THIS->user.pwd) );
|
|
|
|
GB.StoreString(PROP(GB_STRING), &(THIS->user.pwd) );
|
|
|
|
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
/*********************************************
|
2010-11-16 02:49:18 +01:00
|
|
|
Status : inactive, working or Error code
|
|
|
|
*********************************************/
|
2011-09-04 15:39:33 +02:00
|
|
|
BEGIN_PROPERTY(CCURL_Status)
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
GB.ReturnInteger(THIS_STATUS);
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
2011-09-04 15:39:33 +02:00
|
|
|
BEGIN_PROPERTY(Curl_ErrorText)
|
|
|
|
|
|
|
|
if (THIS_STATUS >= 0)
|
|
|
|
GB.ReturnNull();
|
|
|
|
else
|
|
|
|
GB.ReturnConstZeroString(curl_easy_strerror((-THIS_STATUS) - 1000));
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
/*****************************************************************
|
2010-11-16 02:49:18 +01:00
|
|
|
URL to work with
|
|
|
|
*****************************************************************/
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
BEGIN_PROPERTY(CCURL_URL)
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
char *url, *tmp;
|
|
|
|
char *protocol;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
|
|
|
{
|
2011-06-02 18:09:04 +02:00
|
|
|
GB.ReturnString(THIS_URL);
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (THIS_STATUS > 0)
|
|
|
|
{
|
2011-06-02 18:09:04 +02:00
|
|
|
GB.Error ("URL is read-only while working");
|
2007-12-30 17:41:49 +01:00
|
|
|
return;
|
2011-06-02 18:09:04 +02:00
|
|
|
}
|
|
|
|
|
2011-06-28 13:04:52 +02:00
|
|
|
if (PLENGTH() == 0)
|
|
|
|
goto UNKNOWN_PROTOCOL;
|
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
url = GB.NewString(PSTRING(), PLENGTH());
|
|
|
|
|
|
|
|
if (GB.Is(THIS, GB.FindClass("FtpClient")))
|
|
|
|
{
|
|
|
|
protocol = CURL_get_protocol(url, "ftp://");
|
|
|
|
if (strcmp(protocol, "ftp://"))
|
|
|
|
goto UNKNOWN_PROTOCOL;
|
|
|
|
}
|
|
|
|
else if (GB.Is(THIS, GB.FindClass("HttpClient")))
|
|
|
|
{
|
|
|
|
protocol = CURL_get_protocol(url, "http://");
|
|
|
|
if (strcmp(protocol, "http://") && strcmp(protocol, "https://"))
|
|
|
|
goto UNKNOWN_PROTOCOL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
goto UNKNOWN_PROTOCOL;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
if (strncmp(url, protocol, strlen(protocol)))
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2011-06-02 18:09:04 +02:00
|
|
|
tmp = GB.NewZeroString(protocol);
|
|
|
|
GB.AddString(&tmp, url, GB.StringLength(url));
|
|
|
|
GB.FreeString(&url);
|
|
|
|
url = tmp;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
2011-06-02 18:09:04 +02:00
|
|
|
|
|
|
|
GB.FreeString(&THIS_URL);
|
|
|
|
THIS_URL = url;
|
|
|
|
return;
|
|
|
|
|
|
|
|
UNKNOWN_PROTOCOL:
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
GB.Error("Unknown protocol");
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CCURL_new)
|
|
|
|
|
2008-09-13 17:35:13 +02:00
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "CCURL_new: %p\n", THIS);
|
|
|
|
#endif
|
|
|
|
|
2008-10-04 14:31:49 +02:00
|
|
|
/*curlData *data=NULL;
|
2008-02-14 19:11:54 +01:00
|
|
|
|
|
|
|
GB.Alloc(POINTER(&data),sizeof(curlData));
|
2008-10-04 14:31:49 +02:00
|
|
|
((void**)THIS->stream._free)[0]=(void*)data;*/
|
2008-02-14 19:11:54 +01:00
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
THIS->stream.desc = NULL;
|
|
|
|
THIS_CURL = NULL;
|
|
|
|
THIS_URL = NULL;
|
|
|
|
THIS_FILE = NULL;
|
|
|
|
THIS_STATUS = 0;
|
|
|
|
|
|
|
|
Adv_user_NEW(&THIS->user);
|
2007-12-30 17:41:49 +01:00
|
|
|
Adv_proxy_NEW(&THIS->proxy.proxy);
|
2011-06-02 18:09:04 +02:00
|
|
|
|
|
|
|
THIS->proxy.parent_status = (int*)&THIS_STATUS;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CCURL_free)
|
|
|
|
|
2008-09-13 17:35:13 +02:00
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "CCURL_free: %p\n", THIS);
|
|
|
|
#endif
|
|
|
|
|
2011-06-02 18:09:04 +02:00
|
|
|
GB.FreeString(&THIS_URL);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-02-14 12:25:00 +01:00
|
|
|
if (THIS_FILE) fclose(THIS_FILE);
|
2008-09-13 17:35:13 +02:00
|
|
|
if (THIS_CURL)
|
|
|
|
{
|
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- [%p] curl_easy_cleanup(%p)\n", THIS, THIS_CURL);
|
|
|
|
#endif
|
|
|
|
curl_easy_cleanup(THIS_CURL);
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
Adv_user_CLEAR (&THIS->user);
|
|
|
|
Adv_proxy_CLEAR(&THIS->proxy.proxy);
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CCURL_init)
|
|
|
|
|
2008-09-13 17:35:13 +02:00
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- curl_multi_init()\n");
|
|
|
|
#endif
|
2007-12-30 17:41:49 +01:00
|
|
|
CCURL_multicurl=curl_multi_init();
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CCURL_exit)
|
|
|
|
|
2008-09-13 17:35:13 +02:00
|
|
|
#if DEBUG
|
|
|
|
fprintf(stderr, "-- curl_multi_cleanup()\n");
|
|
|
|
#endif
|
2007-12-30 17:41:49 +01:00
|
|
|
curl_multi_cleanup(CCURL_multicurl);
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(CCURL_Peek)
|
|
|
|
|
2010-03-13 19:27:51 +01:00
|
|
|
GB.ReturnString(THIS->data);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
2010-03-13 19:27:51 +01:00
|
|
|
BEGIN_PROPERTY(Curl_Debug)
|
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
|
|
|
GB.ReturnBoolean(THIS->debug);
|
|
|
|
else
|
|
|
|
THIS->debug = VPROP(GB_BOOLEAN);
|
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
//*************************************************************************
|
|
|
|
//#################### GAMBAS INTERFACE ###################################
|
|
|
|
//*************************************************************************
|
|
|
|
GB_DESC CCurlDesc[] =
|
|
|
|
{
|
2010-11-16 02:49:18 +01:00
|
|
|
GB_DECLARE("Curl", sizeof(CCURL)), GB_NOT_CREATABLE(),
|
|
|
|
|
|
|
|
GB_INHERITS("Stream"),
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-11-16 02:49:18 +01:00
|
|
|
GB_METHOD("_new", NULL, CCURL_new, NULL),
|
|
|
|
GB_METHOD("_free", NULL, CCURL_free, NULL),
|
|
|
|
GB_METHOD("Peek","s", CCURL_Peek, NULL),
|
|
|
|
|
|
|
|
GB_STATIC_METHOD("_init",NULL,CCURL_init, NULL),
|
|
|
|
GB_STATIC_METHOD("_exit",NULL,CCURL_exit, NULL),
|
|
|
|
|
|
|
|
GB_EVENT("Finished", NULL, NULL, &CURL_FINISHED),
|
|
|
|
GB_EVENT("Connect", NULL, NULL, &CURL_CONNECT),
|
|
|
|
GB_EVENT("Read", NULL, NULL, &CURL_READ),
|
|
|
|
GB_EVENT("Error", NULL,NULL, &CURL_ERROR),
|
|
|
|
|
|
|
|
GB_PROPERTY("URL", "s",CCURL_URL),
|
|
|
|
GB_PROPERTY("User","s",CCURL_sUser),
|
|
|
|
GB_PROPERTY("Password","s",CCURL_Password),
|
|
|
|
GB_PROPERTY("Async","b",CCURL_Async),
|
|
|
|
GB_PROPERTY("Timeout","i",CCURL_TimeOut),
|
2011-08-21 23:46:20 +02:00
|
|
|
GB_PROPERTY_SELF("Proxy",".Curl.Proxy"),
|
2010-11-16 02:49:18 +01:00
|
|
|
GB_PROPERTY_READ("Status","i",CCURL_Status),
|
2011-09-04 15:39:33 +02:00
|
|
|
GB_PROPERTY_READ("ErrorText", "s", Curl_ErrorText),
|
2010-11-16 02:49:18 +01:00
|
|
|
GB_PROPERTY("Debug", "b", Curl_Debug),
|
|
|
|
|
|
|
|
GB_END_DECLARE
|
2007-12-30 17:41:49 +01:00
|
|
|
};
|
|
|
|
|