<p dir="ltr">Oleg,</p>
<p dir="ltr">How is your idea an improvement over James' idea? It seems to me that a call to translate-logical-pathname would be far simpler and easier to review.</p>
<p dir="ltr">I do not read iterate, so if we are moving forward with your approach, please use loop or other standard CL iteration facilities.</p>
<p dir="ltr">Thanks,<br>
Hans</p>
<div class="gmail_quote">Am 01.02.2014 10:29 schrieb "Left Right" <<a href="mailto:olegsivokon@gmail.com">olegsivokon@gmail.com</a>>:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Hans,<br>
<br>
The below hardly qualifies as a patch, just a general idea (I'll give<br>
it a try for now and will see if I can make it better):<br>
<br>
(defun tbnl:request-pathname (&optional (request tbnl:*request*)<br>
(uri-prefix "."))<br>
  (let* ((path (tbnl:url-decode (tbnl:script-name request)))<br>
         (parts (parse-namestring path))<br>
         (uri-parts (parse-namestring uri-prefix)))<br>
    (iter<br>
      (with pick := nil)<br>
      (with uri-dirs := (cdr (pathname-directory uri-parts)))<br>
      (for uri-part := (pop uri-dirs))<br>
      (for part :in (cdr (pathname-directory parts)))<br>
      (when (or pick (not (equal uri-part part)))<br>
        (setf pick t)<br>
        (collect part :into uri))<br>
      (finally<br>
       (return (make-pathname<br>
                :host (pathname-host<br>
                       (tbnl:acceptor-document-root<br>
                        (tbnl::request-acceptor request)))<br>
                :directory (cons :relative uri)<br>
                :name (pathname-name parts)<br>
                :type (pathname-type parts)))))))<br>
