root/lang/perl/MENTA/trunk/lib/MENTA/Dispatch.pm @ 25407

Revision 25407, 2.9 kB (checked in by tokuhirom, 4 years ago)

package main; はやっぱりいろいろめんどいので、やめる。

Line 
1package MENTA::Dispatch;
2use strict;
3use warnings;
4use utf8;
5
6sub dispatch {
7    my $path = $ENV{PATH_INFO} || '/';
8    $path =~ s!^/+!!g;
9    $path ||= 'index';
10    if ($path =~ m{^[a-z0-9_/]+$}) {
11        my $cdir = MENTA::controller_dir();
12        my $controller = "${cdir}/${path}.pl";
13        my $controller_mt = "${cdir}/${path}.mt";
14        if (-f $controller) {
15            my $meth = $path;
16            $meth =~ s!^.+/!!;
17            $meth = "do_$meth";
18            package main;
19            do $controller;
20            if (my $e = $@) {
21                if (ref $e) {
22                    return;
23                } else {
24                    die $e;
25                }
26            }
27            die $@ if $@;
28            if (my $code = main->can($meth)) {
29                $code->();
30                die "なにも出力してません";
31            } else {
32                die "「${path}」というモードは存在しません!${controller} の中に ${meth} が定義されていないようです";
33            }
34        } elsif (-f $controller_mt) {
35            MENTA::Util::require_once('MENTA/TemplateLoader.pm');
36            my $tmpldir = MENTA::controller_dir();
37            my $out = MENTA::TemplateLoader::__load("${tmpldir}/${path}.mt", MENTA::controller_dir());
38            $out = MENTA::Util::encode_output($out);
39            MENTA::finalize($out);
40        } else {
41            die "「${path}」というモードは存在しません。コントローラファイルもありません(${controller})。テンプレートファイルもありません(${controller_mt})";
42        }
43    } elsif ($path ne 'menta.cgi' && -f "app/$path" && $path =~ /^static\//) {
44        show_static("app/$path");
45    } elsif ($path =~ /^(?:crossdomain\.xml|favicon\.ico|robots\.txt)$/) {
46        print "status: 404\r\ncontent-type: text/plain\r\n\r\n";
47    } else {
48        die "'${path}' を処理する方法がわかりません";
49    }
50}
51
52sub show_static {
53    my $path = shift;
54    MENTA::Util::require_once('Cwd.pm');
55    MENTA::Util::require_once('File/Spec.pm');
56    $path = Cwd::realpath($path);
57    my $appdir = Cwd::realpath(File::Spec->catfile(Cwd::cwd(), 'app', 'static'));
58    if (index($path, $appdir) != 0) {
59        die "どうやら攻撃されているようだ: $path";
60    }
61    open my $fh, '<:raw', $path or die "ファイルを開けません: ${path}: $!";
62    binmode STDOUT;
63    printf "Content-Length: %d\r\n", -s $path;
64    printf "Content-Type: %s\r\n\r\n", guess_mime_type($path);
65    print do { local $/; <$fh> };
66    close $fh;
67}
68
69sub guess_mime_type {
70    my $ext = shift;
71    $ext =~ s/.+\.([^.]+)$/$1/;
72
73    # TODO should be moved to other.
74    my $mime_map = {
75        css  => 'text/css',
76        gif  => 'image/gif',
77        jpeg => 'image/jpeg',
78        jpg  => 'image/jpeg',
79        js   => 'application/javascript',
80        png  => 'image/png',
81        txt  => 'text/plain',
82    };
83    $mime_map->{$ext} || 'application/octet-stream';
84}
85
86"END OF MODULE";
Note: See TracBrowser for help on using the browser.