Russian Apache Switch to English
Switch to Russian koi8-r
windows=1251
cp-866
iso8859-5
Russian Apache Как это работает Рекоммендации Где взять Как установить Как настроить Статус и поддержка
Краткий обзор FAQ Список рассылки Благодарности Поиск по серверу Powered by Russian Apache
Russian Apache mailing list archive (apache-rus@lists.lexa.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [apache-talk] mathopd ranges



On Wed, Dec 12, 2001 at 02:53:19PM +0300, Alex Tutubalin wrote:
> > > но есть ranges) или mathopd (есть keep-alive, но в публичной доступности
> > > нет ranges).
> > 
> > У меня есть. Кому нужно -- пишите. Или же могу прислать прямо сюда.
> 
> Давай прямо сюда - оно ляжет в архив и можно будет потом давать ссылку.

На всякий случай: условия использования -- такие же, как сам mathopd
(кажется, BSD-style).


> 
> 
> Алексей Тутубалин
> mailto: lexa@xxxxxxx

__
AT
diff -ur src-1.4b13/Makefile src/Makefile
--- src-1.4b13/Makefile	Mon Aug  6 22:40:10 2001
+++ src/Makefile	Tue Oct  9 17:47:31 2001
@@ -1,14 +1,14 @@
 BIN = mathopd
 CC = gcc
 CFLAGS = -O -Wall
-CPPFLAGS = 
+CPPFLAGS = -DPARTIAL_CONTENT
 LDFLAGS = 
 LIBS = -lcrypt
 PREFIX = /usr/local
 SBINDIR = $(PREFIX)/sbin
 
 # On Solaris, uncomment the following
-# CPPFLAGS = -DNEED_INET_ATON -DHAVE_CRYPT_H
+# CPPFLAGS = -DNEED_INET_ATON -DHAVE_CRYPT_H -DPARTIAL_CONTENT
 # LIBS = -lsocket -lnsl
 
 OBJS = base64.o cgi.o config.o core.o dump.o imap.o log.o main.o \
diff -ur src-1.4b13/core.c src/core.c
--- src-1.4b13/core.c	Mon Aug  6 22:40:10 2001
+++ src/core.c	Tue Oct  9 17:47:31 2001
@@ -405,6 +405,11 @@
 			cn->action = HC_CLOSING;
 			return;
 		}
+#ifdef PARTIAL_CONTENT
+		if (cn->r->status == 206)
+			cn->left = cn->r->range_length;
+		else
+#endif
 		cn->left = cn->r->content_length;
 		if (fill_connection(cn) == -1) {
 			cn->action = HC_CLOSING;
diff -ur src-1.4b13/dump.c src/dump.c
--- src-1.4b13/dump.c	Mon Aug  6 22:40:10 2001
+++ src/dump.c	Tue Oct  9 17:47:31 2001
@@ -44,6 +44,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 #include <fcntl.h>
 #include "mathopd.h"
 
diff -ur src-1.4b13/main.c src/main.c
--- src-1.4b13/main.c	Mon Aug  6 22:40:10 2001
+++ src/main.c	Tue Oct  9 17:47:31 2001
@@ -47,6 +47,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <pwd.h>
 #include <grp.h>
 #include <string.h>
diff -ur src-1.4b13/mathopd.h src/mathopd.h
--- src-1.4b13/mathopd.h	Mon Aug  6 22:40:10 2001
+++ src/mathopd.h	Tue Oct  9 17:47:31 2001
@@ -231,6 +231,13 @@
 	char newloc[PATHLEN];
 	const char *allowedmethods;
 	size_t location_length;
+#ifdef PARTIAL_CONTENT
+	char *in_range;
+	char *if_range_s;
+	time_t if_range;
+	long range_offset;
+	long range_length;
+#endif
 };
 
 struct connection {
diff -ur src-1.4b13/request.c src/request.c
--- src-1.4b13/request.c	Mon Aug  6 22:40:10 2001
+++ src/request.c	Tue Oct  9 17:47:31 2001
@@ -278,8 +278,20 @@
 	if (r->num_content >= 0) {
 		b += sprintf(b, "Content-type: %s\r\n", r->content_type);
 		cl = r->content_length;
+#ifdef PARTIAL_CONTENT
+		if (cl >= 0) {
+			if (r->status == 206)
+				b += sprintf(b, "Content-Range: bytes %ld-%ld/%ld\r\n"
+					"Content-Length: %ld\r\n",
+					r->range_offset, r->range_offset + r->range_length - 1, cl,
+					r->range_length);
+			else
+				b += sprintf(b, "Content-Length: %ld\r\n", cl);
+		}
+#else
 		if (cl >= 0)
 			b += sprintf(b, "Content-length: %ld\r\n", cl);
+#endif
 		if (r->last_modified)
 			b += sprintf(b, "Last-Modified: %s\r\n", rfctime(r->last_modified, gbuf));
 	}
@@ -524,6 +536,10 @@
 static int process_fd(struct request *r)
 {
 	int fd;
+#ifdef PARTIAL_CONTENT
+	int status_2xx;
+	char *range;
+#endif
 
 	if (r->path_args[0] && r->c->path_args_ok == 0 && (r->path_args[1] || r->isindex == 0)) {
 		r->error_file = r->c->error_404_file;
@@ -558,12 +574,78 @@
 		r->num_content = -1;
 		return 304;
 	}
+#ifdef PARTIAL_CONTENT
+	status_2xx = 200;
+	range = r->in_range;
+#define SKIP_SPACE(str) while(isspace(*(str))) (str)++
+	if (range && (!r->if_range_s || r->last_modified <= r->if_range) &&
+		!strncasecmp(range, "bytes=", 6))
+	{
+		long rv, cl;
+		
+		range += 6;
+		SKIP_SPACE(range);
+		cl = r->content_length;
+		r->range_offset = r->range_length = -1L;
+			
+		if (isdigit(*range)) {
+			rv = strtol(range, &range, 10);
+			SKIP_SPACE(range);
+			if (*range++ == '-') {
+				r->range_offset = rv;
+				SKIP_SPACE(range);
+				if (*range == '\0')
+					r->range_length = cl - r->range_offset;
+				else if (isdigit(*range)) {
+					rv = strtol(range, &range, 10);
+					SKIP_SPACE(range);
+					if (*range == '\0' && rv >= r->range_offset)
+						r->range_length = rv - r->range_offset + 1;
+				}
+			}
+		} else if (*range++ == '-') {
+			SKIP_SPACE(range);
+			if (isdigit(*range)) {
+				rv = strtol(range, &range, 10);
+				SKIP_SPACE(range);
+				if (*range == '\0') {
+					if (rv > cl) {
+						r->range_length = cl;
+						r->range_offset = 0;
+					} else {
+						r->range_length = rv;
+						r->range_offset = cl - rv;
+					}
+				}
+			}
+		}
+
+		if (r->range_offset >= 0 && r->range_length > 0) {
+			if (cl > r->range_offset) {
+				status_2xx = 206;
+				if (r->range_offset && lseek(fd, r->range_offset, SEEK_SET) != r->range_offset) {
+					lerror("lseek");
+					close(fd);
+					return 500;
+				}
+			} else {
+				log_d("range %s not satisfiable for %s", r->in_range, r->path_translated);
+				close(fd);
+				return 416;
+			}
+		}
+	}
+#endif
 	if (r->method == M_GET) {
 		fcntl(fd, F_SETFD, FD_CLOEXEC);
 		r->cn->rfd = fd;
 	} else
 		close(fd);
+#ifdef PARTIAL_CONTENT
+	return status_2xx;
+#else
 	return 200;
+#endif
 }
 
 static int add_fd(struct request *r, const char *filename)
@@ -830,6 +912,12 @@
 			r->in_content_type = s;
 		else if (!strcasecmp(l, "Content-length"))
 			r->in_content_length = s;
+#ifdef PARTIAL_CONTENT
+		else if (!strcasecmp(l, "Range") || !strcasecmp(l, "Request-Range"))
+			r->in_range = s;
+		else if (!strcasecmp(l, "If-Range") || !strcasecmp(l, "Range-If"))
+			r->if_range_s = s;
+#endif
 	}
 	s = r->method_s;
 	if (s == 0) {
@@ -897,7 +985,11 @@
 		else
 			r->cn->keepalive = s && strcasecmp(s, "Keep-Alive") == 0;
 	}
