The pending comments are now stored in comments/.pending.
[gruta.git] / Gruta / CGI.pm
blob356c027f8e32d30dfde52d83b11682ec3a8a23f3
1 package Gruta::CGI;
3 use CGI;
4 use Carp;
6 sub vars {
7 return $_[0]->{cgi}->Vars();
10 sub upload_dirs {
11 return @{ $_[0]->{upload_dirs} };
14 sub http_headers {
15 my $self = shift;
16 my %headers = @_;
18 foreach my $k (keys(%headers)) {
19 $self->{http_headers}->{$k} = $headers{$k};
22 return $self->{http_headers};
25 sub cookie {
26 my $self = shift;
28 if (@_) {
29 $self->http_headers( 'Set-Cookie', shift );
32 return $ENV{HTTP_COOKIE};
35 sub status {
36 $_[0]->http_headers( 'Status', $_[1] );
39 sub redirect {
40 my $self = shift;
42 $self->http_headers('Location', $self->data->url(@_));
44 return $self;
47 sub data {
48 my $self = shift;
49 my $data = shift;
51 if (defined($data)) {
52 $self->{data} = $data;
55 return $self->{data};
59 sub upload {
60 my $self = shift;
61 my $dir = shift;
62 my $field = shift;
64 my $file = $self->{cgi}->param($field);
65 my ($basename) = ($file =~ /([^\/\\]+)$/);
67 if (! grep(/^$dir$/, $self->upload_dirs())) {
68 croak "Unauthorized upload directory $dir";
71 # create the directory
72 mkdir $dir;
74 my $filename = $dir . '/' . $basename;
76 open F, '>' . $filename or croak "Can't write $filename";
77 while(<$file>) {
78 print F $_;
81 close F;
85 sub new {
86 my $class = shift;
88 my $obj = bless( { @_ }, $class );
90 $obj->{charset} ||= 'UTF-8';
91 $obj->{min_size_for_gzip} ||= 10000;
93 $obj->{http_headers} = {
94 'Content-Type' => 'text/html; charset=' . $obj->{charset},
95 'X-Gateway-Interface' => $ENV{'GATEWAY_INTERFACE'},
96 'X-Server-Name' => $ENV{'SERVER_NAME'}
99 $obj->{upload_dirs} ||= [];
101 $obj->{cgi} = CGI->new();
103 return $obj;
107 sub run {
108 my $self = shift;
110 my $data = $self->data();
111 my $vars = $self->vars();
113 $data->template->cgi_vars($vars);
115 if ($ENV{REMOTE_USER} and my $u = $data->source->user($ENV{REMOTE_USER})) {
116 $data->auth( $u );
118 elsif (my $cookie = $self->cookie()) {
119 if (my ($sid) = ($cookie =~ /sid\s*=\s*(\d+)/)) {
120 $data->auth_from_sid( $sid );
124 my $st = 'INDEX';
126 if ($vars->{t}) {
127 $st = uc($vars->{t});
130 $st = 'INDEX' unless $st =~ /^[-\w0-9_]+$/;
132 # not identified nor users found?
133 if (!$data->auth() && ! $data->source->users()) {
135 # create the admin user
136 my $u = Gruta::Data::User->new(
137 id => 'admin',
138 is_admin => 1,
139 can_upload => 1,
140 username => 'Admin',
141 email => 'webmaster@localhost'
144 # set a random password (to be promptly changed)
145 $u->password(rand());
147 # insert the user
148 $data->source->insert_user($u);
150 # create a new session
151 my $session = Gruta::Data::Session->new(user_id => 'admin');
152 $u->source->insert_session($session);
154 $self->cookie('sid=' . $session->get('id'));
156 $data->auth($u);
157 $data->session($session);
159 $st = 'ADMIN';
162 my $body = undef;
164 eval { $body = $data->template->process( $st ) };
166 if ($@) {
167 $data->log($@);
168 # $self->redirect('INDEX');
170 $self->status(500);
171 $body = "<h1>500 Internal Server Error</h1><pre>$@</pre>";
173 # main processing failed
174 $self->{error} = 1;
177 $self->http_headers('X-BaseURL' => $self->data->base_url());
178 $self->http_headers('X-Powered-By' => 'Gruta ' . $self->data->version());
180 if (!$data->auth()) {
181 use Digest::MD5;
182 use Encode qw(encode_utf8);
184 my $md5 = Digest::MD5->new();
185 $md5->add(encode_utf8($body));
186 my $etag = $md5->hexdigest();
188 my $inm = $ENV{HTTP_IF_NONE_MATCH} || '';
190 if ($inm eq $etag) {
191 $self->status(304);
192 $body = '';
194 else {
195 $self->http_headers('ETag' => $etag);
199 # does the client accept compression?
200 if (length($body) > $self->{min_size_for_gzip} &&
201 $ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/) {
202 # compress!!
203 use Compress::Zlib;
205 if (my $cbody = Compress::Zlib::memGzip($body)) {
206 $self->http_headers('Content-encoding' => 'gzip');
207 $body = $cbody;
211 my $h = $self->http_headers();
212 foreach my $k (keys(%{ $h })) {
213 print $k, ': ', $h->{$k}, "\n";
215 print "\n";
217 print $body;