Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > cd38b09e3cb8d6c675b02d30393e68af > files > 24

kaya-doc-0.5.2-8.fc14.noarch.rpm

/* This web application demonstrates using cookies to store state. */
webapp cookie;

import Webapp;
import HTMLDocument;

// this stores the user state
data User(String username, Int visited);

globals {
  // this isn't ideal, but it makes the rest of the code simpler
  HTMLDocument doc;
}

HTMLDocument webmain() {
  doc = new(HTML4Strict,"Cookie demonstration");

  // for simplicity, the entire page is generated in the handler
  // in a real application, there'd probably be some template code
  // above and below this call
  appendExisting(doc.body,
		 retrieveFunction(@notLoggedIn,
				  cookieRetriever,
				  "cookie_example_login"));

  source = addParagraph(doc.body,"Read the ");
  void(appendInlineElement(source,Hyperlink("../files/cookie.k"),"source code"));
  return doc;
}

// this is the default function if the cookie doesn't exist.
ElementTree notLoggedIn() {
  // if the form has been submitted
  if (incomingExists("username",DataPost)) {
    // then log in
    user = incomingValue("username",DataPost);
    // and switch to the logged-in handler
    return loggedIn(User(user,0));
  } else {
    // otherwise display the log in form
    content = anonymousBlock;
    void(addHeading(content,1,"Please log in"));
    void(addParagraph(content,"You are not logged in. Please make up a username and log in to see the rest of this application."));
    form = addLocalForm(content);
    f1 = addFieldset(form,"Log in");
    void(addLabelledInput(f1,"Username",InputText,"username","",10));
    void(addRemoteControlInput(f1,InputSubmit,"","Log in"));
    return content;
  }
}

ElementTree loggedIn(User user) {
  if (incomingExists("logout",DataGet) && !incomingExists("username",DataPost)) {
    // erase the login cookie
    if (incomingExists("logout",DataGet)) {
      addHTTPHeader(doc,setCookie("cookie_example_login",""));
    }
    // the second half of the condition should always be false, but
    // if it's not included, someone could mischievously send the
    // application into an infinite loop.
    return notLoggedIn();
    // anyway, if they're logging out, print the log in form
    // we've already deleted the cookie above.
  } else {
    // but usually, it'll just be a page.
    content = anonymousBlock();
    // keep track of the number of pages visited, just to prove that
    // state can be updated as the user navigates the application
    user.visited++;
    void(addParagraph(content,"Hello "+user.username+". You have viewed "+user.visited+" pages this session."));

    // while logged in, the page parameter says what page to view.
    if (incomingExists("page",DataGet)) {
      pageid = Int(incomingValue("page",DataGet));
    } else {
      pageid = 100;
    }
    // now show the page-specific content
    showPage(content,pageid);

    logout = addParagraph(content,"When you're finished, ");
    void(appendInlineElement(logout,Hyperlink(webappName()+"?logout"),"log out"));

    void(storeFunction(cookieStorer@(doc),@loggedIn,user));
    return content;
  }
}

Void linkToPage(ElementTree list, Int linkid) {
  li = pushListItem(list,"Go to ");
  void(appendInlineElement(li,Hyperlink(webappName()+"?page="+linkid),"page "+linkid));
}

Void showPage(ElementTree content, Int pageid) {
  cpage = addParagraph(content,"You are now on page "+pageid+".");
  if (pageid == 1) {
    addString(cpage," Well done - you found page 1! You can log out and try to find it again in fewer moves if you're really bored.");
    // Exercise for the reader: modify this application so that a visitor
    // can't cheat and go straight to page 1 by changing the URL. Fixing
    // things like this is a crucial part of web application security.
    // Hint: you will probably need to expand the state data type a bit
  } else {
    addString(cpage," If you get bored, try to find page 1.");
  }
  // add some navigation to simulate links to the next stages of the
  // application.
  ul = addList(content,Unordered,0);
  if (pageid % 2 == 0) {
    linkToPage(ul,pageid/2);
  } else {
    linkToPage(ul,(pageid*7)+1);
  }
  if (pageid % 5 == 1) {
    linkToPage(ul,pageid+4);
  } else {
    linkToPage(ul,pageid+10);
  }
  if (pageid % 3 == 0) {
    linkToPage(ul,(pageid*2)-1);
  } else if (pageid % 3 == 1) {
    linkToPage(ul,pageid-13);
  } else {
    linkToPage(ul,pageid/3);
  }
  if (pageid < 10) {
    linkToPage(ul,pageid*pageid);
  } else if (pageid > 1000) {
    linkToPage(ul,pageid/20);
  }

}

String cookieStorer(HTMLDocument hdoc, String state) {
    cookie = setCookie("cookie_example_login",state);
    addHTTPHeader(hdoc,cookie);
    return "cookie_example_login";
}

String cookieRetriever(String key) {
    return incomingValue(key,DataCookie);
}