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 [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]