removed unnecessary code in http.c
This commit is contained in:
parent
c9ada27eb0
commit
63925a2832
5
Makefile
5
Makefile
|
@ -1,9 +1,8 @@
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-I. -Wall -Wextra -lgumbo -lcurl -g
|
CFLAGS= -Wall -Wextra -lgumbo -lcurl -g
|
||||||
DEPS =
|
|
||||||
OBJ = main.o link.o test.o http.o
|
OBJ = main.o link.o test.o http.o
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
mount-http-dir: $(OBJ)
|
mount-http-dir: $(OBJ)
|
||||||
|
|
225
http.c
225
http.c
|
@ -57,16 +57,12 @@
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* we use a global one for convenience */
|
/* we use a global one for convenience */
|
||||||
static CURLM *multi_handle;
|
static CURLM *multi_handle;
|
||||||
|
|
||||||
/* curl calls this routine to get more data */
|
/* curl calls this routine to get more data */
|
||||||
static size_t write_callback(char *buffer,
|
static size_t write_callback(char *buffer, size_t size,
|
||||||
size_t size,
|
size_t nitems, void *userp)
|
||||||
size_t nitems,
|
|
||||||
void *userp)
|
|
||||||
{
|
{
|
||||||
char *newbuff;
|
char *newbuff;
|
||||||
size_t rembuff;
|
size_t rembuff;
|
||||||
|
@ -82,8 +78,7 @@ static size_t write_callback(char *buffer,
|
||||||
if(newbuff == NULL) {
|
if(newbuff == NULL) {
|
||||||
fprintf(stderr, "callback buffer grow failed\n");
|
fprintf(stderr, "callback buffer grow failed\n");
|
||||||
size = rembuff;
|
size = rembuff;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* realloc succeeded increase buffer size*/
|
/* realloc succeeded increase buffer size*/
|
||||||
url->buffer_len += size - rembuff;
|
url->buffer_len += size - rembuff;
|
||||||
url->buffer = newbuff;
|
url->buffer = newbuff;
|
||||||
|
@ -96,6 +91,36 @@ static size_t write_callback(char *buffer,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t header_callback(char *buffer, size_t size,
|
||||||
|
size_t nitems, void *userp)
|
||||||
|
{
|
||||||
|
char *newbuff;
|
||||||
|
size_t rembuff;
|
||||||
|
|
||||||
|
URL_FILE *url = (URL_FILE *)userp;
|
||||||
|
size *= nitems;
|
||||||
|
|
||||||
|
rembuff = url->header_len - url->header_pos; /* remaining space in buffer */
|
||||||
|
|
||||||
|
if(size > rembuff) {
|
||||||
|
/* not enough space in buffer */
|
||||||
|
newbuff = realloc(url->header, url->header_len + (size - rembuff));
|
||||||
|
if(newbuff == NULL) {
|
||||||
|
fprintf(stderr, "callback buffer grow failed\n");
|
||||||
|
size = rembuff;
|
||||||
|
} else {
|
||||||
|
/* realloc succeeded increase buffer size*/
|
||||||
|
url->header_len += size - rembuff;
|
||||||
|
url->header = newbuff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&url->header[url->header_pos], buffer, size);
|
||||||
|
url->header_pos += size;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
/* use to attempt to fill the read buffer up to requested number of bytes */
|
/* use to attempt to fill the read buffer up to requested number of bytes */
|
||||||
static int fill_buffer(URL_FILE *file, size_t want)
|
static int fill_buffer(URL_FILE *file, size_t want)
|
||||||
{
|
{
|
||||||
|
@ -201,19 +226,19 @@ static int use_buffer(URL_FILE *file, size_t want)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void http_curl_start_fetching(URL_FILE *file)
|
static void start_fetching(URL_FILE *file)
|
||||||
{
|
{
|
||||||
/* lets start the fetch */
|
/* lets start the fetch */
|
||||||
curl_multi_perform(multi_handle, &file->still_running);
|
curl_multi_perform(multi_handle, &file->still_running);
|
||||||
|
|
||||||
if((file->buffer_pos == 0) && (!file->still_running)) {
|
if (url_feof(file)) {
|
||||||
/* if still_running is 0 now, we should return NULL */
|
/* if still_running is 0 now, we should return NULL */
|
||||||
|
|
||||||
/* make sure the easy handle is not in the multi handle anymore */
|
/* make sure the easy handle is not in the multi handle anymore */
|
||||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
curl_multi_remove_handle(multi_handle, file->handle);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
curl_easy_cleanup(file->handle.curl);
|
curl_easy_cleanup(file->handle);
|
||||||
|
|
||||||
free(file);
|
free(file);
|
||||||
|
|
||||||
|
@ -223,112 +248,83 @@ static void http_curl_start_fetching(URL_FILE *file)
|
||||||
|
|
||||||
URL_FILE *url_fopen(const char *url, const char *operation)
|
URL_FILE *url_fopen(const char *url, const char *operation)
|
||||||
{
|
{
|
||||||
/* this code could check for URLs or types in the 'url' and
|
URL_FILE *file;
|
||||||
basically use the real fopen() for standard files */
|
|
||||||
|
|
||||||
URL_FILE *file;
|
file = calloc(1, sizeof(URL_FILE));
|
||||||
(void)operation;
|
if (!file) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
file = calloc(1, sizeof(URL_FILE));
|
file->handle = curl_easy_init();
|
||||||
if(!file)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
file->handle.file = fopen(url, operation);
|
curl_easy_setopt(file->handle, CURLOPT_URL, url);
|
||||||
if(file->handle.file)
|
curl_easy_setopt(file->handle, CURLOPT_VERBOSE, 0L);
|
||||||
file->type = CFTYPE_FILE; /* marked as URL */
|
|
||||||
|
|
||||||
else {
|
for (const char *c = operation; *c; c++) {
|
||||||
file->type = CFTYPE_CURL; /* marked as URL */
|
switch (*c) {
|
||||||
file->handle.curl = curl_easy_init();
|
case 'r':
|
||||||
|
curl_easy_setopt(file->handle,
|
||||||
|
CURLOPT_WRITEDATA, file);
|
||||||
|
curl_easy_setopt(file->handle,
|
||||||
|
CURLOPT_WRITEFUNCTION, write_callback);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
curl_easy_setopt(file->handle,
|
||||||
|
CURLOPT_HEADERDATA, file);
|
||||||
|
curl_easy_setopt(file->handle,
|
||||||
|
CURLOPT_HEADERFUNCTION, header_callback);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "url_fopen: invalid operation %c", *c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
|
if (!multi_handle) {
|
||||||
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
|
multi_handle = curl_multi_init();
|
||||||
curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L);
|
}
|
||||||
curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
|
|
||||||
|
|
||||||
if(!multi_handle)
|
curl_multi_add_handle(multi_handle, file->handle);
|
||||||
multi_handle = curl_multi_init();
|
|
||||||
|
|
||||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
start_fetching(file);
|
||||||
|
|
||||||
http_curl_start_fetching(file);
|
return file;
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int url_fclose(URL_FILE *file)
|
CURLMcode url_fclose(URL_FILE *file)
|
||||||
{
|
{
|
||||||
int ret = 0;/* default is good return */
|
|
||||||
|
|
||||||
switch(file->type) {
|
|
||||||
case CFTYPE_FILE:
|
|
||||||
ret = fclose(file->handle.file); /* passthrough */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFTYPE_CURL:
|
|
||||||
/* make sure the easy handle is not in the multi handle anymore */
|
/* make sure the easy handle is not in the multi handle anymore */
|
||||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
CURLMcode ret = curl_multi_remove_handle(multi_handle, file->handle);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
curl_easy_cleanup(file->handle.curl);
|
curl_easy_cleanup(file->handle);
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* unknown or supported type - oh dear */
|
free(file->buffer);/* free any allocated buffer space */
|
||||||
ret = EOF;
|
free(file->header);
|
||||||
errno = EBADF;
|
free(file);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(file->buffer);/* free any allocated buffer space */
|
return ret;
|
||||||
free(file);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int url_feof(URL_FILE *file)
|
int url_feof(URL_FILE *file)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
return (!file->buffer_pos) && (!file->still_running);
|
||||||
|
|
||||||
switch(file->type) {
|
|
||||||
case CFTYPE_FILE:
|
|
||||||
ret = feof(file->handle.file);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFTYPE_CURL:
|
|
||||||
if((file->buffer_pos == 0) && (!file->still_running))
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* unknown or supported type - oh dear */
|
|
||||||
ret = -1;
|
|
||||||
errno = EBADF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
||||||
{
|
{
|
||||||
size_t want;
|
size_t want = nmemb * size;
|
||||||
|
|
||||||
switch(file->type) {
|
|
||||||
case CFTYPE_FILE:
|
|
||||||
want = fread(ptr, size, nmemb, file->handle.file);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFTYPE_CURL:
|
|
||||||
want = nmemb * size;
|
|
||||||
|
|
||||||
fill_buffer(file, want);
|
fill_buffer(file, want);
|
||||||
|
|
||||||
/* check if there's data in the buffer - if not fill_buffer()
|
/* check if there's data in the buffer - if not fill_buffer()
|
||||||
* either errored or EOF */
|
* either errored or EOF */
|
||||||
if(!file->buffer_pos)
|
if(!file->buffer_pos)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* ensure only available data is considered */
|
/* ensure only available data is considered */
|
||||||
if(file->buffer_pos < want)
|
if(file->buffer_pos < want)
|
||||||
want = file->buffer_pos;
|
want = file->buffer_pos;
|
||||||
|
|
||||||
/* xfer data to caller */
|
/* xfer data to caller */
|
||||||
memcpy(ptr, file->buffer, want);
|
memcpy(ptr, file->buffer, want);
|
||||||
|
@ -336,46 +332,33 @@ size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
||||||
use_buffer(file, want);
|
use_buffer(file, want);
|
||||||
|
|
||||||
want = want / size; /* number of items */
|
want = want / size; /* number of items */
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* unknown or supported type - oh dear */
|
return want;
|
||||||
want = 0;
|
|
||||||
errno = EBADF;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
return want;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *url_fgets(char *ptr, size_t size, URL_FILE *file)
|
char *url_fgets(char *ptr, size_t size, URL_FILE *file)
|
||||||
{
|
{
|
||||||
size_t want = size - 1;/* always need to leave room for zero termination */
|
size_t want = size - 1;/* always need to leave room for zero termination */
|
||||||
size_t loop;
|
size_t loop;
|
||||||
|
|
||||||
switch(file->type) {
|
|
||||||
case CFTYPE_FILE:
|
|
||||||
ptr = fgets(ptr, (int)size, file->handle.file);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFTYPE_CURL:
|
|
||||||
fill_buffer(file, want);
|
fill_buffer(file, want);
|
||||||
|
|
||||||
/* check if there's data in the buffer - if not fill either errored or
|
/* check if there's data in the buffer - if not fill either errored or
|
||||||
* EOF */
|
* EOF */
|
||||||
if(!file->buffer_pos)
|
if(!file->buffer_pos)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* ensure only available data is considered */
|
/* ensure only available data is considered */
|
||||||
if(file->buffer_pos < want)
|
if(file->buffer_pos < want)
|
||||||
want = file->buffer_pos;
|
want = file->buffer_pos;
|
||||||
|
|
||||||
/*buffer contains data */
|
/*buffer contains data */
|
||||||
/* look for newline or eof */
|
/* look for newline or eof */
|
||||||
for(loop = 0; loop < want; loop++) {
|
for(loop = 0; loop < want; loop++) {
|
||||||
if(file->buffer[loop] == '\n') {
|
if(file->buffer[loop] == '\n') {
|
||||||
want = loop + 1;/* include newline */
|
want = loop + 1;/* include newline */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xfer data to caller */
|
/* xfer data to caller */
|
||||||
|
@ -384,30 +367,16 @@ char *url_fgets(char *ptr, size_t size, URL_FILE *file)
|
||||||
|
|
||||||
use_buffer(file, want);
|
use_buffer(file, want);
|
||||||
|
|
||||||
break;
|
return ptr;/*success */
|
||||||
|
|
||||||
default: /* unknown or supported type - oh dear */
|
|
||||||
ptr = NULL;
|
|
||||||
errno = EBADF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;/*success */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void url_rewind(URL_FILE *file)
|
void url_rewind(URL_FILE *file)
|
||||||
{
|
{
|
||||||
switch(file->type) {
|
|
||||||
case CFTYPE_FILE:
|
|
||||||
rewind(file->handle.file); /* passthrough */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFTYPE_CURL:
|
|
||||||
/* halt transaction */
|
/* halt transaction */
|
||||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
curl_multi_remove_handle(multi_handle, file->handle);
|
||||||
|
|
||||||
/* restart */
|
/* restart */
|
||||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
curl_multi_add_handle(multi_handle, file->handle);
|
||||||
|
|
||||||
/* ditch buffer - write will recreate - resets stream pos*/
|
/* ditch buffer - write will recreate - resets stream pos*/
|
||||||
free(file->buffer);
|
free(file->buffer);
|
||||||
|
@ -415,12 +384,6 @@ void url_rewind(URL_FILE *file)
|
||||||
file->buffer_pos = 0;
|
file->buffer_pos = 0;
|
||||||
file->buffer_len = 0;
|
file->buffer_len = 0;
|
||||||
|
|
||||||
http_curl_start_fetching(file);
|
start_fetching(file);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* unknown or supported type - oh dear */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
http.h
29
http.h
|
@ -3,23 +3,22 @@
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
enum fcurl_type_e {
|
|
||||||
CFTYPE_NONE = 0,
|
|
||||||
CFTYPE_FILE = 1,
|
|
||||||
CFTYPE_CURL = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum fcurl_type_e type; /* type of handle */
|
CURL *handle; /* handle */
|
||||||
union {
|
|
||||||
CURL *curl;
|
int still_running; /* Is background url fetch still in progress */
|
||||||
FILE *file;
|
|
||||||
} handle; /* handle */
|
|
||||||
|
|
||||||
char *buffer; /* buffer to store cached data*/
|
char *buffer; /* buffer to store cached data*/
|
||||||
size_t buffer_len; /* currently allocated buffers length */
|
size_t buffer_len; /* currently allocated buffers length */
|
||||||
size_t buffer_pos; /* end of data in buffer*/
|
size_t buffer_pos; /* end of data in buffer*/
|
||||||
int still_running; /* Is background url fetch still in progress */
|
|
||||||
|
char *header; /* character array to store the header */
|
||||||
|
size_t header_len; /* the current header length */
|
||||||
|
size_t header_pos; /* end of header in buffer */
|
||||||
|
|
||||||
|
int accept_range; /* does it accept range request */
|
||||||
|
int content_length; /* the length of the content */
|
||||||
|
|
||||||
} URL_FILE;
|
} URL_FILE;
|
||||||
|
|
||||||
URL_FILE *url_fopen(const char *url, const char *operation);
|
URL_FILE *url_fopen(const char *url, const char *operation);
|
||||||
|
@ -30,7 +29,11 @@ int url_feof(URL_FILE *file);
|
||||||
|
|
||||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
|
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
|
||||||
|
|
||||||
/* \details This is probably not the function that you want to use! */
|
/*
|
||||||
|
* \brief fgets implemented using libcurl.
|
||||||
|
* \details This is probably not the function that you want to use,
|
||||||
|
* because it doesn't work well with binary!
|
||||||
|
*/
|
||||||
char *url_fgets(char *ptr, size_t size, URL_FILE *file);
|
char *url_fgets(char *ptr, size_t size, URL_FILE *file);
|
||||||
|
|
||||||
void url_rewind(URL_FILE *file);
|
void url_rewind(URL_FILE *file);
|
||||||
|
|
10
link.c
10
link.c
|
@ -71,14 +71,8 @@ void html_to_linklist(GumboNode *node, ll_t *links)
|
||||||
/* if it is valid, copy the link onto the heap */
|
/* if it is valid, copy the link onto the heap */
|
||||||
if (is_valid_link(href->value)) {
|
if (is_valid_link(href->value)) {
|
||||||
links->num++;
|
links->num++;
|
||||||
if (!links->link) {
|
links->link = realloc(links->link, links->num * sizeof(char *));
|
||||||
links->link = malloc(sizeof(char *));
|
links->type = realloc(links->type, links->num * sizeof(linktype *));
|
||||||
links->type = malloc(sizeof(linktype *));
|
|
||||||
} else {
|
|
||||||
links->link = realloc(links->link, links->num * sizeof(char *));
|
|
||||||
links->type = realloc(links->type,
|
|
||||||
links->num * sizeof(linktype *));
|
|
||||||
}
|
|
||||||
int i = links->num - 1;
|
int i = links->num - 1;
|
||||||
links->link[i] = malloc(strlen(href->value) * sizeof(char *));
|
links->link[i] = malloc(strlen(href->value) * sizeof(char *));
|
||||||
strcpy(links->link[i], href->value);
|
strcpy(links->link[i], href->value);
|
||||||
|
|
2
main.c
2
main.c
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
// gumbo_test(argc, argv);
|
// gumbo_test(argc, argv);
|
||||||
// url_test();
|
// url_test();
|
||||||
http_test();
|
http_test();
|
||||||
|
|
3
test.c
3
test.c
|
@ -22,7 +22,7 @@ int http_test()
|
||||||
/* ---------------------------Test fgets ----------------------------*/
|
/* ---------------------------Test fgets ----------------------------*/
|
||||||
|
|
||||||
/* open the input file */
|
/* open the input file */
|
||||||
handle = url_fopen(url, "r");
|
handle = url_fopen(url, "rh");
|
||||||
if(!handle) {
|
if(!handle) {
|
||||||
printf("couldn't url_fopen() %s\n", url);
|
printf("couldn't url_fopen() %s\n", url);
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -40,6 +40,7 @@ int http_test()
|
||||||
url_fgets(buffer, sizeof(buffer), handle);
|
url_fgets(buffer, sizeof(buffer), handle);
|
||||||
fwrite(buffer, 1, strlen(buffer), outf);
|
fwrite(buffer, 1, strlen(buffer), outf);
|
||||||
}
|
}
|
||||||
|
printf(handle->header);
|
||||||
|
|
||||||
/* close the handles for the fgets test*/
|
/* close the handles for the fgets test*/
|
||||||
url_fclose(handle);
|
url_fclose(handle);
|
||||||
|
|
Loading…
Reference in New Issue