30.11.07

PHP: sleep - Manual

PHP: sleep - Manual: "Regarding the use of sleep to discourage crackers, there is an alternative that could be used. Derived from the 'HTTP Digest Access Authentication' concept at http://www.faqs.org/rfcs/rfc2617.html under chapter '3 Digest Access Authentication Scheme'. For every time the login page is requested, have the server generate and remember a nonce and attach it to the login form. When the form comes back with that nonce, check if the nonce received matches the one in memory. If yes, continue the login process, otherwise reject the login attempt. Throw away the nonce after one use. Brute-force cracking won't be an option in this case, because the hacker/cracker must download the login page for every attempt to try a password. And this will also neatly sidestep a possible weakness via the use of 'sleep' to DoS attacks."

28.11.07

Web Hosts for WordPress

There are hundreds of thousands of web hosts out there, the vast majority of which meet the WordPress minimum requirements, and choosing one from the crowd can be a chore. Just like flowers need the right enviroment to grow, WordPress works best when it's in a rich hosting environment. We've dealt with more hosts than you can imagine; in our opinion, the hosts below represent some of the best and brightest of the hosting world. If you do decide to go with one of the hosts below and click through from this page, some will donate a portion of your fee back—so you can have a great host and support WordPress at the same time.

If you don't need the flexibility of a full web host, you may consider getting a free blog on WordPress.com.

AN Hosting AN Hosting

“AN Hosting offers a number of WordPress Specific features, such as: Automatic WordPress Installation (free of charge) and WordPress Theme Library (also free of charge) access. Hosting package includes unlimited MySQL databases, 250 GB of Disk Space, 2.5 TB of transfer, Unlimited Sub Domains, Free Fanastico, 99.9% Uptime Guarantee and the ability to host 10 sites on 1 account. No setup fees or hidden charges, just $6.95/month.”

HostICan HostICan

“HostICan is the preferred host for any WordPress user. Their WordPress specific setup features one-click WordPress installation (free!). The hosting package includes: 200 GB of Disk Space, 2000 GB of monthly Transfer, 99.99% Uptime Guarantee, Fantastico, and unlimited sub domains and MySQL databases. You're getting the best offer on the market all for just $6.95/mo.”

DreamHost DreamHost

“WordPress auto-install and upgrade, 160GB disk storage, 1.6 TB bandwidth, free domain, unlimited databases, 3000 email accounts, unlimited domain forwarding, Jabber support.” Dreamhost supports mod_security. (They call it "extra web security" in their control panel.)

Laughing Squid Laughing Squid

“Laughing Squid Web Hosting is an independently owned and operated web host, based out of San Francisco, that provides friendly, dependable and secure web hosting services to artists, individuals, bloggers, non-profits, and small businesses. We are open source geeks who are here to help you get your content online and rescue you from the endless void of impersonal and unreliable web hosting.”

Aaron Wall on Why Most Bloggers Need a Day Job to Afford a Cup of Coffee

The Problem

Bloggers create large pools of relevant content, and due to the social nature of blogs many bloggers have built up significant trust with search engines. But, as mentioned in Brian Clark’s Teaching Sells report,
some bloggers get thousands of visitors a day, but can hardly afford a cup of coffee for their efforts.

The big problem with blogging is that there is an echo effect to it, and bloggers end up chasing the same keywords that other bloggers are targeting, and many of these have limited commercial viability.

The Solution

Instead of comparing your blog to other blogs, you can step outside of that echo chamber by comparing your site to commercially oriented sites in your field. Blogs have significant authority and Google’s algorithms tend to prefer to rank informational pages to commercial sites, so you should be able to outrank commercial sites for some of their most important keywords.

Search Google for shopping or commerce related keywords in your field and find sites worth replicating. Then go to Compete Search Analytics and pull down their analytics reports, which will show you the top keywords sending real traffic to competing sites and blogs. You can refine this data one step further by using Google’s Traffic Estimator tool to sort keywords by estimated value. Even if you don’t know where to start, Compete.com Search Analytics offers over 100 categories of keywords, which help you find keywords worth targeting and sites worth replicating.

