httpd-docs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Arthur A Gwozdz <gwozd...@bvt.gdarm.com>
Subject Patch for 1.3 PUT documentation page
Date Tue, 16 Oct 2001 14:50:30 GMT

page: http://www.apacheweek.com/features/put

There were several relatively inconsequential grammar or spelling errors
in
the PUT page documentation. I've corrected them and included the altered
html
below in what I believe is the desired format for updating
documentation.
Changes: 
send > sent
Amongst aother > Among other
commonest > most common
handled > handed
a > as
relative > relatively
So the > The
Please let me know if the format of this message is correct.
Regards,
	ARt G.

----------------------------------------------------------------------------------------------------


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>Apache Week. Publishing Pages with PUT</title>
<META name="description" content="The O'Reilly Network has teamed with
Red Hat Apache Week, the leading commercial Apache site to offer
comprehensive Apache information and resources.  Apache Week offers
news, feature articles, reviews, resources, and documentation.">
<META name="keywords" content="Apache Week, Apache distribution,
o'reilly network, o'reilly, Apache, web development, web server,
network, open source, development reference, technical information,
java, xml, cgi, modperl, red hat, redhat">
<link rel="stylesheet" type="text/css" href="../apacheweek.css">
</head>
<body class="aw-green" marginheight="0" marginwidth="0" topmargin="0"
leftmargin="0" text="#000033" link="#0000ca" vlink="#0000ca"><table
border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="center" width="160">
<a href="../"><img border="0" width="150" height="47"
src="../img/6_apacheweek.gif" alt="Apache Week"></a>
<br>
</td>
<td align="center"><span class="body"></span></td>
<td> </td>
</tr>
<tr><td colspan="3"><img width="1" height="10" src="../img/pad.gif"
alt=" "></td></tr>
<tr>
<td valign="top"><table width="152" border="0" cellspacing="0"
cellpadding="0">
<tr bgcolor="#666666" class="navmain"
onClick="self.location='../issues/search.cgi'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="1" height="18" border="0" alt="
"></td>
<td><a href="../issues/search.cgi" class="sidenavbg">Search
Issues</a></td>
</tr>
    <tr bgcolor="#cccccc" class="nav">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><span class="sidenavsm"><table width="97%" cellpadding="0"
cellspacing="0" border="0"><form method="GET"
action="../issues/search.cgi"><tr>
<td><input type="text" name="isindex" value="criteria" size="12"></td>
<td width="20"><input type="image" width="20" height="18" alt="GO"
bordmoer="0" name="submit" src="../img/go-button.gif"></td>
</tr></form></table></span></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
  <tr bgcolor="#666666" class="navmain" onClick="self.location='../'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="1" height="18" border="0" alt="
"></td>
<td><a href="../" class="sidenavbg">Newsletter</a></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../issues/current'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../issues/current" class="sidenavsm">This week</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';" onClick="self.location='../issues/'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../issues/" class="sidenavsm">Back issues</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../aw/email'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../aw/email" class="sidenavsm">Subscribe</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
  <tr bgcolor="#666666" class="navmain">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="1" height="18" border="0" alt="
"></td>
<td><span class="sidenavbg">Features</span></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../features/'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../features/" class="sidenavsm">Feature index</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../features/ap2'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../features/ap2" class="sidenavsm">Apache 2.0</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';" onClick="self.location='../books/'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../books/" class="sidenavsm">Book reviews</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';" onClick="self.location='../jobs/'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../jobs/" class="sidenavsm">Apache jobs</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
  <tr bgcolor="#666666" class="navmain">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="1" height="18" border="0" alt="
"></td>
<td><span class="sidenavbg">External</span></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../redirect.cgi?link=http://www.apache.org/'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../redirect.cgi?link=http://www.apache.org/"
class="sidenavsm">Apache Software Foundation</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../features/links'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../features/links" class="sidenavsm">Apache links</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
  <tr bgcolor="#666666" class="navmain"
onClick="self.location='../aw/about'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="1" height="18" border="0" alt="
"></td>
<td><a href="../aw/about" class="sidenavbg">About Apache Week</a></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../aw/about'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../aw/about" class="sidenavsm">About us</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
    <tr bgcolor="#cccccc" class="nav"
