fixed rewind function in http.c
This commit is contained in:
parent
fb7c56b9c4
commit
c9ada27eb0
|
@ -1,3 +1,4 @@
|
||||||
tmp
|
tmp
|
||||||
*.o
|
*.o
|
||||||
mount-http-dir
|
mount-http-dir
|
||||||
|
*_test.txt
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -1,7 +1,7 @@
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-I. -Wall -Wextra -lgumbo -g
|
CFLAGS=-I. -Wall -Wextra -lgumbo -lcurl -g
|
||||||
DEPS =
|
DEPS =
|
||||||
OBJ = main.o link.o test.o
|
OBJ = main.o link.o test.o http.o
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
168
http.c
168
http.c
|
@ -55,37 +55,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include "http.h"
|
||||||
|
|
||||||
enum fcurl_type_e {
|
|
||||||
CFTYPE_NONE = 0,
|
|
||||||
CFTYPE_FILE = 1,
|
|
||||||
CFTYPE_CURL = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fcurl_data
|
|
||||||
{
|
|
||||||
enum fcurl_type_e type; /* type of handle */
|
|
||||||
union {
|
|
||||||
CURL *curl;
|
|
||||||
FILE *file;
|
|
||||||
} handle; /* handle */
|
|
||||||
|
|
||||||
char *buffer; /* buffer to store cached data*/
|
|
||||||
size_t buffer_len; /* currently allocated buffers length */
|
|
||||||
size_t buffer_pos; /* end of data in buffer*/
|
|
||||||
int still_running; /* Is background url fetch still in progress */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct fcurl_data URL_FILE;
|
|
||||||
|
|
||||||
/* exported functions */
|
|
||||||
URL_FILE *url_fopen(const char *url, const char *operation);
|
|
||||||
int url_fclose(URL_FILE *file);
|
|
||||||
int url_feof(URL_FILE *file);
|
|
||||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
|
|
||||||
char *url_fgets(char *ptr, size_t size, URL_FILE *file);
|
|
||||||
void url_rewind(URL_FILE *file);
|
|
||||||
|
|
||||||
/* we use a global one for convenience */
|
/* we use a global one for convenience */
|
||||||
static CURLM *multi_handle;
|
static CURLM *multi_handle;
|
||||||
|
@ -229,6 +201,26 @@ static int use_buffer(URL_FILE *file, size_t want)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void http_curl_start_fetching(URL_FILE *file)
|
||||||
|
{
|
||||||
|
/* lets start the fetch */
|
||||||
|
curl_multi_perform(multi_handle, &file->still_running);
|
||||||
|
|
||||||
|
if((file->buffer_pos == 0) && (!file->still_running)) {
|
||||||
|
/* if still_running is 0 now, we should return NULL */
|
||||||
|
|
||||||
|
/* make sure the easy handle is not in the multi handle anymore */
|
||||||
|
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
curl_easy_cleanup(file->handle.curl);
|
||||||
|
|
||||||
|
free(file);
|
||||||
|
|
||||||
|
file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
|
/* this code could check for URLs or types in the 'url' and
|
||||||
|
@ -259,22 +251,7 @@ URL_FILE *url_fopen(const char *url, const char *operation)
|
||||||
|
|
||||||
curl_multi_add_handle(multi_handle, file->handle.curl);
|
curl_multi_add_handle(multi_handle, file->handle.curl);
|
||||||
|
|
||||||
/* lets start the fetch */
|
http_curl_start_fetching(file);
|
||||||
curl_multi_perform(multi_handle, &file->still_running);
|
|
||||||
|
|
||||||
if((file->buffer_pos == 0) && (!file->still_running)) {
|
|
||||||
/* if still_running is 0 now, we should return NULL */
|
|
||||||
|
|
||||||
/* make sure the easy handle is not in the multi handle anymore */
|
|
||||||
curl_multi_remove_handle(multi_handle, file->handle.curl);
|
|
||||||
|
|
||||||
/* cleanup */
|
|
||||||
curl_easy_cleanup(file->handle.curl);
|
|
||||||
|
|
||||||
free(file);
|
|
||||||
|
|
||||||
file = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -438,6 +415,8 @@ 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);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* unknown or supported type - oh dear */
|
default: /* unknown or supported type - oh dear */
|
||||||
|
@ -445,102 +424,3 @@ void url_rewind(URL_FILE *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FGETSFILE "fgets.test"
|
|
||||||
#define FREADFILE "fread.test"
|
|
||||||
#define REWINDFILE "rewind.test"
|
|
||||||
|
|
||||||
/* Small main program to retrieve from a url using fgets and fread saving the
|
|
||||||
* output to two test files (note the fgets method will corrupt binary files if
|
|
||||||
* they contain 0 chars */
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
URL_FILE *handle;
|
|
||||||
FILE *outf;
|
|
||||||
|
|
||||||
size_t nread;
|
|
||||||
char buffer[256];
|
|
||||||
const char *url;
|
|
||||||
|
|
||||||
if(argc < 2)
|
|
||||||
url = "http://192.168.7.3/testfile";/* default to testurl */
|
|
||||||
else
|
|
||||||
url = argv[1];/* use passed url */
|
|
||||||
|
|
||||||
/* copy from url line by line with fgets */
|
|
||||||
outf = fopen(FGETSFILE, "wb+");
|
|
||||||
if(!outf) {
|
|
||||||
perror("couldn't open fgets output file\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = url_fopen(url, "r");
|
|
||||||
if(!handle) {
|
|
||||||
printf("couldn't url_fopen() %s\n", url);
|
|
||||||
fclose(outf);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(!url_feof(handle)) {
|
|
||||||
url_fgets(buffer, sizeof(buffer), handle);
|
|
||||||
fwrite(buffer, 1, strlen(buffer), outf);
|
|
||||||
}
|
|
||||||
|
|
||||||
url_fclose(handle);
|
|
||||||
|
|
||||||
fclose(outf);
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy from url with fread */
|
|
||||||
outf = fopen(FREADFILE, "wb+");
|
|
||||||
if(!outf) {
|
|
||||||
perror("couldn't open fread output file\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = url_fopen("testfile", "r");
|
|
||||||
if(!handle) {
|
|
||||||
printf("couldn't url_fopen() testfile\n");
|
|
||||||
fclose(outf);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
|
||||||
fwrite(buffer, 1, nread, outf);
|
|
||||||
} while(nread);
|
|
||||||
|
|
||||||
url_fclose(handle);
|
|
||||||
|
|
||||||
fclose(outf);
|
|
||||||
|
|
||||||
|
|
||||||
/* Test rewind */
|
|
||||||
outf = fopen(REWINDFILE, "wb+");
|
|
||||||
if(!outf) {
|
|
||||||
perror("couldn't open fread output file\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = url_fopen("testfile", "r");
|
|
||||||
if(!handle) {
|
|
||||||
printf("couldn't url_fopen() testfile\n");
|
|
||||||
fclose(outf);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
|
||||||
fwrite(buffer, 1, nread, outf);
|
|
||||||
url_rewind(handle);
|
|
||||||
|
|
||||||
buffer[0]='\n';
|
|
||||||
fwrite(buffer, 1, 1, outf);
|
|
||||||
|
|
||||||
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
|
||||||
fwrite(buffer, 1, nread, outf);
|
|
||||||
|
|
||||||
url_fclose(handle);
|
|
||||||
|
|
||||||
fclose(outf);
|
|
||||||
|
|
||||||
return 0;/* all done */
|
|
||||||
}
|
|
||||||
|
|
29
http.h
29
http.h
|
@ -1,9 +1,38 @@
|
||||||
#ifndef HTTP_H
|
#ifndef HTTP_H
|
||||||
#define HTTP_H
|
#define HTTP_H
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
enum fcurl_type_e {
|
||||||
|
CFTYPE_NONE = 0,
|
||||||
|
CFTYPE_FILE = 1,
|
||||||
|
CFTYPE_CURL = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum fcurl_type_e type; /* type of handle */
|
||||||
|
union {
|
||||||
|
CURL *curl;
|
||||||
|
FILE *file;
|
||||||
|
} handle; /* handle */
|
||||||
|
|
||||||
|
char *buffer; /* buffer to store cached data*/
|
||||||
|
size_t buffer_len; /* currently allocated buffers length */
|
||||||
|
size_t buffer_pos; /* end of data in buffer*/
|
||||||
|
int still_running; /* Is background url fetch still in progress */
|
||||||
|
} URL_FILE;
|
||||||
|
|
||||||
URL_FILE *url_fopen(const char *url, const char *operation);
|
URL_FILE *url_fopen(const char *url, const char *operation);
|
||||||
|
|
||||||
int url_fclose(URL_FILE *file);
|
int url_fclose(URL_FILE *file);
|
||||||
|
|
||||||
int url_feof(URL_FILE *file);
|
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! */
|
||||||
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
5
main.c
5
main.c
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
gumbo_test(argc, argv);
|
// gumbo_test(argc, argv);
|
||||||
url_test();
|
// url_test();
|
||||||
|
http_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
111
test.c
111
test.c
|
@ -5,7 +5,118 @@
|
||||||
|
|
||||||
#include "link.h"
|
#include "link.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
#include "http.h"
|
||||||
|
|
||||||
|
|
||||||
|
int http_test()
|
||||||
|
{
|
||||||
|
URL_FILE *handle;
|
||||||
|
FILE *outf;
|
||||||
|
|
||||||
|
size_t nread;
|
||||||
|
char buffer[256];
|
||||||
|
const char *url;
|
||||||
|
|
||||||
|
url = "http://127.0.0.1/~fangfufu/test.txt";
|
||||||
|
|
||||||
|
/* ---------------------------Test fgets ----------------------------*/
|
||||||
|
|
||||||
|
/* open the input file */
|
||||||
|
handle = url_fopen(url, "r");
|
||||||
|
if(!handle) {
|
||||||
|
printf("couldn't url_fopen() %s\n", url);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create the output file for fgets*/
|
||||||
|
outf = fopen("fgets_test.txt", "wb");
|
||||||
|
if(!outf) {
|
||||||
|
perror("couldn't open output file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy from url line by line with fgets */
|
||||||
|
while(!url_feof(handle)) {
|
||||||
|
url_fgets(buffer, sizeof(buffer), handle);
|
||||||
|
fwrite(buffer, 1, strlen(buffer), outf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close the handles for the fgets test*/
|
||||||
|
url_fclose(handle);
|
||||||
|
fclose(outf);
|
||||||
|
|
||||||
|
/* ---------------------------Test fread ----------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* open the input file again */
|
||||||
|
handle = url_fopen(url, "r");
|
||||||
|
if(!handle) {
|
||||||
|
printf("couldn't url_fopen() testfile\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create the output file for fread test*/
|
||||||
|
outf = fopen("fread_test.txt", "wb");
|
||||||
|
if(!outf) {
|
||||||
|
perror("couldn't open fread output file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy from url with fread */
|
||||||
|
do {
|
||||||
|
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
||||||
|
fwrite(buffer, 1, nread, outf);
|
||||||
|
} while(nread);
|
||||||
|
|
||||||
|
/* close the handles for the fgets test*/
|
||||||
|
url_fclose(handle);
|
||||||
|
fclose(outf);
|
||||||
|
|
||||||
|
/* ---------------------------Test rewind ----------------------------*/
|
||||||
|
/* open the input file again */
|
||||||
|
handle = url_fopen(url, "r");
|
||||||
|
if(!handle) {
|
||||||
|
printf("couldn't url_fopen() testfile\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create the output file for rewind test*/
|
||||||
|
outf = fopen("rewind_test.txt", "wb");
|
||||||
|
if(!outf) {
|
||||||
|
perror("couldn't open fread output file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy from url with fread */
|
||||||
|
do {
|
||||||
|
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
||||||
|
fwrite(buffer, 1, nread, outf);
|
||||||
|
} while(nread);
|
||||||
|
|
||||||
|
url_rewind(handle);
|
||||||
|
fprintf(outf, "\n-------------------\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the URL again after rewind:
|
||||||
|
* - copy from url line by line with fgets
|
||||||
|
*/
|
||||||
|
while(!url_feof(handle)) {
|
||||||
|
url_fgets(buffer, sizeof(buffer), handle);
|
||||||
|
fwrite(buffer, 1, strlen(buffer), outf);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0]='\n';
|
||||||
|
fwrite(buffer, 1, 1, outf);
|
||||||
|
|
||||||
|
nread = url_fread(buffer, 1, sizeof(buffer), handle);
|
||||||
|
fwrite(buffer, 1, nread, outf);
|
||||||
|
|
||||||
|
url_fclose(handle);
|
||||||
|
|
||||||
|
fclose(outf);
|
||||||
|
|
||||||
|
return 0;/* all done */
|
||||||
|
}
|
||||||
void url_test()
|
void url_test()
|
||||||
{
|
{
|
||||||
printf("--- start of url_test ---\n");
|
printf("--- start of url_test ---\n");
|
||||||
|
|
Loading…
Reference in New Issue