forked from enlightenment/efl
WIP: efl.net: Introduce Efl.Net.Dialer.Http
This class implements the Efl.Net.Dialer interface using libcurl to perform HTTP requests. That means it's an Efl.Net.Dialer, Efl.Net.Socket, Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being usable with Efl.Io.Copier as demonstrated in the efl_io_copier_example.c
This commit is contained in:
parent
e7df1a7483
commit
b791c79ca0
|
@ -11,6 +11,7 @@ ecore_con_eolian_files = \
|
||||||
lib/ecore_con/efl_net_socket_tcp.eo \
|
lib/ecore_con/efl_net_socket_tcp.eo \
|
||||||
lib/ecore_con/efl_net_dialer.eo \
|
lib/ecore_con/efl_net_dialer.eo \
|
||||||
lib/ecore_con/efl_net_dialer_tcp.eo \
|
lib/ecore_con/efl_net_dialer_tcp.eo \
|
||||||
|
lib/ecore_con/efl_net_dialer_http.eo \
|
||||||
lib/ecore_con/efl_net_server.eo \
|
lib/ecore_con/efl_net_server.eo \
|
||||||
lib/ecore_con/efl_net_server_fd.eo \
|
lib/ecore_con/efl_net_server_fd.eo \
|
||||||
lib/ecore_con/efl_net_server_tcp.eo \
|
lib/ecore_con/efl_net_server_tcp.eo \
|
||||||
|
@ -19,8 +20,13 @@ ecore_con_eolian_files = \
|
||||||
lib/ecore_con/ecore_con_eet_client_obj.eo \
|
lib/ecore_con/ecore_con_eet_client_obj.eo \
|
||||||
lib/ecore_con/efl_network_url.eo
|
lib/ecore_con/efl_network_url.eo
|
||||||
|
|
||||||
|
ecore_con_eolian_type_files = \
|
||||||
|
lib/ecore_con/efl_net_http_types.eot
|
||||||
|
|
||||||
|
|
||||||
ecore_con_eolian_c = $(ecore_con_eolian_files:%.eo=%.eo.c)
|
ecore_con_eolian_c = $(ecore_con_eolian_files:%.eo=%.eo.c)
|
||||||
ecore_con_eolian_h = $(ecore_con_eolian_files:%.eo=%.eo.h) \
|
ecore_con_eolian_h = $(ecore_con_eolian_files:%.eo=%.eo.h) \
|
||||||
|
$(ecore_con_eolian_type_files:%.eot=%.eot.h) \
|
||||||
$(ecore_con_eolian_files:%.eo=%.eo.legacy.h)
|
$(ecore_con_eolian_files:%.eo=%.eo.legacy.h)
|
||||||
|
|
||||||
BUILT_SOURCES += \
|
BUILT_SOURCES += \
|
||||||
|
@ -29,11 +35,13 @@ BUILT_SOURCES += \
|
||||||
|
|
||||||
ecoreconeolianfilesdir = $(datadir)/eolian/include/ecore-@VMAJ@
|
ecoreconeolianfilesdir = $(datadir)/eolian/include/ecore-@VMAJ@
|
||||||
ecoreconeolianfiles_DATA = \
|
ecoreconeolianfiles_DATA = \
|
||||||
$(ecore_con_eolian_files)
|
$(ecore_con_eolian_files) \
|
||||||
|
$(ecore_con_eolian_type_files)
|
||||||
|
|
||||||
EXTRA_DIST2 += \
|
EXTRA_DIST2 += \
|
||||||
${ecoreconeolianfiles_DATA}
|
${ecoreconeolianfiles_DATA}
|
||||||
|
|
||||||
|
|
||||||
lib_LTLIBRARIES += lib/ecore_con/libecore_con.la
|
lib_LTLIBRARIES += lib/ecore_con/libecore_con.la
|
||||||
|
|
||||||
installed_ecoreconmainheadersdir = $(includedir)/ecore-con-@VMAJ@
|
installed_ecoreconmainheadersdir = $(includedir)/ecore-con-@VMAJ@
|
||||||
|
@ -66,6 +74,7 @@ lib/ecore_con/efl_net_socket_fd.c \
|
||||||
lib/ecore_con/efl_net_socket_tcp.c \
|
lib/ecore_con/efl_net_socket_tcp.c \
|
||||||
lib/ecore_con/efl_net_dialer.c \
|
lib/ecore_con/efl_net_dialer.c \
|
||||||
lib/ecore_con/efl_net_dialer_tcp.c \
|
lib/ecore_con/efl_net_dialer_tcp.c \
|
||||||
|
lib/ecore_con/efl_net_dialer_http.c \
|
||||||
lib/ecore_con/efl_net_server.c \
|
lib/ecore_con/efl_net_server.c \
|
||||||
lib/ecore_con/efl_net_server_fd.c \
|
lib/ecore_con/efl_net_server_fd.c \
|
||||||
lib/ecore_con/efl_net_server_tcp.c
|
lib/ecore_con/efl_net_server_tcp.c
|
||||||
|
|
|
@ -48,3 +48,4 @@
|
||||||
/ecore_buffer_provider_example
|
/ecore_buffer_provider_example
|
||||||
/efl_io_copier_example
|
/efl_io_copier_example
|
||||||
/efl_net_server_example
|
/efl_net_server_example
|
||||||
|
/efl_net_dialer_http_example
|
||||||
|
|
|
@ -78,7 +78,8 @@ ecore_getopt_example \
|
||||||
ecore_con_eet_client_example \
|
ecore_con_eet_client_example \
|
||||||
ecore_con_eet_server_example \
|
ecore_con_eet_server_example \
|
||||||
efl_io_copier_example \
|
efl_io_copier_example \
|
||||||
efl_net_server_example
|
efl_net_server_example \
|
||||||
|
efl_net_dialer_http_example
|
||||||
|
|
||||||
ECORE_COMMON_LDADD = \
|
ECORE_COMMON_LDADD = \
|
||||||
$(top_builddir)/src/lib/ecore/libecore.la \
|
$(top_builddir)/src/lib/ecore/libecore.la \
|
||||||
|
@ -285,6 +286,9 @@ efl_io_copier_example_LDADD = $(ECORE_CON_COMMON_LDADD)
|
||||||
efl_net_server_example_SOURCES = efl_net_server_example.c
|
efl_net_server_example_SOURCES = efl_net_server_example.c
|
||||||
efl_net_server_example_LDADD = $(ECORE_CON_COMMON_LDADD)
|
efl_net_server_example_LDADD = $(ECORE_CON_COMMON_LDADD)
|
||||||
|
|
||||||
|
efl_net_dialer_http_example_SOURCES = efl_net_dialer_http_example.c
|
||||||
|
efl_net_dialer_http_example_LDADD = $(ECORE_CON_COMMON_LDADD)
|
||||||
|
|
||||||
SRCS = \
|
SRCS = \
|
||||||
ecore_animator_example.c \
|
ecore_animator_example.c \
|
||||||
ecore_buffer_example.c \
|
ecore_buffer_example.c \
|
||||||
|
@ -331,7 +335,9 @@ ecore_getopt_example.c \
|
||||||
ecore_con_eet_client_example.c \
|
ecore_con_eet_client_example.c \
|
||||||
ecore_con_eet_server_example.c \
|
ecore_con_eet_server_example.c \
|
||||||
ecore_con_eet_descriptor_example.c \
|
ecore_con_eet_descriptor_example.c \
|
||||||
efl_io_copier_example.c
|
efl_io_copier_example.c \
|
||||||
|
efl_net_server_example.c \
|
||||||
|
efl_net_dialer_http_example.c
|
||||||
|
|
||||||
DATA_FILES = red.png Makefile.examples
|
DATA_FILES = red.png Makefile.examples
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,63 @@ EFL_CALLBACKS_ARRAY_DEFINE(dialer_cbs,
|
||||||
{ EFL_NET_DIALER_EVENT_ERROR, _dialer_error },
|
{ EFL_NET_DIALER_EVENT_ERROR, _dialer_error },
|
||||||
{ EFL_NET_DIALER_EVENT_CONNECTED, _dialer_connected });
|
{ EFL_NET_DIALER_EVENT_CONNECTED, _dialer_connected });
|
||||||
|
|
||||||
|
static void
|
||||||
|
_http_headers_done(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
Eina_Iterator *itr;
|
||||||
|
Efl_Net_Http_Header *h;
|
||||||
|
Efl_Net_Http_Version ver = efl_net_dialer_http_version_get(event->object);
|
||||||
|
const char *response_content_type;
|
||||||
|
int64_t response_content_length;
|
||||||
|
|
||||||
|
fprintf(stderr, "INFO: HTTP/%d.%d connected to '%s', code=%d, headers:\n",
|
||||||
|
ver / 100, ver % 100,
|
||||||
|
efl_net_dialer_address_dial_get(event->object),
|
||||||
|
efl_net_dialer_http_response_status_get(event->object));
|
||||||
|
|
||||||
|
/* this is only for the last request, if allow_redirects and you want
|
||||||
|
* all of the headers, use efl_net_dialer_http_response_headers_all_get()
|
||||||
|
*/
|
||||||
|
itr = efl_net_dialer_http_response_headers_get(event->object);
|
||||||
|
|
||||||
|
EINA_ITERATOR_FOREACH(itr, h)
|
||||||
|
fprintf(stderr, "INFO: Header '%s: %s'\n", h->key, h->value);
|
||||||
|
|
||||||
|
eina_iterator_free(itr);
|
||||||
|
|
||||||
|
/* be nice to memory, we do not need these anymore */
|
||||||
|
efl_net_dialer_http_response_headers_clear(event->object);
|
||||||
|
|
||||||
|
response_content_length = efl_net_dialer_http_response_content_length_get(event->object);
|
||||||
|
response_content_type = efl_net_dialer_http_response_content_type_get(event->object);
|
||||||
|
fprintf(stderr, "INFO: Download %" PRId64 " bytes of type %s\n",
|
||||||
|
response_content_length, response_content_type);
|
||||||
|
|
||||||
|
if (efl_net_dialer_http_primary_mode_get(event->object) == EFL_NET_DIALER_HTTP_PRIMARY_MODE_UPLOAD)
|
||||||
|
{
|
||||||
|
int64_t request_content_type = efl_net_dialer_http_request_content_length_get(event->object);
|
||||||
|
fprintf(stderr, "INFO: Upload %" PRId64 " bytes\n",
|
||||||
|
request_content_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_http_closed(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
uint64_t dn, dt, un, ut;
|
||||||
|
|
||||||
|
efl_net_dialer_http_progress_download_get(event->object, &dn, &dt);
|
||||||
|
efl_net_dialer_http_progress_upload_get(event->object, &un, &ut);
|
||||||
|
fprintf(stderr, "INFO: http transfer info: "
|
||||||
|
"download=%" PRIu64 "/%" PRIu64 " "
|
||||||
|
"upload=%" PRIu64 "/%" PRIu64 "\n",
|
||||||
|
dn, dt, un, ut);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFL_CALLBACKS_ARRAY_DEFINE(http_cbs,
|
||||||
|
{ EFL_NET_DIALER_HTTP_EVENT_HEADERS_DONE, _http_headers_done },
|
||||||
|
{ EFL_IO_CLOSER_EVENT_CLOSED, _http_closed });
|
||||||
|
|
||||||
/* copier events are of interest, you should hook to at least "done"
|
/* copier events are of interest, you should hook to at least "done"
|
||||||
* and "error"
|
* and "error"
|
||||||
*/
|
*/
|
||||||
|
@ -274,6 +331,7 @@ static const Ecore_Getopt options = {
|
||||||
"The input file name or:\n"
|
"The input file name or:\n"
|
||||||
":stdin: to read from stdin.\n"
|
":stdin: to read from stdin.\n"
|
||||||
"tcp://IP:PORT to connect using TCP and an IPv4 (A.B.C.D:PORT) or IPv6 ([A:B:C:D::E]:PORT).\n"
|
"tcp://IP:PORT to connect using TCP and an IPv4 (A.B.C.D:PORT) or IPv6 ([A:B:C:D::E]:PORT).\n"
|
||||||
|
"http://address to do a GET request\n"
|
||||||
"",
|
"",
|
||||||
"input-file"),
|
"input-file"),
|
||||||
ECORE_GETOPT_STORE_METAVAR_STR(0, NULL,
|
ECORE_GETOPT_STORE_METAVAR_STR(0, NULL,
|
||||||
|
@ -283,6 +341,7 @@ static const Ecore_Getopt options = {
|
||||||
":memory: to write to a memory buffer.\n"
|
":memory: to write to a memory buffer.\n"
|
||||||
":none: to not use a destination object.\n"
|
":none: to not use a destination object.\n"
|
||||||
"tcp://IP:PORT to connect using TCP and an IPv4 (A.B.C.D:PORT) or IPv6 ([A:B:C:D::E]:PORT).\n"
|
"tcp://IP:PORT to connect using TCP and an IPv4 (A.B.C.D:PORT) or IPv6 ([A:B:C:D::E]:PORT).\n"
|
||||||
|
"http://address to do a PUT request\n"
|
||||||
"",
|
"",
|
||||||
"output-file"),
|
"output-file"),
|
||||||
ECORE_GETOPT_SENTINEL
|
ECORE_GETOPT_SENTINEL
|
||||||
|
@ -321,6 +380,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
ecore_init();
|
ecore_init();
|
||||||
ecore_con_init();
|
ecore_con_init();
|
||||||
|
ecore_con_url_init();
|
||||||
|
|
||||||
args = ecore_getopt_parse(&options, values, argc, argv);
|
args = ecore_getopt_parse(&options, values, argc, argv);
|
||||||
if (args < 0)
|
if (args < 0)
|
||||||
|
@ -386,6 +446,32 @@ main(int argc, char **argv)
|
||||||
goto end_input;
|
goto end_input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strncmp(input_fname, "http://", strlen("http://")) == 0 ||
|
||||||
|
strncmp(input_fname, "https://", strlen("https://")) == 0)
|
||||||
|
{
|
||||||
|
Eina_Error err;
|
||||||
|
|
||||||
|
input = efl_add(EFL_NET_DIALER_HTTP_CLASS, ecore_main_loop_get(),
|
||||||
|
efl_net_dialer_http_method_set(efl_self, "GET"),
|
||||||
|
efl_event_callback_array_add(efl_self, input_cbs(), NULL), /* optional */
|
||||||
|
efl_event_callback_array_add(efl_self, dialer_cbs(), NULL), /* optional */
|
||||||
|
efl_event_callback_array_add(efl_self, http_cbs(), NULL) /* optional */
|
||||||
|
);
|
||||||
|
if (!input)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: could not create HTTP Dialer.\n");
|
||||||
|
retval = EXIT_FAILURE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = efl_net_dialer_dial(input, input_fname);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: could not HTTP dial %s: %s\n",
|
||||||
|
input_fname, eina_error_msg_get(err));
|
||||||
|
goto end_input;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* regular file, open with flags: read-only and close-on-exec */
|
/* regular file, open with flags: read-only and close-on-exec */
|
||||||
|
@ -493,6 +579,32 @@ main(int argc, char **argv)
|
||||||
goto end_output;
|
goto end_output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strncmp(output_fname, "http://", strlen("http://")) == 0 ||
|
||||||
|
strncmp(output_fname, "https://", strlen("https://")) == 0)
|
||||||
|
{
|
||||||
|
Eina_Error err;
|
||||||
|
|
||||||
|
output = efl_add(EFL_NET_DIALER_HTTP_CLASS, ecore_main_loop_get(),
|
||||||
|
efl_net_dialer_http_method_set(efl_self, "PUT"),
|
||||||
|
efl_event_callback_array_add(efl_self, output_cbs(), NULL), /* optional */
|
||||||
|
efl_event_callback_array_add(efl_self, dialer_cbs(), NULL), /* optional */
|
||||||
|
efl_event_callback_array_add(efl_self, http_cbs(), NULL) /* optional */
|
||||||
|
);
|
||||||
|
if (!output)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: could not create HTTP Dialer.\n");
|
||||||
|
retval = EXIT_FAILURE;
|
||||||
|
goto end_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = efl_net_dialer_dial(output, output_fname);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: could not HTTP dial %s: %s\n",
|
||||||
|
output_fname, eina_error_msg_get(err));
|
||||||
|
goto end_output;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* regular file, open with flags: write-only, close-on-exec,
|
/* regular file, open with flags: write-only, close-on-exec,
|
||||||
|
@ -560,6 +672,7 @@ main(int argc, char **argv)
|
||||||
input = NULL;
|
input = NULL;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
ecore_con_url_shutdown();
|
||||||
ecore_con_shutdown();
|
ecore_con_shutdown();
|
||||||
ecore_shutdown();
|
ecore_shutdown();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,414 @@
|
||||||
|
#define EFL_BETA_API_SUPPORT 1
|
||||||
|
#define EFL_EO_API_SUPPORT 1
|
||||||
|
#include <Ecore.h>
|
||||||
|
#include <Ecore_Con.h>
|
||||||
|
#include <Ecore_Getopt.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
static int retval = EXIT_SUCCESS;
|
||||||
|
static int waiting;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_closed(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "INFO: closed %s\n",
|
||||||
|
efl_name_get(event->object));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eos(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "INFO: eos %s\n",
|
||||||
|
efl_name_get(event->object));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_connected(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "INFO: connected %s\n",
|
||||||
|
efl_net_dialer_address_dial_get(event->object));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_resolved(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "INFO: resolved %s => %s\n",
|
||||||
|
efl_net_dialer_address_dial_get(event->object),
|
||||||
|
efl_net_socket_address_remote_get(event->object));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_error(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
const Eina_Error *perr = event->info;
|
||||||
|
fprintf(stderr, "INFO: error: %d '%s'\n", *perr, eina_error_msg_get(*perr));
|
||||||
|
retval = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_http_headers_done(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
Eo *o = event->object;
|
||||||
|
Efl_Net_Http_Version ver = efl_net_dialer_http_version_get(o);
|
||||||
|
Eina_Iterator *itr;
|
||||||
|
const Efl_Net_Http_Header *h;
|
||||||
|
|
||||||
|
fprintf(stderr, "INFO: HTTP/%d.%d status=%d url=%s\n",
|
||||||
|
ver / 100, ver % 100,
|
||||||
|
efl_net_dialer_http_response_status_get(o),
|
||||||
|
efl_net_socket_address_remote_get(o));
|
||||||
|
|
||||||
|
itr = efl_net_dialer_http_response_headers_get(o);
|
||||||
|
EINA_ITERATOR_FOREACH(itr, h)
|
||||||
|
fprintf(stderr, "INFO: %s: %s\n", h->key, h->value);
|
||||||
|
|
||||||
|
eina_iterator_free(itr);
|
||||||
|
|
||||||
|
fprintf(stderr, "INFO: content-type: %s, content-length: %" PRId64 "\n",
|
||||||
|
efl_net_dialer_http_response_content_type_get(o),
|
||||||
|
efl_net_dialer_http_response_content_length_get(o));
|
||||||
|
|
||||||
|
fprintf(stderr, "INFO: to upload %zd bytes\n", efl_net_dialer_http_request_content_length_get(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
EFL_CALLBACKS_ARRAY_DEFINE(dialer_cbs,
|
||||||
|
{ EFL_NET_DIALER_HTTP_EVENT_HEADERS_DONE, _http_headers_done },
|
||||||
|
{ EFL_NET_DIALER_EVENT_CONNECTED, _connected },
|
||||||
|
{ EFL_NET_DIALER_EVENT_RESOLVED, _resolved },
|
||||||
|
{ EFL_NET_DIALER_EVENT_ERROR, _error },
|
||||||
|
{ EFL_IO_CLOSER_EVENT_CLOSED, _closed },
|
||||||
|
{ EFL_IO_READER_EVENT_EOS, _eos });
|
||||||
|
|
||||||
|
static void
|
||||||
|
_done(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
waiting--;
|
||||||
|
fprintf(stderr, "INFO: done %s, waiting=%d\n",
|
||||||
|
efl_name_get(event->object), waiting);
|
||||||
|
if (waiting == 0)
|
||||||
|
ecore_main_loop_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
EFL_CALLBACKS_ARRAY_DEFINE(copier_cbs,
|
||||||
|
{ EFL_IO_COPIER_EVENT_DONE, _done },
|
||||||
|
{ EFL_IO_CLOSER_EVENT_CLOSED, _closed });
|
||||||
|
|
||||||
|
static const char *primary_mode_choices[] = {
|
||||||
|
"auto",
|
||||||
|
"download",
|
||||||
|
"upload",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static Efl_Net_Dialer_Http_Primary_Mode
|
||||||
|
_parse_primary_mode(const char *str)
|
||||||
|
{
|
||||||
|
if (strcmp(str, "upload") == 0)
|
||||||
|
return EFL_NET_DIALER_HTTP_PRIMARY_MODE_UPLOAD;
|
||||||
|
if (strcmp(str, "download") == 0)
|
||||||
|
return EFL_NET_DIALER_HTTP_PRIMARY_MODE_DOWNLOAD;
|
||||||
|
|
||||||
|
return EFL_NET_DIALER_HTTP_PRIMARY_MODE_AUTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *http_version_choices[] = {
|
||||||
|
"1.0",
|
||||||
|
"1.1",
|
||||||
|
"2.0",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static Efl_Net_Http_Version
|
||||||
|
_parse_http_version(const char *str)
|
||||||
|
{
|
||||||
|
if (strcmp(str, "1.1") == 0)
|
||||||
|
return EFL_NET_HTTP_VERSION_V1_1;
|
||||||
|
if (strcmp(str, "2.0") == 0)
|
||||||
|
return EFL_NET_HTTP_VERSION_V2_0;
|
||||||
|
|
||||||
|
return EFL_NET_HTTP_VERSION_V1_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *authentication_method_choices[] = {
|
||||||
|
"none",
|
||||||
|
"basic",
|
||||||
|
"digest",
|
||||||
|
"negotiate",
|
||||||
|
"ntlm",
|
||||||
|
"ntlm_winbind",
|
||||||
|
"any_safe",
|
||||||
|
"any",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Efl_Net_Http_Authentication_Method
|
||||||
|
_parse_authentication_method(const char *str)
|
||||||
|
{
|
||||||
|
if (strcmp(str, "basic") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_BASIC;
|
||||||
|
if (strcmp(str, "digest") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_DIGEST;
|
||||||
|
if (strcmp(str, "negotiate") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_NEGOTIATE;
|
||||||
|
if (strcmp(str, "ntlm") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_NTLM;
|
||||||
|
if (strcmp(str, "ntlm_winbind") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_NTLM_WINBIND;
|
||||||
|
if (strcmp(str, "any_safe") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_ANY_SAFE;
|
||||||
|
if (strcmp(str, "any") == 0)
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_ANY;
|
||||||
|
|
||||||
|
return EFL_NET_HTTP_AUTHENTICATION_METHOD_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Ecore_Getopt options = {
|
||||||
|
"efl_net_dialer_http_example", /* program name */
|
||||||
|
NULL, /* usage line */
|
||||||
|
"1", /* version */
|
||||||
|
"(C) 2016 Enlightenment Project", /* copyright */
|
||||||
|
"BSD 2-Clause", /* license */
|
||||||
|
/* long description, may be multiline and contain \n */
|
||||||
|
"Example of Efl_Net_Dialer_Http usage.\n",
|
||||||
|
EINA_FALSE,
|
||||||
|
{
|
||||||
|
ECORE_GETOPT_STORE_STR('m', "method", "HTTP method such as GET, POST, PUT..."),
|
||||||
|
ECORE_GETOPT_CHOICE('M', "primary-mode", "Define primary operation mode.", primary_mode_choices),
|
||||||
|
ECORE_GETOPT_CHOICE('v', "http-version", "HTTP protocol version to use", http_version_choices),
|
||||||
|
ECORE_GETOPT_STORE_STR('U', "username", "Authentication username"),
|
||||||
|
ECORE_GETOPT_STORE_STR('P', "password", "Authentication password"),
|
||||||
|
ECORE_GETOPT_CHOICE('A', "authentication-method", "Authentication method", authentication_method_choices),
|
||||||
|
ECORE_GETOPT_STORE_BOOL('R', "authentication-restricted", "Authentication method must be restricted"),
|
||||||
|
ECORE_GETOPT_STORE_BOOL('r', "allow-redirects", "allow redirections by following 'Location:' headers"),
|
||||||
|
ECORE_GETOPT_STORE_DOUBLE('t', "connect-timeout", "timeout in seconds for the connection phase"),
|
||||||
|
ECORE_GETOPT_APPEND('H', "header", "Add custom headers. Format must be 'Key: Value'", ECORE_GETOPT_TYPE_STR),
|
||||||
|
ECORE_GETOPT_APPEND('F', "form", "Add form field. Format must be 'key=value'", ECORE_GETOPT_TYPE_STR),
|
||||||
|
ECORE_GETOPT_STORE_STR('i', "input-file", "Input file to use when uploading"),
|
||||||
|
ECORE_GETOPT_VERSION('V', "version"),
|
||||||
|
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
|
||||||
|
ECORE_GETOPT_LICENSE('L', "license"),
|
||||||
|
ECORE_GETOPT_HELP('h', "help"),
|
||||||
|
ECORE_GETOPT_STORE_METAVAR_STR(0, NULL,
|
||||||
|
"The address (URL) to dial", "address"),
|
||||||
|
ECORE_GETOPT_STORE_METAVAR_STR(0, NULL,
|
||||||
|
"The output file name or :stdout:",
|
||||||
|
"output-file"),
|
||||||
|
ECORE_GETOPT_SENTINEL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *method = "GET";
|
||||||
|
char *primary_mode_str = "auto";
|
||||||
|
char *http_version_str = "1.1";
|
||||||
|
char *username = NULL;
|
||||||
|
char *password = NULL;
|
||||||
|
char *authentication_method_str = "basic";
|
||||||
|
char *address = NULL;
|
||||||
|
char *output_fname = NULL;
|
||||||
|
char *input_fname = NULL;
|
||||||
|
Eina_Bool quit_option = EINA_FALSE;
|
||||||
|
Eina_Bool authentication_restricted = EINA_FALSE;
|
||||||
|
Eina_Bool allow_redirects = EINA_TRUE;
|
||||||
|
double timeout_dial = 30.0;
|
||||||
|
Eina_List *headers = NULL;
|
||||||
|
Eina_List *form_fields = NULL;
|
||||||
|
Ecore_Getopt_Value values[] = {
|
||||||
|
ECORE_GETOPT_VALUE_STR(method),
|
||||||
|
ECORE_GETOPT_VALUE_STR(primary_mode_str),
|
||||||
|
ECORE_GETOPT_VALUE_STR(http_version_str),
|
||||||
|
ECORE_GETOPT_VALUE_STR(username),
|
||||||
|
ECORE_GETOPT_VALUE_STR(password),
|
||||||
|
ECORE_GETOPT_VALUE_STR(authentication_method_str),
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(authentication_restricted),
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(allow_redirects),
|
||||||
|
ECORE_GETOPT_VALUE_DOUBLE(timeout_dial),
|
||||||
|
ECORE_GETOPT_VALUE_LIST(headers),
|
||||||
|
ECORE_GETOPT_VALUE_LIST(form_fields),
|
||||||
|
ECORE_GETOPT_VALUE_STR(input_fname),
|
||||||
|
|
||||||
|
/* standard block to provide version, copyright, license and help */
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -V/--version quits */
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -C/--copyright quits */
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -L/--license quits */
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -h/--help quits */
|
||||||
|
|
||||||
|
/* positional argument */
|
||||||
|
ECORE_GETOPT_VALUE_STR(address),
|
||||||
|
ECORE_GETOPT_VALUE_STR(output_fname),
|
||||||
|
|
||||||
|
ECORE_GETOPT_VALUE_NONE /* sentinel */
|
||||||
|
};
|
||||||
|
int args;
|
||||||
|
Eo *input, *dialer, *output, *sender, *receiver, *loop;
|
||||||
|
Efl_Net_Dialer_Http_Primary_Mode primary_mode;
|
||||||
|
Efl_Net_Http_Version http_version;
|
||||||
|
Efl_Net_Http_Authentication_Method authentication_method;
|
||||||
|
Efl_Net_Http_Header *header;
|
||||||
|
Eina_Iterator *itr;
|
||||||
|
Eina_Error err;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
ecore_init();
|
||||||
|
ecore_con_init();
|
||||||
|
ecore_con_url_init();
|
||||||
|
|
||||||
|
args = ecore_getopt_parse(&options, values, argc, argv);
|
||||||
|
if (args < 0)
|
||||||
|
{
|
||||||
|
fputs("ERROR: Could not parse command line options.\n", stderr);
|
||||||
|
retval = EXIT_FAILURE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quit_option) goto end;
|
||||||
|
|
||||||
|
loop = ecore_main_loop_get();
|
||||||
|
|
||||||
|
args = ecore_getopt_parse_positional(&options, values, argc, argv, args);
|
||||||
|
if (args < 0)
|
||||||
|
{
|
||||||
|
fputs("ERROR: Could not parse positional arguments.\n", stderr);
|
||||||
|
retval = EXIT_FAILURE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!input_fname) || (strcmp(input_fname, ":stdin:") == 0))
|
||||||
|
{
|
||||||
|
input = efl_add(EFL_IO_STDIN_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "stdin"),
|
||||||
|
efl_event_callback_add(efl_self, EFL_IO_READER_EVENT_EOS, _eos, NULL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input = efl_add(EFL_IO_FILE_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "input"),
|
||||||
|
efl_file_set(efl_self, input_fname, NULL),
|
||||||
|
efl_io_file_flags_set(efl_self, O_RDONLY | O_CLOEXEC),
|
||||||
|
efl_event_callback_add(efl_self, EFL_IO_READER_EVENT_EOS, _eos, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!output_fname) || (strcmp(output_fname, ":stdout:") == 0))
|
||||||
|
{
|
||||||
|
output = efl_add(EFL_IO_STDOUT_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "stdout"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output = efl_add(EFL_IO_FILE_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "output"),
|
||||||
|
efl_file_set(efl_self, output_fname, NULL),
|
||||||
|
efl_io_file_mode_set(efl_self, 0644),
|
||||||
|
efl_io_file_flags_set(efl_self, O_WRONLY | O_CLOEXEC | O_TRUNC | O_CREAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
primary_mode = _parse_primary_mode(primary_mode_str);
|
||||||
|
http_version = _parse_http_version(http_version_str);
|
||||||
|
authentication_method = _parse_authentication_method(authentication_method_str);
|
||||||
|
|
||||||
|
dialer = efl_add(EFL_NET_DIALER_HTTP_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "dialer"),
|
||||||
|
efl_net_dialer_http_method_set(efl_self, method),
|
||||||
|
efl_net_dialer_http_primary_mode_set(efl_self, primary_mode),
|
||||||
|
efl_net_dialer_http_version_set(efl_self, http_version),
|
||||||
|
efl_net_dialer_http_authentication_set(efl_self, username, password, authentication_method, authentication_restricted),
|
||||||
|
efl_net_dialer_http_allow_redirects_set(efl_self, allow_redirects),
|
||||||
|
efl_net_dialer_timeout_dial_set(efl_self, timeout_dial),
|
||||||
|
efl_event_callback_array_add(efl_self, dialer_cbs(), NULL));
|
||||||
|
|
||||||
|
EINA_LIST_FREE(headers, str)
|
||||||
|
{
|
||||||
|
char *p = strchr(str, ':');
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
p[0] = '\0';
|
||||||
|
p++;
|
||||||
|
while ((p[0] != '\0') && isspace(p[0]))
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
efl_net_dialer_http_request_header_add(dialer, str, p);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
EINA_LIST_FREE(form_fields, str)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "TODO: form_field %s", str);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
waiting = 1;
|
||||||
|
if (efl_net_dialer_http_primary_mode_get(dialer) == EFL_NET_DIALER_HTTP_PRIMARY_MODE_UPLOAD)
|
||||||
|
waiting++;
|
||||||
|
|
||||||
|
sender = efl_add(EFL_IO_COPIER_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "sender"),
|
||||||
|
efl_io_copier_source_set(efl_self, input),
|
||||||
|
efl_io_copier_destination_set(efl_self, dialer),
|
||||||
|
efl_event_callback_array_add(efl_self, copier_cbs(), NULL));
|
||||||
|
|
||||||
|
fprintf(stderr, "INFO: sending %s->%s\n",
|
||||||
|
efl_name_get(input),
|
||||||
|
efl_name_get(dialer));
|
||||||
|
|
||||||
|
receiver = efl_add(EFL_IO_COPIER_CLASS, loop,
|
||||||
|
efl_name_set(efl_self, "receiver"),
|
||||||
|
efl_io_copier_source_set(efl_self, dialer),
|
||||||
|
efl_io_copier_destination_set(efl_self, output),
|
||||||
|
efl_event_callback_array_add(efl_self, copier_cbs(), NULL));
|
||||||
|
fprintf(stderr, "INFO: receiving %s->%s\n",
|
||||||
|
efl_name_get(dialer),
|
||||||
|
efl_name_get(output));
|
||||||
|
|
||||||
|
err = efl_net_dialer_dial(dialer, address);
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: could not dial '%s': %s",
|
||||||
|
address, eina_error_msg_get(err));
|
||||||
|
goto no_mainloop;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"INFO: dialed %s\n"
|
||||||
|
"INFO: - method=%s\n"
|
||||||
|
"INFO: - primary_mode=%d\n"
|
||||||
|
"INFO: - version=%d\n"
|
||||||
|
"INFO: - allow_redirects=%d\n"
|
||||||
|
"INFO: - timeout_dial=%fs\n"
|
||||||
|
"INFO: - request headers:\n",
|
||||||
|
efl_net_dialer_address_dial_get(dialer),
|
||||||
|
efl_net_dialer_http_method_get(dialer),
|
||||||
|
efl_net_dialer_http_primary_mode_get(dialer),
|
||||||
|
efl_net_dialer_http_version_get(dialer),
|
||||||
|
efl_net_dialer_http_allow_redirects_get(dialer),
|
||||||
|
efl_net_dialer_timeout_dial_get(dialer));
|
||||||
|
|
||||||
|
itr = efl_net_dialer_http_request_headers_get(dialer);
|
||||||
|
EINA_ITERATOR_FOREACH(itr, header)
|
||||||
|
fprintf(stderr, "INFO: %s: %s\n", header->key, header->value);
|
||||||
|
eina_iterator_free(itr);
|
||||||
|
|
||||||
|
ecore_main_loop_begin();
|
||||||
|
|
||||||
|
fprintf(stderr, "INFO: main loop finished.\n");
|
||||||
|
|
||||||
|
no_mainloop:
|
||||||
|
efl_io_closer_close(sender);
|
||||||
|
efl_del(sender);
|
||||||
|
|
||||||
|
efl_io_closer_close(receiver);
|
||||||
|
efl_del(receiver);
|
||||||
|
|
||||||
|
efl_del(dialer);
|
||||||
|
efl_del(output);
|
||||||
|
efl_del(input);
|
||||||
|
|
||||||
|
end:
|
||||||
|
ecore_con_url_shutdown();
|
||||||
|
ecore_con_shutdown();
|
||||||
|
ecore_shutdown();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
|
@ -14,3 +14,62 @@
|
||||||
#include "efl_net_socket_tcp.eo.h"
|
#include "efl_net_socket_tcp.eo.h"
|
||||||
#include "efl_net_dialer_tcp.eo.h"
|
#include "efl_net_dialer_tcp.eo.h"
|
||||||
#include "efl_net_server_tcp.eo.h"
|
#include "efl_net_server_tcp.eo.h"
|
||||||
|
|
||||||
|
#include "efl_net_http_types.eot.h"
|
||||||
|
/* TODO: should be generated from 'var Efl.Net.Http.Error.*' */
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_BAD_CONTENT_ENCODING;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_BAD_DOWNLOAD_RESUME;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_BAD_FUNCTION_ARGUMENT;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_CHUNK_FAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_CONV_FAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_CONV_REQD;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_COULDNT_CONNECT;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_COULDNT_RESOLVE_HOST;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_COULDNT_RESOLVE_PROXY;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_FAILED_INIT;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_FILE_COULDNT_READ_FILE;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_FILESIZE_EXCEEDED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_FUNCTION_NOT_FOUND;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_GOT_NOTHING;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_HTTP2;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_HTTP2_STREAM;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_HTTP_POST_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_HTTP_RETURNED_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_INTERFACE_FAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_LOGIN_DENIED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_NO_CONNECTION_AVAILABLE;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_NOT_BUILT_IN;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_OPERATION_TIMEDOUT;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_PARTIAL_FILE;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_PEER_FAILED_VERIFICATION;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_RANGE_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_READ_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_RECV_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_REMOTE_ACCESS_DENIED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_REMOTE_DISK_FULL;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_REMOTE_FILE_EXISTS;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_REMOTE_FILE_NOT_FOUND;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SEND_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SEND_FAIL_REWIND;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_CACERT;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_CACERT_BADFILE;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_CERTPROBLEM;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_CIPHER;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_CONNECT_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_CRL_BADFILE;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_ENGINE_INITFAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_ENGINE_NOTFOUND;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_ENGINE_SETFAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_INVALIDCERTSTATUS;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_ISSUER_ERROR;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_SSL_SHUTDOWN_FAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_TOO_MANY_REDIRECTS;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_UNKNOWN_OPTION;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_UNSUPPORTED_PROTOCOL;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_UPLOAD_FAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_URL_MALFORMAT;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_USE_SSL_FAILED;
|
||||||
|
extern Eina_Error EFL_NET_HTTP_ERROR_WRITE_ERROR;
|
||||||
|
|
||||||
|
#include "efl_net_dialer_http.eo.h"
|
||||||
|
|
|
@ -26,6 +26,204 @@ Ecore_Con_Curl *_c = NULL;
|
||||||
Eina_Bool _c_fail = EINA_FALSE;
|
Eina_Bool _c_fail = EINA_FALSE;
|
||||||
double _c_timeout = 0.0;
|
double _c_timeout = 0.0;
|
||||||
|
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_BAD_CONTENT_ENCODING = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_BAD_DOWNLOAD_RESUME = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_BAD_FUNCTION_ARGUMENT = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_CHUNK_FAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_CONV_FAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_CONV_REQD = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_COULDNT_CONNECT = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_COULDNT_RESOLVE_HOST = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_COULDNT_RESOLVE_PROXY = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_FAILED_INIT = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_FILE_COULDNT_READ_FILE = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_FILESIZE_EXCEEDED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_FUNCTION_NOT_FOUND = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_GOT_NOTHING = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_HTTP2 = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_HTTP2_STREAM = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_HTTP_POST_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_HTTP_RETURNED_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_INTERFACE_FAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_LOGIN_DENIED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_NO_CONNECTION_AVAILABLE = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_NOT_BUILT_IN = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_OPERATION_TIMEDOUT = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_PARTIAL_FILE = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_PEER_FAILED_VERIFICATION = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_RANGE_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_READ_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_RECV_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_REMOTE_ACCESS_DENIED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_REMOTE_DISK_FULL = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_REMOTE_FILE_EXISTS = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_REMOTE_FILE_NOT_FOUND = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SEND_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SEND_FAIL_REWIND = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_CACERT = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_CACERT_BADFILE = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_CERTPROBLEM = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_CIPHER = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_CONNECT_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_CRL_BADFILE = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_ENGINE_INITFAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_ENGINE_NOTFOUND = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_ENGINE_SETFAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_INVALIDCERTSTATUS = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_ISSUER_ERROR = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_PINNEDPUBKEYNOTMATCH = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_SSL_SHUTDOWN_FAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_TOO_MANY_REDIRECTS = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_UNKNOWN_OPTION = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_UNSUPPORTED_PROTOCOL = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_UPLOAD_FAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_URL_MALFORMAT = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_USE_SSL_FAILED = 0;
|
||||||
|
EAPI Eina_Error EFL_NET_HTTP_ERROR_WRITE_ERROR = 0;
|
||||||
|
|
||||||
|
Eina_Error
|
||||||
|
_curlcode_to_eina_error(const CURLcode code)
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case CURLE_OK: return 0;
|
||||||
|
case CURLE_ABORTED_BY_CALLBACK: return ECONNABORTED;
|
||||||
|
case CURLE_AGAIN: return EAGAIN;
|
||||||
|
case CURLE_OUT_OF_MEMORY: return ENOMEM;
|
||||||
|
|
||||||
|
#define _MAP(n) case CURLE_ ## n: return EFL_NET_HTTP_ERROR_ ## n
|
||||||
|
|
||||||
|
_MAP(BAD_CONTENT_ENCODING);
|
||||||
|
_MAP(BAD_DOWNLOAD_RESUME);
|
||||||
|
_MAP(BAD_FUNCTION_ARGUMENT);
|
||||||
|
_MAP(CHUNK_FAILED);
|
||||||
|
_MAP(CONV_FAILED);
|
||||||
|
_MAP(CONV_REQD);
|
||||||
|
_MAP(COULDNT_CONNECT);
|
||||||
|
_MAP(COULDNT_RESOLVE_HOST);
|
||||||
|
_MAP(COULDNT_RESOLVE_PROXY);
|
||||||
|
_MAP(FAILED_INIT);
|
||||||
|
_MAP(FILE_COULDNT_READ_FILE);
|
||||||
|
_MAP(FILESIZE_EXCEEDED);
|
||||||
|
_MAP(FUNCTION_NOT_FOUND);
|
||||||
|
_MAP(GOT_NOTHING);
|
||||||
|
_MAP(HTTP2);
|
||||||
|
_MAP(HTTP2_STREAM);
|
||||||
|
_MAP(HTTP_POST_ERROR);
|
||||||
|
_MAP(HTTP_RETURNED_ERROR);
|
||||||
|
_MAP(INTERFACE_FAILED);
|
||||||
|
_MAP(LOGIN_DENIED);
|
||||||
|
_MAP(NO_CONNECTION_AVAILABLE);
|
||||||
|
_MAP(NOT_BUILT_IN);
|
||||||
|
_MAP(OPERATION_TIMEDOUT);
|
||||||
|
_MAP(PARTIAL_FILE);
|
||||||
|
_MAP(PEER_FAILED_VERIFICATION);
|
||||||
|
_MAP(RANGE_ERROR);
|
||||||
|
_MAP(READ_ERROR);
|
||||||
|
_MAP(RECV_ERROR);
|
||||||
|
_MAP(REMOTE_ACCESS_DENIED);
|
||||||
|
_MAP(REMOTE_DISK_FULL);
|
||||||
|
_MAP(REMOTE_FILE_EXISTS);
|
||||||
|
_MAP(REMOTE_FILE_NOT_FOUND);
|
||||||
|
_MAP(SEND_ERROR);
|
||||||
|
_MAP(SEND_FAIL_REWIND);
|
||||||
|
_MAP(SSL_CACERT);
|
||||||
|
_MAP(SSL_CACERT_BADFILE);
|
||||||
|
_MAP(SSL_CERTPROBLEM);
|
||||||
|
_MAP(SSL_CIPHER);
|
||||||
|
_MAP(SSL_CONNECT_ERROR);
|
||||||
|
_MAP(SSL_CRL_BADFILE);
|
||||||
|
_MAP(SSL_ENGINE_INITFAILED);
|
||||||
|
_MAP(SSL_ENGINE_NOTFOUND);
|
||||||
|
_MAP(SSL_ENGINE_SETFAILED);
|
||||||
|
_MAP(SSL_INVALIDCERTSTATUS);
|
||||||
|
_MAP(SSL_ISSUER_ERROR);
|
||||||
|
_MAP(SSL_PINNEDPUBKEYNOTMATCH);
|
||||||
|
_MAP(SSL_SHUTDOWN_FAILED);
|
||||||
|
_MAP(TOO_MANY_REDIRECTS);
|
||||||
|
_MAP(UNKNOWN_OPTION);
|
||||||
|
_MAP(UNSUPPORTED_PROTOCOL);
|
||||||
|
_MAP(UPLOAD_FAILED);
|
||||||
|
_MAP(URL_MALFORMAT);
|
||||||
|
_MAP(USE_SSL_FAILED);
|
||||||
|
_MAP(WRITE_ERROR);
|
||||||
|
#undef _MAP
|
||||||
|
|
||||||
|
default:
|
||||||
|
ERR("unexpected error CURcode=%d '%s', not mapped",
|
||||||
|
code, _c->curl_easy_strerror(code));
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_c_init_errors(void)
|
||||||
|
{
|
||||||
|
/* use from system: */
|
||||||
|
// CURLE_ABORTED_BY_CALLBACK = ECONNABORTED
|
||||||
|
// CURLE_AGAIN = EAGAIN
|
||||||
|
// CURLE_OUT_OF_MEMORY = ENOMEM
|
||||||
|
|
||||||
|
if (EFL_NET_HTTP_ERROR_BAD_CONTENT_ENCODING) return; /* only once in the whole runtime */
|
||||||
|
|
||||||
|
#define _MAP(n) EFL_NET_HTTP_ERROR_ ## n = eina_error_msg_static_register(_c->curl_easy_strerror(CURLE_ ## n))
|
||||||
|
_MAP(BAD_CONTENT_ENCODING);
|
||||||
|
_MAP(BAD_DOWNLOAD_RESUME);
|
||||||
|
_MAP(BAD_FUNCTION_ARGUMENT);
|
||||||
|
_MAP(CHUNK_FAILED);
|
||||||
|
_MAP(CONV_FAILED);
|
||||||
|
_MAP(CONV_REQD);
|
||||||
|
_MAP(COULDNT_CONNECT);
|
||||||
|
_MAP(COULDNT_RESOLVE_HOST);
|
||||||
|
_MAP(COULDNT_RESOLVE_PROXY);
|
||||||
|
_MAP(FAILED_INIT);
|
||||||
|
_MAP(FILE_COULDNT_READ_FILE);
|
||||||
|
_MAP(FILESIZE_EXCEEDED);
|
||||||
|
_MAP(FUNCTION_NOT_FOUND);
|
||||||
|
_MAP(GOT_NOTHING);
|
||||||
|
_MAP(HTTP2);
|
||||||
|
_MAP(HTTP2_STREAM);
|
||||||
|
_MAP(HTTP_POST_ERROR);
|
||||||
|
_MAP(HTTP_RETURNED_ERROR);
|
||||||
|
_MAP(INTERFACE_FAILED);
|
||||||
|
_MAP(LOGIN_DENIED);
|
||||||
|
_MAP(NO_CONNECTION_AVAILABLE);
|
||||||
|
_MAP(NOT_BUILT_IN);
|
||||||
|
_MAP(OPERATION_TIMEDOUT);
|
||||||
|
_MAP(PARTIAL_FILE);
|
||||||
|
_MAP(PEER_FAILED_VERIFICATION);
|
||||||
|
_MAP(RANGE_ERROR);
|
||||||
|
_MAP(READ_ERROR);
|
||||||
|
_MAP(RECV_ERROR);
|
||||||
|
_MAP(REMOTE_ACCESS_DENIED);
|
||||||
|
_MAP(REMOTE_DISK_FULL);
|
||||||
|
_MAP(REMOTE_FILE_EXISTS);
|
||||||
|
_MAP(REMOTE_FILE_NOT_FOUND);
|
||||||
|
_MAP(SEND_ERROR);
|
||||||
|
_MAP(SEND_FAIL_REWIND);
|
||||||
|
_MAP(SSL_CACERT);
|
||||||
|
_MAP(SSL_CACERT_BADFILE);
|
||||||
|
_MAP(SSL_CERTPROBLEM);
|
||||||
|
_MAP(SSL_CIPHER);
|
||||||
|
_MAP(SSL_CONNECT_ERROR);
|
||||||
|
_MAP(SSL_CRL_BADFILE);
|
||||||
|
_MAP(SSL_ENGINE_INITFAILED);
|
||||||
|
_MAP(SSL_ENGINE_NOTFOUND);
|
||||||
|
_MAP(SSL_ENGINE_SETFAILED);
|
||||||
|
_MAP(SSL_INVALIDCERTSTATUS);
|
||||||
|
_MAP(SSL_ISSUER_ERROR);
|
||||||
|
_MAP(SSL_PINNEDPUBKEYNOTMATCH);
|
||||||
|
_MAP(SSL_SHUTDOWN_FAILED);
|
||||||
|
_MAP(TOO_MANY_REDIRECTS);
|
||||||
|
_MAP(UNKNOWN_OPTION);
|
||||||
|
_MAP(UNSUPPORTED_PROTOCOL);
|
||||||
|
_MAP(UPLOAD_FAILED);
|
||||||
|
_MAP(URL_MALFORMAT);
|
||||||
|
_MAP(USE_SSL_FAILED);
|
||||||
|
_MAP(WRITE_ERROR);
|
||||||
|
#undef _MAP
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
_c_init(void)
|
_c_init(void)
|
||||||
{
|
{
|
||||||
|
@ -88,15 +286,20 @@ _c_init(void)
|
||||||
SYM(curl_multi_perform);
|
SYM(curl_multi_perform);
|
||||||
SYM(curl_multi_add_handle);
|
SYM(curl_multi_add_handle);
|
||||||
SYM(curl_multi_setopt);
|
SYM(curl_multi_setopt);
|
||||||
|
SYM(curl_multi_socket_action);
|
||||||
|
SYM(curl_multi_assign);
|
||||||
SYM(curl_easy_init);
|
SYM(curl_easy_init);
|
||||||
SYM(curl_easy_setopt);
|
SYM(curl_easy_setopt);
|
||||||
SYM(curl_easy_strerror);
|
SYM(curl_easy_strerror);
|
||||||
SYM(curl_easy_cleanup);
|
SYM(curl_easy_cleanup);
|
||||||
SYM(curl_easy_getinfo);
|
SYM(curl_easy_getinfo);
|
||||||
|
SYM(curl_easy_pause);
|
||||||
SYM(curl_slist_free_all);
|
SYM(curl_slist_free_all);
|
||||||
SYM(curl_slist_append);
|
SYM(curl_slist_append);
|
||||||
SYM(curl_version_info);
|
SYM(curl_version_info);
|
||||||
|
|
||||||
|
_c_init_errors();
|
||||||
|
|
||||||
// curl_global_init() is not thread safe!
|
// curl_global_init() is not thread safe!
|
||||||
if (_c->curl_global_init(CURL_GLOBAL_ALL)) goto error;
|
if (_c->curl_global_init(CURL_GLOBAL_ALL)) goto error;
|
||||||
_c->_curlm = _c->curl_multi_init();
|
_c->_curlm = _c->curl_multi_init();
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
#ifndef ECORE_CON_URL_CURL_H
|
#ifndef ECORE_CON_URL_CURL_H
|
||||||
#define ECORE_CON_URL_CURL_H 1
|
#define ECORE_CON_URL_CURL_H 1
|
||||||
|
|
||||||
|
#ifdef USE_CURL_H
|
||||||
|
/* During development you can set USE_CURL_H to use the system's
|
||||||
|
* curl.h instead of the local replicated values, it will provide all
|
||||||
|
* constants and type-checking.
|
||||||
|
*/
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#else
|
||||||
|
|
||||||
// all the types, defines, enums etc. from curl that we actually USE.
|
// all the types, defines, enums etc. from curl that we actually USE.
|
||||||
// we have to add to this if we use more things from curl not already
|
// we have to add to this if we use more things from curl not already
|
||||||
// defined here. see curl headers to get them from
|
// defined here. see curl headers to get them from
|
||||||
|
@ -9,13 +17,173 @@ typedef enum
|
||||||
CURLM_CALL_MULTI_PERFORM = -1,
|
CURLM_CALL_MULTI_PERFORM = -1,
|
||||||
CURLM_OK = 0
|
CURLM_OK = 0
|
||||||
} CURLMcode;
|
} CURLMcode;
|
||||||
typedef enum
|
|
||||||
{
|
#ifndef curl_socket_typedef
|
||||||
CURLE_OK = 0,
|
/* socket typedef */
|
||||||
CURLE_OPERATION_TIMEDOUT = 28
|
#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
|
||||||
|
typedef SOCKET curl_socket_t;
|
||||||
|
#define CURL_SOCKET_BAD INVALID_SOCKET
|
||||||
|
#else
|
||||||
|
typedef int curl_socket_t;
|
||||||
|
#define CURL_SOCKET_BAD -1
|
||||||
|
#endif
|
||||||
|
#define curl_socket_typedef
|
||||||
|
#endif /* curl_socket_typedef */
|
||||||
|
|
||||||
|
#define CURL_POLL_NONE 0
|
||||||
|
#define CURL_POLL_IN 1
|
||||||
|
#define CURL_POLL_OUT 2
|
||||||
|
#define CURL_POLL_INOUT 3
|
||||||
|
#define CURL_POLL_REMOVE 4
|
||||||
|
|
||||||
|
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||||
|
|
||||||
|
#define CURL_CSELECT_IN 0x01
|
||||||
|
#define CURL_CSELECT_OUT 0x02
|
||||||
|
#define CURL_CSELECT_ERR 0x04
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CURLINFO_TEXT = 0,
|
||||||
|
CURLINFO_HEADER_IN, /* 1 */
|
||||||
|
CURLINFO_HEADER_OUT, /* 2 */
|
||||||
|
CURLINFO_DATA_IN, /* 3 */
|
||||||
|
CURLINFO_DATA_OUT, /* 4 */
|
||||||
|
CURLINFO_SSL_DATA_IN, /* 5 */
|
||||||
|
CURLINFO_SSL_DATA_OUT, /* 6 */
|
||||||
|
CURLINFO_END
|
||||||
|
} curl_infotype;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CURLE_OK = 0,
|
||||||
|
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
||||||
|
CURLE_FAILED_INIT, /* 2 */
|
||||||
|
CURLE_URL_MALFORMAT, /* 3 */
|
||||||
|
CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
|
||||||
|
7.17.0, reused in April 2011 for 7.21.5] */
|
||||||
|
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||||
|
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||||
|
CURLE_COULDNT_CONNECT, /* 7 */
|
||||||
|
CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
|
||||||
|
CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
|
||||||
|
due to lack of access - when login fails
|
||||||
|
this is not returned. */
|
||||||
|
CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for
|
||||||
|
7.15.4, reused in Dec 2011 for 7.24.0]*/
|
||||||
|
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
|
||||||
|
CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server
|
||||||
|
[was obsoleted in August 2007 for 7.17.0,
|
||||||
|
reused in Dec 2011 for 7.24.0]*/
|
||||||
|
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
||||||
|
CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
|
||||||
|
CURLE_FTP_CANT_GET_HOST, /* 15 */
|
||||||
|
CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
|
||||||
|
[was obsoleted in August 2007 for 7.17.0,
|
||||||
|
reused in July 2014 for 7.38.0] */
|
||||||
|
CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
|
||||||
|
CURLE_PARTIAL_FILE, /* 18 */
|
||||||
|
CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
|
||||||
|
CURLE_OBSOLETE20, /* 20 - NOT USED */
|
||||||
|
CURLE_QUOTE_ERROR, /* 21 - quote command failure */
|
||||||
|
CURLE_HTTP_RETURNED_ERROR, /* 22 */
|
||||||
|
CURLE_WRITE_ERROR, /* 23 */
|
||||||
|
CURLE_OBSOLETE24, /* 24 - NOT USED */
|
||||||
|
CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
|
||||||
|
CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
|
||||||
|
CURLE_OUT_OF_MEMORY, /* 27 */
|
||||||
|
/* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
|
||||||
|
instead of a memory allocation error if CURL_DOES_CONVERSIONS
|
||||||
|
is defined
|
||||||
|
*/
|
||||||
|
CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
|
||||||
|
CURLE_OBSOLETE29, /* 29 - NOT USED */
|
||||||
|
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
||||||
|
CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
|
||||||
|
CURLE_OBSOLETE32, /* 32 - NOT USED */
|
||||||
|
CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
|
||||||
|
CURLE_HTTP_POST_ERROR, /* 34 */
|
||||||
|
CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
|
||||||
|
CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
|
||||||
|
CURLE_FILE_COULDNT_READ_FILE, /* 37 */
|
||||||
|
CURLE_LDAP_CANNOT_BIND, /* 38 */
|
||||||
|
CURLE_LDAP_SEARCH_FAILED, /* 39 */
|
||||||
|
CURLE_OBSOLETE40, /* 40 - NOT USED */
|
||||||
|
CURLE_FUNCTION_NOT_FOUND, /* 41 */
|
||||||
|
CURLE_ABORTED_BY_CALLBACK, /* 42 */
|
||||||
|
CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
|
||||||
|
CURLE_OBSOLETE44, /* 44 - NOT USED */
|
||||||
|
CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
|
||||||
|
CURLE_OBSOLETE46, /* 46 - NOT USED */
|
||||||
|
CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */
|
||||||
|
CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
|
||||||
|
CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */
|
||||||
|
CURLE_OBSOLETE50, /* 50 - NOT USED */
|
||||||
|
CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
|
||||||
|
wasn't verified fine */
|
||||||
|
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
||||||
|
CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
|
||||||
|
CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
|
||||||
|
default */
|
||||||
|
CURLE_SEND_ERROR, /* 55 - failed sending network data */
|
||||||
|
CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
|
||||||
|
CURLE_OBSOLETE57, /* 57 - NOT IN USE */
|
||||||
|
CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
|
||||||
|
CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
|
||||||
|
CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */
|
||||||
|
CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
|
||||||
|
CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
|
||||||
|
CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
|
||||||
|
CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
|
||||||
|
CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
|
||||||
|
that failed */
|
||||||
|
CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
|
||||||
|
CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
|
||||||
|
accepted and we failed to login */
|
||||||
|
CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
|
||||||
|
CURLE_TFTP_PERM, /* 69 - permission problem on server */
|
||||||
|
CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
|
||||||
|
CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
|
||||||
|
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
||||||
|
CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
|
||||||
|
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
||||||
|
CURLE_CONV_FAILED, /* 75 - conversion failed */
|
||||||
|
CURLE_CONV_REQD, /* 76 - caller must register conversion
|
||||||
|
callbacks using curl_easy_setopt options
|
||||||
|
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||||
|
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
|
||||||
|
CURLOPT_CONV_FROM_UTF8_FUNCTION */
|
||||||
|
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
|
||||||
|
or wrong format */
|
||||||
|
CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
|
||||||
|
CURLE_SSH, /* 79 - error from the SSH layer, somewhat
|
||||||
|
generic so the error message will be of
|
||||||
|
interest when this has happened */
|
||||||
|
|
||||||
|
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
|
||||||
|
connection */
|
||||||
|
CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
|
||||||
|
wait till it's ready and try again (Added
|
||||||
|
in 7.18.2) */
|
||||||
|
CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
|
||||||
|
wrong format (Added in 7.19.0) */
|
||||||
|
CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
|
||||||
|
7.19.0) */
|
||||||
|
CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
|
||||||
|
CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
|
||||||
|
CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
|
||||||
|
CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
|
||||||
|
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
||||||
|
CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
|
||||||
|
session will be queued */
|
||||||
|
CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
|
||||||
|
match */
|
||||||
|
CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
|
||||||
|
CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer
|
||||||
|
*/
|
||||||
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
#define CURLOPTTYPE_LONG 0
|
#define CURLOPTTYPE_LONG 0
|
||||||
#define CURLOPTTYPE_OBJECTPOINT 10000
|
#define CURLOPTTYPE_OBJECTPOINT 10000
|
||||||
|
#define CURLOPTTYPE_STRINGPOINT 10000
|
||||||
#define CURLOPTTYPE_FUNCTIONPOINT 20000
|
#define CURLOPTTYPE_FUNCTIONPOINT 20000
|
||||||
#define CURLOPTTYPE_OFF_T 30000
|
#define CURLOPTTYPE_OFF_T 30000
|
||||||
#define CINIT(na, t, nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
|
#define CINIT(na, t, nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
|
||||||
|
@ -29,6 +197,7 @@ typedef enum
|
||||||
CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
|
CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
|
||||||
CINIT(READFUNCTION, FUNCTIONPOINT, 12),
|
CINIT(READFUNCTION, FUNCTIONPOINT, 12),
|
||||||
CINIT(POSTFIELDS, OBJECTPOINT, 15),
|
CINIT(POSTFIELDS, OBJECTPOINT, 15),
|
||||||
|
CINIT(USERAGENT, STRINGPOINT, 18),
|
||||||
CINIT(HTTPHEADER, OBJECTPOINT, 23),
|
CINIT(HTTPHEADER, OBJECTPOINT, 23),
|
||||||
CINIT(WRITEHEADER, OBJECTPOINT, 29),
|
CINIT(WRITEHEADER, OBJECTPOINT, 29),
|
||||||
CINIT(COOKIEFILE, OBJECTPOINT, 31),
|
CINIT(COOKIEFILE, OBJECTPOINT, 31),
|
||||||
|
@ -40,6 +209,7 @@ typedef enum
|
||||||
CINIT(NOBODY, LONG, 44),
|
CINIT(NOBODY, LONG, 44),
|
||||||
CINIT(UPLOAD, LONG, 46),
|
CINIT(UPLOAD, LONG, 46),
|
||||||
CINIT(POST, LONG, 47),
|
CINIT(POST, LONG, 47),
|
||||||
|
CINIT(PUT, LONG, 54),
|
||||||
CINIT(FOLLOWLOCATION, LONG, 52),
|
CINIT(FOLLOWLOCATION, LONG, 52),
|
||||||
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
|
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
|
||||||
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
|
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
|
||||||
|
@ -47,18 +217,26 @@ typedef enum
|
||||||
CINIT(SSL_VERIFYPEER, LONG, 64),
|
CINIT(SSL_VERIFYPEER, LONG, 64),
|
||||||
CINIT(CAINFO, OBJECTPOINT, 65),
|
CINIT(CAINFO, OBJECTPOINT, 65),
|
||||||
CINIT(CONNECTTIMEOUT, LONG, 78),
|
CINIT(CONNECTTIMEOUT, LONG, 78),
|
||||||
|
CINIT(CONNECTTIMEOUT_MS, LONG, 156),
|
||||||
CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
|
CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
|
||||||
|
CINIT(HTTPGET, LONG, 80),
|
||||||
CINIT(COOKIEJAR, OBJECTPOINT, 82),
|
CINIT(COOKIEJAR, OBJECTPOINT, 82),
|
||||||
CINIT(HTTP_VERSION, LONG, 84),
|
CINIT(HTTP_VERSION, LONG, 84),
|
||||||
CINIT(FTP_USE_EPSV, LONG, 85),
|
CINIT(FTP_USE_EPSV, LONG, 85),
|
||||||
|
CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
|
||||||
|
CINIT(DEBUGDATA, OBJECTPOINT, 95),
|
||||||
CINIT(COOKIESESSION, LONG, 96),
|
CINIT(COOKIESESSION, LONG, 96),
|
||||||
CINIT(PROXYTYPE, LONG, 101),
|
CINIT(PROXYTYPE, LONG, 101),
|
||||||
CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102),
|
CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102),
|
||||||
|
CINIT(PRIVATE, OBJECTPOINT, 103),
|
||||||
CINIT(HTTPAUTH, LONG, 107),
|
CINIT(HTTPAUTH, LONG, 107),
|
||||||
CINIT(INFILESIZE_LARGE, OFF_T, 115),
|
CINIT(INFILESIZE_LARGE, OFF_T, 115),
|
||||||
|
CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
|
||||||
CINIT(COOKIELIST, OBJECTPOINT, 135),
|
CINIT(COOKIELIST, OBJECTPOINT, 135),
|
||||||
CINIT(USERNAME, OBJECTPOINT, 173),
|
CINIT(USERNAME, OBJECTPOINT, 173),
|
||||||
CINIT(PASSWORD, OBJECTPOINT, 174)
|
CINIT(PASSWORD, OBJECTPOINT, 174),
|
||||||
|
CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
|
||||||
|
#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
#define CURLINFO_STRING 0x100000
|
#define CURLINFO_STRING 0x100000
|
||||||
#define CURLINFO_LONG 0x200000
|
#define CURLINFO_LONG 0x200000
|
||||||
|
@ -68,7 +246,15 @@ typedef enum
|
||||||
#define CURLINFO_TYPEMASK 0xf00000
|
#define CURLINFO_TYPEMASK 0xf00000
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
|
CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
|
||||||
|
CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
|
||||||
|
CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
|
||||||
|
CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
|
||||||
|
CURLINFO_PRIVATE = CURLINFO_STRING + 21,
|
||||||
|
CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46,
|
||||||
|
CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
|
||||||
|
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
|
||||||
|
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -82,7 +268,11 @@ typedef enum
|
||||||
#define CINIT(name, type, num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
|
#define CINIT(name, type, num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CINIT(PIPELINING, LONG, 3)
|
CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
|
||||||
|
CINIT(SOCKETDATA, OBJECTPOINT, 2),
|
||||||
|
CINIT(PIPELINING, LONG, 3),
|
||||||
|
CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
|
||||||
|
CINIT(TIMERDATA, OBJECTPOINT, 5)
|
||||||
} CURLMoption;
|
} CURLMoption;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -92,8 +282,10 @@ typedef enum
|
||||||
} curl_TimeCond;
|
} curl_TimeCond;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
CURL_HTTP_VERSION_NONE = 0,
|
||||||
CURL_HTTP_VERSION_1_0 = 1,
|
CURL_HTTP_VERSION_1_0 = 1,
|
||||||
CURL_HTTP_VERSION_1_1 = 2,
|
CURL_HTTP_VERSION_1_1 = 2,
|
||||||
|
CURL_HTTP_VERSION_2_0 = 3
|
||||||
};
|
};
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -112,11 +304,26 @@ typedef enum
|
||||||
#define CURLOPT_READDATA CURLOPT_INFILE
|
#define CURLOPT_READDATA CURLOPT_INFILE
|
||||||
#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
|
#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
|
||||||
#define CURLVERSION_NOW CURLVERSION_FOURTH
|
#define CURLVERSION_NOW CURLVERSION_FOURTH
|
||||||
|
#define CURLAUTH_NONE ((unsigned long)0)
|
||||||
#define CURLAUTH_BASIC (((unsigned long)1) << 0)
|
#define CURLAUTH_BASIC (((unsigned long)1) << 0)
|
||||||
|
#define CURLAUTH_DIGEST (((unsigned long)1)<<1)
|
||||||
|
#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
|
||||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1) << 4)
|
#define CURLAUTH_DIGEST_IE (((unsigned long)1) << 4)
|
||||||
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
||||||
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC | CURLAUTH_DIGEST_IE))
|
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
||||||
|
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
||||||
|
#define CURLAUTH_ONLY (((unsigned long)1)<<31)
|
||||||
|
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
||||||
|
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
|
||||||
#define CURL_READFUNC_ABORT 0x10000000
|
#define CURL_READFUNC_ABORT 0x10000000
|
||||||
|
#define CURL_READFUNC_PAUSE 0x10000001
|
||||||
|
#define CURL_WRITEFUNC_PAUSE 0x10000001
|
||||||
|
|
||||||
|
#define CURLPAUSE_RECV (1<<0)
|
||||||
|
#define CURLPAUSE_RECV_CONT (0)
|
||||||
|
|
||||||
|
#define CURLPAUSE_SEND (1<<2)
|
||||||
|
#define CURLPAUSE_SEND_CONT (0)
|
||||||
|
|
||||||
typedef void CURLM;
|
typedef void CURLM;
|
||||||
typedef void CURL;
|
typedef void CURL;
|
||||||
|
@ -153,6 +360,9 @@ typedef struct
|
||||||
} data;
|
} data;
|
||||||
} CURLMsg;
|
} CURLMsg;
|
||||||
|
|
||||||
|
#endif /* USE_CURL_H */
|
||||||
|
|
||||||
|
|
||||||
typedef struct _Ecore_Con_Curl Ecore_Con_Curl;
|
typedef struct _Ecore_Con_Curl Ecore_Con_Curl;
|
||||||
|
|
||||||
struct _Ecore_Con_Curl
|
struct _Ecore_Con_Curl
|
||||||
|
@ -183,11 +393,19 @@ struct _Ecore_Con_Curl
|
||||||
CURL *curl_handle);
|
CURL *curl_handle);
|
||||||
CURLMcode (*curl_multi_setopt)(CURLM *multi_handle,
|
CURLMcode (*curl_multi_setopt)(CURLM *multi_handle,
|
||||||
CURLMoption option, ...);
|
CURLMoption option, ...);
|
||||||
|
CURLMcode (*curl_multi_socket_action)(CURLM *multi_handle,
|
||||||
|
curl_socket_t fd,
|
||||||
|
int ev_bitmask,
|
||||||
|
int *running_handles);
|
||||||
|
CURLMcode (*curl_multi_assign)(CURLM *multi_handle,
|
||||||
|
curl_socket_t sockfd,
|
||||||
|
void *sockp);
|
||||||
CURL *(*curl_easy_init)(void);
|
CURL *(*curl_easy_init)(void);
|
||||||
CURLcode (*curl_easy_setopt)(CURL *curl, CURLoption option, ...);
|
CURLcode (*curl_easy_setopt)(CURL *curl, CURLoption option, ...);
|
||||||
const char *(*curl_easy_strerror)(CURLcode);
|
const char *(*curl_easy_strerror)(CURLcode);
|
||||||
void (*curl_easy_cleanup)(CURL *curl);
|
void (*curl_easy_cleanup)(CURL *curl);
|
||||||
CURLcode (*curl_easy_getinfo)(CURL *curl, CURLINFO info, ...);
|
CURLcode (*curl_easy_getinfo)(CURL *curl, CURLINFO info, ...);
|
||||||
|
CURLcode (*curl_easy_pause)(CURL *curl, int bitmask);
|
||||||
void (*curl_slist_free_all)(struct curl_slist *);
|
void (*curl_slist_free_all)(struct curl_slist *);
|
||||||
struct curl_slist *(*curl_slist_append)(struct curl_slist *list,
|
struct curl_slist *(*curl_slist_append)(struct curl_slist *list,
|
||||||
const char *string);
|
const char *string);
|
||||||
|
@ -202,5 +420,6 @@ extern double _c_timeout;
|
||||||
|
|
||||||
Eina_Bool _c_init(void);
|
Eina_Bool _c_init(void);
|
||||||
void _c_shutdown(void);
|
void _c_shutdown(void);
|
||||||
|
Eina_Error _curlcode_to_eina_error(const CURLcode code);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,314 @@
|
||||||
|
import efl_net_http_types;
|
||||||
|
|
||||||
|
enum Efl.Net.Dialer.Http.Primary_Mode {
|
||||||
|
auto,
|
||||||
|
download,
|
||||||
|
upload,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Efl.Net.Dialer.Http (Efl.Loop_User, Efl.Net.Dialer, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Sizer) { /* TODO: reader/writer should be from dialer->socket, but are being missed somehow... */
|
||||||
|
[[HTTP Dialer (Client).
|
||||||
|
|
||||||
|
The effective URL in use, if @.allow_redirects is $true will be
|
||||||
|
available as @Efl.Net.Socket.address_remote. The
|
||||||
|
@Efl.Net.Socket.address_local is an IP:PORT pair.
|
||||||
|
|
||||||
|
The dialer can do bi-directional information exchange. It can
|
||||||
|
also do a PUT and upload a file, or GET and download one. Anoter
|
||||||
|
case is to do a POST with some form values, including a file,
|
||||||
|
and retrieve its headers and response body. To make usage more
|
||||||
|
streamlined, choose your primary interest with @.primary_mode
|
||||||
|
then get some properties such as @Efl.Io.Sizer.size to report or
|
||||||
|
use what matters to your use case.
|
||||||
|
|
||||||
|
If @.allow_redirects is $true, multiple "connected" and
|
||||||
|
"resolved" signals will be dispatched, one for each
|
||||||
|
connection. Then @.response_status and @.response_headers_get
|
||||||
|
will keep changing. Using @.response_headers_all_get one can see
|
||||||
|
the whole history of headers and connections.
|
||||||
|
|
||||||
|
To enable debugging use EINA_LOG_LEVELS=ecore_con:4 environment
|
||||||
|
variable.
|
||||||
|
|
||||||
|
@since 1.19
|
||||||
|
]]
|
||||||
|
methods {
|
||||||
|
@property method {
|
||||||
|
[[The HTTP method to use.
|
||||||
|
|
||||||
|
A string representing the HTTP method to use, such as
|
||||||
|
GET, POST, HEAD, PUT, DELETE...
|
||||||
|
|
||||||
|
This should be set before dialing.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
method: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property primary_mode {
|
||||||
|
[[Is this request primarily a download or upload?
|
||||||
|
|
||||||
|
This property will change the behavior of @Efl.Io.Sizer:
|
||||||
|
|
||||||
|
- if @Efl.Net.Dialer.Http.Primary_Mode.auto, then
|
||||||
|
@Efl.Net.Dialer.Http.Primary_Mode.download or
|
||||||
|
@Efl.Net.Dialer.Http.Primary_Mode.upload will be
|
||||||
|
choosen based on the @.method: if "PUT", then it's
|
||||||
|
upload, otherwise it's download.
|
||||||
|
|
||||||
|
- if @Efl.Net.Dialer.Http.Primary_Mode.upload, applying
|
||||||
|
a new size with @Efl.Io.Sizer.resize or
|
||||||
|
@Efl.Io.Sizer.size.set will specify the
|
||||||
|
"Content-Length" to upload. If no size is previously
|
||||||
|
set, then the upload will happen in
|
||||||
|
"Transfer-encoding: chunked".
|
||||||
|
|
||||||
|
- if @Efl.Net.Dialer.Http.Primary_Mode.download, then
|
||||||
|
@Efl.Io.Sizer.size.get will report the
|
||||||
|
"Content-Length" provided by the server, if any.
|
||||||
|
|
||||||
|
If is worth to mention that one can provide and
|
||||||
|
retrieve these values using @.request_headers_get (to
|
||||||
|
send) and @.response_headers_get (what was received),
|
||||||
|
as well as using the specific properties
|
||||||
|
@.request_content_length (upload) and
|
||||||
|
@.response_content_length (download).
|
||||||
|
]]
|
||||||
|
get {
|
||||||
|
[[The effective primary mode.
|
||||||
|
|
||||||
|
This will return one of
|
||||||
|
@Efl.Net.Dialer.Http.Primary_Mode.download or
|
||||||
|
@Efl.Net.Dialer.Http.Primary_Mode.upload. If "auto"
|
||||||
|
was set (the default), then it will pick the best
|
||||||
|
based on the @.method in use.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
primary_mode: Efl.Net.Dialer.Http.Primary_Mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property user_agent {
|
||||||
|
[[The User-Agent to specify.
|
||||||
|
|
||||||
|
This should be set before dialing.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
user_agent: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property http_version {
|
||||||
|
[[The HTTP version to use.
|
||||||
|
|
||||||
|
This should be set before dialing.
|
||||||
|
|
||||||
|
Once connected, it will change to the actual connection
|
||||||
|
HTTP version, so check after "connected" event.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
http_version: Efl.Net.Http.Version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property authentication {
|
||||||
|
[[HTTP authentication to use.
|
||||||
|
|
||||||
|
This should be set before dialing.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
method: Efl.Net.Http.Authentication_Method @optional; [[authentication method to use, defaults to @Efl.Net.Http.Authentication_Method.basic]]
|
||||||
|
restricted: bool @optional; [[restrict method]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property allow_redirects {
|
||||||
|
[[Allow HTTP redirects to be followed.
|
||||||
|
|
||||||
|
This should be set before dialing.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
allow_redirects: bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request_header_add {
|
||||||
|
[[Add a request header 'key: value'.
|
||||||
|
|
||||||
|
See @.request_headers_clear
|
||||||
|
|
||||||
|
This should be called before dialing.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in key: string;
|
||||||
|
@in value: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request_headers_clear {
|
||||||
|
[[Clear all request headers.
|
||||||
|
|
||||||
|
See @.request_header_add
|
||||||
|
|
||||||
|
This should be called before dialing.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
|
||||||
|
request_headers_get {
|
||||||
|
[[Return an iterator to the key-value pairs for request headers]]
|
||||||
|
return: free(own(iterator<Efl.Net.Http.Header>), eina_iterator_free) @warn_unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property request_content_length {
|
||||||
|
[["Content-Length:" Header used for uploading/sending.
|
||||||
|
|
||||||
|
To unset use -1
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set { }
|
||||||
|
values {
|
||||||
|
length: int64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property response_content_length {
|
||||||
|
[["Content-Length:" Header used for downloading/receiving.
|
||||||
|
|
||||||
|
If unset is -1.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
set @protected { }
|
||||||
|
values {
|
||||||
|
length: int64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property response_content_type {
|
||||||
|
[["Content-Type:" Header used for downloading/receiving]]
|
||||||
|
get { }
|
||||||
|
set @protected { }
|
||||||
|
values {
|
||||||
|
content_type: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property response_status {
|
||||||
|
[[The HTTP response status of this request.
|
||||||
|
|
||||||
|
It will be 0 if not connected, otherwise will be what is
|
||||||
|
returned by the server, such as.
|
||||||
|
|
||||||
|
See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
||||||
|
|
||||||
|
This will be usable after "connected" event is dispatched.
|
||||||
|
]]
|
||||||
|
get { }
|
||||||
|
values {
|
||||||
|
status_code: Efl.Net.Http.Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response_headers_get {
|
||||||
|
[[Return an iterator to the key-value pairs for the last response headers.
|
||||||
|
|
||||||
|
Since multiple requests can happen if @.allow_redirects
|
||||||
|
is true, then all headers will be accumulated. This
|
||||||
|
method returns only the headers for the last request.
|
||||||
|
|
||||||
|
To know all the headers, check @.response_headers_all_get.
|
||||||
|
|
||||||
|
This will be usable after "headers,done" event is dispatched.
|
||||||
|
]]
|
||||||
|
return: free(own(iterator<Efl.Net.Http.Header>), eina_iterator_free) @warn_unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
response_headers_all_get {
|
||||||
|
[[Return an iterator to the key-value pairs for all response headers.
|
||||||
|
|
||||||
|
Since multiple requests can happen if @.allow_redirects
|
||||||
|
is true, then all headers will be accumulated. To know
|
||||||
|
when new request is started, check for headers with keys
|
||||||
|
being NULL, the value will be the "HTTP/VERSION RESPONSE"
|
||||||
|
string received from the host, such as:
|
||||||
|
|
||||||
|
- key=NULL, value="HTTP/1.1 302 Found"
|
||||||
|
- key="Location", value="http://someredirect.com"
|
||||||
|
- key=NULL, value="HTTP/1.1 200 Ok"
|
||||||
|
- key="Content-Type", value="text/html"
|
||||||
|
|
||||||
|
Which mean the original request had a redirect to
|
||||||
|
http://someredirect.com.
|
||||||
|
|
||||||
|
To receive an iterator to just the last request, use
|
||||||
|
@.response_headers_get
|
||||||
|
|
||||||
|
This will be usable after "headers,done" event is dispatched.
|
||||||
|
]]
|
||||||
|
return: free(own(iterator<Efl.Net.Http.Header>), eina_iterator_free) @warn_unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
response_headers_clear {
|
||||||
|
[[Save some memory by disposing the received headers]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@property progress_download {
|
||||||
|
[[How many bytes were downloaded and how much was expected.]]
|
||||||
|
get { }
|
||||||
|
values {
|
||||||
|
downloaded: uint64 @optional;
|
||||||
|
total: uint64 @optional; [[0 if unknown]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property progress_upload {
|
||||||
|
[[How many bytes were uploaded and how much was expected.]]
|
||||||
|
get { }
|
||||||
|
values {
|
||||||
|
uploaded: uint64 @optional;
|
||||||
|
total: uint64 @optional; [[0 if unknown]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
events {
|
||||||
|
headers,done; [[Notifies all headers were parsed and are available.]]
|
||||||
|
}
|
||||||
|
|
||||||
|
implements {
|
||||||
|
Efl.Object.constructor;
|
||||||
|
Efl.Object.destructor;
|
||||||
|
Efl.Net.Dialer.dial;
|
||||||
|
Efl.Net.Dialer.address_dial;
|
||||||
|
Efl.Net.Dialer.connected;
|
||||||
|
Efl.Net.Dialer.timeout_dial;
|
||||||
|
Efl.Net.Socket.address_local;
|
||||||
|
Efl.Net.Socket.address_remote;
|
||||||
|
Efl.Io.Reader.read;
|
||||||
|
Efl.Io.Reader.can_read.get;
|
||||||
|
Efl.Io.Reader.can_read.set;
|
||||||
|
Efl.Io.Reader.eos.get;
|
||||||
|
Efl.Io.Reader.eos.set;
|
||||||
|
Efl.Io.Writer.write;
|
||||||
|
Efl.Io.Writer.can_write.get;
|
||||||
|
Efl.Io.Writer.can_write.set;
|
||||||
|
Efl.Io.Closer.close;
|
||||||
|
Efl.Io.Closer.closed.get;
|
||||||
|
Efl.Io.Sizer.resize;
|
||||||
|
Efl.Io.Sizer.size.get;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
import eina_types;
|
||||||
|
|
||||||
|
enum Efl.Net.Http.Version {
|
||||||
|
v1_0 = 100, [[1.0]]
|
||||||
|
v1_1 = 101, [[1.1]]
|
||||||
|
v2_0 = 200, [[2.0]]
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Efl.Net.Http.Authentication_Method {
|
||||||
|
none = 0,
|
||||||
|
basic = (1 << 0),
|
||||||
|
digest = (1 << 1),
|
||||||
|
negotiate = (1 << 2),
|
||||||
|
ntlm = (1 << 3),
|
||||||
|
ntlm_winbind = (1 << 4),
|
||||||
|
any_safe = Efl.Net.Http.Authentication_Method.digest | Efl.Net.Http.Authentication_Method.negotiate | Efl.Net.Http.Authentication_Method.ntlm | Efl.Net.Http.Authentication_Method.ntlm_winbind,
|
||||||
|
any = Efl.Net.Http.Authentication_Method.any_safe | Efl.Net.Http.Authentication_Method.basic,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Efl.Net.Http.Status {
|
||||||
|
[[Common HTTP status codes]]
|
||||||
|
|
||||||
|
unknown = 0, [[unknown status, likely not connected]]
|
||||||
|
|
||||||
|
/* Informational: 1xx */
|
||||||
|
continue = 100,
|
||||||
|
switching_protocols = 101,
|
||||||
|
checkpoint = 103, /* unofficial extension */
|
||||||
|
processing = 102,
|
||||||
|
|
||||||
|
/* success: 2xx */
|
||||||
|
ok = 200,
|
||||||
|
created = 201,
|
||||||
|
accepted = 202,
|
||||||
|
non_authoritative_information = 203,
|
||||||
|
no_content = 204,
|
||||||
|
reset_content = 205,
|
||||||
|
partial_content = 206,
|
||||||
|
multi_status = 207,
|
||||||
|
already_reported = 208,
|
||||||
|
im_used = 226,
|
||||||
|
|
||||||
|
/* redirection: 3xx */
|
||||||
|
multiple_choices = 300,
|
||||||
|
moved_permanently = 301,
|
||||||
|
found = 302,
|
||||||
|
see_other = 303,
|
||||||
|
not_modified = 304,
|
||||||
|
use_proxy = 305,
|
||||||
|
switch_proxy = 306,
|
||||||
|
temporary_redirect = 307,
|
||||||
|
permanent_redirect = 308,
|
||||||
|
|
||||||
|
/* client error: 4xx */
|
||||||
|
bad_request = 400,
|
||||||
|
unauthorized = 401,
|
||||||
|
payment_required = 402,
|
||||||
|
forbidden = 403,
|
||||||
|
not_found = 404,
|
||||||
|
method_not_allowed = 405,
|
||||||
|
not_acceptable = 406,
|
||||||
|
proxy_authentication_required = 407,
|
||||||
|
request_timeout = 408,
|
||||||
|
conflict = 409,
|
||||||
|
gone = 410,
|
||||||
|
length_required = 411,
|
||||||
|
precondition_failed = 412,
|
||||||
|
payload_too_large = 413,
|
||||||
|
uri_too_long = 414,
|
||||||
|
unsupported_media_type = 415,
|
||||||
|
range_not_satisfiable = 416,
|
||||||
|
expectation_failed = 417,
|
||||||
|
misdirected_request = 421,
|
||||||
|
unprocessable_entity = 422,
|
||||||
|
locked = 423,
|
||||||
|
failed_dependency = 424,
|
||||||
|
upgrade_required = 426,
|
||||||
|
precondition_required = 428,
|
||||||
|
too_many_requests = 429,
|
||||||
|
request_header_fields_too_large = 431,
|
||||||
|
login_timeout = 440, /* unofficial extension */
|
||||||
|
no_response = 444, /* unofficial extension */
|
||||||
|
retry_with = 449, /* unofficial extension */
|
||||||
|
blocked_by_windows_parental_controls = 450, /* unofficial extension */
|
||||||
|
unavailable_for_legal_reasons = 451,
|
||||||
|
ssl_certificate_error = 495, /* unofficial extension */
|
||||||
|
ssl_certificate_required = 496, /* unofficial extension */
|
||||||
|
http_request_sent_to_https_port = 497, /* unofficial extension */
|
||||||
|
request_has_been_forbidden_by_antivirus = 499,
|
||||||
|
|
||||||
|
/* server error: 5xx */
|
||||||
|
internal_server_error = 500,
|
||||||
|
not_implemented = 501,
|
||||||
|
bad_gateway = 502,
|
||||||
|
service_unavailable = 503,
|
||||||
|
gateway_timeout = 504,
|
||||||
|
http_version_not_supported = 505,
|
||||||
|
variant_also_negotiates = 506,
|
||||||
|
insufficient_storage = 507,
|
||||||
|
loop_detected = 508,
|
||||||
|
bandwidth_limit_exceeded = 509, /* unofficial extension */
|
||||||
|
not_extended = 510,
|
||||||
|
network_authentication_required = 511,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Efl.Net.Http.Header {
|
||||||
|
[[An HTTP Header.
|
||||||
|
|
||||||
|
Do not assume strings are Eina_Stringshare and they may be
|
||||||
|
NULL. The key and value should not include any trailing
|
||||||
|
whitespace.
|
||||||
|
|
||||||
|
There is a special case for response headers when
|
||||||
|
"allow_redirects" is enabled, in that case
|
||||||
|
efl_net_dialer_http_response_headers_all_get() will return some
|
||||||
|
items with key being NULL, that notifies of a new request as
|
||||||
|
described in the value "HTTP/1.1 200 Ok".
|
||||||
|
]]
|
||||||
|
key: string; [[for response headers this may be null to indicate a new request response, then the value will be a line such as 'HTTP/1.1 200 Ok']]
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
var @extern Efl.Net.Http.Error.BAD_CONTENT_ENCODING: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.BAD_DOWNLOAD_RESUME: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.BAD_FUNCTION_ARGUMENT: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.CHUNK_FAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.CONV_FAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.CONV_REQD: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.COULDNT_CONNECT: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.COULDNT_RESOLVE_HOST: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.COULDNT_RESOLVE_PROXY: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.FAILED_INIT: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.FILE_COULDNT_READ_FILE: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.FILESIZE_EXCEEDED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.FUNCTION_NOT_FOUND: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.GOT_NOTHING: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.HTTP2: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.HTTP2_STREAM: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.HTTP_POST_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.HTTP_RETURNED_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.INTERFACE_FAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.LOGIN_DENIED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.NO_CONNECTION_AVAILABLE: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.NOT_BUILT_IN: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.OPERATION_TIMEDOUT: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.PARTIAL_FILE: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.PEER_FAILED_VERIFICATION: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.RANGE_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.READ_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.RECV_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.REMOTE_ACCESS_DENIED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.REMOTE_DISK_FULL: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.REMOTE_FILE_EXISTS: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.REMOTE_FILE_NOT_FOUND: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SEND_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SEND_FAIL_REWIND: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_CACERT: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_CACERT_BADFILE: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_CERTPROBLEM: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_CIPHER: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_CONNECT_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_CRL_BADFILE: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_ENGINE_INITFAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_ENGINE_NOTFOUND: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_ENGINE_SETFAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_INVALIDCERTSTATUS: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_ISSUER_ERROR: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_PINNEDPUBKEYNOTMATCH: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.SSL_SHUTDOWN_FAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.TOO_MANY_REDIRECTS: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.UNKNOWN_OPTION: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.UNSUPPORTED_PROTOCOL: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.UPLOAD_FAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.URL_MALFORMAT: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.USE_SSL_FAILED: Eina.Error;
|
||||||
|
var @extern Efl.Net.Http.Error.WRITE_ERROR: Eina.Error;
|
Loading…
Reference in New Issue