onMouseOver="this.className='navhilite';"
onMouseOut="this.className='nav';"
onClick="self.location='../aw/contact'">
<td class="aw-green"><img src="../img/pad.gif" width="6" height="18"
border="0" alt=" "></td>
<td><img src="../img/pad.gif" width="10" height="18" border="0" alt="
"></td>
<td><a href="../aw/contact" class="sidenavsm">Contact us</a></td>
</tr>
<tr>
<td></td>
<td colspan="2" bgcolor="#999999"><img src="../img/pad.gif" width="1"
height="1" border="0" alt=" "></td>
</tr>
  <tr valign="bottom"><td align="center" width="160" colspan="3">
<img width="1" height="20" src="../img/pad.gif" alt=" ">
<br>
<span class="small">
Copyright 1996-2001<br>
<a href="http://www.redhat.com/"><img border="0" width="137" height="45"
src="../img/redhat_logo137x45.gif" alt="Red Hat, Inc."></a>
</span>
<br>
</td></tr>
</table></td>
<td valign="top" align="center" class="table-cell"><table width="95%">
<tr><td align="left">
<h1><a name="">Publishing Pages with PUT</a></h1>
<p>
<h2></h2>
<span class="body">
    <p>One of the most common questions we get asked is
    whether Apache supports web publishing with the PUT method.
    Netscape Navigator Gold, AOLPress and Amaya all support this
    method of publishing pages. Technically the answer is yes,
    Apache supports that method. However it does not come with any
    scripts or programs which actually implement the publishing
    behaviour. This article explains what the PUT method is, how it
    can be used in Apache, and what is required to support
    publishing with it. It also gives a basic script to handle
    publishing, and explains why this script should be used very
    carefully to prevent security problems. </p>
    <p>
      First published in Apache Week issue 59 (4th
      April 1997).
    </p>
</span>
<p>
<h2>How Apache Supports GET, POST and PUT</h2>
<span class="body">
    <p>
      When a browser requests a normal page from a server, it uses
      the &quot;GET&quot; method. This is the standard way to get back
      information from a server. The information itself may come
      from a static page, a CGI program, a server-side include page
      or any other source handed by the server. By definition it
      is safe for a browser to obtain a page by GET as many times
      as it likes - it will never cause any permanent action on the
      server (such as entering a product order).
    </p>
    <p>
      To perform a permanent action on the server, the &quot;POST&quot;
      method is used. This method must be handled by a program or
      script, and the browser should not re-request a POST page
      without getting the user to confirm it. This POST method is
      used when a script or program requires a lot of form data
      input or when the request makes the server perform a real
      action such as entering an order.
    </p>
    <p>
      The &quot;PUT&quot; method is similar to the POST method in that
it can
      cause information to be updated on the server. The difference
      is that the POST method is normally handled a script which is
      explicitly named by the resource (that is, something that
      already exists), while a PUT request could be directed at a
      resource which does not (yet) exist. Another difference is
      that the POST method can be used in response to a form, while
      the PUT method can only contain a single data item. So the
      PUT method is suited for publishing pages.
    </p>
    <p>
      There is some confusion about whether Apache supports the PUT
      method. In fact, Apache handles PUT exactly like it handles
      the POST method. That is, it supports it, but in order for it
      to do anything useful you need to supply a suitable CGI
      program. This is on contrast to the GET method, which Apache
      supports internally by sending back files or SSI documents.
    </p>
    </span>
<p>
<h2>Using the PUT Method</h2>
<span class="body">
    <p>
      If you have a script which is capable of handling PUT
      requests, you can easily configure Apache to support that
      script. This is done with the <samp>Script</samp> directive.
      This specifies a script (i.e. a CGI program) to be run
      whenever a PUT request is received. For example, if you put
      your CGI program which handles PUT requests into
      /cgi-bin/put, you would add this like
    </p>
<pre>
  Script PUT /cgi-bin/put
