diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index de1f5229..80817390 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -1354,6 +1354,7 @@ Lua: color: "#fa1fa1" extensions: - .lua + - .fcgi - .nse - .pd_lua - .rbxs @@ -1690,6 +1691,7 @@ PHP: - .php - .aw - .ctp + - .fcgi - .module - .php3 - .php4 @@ -1882,6 +1884,7 @@ Python: extensions: - .py - .cgi + - .fcgi - .gyp - .lmi - .pyde @@ -2043,6 +2046,7 @@ Ruby: extensions: - .rb - .builder + - .fcgi - .gemspec - .god - .irbrc @@ -2195,6 +2199,7 @@ Shell: - .bash - .bats - .cgi + - .fcgi - .tmux - .zsh interpreters: diff --git a/samples/Lua/wsapi.fcgi b/samples/Lua/wsapi.fcgi new file mode 100755 index 00000000..6eeef23c --- /dev/null +++ b/samples/Lua/wsapi.fcgi @@ -0,0 +1,28 @@ +#!/usr/bin/lua + +-- Generic WSAPI FastCGI launcher, extracts application to launch +-- from SCRIPT_FILENAME/PATH_TRANSLATED, each application (defined +-- by its script entry point) gets an isolated Lua VM; sequential +-- requests to the same application go to the same VM + +pcall(require,"luarocks.require") + +local common = require "wsapi.common" +local fastcgi = require "wsapi.fastcgi" + +local ONE_HOUR = 60 * 60 +local ONE_DAY = 24 * ONE_HOUR + +local wsapi_loader = common.make_loader{ + isolated = true, -- isolate each script in its own Lua state + filename = nil, -- if you want to force the launch of a single script + launcher = "wsapi.fcgi", -- the name of this script + reload = false, -- if you want to reload the application on every request + period = ONE_HOUR, -- frequency of Lua state staleness checks + ttl = ONE_DAY, -- time-to-live for Lua states + vars = -- order of checking for the path of the script + { "SCRIPT_FILENAME", + "PATH_TRANSLATED" } +} + +fastcgi.run(wsapi_loader) diff --git a/samples/PHP/prefix.fcgi b/samples/PHP/prefix.fcgi new file mode 100755 index 00000000..e3883520 --- /dev/null +++ b/samples/PHP/prefix.fcgi @@ -0,0 +1,3 @@ + diff --git a/samples/Python/backstage.fcgi b/samples/Python/backstage.fcgi new file mode 100755 index 00000000..393ee58b --- /dev/null +++ b/samples/Python/backstage.fcgi @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +import sqlite +import urllib2 +import csv +import cgi +import simplejson +import jsontemplate +import time + +log = open('log.txt', 'a') + +def urldecode(query): + d = {} + a = query.split('&') + for s in a: + if s.find('='): + k,v = map(urllib2.unquote, s.split('=')) + try: + d[k].append(v) + except KeyError: + d[k] = [v] + + return d + +def load_table(uri, cur): + table = uri.split('/')[-1] + table = table.split('.')[0] + + contents = urllib2.urlopen(uri) + fields = "" + for field in contents.readline().strip().split(','): + fields += field + fields += "," + fields = fields.rstrip(',') + + cur.execute("SELECT name FROM sqlite_master WHERE type='table' \ + AND name='%s';" % (table)) + if cur.fetchone() == None: +# cur.execute("DROP TABLE %s;" % (table)) + cur.execute("CREATE TABLE %s (%s);" % (table, fields)) + for line in contents: + values = line.strip() + values = "','".join([val.strip() for val in values.split(",")]) + values = "'" + values + "'" + sql = "INSERT INTO %s (%s) VALUES (%s);" % (table, fields, values) + cur.execute(sql) + return table + +def build_structure(headings, allresults): + results = [] + for result in allresults: + results.append(dict(zip(headings, result))) + results = { "query" : results } + return results + +def build_json(headings, allresults, callback): + results = build_structure(headings, allresults) + return_str = simplejson.dumps(results) + if callback != None: + return_str = callback + "(" + return_str + ");"; + return return_str + +def load_template(templatefile): + return "".join(urllib2.urlopen(templatefile).readlines()) + +def build_template(headings, allresults, template_str): + results = build_structure(headings, allresults) + return jsontemplate.expand(template_str, results) + return "" + +def myapp(environ, start_response): + args = cgi.parse_qs(environ['QUERY_STRING']) + + query = args['query'][0] + uri = args['uri'][0] + callback = None + if 'callback' in args: + callback = args['callback'][0] + label = "no label" + if 'label' in args: + label = args['label'][0] + templatefile = None + if 'templatefile' in args: + templatefile = args['templatefile'][0] + + con = sqlite.connect('mydatabase.db') + cur = con.cursor() + table_uris = uri.split(',') + tables = [load_table(uri, cur) for uri in table_uris] + con.commit() + before = time.time() + cur.execute(query) + allresults = cur.fetchall() + after = time.time() + log.write("%s: query time %f\n" % (label, after - before)) + + headings = [name[0] for name in cur.description] + return_str = "" + if templatefile != None: + start_response('200 OK', [('Content-Type', 'text/html')]) + before = time.time() + template_str = load_template(templatefile) + after = time.time() + log.write("%s: template loading time %f\n" % (label, after - before)) + before = time.time() + return_str = build_template(headings, allresults, template_str) + after = time.time() + log.write("%s: template rendering time %f\n" % (label, after - before)) + else: + start_response('200 OK', [('Content-Type', 'text/plain')]) + before = time.time() + return_str = build_json(headings, allresults, callback) + after = time.time() + log.write("%s: json-making time %f\n" % (label, after - before)) + return return_str + +if __name__ == '__main__': + from fcgi import WSGIServer + WSGIServer(myapp).run() diff --git a/samples/Ruby/mdata_server.fcgi b/samples/Ruby/mdata_server.fcgi new file mode 100755 index 00000000..c09d5047 --- /dev/null +++ b/samples/Ruby/mdata_server.fcgi @@ -0,0 +1,68 @@ +#!/usr/bin/env ruby +require "xmlrpc/server" + +# NOTE: force the usage of the pure-ruby version of fcgi. +# - this is required by the workaround to get fcgi+xmlrpc working together +FCGI_PURE_RUBY=true +require 'fcgi' + +require File.join(File.dirname(__FILE__), '../bt_cast/mdata_echo_server/bt_cast_mdata_server_t.rb') + +################################################################################ +################################################################################ +# CGI handling for xmlrpc +################################################################################ +################################################################################ +# - for basic xmlrpc via CGI example +# - see http://www.ntecs.de/projects/xmlrpc4r/server.html#label-19 + +# create the directory needed for Neoip::Cast_mdata_server_t +Neoip::Cast_mdata_server_t.create_dir_ifneeded(); + +# init the cgi_server +cgi_server = XMLRPC::CGIServer.new +# register all the xmlrpc function +cgi_server.add_handler("set_cast_mdata_pull") do |web2srv_str, cast_name, cast_privtext, cast_id, + port_lview, port_pview, uri_pathquery| + Neoip::Cast_mdata_server_t.set_cast_mdata_pull(web2srv_str, cast_name, cast_privtext, cast_id, + port_lview, port_pview, uri_pathquery, ENV['REMOTE_ADDR']); +end +cgi_server.add_handler("set_cast_mdata_push") do |web2srv_str, cast_name, cast_privtext, cast_mdata| + Neoip::Cast_mdata_server_t.set_cast_mdata_push(web2srv_str, cast_name, cast_privtext, cast_mdata); +end +cgi_server.add_handler("get_cast_mdata") do |cast_name, cast_privhash| + Neoip::Cast_mdata_server_t.get_cast_mdata(cast_name, cast_privhash); +end +cgi_server.add_handler("del_cast_mdata") do |cast_name, cast_privtext| + Neoip::Cast_mdata_server_t.del_cast_mdata(cast_name, cast_privtext); +end + +# handle the unknown/bad formered calls +cgi_server.set_default_handler do |name, *args| + raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + + " or wrong number of parameters!") +end + +# server the cgi_server +#cgi_server.serve +#exit + +# experiment at using fast-cgi +FCGI.each_request do |request| + # XMLRPC::CGIServer expect some value in ENV[] but FCGI doesnt provides them + # - so working around by copying them by hand... dirty + ENV['REMOTE_ADDR'] = request.env['REMOTE_ADDR']; + ENV['REQUEST_METHOD'] = request.env['REQUEST_METHOD']; + ENV['CONTENT_TYPE'] = "text/xml"; + ENV['CONTENT_LENGTH'] = "#{request.in.length}"; + + # copy the request in/out into the stdin/stdout to act as a CGI + $stdin = request.in + $stdout = request.out + + # process the cgi itself + cgi_server.serve + + # mark the request as finished + request.finish +end diff --git a/samples/Shell/php.fcgi b/samples/Shell/php.fcgi new file mode 100755 index 00000000..cd573a30 --- /dev/null +++ b/samples/Shell/php.fcgi @@ -0,0 +1,16 @@ +#!/bin/sh +# you can change the PHP version here. +version="RB_PHP_VERSION_X_Y_Z" + +# php.ini file location +PHPRC=/usr/local/php/phpfarm/inst/php-${version}/lib/php.ini +export PHPRC + +PHP_FCGI_CHILDREN=3 +export PHP_FCGI_CHILDREN + +PHP_FCGI_MAX_REQUESTS=5000 +export PHP_FCGI_MAX_REQUESTS + +# which php-cgi binary to execute +exec /usr/local/php/inst/php-${version}/bin/php-cgi