Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-adding-flash-your-wordpress-theme
Packt
24 Dec 2009
11 min read
Save for later

Adding Flash to your WordPress Theme

Packt
24 Dec 2009
11 min read
Adobe Flash—it's come quite a long way since my first experience with it as a Macromedia product (version 2 in 1997). Yet still, it does not adhere to W3C standards, requires a plugin to view, and above all, is a pretty pricey proprietary product. So why is everyone so hot on using it? Love it or hate it, Flash is here to stay. It does have a few advantages that we'll take a quick look at. The Flash player plugin does boast the highest saturation rate around (way above other media player plugins) and it now readily accommodates audio and video, as video sites such as You Tube take advantage of it. It's pretty easy to add and upgrade for all major browsers. The price may seem prohibitive at first, but after the initial purchase, additional upgrades are reasonably priced. Plus, many third-party software companies offer very cheap authoring tools that allow you to create animations and author content using the Flash player format. (In most cases, no one needs to know you're using the $50 version of Swish and not the $800 Flash CS3 to create your content.) Above all, it can do so much more than just playing video and audio (like most plugins). You can create seriously rich and interactive content, even entire applications with it, and the best part is, no matter what you create with it, it is going to look and work exactly the same on all browsers and platforms. These are just a few of the reasons why so many developers chose to build content and applications for the Flash player. Oh, and did I mention you can easily make awesome, visually slick, audio-filled stuff with it? Yeah, that's why your client wants you to put it in their site. Flash in your theme A commonly requested use of Flash is usually in the form of a snazzy header within the theme of the site, the idea being that various relevant and/or random photographs or designs load into the header with some supercool animation (and possibly audio) every time a page loads or a section changes. I'm going to assume if you're using anything that requires the Flash player, you're pretty comfortable with generating content for it. So, we're not going to focus on any Flash timeline tricks or ActionScripting. We'll simply cover getting your Flash content into your WordPress theme. For the most part, you can simply take the HTML object embed code that Flash (or other third-party tools) will generate for you and paste it into the header area of your WordPress index.php or header.php template file. Handling users without Flash, older versions of Flash, and IE6 users While the previous method is extremely clean and simple, it doesn't help all of your site's users in dealing with Flash. What about users who don't have Flash installed or have an older version that won't support your content? What about IE users who have the Active X restrain? You'll want your site and theme to gracefully handle users who do not have Flash (if you've used the overlay method, they'll simply see the CSS background image and probably not know anything is wrong!) or an older version of Flash that doesn't support the content you wish to display. This method lets you add in a line of text or a static image as an alternative, so people who don't have the plugin/correct version installed are either served up alternative content and they're none-the-wiser, or served up content that nicely explains that they need the plugin and directs them towards getting it. Most importantly, this method also nicely handles IE's ActiveX restrictions. Is the ActiveX restriction still around? In 2006, the IE browser upped its security, so users had to validate content that shows up in the Flash player (or any player) via Microsoft's ActiveX controls). Your Flash content starts to play, but there's a "grey outline" around the player area which may or may not mess up your design. If your content is interactive, then people will need to click to activate it. This is annoying, but the main workaround involved "injecting" controls and players via JavaScript. Essentially, you need to include your Flash content via a JavaScript include file. As of April 2008, this restriction was reverted, but only if your user has updated their browser; chances are, if they intent on still using IE6 or 7, they haven't done this update. Regardless of whether you are concerned about ActiveX restrictions, using JavaScript to help you instantiate your Flash will greatly add to the ease of embedding content. It will also make sure that users of all versions or who need to install Flash are handled either by directing them to the proper Flash installation and/or letting them see an alternative version of the content. swfObject For a while, I used this standard swfObject method that was detailed in this great SitePoint article: http://www.sitepoint.com/article/activex-activationissue-ie. A similar, robust version of this JavaScript is located on Google Code's AJAX API http://code.google.com/p/swfobject/wiki/hosted_library. You can download the script (it's very small) or you can link directly to the swfObject AJAX API URL: <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> Downloaded or linked to the Google Code CDN, be sure to place this below your wp_head or any wp_enqueue_script calls in your < head > tags in your header.php template file or other head template file. Adding a SWF to the template using swfObject If you'd like to use the swfObject.js file and method, you can read the full documentation here: http://code.google.com/p/swfobject/wiki/documentation. But essentially, we're going to use the dynamic publishing option to include our SWF file. Using the SWF file included in this book's code packet, create a new directory in your theme called flash and place the SWF file in it. Then, create a div with alternative content and a script tag that includes the following JavaScript: <script type="text/javascript">swfobject.embedSWF("myContent.swf", "myContent", "300", "120","9.0.0");</script>...<div id="myContent"><p>Alternative content</p></div>... Add this ID rule to your stylesheet (I placed it just below my other header and intHeader ID rules): #flashHold{float: right;margin-top: 12px;margin-right: 47px;} As long as you take care to make sure the div is positioned correctly, the object embed code has the correct height and width of your Flash file, and you're not accidentally overwriting any parts of the theme that contain WordPress template tags or other valuable PHP code, you're good to go. What's the Satay method?It's a cleaner way to embed your Flash movies while still supporting web standards. Drew McLellan discusses its development in detail in this article: http://www.alistapart.com/articles/flashsatay. This method was fine on its own until IE6 decided to include its ActiveX security restriction. Nowadays, a modified embed method called the "nested-objects method": http://www.alistapart.com/articles/flashembedcagematch/ is used with the swfObject JavaScript we just covered. Good developer's tip:Even if you loathe IE (as lots of us as developers tend to), it is an "industry standard" browser and you have to work with it. I've found the Microsoft's IE blog ( http://blogs.msdn.com/ie/) extremely useful in keeping tabs on IE so that I can better develop CSS-based templates for it. While you're at it, go ahead and subscribe to the RSS feeds for Firefox ( http://developer.mozilla.org/devnews/), Safari ( http://developer.apple.com/internet/safari/), and your other favorite browsers. You'll be surprised at the insight you can glean, which can be extremely handy if you ever need to debug CSS or JavaScripts for one of those browsers. jQuery Flash plugin In the past year, as I've found myself making more and more use of jQuery, I've discovered and really liked Luke Lutman's jQuery Flash plugin. There is no CDN for this and it's not bundled with WordPress, so you'll need to download it and add it to your theme's js directory: ( http://jquery.lukelutman.com/plugins/flash/). Embedding Flash files using the jQuery Flash plugin As we're leveraging jQuery already, I find Luke's Flash plugin a little easier to deal with. Load the script under the wp_head. Place a div of alternative content; just the div of alternative content and nothing else! Write the jQuery script that will replace that content or show your alternative content for old/no Flash players. Code goes here. I think you see why I liked this so much more. Passing Flash a WordPress variable So now you've popped a nice Flash header into your theme. Here's a quick trick to make it all the more impressive. If you'd like to keep track of what page, post, or category your WordPress user has clicked on and display a relevant image or animation in the header, you can pass your Flash SWF file a variable from WordPress using PHP. I've made a small and simple Flash movie that will fit right over the top-right of my internal page's header. I'd like my Flash header to display some extra text when the viewer selects a different "column" (a.k.a. category). In this case, the animation will play and display OpenSource Magazine: On The New Web underneath the open source logo when the user selects the On The New Web category. More fun with CSSIf you look at the final theme package available from this title's URL on the Packt Publishing site, I've included the original ooflash-sample. FLA file. You'll notice the FLA has a standard white background. If you look at my header.php file, you'll notice that I've set my wmode parameter to transparent. This way, my animation is working with my CSS background. Rather than beef up my SWF's file size with another open source logo, I simply animate over it! Even if my animation "hangs" or never loads, the user's perception and experience of the page is not hampered. You can also use this trick as a "cheater's preloader". In your stylesheet, assign the div that holds your Flash object embed tags, a background image of an animated preloading GIF or some other image that indicates the user should expect something to load. The user will see this background image until your Flash file starts to play and covers it up. My favorite site to get and create custom loading GIFs is http://www.ajaxload.info/.   In your Flash authoring program, set up a series of animations or images that will load or play based on a variable set in the root timeline called catName. You'll pass this variable to your ActionScript. In my FLA example, if the catName variable does not equal On The New Web, then the main animation will play, but if the variable returns On The New Web, then the visibility of the movie clip containing the words OpenSource Magazine: On The New Web will be set to "true". Now, let's get our PHP variable into our SWF file. In your object embed code where your swfs are called, be sure to add the following code: If you plan on using the Satay embed method, your object embed will look like this: ...<script type="text/javascript">var flashvars = {catName: "<?echo single_cat_title('');?>"};swfobject.embedSWF("<?php bloginfo('template_directory');?>/flash/ooflash-sample.swf", "flashHold", "338", "150","8.0.0","expressInstall.swf", flashvars);</script>... If you'd like to use jQuery Flash, your jQuery will look like this: ...<script type="text/javascript">jQuery(document).ready(function(){jQuery('#flashHold').flash({src: '<?php bloginfo('template_directory');?>/flash/ooflash-sample.swf',width: 338,height: 150,flashvars: { catName: '<?echo single_cat_title('');?>' }},{ version: 8 });});</script>... Be sure to place the full path to your SWF file in the src and value parameters for the embed tags or jQuery src. Store your Flash file inside your themes directory and link to it directly, that is, src="/mythemename/flas'); template tag. This will ensure that your SWF file loads properly. Using this method every time someone loads a page or clicks on a link on your site that is within the On The New Web category, PHP will render the template tag as myswfname.swf?catName=On The New Web, or whatever the $single_cat_title(""); for that page is. So your Flash file's ActionScript is going to look for a variable called catName in the_root or _level0, and based on that value, do whatever you told it to do—call a function, go to a frame and animate; you can even name it. For extra credit, you can play around with the other template tag variables such as the_author_meta or the_date(), for example, and load up special animations, images, or call functions based on them.
Read more
  • 0
  • 2
  • 8468

article-image-extending-dialog-jquery-user-interface-17
Packt
24 Dec 2009
6 min read
Save for later

Extending The Dialog in jQuery User Interface 1.7

Packt
24 Dec 2009
6 min read
Controlling a dialog programmatically The dialog requires few methods in order to function. The full list of the methods we can call on a dialog is as follows: Method Used to close Close or hide the dialog. destroy Permanently disable the dialog. The destroy method for a dialog works in a slightly different way than it does for the other widgets we've seen so far. Instead of just returning the underlying HTML to its original state, the dialog's destroy method also hides it. disable Temporarily disable the dialog. enable Enable the dialog if it has been disabled. isOpen Determine whether a dialog is open or not. moveToTop Move the specified dialog to the top of the stack. open Open the dialog. option Get or set any configurable option after the dialog has been initialized. Toggling the dialog We first take a look at opening the widget, which can be achieved with the simple use of the open method. Let's revisit dialog3.html in which the autoOpen option was set to false, so the dialog did not open when the page was loaded. Add the following < button> to the page: <button id="toggle">Toggle dialog!</button> Then add the following click-handler directly after the dialog's widget method: $("#toggle").click(function() { ($("#myDialog").dialog("isOpen") == false) ?  $("#myDialog").dialog("open") : $("#myDialog").dialog("close") ;}); Save this file as dialog14.html. To the page we've added a simple < button> that can be used to either open or close the dialog depending on its current state. In the < script> element, we've added a click handler for the < button> that uses the JavaScript ternary conditional to check the return value of the isOpen method. If it returns false, the dialog is not open so we call its open method else we call the close method instead. The open and close methods both trigger any applicable events, for example, the close method fires first the beforeclose and then the close events. Calling the close method is analogous to clicking the close button on the dialog. Getting data from the dialog Because the widget is a part of the underlying page, passing data to and from it is simple. The dialog can be treated as any other standard element on the page. Let's look at a basic example. We looked at an example earlier in the article which added some < button> elements to the dialog. The callback functions in that example didn't do anything, but this example gives us the opportunity to use them. Add the following code above the < script> tags in dialog14.html. <p>Please answer the opinion poll:</p><div id="myDialog" title="Best Widget Library"> <p>Is jQuery UI the greatest JavaScript widget library?</p> <label for="yes">Yes!</label><input type="radio" id="yes" value="yes" name="question"  checked="checked"><br> <label for="no">No!</label><input type="radio" id="no" value="no" name="question"></div><script type="text/javascript" src="development-bundle/jquery-1.3.2.js"></script> Now change the final < script> element to as follows: <script type="text/javascript"> $(function(){ var execute = function(){ var answer; $("input").each(function(){ (this.checked == true) ? answer = $(this).val() : null; }); $("<p>").text("Thanks for selecting " +answer).appendTo($("body")); $("#myDialog").dialog("close"); } var cancel = function() { $("#myDialog").dialog("close"); } var dialogOpts = { buttons: { "Ok": execute, "Cancel": cancel } }; $("#myDialog").dialog(dialogOpts); });</script> Save this as dialog15.html. Our dialog widget now contains a set of radio buttons, < label> elements, and some text. The purpose of the example is to get the result of which radio is selected, and then do something with it when the dialog closes. We start the < script> by filling out the execute function that will be attached as the value of the Ok property in the buttons object later in the script. It will therefore be executed each time the Ok button is clicked. In this function we use jQuery's each() method to look at both of the radio buttons and determine which one is selected. We set the value of the answer variable to the radio button's value and then created a short message along with appending it to the < body> of the page. The callback mapped to the Cancel button is simple, all we do is close the dialog using the close method. The following screenshot shows how the page should appear once a radio button has been selected and the Ok button has been clicked: The point of this trivial example was to see that getting data from the dialog is as simple as getting data from any other component on the page. Dialog interoperability We can easily place other UI widgets into the dialog, such as the accordion widget. In a new file in your text editor create the following page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="development-bundle/themes/smoothness/ui.all.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Dialog Example 17</title> </head> <body> <div id="myDialog" title="An Accordion Dialog"> <div id="myAccordion"> <h2><a href="#">Header 1</a></h2><div>Lorem ipsum dolor sit amet,  consectetuer adipiscing elit.Aenean sollicitudin.</div> <h2><a href="#">Header 2</a></h2><div>Etiam tincidunt est vitae est.  Ut posuere, mauris at sodales rutrum, turpis.</div> <h2><a href="#">Header 3</a></h2><div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus.</div> </div> </div> <script type="text/javascript" src="development-bundle/jquery-1.3.2.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.core.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.dialog.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.draggable.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.resizable.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.accordion.js"></script> <script type="text/javascript"> $(function(){ $("#myDialog").dialog(); $("#myAccordion").accordion(); }); </script> </body></html> Save this file as dialog16.html. The underlying markup for the accordion widget is placed into the dialog's container element, and we just call each component's widget method in the < script>. The combined widget should appear like this:
Read more
  • 0
  • 0
  • 2043

