ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 

  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА














     АРХИВ :: Apache-Talk
Apache-Talk mailing list archive (apache-talk@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@lexa.ru

__
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)


 




Copyright © Lexa Software, 1996-2009.