Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

QueryString Javascript

function qs() {
	var data = [];
	this.Read = function() 
	{
		var aPairs, aTmp;
		var queryString = new String(window.location.search);
		queryString = queryString.substr(1, queryString.length); //remove "?"
		aPairs = queryString.split("&");	
		
		for (var i=0 ; i<aPairs.length; i++)
		{
			aTmp = aPairs[i].split("=");
			data[aTmp[0]] = aTmp[1];
		}
	}
	
	this.GetValue = function( key )
	{
		return data[key];
	}
	this.SetValue = function( key, value )
	{
		if (value == null)
			delete data[key];
		else 
			data[key] = value;
	}
	this.ToString = function()
	{
		var queryString = new String(""); 
		
		for (var key in data)
		{	
			if (queryString != "")
				queryString += "&"
			if (data[key])
				queryString += key + "=" + data[key];		
		}
		if (queryString.length > 0)
			return "?" + queryString;
		else
			return queryString;
	}
	this.Clear = function()
	{
		delete data;
		data = [];
	}
}

Log website response times with cURL in windows

This code snippet should be saved as a batch file and run in Windows. It can be set up as a scheduled task to log response times at a fixed interval. It takes one argument, the URL, which should be enclosed in quotes or Windows will barf on URLs with = (equals) signs in. If you don't supply any arguments, you will be prompted. Binary versions of curl are available via google.

If you have ISA:
REM measure response times for a site:
@echo off
IF a%1 == a (
  SET /P varHost=Enter the address, e.g. http://google.com: 
) ELSE (
  SET varHost=%1
)
SET startTime=%date% %time%
curl.exe --proxy-ntlm --proxy yourISAproxy:8080 --proxy-user username:password -s %varHost% > fulloutput.txt
echo %startTime%,%date% %time%,%varHost% >> respTimeLog.txt


If you have no proxy:
REM measure response times for a site:
@echo off
IF a%1 == a (
  SET /P varHost=Enter the address, e.g. http://google.com: 
) ELSE (
  SET varHost=%1
)
SET startTime=%date% %time%
curl -s %varHost% > fulloutput.txt
echo %startTime%,%date% %time%,%varHost% >> respTimeLog.txt

Get remote file size, following redirects (PHP)

function get_remote_file_size($url, $readable = true){
   $parsed = parse_url($url);
   $host = $parsed["host"];
   $fp = @fsockopen($host, 80, $errno, $errstr, 20);
   if(!$fp) return false;
   else {
       @fputs($fp, "HEAD $url HTTP/1.1\r\n");
       @fputs($fp, "HOST: $host\r\n");
       @fputs($fp, "Connection: close\r\n\r\n");
       $headers = "";
       while(!@feof($fp))$headers .= @fgets ($fp, 128);
   }
   @fclose ($fp);
   $return = false;
   $arr_headers = explode("\n", $headers);
   foreach($arr_headers as $header) {
			// follow redirect
			$s = 'Location: ';
			if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
				$url = trim(substr($header, strlen($s)));
				return get_remote_file_size($url, $readable);
			}
			
			// parse for content length
       $s = "Content-Length: ";
       if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
           $return = trim(substr($header, strlen($s)));
           break;
       }
   }
   if($return && $readable) {
			$size = round($return / 1024, 2);
			$sz = "KB"; // Size In KB
			if ($size > 1024) {
				$size = round($size / 1024, 2);
				$sz = "MB"; // Size in MB
			}
			$return = "$size $sz";
   }
   return $return;
}

Authenticated Digest for Net:HTTPHeader

Allows authenticated requests to be made.

Based off of http://theexciter.com/articles/bingo and updated for Ruby 1.8.6

Use by calling

    req.digest_auth(username, password, res)


on an HTTP request object before asking for a response.

# net_digest_auth.rb
require 'digest/md5'
require 'net/http'

