Archive for October, 2008
URL Layout
URL Layout
Canonical URLs
- Description:
- On some webservers there are more than one URL for a resource. Usually there are canonical URLs (which should be actually used and distributed) and those which are just shortcuts, internal ones, etc. Independed which URL the user supplied with the request he should finally see the canonical one only.
- Solution:
- We do an external HTTP redirect for all non-canonical URLs to fix them in the location view of the Browser and for all subsequent requests. In the example ruleset below we replace
/~userby the canonical/u/userand fix a missing trailing slash for/u/user.RewriteRule ^/~([^/]+)/?(.*) /u/$1/$2 [R] RewriteRule ^/([uge])/([^/]+)$ /$1/$2/ [R]
Canonical Hostnames
- Description:
- …
- Solution:
-
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC] RewriteCond %{HTTP_HOST} !^$ RewriteCond %{SERVER_PORT} !^80$ RewriteRule ^/(.*) http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R] RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*) http://fully.qualified.domain.name/$1 [L,R]
Moved DocumentRoot
- Description:
- Usually the DocumentRoot of the webserver directly relates to the URL “
/”. But often this data is not really of top-level priority, it is perhaps just one entity of a lot of data pools. For instance at our Intranet sites there are/e/www/(the homepage for WWW),/e/sww/(the homepage for the Intranet) etc. Now because the data of the DocumentRoot stays at/e/www/we had to make sure that all inlined images and other stuff inside this data pool work for subsequent requests. - Solution:
- We just redirect the URL
/to/e/www/. While is seems trivial it is actually trivial with mod_rewrite, only. Because the typical old mechanisms of URL Aliases (as provides by mod_alias and friends) only used prefix matching. With this you cannot do such a redirection because the DocumentRoot is a prefix of all URLs. With mod_rewrite it is really trivial:RewriteEngine on RewriteRule ^/$ /e/www/ [R]
Trailing Slash Problem
- Description:
- Every webmaster can sing a song about the problem of the trailing slash on URLs referencing directories. If they are missing, the server dumps an error, because if you say
/~quux/fooinstead of/~quux/foo/then the server searches for a file namedfoo. And because this file is a directory it complains. Actually is tries to fix it themself in most of the cases, but sometimes this mechanism need to be emulated by you. For instance after you have done a lot of complicated URL rewritings to CGI scripts etc. - Solution:
- The solution to this subtle problem is to let the server add the trailing slash automatically. To do this correctly we have to use an external redirect, so the browser correctly requests subsequent images etc. If we only did a internal rewrite, this would only work for the directory page, but would go wrong when any images are included into this page with relative URLs, because the browser would request an in-lined object. For instance, a request for
image.gifin/~quux/foo/index.htmlwould become/~quux/image.gifwithout the external redirect! So, to do this trick we write:RewriteEngine on RewriteBase /~quux/ RewriteRule ^foo$ foo/ [R]
The crazy and lazy can even do the following in the top-level
.htaccessfile of their homedir. But notice that this creates some processing overhead.RewriteEngine on RewriteBase /~quux/ RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.+[^/])$ $1/ [R]
Webcluster through Homogeneous URL Layout
- Description:
- We want to create a homogenous and consistent URL layout over all WWW servers on a Intranet webcluster, i.e. all URLs (per definition server local and thus server dependent!) become actually server independed! What we want is to give the WWW namespace a consistent server-independend layout: no URL should have to include any physically correct target server. The cluster itself should drive us automatically to the physical target host.
- Solution:
- First, the knowledge of the target servers come from (distributed) external maps which contain information where our users, groups and entities stay. The have the form
user1 server_of_user1 user2 server_of_user2 : :We put them into files
map.xxx-to-host. Second we need to instruct all servers to redirect URLs of the forms/u/user/anypath /g/group/anypath /e/entity/anypathto
http://physical-host/u/user/anypath http://physical-host/g/group/anypath http://physical-host/e/entity/anypathwhen the URL is not locally valid to a server. The following ruleset does this for us by the help of the map files (assuming that server0 is a default server which will be used if a user has no entry in the map):
RewriteEngine on RewriteMap user-to-host txt:/path/to/map.user-to-host RewriteMap group-to-host txt:/path/to/map.group-to-host RewriteMap entity-to-host txt:/path/to/map.entity-to-host RewriteRule ^/u/([^/]+)/?(.*) http://${user-to-host:$1|server0}/u/$1/$2 RewriteRule ^/g/([^/]+)/?(.*) http://${group-to-host:$1|server0}/g/$1/$2 RewriteRule ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2 RewriteRule ^/([uge])/([^/]+)/?$ /$1/$2/.www/ RewriteRule ^/([uge])/([^/]+)/([^.]+.+) /$1/$2/.www/$3\
Add comment October 20, 2008
The Apache configuration htpasswd, md5, mod_rewrite,
The Apache configuration file httpd.conf contains settings applied to all hosted domains, and also domain specific settings (settings contained in <VirtualHost> tags). Of course you don’t want your users to edit the httpd.conf file, but fortunately they can do site specific settings themselves by allowing them to use .htaccess files.
It’s easy…
A .htaccess file (note the dot in front of the filename) is a plain text file with settings in it. It can be placed at the root of a website or any sub directory. The settings in it will apply to the current and all sub directories in the current directory.
First of all, you must set the AllowOverride directive in httpd.conf. AllowOverrride controls which types of directives that are allowed in .htaccess files.:
<Directory “/usr/local/www/test.com”>
AllowOverride All
</Directory>
Add a section like the above for each of the domains you want to allow using .htaccess.
Remember to restart Apache to make the changes take effect.
The following sections of this page, describes som examples of using .htaccess files.
Note: Instruct your users to use ASCII mode when uploading .htaccess files. If BINARY mode is used the file will NOT work.
Password protection using a password file
This section describes how to protect all or part of a website against unauthorized access. The content of the .htaccess file:
AuthUserFile /usr/local/www/secure_directory/.htpasswd
AuthGroupFile /dev/null
AuthName “My protected site”
AuthType Basic
require valid-user
In the first line, replace bolded text with the path to your own protected area. In the third line, replace bolded text with a text of your choice. This text will appear in the login boks.
You may need to CHMOD the .htaccess file to 644 or (RW-R–R–). This makes the file usable by the server.
Create a directory just above your website root. This is where you will create your password file, and we don’t want this in a public directory.
For example, my password file is in /usr/local/www/secure_directory/
Now, you need to create the .htpasswd file. You can do it manually by putting each users username an password into it:
pas:ffff;
Each line must end with a line break, and there must be an empty line at the end of the file.
Another way of creating the password file is by using the htpasswd command, but this requires ssh access to the server.
htpasswd -c /usr/local/www/secure_directory/.htpasswd pas
New password:
Re-type new password:
Adding password for user pas
Next time you want to create a user, ommit the -c option (this is important to remember, or you will override the existing users/passwords in the file). For security reasons, passwords do not show op on the screen as you type.
This example shows how to change the password for an existing user (bold text is all in one line):
htpasswd -b /usr/local/www/secure_directory/.htpasswd pas fff
Updating password for user pas
Add comment October 20, 2008
function html to text
function htmltotext($html)
{
$tags = array (
0 => ‘~<h[123][^>]+>~si’,
1 => ‘~<h[456][^>]+>~si’,
2 => ‘~<table[^>]+>~si’,
3 => ‘~<tr[^>]+>~si’,
4 => ‘~<li[^>]+>~si’,
5 => ‘~<br[^>]+>~si’,
6 => ‘~<p[^>]+>~si’,
7 => ‘~<div[^>]+>~si’,
);
$html = preg_replace($tags,”\n”,$html);
$html = preg_replace(‘~</t(d|h)>\s*<t(d|h)[^>]+>~si’,’ – ‘,$html);
$html = preg_replace(‘~<[^>]+>~s’,”,$html);
$html = preg_replace(‘~ +~s’,’ ‘,$html);
$html = preg_replace(‘~^\s+~m’,”,$html);
$html = preg_replace(‘~\s+$~m’,”,$html);
$html = preg_replace(‘~\n+~s’,”\n”,$html);
return $html;
}
Add comment October 18, 2008
function error php
function error( $message )
{
echo ‘<div style=”color:red;font-weight:bold;font-size:12pt;font-family:monospace”>’.
“infobox::$message</div>”;
} // eof error()
Add comment October 18, 2008
Function php infoboxes with cookie
function infoboxes()
{
if( isset( $_COOKIE['infoboxes'] ))
{
if( $this->debug) echo $_COOKIE['infoboxes'];
$this->showinfoboxex = ( $_COOKIE['infoboxes'] == ‘ON’ );
}
}
Add comment October 18, 2008
function checkitems combolbox list c-sharp
public void CheckItem(string sItem)
{
for (int i = 0; i < cblPinakes.Items.Count; i++)
{
if (cblPinakes.Items[i].ToString() == sItem)
{
cblPinakes.SetItemChecked(i, true);
cblPinakes.SetSelected(i, true);
}
}
}
Add comment October 18, 2008
Function c# Load tables from sql 2000 -2005
public void Load_Tables()
{
dataSetPinakes.Tables[0].Clear();
System.Data.SqlClient.SqlCommand sqlcmdselect = new SqlCommand();
sqlcmdselect.CommandText = “select name, ‘0′ as seeĀ from sysobjects where xtype=’U'” ;
sqlcmdselect.Connection = MSSqlcon;
System.Data.SqlClient.SqlDataAdapter sqlDataAdapter_kos = new SqlDataAdapter();
sqlDataAdapter_kos.SelectCommand = sqlcmdselect;
try
{
sqlDataAdapter_kos.Fill(dataSetPinakes.Tables[0]);
DataRow[] row_select = dataSetPinakes.Tables[0].Select();
cblPinakes.Items.Clear();
for (int bb = 0; bb < row_select.Length; bb++)
{
object obj = row_select[bb][0].ToString();
cblPinakes.Items.Add(obj);
}
DataTable dt = dataSetPinakes.Tables[0].Copy();
dt.Clear();
dt.ReadXml(“Tables.xml”);
DataRow[] rowsel = dt.Select();
for (int ii = 0; ii < rowsel.Length; ii++)
{
if (rowsel[ii][1].ToString() == “1″)
{
CheckItem(rowsel[ii][0].ToString());
}
}
}
catch (Exception ex)
{ MessageBox.Show(ex.ToString()); }
}
Add comment October 18, 2008
isIdentity sql query
select COLUMNPROPERTY(object_id(‘tmp’),’id1′,’isIdentity’)
sp_configure ‘allow update’, 1
go
reconfigure with override
go
update syscolumns set colstat = colstat – 1
where id = object_id(‘tmp’)
and name = ‘id1′
go
exec sp_configure ‘allow update’, 0
go
reconfigure with override
go
Add comment October 18, 2008
Function c# run sql destination
public void runsqldestination(string query)
{
string sqlupd = query;
SqlCommand cmd6 = new SqlCommand(sqlupd, MSSqlcon2);
cmd6.CommandTimeout = 99920;
try
{
cmd6.ExecuteNonQuery();
}
catch
{ MessageBox.Show(” Error ! “); }
}
Add comment October 18, 2008
Convert dataset to sql query insert
public void GetDataset(DataSet ds, string TableName)
{
string squeryInsert = “insert into ” + TableName + ” (“;
for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
{
if (i == 0)
{
squeryInsert = squeryInsert + ds.Tables[0].Columns[i].ToString();
}
else
{
squeryInsert = squeryInsert + “,” + ds.Tables[0].Columns[i].ToString();
}
}
squeryInsert = squeryInsert + “) values ( “;
DataRow[] row1 = ds.Tables[0].Select();
string squery = “”;
for (int ii = 0; ii < row1.Length; ii++)//pernoume ta rows
{
for (int i = 0; i < ds.Tables[0].Columns.Count; i++)// pernoume ta column
{
if (i == 0)
{
squery = squery + “N’” + row1[ii][i].ToString().Replace(“‘”, “””).Replace(@”\”, @”\\”) + “‘”;
}
else
{
squery = squery + “,N” + “‘” + row1[ii][i].ToString().Replace(“‘”, “””).Replace(@”\”, @”\\”) + “‘”;
}
}
squery = squeryInsert + squery + ” )”;
RunSql(squery);
runsqldestination(squery);
lblProgressBar.Text = “ProgessĀ ” + TableName.ToUpper() + ” :”;
progressBar1.Maximum = row1.Length;
progressBar1.Minimum = 0;
progressBar1.Value = ii;
Application.DoEvents();
squery = “”;
}
}
Add comment October 18, 2008