</pre>
    <p>
      into your srm.conf or access.conf (depending on whether you
      want your entire contents to handled by this script, or just
      a specific subdirectory). Note that you also need to make
      sure that this script is executable, by either placing it in
      a <samp>ScriptAlias</samp> directory, or giving it a suitable
      extension and turning on CGI execution for that extension.
    </p>
    <p>
      The CGI script has to be able to accept a page sent it, and
      look and the request URL to decide where to place the file.
      If it is successful it should return a status of 201 or 204
      if everything went ok.
    </p>
    <p>
      The basic operation of a PUT script should be:
    </p>
    <ol>
      <li>
        Check that request comes from the PUT method
      </li>
      <li>
        Get the file to update or create from PATH_TRANSLATED
      </li>
      <li>
        Read the data (read CONTENT_LENGTH bytes from standard
        input)
      </li>
      <li>
        Write the data to the file
      </li>
      <li>
        Return a 201 or 204 status. 
        <p>
          A simplistic script to implement PUT handling like this
          is available in <a
href="http://www.apacheweek.com/issues/put1">put1</a>.
          Amon other limitations, this script does not check to
          see if you are attempting to upload a CGI script or if
          the destination is a directory. However the main failing
          is that it implements no security checks, and if you have
          a secure setup it will not even have permission to update
          the files.
        </p>
      </li>
    </ol>
  </span>
<p>
<h2>The Security Isssues</h2>
<span class="body">
        <p>
          Configuring Apache is the easy part: the hard part is
          creating a server environment and script which are
          secure. Some of the main security requirements are:
        </p>
        <ul>
          <li>
            Make sure the PUT script can only be run by authorised
            users
          </li>
          <li>
            Make sure that the script can update only web content
            files
          </li>
          <li>
            Make sure the authorised users can only update their
            pages, not other people's pages on the same server
          </li>
        </ul>
        <p>
          The first issue can be addressed by making sure that the
          script is protected by username and password
          authentication.
        </p>
        <p>
          The second issue is more complex. To be able to update
          the files on your server the script must have enough
          permission to write or create the content files. This in
          itself is a security risk, since it means if a bug or
          security hole is found in any of your other CGI programs
          anyone on the Internet could potentially change any of
          your files. On most servers the httpd process runs as some
          relatively unprivileged user, such as &quot;nobody&quot;. This
user
          should not own or have write access to any of the files
          on the server. The first problem with generating a
          secure PUT script is determining how the script can get
          permissions to update files owned by a different user.
        </p>
        <p>
          One way of doing this, new in Apache 1.2 betas, is to use
          the &quot;suEXEC&quot; code. This allows a script to be run as
a
          different user. This comes with Apache but is not
          installed by default, because of the security risks it
          can create if used inappropriately. You need to install
          it, and arrange it so that the PUT script is executed as
          the user that owns your web files. In this case, it would
          be sensible to ensure that this user does not have write
          access to any other parts of the file system, such as
          your Apache configuration files or .htaccess files.
        </p>
        <p>
          The final security issue applies if you have multiple
          content providers (such as different customers) where you
          cannot trust them not to try to update each other's
          pages. There are several ways to add fix this:
        </p>
        <ul>
          <li>
            If the customers are in different virtual hosts, use
            the suEXEC mechanism to give each customer a different
            Unix username and execute the script as that user.
          </li>
          <li>
            Use a different PUT script for each customer, with
            individual access authentication for each user, and
            hard-code the paths that they are allowed to update
            into the script.
          </li>
          <li>
            Add lots of careful checks into the PUT script to
            ensure that each REMOTE_USER can only update pages in
            their area
          </li>
        </ul>
      </span>
<p>
<h2>Using PUT Publishing</h2>
<span class="body">
        <p>
          Netscape Navigator Gold, AOLPress and Amaya can publish
          pages with the PUT method. Assuming you have a PUT script
          which provides a level of security you are happy with,
          this section explains how to use these programs to
          publish pages. Other Web publishing program should be
          similar.
        </p>
        <p>
          To publish pages, you need to configure your server as
          given above. This section shows how to do this in more
          detail with better user security. First, decide which
          areas of your document tree you want to allow people to
          publish to. For this example, we will assume people can
          publish to any page on the server. You need to add a
          <samp>Script PUT</samp> directive into the
          <samp>&lt;Directory&gt;</samp> section for the directory
          where you want to enable PUT uploading, and put the PUT
          script into a user-authenticated directory. For example
        </p>
