Following patch addresses issue with httpfs2 and nginx web server. Please review and apply.
diff httpfs2.c httpfs2.c.new 111c111 < static void destroy_url_copy(void *); --- > // static void destroy_url_copy(void *); 405,424c405,424 < static int free_url(struct_url* url) < { < if(url->host) free(url->host); < url->host = 0; < if(url->path) free(url->path); < url->path = 0; < if(url->name) free(url->name); < url->name = 0; < #ifdef USE_AUTH < if(url->auth) free(url->auth); < url->auth = 0; < #endif < if(url->sock_type != SOCK_CLOSED) < close_client_force(url); < url->port = 0; < url->proto = 0; /* only after socket closed */ < url->file_size=0; < url->last_modified=0; < return 0; < } --- > // static int free_url(struct_url* url) > // { > // if(url->host) free(url->host); > // url->host = 0; > // if(url->path) free(url->path); > // url->path = 0; > // if(url->name) free(url->name); > // url->name = 0; > // #ifdef USE_AUTH > // if(url->auth) free(url->auth); > // url->auth = 0; > // #endif > // if(url->sock_type != SOCK_CLOSED) > // close_client_force(url); > // url->port = 0; > // url->proto = 0; /* only after socket closed */ > // url->file_size=0; > // url->last_modified=0; > // return 0; > // } 623a624 > 629c630 < --- > 632,633c633 < < { --- > { 649a650 > 906a908,909 > #include <string.h> > 926,934d928 < static ssize_t < parse_header(struct_url *url, const char * buf, ssize_t bytes, < const char * method, size_t * content_length, int expect) < { < /* FIXME check the header parser */ < int status; < const char * ptr = buf; < const char * end; < int seen_accept = 0, seen_length = 0, seen_close = 0; 936,938c930,931 < if (bytes <= 0) { < return -1; < } --- > #define HTTP_STATUS "HTTP/1.1 " > #define ERROR -1 940,945c933,934 < end = memchr(ptr, '\n', bytes); < if(!end) { < plain_report ( "reply does not contain newline!", method, buf, 0); < errno = EIO; < return -1; < } --- > static int check_end_of_header_and_get_len(const char * ptr, int bytes) { > const char * end; 950,953c939 < plain_report ("reply does not contain end of header!", < method, buf, bytes); < errno = EIO; < return -1; --- > return ERROR; 957a944,945 > return header_len; > } 959,974c947,952 < end = memchr(ptr, '\n', bytes); < char * http = "HTTP/1.1 "; < if(!mempref(ptr, http, end - ptr) || !isdigit( *(ptr + strlen(http))) ) { < plain_report ("reply does not contain status!", < method, buf, header_len); < errno = EIO; < return -1; < } < status = strtol( ptr + strlen(http), (char **)&ptr, 10); < if (status != expect) { < fprintf(stderr, "%s: %s: failed with status: %d%.*s.\n", < argv0, method, status, (end - ptr) - 1, ptr); < if (!strcmp("HEAD", method)) fwrite(buf, bytes, 1, stderr); /*DEBUG*/ < errno = EIO; < if (status == 404) errno = ENOENT; < return -1; --- > > > static int check_exists_http_status(const char * ptr, int bytes) { > char * end = memchr(ptr, '\n', bytes); > if(!mempref(ptr, HTTP_STATUS, end - ptr) || !isdigit( *(ptr + > strlen(HTTP_STATUS))) ) { > return ERROR; 975a954,955 > return 1; > } 977c957,962 < char * content_length_str = "Content-Length: "; --- > static int parse_http_status(const char * ptr) { > int status = strtol( ptr + strlen(HTTP_STATUS), (char **)&ptr, 10); > return status; > } > > static int check_http_accept_header(const char* buf, int bytes, int > header_len) { 979,983c964,990 < char * date = "Last-Modified: "; < char * close = "Connection: close"; < struct tm tm; < while(1) < { --- > const char * ptr = buf; > char * end = memchr(ptr, '\n', bytes); > int seen_accept; > while(1) > { > ptr = end+1; > if( !(ptr < buf + (header_len - 4))){ > if(! seen_accept){ > return ERROR; > } > return header_len; > } > end = memchr(ptr, '\n', bytes - (ptr - buf)); > if( mempref(ptr, accept, strlen(accept))) { > seen_accept = 1; > continue; > } > } > } > > static int check_http_content_len_header(const char* buf, int bytes, int > header_len, size_t * content_length) { > char * content_length_str = "Content-Length: "; > const char * ptr = buf; > int seen_length = 0; > char * end = memchr(ptr, '\n', bytes); > while(1) > { 986,991d992 < if(! seen_accept){ < plain_report("server must Accept-Range: bytes", < method, buf, 0); < errno = EIO; < return -1; < } 993,996c994 < plain_report("reply didn't contain Content-Length!", < method, buf, 0); < errno = EIO; < return -1; --- > return ERROR; 998,1001d995 < if(url->sock_type == SOCK_OPEN && !seen_close) < url->sock_type = SOCK_KEEPALIVE; < if(url->sock_type == SOCK_KEEPALIVE && seen_close) < url->sock_type = SOCK_OPEN; 1011,1013c1005,1023 < if( mempref(ptr, accept, end - ptr) ){ < seen_accept = 1; < continue; --- > } > } > > static void set_client_sock_http_connection(const char* buf, int bytes, int > header_len, struct_url * url, const char* method) { > char * date = "Last-Modified: "; > char * close = "Connection: close"; > const char * ptr = buf; > char * end = memchr(ptr, '\n', bytes); > int seen_close = 0; > struct tm tm; > while(1) > { > ptr = end+1; > if( !(ptr < buf + (header_len - 4))){ > if(url->sock_type == SOCK_OPEN && !seen_close) > url->sock_type = SOCK_KEEPALIVE; > if(url->sock_type == SOCK_KEEPALIVE && seen_close) > url->sock_type = SOCK_OPEN; > return; 1014a1025 > end = memchr(ptr, '\n', bytes - (ptr - buf)); 1032a1044,1108 > static int check_contain_newline(const char* ptr, int bytes) { > const char * end = memchr(ptr, '\n', bytes); > if(!end) { > return ERROR; > } > return 1; > } > > static ssize_t > parse_header(struct_url *url, const char * buf, ssize_t bytes, > const char * method, size_t * content_length, int expect) > { > const char * ptr = buf; > > if (bytes <= 0) { > return ERROR; > } > > if(check_contain_newline(ptr, bytes) == ERROR) { > plain_report ( "reply does not contain newline!", method, buf, 0); > errno = EIO; > return ERROR; > } > > size_t header_len; > if ((header_len = check_end_of_header_and_get_len(ptr, bytes)) == ERROR) { > plain_report ("reply does not contain end of header!", > method, buf, bytes); > errno = EIO; > return ERROR; > } > > if (check_exists_http_status(ptr, bytes) == ERROR) { > plain_report ("reply does not contain status!", > method, buf, header_len); > errno = EIO; > return ERROR; > } > > int status = parse_http_status(ptr); > if (status != expect) { > //fprintf(stderr, "%s: %s: failed with status: %d%.*s.\n", > // argv0, method, status); > if (!strcmp("HEAD", method)) fwrite(buf, bytes, 1, stderr); /*DEBUG*/ > errno = EIO; > if (status == 404) errno = ENOENT; > return ERROR; > } > > if (check_http_accept_header(buf, bytes, header_len) == ERROR) { > plain_report("server must Accept-Range: bytes", > method, buf, 0); > errno = EIO; > return ERROR; > } > if (check_http_content_len_header(buf, bytes, header_len, content_length) > == ERROR) { > plain_report("reply didn't contain Content-Length!", method, buf, 0); > errno = EIO; > return ERROR; > } > > set_client_sock_http_connection(buf, bytes, header_len, url, method); > return header_len; > } > 1178a1255 > -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org