Wednesday, May 21, 2008
IWA Performance consideration
This article by Matthew Langston explains how IWA works: http://confluence.slac.stanford.edu/display/Gino/Integrated+Windows+Authentication?decorator=printable. So I don't need to explain it again here.
Since you can't eliminate the 2 401 errors (That's the way IWA works), you can improve on performance by cutting down the amount of data transfered over the network. By default IIS is configured to send the standard HTML file when a 401 error occurs. You need to change the setting in the "Custom Errors" tab (in IIS website properties) and set the 401 errors to send default text message instead of the HTML file. This will reduce amount of data transferred from around 2KB to about 83 bytes. You will see substantial improvement in performance.
This article explains how to change the "custom Errors" properties (Your website setting maybe slightly different): http://support.microsoft.com/kb/817322/en-us
Peace!
Thursday, May 8, 2008
Coding Standards and Guidelines
Coding Standards
1. Introduction
Application developers need to adhere to certain coding standards in order to
enhance the readability and maintainability of the application.
Well written software offers many advantages. It will contain fewer bugs and
will run more efficiently than poorly written programs. Since software has a
life cycle and much of which revolves around maintenance, it will be easier for
the original developer(s) and future keepers of the code to maintain and modify
the software as needed. This will lead to increased productivity of the
developer(s). The overall cost of the software is greatly reduced when the code
is developed and maintained according to software standards.
This guide makes a distinction between standards and guidelines. Standards are
rules which programmers are expected to follow. Guidelines can be viewed as
suggestions which can help programmers write better software and are optional,
but highly recommended.
2. Internal Documentation Standards
If done correctly, internal documentation improves the readability of a software
module. A file containing one of more software modules should have comment block
at its beginning containing the following basic information:
- The name of the author who created the file
- The date the file was created
- The author’s development group
- Description (overview of the purpose of the modules)
Note that a module is a method, function, or subroutine.
Each module contained within the source file should be preceded by a block of comments showing the following:
- The name of the module
- The name of the original author (if the module author is different than the author of the file.)
- The date the module was created
- A description of what the module does
- A list of the calling arguments, their types, and brief explanations of what they do
- A list of required files and/or database tables needed by the routine, indicating if the routine expects
the database or files to be already opened - Return values
- Error codes/exceptions
3. Coding Standards
3.1 Indentation:
Proper and consistent indentation is important in producing easy to read and
maintainable programs. Indentation should be used to:
- Emphasize the body of a control statement such as a loop or a select statement
- Emphasize the body of a conditional statement
- Emphasize a new scope block
Tabs should be used for indentation.
Examples:
/* Indentation used in a loop construct. */
for (int i = 0; i < number_of_employees; ++i)
{
total_wages += employee[i].wages;
if (total_wages > 1,000,000)
{
System.out.println(“Over one million”);
}
}
// Indentation used in the body of a method.
package void get_vehicle_info ( )
{
System.out.println ( “VIN: “ + vin ) ;
System.out.println ( “Make: “ + make ) ;
System.out.println ( “Model: “ + model ) ;
System.out.println ( “Year: “ + year ) ;
}
3.2 Inline Comments
Inline comments explaining the functioning of the subroutine or key aspects of
the algorithm shall be frequently used.
Inline comments should be used to make the code clearer to a programmer trying
to read and understand it. Writing a well structured program lends much to its
readability even without inline comments. The bottom line is to use inline
comments where they are needed to explain complicated program behavior or
requirements. Use inline comments to generalize what a block of code,
conditional structure, or control structure is doing. Do not use overuse inline
comments to explain program details which are readily obvious to an
intermediately skilled programmer.
3.3 Structured Programming
Structured (or modular) programming techniques shall be used. GO TO statements
shall not be used as they lead to “spaghetti” code, which is hard to read and
maintain
3.4 Classes, Subroutines, Functions, and Methods
Keep subroutines, functions, and methods reasonably sized. This depends upon the
language being used. A good rule of thumb for module length is to constrain each
module to one function or action (i.e. each module should only do one “thing”).
If a module grows too large, it is usually because the programmer is trying to
accomplish too many actions at one time.
The names of the classes, subroutines, functions, and methods shall have verbs
in them. That is the names shall specify an action, e.g. “getName”, “computeStatistics”.
3.5 Source Files
The name of the source file or script shall represent its function. All of the
routines in a file shall have a common purpose.
3.6 Variable Names
Variable shall have mnemonic or meaningful names that convey to a casual
observer, the intent of its use. Variables shall be initialized prior to its
first use. Variable names shall be defined in Pascal Case (e.g. getUserInfo,
setMemberProfile).
3.7 Use of Braces
In some languages, braces are used to delimit the bodies of conditional
statements, control constructs, and blocks of scope. Programmers shall use the
following bracing style:
for (int i = 0 ; i < 100; i++)
{
/* Some work is done here. */
}
Braces shall be used even when there is only one statement in the control block.
For example:
Bad:
if (i <= 0)
printf (“Positive number required.\n”);
Better:
if (i <= 0)
{
printf (“Positive number required.\n”);
}
4. Coding Guidelines
General coding guidelines provide the programmer with a set of best practices
which can be used to make programs easier to read and maintain.
4.1 Line Length
It is considered good practice to keep the lengths of source code lines at or
below 80 characters. Lines longer than this may not be displayed properly on
some terminals and tools.
4.2 Spacing
The proper use of spaces within a line of code can enhance readability. Good
rules of thumb are as follows:
- A keyword followed by a parenthesis should be separated by a space.
- A blank space should appear after each comma in an argument list.
- All binary operators except “.” should be separated from their operands by spaces. Blank spaces should never separate unary operators such as unary minus,
increment (“++”), and decrement (“—“) from their operands. - Casts should be made followed by a blank space.
Example:
Bad:
cost=price+(price*sales_tax);
Better:
cost = price + ( price * sales_tax );
4.3 Wrapping Lines
When an expression will not fit on a single line, break it according to these
following principles:
- Break after a comma
Example:
fprintf ( stdout , “\nThere are %d reasons to use standards\n” ,
num_reasons ) ; - Break after an operator
Example:
long int total_apples = num_my_apples + num_his_apples +
num_her_apples ; - Prefer higher-level breaks to lower-level breaks
Example:
Bad:
longName1 = longName2 * (longName3 + LongName4 –
longName5) + 4 * longName6 ;
Better:
longName1 = longName2 * (longName3 + LongName4 – LongName5)
+ 4 * longName6 ; - Align the new line with the beginning of the expression at the same level on the previous line.
Example:
total_windows = number_attic_windows + number_second_floor_windows +
number_first_floor_windows ;
4.4 Program Statements
Program statements should be limited to one per line. Also, nested statements
should be avoided when possible.
Examples:
Bad:
number_of_names = names.length ; b = new JButton [ number_of_names ] ;
Better:
number_of_names = names.length ;
b = new JButton [ number_of_names ] ;
Bad:
strncpy ( city_name , string , strlen ( string ) ) ;
Better:
length = strlen ( string ) ;
strncpy ( city_name , string , length ) ;
4.5 Use of Parentheses
It is better to use parentheses liberally. Even in cases where operator
precedence unambiguously dictates the order of evaluation of an expression,
often it is beneficial from a readability point of view to include parentheses
anyway.
Example:
Acceptable:
total = 3 – 4 * 3 ;
Better:
total = 3 – ( 4 * 3 ) ;
4.6 Coding for Efficiency vs. Coding for Readability
There are many aspects to programming. These include writing software that runs
efficiently and writing software that is easy to maintain. These two goals often
collide with each other. Creating code that runs as efficiently as possible
often means writing code that uses tricky logic and complex algorithms, code
that can be hard to follow and maintain even with ample inline comments.
The programmer needs to carefully weigh efficiency gains versus program
complexity and readability. If a more complicated algorithm offers only small
gains in the speed of a program, the programmer should consider using a simpler
algorithm. Although slower, the simpler algorithm will be easier for other
programmers to understand.
4.7 Meaningful Error Messages
Error handling is an important aspect of computer programming. This not only
includes adding the necessary logic to test for and handle errors but also
involves making error messages meaningful. Error messages should also be stored
in way that makes them easy to review.
Secure Coding Guidelines
Protecting access to your data source is one of the most important goals when
working on the security of your application. To help limit access to your data
source it is imperative to keep connection information such as Username,
Password, data source name, etc. private.
1. Read Only DB User
Applications code must connect to the database as a database user who has read
only access to the data and can’t update or change any data or objects. Only
where necessary (such as admin pages that require update or insert) connect as
another user who has limited privileges to write to only the required database
objects. Also strongly consider using Windows Integrated Authentication to
access SQL Server in your code. If it can’t be used for any reason, avoid
storing clear text password instead store the password encrypted.
2. Validating Inputs
Before using the HTTP inputs provided by end users in a database query, validate
them using regular expressions or other means. For example, the following
ensures that a userid value is an 8-character alphanumeric string.
[Visual Basic] Copy Code
Public Static Function ValidateUserid(inString As String) As Boolean
Dim r As Regex = New Regex("^[A-Za-z0-9]{8}$")
Return r.IsMatch(inString)
End Function
[C#]
public static bool ValidateUserid(string inString)
{
Regex r = new Regex("^[A-Za-z0-9]{8}$");
return r.IsMatch(inString)
}
Validating whether the input data is per our expectation reduces the risk of SQL
injection attacks substantially.
3. Using Parameters (Prepared Statements)
Parameters provide a convenient method for organizing values passed with a SQL
statement or to a stored procedure. Additionally, parameters can guard against a
SQL Insertion attack by ensuring that values received from an external source
are passed as values only, and not part of the SQL statement. As a result, SQL
commands inserted into a value are not executed at the data source. Rather, the
values passed are treated as a parameter value only. The following code shows an
example of using a parameter to pass a value.
[Visual Basic] Copy Code
'Retrieve CustomerID to search for from external source.
Dim custID As String = GetCustomerID()
Dim selectString As String = "SELECT * FROM Customers
WHERE CustomerID = @CustomerID"
Dim cmd As SqlCommand = New SqlCommand(selectString, conn)
cmd.Parameters.Add("@CustomerID", SqlDbType.VarChar, 5).Value = custID
conn.Open()
Dim myReader As SqlDataReader = cmd.ExecuteReader()
'Process results.
myReader.Close()
conn.Close()
[C#]
// Retrieve CustomerID to search for from external source.
string custID = GetCustomerID();
string selectString = @"SELECT * FROM Customers
WHERE CustomerID = @CustomerID";
SqlCommand cmd = new SqlCommand(selectString, conn);
cmd.Parameters.Add("@CustomerID", SqlDbType.VarChar, 5).Value = custID;
conn.Open();
SqlDataReader myReader = cmd.ExecuteReader();
'Process results.
myReader.Close();
conn.Close();
4. Keep Exception / Server Error Information Private
Attackers often use information from an exception, such as the name of your
server, database, or table to mount a specific attack on your system. Because
exceptions can contain specific information about your application or data
source, you can help your application and data source better protected by only
exposing information to the client that is required.
Use friendly error messages such as “Database Connection failed. Please contact
the Customer Support at support@company.com”. Do not display the server errors
or the Exception stack to the end user in production environments.
Saturday, May 3, 2008
Simple Oracle Export script
Set mm=%DATE:~4,2%
Set dd=%DATE:~7,2%
Set yyyy=%DATE:~10,4%
exp system/password file=DMP\sysadm-%yyyy%-%mm%-%dd%.dmp compress=y owner=schema1 consistent=y log=logs\sysadm-%yyyy%-%mm%-%dd%.log
This puts the dump file in a folder called DMP and a log file in the logs folder under the current folder where the script runs with a timestamp in the file name.
Now I know you will ask me how to delete older backups. This link: http://blogs.msdn.com/benjguin/archive/2006/12/01/delete-old-files-script.aspx gives you a script to delete old files based on your needs. Just in case the link doesn't work, here is the script again (Thanks Benjamin):
Delete Old Files script
This sample script (WHICH IS PROVIDED AS IS) may help purging files older than n days in a folder
Just copy the following code to a VBS file (DeleteOldFiles.vbs).
Sample call:
cscript DeleteOldFiles.vbs C:\Windows\Temp 90
The code is:
option explicit
Call DoTheJob()
WScript.Echo "--- end of script execution ---"
Sub DoTheJob
dim limitDate
dim formattedLimitDate
dim folder
dim strComputer
dim objWMIService
dim colFileList
dim objFile
dim nbFiles
dim totalFiles
dim nbErrors
dim result
dim nbDays
if WScript.Arguments.Count <> 2 then
WScript.Echo "usage : DeleteOldFiles.vbs
WScript.Echo "sample: DeleteOldFiles.vbs C:\Windows\temp 90"
Exit Sub
end if
folder = WScript.Arguments(0)
nbDays = WScript.Arguments(1)
'calculate and format limit date
limitDate = DateAdd("d", -1 * nbDays , Date)
formattedLimitDate = DatePart("yyyy", limitDate)
if DatePart("m", limitDate) < formattedlimitdate =" formattedLimitDate" formattedlimitdate =" formattedLimitDate">
if DatePart("d", limitDate) < formattedlimitdate =" formattedLimitDate" formattedlimitdate =" formattedLimitDate">
'show what will be done
WScript.Echo "Will remove files from " & folder & " with a date older than " & formattedLimitDate & " (" & nbDays & " days ago)"
'Get the files and delete the old ones
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colFileList = objWMIService.ExecQuery _
("ASSOCIATORS OF {Win32_Directory.Name='" & folder & "'} Where " _
& "ResultClass = CIM_DataFile")
nbFiles = 0
totalFiles = 0
nbErrors = 0
For Each objFile In colFileList
totalFiles = totalFiles + 1
if objFile.CreationDate < result =" objFile.Delete()" result =" 0" nbfiles =" nbFiles" nberrors =" nbErrors">
'Show the result
Wscript.Echo "Total files in folder: " & totalFiles
WScript.Echo "Deleted files: " & nbFiles
WScript.echo "Errors: " & nbErrors
End Sub