<pre>
  &lt;Directory /usr/local/etc/httpd/htdocs&gt;
  Script PUT /cgi-bin-putusers/put.cgi
  &lt;/Directory&gt;

  &lt;Directory /usr/local/etc/httpd/cgi-bin-putusers&gt;
  AuthType Basic
  AuthName &quot;Authorised PUT Publishers&quot;
  AuthUserFile /usr/local/etc/httpd/htpasswd-putusers
  &lt;/Directory&gt;

  ScriptAlias /cgi-bin-putusers /usr/local/etc/httpd/cgi-bin-putusers
</pre>
        <p>
          You will have to modify this for your setup. You also
          need to enter a username and password into the
          htpasswd-putusers file using <samp>htpasswd</samp>. Note
          that there are many other ways to configure user
          authentication for a PUT script, including using a
          <samp>&lt;Files&gt;</samp> to apply a restriction to just
          the PUT script, or using <samp>&lt;LIMIT PUT&gt;</samp>
          to limit just the PUT method scripts within your existing
          cgi-bin directory.
        </p>
        <p>
          With this configuration, all PUT requests will be handled
          by the named script
          (/usr/local/etc/httpd/cgi-bin-putusers/put.cgi).
        </p>
        <p>
          Now all you need to do is author a page then select the
          publish function. In AOLPress and Amaya, you do File,
          Save (or File, Save As) and type the full URL of the
          location to publish the file to (e.g.
          http://www.my_server.com/first.html).
        </p>
        <p>
          In Navigator Gold, select File, Publish. In the &quot;Upload
          Files to this location&quot; box, enter the full URL of the
          page to create. For example, if your server is called
          www.my_server.com and you want to upload to a file called
          &quot;first.html&quot; in the document root, you would enter
        </p>
<pre>
  http://www.my_server.com/first.html
</pre>
        <p>
          Also enter the username and password you created in the
          htpasswd-putusers file.
        </p>
        <p>
          With AOLPress, select File|Save As, then type the full
          URL of the page to upload into the &quot;Location&quot; box.
        </p>
        </span>
<p>
<h2>Put Scripts</h2>
<span class="body">
        <p>
          There are few scripts available which implement PUT
          handling securely. For this reason the general
          recommendation for using publishing functions is to use
          FTP rather than HTTP where possible. However if you want
          to implement PUT-based publishing, you might like to
          start which one of these programs:
        </p>
        <ul>
          <li>
            <a href="http://www.w3.org/pub/WWW/Amaya/User/PutCern.html">
            A PUT program in C designed for the CERN server</a>
          </li>
          <li>
            <a
href="http://hpwww.ec-lyon.fr/~vincent/apache/mod_put.html">
            mod_put Apache module for PUT and DELETE</a>
          </li>
        </ul>
        <p>
          The issues raised in the above section on security apply
          to these programs as well, so before you use them review
          the source code, install them in a user-authenticated
          area, and make sure that when run from the httpd server
          they only have write permission to the content files you
          want to be able to update.
        </p>
    </span>
</td></tr>
<tr><td align="left">
<hr>
<span class="small">

        Comments or criticisms? Please email us at <a
href="mailto:editors@apacheweek.com">editors@apacheweek.com</a>
<br>
<a href="../aw/email">Subscribe for free</a> and get Apache Week each
Friday by email
        </span>
</td></tr>
</table></td>
<td width="15"><img width="15" height="1" src="../img/pad.gif" alt="
"></td>
</tr>
<tr><td colspan="3"><img width="1" height="10" src="../img/pad.gif"
alt=" "></td></tr>
</table></body>
</html>

---------------------------------------------------------------------
To unsubscribe, e-mail: apache-docs-unsubscribe@apache.org
For additional commands, e-mail: apache-docs-help@apache.org


Mime
View raw message