Hi, folks. I'm not a C# programmer, but for now I have the task of translating a short PHP script into C#, and I'm hoping someone here will be able to help me.
The goal of the script is to bundle and minify JS and CSS files on the fly. So, for example, I could write:
<link href="/bundle.aspx?file1.css&file2.css&file3.css">
<script src="/bundle.aspx?file1.js&file2.js&file3.js"></script>
And the response would be each of the requested files concatenated and minified.
But I'm not sure how I should even start. I'm not sure if I should extend System.Web.UI.Page, or if I should implement IHttpModule, or if I should do something else entirely. I'm hoping someone can at least get me started on the right track.
Below is the PHP script I'm working from.
<?php
// Get file list
$files = array();
foreach (explode('&', $_SERVER['QUERY_STRING']) as $file)
{
$files[] = urldecode($file);
}
/*
TODO: use cache if none of the requested files have been updated since cache was created (check modification times)
*/
// Ensure no funny file paths
foreach ($files as $file)
{
if (is_file("wwwroot/$file") and strpos(realpath("wwwroot/$file"), realpath('wwwroot')) !== 0)
{
bad_request();
}
}
// Determine if JS, CSS or something else is being requested
$reqJS = false;
$reqCSS = false;
$reqOther = false;
foreach ($files as $file)
{
$file = strtolower($file);
if (substr($file, -3) == '.js')
{
$reqJS = true;
}
elseif (substr($file, -4) == '.css')
{
$reqCSS = true;
}
else
{
$reqOther = true;
}
}
// Ensure only JS or only CSS files are requested
if ($reqJS and $reqCSS or ! $reqJS and ! $reqCSS or $reqOther)
{
bad_request();
}
// Set header
if ($reqJS)
{
header('Content-type: text/javascript');
}
else /* assume CSS */
{
header('Content-type: text/css');
}
// Get file data
$data = '';
foreach ($files as $file)
{
$file = "wwwroot/$file";
if (is_file($file))
{
$data .= file_get_contents($file);
}
}
// Compress data
// Fork the java process
$cmd = 'java -jar "' . realpath('bin/yuicompressor.jar') . '" --type ' . ($reqJS ? 'js' : 'css');
$descriptors = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$process = proc_open($cmd, $descriptors, $pipes);
if ($process === false)
{
internal_server_error();
}
// Feed the data to the compressor
fwrite($pipes[0], $data);
fclose($pipes[0]);
// Read back the compressed data
$compressed = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// Check for errors
$errors = stream_get_contents($pipes[2]);
fclose($pipes[2]);
// Close the process
$exitStatus = proc_close($process);
// Check if unsuccesful
if ($exitStatus != 0 or $errors != '')
{
internal_server_error();
}
/* TODO: cache compressed output */
echo $compressed;
function bad_request()
{
header('HTTP/1.1 400 Bad Request');
exit;
}
function internal_server_error()
{
header('HTTP/1.1 500 Internal Server Error');
exit;
}