article-image-seam-conversation-management-using-jboss-seam-components-part-1
Packt
24 Dec 2009
8 min read
Save for later

Seam Conversation Management using JBoss Seam Components: Part 1

Packt
24 Dec 2009
8 min read
The JBoss Seam framework provides elegant solutions to a number of problems. One of these problems is the concept of conversation management. Traditional web applications have a limited number of scopes (or container-managed memory regions) in which they can store data needed by the application at runtime. In a typical Java web application, these scopes are the application scope, the session scope, and the request scope. JSP-based Java web applications also have a page scope. Application scope is typically used to store stateless components or long-term read-only application data. Session scope provides a convenient, medium-term storage for per-user application state, such as user credentials, application preferences, and the contents of a shopping cart. Request scope is short-term storage for per-request information, such as search keywords, data table sort direction, and so on. Seam introduces another scope for JSF applications: the conversation scope. The conversation scope can be as short-term as the request scope, or as long-term as the session scope. Seam conversations come in two types: temporary conversations and long-running conversations. A temporary Seam conversation typically lasts as  long as a single HTTP request. A long-running Seam conversation typically spans several screens and can be tied to more elaborate use cases and workflows within the application, for example, booking a hotel, renting a car, or placing an order for computer hardware. There are some important implications for Seam's conversation management when using Ajax capabilities of RichFaces and Ajax4jsf. As an Ajax-enabled JSF form may involve many Ajax requests before the form is "submitted" by the user at the end of a  use case, some subtle side effects can impact our application if we are not careful. Let's look at an example of how to use Seam conversations effectively with Ajax. Temporary conversations When a Seam-enabled conversation-scoped JSF backing bean is accessed for the first time, through a value expression or method expression from the JSF page for instance, the Seam framework creates a temporary conversation if a conversation does not already exist and stores the component instance in that scope. If a long-running conversation already exists, and the component invocation requires a long-running conversation, for example by associating the view with a long-running conversation in pages.xml, by annotating the bean class or method with Seam's @Conversational annotation, by annotating a method with Seam's @Begin annotation, or by using the conversationPropagation request parameter, then Seam stores the component instance in the existing long-running conversation. ShippingCalculatorBean.java The following source code demonstrates how to declare a conversation-scoped backing being using Seam annotations. In this example, we declare the ShippingCalculatorBean as a Seam-managed conversation-scoped component named shippingCalculatorBeanSeam. @Scope(ScopeType.CONVERSATION) public class ShippingCalculatorBean implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Country country; private Product product; public Country getCountry() { return country; } public Product getProduct() { return product; } public Double getTotal() { Double total = 0d; if (country != null && product != null) { total = product.getPrice(); if (country.getName().equals("USA")) { total = +5d; } else { total = +10d; } } return total; } public void setCountry(Country country) { this.country = country; } public void setProduct(Product product) { this.product = product; } } faces-config.xml We also declare the same ShippingCalculatorBean class as a request-scoped backing bean named shippingCalculaorBean in faces-config.xml. Keep in mind that the JSF framework manages this instance of the class, so none of the Seam annotations are effective for instances of this managed bean. <managed-bean> <description>Shipping calculator bean.</description> <managed-bean-name>shippingCalculatorBean</managed-bean-name> <managed-bean-class>chapter5.bean.ShippingCalculatorBean </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> pages.xml The pages.xml file is an important Seam configuration file. When a Seam-enabled web application is deployed, the Seam framework looks for and processes a file in the WEB-INF directory named pages.xml. This file contains important information about the pages in the JSF application, and enables us to indicate if a long-running conversation should be started automatically when a view is first accessed. In this example, we declare two pages in pages.xml, one that does not start a long-running conversation, and one that does. <?xml version="1.0" encoding="utf-8"?> <pages xsi_schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd"> <page view-id="/conversation01.jsf" /> <page view-id="/conversation02.jsf"> <begin-conversation join="true"/> </page> … </pages> conversation01.jsf Let's look at the source code for our first Seam conversation test page. In this page, we render two forms side-by-side in an HTML panel grid. The first form is bound to the JSF-managed request-scoped ShippingCalculatorBean, and the second form is bound to the Seam-managed conversation-scoped ShippingCalculatorBean. The form allows the user to select a product and a shipping destination, and then calculates the shipping cost when the command button is clicked. When the user tabs through the fields in a form, an Ajax request is sent, submitting the form data and re-rendering the button. The button is in a disabled state until the user has selected a value in both the fields. The Ajax request creates a new HTTP request on the server, so for the first form JSF creates a new request-scoped instance of our ShippingCalculatorBean for every Ajax request. As the view is not configured to use a long-running conversation, Seam creates a new temporary conversation and stores a new instance of our ShippingCalculatorBean class in that scope for each Ajax request. Therefore, the behavior that can be observed when running this page in the browser is that the calculation simply does not work. The value is always zero. This is because the model state is being lost due to the incorrect scoping of our backing beans. <h:panelGrid columns="2" cellpadding="10"> <h:form> <rich:panel> <f:facet name="header"> <h:outputText value="Shipping Calculator (No Conversation)" /> </f:facet> <h:panelGrid columns="1" width="100%"> <h:outputLabel value="Select Product: " for="product" /> <h:selectOneMenu id="product" value="#{shippingCalculatorBean.product}"> <s:selectItems var="product" value="#{productBean.products}" label="#{product.name}" noSelectionLabel="Select" /> <a4j:support event="onchange" reRender="button" /> <s:convertEntity /> </h:selectOneMenu> <h:outputLabel value="Select Shipping Destination: " for="country" /> <h:selectOneMenu id="country" value="#{shippingCalculatorBean.country}"> <s:selectItems var="country" value="#{customerBean.countries}" label="#{country.name}" noSelectionLabel="Select" /> <a4j:support event="onchange" reRender="button"/> <s:convertEntity /> </h:selectOneMenu> <h:panelGrid columns="1" columnClasses="centered" width="100%"> <a4j:commandButton id="button" value="Calculate" disabled="#{shippingCalculatorBean.country eq null or shippingCalculatorBean.product eq null}" reRender="total" /> <h:panelGroup> <h:outputText value="Total Shipping Cost: " /> <h:outputText id="total" value="#{shippingCalculatorBean.total}"> <f:convertNumber type="currency" currencySymbol="$" maxFractionDigits="0" /> </h:outputText> </h:panelGroup> </h:panelGrid> </h:panelGrid> </rich:panel> </h:form> <h:form> <rich:panel> <f:facet name="header"> <h:outputText value="Shipping Calculator (with Temporary Conversation)" /> </f:facet> <h:panelGrid columns="1"> <h:outputLabel value="Select Product: " for="product" /> <h:selectOneMenu id="product" value="#{shippingCalculatorBeanSeam.product}"> <s:selectItems var="product" value="#{productBean.products}" label="#{product.name}" noSelectionLabel="Select" /> <a4j:support event="onchange" reRender="button" /> <s:convertEntity /> </h:selectOneMenu> <h:outputLabel value="Select Shipping Destination: " for="country" /> <h:selectOneMenu id="country" value="#{shippingCalculatorBeanSeam.country}"> <s:selectItems var="country" value="#{customerBean.countries}" label="#{country.name}" noSelectionLabel="Select" /> <a4j:support event="onchange" reRender="button" /> <s:convertEntity /> </h:selectOneMenu> <h:panelGrid columns="1" columnClasses="centered" width="100%"> <a4j:commandButton id="button" value="Calculate" disabled="#{shippingCalculatorBeanSeam.country eq null or shippingCalculatorBeanSeam.product eq null}" reRender="total" /> <h:panelGroup> <h:outputText value="Total Shipping Cost: " /> <h:outputText id="total" value="#{shippingCalculatorBeanSeam.total}"> <f:convertNumber type="currency" currencySymbol="$" maxFractionDigits="0" /> </h:outputText> </h:panelGroup> </h:panelGrid> </h:panelGrid> </rich:panel> </h:form> </h:panelGrid> The following screenshot demonstrates the problem of using request-scoped or temporary conversation-scoped backing beans in an Ajax-enabled JSF application. As an Ajax request is simply an asynchronous HTTP request marshalled by client-side code executed by the browser's JavaScript interpreter, the request-scoped backing beans are recreated with every Ajax request. The model state is lost and the behavior of the components in the view is incorrect.
Read more
  • 0
  • 0
  • 2536

article-image-dynamic-menus-wordpress
Packt
07 Dec 2009
5 min read
Save for later

Dynamic Menus in WordPress

