Roxen.git
/
server
/
plugins
/
protocols
/
prot_https.pike
version
»
Context lines:
10
20
40
80
file
none
3
Roxen.git/server/plugins/protocols/prot_https.pike:1:
+
// This is a roxen protocol module.
+
// Copyright © 2001, Roxen IS.
-
+
// $Id: prot_https.pike,v 2.4 2001/08/23 05:33:44 nilsson Exp $
+
+
// --- Debug defines ---
+
+
#ifdef SSL3_DEBUG
+
# define SSL3_WERR(X) werror("SSL3: "+X+"\n")
+
#else
+
# define SSL3_WERR(X)
+
#endif
+
+
inherit SSLProtocol;
+
+
constant supports_ipless = 0;
+
constant name = "https";
+
constant prot_name = "https";
+
constant requesthandlerfile = "protocols/http.pike";
+
constant default_port = 443;
+
+
+
class fallback_redirect_request
+
{
+
string in = "";
+
string out;
+
string default_prefix;
+
int port;
+
Stdio.File f;
+
+
void die()
+
{
+
SSL3_WERR(sprintf("fallback_redirect_request::die()"));
+
f->close();
+
destruct(f);
+
destruct(this_object());
+
}
+
+
void write_callback(object id)
+
{
+
SSL3_WERR(sprintf("fallback_redirect_request::write_callback()"));
+
int written = id->write(out);
+
if (written <= 0)
+
die();
+
out = out[written..];
+
if (!strlen(out))
+
die();
+
}
+
+
void read_callback(object id, string s)
+
{
+
SSL3_WERR(sprintf("fallback_redirect_request::read_callback(X, \"%s\")\n", s));
+
in += s;
+
string name;
+
string prefix;
+
+
if (search(in, "\r\n\r\n") >= 0)
+
{
+
// werror("request = '%s'\n", in);
+
array(string) lines = in / "\r\n";
+
array(string) req = replace(lines[0], "\t", " ") / " ";
+
if (sizeof(req) < 2)
+
{
+
out = "HTTP/1.0 400 Bad Request\r\n\r\n";
+
}
+
else
+
{
+
if (sizeof(req) == 2)
+
{
+
name = req[1];
+
}
+
else
+
{
+
name = req[1..sizeof(req)-2] * " ";
+
foreach(map(lines[1..], `/, ":"), array header)
+
{
+
if ( (sizeof(header) >= 2) &&
+
(lower_case(header[0]) == "host") )
+
prefix = "https://" + header[1] - " ";
+
}
+
}
+
if (prefix) {
+
if (prefix[-1] == '/')
+
prefix = prefix[..strlen(prefix)-2];
+
prefix = prefix + ":" + port;
+
} else {
+
/* default_prefix (aka MyWorldLocation) already contains the
+
* portnumber.
+
*/
+
if (!(prefix = default_prefix)) {
+
/* This case is most unlikely to occur,
+
* but better safe than sorry...
+
*/
+
string ip = (f->query_address(1)/" ")[0];
+
prefix = "https://" + ip + ":" + port;
+
} else if (prefix[..4] == "http:") {
+
/* Broken MyWorldLocation -- fix. */
+
prefix = "https:" + prefix[5..];
+
}
+
}
+
out = sprintf("HTTP/1.0 301 Redirect to secure server\r\n"
+
"Location: %s%s\r\n\r\n", prefix, name);
+
}
+
f->set_read_callback(0);
+
f->set_write_callback(write_callback);
+
}
+
}
+
+
void create(object socket, string s, string l, int p)
+
{
+
SSL3_WERR(sprintf("fallback_redirect_request(X, \"%s\", \"%s\", %d)", s, l||"CONFIG PORT", p));
+
f = socket;
+
default_prefix = l;
+
port = p;
+
f->set_nonblocking(read_callback, 0, die);
+
f->set_id(f);
+
read_callback(f, s);
+
}
+
}
+
+
class http_fallback
+
{
+
object my_fd;
+
+
void ssl_alert_callback(object alert, object|int n, string data)
+
{
+
SSL3_WERR(sprintf("http_fallback(X, %O, \"%s\")", n, data));
+
// trace(1);
+
if ( (my_fd->current_write_state->seq_num == 0)
+
&& search(lower_case(data), "http"))
+
{
+
object raw_fd = my_fd->socket;
+
my_fd->socket = 0;
+
+
/* Redirect to a https-url */
+
// my_fd->set_close_callback(0);
+
// my_fd->leave_me_alone = 1;
+
fallback_redirect_request(raw_fd, data,
+
my_fd->config &&
+
my_fd->config->query("MyWorldLocation"),
+
port);
+
destruct(my_fd);
+
destruct(this_object());
+
// my_fd = 0; /* Forget ssl-object */
+
}
+
}
+
+
void ssl_accept_callback(object id)
+
{
+
SSL3_WERR(sprintf("ssl_accept_callback(X)"));
+
id->set_alert_callback(0); /* Forget about http_fallback */
+
my_fd = 0; /* Not needed any more */
+
}
+
+
void create(object fd)
+
{
+
my_fd = fd;
+
fd->set_alert_callback(ssl_alert_callback);
+
fd->set_accept_callback(ssl_accept_callback);
+
}
+
}
+
+
object accept()
+
{
+
object q = ::accept();
+
+
if (q) {
+
http_fallback(q);
+
}
+
return q;
+
}
+
+
int set_cookie, set_cookie_only_once;
+
void fix_cvars( Variable.Variable a )
+
{
+
set_cookie = query( "set_cookie" );
+
set_cookie_only_once = query( "set_cookie_only_once" );
+
}
+
+
void create( mixed ... args )
+
{
+
roxen.set_up_http_variables( this_object() );
+
if( variables[ "set_cookie" ] )
+
variables[ "set_cookie" ]->set_changed_callback( fix_cvars );
+
if( variables[ "set_cookie_only_once" ] )
+
variables[ "set_cookie_only_once" ]->set_changed_callback( fix_cvars );
+
fix_cvars(0);
+
::create( @args );
+
}
Newline at end of file added.