Bug fix for sending partial files using ne_set_request_body_fd()

Lou Montulli lou at montulli.org
Thu Mar 11 16:03:34 EST 2010


Joe,

Thanks for the incredibly fast response.   I think that is the fastest bug fix turnaround I have ever seen.

BTW- I was using this to implement partial file PUT's using WebDav.   Surprisingly, the Apache Webdav module already has support for them.   When we did the initial design for ByteRange requests we didn't put much thought into PUT, only GET's. 

:lou

-----Original Message-----
From: Joe Orton [mailto:jorton at manyfish.co.uk] On Behalf Of Joe Orton
Sent: Thursday, March 11, 2010 2:36 AM
To: Lou Montulli
Cc: neon at lists.manyfish.co.uk
Subject: Re: Bug fix for sending partial files using ne_set_request_body_fd()

On Wed, Mar 10, 2010 at 05:22:22PM -0800, Lou Montulli wrote:
> The bug is caused by "body_fd_send()" not decrementing
> "req->body.file.remain" after reading from the file.    Eventually "read()"
> returns "0" when it reaches the end of the file, so this bug doesn't effect
> a full file send.

Ouch!  Good catch.  Thanks for the report and patch.  I'm going to 
commit something slightly more complex, which also adds handling of 
read() errors:

Index: src/ne_request.c
===================================================================
--- src/ne_request.c	(revision 1792)
+++ src/ne_request.c	(working copy)
@@ -1,6 +1,6 @@
 /* 
    HTTP request/response handling
-   Copyright (C) 1999-2009, Joe Orton <joe at manyfish.co.uk>
+   Copyright (C) 1999-2010, Joe Orton <joe at manyfish.co.uk>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -284,6 +284,8 @@
     ne_request *req = userdata;
 
     if (count) {
+        ssize_t ret;
+
         if (req->body.file.remain == 0)
             return 0;
 
@@ -292,7 +294,26 @@
          * and 64-bit off64_t: */
         if ((ne_off_t)count > req->body.file.remain)
             count = (size_t)req->body.file.remain;
-	return read(req->body.file.fd, buffer, count);
+        
+        ret = read(req->body.file.fd, buffer, count);
+        if (ret > 0) {
+            req->body.file.remain -= ret;
+            return ret;
+        }
+        else if (ret == 0) {
+            ne_set_error(req->session, 
+                         _("Premature EOF in request body file"));
+        }
+        else if (ret < 0) {
+            char err[200];
+            int errnum = errno;
+
+            ne_set_error(req->session, 
+                         _("Failed reading request body file: %s"),
+                         ne_strerror(errnum, err, sizeof err));
+        }
+
+        return -1;
     } else {
         ne_off_t newoff;
 





More information about the neon mailing list