2005-10-28
2005-10-28 11:58:55 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
c1413f5af65b3680eb9f6fadcbe5f307e5c4560d
(87 lines)
(+56/-31)
[
Show
| Annotate
]
Branch: 5.2
Ported fix for [bug 4040 (#4040)] from Roxen 4.0.
Rev: server/protocols/http.pike:1.476
2:
// Modified by Francesco Chemolli to add throttling capabilities.
// Copyright © 1996 - 2004, Roxen IS.
- constant cvs_version = "$Id: http.pike,v 1.475 2005/10/10 14:37:10 jonasw Exp $";
+ constant cvs_version = "$Id: http.pike,v 1.476 2005/10/28 11:58:55 grubba Exp $";
// #define REQUEST_DEBUG
#define MAGIC_ERROR
1511:
foreach(indices(heads), string h)
{
if(lower_case(h) == "content-type") {
- type = heads[h];
+ array(string)|string t = heads[h];
m_delete(heads, h);
-
+ if (arrayp(t)) type = t[-1];
+ else type = t;
}
}
if(id->request_headers["request-range"])
1665:
array err;
int tmp;
- string head_string="";
+
if (result)
file = result;
#ifdef PROFILE
1725:
if(file->type == "raw") file->raw = 1;
}
+ // Invariant part of header. (Cached)
+ // Contains the result line except for the protocol part.
+ // Note: Only a single CRLF as terminator.
+ string head_string="";
+
+ // Variant part of header.
+ // Currently the Date and Connection headers.
+ // Note: Terminated with a double CRLF.
+ string variant_string="";
+
+ // The full header block (prot + head_string + variant_string).
+ string full_headers="";
+
if(!file->raw && (prot != "HTTP/0.9"))
{
if (!sizeof (file) && multi_status)
1760:
mapping(string:string) heads = make_response_headers (file);
+ mapping(string:string) variant_heads = ([ "Date":"",
+ "Connection":"" ]) & heads;
+ m_delete(heads, "Date");
+ m_delete(heads, "Connection");
+
if (file->error == 200) {
int conditional;
if (none_match) {
1860:
}
}
- head_string = sprintf("%s %d %s\r\n", prot, file->error,
+ // FIXME: prot.
+ head_string = sprintf(" %d %s\r\n", file->error,
head_status || errors[file->error] || "");
// Must update the content length after the modifications of the
1872:
// close in that case.
if( file->error/100 == 2 && file->len <= 0 )
{
- heads->Connection = "close";
+ variant_heads->Connection = "close";
misc->connection = "close";
}
1913:
}
#endif
- if( mixed err = catch( head_string += Roxen.make_http_headers( heads ) ) )
+ if (mixed err = catch(head_string += Roxen.make_http_headers(heads, 1)))
{
#ifdef DEBUG
report_debug ("Roxen.make_http_headers failed: " +
1936:
}
head_string += "\r\n";
}
- conf->hsent += strlen(head_string);
+
+ variant_string = Roxen.make_http_headers(variant_heads);
+ full_headers = prot + head_string + variant_string;
+ conf->hsent += strlen(full_headers);
}
else
if(!file->type) file->type="text/plain";
1955: Inside #if defined(RAM_CACHE)
(prot != "HTTP/0.9") && !misc->no_proto_cache)
{
if( file->len>0 && // known length.
- ((file->len + strlen( head_string )) <
+ ((file->len + sizeof(head_string)) <
conf->datacache->max_file_size)
// vvv Relying on the interpreter lock from here.
&& misc->cachekey )
1969: Inside #if defined(RAM_CACHE)
MY_TRACE_LEAVE ("");
conf->datacache->set( raw_url, data,
([
- // We have to handle the date header.
+
"hs":head_string,
"key":misc->cachekey,
"etag":misc->etag,
1988:
#endif
if(!kept_alive &&
(file->len > 0) &&
- ((sizeof(head_string) + file->len) < (HTTP_BLOCKING_SIZE_THRESHOLD)))
+ ((sizeof(full_headers) + file->len) < (HTTP_BLOCKING_SIZE_THRESHOLD)))
{
// The first time we get a request, the output buffers will
// be empty. We can thus just do a single blocking write()
1996:
int s;
TIMER_END(send_result);
TIMER_START(blocking_write);
- string data = head_string;
+ string data = full_headers;
if (file->data)
data += file->data[..file->len-1];
if (file->file)
2015:
do_log( s );
return;
}
- if(strlen(head_string)) send(head_string);
+ if(strlen(full_headers)) send(full_headers);
if(file->data && strlen(file->data)) send(file->data, file->len);
if(file->file) send(file->file, file->len);
}
else
{
if( !kept_alive &&
- (strlen(head_string) < (HTTP_BLOCKING_SIZE_THRESHOLD)))
+ (strlen(full_headers) < (HTTP_BLOCKING_SIZE_THRESHOLD)))
{
#ifdef CONNECTION_DEBUG
werror ("HTTP: Response =================================================\n"
"%s\n",
- replace (sprintf ("%O", head_string),
+ replace (sprintf ("%O", full_headers),
({"\\r\\n", "\\n", "\\t"}),
({"\n", "\n", "\t"})));
#else
- REQUEST_WERR (sprintf ("HTTP: Send headers blocking %O", head_string));
+ REQUEST_WERR (sprintf ("HTTP: Send headers blocking %O",
+ full_headers));
#endif
- do_log( my_fd->write( head_string ) );
+ do_log( my_fd->write( full_headers ) );
return;
}
- send(head_string);
+ send(full_headers);
file->len = 1; // Keep those alive, please...
}
2398: Inside #if defined(RAM_CACHE)
((st = file_stat( file->rf )) && st->mtime == file->mtime ))
#endif
{
- string fix_date( string headers )
- {
- string a, b;
- if( sscanf( headers, "%sDate: %*s\n%s", a, b ) == 3 )
- return a+"Date: "+Roxen.http_date( predef::time(1) ) +"\r\n"+b;
- return headers;
- };
+ string full_headers = prot + file->hs +
+ Roxen.make_http_headers(([
+ "Date":Roxen.http_date(predef::time(1)),
+ "Connection":misc->connection ||
+ ([ "HTTP/1.1":"keep-alive" ])[prot] || "close",
+ ]));
MY_TRACE_LEAVE ("Using entry from ram cache");
- conf->hsent += strlen(file->hs);
+ conf->hsent += strlen(full_headers);
cache_status["protcache"] = 1;
- if( strlen( d ) < (HTTP_BLOCKING_SIZE_THRESHOLD) )
+ if( (sizeof(full_headers) + strlen(d)) <
+ (HTTP_BLOCKING_SIZE_THRESHOLD) )
{
TIMER_END(cache_lookup);
- do_log( my_fd->write( fix_date(file->hs)+d ) );
+ do_log( my_fd->write( ({ full_headers, d }) ));
}
else
{
TIMER_END(cache_lookup);
- send( fix_date(file->hs)+d );
+ send( full_headers );
+ send( d );
start_sender( );
}
return;