+#ifdef PARTIAL_CONTENT
+	if (r->method == M_GET || r->method == M_HEAD) {
+#else
 	if (r->method == M_GET) {
+#endif
 		s = r->ims_s;
 		if (s) {
 			i = timerfc(s);
@@ -907,6 +999,17 @@
 			}
 			r->ims = i;
 		}
+#ifdef PARTIAL_CONTENT
+		s = r->if_range_s;
+		if (s) {
+			i = timerfc(s);
+			if (i == -1) {
+				log_d("illegal date \"%s\" in If-Range", s);
+				return 400;
+			}
+			r->if_range = i;
+		}
+#endif
 	}
 	return 0;
 }
@@ -929,6 +1032,12 @@
 		r->status_line = "204 No Content";
 		send_message = 0;
 		break;
+#ifdef PARTIAL_CONTENT
+	case 206:
+		r->status_line = "206 Partial Content";
+		send_message = 0;
+		break;
+#endif
 	case 302:
 		r->status_line = "302 Moved";
 		break;
@@ -952,6 +1061,11 @@
 		r->status_line = "405 Method Not Allowed";
 		r->allowedmethods = "GET, HEAD";
 		break;
+#ifdef PARTIAL_CONTENT
+	case 416:
+		r->status_line = "416 Requested Range Not Satisfiable";
+		break;
+#endif
 	case 501:
 		r->status_line = "501 Not Implemented";
 		break;
@@ -992,6 +1106,11 @@
 		case 404:
 			b += sprintf(b, "The resource requested could not be found on this server.\n");
 			break;
+#ifdef PARTIAL_CONTENT
+		case 416:
+			b += sprintf(b, "None of the range-specifier values in the Range request-header field overlap the current extent of the selected resource.\n");
+			break;
+#endif
 		case 503:
 			b += sprintf(b, "The server is temporarily busy.\n");
 			break;
@@ -1049,6 +1168,11 @@
 	r->servername = 0;
 	r->allowedmethods = 0;
 	r->location_length = 0;
+#ifdef PARTIAL_CONTENT
+	r->in_range = 0;
+	r->if_range_s = 0;
+	r->if_range = 0;
+#endif
 }
 
 int process_request(struct request *r)





Спонсоры сайта:

[ Russian Apache ] [ Как это работает ] [ Рекомендации ] [ Где взять ] [ Как установить ] [ Как настроить ] [ Статус и поддержка ] [ Краткий обзор ] [ FAQ ] [ Список рассылки ] [ Благодарности ] [ Поиск по серверу ] [ Powered by Russian Apache ] [ Apache-talk archive ]

"Russian Apache" includes software developed by the Apache Group for use in the Apache HTTP server project (http://www.apache.org/) See Apache LICENSE.
Copyright (C) 1995-2001 The Apache Group. All rights reserved.
Copyright (C) 1996 Dm. Kryukov; Copyright (C) 1997-2009 Alex Tutubalin. Design (C) 1998 Max Smolev.