Web Server Algorithm - Modularity
A "main" algorithm for a web server could use modularity to improve its design:
BEGIN
CLEAR session variable
WHILE True
INPUT request
IF "home" IN request.querystring THEN
RETURN home.html
ENDIF
IF "login" IN request.querystring THEN
RETURN login.html
ENDIF
IF "login_post" IN request.querystring AND request.method == "POST" THEN
authenticated = Login(request.form('username'), request.form('password'))
IF authenticated THEN
session['authenticated'] = True
REDIRECT request.querystring = "home"
ELSE
REDIRECT request.querystring = "login"
ENDIF
ENDIF
IF "search" IN request.querystring THEN
term = request.parameter('q')
results = Search(term)
page = Render(results)
RETURN page
ENDIF
...
ENDWHILE
END
Accompanying this algorithm are the modular functions Login, Search and Render:
BEGIN Login (uname, pword)
row = EXECUTE SQL "SELECT username, password FROM Users WHERE username == ?", (uname, )
IF LENGTH(row) > 0 THEN
IF row['password'] == HASH(pword) THEN
RETURN True
ELSE
RETURN False
ENDIF
ELSE
RETURN False
ENDIF
END
BEGIN Search (term)
RETURN EXECUTE SQL "SELECT * FROM Products WHERE category LIKE '%?%' OR productName LIKE '%?%'", (term, term)
END
BEGIN Render (data)
IF LENGTH(data) > 0 THEN
html = "<ul>"
FOR counter = 0 TO LENGTH(data)
html = html + "<li>" + data[counter] + "</li>"
NEXT counter
ENDFOR
html = html + "</ul>"
ELSE
html = "<p>No results found.</p>"
ENDIF
RETURN html
END
Some points of interest:
- The SQL uses placeholders for sanitizing values when formulating the query string (i.e., WHERE username == ?", (uname, )). This is for security to protect against SQL Injection Attack.
- The main algorithm uses a session variable. This variable can be used to store values between pages of the application.
- A hash algorithm is used to match the stored password in the Login algorithm. More on hash algorithms in Unit 4, but this is another security measure.
Once implemented, the modules may function as follows:
def Login (uname, pword):
row = [('admin','abcd1234')] #EXECUTE SQL "SELECT ...
if len(row) > 0:
if row[0][1] == pword: #row['password'] == HASH(pword)
return True
else:
return False #uname correct, pword incorrect
else:
return False #uname incorrect
def Search (term):
return [('phones','Apple iPhone 13'), #EXECUTE SQL "SELECT ...
('phones','Galaxy Samsung S21'),
('accessories','phone case')]
def Render (data):
if len(data) > 0:
html = "<ul>"
for counter, text in enumerate(data):
html = html + "<li>" + str(data[counter]) + "</li>" #alt: + text
html = html + "</ul>"
else:
html = "<p>No results found.</p>"
return html
authenticated = Login(uname='admin', pword='abcd1234')
print('authenticated:', authenticated)
results = Search('phone')
page = Render(results)
print('search results:')
print(page) #RETURN page