You should still write all the blog posts you usually would, but from time to time I recommend digging into Compete Search Analytics and Google to find topics that are financially viable. Why not leverage your blog to pay for that next cup of coffee? :-)

Aaron Wall is the author of SEO Book. He provides search engine marketing consultations via Clientside SEM. He and his wife recently published the Blogger’s Guide to SEO.

27.11.07

JavaScript fuzzer available

JavaScript fuzzer available

August 2nd, 2007

Mike Shaver and I just finished presenting “Building and Breaking the Browser”at Blackhat today in Las Vegas. We discussed the methods and tools that Mozilla uses to secure the Firefox browser. These tools include a fuzzer for Javascript, which has led to the discovery and resolution of dozens of critical security bugs. Fuzzers are tools that generate a large amount of input in order to test the robustness of a piece of software and can be used to identify potential vulnerabilities.

This is the tool we discussed in our presentation, the first in a series of security tools that we intend to make publicly available.

https://bugzilla.mozilla.org/show_bug.cgi?id=jsfunfuzz

The responsible sharing of security tools is an important way to contribute to the overall health of the web. We worked with Microsoft, Apple, and Opera to reduce the possibility that this tool might adversely affect users of those browsers. All of these browser vendors reviewed the tool and let us know that they were okay with the release.

Shades of Web Development


Experiments with web technologies, a place of old, new, radical, and controversial ideas and code. On this page, you'll find news, links to technologies and ways to pimp your website.


Experimente mit Netztechnologien, ein Ort der alten, neuen, radikalen und umstrittenen Ideen und des Codes. Auf dieser Seite finden Sie Nachrichten, Verbindungen zu Technologien und Weisen zu kuppeln Ihre Web site.


, ����� ������, �����, �����������, � �������������� ���� � ������. �� ���� ��������, �� ������� , ���������� � pimp ���� website.


Experimenten met Webtechnologieën, een plaats van oude, nieuwe, radicale, en controversiële ideeën en code. Voor deze pagina, zult u vinden nieuws, verbindingen aan technologieën en manieren aan pooi uw website.


实验以 网技术, 老, 新, 根本, 和有争议的想法和代码地方。在这页, 您将发现 新闻, 链接 技术 并且方式 拉皮条您的网站.


웹 기술 에 실험, 오래 되고는, 새롭고, 과격하, 논쟁적인 아이디어 및 부호의 장소. 이 페이지에, 너는 발견할 것이다 뉴스, 연결에 기술 그리고 방법에 너의 웹사이트는 뚜쟁이질를 한다.


網の技術 の実験、古く、新しく、根本的な、論争の的になる考えおよびコードの場所。このページで、見つける ニュース、リンクへの 技術 そして方法への あなたのウェブサイトはpimp。


Experiências com tecnologias da correia fotorreceptora, um lugar de idéias e do código velhos, novos, radicais, e controversos. Nesta página, você encontrará notícia, ligações a tecnologias e maneiras a pimp seu Web site.


Esperimenti con le tecnologie di fotoricettore, un posto di vecchi, nuovi, idee e codice radicali e e discutibili. A questa pagina, troverete notizie, collegamenti a tecnologie e sensi a pimp il vostro Web site.


Expériences avec des technologies d'enchaînement, un endroit de vieux, nouveaux, radicaux, et controversés idées et code. À cette page, vous trouverez nouvelles, liens à technologies et manières à sont souteneurs votre site Web.


Experimentos con tecnologías de la tela, un lugar de viejos, nuevos, radicales, y polémicos ideas y código. En esta página, usted encontrará noticias, acoplamientos a tecnologías y maneras a pimp su Web site.

26.11.07

Tips to Speed Up WordPress Plugin Development

WordPress Tips for Plugin Developers to make plugins easier to create and use.

read more | digg story

Give visitors the choice to open or save a pdf using .htaccess and php

.htaccess and php example serves .pdf files to give visitors the choice to open in an external program or save to disk without having to open it in the browser

read more | digg story

25.11.07

10.11.07