<br>
------ test -----<br>
<br>
(let ((tbnl:*acceptor* (make-instance<br>
                        'rgol-acceptor :port 4242<br>
                        :request-class 'rgol-request<br>
                        :document-root #p"rgol:www;"<br>
                        :message-log-destination #p"rgol:logs;messages.log"<br>
                        :access-log-destination #p"rgol:logs;access.log")))<br>
  (let ((r (make-instance 'tbnl:request<br>
                          :acceptor tbnl:*acceptor*<br>
                          :headers-in '(("Accept:*/*"))<br>
                          :uri "/foo/bar/qux/baz.ext")))<br>
    (let ((no-prefix (tbnl:request-pathname r))<br>
          (prefix (tbnl:request-pathname r "/foo/")))<br>
      (format t<br>
              "~&no-prefix: ~s ~<br>
               with-prefix: ~s ~%~<br>
               resolved no-prefix: ~s ~%~<br>
               resolved prefix: ~s"<br>
              no-prefix prefix<br>
              (merge-pathnames no-prefix #p"rgol:www;")<br>
              (merge-pathnames prefix #p"rgol:www;")))))<br>
<br>
;; no-prefix: #P"RGOL:;FOO;BAR;QUX;BAZ.EXT" with-prefix:<br>
#P"RGOL:;BAR;QUX;BAZ.EXT"<br>
;; resolved no-prefix: #P"RGOL:WWW;FOO;BAR;QUX;BAZ.EXT.NEWEST"<br>
;; resolved prefix: #P"RGOL:WWW;BAR;QUX;BAZ.EXT.NEWEST"<br>
<br>
----------------------------------------------<br>
<br>
If I can suggest: would it be worth to make request-pathname a generic<br>
function, rather then a plain function? I would imagine few have used<br>
this mechanism to implement their own path resolution scheme, but<br>
theoretically it could be useful. Its name and the way it's been used<br>
seem to ask for it to be a method of request class.<br>
<br>
Best,<br>
<br>
Oleg<br>
<br>
On Sat, Feb 1, 2014 at 2:11 PM, Hans Hübner <<a href="mailto:hans.huebner@gmail.com">hans.huebner@gmail.com</a>> wrote:<br>
> Oleg,<br>
><br>
> James Anderson privately shared the observation that if the document root<br>
> logical pathname is translated (using translate-logical-pathname) before it<br>
> is merged to the URI's path, the problem would be solved.  Can you give that<br>
> a try?  If that works for you, then I'd like to see Hunchentoot be changed<br>
> so that it call translate-logical-pathname for the configuration paths that<br>
> the user supplies, in the constructor.  The behavior should be documented.<br>
><br>
> I've also pondered whether it would be better to do the translation for<br>
> every request, but James rightfully pointed out that one would want to see<br>
> erroneous logical pathnames early on.  Also, the overhead might be<br>
> considerable, so I'm tending towards doing it at server initialization time.<br>
> This means that if a logical host definition is changed at run time, the<br>
> server must be restarted to pick up the new definition.<br>
><br>
> -Hans<br>
><br>
><br>
> 2014-02-01 Left Right <<a href="mailto:olegsivokon@gmail.com">olegsivokon@gmail.com</a>>:<br>
>><br>
>> Ha!<br>
>> I see, I think I've given up on pathnames once, but now I've got more<br>
>> time to try to figure them out, so maybe one day I'll have that patch<br>
>> ;)<br>
>><br>
>> Thanks for the info, though!<br>
>><br>
>> Best,<br>
>><br>
>> Oleg<br>
>><br>
>> On Sat, Feb 1, 2014 at 12:32 PM, Hans Hübner <<a href="mailto:hans.huebner@gmail.com">hans.huebner@gmail.com</a>><br>
>> wrote:<br>
>> > Oleg,<br>
>> ><br>
>> > what would be needed is complete support for logical pathnames (which is<br>
>> > not<br>
>> > present at the moment).  I believe that if the document root is a<br>
>> > logical<br>
>> > pathname, the incoming URL would need to be converted to a relative<br>
>> > logical<br>
>> > pathname before it is merged to the document root.<br>
>> ><br>
>> > At this point, I am not prepared to work on this myself.  As pathnames<br>
>> > are<br>
>> > hairy business, I would only want to merge a patch to support logical<br>
>> > pathnames if it comes with thorough tests.<br>
>> ><br>
>> > Alternatively, I would accept a documentation patch that says that if<br>
>> > the<br>
>> > document root is a logical pathname, it must not contain a directory or<br>
>> > file<br>
>> > component. :)<br>
>> ><br>
>> > -Hans<br>
>> ><br>
>> ><br>
>> > 2014-02-01 Left Right <<a href="mailto:olegsivokon@gmail.com">olegsivokon@gmail.com</a>>:<br>
>> ><br>
>> >> Thanks for the answer, Hans,<br>
>> >><br>
>> >> I'm looking now at the misc.lisp,<br>
>> >> create-folder-dispatcher-and-handler, am I right assuming this is the<br>
>> >> function that handles paths merging?<br>
>> >><br>
>> >> If so, I was thinking to override request-pathname on request to<br>
>> >> create a URI with the required bits of the pathname. This would seem<br>
>> >> to me like a better way to handle it. But I'm not certain what would<br>
>> >> it mean in terms of other bits of the code, is it likely to break<br>
>> >> other things?<br>
>> >><br>
>> >> Example:<br>
>> >><br>
>> >> (merge-pathnames (make-pathname :host "rgol" :name "game" :type<br>
>> >> "html") #p"rgol:www;")<br>
>> >> #P"RGOL:WWW;GAME.HTML.NEWEST"<br>
>> >><br>
>> >> The reason I want to do it this way is because merge-pathnames will<br>
>> >> only concatenate paths if the default-pathname is trivial: no<br>
>> >> directories, wildcards etc. So it seems to me that the original<br>
>> >> intention was to simply concatenate paths, but because for trivial<br>
>> >> pathnames merge-pathnames worked as concatenation, it was used. Does<br>
>> >> it make sense?<br>
>> >><br>
>> >> Best,<br>
>> >><br>
>> >> Oleg<br>
>> >><br>
>> >> On Sat, Feb 1, 2014 at 10:59 AM, Hans Hübner <<a href="mailto:hans.huebner@gmail.com">hans.huebner@gmail.com</a>><br>
>> >> wrote:<br>
>> >> > Oleg,<br>
>> >> ><br>
>> >> > the problem seems to be related how logical pathnames are merged.<br>
>> >> > The<br>
>> >> > partial pathname that is created by Hunchentoot and then merged with<br>
>> >> > the<br>
>> >> > document root pathname is considered to contain a directory component<br>
>> >> > by<br>
>> >> > CL.<br>
>> >> > Therefore, the directory component that you are matching in your<br>
>> >> > logical<br>
>> >> > pathname host definition is not present when the two partial<br>
>> >> > pathnames<br>
>> >> > are<br>
>> >> > merged.  To work around this behavior, I'd recommend that you define<br>
>> >> > a<br>
>> >> > separate logical pathname host for your document root.<br>
>> >> ><br>
>> >> > TEST-LOGICAL-PATHNAMES> (setf (logical-pathname-translations "TEST")<br>
>> >> > '(("foo;*.*.*" "/tmp/*")))<br>
>> >> > (("foo;*.*.*" "/tmp/*"))<br>
>> >> > TEST-LOGICAL-PATHNAMES> (directory (merge-pathnames "test.txt"<br>
>> >> > #P"test:foo;"))<br>
>> >> > NIL<br>
>> >> > TEST-LOGICAL-PATHNAMES> (setf (logical-pathname-translations "TEST")<br>
>> >> > '(("*.*.*" "/tmp/*")))<br>
>> >> > (("*.*.*" "/tmp/*"))<br>
>> >> > TEST-LOGICAL-PATHNAMES> (directory (merge-pathnames "test.txt"<br>
>> >> > #P"test:foo;"))<br>
>> >> > (#P"/private/tmp/test.txt")<br>
>> >> > TEST-LOGICAL-PATHNAMES> (directory (merge-pathnames "test.txt"<br>
>> >> > #P"test:"))<br>
>> >> > (#P"/private/tmp/test.txt")<br>
>> >> ><br>
>> >> > -Hans<br>
>> >> ><br>
>> >> ><br>
>> >> > 2014-01-31 Left Right <<a href="mailto:olegsivokon@gmail.com">olegsivokon@gmail.com</a>>:<br>
>> >> ><br>
>> >> >> Sorry, I've copied the wrong log entry, this is the correct one:<br>
>> >> >><br>
>> >> >> 127.0.0.1 - [2014-01-31 17:35:44] "GET /game.html HTTP/1.1" 404 188<br>
>> >> >> "-"<br>
>> >> >> "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like<br>
>> >> >> Gecko)<br>
>> >> >> Chrome/28.0.1500.95 Safari/537.36"<br>
>> >> >><br>
>> >> >><br>
>> >> >> On Fri, Jan 31, 2014 at 5:33 PM, Oleg Sivokon<br>
>> >> >> <<a href="mailto:olegsivokon@gmail.com">olegsivokon@gmail.com</a>><br>
>> >> >> wrote:<br>
>> >> >>><br>
>> >> >>> Hello list,<br>
>> >> >>><br>
>> >> >>> There should be something very simple I've overlooked, yet I can't<br>
>> >> >>> find<br>
>> >> >>> it. Hunchentoot seems not to be able to locate the root directory,<br>
>> >> >>> where<br>
>> >> >>> I have my static content, and I can't get it to print any useful<br>
>> >> >>> information about it. That's why I'm asking for your help.<br>
>> >> >>><br>
>> >> >>> Below is my setup:<br>
>> >> >>><br>
>> >> >>> (setf (logical-pathname-translations "rgol")<br>
>> >> >>>        '(...<br>
>> >> >>>          ("WWW;*.*.*" "/home/wvxvw/.../www/")<br>
>> >> >>>          ("WWW;*;*.*.*" "/home/wvxvw/.../www/*")<br>
>> >> >>>          ...))<br>
>> >> >>><br>
>> >> >>> (make-instance 'hunchentoot:acceptor :port 4242<br>
>> >> >>>     :document-root #p"rgol:www;"<br>
>> >> >>>     :message-log-destination #p"rgol:logs;messages.log"<br>
>> >> >>>     :access-log-destination #p"rgol:logs;access.log")<br>
>> >> >>><br>
>> >> >>> I've defined another handler, which doesn't depend on static files,<br>
>> >> >>> and<br>
>> >> >>> it works fine, however, when I try to access static files, the log<br>
>> >> >>> record looks like this:<br>
>> >> >>><br>
>> >> >>> 127.0.0.1 - [2014-01-31 17:12:40]<br>
>> >> >>> "GET /img/made-with-lisp-logo.jpg HTTP/1.1"<br>
>> >> >>> 404 206 "<a href="http://localhost:4242/game.html" target="_blank">http://localhost:4242/game.html</a>"<br>
>> >> >>> "Mozilla/5.0 (X11; Linux x86_64; rv:23.0) Gecko/20100101<br>
>> >> >>> Firefox/23.0"<br>
>> >> >>><br>
>> >> >>> But the file is definitely there, because if I try this in REPL:<br>
>> >> >>><br>
>> >> >>> (directory #p"rgol:www;*.*")<br>
>> >> >>> (#P"/home/wvxvw/.../www/game.html"<br>
>> >> >>>  ... more files ...)<br>
>> >> >>><br>
>> >> >>> My version of Hunchentoot is:<br>
>> >> >>><br>
>> >> >>> hunchentoot:*hunchentoot-version*<br>
>> >> >>> "1.2.17"<br>
>> >> >>><br>
>> >> >>> $ sbcl --version<br>
>> >> >>> SBCL 1.1.2-1.fc18<br>
>> >> >>><br>
>> >> >>> Best,<br>
>> >> >>><br>
>> >> >>> Oleg<br>
>> >> >><br>
>> >> >><br>
>> >> ><br>
>> ><br>
>> ><br>
><br>
><br>
</blockquote></div>