module Net
  module HTTPHeader
    @@nonce_count = -1
    CNONCE = Digest::MD5.new.update("%x" % (Time.now.to_i + rand(65535))).hexdigest
    def digest_auth(user, password, response)
      # based on http://segment7.net/projects/ruby/snippets/digest_auth.rb
      @@nonce_count += 1

      response['www-authenticate'] =~ /^(\w+) (.*)/

      params = {}
      $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }

      a_1 = "#{user}:#{params['realm']}:#{password}"
      a_2 = "#{@method}:#{@path}"
      request_digest = ''
      request_digest << Digest::MD5.new.update(a_1).hexdigest
      request_digest << ':' << params['nonce']
      request_digest << ':' << ('%08x' % @@nonce_count)
      request_digest << ':' << CNONCE
      request_digest << ':' << params['qop']
      request_digest << ':' << Digest::MD5.new.update(a_2).hexdigest

      header = []
      header << "Digest username=\"#{user}\""
      header << "realm=\"#{params['realm']}\""
      
      header << "qop=#{params['qop']}"

      header << "algorithm=MD5"
      header << "uri=\"#{@path}\""
      header << "nonce=\"#{params['nonce']}\""
      header << "nc=#{'%08x' % @@nonce_count}"
      header << "cnonce=\"#{CNONCE}\""
      header << "response=\"#{Digest::MD5.new.update(request_digest).hexdigest}\""

      @header['Authorization'] = header
    end
  end
end

httpd.rb

// Simple ruby webrick server

require 'webrick'

# The :AccessLog configuration takes an array.
# Each element of the array should be
# a two-element array where the first element
# is the stream (or anything responding to <<)  and
# the second element is the access log format.
# Please see webrick/accesslog.rb for available formats.

access_log_stream = File.open('C:\\Documents and Settings\\madann\\My Documents\\access.log', 'w')
access_log = [ [ access_log_stream, WEBrick::AccessLog::COMBINED_LOG_FORMAT ] ]

DocumentRoot = 'C:\\Documents and Settings\\madann\\My Documents\\Public_html\\';
HTTPPort = 8008

begin
   d = Dir.open(DocumentRoot)
rescue
   puts "Creating Documentroot"
   mkdir DocumentRoot
end

class DownloadHandler < WEBrick::HTTPServlet::AbstractServlet
    def do_get(req,resp)
        p "req : ",req
        p "resp : ",resp
    end

    def go_post(req,resp)
        resp
    end
end


s = WEBrick::HTTPServer.new(
  :Port             => HTTPPort,
  :DocumentRoot     => DocumentRoot,
  :FancyIndexing    => true
  #:Logger          => WEBrick::Log.new('download.log'),
  #:AccessLog       => access_log
)

s.mount("/cgi-bin",
        WEBrick::HTTPServlet::FileHandler,
        "C:\\Documents and Settings\\madann\\My Documents\\Public_html\\cgi-bin\\",
        {:FancyIndexing=>true})

trap("INT"){ s.shutdown }
s.start

rsrcmeter v2

TextDrive: Simple disk usage and HTTP bandwidth counts
This script will allow a TextDrive account holder to easily see their disk usage and monthly HTTP bandwidth consumption, until TextPanel provides the information.
The first time you use rsrcmeter, it may take additional time, as it will be scanning every Apache/HTTP log file for usage information and caching it by month.
(Updated version from http://textsnippets.com/posts/show/632)

Quick install instructions and most up-to-date version is at http://rsrcmeter.textjoy.com/.

Download latest version at http://rsrcmeter.textjoy.com/rsrcmeter-latest.txt.
(Does not appear to work on Shared Accelerators, for disk quota, since the quota tools doesn't return any output currently and doesn't support the group option.)

Sample output:
Disk usage: 23.7227 MiB (Quota: 10.0000 GiB | 0.2% used)
Bandwidth:
Nov 2006: 0.5494 MiB (Month to Date)
Oct 2006: 0.5087 MiB
Sep 2006: 0.5523 MiB
Aug 2006: 1.1567 MiB


#!/usr/local/bin/ruby
# Unofficial TxD Disk & HTTP Bandwidth Usage Meter (rsrcmeter)
# Version 2.0.2
# Written by AJ Zmudosky
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND WITHOUT WARRANTY OF
# ANY KIND. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
# DAMAGES HOWEVER CAUSED, AND ON ANY THEORY OF LIABILITY, ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.

require 'date'
require 'optparse'

# E-mail regexp
module RFC2822
  EmailAddress = begin
    alpha = "a-zA-Z"
    digit = "0-9"
    atext = "[#{alpha}#{digit}\!\#\$\%\&\'\*+\/\=\?\^\_\`\{\|\}\~\-]"
    dot_atom_text = "#{atext}+([.]#{atext}*)*"
    dot_atom = "#{dot_atom_text}"
    qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
    text = "[\\x01-\\x09\\x11\\x12\\x14-\\x7f]"
    quoted_pair = "(\\x5c#{text})"
    qcontent = "(?:#{qtext}|#{quoted_pair})"
    quoted_string = "[\"]#{qcontent}+[\"]"
    atom = "#{atext}+"
    word = "(?:#{atom}|#{quoted_string})"
    obs_local_part = "#{word}([.]#{word})*"
    local_part = "(?:#{dot_atom}|#{quoted_string}|#{obs_local_part})"
    no_ws_ctl = "\\x01-\\x08\\x11\\x12\\x14-\\x1f\\x7f"   
    dtext = "[#{no_ws_ctl}\\x21-\\x5a\\x5e-\\x7e]"
    dcontent = "(?:#{dtext}|#{quoted_pair})"
    domain_literal = "\\[#{dcontent}+\\]"
    obs_domain = "#{atom}([.]#{atom})*"
    domain = "(?:#{dot_atom}|#{domain_literal}|#{obs_domain})"
    addr_spec = "#{local_part}\@#{domain}"
    pattern = /^#{addr_spec}$/
  end
end

# Default options
opt = {
  :base_dir => ENV['HOME'],
  :stat_file => 'histstat',
  :temp_file => 'temp-rsrcmeter-bwcalc',
  :bw_months => 5
}

# Our option flag parsing
OptionParser.new do |opts|
  opts.banner = "Unofficial TxD Disk & HTTP Bandwidth Usage Meter\nUsage: rsrcmeter [options]"
  
  opts.on("-b", "--base BASE", "Change the base directory, defaults to user's $HOME", String) {|base|
    if File.exists?(base)
      opt[:base_dir] = base
    else
      raise(ArgumentError, "Directory (#{base}) specified with -b does not exist")
    end
  }
  
  opts.on("--stat-file FILE", "Change default historical data file from '#{opt[:stat_file]}'", String) {|file|
    opt[:stat_file] = file
  }
  
  opts.on("--temp-file FILE", "Change default temporary file from '#{opt[:temp_file]}'", String) {|file|
    opt[:temp_file] = file
  }
  
  opts.on("-m NUM", "Number of months' bandwidth to show prior to current month (default: #{opt[:bw_months]})", Integer) {|mons|
    opt[:bw_months] = mons if mons > 0
  }
  
  opts.on("-e", "--email ADDRESS", "E-mail results to ADDRESS *instead* of outputting to the screen", String) {|addr|
    if RFC2822::EmailAddress =~ addr
      opt[:email_to] = addr
    else
      raise(ArgumentError, "Invalid e-mail address provided to -e")
    end
  }
  
  opts.on_tail("-h", "--help", "Show this message") do
    puts opts
    exit
  end
end.parse!

Dir.chdir(opt[:base_dir])
File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])

# Look for existing monthly statistics file
if File.exists?(opt[:stat_file])
  # Load and process existing stats
  @stats = Array.new
  lines = File.readlines(opt[:stat_file])
  lines.each {|l| (@stats << [l.chomp.split(',')[0], l.chomp.split(',')[1].to_f]) unless (l.strip)[0,1] == '#'}
  @stats.sort!
  # Determine if any months need to be added
  if Date.today.month == 1
    pm_year = Date.today.year - 1
    pm_month = 12
  else
    pm_year = Date.today.year
    pm_month = Date.today.month - 1
  end
  stop_month = pm_year.to_s + (pm_month < 10 ? '0' : '') + pm_month.to_s
  proc_year = @stats.last[0][0,4].to_i
  proc_month = @stats.last[0][4,2].to_i
  proc_year += 1 if proc_month == 12
  proc_month = (proc_month == 12) ? 1 : proc_month + 1
  proc_str = proc_year.to_s + (proc_month < 10 ? '0' : '') + proc_month.to_s
  # Add any months not already calculated
  while proc_str <= stop_month
    datestr = proc_str + "??"
    File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])
    `cat logs/access_log.#{datestr} 2>/dev/null > #{opt[:temp_file]}`
    `cat domains/*/logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
    `zcat logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
    `zcat domains/*/logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
    month_usage = `cat #{opt[:temp_file]} | awk '{sum += $10} END {print sum}'`.chomp.to_i
    @stats << [proc_str, month_usage]
    # advance counting
    proc_year += 1 if proc_month == 12
    proc_month = (proc_month == 12) ? 1 : proc_month + 1
    proc_str = proc_year.to_s + (proc_month < 10 ? '0' : '') + proc_month.to_s
  end
# Statistics files doesn't exist
else
  # Look for earliest log file
  file_list = Array.new
  Dir.foreach(opt[:base_dir] + "/logs") {|i| file_list << i if /^access_log.\d{8}/ =~ i}
  if File.exists?(opt[:base_dir] + "/domains")
    domains = Array.new
    Dir.foreach(opt[:base_dir] + "/domains") {|dom| domains << dom if /^\w+\.\w+/ =~ dom}
    domains.each {|dom| Dir.foreach(opt[:base_dir] + "/domains/" + dom + "/logs") {|i| file_list << i if /^access_log.\d{8}/  =~ i}}
  end
  file_list.sort!
  unless Date.today.year.to_s + Date.today.month.to_s == file_list.first[11,6]
    # Process from earliest_log year/month forward
    earliest_log_year = file_list.first[11,4]
    earliest_log_month = file_list.first[15,2]
    @stats = Array.new
    earliest_log_year.to_i.upto(Date.today.year) do |year|
      start_month = (earliest_log_year.to_i == year) ? earliest_log_month.to_i : 1;
      start_month.upto(12) do |month|
        unless (year == Date.today.year and month >= Date.today.month)
          month = "0" + month.to_s if month < 10
          datestr = year.to_s + month.to_s + '??'
          File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])
          `cat logs/access_log.#{datestr} 2>/dev/null > #{opt[:temp_file]}`
          `cat domains/*/logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
          `zcat logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
          `zcat domains/*/logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
          month_usage = `cat #{opt[:temp_file]} | awk '{sum += $10} END {print sum}'`.chomp.to_i
          @stats << [year.to_s + month.to_s, month_usage]
        end
      end
    end
  end
end

# Write @stats back to opt[:stat_file] to record any changes
File.open(opt[:stat_file], 'w') {|f|
  f.puts "# rsrcmeter historical statistics file"
  f.puts "# Contains only completed months"
  @stats.each {|i| f.puts i[0] + ',' + i[1].to_s}
}

# Calculate bandwidth consumption for current month
datestr = Date.today.year.to_s + Date.today.month.to_s + "??"
`cat logs/access_log 2>/dev/null > #{opt[:temp_file]}`
`cat domains/*/logs/access_log 2>/dev/null >> #{opt[:temp_file]}`
`cat logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
`cat domains/*/logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
`zcat logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
`zcat domains/*/logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
usage = `cat #{opt[:temp_file]} | awk '{sum += $10} END {print sum}'`.chomp.to_f / 1024 / 1024
File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])
# Determine disk usage
quotaline = `quota -g | tail -n 1`
disk_usage = `echo -n "#{quotaline}" | awk '{print $2}'`.to_f
disk_quota = `echo -n "#{quotaline}" | awk '{print $3}'`.to_f
disk_percent_used = (disk_usage / disk_quota) * 100

# Output results
results = ""
results << "Disk usage: " + sprintf("%.4f", disk_usage / 1024) + " MiB (Quota: " + sprintf("%.4f", disk_quota / 1024 / 1024) +" GiB | " + sprintf("%.1f", disk_percent_used) + "% used)\n"
results << "Bandwidth:\n" + Date::ABBR_MONTHNAMES[Date.today.month] + " " + Date.today.year.to_s + ": " + sprintf("%.4f", usage) + " MiB (Month to Date)\n"
hist_usage = @stats.last(opt[:bw_months]).reverse
hist_usage.each {|h| results << Date::ABBR_MONTHNAMES[Date.parse(h[0] + "01").month] + ' ' + h[0][0,4] + ": " + sprintf("%.4f", (h[1].to_f / 1024 / 1024)) + " MiB\n"}

# We're either e-mailing or outputting
if opt[:email_to]
  t = Time.now.strftime("%a %d %B %Y %H:%M:%S %Z")
  message = <<EOM
From: TxD Resource Meter <#{ENV['USER']}-noreply@#{`/bin/hostname`.chomp}>
To: #{opt[:email_to]}
Subject: [TxD Resource Meter] #{t} report for #{ENV['USER']}
X-Mailer: rsrcmeter | http://textsnippets.com/posts/show/842

Resource Report - #{t}
#{results}
---------------
Generated by rsrcmeter
EOM
  File.open("temp-emailresult", "w") { |file| file.print message }
  `cat temp-emailresult | /usr/sbin/sendmail -t`
  File.delete("temp-emailresult")
else
  puts results
end

rsrcmeter for TxD

This version has been superseded by http://textsnippets.com/posts/show/842

TextDrive: Simple disk usage and HTTP bandwidth counts
This is an updated version of http://textsnippets.com/posts/show/621

#!/usr/local/bin/ruby
Dir.chdir(ENV['HOME'])
# Disk usage
quotaline = `quota -g | tail -n 1`
usage = `echo -n "#{quotaline}" | awk '{print $2}'`.to_f
quota = `echo -n "#{quotaline}" | awk '{print $3}'`.to_f
percent_used = (usage / quota) * 100
puts "Disk usage: " + sprintf("%.4f", usage/1024) + " MiB (Quota: " + sprintf("%.4f", quota/1024/1024) +" GiB; " + sprintf("%.1f", percent_used) + "% used)"

# HTTP Bandwidth
print "Calculating Bandwidth Usage..."
month = `date +"%B %Y"`.chomp
access_logs="access_log." + `date +%Y%m`.chomp + "??"
system("cat logs/access_log 2>/dev/null > temp-bandwidthcount") # Today's log
system("cat domains/*/logs/access_log 2>/dev/null >> temp-bandwidthcount")
system("cat logs/#{access_logs} 2>/dev/null >> temp-bandwidthcount") # Any logs not (yet) gzipped
system("cat domains/*/logs/#{access_logs} 2>/dev/null >> temp-bandwidthcount")
system("zcat logs/#{access_logs}.gz 2>/dev/null >> temp-bandwidthcount") # Gzipped logs from previous days
system("zcat domains/*/logs/#{access_logs}.gz 2>/dev/null >> temp-bandwidthcount")

usage = `cat temp-bandwidthcount | awk '{sum += $10} END {print sum}'`.chomp.to_f / 1024 / 1024
File.delete("temp-bandwidthcount")

30.times {print "\b"}
puts "Bandwidth used for #{month}: " + sprintf("%.4f", usage) + " MiB"


Installing:
Upload the file to your server, put somewhere like your home folder, and name it "rsrcmeter".
chmod u+x rsrcmeter
./rsrcmeter

Using in Webmin (Under Run Processes, Command to run):
export HOME="/users/home/YOURUSERNAME"; $HOME/rsrcmeter


Sample output:
Disk usage: 2.2910 MiB (Quota: 1.9073 GiB; 0.1% used)
Bandwidth used for August 2006: 0.5773 MiB


Confirmed to work on:
- Cardero,
- Davie (by rsimplicio),
- Pendrell (by iolaire),
- Thurlow (by janovetz),
- Bidwell & Jervis (by springworks),
- Chilco (by atl),
- Burnaby (by igner),
- Broughton (Biz Server, by Rich),
- Howe (scoobyfoo),
- Nicola (lderezinski),
- Jervis (mjboyle), and
- One (robertb)
*Should work on any TxD shared/business server.*

Getting HTTP Auth to play nice with PHP run under FastCGI

<?php
/**
 * Get HTTP Auth to work with PHP+FastCGI
 *
 * @author  Jacques Marneweck <jacques@php.net>
 * @license PHP License v3.01
 */

/**
 * Get HTTP Auth to work with PHP+FastCGI
 */

    

if (isset($_SERVER["AUTHORIZATION"]) && !empty($_SERVER["AUTHORIZATION"])) {

    list ($type, $cred) = split (" ", $_SERVER['AUTHORIZATION']);

    if ($type == 'Basic') {
        list ($user, $pass) = explode (":", base64_decode($cred));
        $_SERVER['PHP_AUTH_USER'] = $user;
        $_SERVER['PHP_AUTH_PW'] = $pass;
    }

}

PHP HTTP Connection class

class HttpConnection {
  private $host;
  private $port;
  private $headers;
  
  public function __construct($host, $port) {
    $this->host    = $host;
    $this->port    = $port;
    $this->headers = new HeaderList(array(), "\r\n");
  }
  
  public function get($path, $params = array(), $headers = array()) {
    return $this->send($path, 'get', $params, $headers);
  }
  
  public function post($path, $params = array(), $headers = array()) {
    return $this->send($path, 'post', $params, $headers);
  }
  
  public static function serialize_auth($user, $pass) {
    return base64_encode("$user:$pass");
  }
  
  public static function serialize_params($params) {
   $query_string = array();
    foreach ($params as $key => $value) {
      $query_string[] = urlencode($key) . '=' . urlencode($value);
    }
    return implode('&', $query_string);
  }
  
  private function send($path, $method, $params = array(), $headers = array()) {  
    $this->headers->add($headers);  
    $params = self::serialize_params($params);
    
    $this->request = strtoupper($method) . " http://{$this->host}{$path}?{$params} HTTP/1.0\r\n";
    $this->request .= $this->headers->to_s() . "\r\n";    

    if ($fp = fsockopen($this->host, $this->port, $errno, $errstr, 15)) {
      if (fwrite($fp, $this->request)) {
        while (!feof($fp)) {
         $this->response .= fread($fp, 4096);
       }
      }
      fclose($fp);
    } else {
      throw new Exception("could not establish connection with $host");
    }
    
    return $this->parse_response();
  }
  
  private function parse_response() {
    $this->response = str_replace("\r\n", "\n", $this->response);
    list($headers, $body) = explode("\n\n", $this->response, 2);
    $headers = new HeaderList($headers);
    return array('headers' => $headers->to_a(), 'body' => $body, 'code' => $headers->get_response_code());
  }
}

class HeaderList {
  private $headers;
  private $response_code;
  private $linebreak;
  
  public function __construct($headers = array(), $linebreak = "\n") {
    $this->linebreak = $linebreak;
    $this->headers   = $headers;
    if (is_string($