W3C Mobile Web Initiative

W3C Mobile Web Initiative

Internationalization Best Practices: Handling Right-to-left Scripts in XHTML and HTML Content

Internationalization Best Practices: Handling Right-to-left Scripts in XHTML and HTML Content

Great List of W3C.org Software

0x000000 ◊ The Hacker Webzine

Apache Fun.


Good to know Apache, You might be wondering what I'm mumbling about, okay I will tell you. Anyone who ever played with Apache knows the standard error documents as defined in apache2.conf et al. What not everyone knows is that most versions of Apache have templates that the error documents include when a problem is found. These so called templates are the .html.var files and you can access them without restrictions. While that isn't a big security issue, you might want to consider this twice. In the pages you can find info about the webserver, sometimes path disclosure and almost always the webmaster's email address. It's fairly easy to write a script that visits these pages and collects these email addresses because all these pages are more or less the same. There are further directory traversals -or canonicalization issues- but those are present in 2.0.39 and previous 2.0.x and on Windows systems only.

Here is one for Mozilla:
http://www.mozilla.org/error/HTTP_VARIANT_ALSO_VARIES.html.var

Oh gosh I'm vulnerable too:
http://www.0x000000.com/error/HTTP_VARIANT_ALSO_VARIES.html.var

Not that I care that much, since it's not my email address. Still if you have access to your Apache configuration, and have a high profile website it would be a smart idea to turn this stuff off. And no, this is not a h4ck0r zerodayish thingy, it is pretty well known.

Here is why:
/error/HTTP_BAD_REQUEST.html.var

/error/HTTP_UNAUTHORIZED.html.var

/error/HTTP_FORBIDDEN.html.var

/error/HTTP_NOT_FOUND.html.var

/error/HTTP_METHOD_NOT_ALLOWED.html.var

/error/HTTP_REQUEST_TIME_OUT.html.var

/error/HTTP_GONE.html.var

/error/HTTP_LENGTH_REQUIRED.html.var

/error/HTTP_PRECONDITION_FAILED.html.var

/error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var

/error/HTTP_REQUEST_URI_TOO_LARGE.html.var

/error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var

/error/HTTP_INTERNAL_SERVER_ERROR.html.var

/error/HTTP_NOT_IMPLEMENTED.html.var

/error/HTTP_BAD_GATEWAY.html.var

/error/HTTP_SERVICE_UNAVAILABLE.html.var

/error/HTTP_VARIANT_ALSO_VARIES.html.var

apache warn after gutsy upgrade - Ubuntu Forums

# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE! If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the LockFile documentation
# (available at );
# you will save yourself a lot of trouble.

ServerRoot "/etc/apache2"

# The LockFile directive sets the path to the lockfile used when Apache
# is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or
# USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at
# its default value. The main reason for changing it is if the logs
# directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL
# DISK. The PID of the main server process is automatically appended to
# the filename.

LockFile /var/lock/apache2/accept.lock

# PidFile: The file in which the server should record its process
# identification number when it starts.

PidFile /var/run/apache2.pid

# Timeout: The number of seconds before receives and sends time out.

Timeout 300

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.

KeepAlive On

# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.

MaxKeepAliveRequests 100

# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.

KeepAliveTimeout 15

##
## Server-Pool Size Regulation (MPM specific)
##

# prefork MPM
# StartServers ......... number of server processes to start
# MinSpareServers ...... minimum number of server processes which are kept spare
# MaxSpareServers ...... maximum number of server processes which are kept spare
# MaxClients ........... maximum number of server processes allowed to start
# MaxRequestsPerChild .. maximum number of requests a server process serves

StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 20
MaxRequestsPerChild 0


# pthread MPM
# StartServers ......... initial number of server processes to start
# MaxClients ........... maximum number of server processes allowed to start
# MinSpareThreads ...... minimum number of worker threads which are kept spare
# MaxSpareThreads ...... maximum number of worker threads which are kept spare
# ThreadsPerChild ...... constant number of worker threads in each server process
# MaxRequestsPerChild .. maximum number of requests a server process serves

StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0


# perchild MPM
# NumServers ........... constant number of server processes
# StartThreads ......... initial number of worker threads in each server process
# MinSpareThreads ...... minimum number of worker threads which are kept spare
# MaxSpareThreads ...... maximum number of worker threads which are kept spare
# MaxThreadsPerChild ... maximum number of worker threads in each server process
# MaxRequestsPerChild .. maximum number of connections per server process (then it dies)

NumServers 5
StartThreads 5
MinSpareThreads 5
MaxSpareThreads 10
MaxThreadsPerChild 20
MaxRequestsPerChild 0
AcceptMutex fcntl


User www-data
Group www-data

# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent


# Global error log.
ErrorLog /var/log/apache2/error.log

# Include module configuration:
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf

# Include all the user configurations:
Include /etc/apache2/httpd.conf

# Include ports listing
Include /etc/apache2/ports.conf

# Include generic snippets of statements
Include /etc/apache2/conf.d/[^.#]*

#Let's have some Icons, shall we?
Alias /icons/ "/usr/share/apache2/icons/"

Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all


# Set up the default error docs.
#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
#
# Some examples:
ErrorDocument 500 /ServerError.html
ErrorDocument 404 /DocumentNotFound.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
ErrorDocument 403 /Forbidden.html
#

#
# Putting this all together, we can Internationalize error responses.
#
# We use Alias to redirect any /error/HTTP_.html.var response to
# our collection of by-error message multi-language collections. We use
# includes to substitute the appropriate text.
#
# You can modify the messages' appearance without changing any of the
# default HTTP_.html.var files by adding the line;
#
# Alias /error/include/ "/your/include/path/"
#
# which allows you to create your own set of files by starting with the
# /usr/local/apache2/error/include/ files and
# copying them to /your/include/path/, even on a per-VirtualHost basis.
#



Alias /error/ "/usr/share/apache2/error/"


AllowOverride None
Options IncludesNoExec
AddOutputFilter Includes html .shtml
AddHandler type-map var
Order allow,deny
Allow from all
LanguagePriority en es de fr
ForceLanguagePriority Prefer Fallback


ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
ErrorDocument 410 /error/HTTP_GONE.html.var
ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
ErrorDocument 415 /error/HTTP_SERVICE_UNAVAILABLE.html.var
ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var




DirectoryIndex index.shtml index.html index.cgi index.pl index.php index.xhtml

# UserDir is now a module
#UserDir public_html
#UserDir disabled root

#
# AllowOverride FileInfo AuthConfig Limit
# Options Indexes SymLinksIfOwnerMatch # IncludesNoExec
#


AccessFileName .htaccess


Order allow,deny
Deny from all


UseCanonicalName Off

TypesConfig /etc/mime.types
DefaultType text/plain

HostnameLookups Off

IndexOptions FancyIndexing VersionSort

AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip

AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*

# This really should be .jpg.

AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core

AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^


# This is from Matty J's patch. Anyone want to make the icons?
#AddIcon /icons/dirsymlink.jpg ^^SYMDIR^^
#AddIcon /icons/symlink.jpg ^^SYMLINK^^

DefaultIcon /icons/unknown.gif

ReadmeName README.html
HeaderName HEADER.html

IndexIgnore .??* *~ *# HEADER* RCS CVS *,t

AddEncoding x-compress Z
AddEncoding x-gzip gz tgz

AddLanguage da .dk
AddLanguage nl .nl
AddLanguage en .en
AddLanguage et .et
AddLanguage fr .fr
AddLanguage de .de
AddLanguage el .el
AddLanguage it .it
AddLanguage ja .ja
AddLanguage pl .po
AddLanguage ko .ko
AddLanguage pt .pt
AddLanguage no .no
AddLanguage pt-br .pt-br
AddLanguage ltz .ltz
AddLanguage ca .ca
AddLanguage es .es
AddLanguage sv .se
AddLanguage cz .cz
AddLanguage ru .ru
AddLanguage tw .tw
AddLanguage zh-tw .tw

LanguagePriority en da nl et fr de el it ja ko no pl pt pt-br ltz ca es sv tw


#AddDefaultCharset ISO-8859-1

AddCharset ISO-8859-1 .iso8859-1 .latin1
AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen
AddCharset ISO-8859-3 .iso8859-3 .latin3
AddCharset ISO-8859-4 .iso8859-4 .latin4
AddCharset ISO-8859-5 .iso8859-5 .latin5 .cyr .iso-ru
AddCharset ISO-8859-6 .iso8859-6 .latin6 .arb
AddCharset ISO-8859-7 .iso8859-7 .latin7 .grk
AddCharset ISO-8859-8 .iso8859-8 .latin8 .heb
AddCharset ISO-8859-9 .iso8859-9 .latin9 .trk
AddCharset ISO-2022-JP .iso2022-jp .jis
AddCharset ISO-2022-KR .iso2022-kr .kis
AddCharset ISO-2022-CN .iso2022-cn .cis
AddCharset Big5 .Big5 .big5
# For russian, more than one charset is used (depends on client, mostly):
AddCharset WINDOWS-1251 .cp-1251 .win-1251
AddCharset CP866 .cp866
AddCharset KOI8-r .koi8-r .koi8-ru
AddCharset KOI8-ru .koi8-uk .ua
AddCharset ISO-10646-UCS-2 .ucs2
AddCharset ISO-10646-UCS-4 .ucs4
AddCharset UTF-8 .utf8

AddCharset GB2312 .gb2312 .gb
AddCharset utf-7 .utf7
AddCharset utf-8 .utf8
AddCharset big5 .big5 .b5
AddCharset EUC-TW .euc-tw
AddCharset EUC-JP .euc-jp
AddCharset EUC-KR .euc-kr
AddCharset shift_jis .sjis

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

AddType application/x-tar .tgz

# To use CGI scripts outside /cgi-bin/:
#
AddHandler cgi-script .cgi

# To use server-parsed HTML files
#



AddType text/html .shtml
AddOutputFilter INCLUDES .shtml



# If you wish to use server-parsed imagemap files, use
#
#AddHandler imap-file map

BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

#
# The following directive disables redirects on non-GET requests for
# a directory that does not include the trailing slash. This fixes a
# problem with Microsoft WebFolders which does not appropriately handle
# redirects for folders with DAV methods.
#

BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
BrowserMatch "^WebDrive" redirect-carefully
BrowserMatch "^gnome-vfs" redirect-carefully
BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully

# Allow server status reports, with the URL of http://servername/server-status
# Change the ".your_domain.com" to match your domain to enable.
#
#
# SetHandler server-status
# Order deny,allow
# Deny from all
# Allow from .your_domain.com
#


# Allow remote server configuration reports, with the URL of
# http://servername/server-info (requires that mod_info.c be loaded).
# Change the ".your_domain.com" to match your domain to enable.
#
#
# SetHandler server-info
# Order deny,allow
# Deny from all
# Allow from .your_domain.com
#


# Include the virtual host configurations:
Include /etc/apache2/sites-enabled/[^.#]*



# allow .htaccess files

Options Indexes MultiViews
AllowOverride Authconfig
Order allow,deny
Allow from all


# added to include awstats directory
Include /etc/apache2/awstats.conf

Using MySql with WordPress

This article is an overview for developers of the process WordPress uses to build your blog pages, and how plugins can modify that process. It is aimed at developers of plugins that will do advanced queries and permalinks, and also at developers who want to understand WordPress better, in order to add new features to the core of WordPress or fix WordPress bugs.

For more details, you'll need to read the WordPress core PHP files and functions mentioned.

So, here are the steps WordPress uses to decide what posts or pages to display on a page, and display them:

  1. When a visitor first clicks on or types a URL for a page that is part of your blog, WordPress starts by running a few core files (wp-config.php, wp-settings.php, etc.) If you are interested in the specifics of the file loading order, start at index.php and follow the chain of files as each PHP file includes/requires additional PHP files.
  2. WordPress loads and initializes any plugins you have activated (calls the plugin init actions).
  3. WordPress loads the "text domain" for internationalization, and the functions.php file from the currently active theme.
  4. WordPress runs the wp() function (in wp-includes/functions.php), which calls $wp->main() ($wp is an object of class WP, which is defined in wp-includes/classes.php). This tells WordPress to:
    1. Parse the URL into a query specification using WP->parse_request() -- more on that below.
    2. Set all the is_ variables that are used by Conditional Tags using $wp_query->parse_query() ($wp_query is an object of class WP_Query, which is defined in wp-includes/query.php). Note that in spite of this function's name, in this case WP_Query->parse_query doesn't actually do any parsing for us, since that is done before-hand by WP->parse_request().
    3. Convert the query specification into a MySQL database query, and run the database query to get the list of posts, in function WP_Query->get_posts(). Save the posts in the $wp_query object to be used in the WordPress Loop.
    4. Handle 404 errors.
    5. Send the blog's HTTP headers.
    6. Set up some variables for the WordPress Loop.
  5. WordPress loads your template, figures out which template file to use according to the Template Hierarchy, and runs that file (basically doing whatever your template file says to do). Or, WordPress could run one of the feed files (such as wp-rss2.php) instead.
  6. Generally, the template or feed file runs the WordPress Loop to print blog posts or a static page.
  7. The template or feed file will also likely print out permalinks to some archives, categories, or posts using built-in WordPress functions.

More on WP->parse_request()

As mentioned above, WP->parse_request() (part of class WP in wp-includes/classes.php) parses a URL into a query specification. Here is a summary of the steps it uses to do this:

  1. Strips the GET variable section out of the URL (i.e. anything after a "?" in the URL). Also strips out the blog's home URL.
  2. Obtains the rewrite rules that are currently in effect, by calling $wp_rewrite->wp_rewrite_rules() ($wp_rewrite is an object of class WP_Rewrite, which is defined in wp-includes/rewrite.php). The rewrite rules are basically a set of pattern matching rules for WordPress permalinks, with a specification of what to do if the pattern matches. For instance, by default there is a rule that would match a stripped permalink like category/abc, and its specification says that it means the "abc" category was requested. There is also a rewrite rule for the home page (nothing after the blog URL).
  3. Goes through the rewrite rules in order, until it finds a match between a rewrite rule and the permalink. If nothing is found, it's a 404 error. If a match is found, WordPress extracts the information according to the rule specification.
  4. Obtains the list of query variables that is currently in effect. For each query variable, WordPress checks to see if it has been set by permalink parsing, POST submission, or GET submission, and if so, WordPress saves the variable's value into the query specification array ($wp->query_vars, part of class WP in wp-includes/classes.php).

What Plugins can Modify

Here is an overview of the things a plugin can do to modify the default query and permalink behavior described above. Many of these modifications are described (with examples) in the article Custom Queries.

  • Add, modify, or remove rewrite rules, to affect how permalinks are parsed. This is generally not done with filters and actions, but instead by calling functions in wp-includes/rewrite.php, such as add_rewrite_rule, add_rewrite_endpoint, etc. This can be a bit tricky, because WP_Rewrite->wp_rewrite_rules() usually just gets the previously-saved set of rewrite rules (they are saved in the WordPress database as option "rewrite_rules"). So if you want to modify rewrite rules, you will need to call $wp_rewrite->flush_rules() to force them to recalculate. You'll need to do this in your plugin's init action, so that it happens early enough in the process.
  • Add or remove query variables, to affect which variables are saved in the query specification from POST, GET, and permalink requests (query_vars filter).
  • Modify the query specification, after variable values are saved (request filter or parse_request action; if you want to use conditional tag tests, use the parse_query or pre_get_posts action, as these run after the is_ variables are set).
  • Modify the MySQL database query, after it is created from the query specification (posts_where, posts_join, posts_groupby, posts_orderby, posts_distinct, posts_fields, post_limits, posts_where_paged, posts_join_paged, and posts_request filters).
  • Modify the results of the database query (the_posts filter).
  • Override the default template file choice (template_redirect action).