[prev in list] [next in list] [prev in thread] [next in thread]
List: dav-cvs
Subject: [dav-checkins] CVS: mod_dav mod_dav.c
From: Greg Stein (CVS user) <gjscvs () nebula ! lyra ! org>
Date: 2000-05-28 10:48:42
[Download RAW message or body]
gjscvs 00/05/28 03:48:42
Modified: . mod_dav.c
Log:
add Content-Range support in the GET handling
Revision Changes Path
1.116 +75 -4 mod_dav/mod_dav.c
Index: mod_dav.c
===================================================================
RCS file: /home/cvsroot/mod_dav/mod_dav.c,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -r1.115 -r1.116
--- mod_dav.c 2000/05/27 20:32:08 1.115
+++ mod_dav.c 2000/05/28 10:48:42 1.116
@@ -806,6 +806,9 @@
dav_stream *stream;
dav_error *err;
void *buffer;
+ const char *range;
+ off_t range_start;
+ off_t range_end;
/* set up the HTTP headers for the response */
if ((err = (*resource->hooks->set_headers)(r, resource)) != NULL) {
@@ -815,14 +818,52 @@
return dav_handle_err(r, err, NULL);
}
+ /* use plain READ mode unless we see a Content-Range */
+ mode = DAV_MODE_READ;
+
+ range = ap_table_get(r->headers_in, "content-range");
+ if (range != NULL) {
+ char *dash;
+ char *slash;
+
+ range = ap_pstrdup(r->pool, range);
+ if (strncasecmp(range, "bytes ", 6) != 0
+ || (dash = strchr(range, '-')) == NULL
+ || (slash = strchr(range, '/')) == NULL) {
+ /* malformed header. ignore it (per S14.16 of RFC2616) */
+ range = NULL;
+ }
+ else {
+ *dash = *slash = '\0';
+ range_start = atol(range + 6);
+ range_end = atol(dash + 1);
+ if (range_end < range_start
+ || (slash[1] != '*' && atol(slash + 1) <= range_end)) {
+ /* invalid range. ignore it (per S14.16 of RFC2616) */
+ range = NULL;
+ }
+ else {
+ /* we now have a valid range */
+
+ /* use a read mode which is seekable */
+ mode = DAV_MODE_READ_SEEKABLE;
+
+ /* prep the output */
+ r->status = HTTP_PARTIAL_CONTENT;
+ ap_table_setn(r->headers_out,
+ "Content-Range",
+ ap_psprintf(r->pool, "bytes %ld-%ld/*",
+ range_start, range_end));
+ ap_set_content_length(r, range_end - range_start + 1);
+ }
+ }
+ }
+
if (r->header_only) {
ap_send_http_header(r);
return DONE;
}
- /* ### use DAV_MODE_READ_SEEKABLE if a Content-Range is present */
- mode = DAV_MODE_READ;
-
if ((err = (*resource->hooks->open_stream)(resource, mode,
&stream)) != NULL) {
/* ### assuming FORBIDDEN is probably not quite right... */
@@ -834,6 +875,15 @@
return dav_handle_err(r, err, NULL);
}
+ if (range != NULL
+ && (err = (*resource->hooks->seek_stream)(stream,
+ range_start)) != NULL) {
+ err = dav_push_error(r->pool, err->status, 0,
+ "Could not seek to beginning of the "
+ "specified Content-Range.", err);
+ return dav_handle_err(r, err, NULL);
+ }
+
/* all set. send the headers now. */
ap_send_http_header(r);
@@ -844,7 +894,15 @@
while (1) {
size_t amt;
- amt = DAV_READ_BLOCKSIZE;
+ if (range == NULL)
+ amt = DAV_READ_BLOCKSIZE;
+ else if ((range_end - range_start + 1) > DAV_READ_BLOCKSIZE)
+ amt = DAV_READ_BLOCKSIZE;
+ else {
+ /* note: range_end - range_start is an ssize_t */
+ amt = (size_t)(range_end - range_start + 1);
+ }
+
if ((err = (*resource->hooks->read_stream)(stream, buffer,
&amt)) != NULL) {
break;
@@ -858,6 +916,12 @@
break;
}
+ if (range != NULL) {
+ range_start += amt;
+ if (range_start > range_end)
+ break;
+ }
+
/* reset the timeout after a successful write */
ap_reset_timeout(r);
}
@@ -868,6 +932,13 @@
if (err != NULL)
return dav_handle_err(r, err, NULL);
+ /*
+ ** ### range_start should equal range_end+1. if it doesn't, then
+ ** ### we did not send enough data to the client. the client will
+ ** ### hang (and timeout) waiting for the data.
+ **
+ ** ### what to do? abort the connection?
+ */
return DONE;
}
_______________________________________________
dav-checkins maillist - dav-checkins@lyra.org
http://dav.lyra.org/mailman/listinfo/dav-checkins
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic