Accessing CSS  file located outside of server root

Posted on 2005-05-11
Last Modified: 2008-03-03
Linux HTTPD (apache).
Some experts are of the impression that access to files outside of the server root is not allowed by the (httpd) server. I have a number of PHP scripts that have no difficulty accessing a CSS file located outside of this server root through the HTML link tag and a symbolic link. The files render correctly except for the fact that I have a <BODY class="wp2"> in these scripts which doesn't render as expected, this "wp2" is defined in the CSS file and it works when used in another application.

Has anyone some experience and some hints in this respect?

Here are a few lines of code used in scripts and HTTPD
Document root in HTTPD is /home/meeting/chair
CSS file is /var/nobla/u1/h123.css
This HTML line is in every script <link rel=stylesheet type="text/css" href="h123.css">
This link is in every directory h123.css -> /var/nobla/u1/h123.css
The CSS file links class wp2 to  /var/nobla/i1/wp2.png

Thank you for your help
Question by:rblampain
    LVL 7

    Accepted Solution

    this is an interesting effect... but I wonder why you need to use the symbolic link like that? The whole point of having a 'document root' for HTTPD is that it gives you a place where you want the publicly available files to sit. Adding symlinks will of course work but it is messing up the tidiness of the directory structure.

    as for the wp2 thing, I would be almost certain that this was a problem to do with your HTML or CSS, rather than a weird phenomenom of some other sort. Post your HTML  and CSS and I'll take a look.

    LVL 7

    Expert Comment

    an alternative thing you could try would be to use the Apache 'Alias' directive instead of symlinks. Perhaps that will confirm that the symlink is doing nothing strange.
    LVL 7

    Expert Comment

    or better still, use AliasMatch just ONCE, and you won't need repeated symlinks...
    LVL 32

    Expert Comment

    If you can't access


    over http(i.e by an url in your browser), then you can't refer to any files there either.

    If this line:

    <link rel=stylesheet type="text/css" href="h123.css">

    is from an HTML file on your document root, then it refers to


    (Since /home/meeting/chair is your document root.).

    What you can do is to read the content of the css file and put it between a <style> and </style> tag.




    <style type="text/css">
    echo file_get_contents("/var/nobla/u1/h123.css");



    LVL 32

    Expert Comment

    sorry, didn't see the info regarding the symbolic link.

    If you open the css file in your browser(, do you see the "wp2" class there?

    If yes, then there's probably something wrong in your HTML code.

    LVL 1

    Expert Comment

    The only problem that i have experienced is that I need to put the full path to the css file

    <link rel=stylesheet type="text/css" href="">

    Other than that I have had no problems.
    LVL 7

    Expert Comment

    That shouldn't be required, if it's being hosted on the same server. You're not doing anything funny with multiple <VirtualHost>s are you?
    LVL 2

    Expert Comment

    you could also back out of directories...  "../../../../var/nobla/u1/h123.css"
    LVL 7

    Expert Comment

    You can't back up above the document root. Apache doesn't let you. Unless I'm very much mistaken...


    Author Comment

    Thank you all for your suggestions. A few answers to your comments/questions:
     jdpipe: ......why you need to use the symbolic link like that? We have 2 applications each using their own tailored instances of HTTPD but the rendering of pages is the same, therefore we use the same CSS file.  If there is a better way, I'd welcome it. I'd prefer not to have to copy this file for the second application if possible since this means 2 files to edit instead of one.
    I tried ALIAS in HTTPD conf but it doesn't work, it looks like it's designed to work at the directory level, not the file level. HTTPD is now looking for /documentroot/h123.css.
    ........ You're not doing anything funny with multiple <VirtualHost>s are you? Answer: NO.

    Batalf: yes, the wp2 class shows as expected

     Codeit1978:  it looks  like the use of CSS you're talking about is outside of the server (httpd), The full path you recommend would be added to the document root like this: "documentrootfullpath" which would lead us nowhere.

    Lance_Frisbee: this also seems to be outside the server
    I have 3 HTML scripts followed by a number of PHP scripts in this application, here is the first PHP script. The <body> tags in the HTML scripts do render properly using the same symlink. Only the <body> tags going through the HTTPD server do not render as intended.

    Note that the class is really "wp2cpng" not "wp2" as stated earlier.

    <? session_start(); ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html><head><title>Structure File part 1a</title>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <link rel=stylesheet type="text/css" href="h123.css">

    <body class="wp2cpng">
    <table class="tabl01"><tr><td width="100%">
    <div align="center"><h2>Locate File</h2>
    function create_struct0() {#f0
    # part 1 create array according to path - may be useless
     global $filename, $fyle, $fyle0, $aray, $cont, $ol, $li;
     $stringy=ltrim($filename, "/"); # remove first /
     $_SESSION['cont'] = $cont;
     for ($i=0; $i < $cont; $i++) {#f1
     $fyle .=  $ol . "<br>" . $li . $aray[$i] . "<br>";
     $fyle0 .= "<ol><li>" . $aray[$i];
     $ol="&nbsp;&nbsp;&nbsp;&nbsp;" . $ol;
     $li="&nbsp;&nbsp;&nbsp;&nbsp;" . $li;
     $_SESSION['fyle'] = $fyle;
     $_SESSION['fyle0'] = $fyle0;
     $_SESSION['ol'] = $ol;
     $_SESSION['li'] = $li;
     #echo $fyle;            #= constructed string to be saved & passed *******************
    if (isset($_POST['filename']))
      ### trim it for unwanted spaces or other
      ### add extension to structure filename
      $filenamestruct = $filename . ".struct";
      $_SESSION['filenamestruct'] = $filenamestruct;
      ### check is full path
      if (substr($filename,0,6) != "/home/")            
         {#0            ### adjust /home/ in real life ***  
         echo "Path is incorrect <br>";                  
            ### check main file exists, if struct file exists or not
               if (file_exists($filename))
                 ### check type of file: plain text or html  
                 $unstripped = file_get_contents($filename);
               $stripped = strip_tags($unstripped);
                if ($stripped != $unstripped) {#10
                  echo 'The file has been found, it is of type HTML (it is not PLAIN TEXT)<br>';
                      echo 'The file has been found, it is of type TEXT (it is not HTML)<br>';
                    if (file_exists($filenamestruct))
                       echo "The 'Structure File' exists for   " . $filename ."<br>";
                      <br><Form method = "post" action = "">
                      <input type="submit" value="Click Here To Edit it"></form>
                      Or click one option in the right panel.
                         echo "The 'Structure File' has to be created for <br> " . $filename . "<br><br>";
                         create_struct0();      # according to path - may be useless
                      <form action="struct1.htm" name="form1">
                      <input type="submit" value="If this is correct, click here to Continue">
                    echo "There is no such file as $filename <br>";

    <script type="text/javascript">
    document.write("Last Updated: "+document.lastModified);
    And here is the contents of the CSS file
    .tabl01 {

            border : none;

            margin-left : 12px;

            margin-right : 12px;


            text-align : left;


    .tac {text-align: center;}

    .cr {color: red;}

    .fsi {font-style: italic;}

    .cb {color: blue;}

    .c5 {color: red; font-size: 200%;}

    .c4 {color: red; font-size: 60%; font-style: italic;}

    .c2 {color: red; font-size: 80%;}

    /*dec 2003 raise a topic*/

    .gr  {color: green;}

    .gr1 {color: green; font-size: x-small;}

    .gr2 {color: green; font-size: small;}

    .rd  {color: red;}

    .rd1 {color: red; font-size: x-small;}

    .rd2 {color: red; font-size: small;}

    .pluie {background-image: url("/var/nobla/i1/anipluie.gif"); background-attachment : fixed; }

    .cloud1 { background-image: url("/var/nobla/i1/cloud1.gif");

            background-position: top left;

            background-repeat: repeat-x ;}

    .yel   {background-color: yellow; text-align: center;}

    .li     {background-color: lime; text-align:left;}

    .left { background-image: url("/var/nobla/i1/l.gif");

            background-position: top left;

            background-repeat: repeat-y ;}

    .middle { background-image: url("/var/nobla/i1/m.gif");

            background-position: top left;

            background-repeat: repeat-y ;}

    .right { background-image: url("/var/nobla/i1/r.gif");

            background-position: top left;

            background-repeat: repeat-y ;}

    h1,h2,h3,dt {color: green;}

    a.nodec {text-decoration: none;}

            a:link {color: #0000ff;}

            a:visited {color: #ff00ff;}

            a:active {color: black;}

    .hrul   {color: lime}

    .frul   {border-style: solid; height: 12px; color: #ffccff;}

    /*          wall papers    */

    .wp1 {background-image : url("/var/nobla/i1/wp1.gif"); background-attachment : fixed; border: 0;}

    .wp2 {background-image : url("/var/nobla/i1/wp2.gif"); background-attachment : fixed; border: 0;}

    .wp2a {background-image : url("/var/nobla/i1/wp2a.gif"); background-attachment : fixed; border: 0;}

    .wp2b {background-image : url("/var/nobla/i1/wp2b.gif"); background-attachment : fixed; border: 0;}

    .wp2c {background-image : url("/var/nobla/i1/wp2c.gif"); background-attachment : fixed; border: 0;}

    .wp2cpng {background-image : url("/var/nobla/i1/wp2c.png"); background-attachment : fixed; border: 0;}

    /*           venetian blind          */

    .ven {background-image : url("/var/nobla/i1/ven.gif"); background-attachment : fixed; border: 0;}

    span.lastmodified {font-size: xx-small; background-color: silver;  margin-left : 12px; }

    .lnk01 {color : Blue;}



    overflow-x:hidden;             /*precaution: removes horizontal scrollbars*/

    /* keep this as it works with IE */

    /* ============================= */










    Author Comment

    I've forgotten to mention FRAMES are used.
    LVL 7

    Expert Comment

    When you say you've got a 'tailored' version of HTTPD, what exactly is it that you've tailored?

    Author Comment

    The httpd.conf files have different parameters like the document root and a few others. Nothing special.
    LVL 7

    Expert Comment

    Put that stuff up on a sample server somewhere and tell us what we *should* see and what we *actually* see, OK?


    Author Comment

    To jdpipe:
    I'm not too sure of what you want put on a sample server and I probably wouldn't know how to give access to it. The original problem is just a "tiled backgound" that doesn't show as intended.  I've changed the tag from <body class=...> to <body background =...> and put a symlink to the image that should tile the background, that gives the intended result on the screen and leave only one file to edit (the image). I'm willing to leave it as it is.

    I think that once there is a need to see a lot of material (as above), the issue becomes confused and people start spending too much time for little gain and I think it's not worth it in this case.

    I'm quite prepared to give you the points as you've been focused on the problem and you've spent a fair bit of time on it.  Let me know if you think my view is unsatisfactory.
    LVL 7

    Expert Comment

    Hi rblampain
    Cheers for that. It's hard sometimes to tease out the crux of the problem from a big pile of code. Hope to be of more use next time.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Enabling OSINT in Activity Based Intelligence

    Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

    This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
    Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
    The viewer will learn how to dynamically set the form action using jQuery.

    758 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now