Packt
07 Dec 2009
5 min read
This is the nice thing about WordPress—it's all "dynamic". Once you install WordPress and design a great theme for it, anyone with the right level of administrative capability can log into the Administration Panel and add, edit, or delete content and menu items. But generally, when people ask for "dynamic menus", what they really want are those appearing and disappearing drop-down menus which, I believe, they like because it quickly gives a site a very "busy" feel. I must add my own disclaimer—I don't like dropdowns. Before you get on to my case, I will say it's not that they're "wrong" or "bad"; they just don't meet my own aesthetic standards and I personally find them non-user friendly. I'd prefer to see a menu system that, if subsections are required, displays them somewhere consistently on the page, either by having a vertical navigation expand to display subsections underneath, or showing additional subjections in a set location on the page if a horizontal menu is used. I like to be able to look around and say, "OK, I'm in the New Items | Cool Drink section and I can also check out Red Dinksand Retro Dinks within this section". Having to constantly go back up to the menu and drop-down the options to remind myself of what's available and what my next move might be, is annoying. Still haven't convinced you not to use drop-downs? OK, read on. Drop-down menus So you're going to use dropdowns. Again it's not "wrong"; however, I would strongly caution you to help your client take a look at their target users before implementing them. If there's a good chance that most users are going to use the latest browsers that support the current JavaScript, CSS, and Flash standards, and everyone has great mobility and is "mouse-ready", then there's really no problem in going for it. If it becomes apparent that any percentage of the site's target users will be using older browsers or have disabilities that prevent them from using a mouse and will limit them to tabbing through content, you must consider not using drop-down menus. I was especially negative about drop-down menus as, until recently, they required bulky JavaScripting or the use of Flash, which does not make clean, semantic, and SEO-friendly (or accessible) XHTML. Enter the Suckerfish method developed by Patrick Griffiths and Dan Webb. This method is wonderful because it takes valid, semantically accurate, unordered lists (WordPress' favorite!), and using almost pure CSS, creates dropdowns. The drop-down menus are not tab accessible, but they will simply display as a single, clear unordered list to older browsers that don't support the required CSS. IE6, as per usual, poses a problem or two for us, so there is some minimal DOM JavaScripting needed to compensate and achieve the correct effect in that browser. If you haven't heard of or worked with the Suckerfish method, I'm going to recommend you to go online (right now!) and read Dan and Patrick's article in detail (http://alistapart.com/articles/dropdowns). More recently, Patrick and Dan have revisited this method with "Son-of-a-Suckerfish", which offers multiple levels and an even further pared down DOM JavaScript. Check it out at http://www.htmldog.com/articles/suckerfish/dropdowns/. I also suggest you play around with the sample code provided in these articles so that you understand exactly how it works. Go on, and read it. When you get back, I'll review how to apply this method to your WordPress theme. DIY SuckerFish menus in WordPress All done? Great! As you can see, the essential part of this effect is getting your menu items to show up as unordered lists with sub unordered lists. Once you do that, the rest of the magic can be easily handled by finessing the CSS that Patrick and Dan suggest into your theme's CSS and placing the DOM script in your theme's header tag(s), in your header.php and/or index.php template files. Seriously, that's it! The really good news is that WordPress already outputs your content's pages and their subpages using unordered lists. Right-click on the page links in Firefox to View Selected Source and check that the DOM inspector shows us that the menu is, in fact, being displayed using an unordered list. Now you can go into your WordPress Administration panel and add as many pages and subpages as you'd like (Administration | Page | Add New). You'll use the Page Parent tab on the right to assign your subpages to their parent. If you installed the pageMash plugin, it's even easier! You can drag-and-drop your created pages into any configuration you'd like. Just be sure to hit the Update button when you're done. Once you've added subpages to a page, you'll be able to use the DOM Source of Selection viewer to see that your menu is displayed with unordered lists and sublists.
Read more
  • 0
  • 0
  • 3630

article-image-photo-compositing-gimp-part-1
Packt
07 Dec 2009
7 min read
Save for later

Photo Compositing with The GIMP: Part 1

Packt
07 Dec 2009
7 min read
Basing from my previous GIMP article titled Creating Pseudo-3D Imagery with GIMP, you learned how to do some basic selection manipulation, gradient application, faking Depth of Field, etc.  In line with that, I’m following it with a new article very much related to the concepts discussed therein but we’ll raise the bar a bit by having a glimpse on compositing, where we’ll use an existing image or photograph and later add in our 2-dimensional element seamlessly with the said picture. So if you haven’t read yet “Creating Pseudo-3D Imagery with GIMP”, I highly suggest you do so since almost all major concepts we’ll tackle here are based off of that article.  But if you have an idea on how to do the implied concepts here, then you’re good to go. If you have been following my advices lately, this might feel cliché to you, but you can’t blame me if I say “Always plan what you have to do!”, right? There you go, another useful and tad overused advice. Just to give you an overview, this article you are about to spend some time on will teach you basically how to: 1) add 2-dimensional elements to photos or just any other image you wish to, 2) apply effects to better enhance the composition, 3) plan out your scenes well However, this guide doesn’t teach you how to pick the right color combination nor does it help you how to shoot great photographs, but hopefully though, at the end of your reading, you’ll soon be able to apply the concepts with no hassle and get comfortable with it each time you do. Some of you might be a bit daunted by the title alone of this article, especially those of you most inclined with specialized compositing software, but as much as I would want to make use of those applications, I’m much more comfortable exploring what GIMP is capable of, not only as a simple drawing application but as a minor compositing app as well.  The concepts that I present here though are just basic representations of what compositing actually is.  And in this context, we’ll only be focusing on still images as reference and output all throughout this article.  If you wanted however to do compositing on series of images, animation, or movie, I highly suggest GIMP’s 3D partner – Blender. Ok, promotion set aside, let’s head back to the topic at hand. To give you an idea (because I believe [and I’m positive you do too] that pictures speak louder than words), here’s what we should be having by the end of this article, probably not exactly matching it but fairly close enough and I’ll try my best to be as guiding as possible. So let’s hop on! Heart and Sphere Composited with GIMP Compose, Compose, Compose! Yup, you read it thrice, I did too, don’t worry.  So what’s the fuss about composing anyway? The answer is pretty straightforward, though. Just like how a song is written through a composition, a photo/image is almost the same thing.  Without the proper composition, your image would never give life.  By composition, I mean a proper mix of colors, framing, lighting, etc.  This is one of the hardest obstacles any artist or photographer might face.  It will either ruin a majestic idea or it will turn your doodle into a wonderful creation you could almost hear the melody of your lines rhythm through your senses (wow, that was almost a mouthful!). Whichever tool you’re comfortable using, it really doesn’t differ a lot as compared to how you could easily interpret your ideas into something much more fruitful than worrying how to work your way around. That’s probably one reason I stuck into using GIMP, not only am I confident it can deliver anything I could 2-dimensionally think of but more importantly I am comfortable using it, which is a very important thing regarding design in my opinion. Just like how I wrote this article, composition comes into play (or you might already have doubted me already?).  Without the drafts and planning I made, I don’t believe I could even finish writing a paragraph of this one. To start off the process, we’ll use one photograph I shot just for this article (in an attempt to recreate the first image I showed you). Or if you don’t want to follow this article thoroughly, you can grab a sample photo from Google Images or from Stock Exchange (www.sxc.hu), just be sure to credit the owner though or whatever conditions or licenses the image has. Photo to work on Photo Enhancement Honestly, the photo we have is already decent enough to work with, but let’s just try making it better so we won’t have to go and adjust it later on. First, let’s open our image and do some primary color correction to it, just in case you’re the type who thinks “something has got to be better, always”.  Go ahead and fire up our tool of choice (GIMP in this case) and open the image (as you can see below). Opening the image in GIMP   With our photo active in our canvas and the layer it is on (which is the only layer that you see in the Layer Window by default), right click on the image, select Color, then choose Levels. Adjusting the image’s color levels is one good way to fix some color cast problems and to edit the color range of your colors non-destructively (extreme cases excluded), another great tool is using the Curves Tool to manipulate your image the same way that you do with Levels. But again, for the sake of this tutorial, we’ll use the levels tool since it’s much easier and faster to edit. You can see a screenshot below of the Levels Tool that we’ll be using in awhile. Levels Tool One nifty tool we can use under our Levels Tool is the Auto function which (you guessed it right again!), automates the color adjustment on our image based on the histogram reading and graph analysis of GIMP. Oftentimes, it makes the task easier for you but it might also ruin your image.  Nothing beats your visual judgment still so if you’re not contented with what the Auto Leveling gives you, go on and move the sliders that you see in the window.  Normally, I only adjust the Value data of the image to correct it’s overall brightness and contrast without altering the overall color mood of the photo.  But if in case you weren’t lucky enough to set your color balance settings on your camera the moment you shot the photo or if you felt the image you’re seeing infront of you is color casted too much, you can freely choose the other color channels (Red, Green, and Blue respectively) from the drop-down menu. You can see a screenshot below on how I adjusted the photo we currently loaded. Value Level Adjustment   RGB Color Level Choices That’s basically all that we need to do to enhance our photo (or you could go ahead and repeat the process a few more times to get the appropriate feel you wanted). If you wanted a safer way of editing (just in case you might run out of undo steps), duplicate your base layer that holds your image and work on the duplicate layer instead of the original one, then you can just switch the visibility on and off to see the changes you’ve made so far.
Read more
  • 0
  • 0
  • 5663

article-image-photo-compositing-gimp-part-2
Packt
07 Dec 2009
5 min read
Save for later

Photo Compositing with The GIMP: Part 2

