Hello,

Thanks for working on this!

Gianluca Cannata, le mer. 11 nov. 2026 16:06:43 +0100, a ecrit:
> --- a/configure.in
> +++ b/configure.in
> @@ -4,9 +4,10 @@ AM_INIT_AUTOMAKE
> 
>  AC_PROG_CC
> 
> +PKG_CHECK_MODULES([CURL], [libcurl >= 7.0.0])
>  PKG_CHECK_MODULES(HTTPFS, libxml-2.0)
> 
> -HTTPFS_SHARED_LIBS="-lxml2 -lpthread -lnetfs -lfshelp -lports
> -liohelp -lshouldbeinlibc -lhurdbugaddr"
> +HTTPFS_SHARED_LIBS="-lcurl -lxml2 -lpthread -lnetfs -lfshelp -lports
> -liohelp -lshouldbeinlibc -lhurdbugaddr"

Please rather use $CURL_LIBS, produced by the PKG_CHECK_MODULES above.

Also, please use "cvs up" to get the latest source.

> diff --git a/http.c b/http.c
> index 50184c0..3b50fb5 100644
> --- a/http.c
> +++ b/http.c
> @@ -34,140 +34,96 @@
>  #include <hurd/hurd_types.h>
>  #include <hurd/netfs.h>
> 
> -/* do a DNS lookup for NAME and store result in *ENT */
> -error_t lookup_host (char *url, struct hostent **ent)
> +struct curl_read_request {
> + char *buffer;
> + loff_t offset;
> +};
> +
> +static size_t curl_write_response_to_buffer(char *data, size_t size,
> size_t nmemb, void *userdata)
>  {

Please fix your mailer, it has mangled the tab characters, so that your
patch cannot be applied, and the source code is very hard to read
without the identation.

Samuel

> - if ( (*ent = gethostbyname(url)) == NULL )
> - {
> - fprintf(stderr,"wrong host name\n");
> - return EINVAL;
> + struct curl_read_request *request = (struct curl_read_request *) userdata;
> + if (!request) {
> + return 0;
>   }
> - return 0;
> +
> + size_t total_size = size * nmemb - request->offset;
> + if (total_size == 0) {
> + return 0;
> + }
> +
> + memcpy(request->buffer, data + request->offset, total_size);
> +
> + return total_size;
>  }
> 
>  /* open a connection with the remote web server */
> -error_t open_connection(struct netnode *node, int *fd,off_t *head_len)
> +error_t open_connection(struct netnode *node, char *buffer, loff_t
> offset, off_t *head_len)
>  {
>   /* HTTP GET command returns head and body so we have to prune the
>   * head. *HEAD_LEN indicates the header length, for pruning upto that */
> -
> - error_t err;
> - struct hostent *hptr;
> - struct sockaddr_in dest;
> - ssize_t written;
> - size_t towrite;
> - char buffer[4096];
> - ssize_t bytes_read;
> - char *token,*mesg;
> - int code;
> - char delimiters0[] = " ";
> - char delimiters1[] = "\n";
> + error_t err = 0;
> + long http_status_code = 200;
> + double http_content_length = 0.0f;
> + CURLcode curl_err = CURLE_OK;
> + struct curl_read_request request;
> 
> - bzero(&dest,sizeof(dest));
> - dest.sin_family = AF_INET;
> - dest.sin_port = htons (port);
> + request.buffer = buffer;
> + request.offset = offset;
> 
> - if ( !strcmp(ip_addr,"0.0.0.0") )
> - {
> - /* connection is not through a proxy server
> - * find IP addr. of remote server */
> - err = lookup_host (node->url, &hptr);
> - if (err)
> - {
> - fprintf(stderr,"Could not find IP addr %s\n",node->url);
> - return err;
> - }
> - dest.sin_addr = *(struct in_addr *)hptr->h_addr;
> + CURL *curl = curl_easy_init();
> + if (!curl) {
> + return (err = ENOMEM);
>   }
> - else
> - {
> - /* connection is through the proxy server
> - * need not find IP of remote server
> -         * find IP of the proxy server */
> - if ( inet_aton(ip_addr,&dest.sin_addr) == 0 )
> - {
> - fprintf(stderr,"Invalid IP for proxy\n");
> - return -1;
> - }
> +
> + if (!strcmp(ip_addr, "0.0.0.0")) {
> + /* Connection is not through a proxy server. Do nothing. */
> + } else {
> + /* Connection is through a proxy server. */
> + curl_easy_setopt(curl, CURLOPT_PROXY, ip_addr);
>   }
> 
> + curl_easy_setopt(curl, CURLOPT_URL, node->url);
> + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
> curl_write_response_to_buffer);
> + curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
> + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
> +
>   if (debug_flag)
>   fprintf (stderr, "trying to open %s:%d/%s\n", node->url,
>   port, node->conn_req);
> 
> - *fd = socket (AF_INET, SOCK_STREAM, 0);
> - if (*fd == -1)
> - {
> - fprintf(stderr,"Socket creation error\n");
> - return errno;
> + curl_err = curl_easy_perform(curl);
> + if (curl_err != CURLE_OK) {
> + fprintf (stderr, "curl_easy_perform(): %s\n", curl_easy_strerror(curl_err));
> + err = EAGAIN;
> + goto cleanup;
>   }
> 
> - err = connect (*fd, (struct sockaddr *)&dest, sizeof (dest));
> - if (err == -1)
> - {
> - fprintf(stderr,"Cannot connect to remote host\n");
> - return errno;
> + curl_err = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, 
> &http_status_code);
> + if (curl_err != CURLE_OK) {
> + fprintf(stderr, "Cannot get HTTP status code: %s\n",
> curl_easy_strerror(curl_err));
> + err = EAGAIN;
> + goto cleanup;
> + } else if (http_status_code != 200) {
> + fprintf(stderr, "HTTP status code is: %ld\n", http_status_code);
> + err = EIO;
> + goto cleanup;
>   }
> 
> - /* Send a HEAD request find header length */
> - sprintf(buffer,"HEAD %s HTTP/1.0\r\nHost:
> %s\r\n\r\n",node->conn_req,node->url);
> - towrite = strlen (buffer);
> - written = TEMP_FAILURE_RETRY (write (*fd, buffer, towrite));
> - if ( written == -1 || written < towrite )
> - {
> - fprintf(stderr,"Could not send an HTTP request to host\n");
> - return errno;
> - }
> -
> - bytes_read = read(*fd,buffer,sizeof(buffer));
> - if ( bytes_read < 0 )
> - {
> - fprintf(stderr,"Error with HEAD read\n");
> - return errno;
> + curl_err = curl_easy_getinfo(curl,
> CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &http_content_length);
> + if (curl_err != CURLE_OK) {
> + fprintf(stderr, "Could not determine HTTP content length: %s\n",
> curl_easy_strerror(curl_err));
> + err = EIO;
> + goto cleanup;
>   }
> 
> - *head_len = bytes_read;
> - token = strtok(buffer,delimiters0);
> - token = strtok(NULL,delimiters0);
> - sscanf(token,"%d",&code);
> - token = strtok(NULL,delimiters1);
> - mesg = strdup(token);
> - if ( code != 200 )
> - {
> - /* page does not exist */
> - fprintf(stderr,"Error Page not Accesible\n");
> - fprintf(stderr,"%d %s\n",code,mesg);
> - return EBADF;
> - }
> -
> - close(*fd);
> -
> - /* Send the GET request for the url */
> - *fd = socket (AF_INET, SOCK_STREAM, 0);
> - if (*fd == -1)
> - {
> - fprintf(stderr,"Socket creation error\n");
> - return errno;
> - }
> -
> - err = connect (*fd, (struct sockaddr *)&dest, sizeof (dest));
> - if (err == -1)
> - {
> - fprintf(stderr,"Cannot connect to remote host\n");
> - return errno;
> - }
> + *head_len = (off_t) http_content_length;
> 
> - towrite = strlen (node->comm_buf);
> + err = 0;
> + goto cleanup;
> 
> - /* guard against EINTR failures */
> - written = TEMP_FAILURE_RETRY (write (*fd, node->comm_buf, towrite));
> - written += TEMP_FAILURE_RETRY (write (*fd, "\n\n",  2));
> - if (written == -1 || written < (towrite+2))
> - {
> - fprintf(stderr,"Could not send GET request to remote host\n");
> - return errno;
> - }
> - return 0;
> + cleanup:
> + curl_easy_cleanup(curl);
> + return err;
>  }
> 
>  /* fetch a directory node from the web server
> diff --git a/httpfs.c b/httpfs.c
> index 2da7f0d..67a2b6d 100644
> --- a/httpfs.c
> +++ b/httpfs.c
> @@ -42,6 +42,12 @@ main (int argc, char **argv)
>    mode = 1; /* means directory */
>    ip_addr = strdup ("0.0.0.0");
> 
> +  CURLcode curl_err = CURLE_OK;
> +  curl_err = curl_global_init(CURL_GLOBAL_ALL);
> +  if (curl_err != CURLE_OK) {
> +    error (1, 0, "libcurl cannot be initialized.");
> +  }
> +
>    if (debug_flag)
>      fprintf (stderr, "pid %d\n", getpid ());
>    httpfs_parse_args (argc, argv);
> @@ -165,5 +171,6 @@ main (int argc, char **argv)
> 
>    /* NOT REACHED */
>    free (httpfs);
> +  curl_global_cleanup();
>    return 0;
>  }
> diff --git a/httpfs.h b/httpfs.h
> index 3b54e48..1ab0669 100644
> --- a/httpfs.h
> +++ b/httpfs.h
> @@ -21,6 +21,8 @@
>  #include <sys/stat.h>
>  #include <netdb.h>
> 
> +#include <curl/curl.h>
> +
>  #include <hurd/hurd_types.h>
> 
>  #include "config.h"
> @@ -92,7 +94,7 @@ error_t lookup_host (char *url, struct hostent **ent);
> 
>  /* store the remote socket in *FD and establish the connection and send the
>   * http GET request */
> -error_t open_connection(struct netnode *node, int *fd,off_t *head_len);
> +error_t open_connection(struct netnode *node, char *buffer, loff_t
> offset, off_t *head_len);
> 
>  /* make an instance of `struct netnode' with the specified parameters,
>   * return NULL on error */
> diff --git a/netfs.c b/netfs.c
> index 0b49d93..e0e6b4b 100644
> --- a/netfs.c
> +++ b/netfs.c
> @@ -464,18 +464,16 @@ error_t netfs_attempt_readlink (struct iouser
> *user, struct node *node,
>  error_t netfs_attempt_read (struct iouser *cred, struct node *node,
>             loff_t offset, size_t *len, void *data)
>  {
> - error_t err;
> - static int remote_fd;
> + error_t err = 0;
>   char buffer[4096];
>   int bytes_read;
>   off_t head_len;
> 
>   if ( offset==0) {
> - err = open_connection (node->nn, &remote_fd,&head_len);
> + err = open_connection (node->nn, buffer, offset, &head_len);
>   if (err)
>   return err;
> - bytes_read = pread(remote_fd, buffer, sizeof(buffer), offset);
> - memcpy(data,(void 
> *)(buffer+head_len),sizeof(buffer)-(sizeof(char)*head_len));
> + bytes_read = strlen(buffer) + head_len;
>   if (bytes_read < 0)
>   err = errno;
>   else {
> @@ -486,8 +484,7 @@ error_t netfs_attempt_read (struct iouser *cred,
> struct node *node,
>   }
> 
>   else {
> - bzero(buffer,sizeof(buffer));
> - bytes_read = pread(remote_fd, data, sizeof(buffer), offset);
> + bytes_read = strlen(buffer) + head_len;
>   if (bytes_read < 0)
>   err = errno;
>   else {
> diff --git a/parsehtml.c b/parsehtml.c
> index 3bd202f..5f3ede0 100644
> --- a/parsehtml.c
> +++ b/parsehtml.c
> @@ -98,7 +98,6 @@ error_t parse(struct netnode *node)
>   /* SAX HTML Parsing Variables */
>   htmlSAXHandlerPtr emptysax = &empty;
>   error_t err;
> - static int remote_fd;
>   off_t head_len=0,offset=0;
>   char buffer[MAXBUF];
>   int bytes_read=0;
> @@ -125,20 +124,16 @@ error_t parse(struct netnode *node)
> 
>   /* get the HTML stream corresponding to the directory
>   * send a GET request */
> - err = open_connection(node,&remote_fd,&head_len);
> + err = open_connection(node, buffer, offset, &head_len);
>   if ( err )
>   return err;
> - bytes_read = pread(remote_fd,buffer,sizeof(char)*6,offset);
> + bytes_read = strlen(buffer) + head_len;
> 
>   if ( bytes_read > 0 )
>   {
>   /* Parser operates in Push mode */
>   ctxt = 
> htmlCreatePushParserCtxt(emptysax,NULL,buffer,bytes_read,"abracabadra",0);
> //file name is irrelevant abracabadra
> -
> - while ( (bytes_read=pread(remote_fd,buffer,sizeof(buffer),offset)) > 0) {
> - htmlParseChunk(ctxt,buffer,bytes_read,0);
> - }
> - htmlParseChunk(ctxt,buffer,0,1);
> + htmlParseChunk(ctxt, buffer, bytes_read, 0);
>   doc = ctxt->myDoc;
>   htmlFreeParserCtxt(ctxt);
>   if ( doc != NULL )
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 2823d0a..dfb741b 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -2,7 +2,7 @@ check_PROGRAMS = test_httpfs
> 
>  test_httpfs_SOURCES = test_httpfs.c ../http.c ../parsehtml.c
> ../node.c ../extract.c ../netfs.c ../args.c ../globals.c
>  test_httpfs_CFLAGS = -I$(top_srcdir) $(CMOCKA_CFLAGS)
> -test_httpfs_LDFLAGS = -Wl,--wrap=gethostbyname -Wl,--export-dynamic
> +test_httpfs_LDFLAGS = -Wl,--wrap=curl_easy_init -Wl,--export-dynamic
>  test_httpfs_LDADD = $(CMOCKA_LIBS) $(MHD_LIBS) $(HTTPFS_SHARED_LIBS)
> 
>  TESTS = $(check_PROGRAMS)
> diff --git a/tests/test_httpfs.c b/tests/test_httpfs.c
> index bd2d65b..f46c8f5 100644
> --- a/tests/test_httpfs.c
> +++ b/tests/test_httpfs.c
> @@ -37,50 +37,31 @@
> 
>  #include "globals.h"
> 
> -struct hostent *__wrap_gethostbyname(const char *name) {
> -    assert_non_null(name);
> -
> -    if (strcmp(name, "www.example.com") == 0) {
> -        return (struct hostent *)mock();
> +/* http.c unit tests */
> +CURL *__wrap_curl_easy_init(int is_curl_null) {
> +    if (is_curl_null == 1) {
> +        return NULL;
>      }
> 
> -    return (struct hostent *)mock();
> +    return (CURL *)mock();
>  }
> 
> -/* http.c unit tests */
> -static void test_lookup_host_1(void **state) {
> +static void test_open_connection_curl_easy_init_fails(void **state)
> +{
>      (void) state;
> 
> -    struct hostent mock_hostent;
> -    memset(&mock_hostent, 0, sizeof(mock_hostent));
> -    mock_hostent.h_name = "www.example.com";
> -
> -    will_return(__wrap_gethostbyname, &mock_hostent);
> -
> -    struct hostent *result = NULL;
> -    int ret = lookup_host("www.example.com", &result);
> -
> -    assert_int_equal(ret, 0);
> -    assert_non_null(result);
> -    assert_string_equal(result->h_name, "www.example.com");
> -}
> -
> -static void test_lookup_host_2(void **state) {
> -    (void) state;
> +    CURL *mock_curl;
> 
> -    will_return(__wrap_gethostbyname, NULL);
> +    will_return(__wrap_curl_easy_init, NULL);
> 
> -    struct hostent *result = NULL;
> -    int ret = lookup_host("invalid.url", &result);
> +    error_t err = open_connection(NULL, NULL, 0, NULL);
> 
> -    assert_int_equal(ret, EINVAL);
> -    assert_null(result);
> +    assert_int_equal(err, ENOMEM);
>  }
> 
>  int main(void) {
>      const struct CMUnitTest tests[] = {
> -        cmocka_unit_test(test_lookup_host_1),
> -        cmocka_unit_test(test_lookup_host_2),
> +        cmocka_unit_test(test_open_connection_curl_easy_init_fails),
>      };
> 
>      return cmocka_run_group_tests(tests, NULL, NULL);
> -- 
> 2.56.0
> 

-- 
Samuel
>       dvips -o $@ $<     
Faut faire gffe de pas te couper avec ton truc, t'as mis des ciseaux ($<)
partout :))
-+- Dom in Guide du linuxien pervers - "J'aime pas les Makefile !" -+-

Reply via email to