abaco was confused about how relative urls work.
i've attached the file i'm using (which has some
extra differences), and here's the diff

- erik

---

/n/dump/2012/0220/sys/src/cmd/abaco/urls.c:173,237 - urls.c:173,246
  void
  urlcanon(Rune *name)
  {
-       Rune *s, *t, *tail;
+       Rune *s, *e, *tail, tailr;
        Rune **comp, **p, **q;
-       int rooted;
+       int n;
  
-       name = runestrchr(name, L'/')+2;
-       rooted = name[0]==L'/';
+       name = runestrstr(name, L"://");
+       if(name == nil)
+               return;
+       name = runestrchr(name+3, '/');
+       if(name == nil)
+               return;
+       if(*name == L'/')
+               name++;
+ 
+       n = 0;
+       for(e = name; *e != 0; e++)
+               if(*e == L'/')
+                       n++;
+       comp = emalloc((n+2)*sizeof *comp);
+ 
        /*
         * Break the name into a list of components
         */
-       comp = emalloc(runestrlen(name)*sizeof *comp);
        p = comp;
        *p++ = name;
        tail = nil;
-       for(s = name;; s++){
+       tailr = L'☺';   /* silence compiler */
+       for(s = name; *s != 0; s++){
                if(*s == '?' || *s == '#'){
-                       tail = s;
+                       tail = s+1;
+                       tailr = *s;
+                       *s = 0;
                        break;
                }
                else if(*s == L'/'){
                        *p++ = s+1;
-                       *s = '\0';
+                       *s = 0;
                }
-               else if(*s=='\0')
-                       break;
        }
-       *p=0;
+ 
        /*
         * go through the component list, deleting components that are empty 
(except
-        * the last component) or ., and any .. and its non-.. predecessor.
+        * the last component) or ., and any .. and its predecessor.
         */
-       p=q=comp;
-       while(*p){
-               if(runestrcmp(*p, L"")==0 && p[1]!=0
-               || runestrcmp(*p, L".")==0)
-                       p++;
-               else if(runestrcmp(*p, L"..")==0 && q!=comp && 
runestrcmp(q[-1], L"..")!=0){
-                       --q;
-                       p++;
-               }
+       for(p = q = comp; *p != nil; p++){
+               if(runestrcmp(*p, L"") == 0 && p[1] != nil
+               || runestrcmp(*p, L".") == 0)
+                       continue;
+               else if(q>comp && runestrcmp(*p, L"..") == 0 && 
runestrcmp(q[-1], L"..") != 0)
+                       q--;
                else
-                       *q++=*p++;
+                       *q++ = *p;
        }
-       *q = 0;
+       *q = nil;
+ 
        /*
         * rebuild the path name
         */
        s = name;
-       if(rooted)
-               *s++ = '/';
-       for(p = comp; *p; p++){
-               t = *p;
-               while(*t)
-                       *s++ = *t++;
-               if(p[1] != 0)
-                       *s++='/';
+       for(p = comp; p<q; p++){
+               n = runestrlen(*p);
+               memmove(s, *p, sizeof(Rune)*n);
+               s += n;
+               if(p[1] != nil)
+                       *s++ = '/';
        }
+       *s = 0;
        if(tail)
-               memmove(s, tail, runestrlen(tail));
-       *s = '\0';
+               runeseprint(s, e+1, "%C%S", tailr, tail);
        free(comp);
  }
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <plumb.h>
#include <html.h>
#include "dat.h"
#include "fns.h"

Url *
urlalloc(Runestr *src, Runestr *post, int m)
{
        Url *u;

        u = emalloc(sizeof(Url));
        copyrunestr(&u->src, src);
        if(m==HPost)
                copyrunestr(&u->post, post);
        u->method = m;
        incref(u);
        return u;
}

void
urlfree(Url *u)
{
        if(u==nil || decref(u) > 0)
                return;

        closerunestr(&u->src);
        closerunestr(&u->act);
        closerunestr(&u->post);
        closerunestr(&u->ctype);
        free(u);
}

Url *
urldup(Url *a)
{
        Url *b;

        b = emalloc(sizeof(Url));
        b->method = a->method;
        copyrunestr(&b->src, &a->src);
        copyrunestr(&b->act, &a->act);
        copyrunestr(&b->post, &a->post);
        copyrunestr(&b->ctype, &a->ctype);
        return b;
}

static Runestr
getattr(int conn, char *s)
{
        char buf[BUFSIZE];
        int fd, n;

        snprint(buf, sizeof buf, "%s/%d/%s", webmountpt, conn, s);
        fd = open(buf, OREAD);
        if(fd < 0)
                error("can't open attr file");

        n = read(fd, buf, sizeof(buf)-1);
        if(n < 0)
                error("can't read");

        close(fd);
        buf[n] = '\0';
        return (Runestr){runesmprint("%s", buf), n};
}

// tired of typing http://, tired of going to google first.
void
justgoogleit(Url *u)
{
        Rune *s;
        
        s = ucvt(u->src.r+2);
        free(u->src.r);
        u->src.r = 
runesmprint("http://www.google.com/search?hl=en&ie=UTF-8&q=%S";, s);
        free(s);
        u->src.nr = runestrlen(u->src.r);
}

void
addhttp(Url *u)
{
        Rune *s;
        if(validurl(u->src.r))
                return;
        s = u->src.r;
        u->src.r = runesmprint("http://%S";, u->src.r);
        free(s);
        u->src.nr = runestrlen(u->src.r);
}

struct{
        void    (*f)(Url*);
        Rune    *lead;
        int     len;
} ctab[] = {
        justgoogleit,   L"g ",          2,
        addhttp,                L"",            0,
};

void
urlconvience(Url *u)
{
        int i;

        for(i = 0; u->src.nr >= ctab[i].len && runestrncmp(u->src.r, 
ctab[i].lead, ctab[i].len) != 0; i++)
                ;
        ctab[i].f(u);
}

int
urlopen(Url *u)
{
        char buf[BUFSIZE];
        int cfd, fd, conn, n;

        urlconvience(u);
        snprint(buf, sizeof(buf), "%s/clone", webmountpt);
        cfd = open(buf, ORDWR);
        if(cfd < 0)
                error("can't open clone file");

        n = read(cfd, buf, sizeof(buf)-1);
        if(n <= 0)
                error("reading clone");

        buf[n] = '\0';
        conn = atoi(buf);

        snprint(buf, sizeof(buf), "url %S", u->src.r);
        if(write(cfd, buf, strlen(buf)) < 0){
//              fprint(2, "write: %s: %r\n", buf);
    Err:
                close(cfd);
                return -1;
        }
        if(u->method==HPost && u->post.r != nil){
                snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn);
                fd = open(buf, OWRITE);
                if(fd < 0){
//                      fprint(2, "urlopen: bad query: %s: %r\n", buf);
                        goto Err;
                }
                snprint(buf, sizeof(buf), "%S", u->post.r);
                if(write(fd, buf, strlen(buf)) < 0)
                        fprint(2, "urlopen: bad query: %s: %r\n", buf);

                close(fd);
        }
        snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn);
        fd = open(buf, OREAD);
        if(fd < 0){
//              fprint(2, "open: %S: %r\n", u->src.r);
                goto Err;
        }
        u->ctype = getattr(conn, "contenttype");
        u->act = getattr(conn, "parsed/url");
        if(u->act.nr == 0)
                copyrunestr(&u->act, &u->src);
        close(cfd);
        return fd;
}

void
urlcanon(Rune *name)
{
        Rune *s, *e, *tail, tailr;
        Rune **comp, **p, **q;
        int n;

        name = runestrstr(name, L"://");
        if(name == nil)
                return;
        name = runestrchr(name+3, '/');
        if(name == nil)
                return;
        if(*name == L'/')
                name++;

        n = 0;
        for(e = name; *e != 0; e++)
                if(*e == L'/')
                        n++;
        comp = emalloc((n+2)*sizeof *comp);

        /*
         * Break the name into a list of components
         */
        p = comp;
        *p++ = name;
        tail = nil;
        tailr = L'☺';   /* silence compiler */
        for(s = name; *s != 0; s++){
                if(*s == '?' || *s == '#'){
                        tail = s+1;
                        tailr = *s;
                        *s = 0;
                        break;
                }
                else if(*s == L'/'){
                        *p++ = s+1;
                        *s = 0;
                }
        }

        /*
         * go through the component list, deleting components that are empty 
(except
         * the last component) or ., and any .. and its predecessor.
         */
        for(p = q = comp; *p != nil; p++){
                if(runestrcmp(*p, L"") == 0 && p[1] != nil
                || runestrcmp(*p, L".") == 0)
                        continue;
                else if(q>comp && runestrcmp(*p, L"..") == 0 && 
runestrcmp(q[-1], L"..") != 0)
                        q--;
                else
                        *q++ = *p;
        }
        *q = nil;

        /*
         * rebuild the path name
         */
        s = name;
        for(p = comp; p<q; p++){
                n = runestrlen(*p);
                memmove(s, *p, sizeof(Rune)*n);
                s += n;
                if(p[1] != nil)
                        *s++ = '/';
        }
        *s = 0;
        if(tail)
                runeseprint(s, e+1, "%C%S", tailr, tail);
        free(comp);
}

/* this is a HACK */
Rune*
urlcombine(Rune *b, Rune *u)
{
        Rune *p, *q, *sep, *s;
        Rune endrune[] = { L'?', L'#' };
        int i, restore;

        if(u == nil)
                error("urlcombine: u == nil");

        if(validurl(u))
                return erunestrdup(u);

        if(b==nil || !validurl(b))
                error("urlcombine: b==nil || !validurl(b)");

        if(runestrncmp(u, L"//", 2) == 0){
                q =  runestrchr(b, L':');
                return runesmprint("%.*S:%S", (int)(q-b), b, u);
        }
        p = runestrstr(b, L"://");
        if(p != nil)
                p += 3;
        sep = L"";
        q = nil;
        if(*u ==L'/')
                q = runestrchr(p, L'/');
        else if(*u==L'#' || *u==L'?'){
                for(i=0; i<nelem(endrune); i++)
                        if(q = runestrchr(p, endrune[i]))
                                break;
        }else if(p != nil){
                sep = L"/";
                restore = 0;
                s = runestrchr(p, L'?');
                if(s != nil){
                        *s = '\0';
                        restore = 1;
                }
                q = runestrrchr(p, L'/');
                if(restore)
                        *s = L'?';
        }else
                sep = L"/";
        if(q == nil)
                p = runesmprint("%S%S%S", b, sep, u);
        else
                p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u);
        urlcanon(p);
        return p;
}

Reply via email to