Range:-Header support
Andreas Kotes <[email protected]> Wed, 12 Jun 2002 16:04:41 +0200
| Newsgroups | gmane.comp.djb.publicfile |
|---|---|
| Message-ID | <[email protected]> |
Hi! there's no Range:-Header support for publicfile yet, I've hacked together a rudimentary version which runs with recent wgets. Please have a look at it and comment .. It may be included under the same license as publicfile, in case you want to. Regards Count -- Andreas Kotes - ICQ: 3741366 - The views expressed herein are (only) mine. Look to the future, because that is where you'll spend the rest of your life. -- George Burnsh -- OpenPGP Key 0x8F94C228
publicfile-0.52-range-support.diff
(text/plain, 3.5 KB)
diff -ur publicfile-0.52.orig/httpd.c publicfile-0.52/httpd.c
--- publicfile-0.52.orig/httpd.c Tue Nov 9 08:23:46 1999
+++ publicfile-0.52/httpd.c Wed Jun 12 15:59:19 2002
@@ -1,3 +1,4 @@
+#include <unistd.h>
#include "pathdecode.h"
#include "file.h"
#include "filetype.h"
@@ -51,6 +52,8 @@
stralloc host = {0};
stralloc path = {0};
stralloc ims = {0};
+stralloc range = { 0 };
+int rangedelim = 0;
int flagbody = 1;
char filebuf[1024];
@@ -105,6 +108,9 @@
void get(void)
{
+ unsigned long firstbyte = 0;
+ unsigned long lastbyte = 0;
+ unsigned long curbyte = 0;
unsigned long length;
int fd;
int r;
@@ -128,13 +134,44 @@
fd = file_open(fn.s,&mtime,&length,1);
if (fd == -1)
barf("404 ",error_str(errno));
+ lastbyte = length;
+
+ if (range.len && (protocolnum != 1))
+ barf ("500 ", "Range:-Header supported with HTTP/1.0 only. Strange, but true.");
+
+ if (byte_chr (range.s, range.len, ",") < range.len)
+ barf ("500 ", "Only single ranges supported.");
+
+ rangedelim = byte_chr (range.s, range.len, "-");
+ if (range.len && (range.s[0] == '-'))
+ barf ("500 ", "Ranges to the end of file not supported.");
+ scan_ulong (range.s, &firstbyte);
+ if (rangedelim+1 < range.len)
+ scan_ulong (range.s+rangedelim+1, &lastbyte);
+
+ if (lastbyte > length)
+ barf ("500 ", "Range extends beyond file length");
+
+ if (firstbyte > lastbyte)
+ barf ("500 ", "Range starts after its own end");
if (protocolnum > 0) {
tai_now(&now);
if (!httpdate(&mtimestr,&mtime)) _exit(21);
- if ((ims.len < mtimestr.len) || byte_diff(mtimestr.s,mtimestr.len,ims.s))
- header("200 ","OK");
- else {
+ if ((ims.len < mtimestr.len) || byte_diff(mtimestr.s,mtimestr.len,ims.s)) {
+ if (!range.len)
+ header("200 ","OK");
+ else {
+ header ("206 ", "Partial content");
+ out_puts ("Content-Range: bytes ");
+ out_put (strnum, fmt_ulong (strnum, firstbyte));
+ out_puts ("-");
+ out_put (strnum, fmt_ulong (strnum, lastbyte));
+ out_puts ("/");
+ out_put (strnum, fmt_ulong (strnum, length));
+ out_puts ("\r\n");
+ }
+ } else {
header("304 ","OK");
flagbody = 0;
}
@@ -152,19 +189,24 @@
out_puts("Transfer-Encoding: chunked\r\n");
else {
out_puts("Content-Length: ");
- out_put(strnum,fmt_ulong(strnum,length)); /* XXX: could change */
+ out_put (strnum, fmt_ulong (strnum, lastbyte - firstbyte)); /* XXX: could change */
out_puts("\r\n");
}
out_puts("\r\n");
}
if (protocolnum < 2) {
+ if (firstbyte)
+ curbyte = lseek (fd, firstbyte, SEEK_SET);
if (flagbody)
for (;;) {
r = read(fd,filebuf,sizeof filebuf);
if (r == -1) _exit(23);
if (r == 0) break;
+ if (curbyte + r > lastbyte) r = lastbyte-curbyte;
out_put(filebuf,r);
+ curbyte += r;
+ if (curbyte == lastbyte) break;
}
out_flush();
_exit(0);
@@ -227,6 +269,7 @@
if (!stralloc_copys(&path,"")) _exit(21);
if (!stralloc_copys(&protocol,"")) _exit(21);
if (!stralloc_copys(&ims,"")) _exit(21);
+ if (!stralloc_copys (&range, "")) _exit (21);
protocolnum = 2;
spaces = 0;
@@ -302,6 +345,8 @@
if (!stralloc_append(&host,&field.s[i])) _exit(21);
if (case_startb(field.s,field.len,"if-modified-since:"))
if (!stralloc_copyb(&ims,field.s + 18,field.len - 18)) _exit(21);
+ if (case_startb (field.s, field.len, "range: bytes="))
+ if (!stralloc_copyb (&range, field.s + 13, field.len - 13)) _exit (21);
field.len = 0;
}
if (!line.len) break;