Packt
07 Dec 2009
5 min read
Adding Realism to the Image As of the current state of our image, it’s almost done.  But we could still do something about adding even more believability to it than just our “2-d object on hand” setup here, right? First thing to consider is that photographed scenes aren’t actually as clean-looking as they are and as compared to common CGish images.  Just to break this cleanliness apart, let’s add in a simple cloud noise to our heart.  If that still doesn’t work for you, you could go ahead and paint over some details like cracks, dirt, etc.  This is to simulate the wear and tear effect that is always present everywhere we look at. To add this texture, let’s first create a new transparent layer to work on and let’s call it “texture” or something much more meaningful to you and easier to remember.  This will be the layer that will hold the cloud texture to use for the heart.  After adding this new layer, right click on the image window and select Filters > Render > Clouds > Solid Noise (as seen in the screenshot below). Creating the Texture Again, a pop-up window will appear wherein you can input values for the noise. This will entirely depend on your preference.  This fill then fill-up the entire layer with the cloud noise texture that we’ll use as overlay image for the heart later on.  Check the screenshot below for my settings. Cloud Noise Options You’ll notice now that what we see is just pure texture which is not what really wanted.  Instead we’ll use it as an overlay effect on top of our layer stack.  Let’s do this by changing the layer mode from Normal to Overlay then let’s adjust the opacity of the texture layer to something relevant and subtle. Texture Overlay However, we notice that the texture is affecting everything in our image including the hand and the cloth.  But we only want the heart to be affected by the texture.  We can do this in a couple of ways: the easiest would be to use the Eraser Tool to erase portions of the texture layer so we only leave the part of the heart, but doing this though will add more layers of undo levels everytime we stroke our eraser. What if we wanted to only have this single layer to work on yet have the flexibility as though we were switching from two layers (an original and a duplicate).  With this in mind, I think it’s time we use Layer Masks for more flexibility over our layer management. To apply our masking, let’s first create a selection to exclude the other parts of the image other than the heart, do this by right clicking on the heart layer then selecting Alpha to Selection. What this will do is select regions of the layer where it is opaque, in this case we’re only selecting the heart shape. Creating the Heart Selection Now with the heart shape selection active, let’s go back and activate our layer texture from which we’ll be creating our layer mask on (be sure that your selection is still active or else it will defeat the purpose of even creating it in the first place).  Right click on the texture layer and select Add Layer Mask (see screenshot). Creating a Layer Mask With the pop-up window that appears, select Black (full transparency) then press Add.  You’ll then notice that the effects the texture has are gone now, that’s because we filled the whole layer mask up with color black (which means full mask), making everything in the layer appear as nothing.  But since we want the current heart selection to have an effect on the layer, we’ll do the reverse instead, by filling up the selection with color white (#FFFFFF). Do this by selecting the layer mask, and not the layer itself, then use the Bucket Fill Tool to fill the selection with white.  Now we’ll notice the effects take place. Applying the Layer Mask   We’re only one step close to finishing the compositing here (yes, finally!). If we’re lucky enough to have gotten this far and not got bored the hell out of us, there’s one thing believably missing in our composition here, and that is the way the two fingers seem to be blocked by the heart (which shouldn’t be).  We should instead see the fingers somehow embrace parts of the heart. With all of our settings for the heart (highlights, shadows, and textures) done, we can now merge all of this into only one layer so we would only be working on one instead of applying the same effect over the rest of the layers which will eventually become a burden.  To merge all of the heart layers, let’s first turn off the visibility of the photograph layer, then right click on any of the layers comprising the heart then choose Merge Visible Layers then choose Expanded as Necessary.  This will then compress all of the heart layers into a single layer which would be very handy for our proceeding steps. Merging Visible Layers  
Read more
  • 0
  • 0
  • 8142
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-seasonal-ebook-offer-45
Packt
04 Dec 2009
1 min read
Save for later

Seasonal eBook Offer: Up to 45% off

Packt
04 Dec 2009
1 min read
Packt eBooks are an immediate and cost effective way of receiving one of our books and are a complete electronic version of the print edition.You will be delighted to know that now you can get 30% off on any ebook of your choice, and if you buy 2 or more ebooks, you get 45% off.
Read more
  • 0
  • 0
  • 1379

article-image-blocking-common-attacks-using-modsecurity-25-part-3
Packt
01 Dec 2009
12 min read
Save for later

Blocking Common Attacks using ModSecurity 2.5: Part 3

Packt
01 Dec 2009
12 min read
Source code revelation Normally, requesting a file with a .php extension will cause mod_php to execute the PHP code contained within the file and then return the resulting web page to the user. If the web server is misconfigured (for example if mod_php is not loaded) then the .php file will be sent by the server without interpretation, and this can be a security problem. If the source code contains credentials used to connect to an SQL database then that opens up an avenue for attack, and of course the source code being available will allow a potential attacker to scrutinize the code for vulnerabilities. Preventing source code revelation is easy. With response body access on in ModSecurity, simply add a rule to detect the opening PHP tag: Prevent PHP source code from being disclosed SecRule RESPONSE_BODY "<?" "deny,msg:'PHP source code disclosure blocked'" Preventing Perl and JSP source code from being disclosed works in a similar manner: # Prevent Perl source code from being disclosed SecRule RESPONSE_BODY "#!/usr/bin/perl" "deny,msg:'Perl source code disclosure blocked'" # Prevent JSP source code from being disclosed SecRule RESPONSE_BODY "<%" "deny,msg:'JSP source code disclosure blocked'" Directory traversal attacks Normally, all web servers should be configured to reject attempts to access any document that is not under the web server's root directory. For example, if your web server root is /home/www, then attempting to retrieve /home/joan/.bashrc should not be possible since this file is not located under the /home/www web server root. The obvious attempt to access the /home/joan directory is, of course, easy for the web server to block, however there is a more subtle way to access this directory which still allows the path to start with /home/www, and that is to make use of the .. symbolic directory link which links to the parent directory in any given directory. Even though most web servers are hardened against this sort of attack, web applications that accept input from users may still not be checking it properly, potentially allowing users to get access to files they shouldn't be able to view via simple directory traversal attacks. This alone is reason to implement protection against this sort of attack using ModSecurity rules. Furthermore, keeping with the principle of Defense in Depth, having multiple protections against this vulnerability can be beneficial in case the web server should contain a flaw that allows this kind of attack in certain circumstances. There is more than one way to validly represent the .. link to the parent directory. URL encoding of .. yields % 2e% 2e, and adding the final slash at the end we end up with % 2e% 2e% 2f(please ignore the space). Here, then is a list of what needs to be blocked: ../ ..% 2f .% 2e/ %  2e%  2e% 2f % 2e% 2e/ % 2e./ Fortunately, we can use the ModSecurity transformation t:urlDecode. This function does all the URL decoding for us, and will allow us to ignore the percent-encoded values, and thus only one rule is needed to block these attacks: SecRule REQUEST_URI "../" "t:urlDecode,deny" Blog spam The rise of weblogs, or blogs, as a new way to present information, share thoughts, and keep an online journal has made way for a new phenomenon: blog comments designed to advertise a product or drive traffic to a website. Blog spam isn't a security problem per se, but it can be annoying and cost a lot of time when you have to manually remove spam comments (or delete them from the approval queue, if comments have to be approved before being posted on the blog). Blog spam can be mitigated by collecting a list of the most common spam phrases, and using the ability of ModSecurity to scan POST data. Any attempted blog comment that contains one of the offending phrases can then be blocked. From both a performance and maintainability perspective, using the @pmFromFile operator is the best choice when dealing with large word lists such as spam phrases. To create the list of phrases to be blocked, simply insert them into a text file, for example, /usr/local/spamlist.txt: viagra v1agra auto insurance rx medications cheap medications ... Then create ModSecurity rules to block those phrases when they are used in locations such as the page that creates new blog comments: # # Prevent blog spam by checking comment against known spam # phrases in file /usr/local/spamlist.txt # <Location /blog/comment.php> SecRule ARGS "@pmFromFile /usr/local/spamlist.txt" "t: lowercase,deny,msg:'Blog spam blocked'" </Location> Keep in mind that the spam list file can contain whole sentences—not just single words—so be sure to take advantage of that fact when creating the list of known spam phrases. SQL injection SQL injection attacks can occur if an attacker is able to supply data to a web application that is then used in unsanitized form in an SQL query. This can cause the SQL query to do completely different things than intended by the developers of the web application. Consider an SQL query like this: SELECT * FROM user WHERE username = '%s' AND password = '%s'; The flaw here is that if someone can provide a password that looks like ' OR '1'='1, then the query, with username and password inserted, will become: SELECT * FROM user WHERE username = 'anyuser' AND password = '' OR '1'='1'; This query will return all users in the results table, since the OR '1'='1' part at the end of the statement will make the entire statement true no matter what username and password is provided. Standard injection attempts Let's take a look at some of the most common ways SQL injection attacks are performed. Retrieving data from multiple tables with UNION An SQL UNION statement can be used to retrieve data from two separate tables. If there is one table named cooking_recipes and another table named user_credentials, then the following SQL statement will retrieve data from both tables: SELECT dish_name FROM recipe UNION SELECT username, password FROM user_credentials; It's easy to see how the UNION statement can allow an attacker to retrieve data from other tables in the database if he manages to sneak it into a query. A similar SQL statement is UNION ALL, which works almost the same way as UNION—the only difference is that UNION ALL will not eliminate any duplicate rows returned in the result. Multiple queries in one call If the SQL engine allows multiple statements in a single SQL query then seemingly harmless statements such as the following can present a problem: SELECT * FROM products WHERE id = %d; If an attacker is able to provide an ID parameter of 1; DROP TABLE products;, then the statement suddenly becomes: SELECT * FROM products WHERE id = 1; DROP TABLE products; When the SQL engine executes this, it will first perform the expected SELECT query, and then the DROP TABLE products statement, which will cause the products table to be deleted. Reading arbitrary files MySQL can be used to read data from arbitrary files on the system. This is done by using the LOAD_FILE() function: SELECT LOAD_FILE("/etc/passwd"); This command returns the contents of the file /etc/passwd. This works for any file to which the MySQL process has read access. Writing data to files MySQL also supports the command INTO OUTFILE which can be used to write data into files. This attack illustrates how dangerous it can be to include user-supplied data in SQL commands, since with the proper syntax, an SQL command can not only affect the database, but also the underlying file system. This simple example shows how to use MySQL to write the string some data into the file test.txt: mysql> SELECT "some data" INTO OUTFILE "test.txt"; Preventing SQL injection attacks There are three important steps you need to take to prevent SQL injection attacks: Use SQL prepared statements. Sanitize user data. Use ModSecurity to block SQL injection code supplied to web applications. These are in order of importance, so the most important consideration should always be to make sure that any code querying SQL databases that relies on user input should use prepared statements. A prepared statement looks as follows: SELECT * FROM books WHERE isbn = ? AND num_copies < ?; This allows the SQL engine to replace the question marks with the actual data. Since the SQL engine knows exactly what is data and what SQL syntax, this prevents SQL injection from taking place. The advantages of using prepared statements are twofold: They effectively prevent SQL injection. They speed up execution time, since the SQL engine can compile the statement once, and use the pre-compiled statement on all subsequent query invocations. So not only will using prepared statements make your code more secure—it will also make it quicker. The second step is to make sure that any user data used in SQL queries is sanitized. Any unsafe characters such as single quotes should be escaped. If you are using PHP, the function mysql_real_escape_string() will do this for you. Finally, let's take a look at strings that ModSecurity can help block to prevent SQL injection attacks. What to block The following table lists common SQL commands that you should consider blocking, together with a suggested regular expression for blocking. The regular expressions are in lowercase and therefore assume that the t:lowercase transformation function is used. SQL code Regular expression UNION SELECT unions+select UNION ALL SELECT unions+alls+select INTO OUTFILE intos+outfile DROP TABLE drops+table ALTER TABLE alters+table LOAD_FILE load_file SELECT * selects+* For example, a rule to detect attempts to write data into files using INTO OUTFILE looks as follows: SecRule ARGS "intos+outfile" "t:lowercase,deny,msg: 'SQL Injection'" The s+ regular expression syntax allows for detection of an arbitrary number of whitespace characters. This will detect evasion attempts such as INTO%20%20OUTFILE where multiple spaces are used between the SQL command words. Website defacement We've all seen the news stories: "Large Company X was yesterday hacked and their homepage was replaced with an obscene message". This sort of thing is an everyday occurrence on the Internet. After the company SCO initiated a lawsuit against Linux vendors citing copyright violations in the Linux source code, the SCO corporate website was hacked and an image was altered to read WE OWN ALL YOUR CODE—pay us all your money. The hack was subtle enough that the casual visitor to the SCO site would likely not be able to tell that this was not the official version of the homepage: The above image shows what the SCO homepage looked like after being defaced—quite subtle, don't you think? Preventing website defacement is important for a business for several reasons: Potential customers will turn away when they see the hacked site There will be an obvious loss of revenue if the site is used for any sort of e-commerce sales Bad publicity will tarnish the company's reputation Defacement of a site will of course depend on a vulnerability being successfully exploited. The measures we will look at here are aimed to detect that a defacement has taken place, so that the real site can be restored as quickly as possible. Detection of website defacement is usually done by looking for a specific token in the outgoing web pages. This token has been placed within the pages in advance specifically so that it may be used to detect defacement—if the token isn't there then the site has likely been defaced. This can be sufficient, but it can also allow the attacker to insert the same token into his defaced page, defeating the detection mechanism. Therefore, we will go one better and create a defacement detection technology that will be difficult for the hacker to get around. To create a dynamic token, we will be using the visitor's IP address. The reason we use the IP address instead of the hostname is that a reverse lookup may not always be possible, whereas the IP address will always be available. The following example code in JSP illustrates how the token is calculated and inserted into the page. <%@ page import="java.security.*" %> <% String tokenPlaintext = request.getRemoteAddr(); String tokenHashed = ""; String hexByte = ""; // Hash the IP address MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(tokenPlaintext.getBytes()); byte[] digest = md5.digest(); for (int i = 0; i < digest.length; i++) { hexByte = Integer.toHexString(0xFF & digest[i]); if (hexByte.length() < 2) { hexByte = "0" + hexByte; } tokenHashed += hexByte; } // Write MD5 sum token to HTML document out.println(String.format("<span style='color: white'>%s</span>", tokenHashed)); %>   Assuming the background of the page is white, the <span style="color: white"> markup will ensure it is not visible to website viewers. Now for the ModSecurity rules to handle the defacement detection. We need to look at outgoing pages and make sure that they include the appropriate token. Since the token will be different for different users, we need to calculate the same MD5 sum token in our ModSecurity rule and make sure that this token is included in the output. If not, we block the page from being sent and sound the alert by sending an email message to the website administrator. # # Detect and block outgoing pages not containing our token # SecRule REMOTE_ADDR ".*" "phase:4,deny,chain,t:md5,t:hexEncode, exec:/usr/bin/emailadmin.sh" SecRule RESPONSE_BODY "!@contains %{MATCHED_VAR}" We are placing the rule in phase 4 since this is required when we want to inspect the response body. The exec action is used to send an email to the website administrator to let him know of the website defacement.
Read more
  • 0
  • 1
  • 11735

article-image-blocking-common-attacks-using-modsecurity-25-part-1
Packt
01 Dec 2009
11 min read
Save for later

Blocking Common Attacks using ModSecurity 2.5: Part 1

Packt
01 Dec 2009
11 min read
Web applications can be attacked from a number of different angles, which is what makes defending against them so difficult. Here are just a few examples of where things can go wrong to allow a vulnerability to be exploited: The web server process serving requests can be vulnerable to exploits. Even servers such as Apache, that have a good security track record, can still suffer from security problems - it's just a part of the game that has to be accepted. The web application itself is of course a major source of problems. Originally, HTML documents were meant to be just that - documents. Over time, and especially in the last few years, they have evolved to also include code, such as client-side JavaScript. This can lead to security problems. A parallel can be drawn to Microsoft Office, which in earlier versions was plagued by security problems in its macro programming language. This, too, was caused by documents and executable code being combined in the same file. Supporting modules, such as mod_php which is used to run PHP scripts, can be subject to their own security vulnerabilities. Backend database servers, and the way that the web application interacts with them, can be a source of problems ranging from disclosure of confidential information to loss of data. HTTP fingerprinting Only amateur attackers blindly try different exploits against a server without having any idea beforehand whether they will work or not. More sophisticated adversaries will map out your network and system to find out as much information as possible about the architecture of your network and what software is running on your machines. An attacker looking to break in via a web server will try to find one he knows he can exploit, and this is where a method known as HTTP fingerprinting comes into play. We are all familiar with fingerprinting in everyday life - the practice of taking a print of the unique pattern of a person's finger to be able to identify him or her - for purposes such as identifying a criminal or opening the access door to a biosafety laboratory. HTTP fingerprinting works in a similar manner by examining the unique characteristics of how a web server responds when probed and constructing a fingerprint from the gathered information. This fingerprint is then compared to a database of fingerprints for known web servers to determine what server name and version is running on the target system. More specifically, HTTP fingerprinting works by identifying subtle differences in the way web servers handle requests - a differently formatted error page here, a slightly unusual response header there - to build a unique profile of a server that allows its name and version number to be identified. Depending on which viewpoint you take, this can be useful to a network administrator to identify which web servers are running on a network (and which might be vulnerable to attack and need to be upgraded), or it can be useful to an attacker since it will allow him to pinpoint vulnerable servers. We will be focusing on two fingerprinting tools: httprint One of the original tools - the current version is 0.321 from 2005, so it hasn't been updated with new signatures in a while. Runs on Linux, Windows, Mac OS X, and FreeBSD. httprecon This is a newer tool which was first released in 2007. It is still in active development. Runs on Windows. Let's first run httprecon against a standard Apache 2.2 server: And now let's run httprint against the same server and see what happens: As we can see, both tools correctly guess that the server is running Apache. They get the minor version number wrong, but both tell us that the major version is Apache 2.x. Try it against your own server! You can download httprint at http://www.net-square.com/httprint/ and httprecon at http://www.computec.ch/projekte/httprecon/. Tip If you get the error message Fingerprinting Error: Host/URL not found when running httprint, then try specifying the IP address of the server instead of the hostname. The fact that both tools are able to identify the server should come as no surprise as this was a standard Apache server with no attempts made to disguise it. In the following sections, we will be looking at how fingerprinting tools distinguish different web servers and see if we are able to fool them into thinking the server is running a different brand of web server software. How HTTP fingerprinting works There are many ways a fingerprinting tool can deduce which type and version of web server is running on a system. Let's take a look at some of the most common ones. Server banner The server banner is the string returned by the server in the Server response header (for example: Apache/1.3.3 (Unix) (Red Hat/Linux)). This banner can be changed by using the ModSecurity directive SecServerSignature. Here is what to do to change the banner: # Change the server banner to MyServer 1.0ServerTokens FullSecServerSignature "MyServer 1.0" Response header The HTTP response header contains a number of fields that are shared by most web servers, such as Server, Date, Accept-Ranges, Content-Length, and Content-Type. The order in which these fields appear can give a clue as to which web server type and version is serving the response. There can also be other subtle differences - the Netscape Enterprise Server, for example, prints its headers as Last-modified and Accept-ranges, with a lowercase letter in the second word, whereas Apache and Internet Information Server print the same headers as Last-Modified and Accept-Ranges. HTTP protocol responses An other way to gain information on a web server is to issue a non-standard or unusual HTTP request and observe the response that is sent back by the server. Issuing an HTTP DELETE request The HTTP DELETE command is meant to be used to delete a document from a server. Of course, all servers require that a user is authenticated before this happens, so a DELETE command from an unauthorized user will result in an error message - the question is just which error message exactly, and what HTTP error number will the server be using for the response page? Here is a DELETE request issued to our Apache server: $ nc bytelayer.com 80DELETE / HTTP/1.0HTTP/1.1 405 Method Not AllowedDate: Mon, 27 Apr 2009 09:10:49 GMTServer: Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2Allow: GET,HEAD,POST,OPTIONS,TRACEContent-Length: 303Connection: closeContent-Type: text/html; charset=iso-8859-1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>405 Method Not Allowed</title></head><body><h1>Method Not Allowed</h1><p>The requested method DELETE is not allowed for the URL /index.html.</p><hr><address>Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2 Server at www.bytelayer.com Port 80</address></body></html> As we can see, the server returned a 405 - Method Not Allowed error. The error message accompanying this response in the response body is given as The requested method DELETE is not allowed for the URL/index.html. Now compare this with the following response, obtained by issuing the same request to a server at www.iis.net: $ nc www.iis.net 80DELETE / HTTP/1.0HTTP/1.1 405 Method Not AllowedAllow: GET, HEAD, OPTIONS, TRACEContent-Type: text/htmlServer: Microsoft-IIS/7.0Set-Cookie: CSAnonymous=LmrCfhzHyQEkAAAANWY0NWY1NzgtMjE2NC00NDJjLWJlYzYtNTc4ODg0OWY5OGQz0; domain=iis.net; expires=Mon, 27-Apr-2009 09:42:35GMT; path=/; HttpOnlyX-Powered-By: ASP.NETDate: Mon, 27 Apr 2009 09:22:34 GMTConnection: closeContent-Length: 1293<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/><title>405 - HTTP verb used to access this page is not allowed.</title><style type="text/css"><!--body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica,sans-serif;background:#EEEEEE;}fieldset{padding:0 15px 10px 15px;}h1{font-size:2.4em;margin:0;color:#FFF;}h2{font-size:1.7em;margin:0;color:#CC0000;}h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;fontfamily:"trebuchet MS", Verdana, sans-serif;color:#FFF;background-color:#555555;}#content{margin:0 0 0 2%;position:relative;}.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}--></style>< /head><body><div id="header"><h1>Server Error</h1></div><div id="content"><div class="content-container"><fieldset> <h2>405 - HTTP verb used to access this page is not allowed.</h2> <h3>The page you are looking for cannot be displayed because aninvalid method (HTTP verb) was used to attempt access.</h3> </fieldset></div></div></body></html> The site www.iis.net is Microsoft's official site for its web server platform Internet Information Services, and the Server response header indicates that it is indeed running IIS-7.0. (We have of course already seen that it is a trivial operation in most cases to fake this header, but given the fact that it's Microsoft's official IIS site we can be pretty sure that they are indeed running their own web server software.) The response generated from IIS carries the same HTTP error code, 405; however there are many subtle differences in the way the response is generated. Here are just a few: IIS uses spaces in between method names in the comma separated list for the Allow field, whereas Apache does not The response header field order differs - for example, Apache has the Date field first, whereas IIS starts out with the Allow field IIS uses the error message The page you are looking for cannot be displayed because an invalid method (HTTP verb) was used to attempt access in the response body Bad HTTP version numbers A similar experiment can be performed by specifying a non-existent HTTP protocol version number in a request. Here is what happens on the Apache server when the request GET / HTTP/5.0 is issued: $ nc bytelayer.com 80GET / HTTP/5.0HTTP/1.1 400 Bad RequestDate: Mon, 27 Apr 2009 09:36:10 GMTServer: Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2Content-Length: 295Connection: closeContent-Type: text/html; charset=iso-8859-1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>400 Bad Request</title></head><body><h1>Bad Request</h1><p>Your browser sent a request that this server could notunderstand.<br /></p><hr><address>Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2 Server at www.bytelayer.com Port 80</address></body></html> There is no HTTP version 5.0, and there probably won't be for a long time, as the latest revision of the protocol carries version number 1.1. The Apache server responds with a 400 - Bad Request Error, and the accompanying error message in the response body is Your browser sent a request that this server could not understand. Now let's see what IIS does: $ nc www.iis.net 80GET / HTTP/5.0HTTP/1.1 400 Bad RequestContent-Type: text/html; charset=us-asciiServer: Microsoft-HTTPAPI/2.0Date: Mon, 27 Apr 2009 09:38:37 GMTConnection: closeContent-Length: 334<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"><HTML><HEAD><TITLE>Bad Request</TITLE><META HTTP-EQUIV="Content-Type" Content="text/html; charset=usascii"></HEAD><BODY><h2>Bad Request - Invalid Hostname</h2><hr><p>HTTP Error 400. The request hostname is invalid.</p></BODY></HTML> We get the same error number, but the error message in the response body differs - this time it's HTTP Error 400. The request hostname is invalid. As HTTP 1.1 requires a Host header to be sent with requests, it is obvious that IIS assumes that any later protocol would also require this header to be sent, and the error message reflects this fact.
Read more
  • 0
  • 0
  • 5656

article-image-moodle-19-math-quizzes-part-3
Packt
01 Dec 2009
3 min read
Save for later

Moodle 1.9 Math Quizzes: Part 3

Packt
01 Dec 2009
3 min read
Using STACK My original problem was this: how can I ask my students to expand (x+4)(x-3) and have Moodle automatically mark my students' answers—hopefully with an answer equivalent to x2+x-12. Let's create that question now. Creating a STACK question Return to your course's front page and, from the course administration block, click on Questions to open the course question bank. Then, follow these steps: Click on the Create new question drop-down menu and choose Opaque: On the Add Opaque Question page, click on Manage Stack Questions: A new window (or tab, depending on your browser) is opened. On the Questions available from STACK question engine page, click on the New Question link: Give your question a name (suitable for you to be able to find it again and know what the question is when you do). Write your question in the Question Stem. You need to be careful with the format: math notation can be written in LaTeX (denoted, in my case, with single dollars). Note how I've specified a variable for the student's answer (#answer#). You can call this variable whatever you like, as long as you enclose it in #: Scroll down to the Update button immediately under the Question Note option and click on it: An Interaction Elements section is now inserted into the page. You will need to specify the answer in the Teacher's Answer row. Be careful with the format as it has to be a valid CAS expression (for example, 3x should be specified as 3*x). When you have filled in your answer, click on the Update button at the bottom of this section: We've asked the question and specified our answer. We now need to program STACK to understand whether or not the student's answer is correct. In the Potential Response Trees block, specify a name for the response and press the + button: The student's answer is stored in the variable answer. My answer needs to be specified in the TAns (teacher's answer box). As this is the correct answer, I can copy and paste from the Teacher's Answer in the Interaction Elements box. Notice that the Answer test is AlgEquiv (algebraic equivalents): Now, click on the Update button at the bottom of the Potential Response Trees section. A common mistake when expanding brackets is to forget to multiply out completely (typically submit x2-12 as the answer). Let's accommodate this now in the Potential Response Trees. Add another PR (potential response) by choosing to add 1 new potential response from the drop-down list and clicking the Add button: Populate the new potential response with the incorrect answer and some feedback. Remember to ensure that they aren't awarded a mark for getting the answer wrong: We now have two nodes in the Potential Response Trees that we need to link together. From the actual correct answer response (node No: 0), click on the Next PR drop-down in the false block and choose 1: Can you see how we are linking potential responses together to form a tree of nodes? Click on the Update button at the bottom of the Potential Responses section to save your changes. Scroll down to the bottom of the page, and click on the Save button: The page reloads, and if we have specified everything correctly, then we now have the opportunity to try our new question. Click on Try question: Try specifying different answers to see how Moodle responds. Make sure any feedback you specified is displayed correctly: When you have finished testing, click on the Finished button at the bottom of the page.
Read more
  • 0
  • 0
  • 2225
