index.fcgi 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/perl
  2. # Run Sidef code inside the browser (using FastCGI)
  3. use utf8;
  4. use 5.016;
  5. use strict;
  6. #use autodie;
  7. use CGI::Fast;
  8. use CGI qw(:standard -utf8);
  9. #use CGI::Carp qw(fatalsToBrowser);
  10. use Capture::Tiny qw(capture);
  11. use HTML::Entities qw(encode_entities);
  12. # Path where Sidef exists (when not installed)
  13. #use lib qw(/home/user/Sidef/lib);
  14. # Limit the size of Sidef scripts to 500KB
  15. $CGI::POST_MAX = 1024 * 500;
  16. use Sidef;
  17. binmode(STDOUT, ':utf8');
  18. sub compile {
  19. my ($sidef, $code) = @_;
  20. my $errors = '';
  21. local $SIG{__WARN__} = sub {
  22. $errors .= join("\n", @_);
  23. };
  24. local $SIG{__DIE__} = sub {
  25. $errors .= join("\n", @_);
  26. };
  27. my $ccode = eval { $sidef->compile_code($code, 'Perl') };
  28. return ($ccode, $errors);
  29. }
  30. sub execute {
  31. my ($sidef, $ccode) = @_;
  32. my $errors = '';
  33. local $SIG{__WARN__} = sub {
  34. $errors .= join("\n", @_);
  35. };
  36. local $SIG{__DIE__} = sub {
  37. $errors .= join("\n", @_);
  38. };
  39. my ($stdout, $stderr) = capture {
  40. alarm 5;
  41. $sidef->execute_perl($ccode);
  42. alarm(0);
  43. };
  44. return ($stdout, $errors . $stderr);
  45. }
  46. while (my $c = CGI::Fast->new) {
  47. print header(
  48. -charset => 'UTF-8',
  49. 'Referrer-Policy' => 'no-referrer',
  50. 'X-Frame-Options' => 'DENY',
  51. 'X-Xss-Protection' => '1; mode=block',
  52. 'X-Content-Type-Options' => 'nosniff',
  53. ),
  54. start_html(
  55. -lang => 'en',
  56. -title => 'Sidef Programming Language',
  57. -base => 'true',
  58. -meta => {
  59. 'keywords' => 'sidef programming language web interface',
  60. 'viewport' => 'width=device-width, initial-scale=1.0',
  61. },
  62. -style => [{-src => 'css/main.css'}],
  63. -script => [
  64. {
  65. -src => 'js/jquery-3.6.0.min.js',
  66. },
  67. {
  68. -src => 'js/tabby.js',
  69. },
  70. {
  71. -src => 'js/main.js',
  72. },
  73. ],
  74. );
  75. print h1("Sidef");
  76. print start_form(
  77. -method => 'POST',
  78. -action => $ENV{SCRIPT_NAME},
  79. 'accept-charset' => "UTF-8",
  80. ),
  81. textarea(
  82. -name => 'code',
  83. -default => 'Write your code here...',
  84. -rows => 10,
  85. -columns => 80,
  86. -onfocus => 'clearContents(this);',
  87. ),
  88. br, submit(-name => "Run!"), end_form;
  89. if (defined(my $code = $c->param('code'))) {
  90. # Replace any newline characters with "\n"
  91. $code =~ s/\R/\n/g;
  92. my $sidef = Sidef->new(name => '-');
  93. my ($ccode, $errors) = compile($sidef, $code);
  94. if ($errors ne '') {
  95. chomp($errors);
  96. print pre(encode_entities($errors));
  97. print hr;
  98. $errors = '';
  99. }
  100. if (defined($ccode)) {
  101. my ($output, $errors) = execute($sidef, $ccode);
  102. if ($errors ne "") {
  103. chomp($errors);
  104. print pre(encode_entities($errors));
  105. print hr;
  106. }
  107. if (defined $output and $output ne '') {
  108. print pre(encode_entities($output));
  109. }
  110. }
  111. }
  112. print end_html;
  113. }