article-image-blocking-common-attacks-using-modsecurity-25-part-2
Packt
01 Dec 2009
11 min read
Save for later

Blocking Common Attacks using ModSecurity 2.5: Part 2

Packt
01 Dec 2009
11 min read
Cross-site scripting Cross-site scripting attacks occur when user input is not properly sanitized and ends up in pages sent back to users. This makes it possible for an attacker to include malicious scripts in a page by providing them as input to the page. The scripts will be no different than scripts included in pages by the website creators, and will thus have all the privileges of an ordinary script within the page—such as the ability to read cookie data and session IDs. In this article we will look in more detail on how to prevent attacks. The name "cross-site scripting" is actually rather poorly chosen—the name stems from the first such vulnerability that was discovered, which involved a malicious website using HTML framesets to load an external site inside a frame. The malicious site could then manipulate the loaded external site in various ways—for example, read form data, modify the site, and basically perform any scripting action that a script within the site itself could perform. Thus cross-site scripting, or XSS, was the name given to this kind of attack. The attacks described as XSS attacks have since shifted from malicious frame injection (a problem that was quickly patched by web browser developers) to the class of attacks that we see today involving unsanitized user input. The actual vulnerability referred to today might be better described as a "malicious script injection attack", though that doesn't give it quite as flashy an acronym as XSS. (And in case you're curious why the acronym is XSS and not CSS, the simple explanation is that although CSS was used as short for cross-site scripting in the beginning, it was changed to XSS because so many people were confusing it with the acronym used for Cascading Style Sheets, which is also CSS.) Cross-site scripting attacks can lead not only to cookie and session data being stolen, but also to malware being downloaded and executed and injection of arbitrary content into web pages. Cross-site scripting attacks can generally be divided into two categories: Reflected attacksThis kind of attack exploits cases where the web application takes data provided by the user and includes it without sanitization in output pages. The attack is called "reflected" because an attacker causes a user to provide a malicious script to a server in a request that is then reflected back to the user in returned pages, causing the script to execute. Stored attacksIn this type of XSS attack, the attacker is able to include his malicious payload into data that is permanently stored on the server and will be included without any HTML entity encoding to subsequent visitors to a page. Examples include storing malicious scripts in forum posts or user presentation pages. This type of XSS attack has the potential to be more damaging since it can affect every user who views a certain page. Preventing XSS attacks The most important measure you can take to prevent XSS attacks is to make sure that all user-supplied data that is output in your web pages is properly sanitized. This means replacing potentially unsafe characters, such as angled brackets (< and >) with their corresponding HTML-entity encoded versions—in this case &lt; and &gt;. Here is a list of characters that you should encode when present in user-supplied data that will later be included in web pages: Character HTML-encoded version < &lt; > &gt; ( &#40; ) &#41; # &#35; & &amp; " &quot; ' &#39; In PHP, you can use the htmlentities() function to achieve this. When encoded, the string <script> will be converted into &lt;script&gt;. This latter version will be displayed as <script> in the web browser, without being interpreted as the start of a script by the browser. In general, users should not be allowed to input any HTML markup tags if it can be avoided. If you do allow markup such as <a href="..."> to be input by users in blog comments, forum posts, and similar places then you should be aware that simply filtering out the <script> tag is not enough, as this simple example shows: <a href="http://www.google.com" onMouseOver="javascript:alert('XSS Exploit!')">Innocent link</a> This link will execute the JavaScript code contained within the onMouseOver attribute whenever the user hovers his mouse pointer over the link. You can see why even if the web application replaced <script> tags with their HTML-encoded version, an XSS exploit would still be possible by simply using onMouseOver or any of the other related events available, such as onClick or onMouseDown. I want to stress that properly sanitizing user input as just described is the most important step you can take to prevent XSS exploits from occurring. That said, if you want to add an additional line of defense by creating ModSecurity rules, here are some common XSS script fragments and regular expressions for blocking them: Script fragment Regular expression <script <script eval( evals*( onMouseOver onmouseover onMouseOut onmouseout onMouseDown onmousedown onMouseMove onmousemove onClick onclick onDblClick ondblclick onFocus onfocus PDF XSS protection You may have seen the ModSecurity directive SecPdfProtect mentioned, and wondered what it does. This directive exists to protect users from a particular class of cross-site scripting attack that affects users running a vulnerable version of the Adobe Acrobat PDF reader. A little background is required in order to understand what SecPdfProtect does and why it is necessary. In 2007, Stefano Di Paola and Giorgio Fedon discovered a vulnerability in Adobe Acrobat that allows attackers to insert JavaScript into requests, which is then executed by Acrobat in the context of the site hosting the PDF file. Sound confusing? Hang on, it will become clearer in a moment. The vulnerability was quickly fixed by Adobe in version 7.0.9 of Acrobat. However, there are still many users out there running old versions of the reader, which is why preventing this sort of attack is still an ongoing concern. The basic attack works like this: An attacker entices the victim to click a link to a PDF file hosted on www.example.com. Nothing unusual so far, except for the fact that the link looks like this: http://www.example.com/document.pdf#x=javascript:alert('XSS'); Surprisingly, vulnerable versions of Adobe Acrobat will execute the JavaScript in the above link. It doesn't even matter what you place before the equal sign, gibberish= will work just as well as x= in triggering the exploit. Since the PDF file is hosted on the domain www.example.com, the JavaScript will run as if it was a legitimate piece of script within a page on that domain. This can lead to all of the standard cross-site scripting attacks that we have seen examples of before. This diagram shows the chain of events that allows this exploit to function: The vulnerability does not exist if a user downloads the PDF file and then opens it from his local hard drive. ModSecurity solves the problem of this vulnerability by issuing a redirect for all PDF files. The aim is to convert any URLs like the following: http://www.example.com/document.pdf#x=javascript:alert('XSS'); into a redirected URL that has its own hash character: http://www.example.com/document.pdf#protection This will block any attacks attempting to exploit this vulnerability. The only problem with this approach is that it will generate an endless loop of redirects, as ModSecurity has no way of knowing what is the first request for the PDF file, and what is a request that has already been redirected. ModSecurity therefore uses a one-time token to keep track of redirect requests. All redirected requests get a token included in the new request string. The redirect link now looks like this: http://www.example.com/document.pdf?PDFTOKEN=XXXXX#protection ModSecurity keeps track of these tokens so that it knows which links are valid and should lead to the PDF file being served. Even if a token is not valid, the PDF file will still be available to the user, he will just have to download it to the hard drive. These are the directives used to configure PDF XSS protection in ModSecurity: SecPdfProtect On SecPdfProtectMethod TokenRedirection SecPdfProtectSecret "SecretString" SecPdfProtectTimeout 10 SecPdfProtectTokenName "token" The above configures PDF XSS protection, and uses the secret string SecretString to generate the one-time tokens. The last directive, SecPdfProtectTokenName, can be used to change the name of the token argument (the default is PDFTOKEN). This can be useful if you want to hide the fact that you are running ModSecurity, but unless you are really paranoid it won't be necessary to change this. The SecPdfProtectMethod can also be set to ForcedDownload, which will force users to download the PDF files instead of viewing them in the browser. This can be an inconvenience to users, so you would probably not want to enable this unless circumstances warrant (for example, if a new PDF vulnerability of the same class is discovered in the future). HttpOnly cookies to prevent XSS attacks One mechanism to mitigate the impact of XSS vulnerabilities is the HttpOnly flag for cookies. This extension to the cookie protocol was proposed by Microsoft (see http://msdn.microsoft.com/en-us/library/ms533046.aspx for a description), and is currently supported by the following browsers: Internet Explorer (IE6 SP1 and later) Firefox (2.0.0.5 and later) Google Chrome (all versions) Safari (3.0 and later) Opera (version 9.50 and later) HttpOnly cookies work by adding the HttpOnly flag to cookies that are returned by the server, which instructs the web browser that the cookie should only be used when sending HTTP requests to the server and should not be made available to client-side scripts via for example the document.cookie property. While this doesn't completely solve the problem of XSS attacks, it does mitigate those attacks where the aim is to steal valuable information from the user's cookies, such as for example session IDs. A cookie header with the HttpOnly flag set looks like this: Set-Cookie: SESSID=d31cd4f599c4b0fa4158c6fb; HttpOnly HttpOnly cookies need to be supported on the server-side for the clients to be able to take advantage of the extra protection afforded by them. Some web development platforms currently support HttpOnly cookies through the use of the appropriate configuration option. For example, PHP 5.2.0 and later allow HttpOnly cookies to be enabled for a page by using the following ini_set() call: <?php ini_set("session.cookie_httponly", 1); ?> Tomcat (a Java Servlet and JSP server) version 6.0.19 and later supports HttpOnly cookies, and they can be enabled by modifying a context's configuration so that it includes the useHttpOnly option, like so: <Context> <Manager useHttpOnly="true" /> </Context> In case you are using a web platform that doesn't support HttpOnly cookies, it is actually possible to use ModSecurity to add the flag to outgoing cookies. We will see how to do this now. Session identifiers Assuming we want to add the HttpOnly flag to session identifier cookies, we need to know which cookies are associated with session identifiers. The following table lists the name of the session identifier cookie for some of the most common languages: Language Session identifier cookie name PHP PHPSESSID JSP JSESSIONID ASP ASPSESSIONID ASP.NET ASP.NET_SessionId The table shows us that a good regular expression to identify session IDs would be (sessionid|sessid), which can be shortened to sess(ion)?id. The web programming language you are using might use another name for the session cookie. In that case, you can always find out what it is by looking at the headers returned by the server: echo -e "GET / HTTP/1.1nHost:yourserver.comnn"|nc yourserver.com 80|head Look for a line similar to: Set-Cookie: JSESSIONID=4EFA463BFB5508FFA0A3790303DE0EA5; Path=/ This is the session cookie—in this case the name of it is JESSIONID, since the server is running Tomcat and the JSP web application language. The following rules are used to add the HttpOnly flag to session cookies: # # Add HttpOnly flag to session cookies # SecRule RESPONSE_HEADERS:Set-Cookie "!(?i:HttpOnly)" "phase:3,chain,pass" SecRule MATCHED_VAR "(?i:sess(ion)?id)" "setenv:session_ cookie=%{MATCHED_VAR}" Header set Set-Cookie "%{SESSION_COOKIE}e; HttpOnly" env=session_ cookie We are putting the rule chain in phase 3—RESPONSE_HEADERS, since we want to inspect the response headers for the presence of a Set-Cookie header. We are looking for those Set-Cookie headers that do not contain an HttpOnly flag. The (?i: ) parentheses are a regular expression construct known as a mode-modified span. This tells the regular expression engine to ignore the case of the HttpOnly string when attempting to match. Using the t:lowercase transform would have been more complicated, as we will be using the matched variable in the next rule, and we don't want the case of the variable modified when we set the environment variable.
Read more
  • 0
  • 0
  • 6228

article-image-report-components-nav-2009-part-2
Packt
30 Nov 2009
6 min read
Save for later

Report components in NAV 2009: Part 2

Packt
30 Nov 2009
6 min read
Data item Sections Earlier in our discussion on reports, we referred to the primary components of a report. The Triggers and Properties we have reviewed so far are the data processing components. Next in the report processing sequence are Sections. In Classic RD reports, Sections are the output layout and formatting components. In RTC reports, Sections have a much more limited, but still critically important, role. In the process of creating the initial report design, you may be entering data either completely manually as we've done in our example work, or you may use the Classic Report Wizard. If you use the Wizard, you will end up with Sections defined suitable for Classic Client Report processing. Those Sections may be only rough draft equivalents of what you may want your final report to look like, but they are a suitable starting place for the Classic RD layout work, if that were the tool you were going to use. If you are creating your report completely manually, that is by not using the Wizard, you may also find it appropriate to define Sections to the point that the Classic Client could print a basic, readable report. In our case, we are focusing our production report development effort on the RoleTailored Client, so we will invest minimal effort on Classic Client compatible report layouts. We might do just enough to allow test report runs for data examination purposes and logic flow debugging. However, creating basic Section layouts provides us with another benefit relative to our VS RD layout work, especially if we can create them using the Report Wizard, because all the fields to be used by VS RD must be specified in the Sections. Creating RTC reports via the Classic Report Wizard Let's look at the RTC report development flow again. The preceding image is very similar to the one we studied earlier in this articles, but this flowchart only shows the steps that are pertinent to VS RD. In Step 6 of this flow, there is an option to Create Layout Suggestion in the Visual Studio Report Designer as shown in the following screenshot: When you choose Create Layout Suggestion, the C/SIDE Report Designer will invoke a process that transforms the layout in Sections to a layout in the Visual Studio Report Designer. If a VS RD layout previously existed, the newly created layout will overwrite it. Therefore, this option will normally be used only once, in the initial stages of report design. Let's experiment by using the Report Wizard to create a simple report listing the gifts received by ICAN. We will access the Report Wizard in the Object Designer. Click on Reports | New, then fill in the Wizard screen as shown in the following image. Then click on OK and choose fields to display in the report as shown in the following screenshot. Click on Next, then choose the sorting order (that is index or key) that starts with Donor ID. Click on Next again and choose to Group the data by Donor ID. Click on Next again and choose to create totals for the Estimated Value field. One more, click on Next and choose the List Style for the report, then click on Finish. At this point, you will have generated a Classic Client report using the Report Wizard. If you View | Sections, you should see a C/SIDE report layout that looks much like the following screenshot. Let's save our newly generated report so that, if we need to, we can come back to this point as a checkpoint. Click on File | Save As and assign the report to ID 50002 with the Name of Gifts by Donor. Now click on Tools | Create Layout Suggestion. The process of transforming the Classic Report Layout to a Visual Studio Report Designer Layout will take a few seconds. When the report layout transformation process completes, you should see a screen that looks very similar to the following screenshot. The primary data layout portion of the same VS RD screen is shown in the next image. Compare this to the Classic RD data layout we just looked at a couple of steps ago. You will see some similarities and some considerable differences. Without doing anything else, let's save the VS RD layout we just created for the RoleTailored Client, then run both versions of the report to see the differences in the generated results. To save the VS RD layout, start by simply exiting the VS Report Designer. Once the VS RD screen closes, you will see the following question. Respond by clicking Yes. Then, when you exit the Classic Report Designer, you will see this question. Respond by clicking Yes. You will then be presented with the following message. Again, click on Yes. If there were an error in the RDLC created within the VS RD (such as an incorrect variable name used), an error message similar to the following would display. Since, hopefully, we didn't get such an error message, we can proceed to test both the Classic Client and the RoleTailored Client versions of our generated report. We can test the Classic Client (or C/SIDE RD) version of Report 50002 from the same Object Designer screen where we did our initial design work. Highlight the line for Report 50002 and click on the Run button. You should see the following screen: If we were running this as users, we might want to make a selection of specific Donors here on which to report. As we are just testing, simply click on Preview to see our report onscreen. The report will then appear, looking like the following: As you can see, with minimum development effort (and a minimum of technical knowledge), we have designed and created a report listing Gifts by Donor with subtotals by Donor. The report has proper page and column headings. Not only that, but the report was initiated withs a Request Form allowing application of filters. Close the Classic Client report; now let's run the RTC version. Just like we could do with Pages, we will run our Report test from the Windows Run option. Click on Run and enter the command to run Report 50002, as shown in the next screenshot. Click on OK. If the RoleTailored Client is not active, after a short pause, it will be activated. Then the Request Page will appear. Compare the look and contents of this Request Page with the one we saw previously for the Classic Client. As before, click on Preview and view the report. Of course, this time we're looking at the RTC version. This method of automatic transformation is very useful for getting an initial base for a new report or, obviously, for the complete generation process for a simple report where the requirements for layout are not too restrictive.
Read more
  • 0
  • 0
  • 2556

article-image-ways-improve-performance-your-server-modsecurity-25
Packt
30 Nov 2009
13 min read
Save for later

Ways to improve performance of your server in ModSecurity 2.5

Packt
30 Nov 2009
13 min read
A typical HTTP request To get a better picture of the possible delay incurred when using a web application firewall, it helps to understand the anatomy of a typical HTTP request, and what processing time a typical web page download will incur. This will help us compare any added ModSecurity processing time to the overall time for the entire request. When a user visits a web page, his browser first connects to the server and downloads the main resource requested by the user (for example, an .html file). It then parses the downloaded file to discover any additional files, such as images or scripts, that it must download to be able to render the page. Therefore, from the point of view of a web browser, the following sequence of events happens for each file: Connect to web server. Request required file. Wait for server to start serving file. Download file. Each of these steps adds latency, or delay, to the request. A typical download time for a web page is on the order of hundreds of milliseconds per file for a home cable/DSL user. This can be slower or faster, depending on the speed of the connection and the geographical distance between the client and server. If ModSecurity adds any delay to the page request, it will be to the server processing time, or in other words the time from when the client has connected to the server to when the last byte of content has been sent out to the client. Another aspect that needs to be kept in mind is that ModSecurity will increase the memory usage of Apache. In what is probably the most common Apache configuration, known as "prefork", Apache starts one new child process for each active connection to the server. This means that the number of Apache instances increases and decreases depending on the number of client connections to the server.As the total memory usage of Apache depends on the number of child processes running and the memory usage of each child process, we should look at the way ModSecurity affects the memory usage of Apache. A real-world performance test In this section we will run a performance test on a real web server running Apache 2.2.8 on a Fedora Linux server (kernel 2.6.25). The server has an Intel Xeon 2.33 GHz dual-core processor and 2 GB of RAM. We will start out benchmarking the server when it is running just Apache without having ModSecurity enabled. We will then run our tests with ModSecurity enabled but without any rules loaded. Finally, we will test ModSecurity with a ruleset loaded so that we can draw conclusions about how the performance is affected. The rules we will be using come supplied with ModSecurity and are called the "core ruleset". The core ruleset The ModSecurity core ruleset contains over 120 rules and is shipped with the default ModSecurity source distribution (it's contained in the rules sub-directory). This ruleset is designed to provide "out of the box" protection against some of the most common web attacks used today. Here are some of the things that the core ruleset protects against: Suspicious HTTP requests (for example, missing User-Agent or Accept headers) SQL injection Cross-Site Scripting (XSS) Remote code injection File disclosure We will examine these methods of attack, but for now, let's use the core ruleset and examine how enabling it impacts the performance of your web service. Installing the core ruleset To install the core ruleset, create a new sub-directory named modsec under your Apache conf directory (the location will vary depending on your distribution). Then copy all the .conf files from the rules sub-directory of the source distribution to the new modsec directory: mkdir /etc/httpd/conf/modseccp/home/download/modsecurity-apache/rules/modsecurity_crs_*.conf /etc/httpd/conf/modsec Finally, enter the following line in your httpd.conf file and restart Apache to make it read the new rule files: # Enable ModSecurity core rulesetInclude conf/modsecurity/*.conf Putting the core rules in a separate directory makes it easy to disable them—all you have to do is comment out the above Include line in httpd.conf, restart Apache, and the rules will be disabled. Making sure it works The core ruleset contains a file named modsecurity_crs_10_config.conf. This file contains some of the basic configuration directives needed to turn on the rule engine and configure request and response body access. Since we have already configured these directives, we do not want this file to conflict with our existing configuration, and so we need to disable this. To do this, we simply need to rename the file so that it has a different extension as Apache only loads *.conf files with the Include directive we used above: $ mv modsecurity_crs_10_config.conf modsecurity_crs_10_config.conf.disabled Once we have restarted Apache, we can test that the core ruleset is loaded by attempting to access an URL that it should block. For example, try surfing to http://yourserver/ftp.exe and you should get the error message Method Not Implemented, ensuring that the core rules are loaded. Performance testing basics So what effect does loading the core ruleset have on web application response time and how do we measure this? We could measure the response time for a single request with and without the core ruleset loaded, but this wouldn't have any statistical significance—it could happen that just as one of the requests was being processed, the server started to execute a processor-intensive scheduled task, causing a delayed response time. The best way to compare the response times is to issue a large number of requests and look at the average time it takes for the server to respond. An excellent tool—and the one we are going to use to benchmark the server in the following tests—is called httperf. Written by David Mosberger of Hewlett Packard Research Labs, httperf allows you to simulate high workloads against a web server and obtain statistical data on the performance of the server. You can obtain the program at http://www.hpl.hp.com/research/linux/httperf/ where you'll also find a useful manual page in the PDF file format and a link to the research paper published together with the first version of the tool. Using httperf We'll run httperf with the options --hog (use as many TCP ports as needed), --uri/index.html (request the static web page index.html) and we'll use --num-conn 1000 (initiate a total of 1000 connections). We will be varying the number of requests per second (specified using --rate) to see how the server responds under different workloads. This is what the typical output from httperf looks like when run with the above options: $ ./httperf --hog --server=bytelayer.com --uri /index.html --num-conn1000 --rate 50Total: connections 1000 requests 1000 replies 1000 test-duration20.386 sConnection rate: 49.1 conn/s (20.4 ms/conn, <=30 concurrentconnections)Connection time [ms]: min 404.1 avg 408.2 max 591.3 median 404.5stddev 16.9Connection time [ms]: connect 102.3Connection length [replies/conn]: 1.000Request rate: 49.1 req/s (20.4 ms/req)Request size [B]: 95.0Reply rate [replies/s]: min 46.0 avg 49.0 max 50.0 stddev 2.0 (4samples)Reply time [ms]: response 103.1 transfer 202.9Reply size [B]: header 244.0 content 19531.0 footer 0.0 (total19775.0)Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0CPU time [s]: user 2.37 system 17.14 (user 11.6% system 84.1% total95.7%)Net I/O: 951.9 KB/s (7.8*10^6 bps)Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 The output shows us the number of TCP connections httperf initiated per second ("Connection rate"), the rate at which it requested files from the server ("Request rate"), and the actual reply rate that the server was able to provide ("Reply rate"). We also get statistics on the reply time—the "reply time – response" is the time taken from when the first byte of the request was sent to the server to when the first byte of the reply was received—in this case around 103 milliseconds. The transfer time is the time to receive the entire response from the server. The page we will be requesting in this case, index.html, is 20 KB in size which is a pretty average size for an HTML document. httperf requests the page one time per connection and doesn't follow any links in the page to download additional embedded content or script files, so the number of such links in the page is of no relevance to our test. Getting a baseline: Testing without ModSecurity When running benchmarking tests like this one, it's always important to get a baseline result so that you know the performance of your server when the component you're measuring is not involved. In our case, we will run the tests against the server when ModSecurity is disabled. This will allow us to tell which impact, if any, running with ModSecurity enabled has on the server. Response time The following chart shows the response time, in milliseconds, of the server when it is running without ModSecurity. The number of requests per second is on the horizontal axis: As we can see, the server consistently delivers response times of around 300 milliseconds until we reach about 75 requests per second. Above this, the response time starts increasing, and at around 500 requests per second the response time is almost a second per request. This data is what we will use for comparison purposes when looking at the response time of the server after we enable ModSecurity. Memory usage Finding the memory usage on a Linux system can be quite tricky. Simply running the Linux top utility and looking at the amount of free memory doesn't quite cut it, and the reason is that Linux tries to use almost all free memory as a disk cache. So even on a system with several gigabytes of memory and no memory-hungry processes, you might see a free memory count of only 50 MB or so. Another problem is that Apache uses many child processes, and to accurately measure the memory usage of Apache we need to sum the memory usage of each child process. What we need is a way to measure the memory usage of all the Apache child processes so that we can see how much memory the web server truly uses. To solve this, here is a small shell script that I have written that runs the ps command to find all the Apache processes. It then passes the PID of each Apache process to pmap to find the memory usage, and finally uses awk to extract the memory usage (in KB) for summation. The result is that the memory usage of Apache is printed to the terminal. The actual shell command is only one long line, but I've put it into a file called apache_mem.sh to make it easier to use: #!/bin/sh# apache_mem.sh# Calculate the Apache memory usageps -ef | grep httpd | grep ^apache | awk '{ print $2 }' | xargs pmap -x | grep 'total kB' | awk '{ print $3 }' | awk '{ sum += $1 } END { print sum }' Now, let's use this script to look at the memory usage of all of the Apache processes while we are running our performance test. The following graph shows the memory usage of Apache as the number of requests per second increases: Apache starts out consuming about 300 MB of memory. Memory usage grows steadily and at about 150 requests per second it starts climbing more rapidly. At 500 requests per second, the memory usage is over 2.4 GB—more than the amount of physical RAM of the server. The fact that this is possible is because of the virtual memory architecture that Linux (and all modern operating systems) use. When there is no more physical RAM available, the kernel starts swapping memory pages out to disk, which allows it to continue operating. However, since reading and writing to a hard drive is much slower than to memory, this starts slowing down the server significantly, as evidenced by the increase in response time seen in the previous graph. CPU usage In both of the tests above, the server's CPU usage was consistently around 1 to 2%, no matter what the request rate was. You might have expected a graph of CPU usage in the previous and subsequent tests, but while I measured the CPU usage in each test, it turned out to run at this low utilization rate for all tests, so a graph would not be very useful. Suffice it to say that in these tests, CPU usage was not a factor. ModSecurity without any loaded rules Now, let's enable ModSecurity—but without loading any rules—and see what happens to the response time and memory usage. Both SecRequestBodyAccess and SecResponseBodyAccess were set to On, so if there is any performance penalty associated with buffering requests and responses, we should see this now that we are running ModSecurity without any rules. The following graph shows the response time of Apache with ModSecurity enabled: We can see that the response time graph looks very similar to the response time graph we got when ModSecurity was disabled. The response time starts increasing at around 75 requests per second, and once we pass 350 requests per second, things really start going downhill. The memory usage graph is also almost identical to the previous one: Apache uses around 1.3 MB extra per child process when ModSecurity is loaded, which equals a total increase of memory usage of 26 MB for this particular setup. Compared to the total amount of memory Apache uses when the server is idle (around 300 MB) this equals an increase of about 10%. Mod Security with the core ruleset loaded Now for the really interesting test we'll run httperf against ModSecurity with the core ruleset loaded and look at what that does to the response time and memory usage. Response time The following graph shows the server response time with the core ruleset loaded: At first, the response time is around 340 ms, which is about 35 ms slower than in previous tests. Once the request rate gets above 50, the server response time starts deteriorating. As the request rates grows, the response time gets worse and worse, reaching a full 5 seconds at 100 requests per second. I have capped the graph at 100 requests per second, as the server performance has already deteriorated enough at this point to allow us to see the trend. We see that the point at which memory usage starts increasing has gone down from 75 to 50 requests per second now that we have enabled the core ruleset. This equals a reduction in the maximum number of requests per second the server can handle of 33%.
Read more
  • 0
  • 0
  • 20675
article-image-user-interface-design-icefaces-18-part-2
Packt
30 Nov 2009
11 min read
Save for later

User Interface Design in ICEfaces 1.8: Part 2

Packt
30 Nov 2009
11 min read
Facelets templating To implement the layout design, we use the Facelets templating that is officially a part of the JSF specification since release 2.0. This article will only have a look at certain parts of the Facelets technology. So, we will not discuss how to configure a web project to use Facelets. You can study the source code examples of this article, or have a look at the developer documentation (https://facelets.dev.java.net/nonav/docs/dev/docbook.html) and the articles section of the Facelets wiki (http://wiki.java.net/bin/view/Projects/FaceletsArticles)for further details. The page template First of all, we define a page template that follows our mockup design. For this, we reuse the HelloWorld(Facelets) application. You can import the WAR file now if you did not create a Facelets project. For importing a WAR file, use the menu File | Import | Web | WAR file. In the dialog box, click on the Browse button and select the corresponding WAR file. Click on the Finish button to start the import. The run configuration is done. However, you do not have to configure the Jetty server again. Instead, it can be simply selected as your target. We start coding with a new XHTML file in the WebContent folder. Use the menu File | New | Other | Web | HTML Page and click on the Next button. Use page-template.xhtml for File name in the next dialog. Click on the Next button again and choose New ICEfaces Facelets.xhtml File (.xhtml). Click on the Finish button to create the file. The ICEfaces plugin creates this code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <div id="header"> <ui:include src="/header.xhtml"> <ui:param name="param_name" value="param_value"/> </ui:include> </div> <div id="content"> <ice:form> </ice:form> </div> </body> </html> The structure of the page is almost pure HTML. This is an advantage when using Facelets. The handling of pages is easier and can even be done with a standard HTML editor. The generated code is not what we need. If you try to run this, you will get an error because the header.xhtml file is missing in the project. So, we delete the code between the <body> tags and add the basic structure for the templating. The changed code looks like this: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <table align="center" cellpadding="0" cellspacing="0"> <tr><td><!-- header --></td></tr> <tr><td><!-- main navigation --></td></tr> <tr><td><!-- content --></td></tr> <tr><td><!-- footer --></td></tr> </table> </body> </html> We change the <body> part to a table structure. You may wonder why we use a <table> for the layout, and even the align attribute, when there is a <div> tag and CSS. The answer is pragmatism. We do not follow the doctrine because we want to get a clean code and keep things simple. If you have a look at the insufficient CSS support of the Internet Explorer family and the necessary waste of time to get things running, it makes no sense to do so. The CSS support in Internet Explorer is a good example of the violation of user expectations. We define four rows in the table to follow our layout design. You may have recognized that the <title> tag still has its <ui:insert> definition. This is the Facelets tag we use to tell the templating where we want to insert our page-specific code. To separate the different insert areas from each other, the <ui:insert> has a name attribute. We substitute the comments with the <ui:insert> definitions, so that the templating can do the replacements: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <table align="center" cellpadding="0" cellspacing="0"> <tr><td><ui:insert name="header"/></td></tr> <tr><td><ui:insert name="mainNavigation"/></td></tr> <tr><td><ui:insert name="content"/></td></tr> <tr><td><ui:insert name="footer"/></td></tr> </table> </body> </html> The <ui:insert> tag allows us to set defaults that are used if we do not define something for replacement. Everything defined between <ui:insert> and </ui:insert> will then be shown instead. We will use this to define a standard behavior of a page that can be overwritten, if necessary. Additionally, this allows us to give hints in the rendering output if something that should be defined in a page is missing. Here is the code showing both aspects: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <ice:outputStyle href="/xmlhttp/css/royale/royale.css" /> <title> <ui:insert name="title"> Please, define a title. </ui:insert> </title> </head> <body> <table align="center" cellpadding="0" cellspacing="0"> <tr><td> <ui:insert name="header"> <ice:graphicImage url="/logo.png" /> </ui:insert> </td></tr> <tr><td> <ui:insert name="mainNavigation"> <ice:form> <ice:menuBar noIcons="true"> <ice:menuItem value="Menu 1"/> <ice:menuItem value="Menu 2"/> <ice:menuItem value="Menu 3"/> </ice:menuBar> </ice:form> </ui:insert> </td></tr> <tr><td> <ui:insert name="content"> Please, define some content. </ui:insert> </td></tr> <tr><td> <ui:insert name="footer"> <ice:outputText value="&#169; 2009 by The ICEcubes." /> </ui:insert> </td></tr> </table> </body> </html> The header, the main navigation, and the footer now have defaults. For the page title and the page content, there are messages that ask for an explicit definition. The header has a reference to an image. Add any image you like to the WebContent and adapt the url attribute of the <ice:graphicImage> tag, if necessary. The example project for this article will show the ICEcube logo. It is the logo that is shown in the mockup above. The <ice:menuBar> tag has to be surrounded by a <ice:form> tag, so that the JSF actions of the menu entries can be processed. Additionally, we need a reference to one of the ICEfaces default skins in the <head> tag to get a correct menu presentation. We take the Royale skin here. If you do not know what the Royale skin looks like, you can have a look at the ICEfaces Component Showcase (http://component-showcase.icefaces.org) and select it in the combo box on the top left. After your selection, all components present themselves in this skin definition. Using the template A productive page template has a lot more to define and is also different in its structure. References to your own CSS, JavaScript, or FavIcon files are missing here. The page template would be unmaintainable soon if we were to manage the pull-down menu this way. However, we will primarily look at the basics here. So, we keep the page template for now. Next, we adapt the existing ICEfacesPage1.xhtml to use the page template for its rendering. Here is the original code: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <title> <ui:insert name="title"> Default title </ui:insert> </title> </head> <body> <div id="header"> <!-- <ui:include src="/header.xhtml" > <ui:param name="param_name" value="param_value" /> </ui:include> --> </div> <div id="content"> <ice:form> <ice:outputText value="Hello World!"/> <!-- drop ICEfaces components here --> </ice:form> </div> </body> </html> We keep the Hello World! output and use the new page template to give some decoration to it. First of all, we need a reference to the page template so that the templating knows that it has to manage the page. As the page template defines the page structure, we no longer need a <head> tag definition. You may recognize <ui:insert> in the <title> tag. This is indeed the code we normally use in a page template. Facelets has rendered the content in between because it did not find a replacement tag. Theoretically, you are free to define such statements in any location of your code. However, this is not recommended. Facelets has a look at the complete code base and matches pairs of corresponding name attribute definitions between <ui:insert name="..."> and <ui:define name="..."> tags. Here is the adapted code: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="/page-template.xhtml"> <div id="content"> <ice:form> <ice:outputText value="Hello World!"/> </ice:form> </div> </ui:composition> </body> </html> This code creates the following output: We can see our friendly reminders for the missing title and the missing content. The header, the main navigation, and the footer are rendered as expected. The structure of the template seems to be valid, although we recognize that a CSS fle is necessary to define some space between the rows of our layout table. However, something is wrong. Any idea what it is? If you have a look at the hello-world.xhtml again, you can find our Hello World! output; but this cannot be found in the rendering result. As we use the page template, we have to tell the templating where something has to be rendered in the page. However, we did not do this for our Hello World! output. The following code defines the missing <ui:define> tag and skips the <div> and <ice:form> tags that are not really necessary here: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <body> <ui:composition template="/page-template.xhtml"> <ui:define name="title"> Hello World on Facelets </ui:define> <ui:define name="content"> <ice:outputText value="Hello World!"/> </ui:define> </ui:composition> </body> </html>
Read more
  • 0
  • 0
  • 2540

article-image-drag-and-drop-yui-part-3
Packt
30 Nov 2009
6 min read
Save for later

Drag-and-Drop with the YUI: Part-3

Packt
30 Nov 2009
6 min read
Visual Selection with the Slider Control So far in this chapter we've focused on the functionality provided by the Drag-and-Drop utility. Let's shift our focus back to the interface controls section of the library and look at one of the components which is related very closely to drag-and-drop—the Slider control. A slider can be defined using a very minimal set of HTML. All you need are two elements: the slider background and the slider thumb, with the thumb appearing as a child of the background element: <div id="slider_bg" title="the slider background"><div id="slider_thumb" title="the slider thumb"><img src="images/slider_thumb.gif"></div></div> These elements go together to form the basic Slider control, as shown in below: The Slider control works as a specific implementation of DragDrop in that the slider thumb can be dragged along the slider background either vertically or horizontally. The DragDrop classes are extended to provide additional properties, methods, and events specific to Slider. One of the main concepts differentiating Slider from DragDrop is that with a basic slider, the slider thumb is constrained to just one axis of motion, either X or Y depending on whether the Slider is horizontal or vertical respectively. The Slider is another control that can be animated by including a reference to the Animation control in the head of the page. Including this means that when any part of the slider background is clicked on, the slider thumb will gracefully slide to that point of the background rather than just moving there instantly. The Constructor and Factory Methods The constructor for the slider control is always called in conjunction with one of the three factory methods, depending on which type of slider you want to display. To generate a horizontal slider the YAHOO.widget.Slider.getHorizSlider is called, with the appropriate arguments. To generate a vertical slider, on the other hand, the YAHOO.widget.Slider.getVertSlider would instead be used. There is also another type of slider that can be created—the YAHOO.widget.Slider.getSliderRegion constructor and factory method combination creates a two-dimensional slider, the thumb of which can be moved both vertically and horizontally. There are a range of arguments used with the different types of slider constructor. The first two arguments are the same for all of them, with the first argument corresponding to the id of the background HTML element and the second corresponding to the id of the thumb element. The type of slider you are creating denotes what the next two (or four when using the SliderRegion) arguments relate to. With the horizontal slider or region slider the third argument is the number of pixels that the thumb element can move left, but with the horizontal slider it is the number of pixels it can move up. The fourth argument is either the number of pixels which the thumb can move right, or the number of pixels it can move down. When using the region slider, the fifth and sixth arguments are the number of pixels the thumb element can move up and down, so with this type of slider all four directions must be specified. Alternatively, with either the horizontal or vertical sliders, only two directions need to be accounted for. The final argument (either argument number five for the horizontal or vertical sliders, or argument number seven for the region slider) is optional and refers to the number of pixels between each tick, also known as the tick size. This is optional because you may not use ticks in your slider, therefore making the Slider control analogue rather than digital. Class of Two There are just two classes that make up the Slider control—the YAHOO.widget.Slider class is a subclass of the YAHOO.util.DragDrop class and inherits a whole bunch of its most powerful properties and methods, as well as defining a load more of its own natively. The YAHOO.widget.SliderThumb class is a subclass of the YAHOO.util.DD class and inherits properties and methods from this class (as well as defining a few of its own natively). Some of the native properties defined by the Slider class and available for you to use include: animate—a boolean indicating whether the slider thumb should animate. Defaults to true if the Animation utility is included, false if not animationDuration—an integer specifying the duration of the animation in seconds. The default is 0.2 backgroundEnabled—a boolean indicating whether the slider thumb should automatically move to the part of the background that is selected when clicked. Defaults to true enableKeys—another boolean which enables the home, end and arrow keys on the visitors keyboard to control the slider. Defaults to true, although the slider control must be clicked once with the mouse before this will work keyIncrement—an integer specifying the number of pixels the slider thumb will move when an arrow key is pressed. Defaults to 25 pixels A large number of native methods are also defined in the class, but a good deal of them are used internally by the slider control and will therefore never need to be called directly by you in your own code. There are a few of them that you may need at some point however, including: .getThumb()—returns a reference to the slider thumb .getValue()—returns an integer determining the number of pixels the slider thumb has moved from the start position .getXValue()—an integer representing the number of pixels the slider has moved along the X axis from the start position .getYValue()—an integer representing the number of pixels the slider has moved along the Y axis from the start position .onAvailable()—executed when the slider becomes available in the DOM .setRegionValue() and .setValue()—allow you to programmatically set the value of the region slider's thumb More often than not, you'll find the custom events defined by the Slider control to be most beneficial to you in your implementations. You can capture the slider thumb being moved using the change event, or detect the beginning or end of a slider interaction by subscribing to slideStart or slideEnd respectively. The YAHOO.widget.SliderThumb class is a subclass of the DD class; this is a much smaller class than the one that we have just looked at and all of the properties are private, meaning that you need not take much notice of them. The available methods are similar to those defined by the Slider class, and once again, these are not something that you need to concern yourself with in most basic implementations of the control.
Read more
  • 0
  • 0
  • 2502
Modal Close icon
Modal Close icon