You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by er...@apache.org on 2010/11/19 08:17:56 UTC
svn commit: r1036750 [2/2] - in /trafficserver/plugins/mysql_remap: ./ lib/
schema/
Added: trafficserver/plugins/mysql_remap/mysql_remap.cc
URL: http://svn.apache.org/viewvc/trafficserver/plugins/mysql_remap/mysql_remap.cc?rev=1036750&view=auto
==============================================================================
--- trafficserver/plugins/mysql_remap/mysql_remap.cc (added)
+++ trafficserver/plugins/mysql_remap/mysql_remap.cc Fri Nov 19 07:17:55 2010
@@ -0,0 +1,245 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <ts/ts.h>
+#include <ts/remap.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "mysql/mysql.h"
+#include "lib/iniparser.h"
+#include "default.h"
+
+MYSQL mysql;
+
+typedef struct {
+ char * query;
+} my_data;
+
+bool do_mysql_remap(TSCont contp,TSHttpTxn txnp) {
+ TSMBuffer reqp;
+ TSMLoc hdr_loc, url_loc, field_loc;
+ bool ret_val = false;
+
+ const char * request_host;
+ int request_host_length = 0;
+ const char * request_scheme;
+ int request_scheme_length = 0;
+ int request_port = 80;
+ char * query;
+
+ MYSQL_ROW row;
+ MYSQL_RES *res;
+
+ my_data * data = (my_data*) TSContDataGet(contp);
+ query = data->query;
+
+ if (!TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) {
+ TSDebug(PLUGIN_NAME,"could not get request data");
+ return false;
+ }
+
+ url_loc = TSHttpHdrUrlGet(reqp, hdr_loc);
+
+ if (!url_loc) {
+ TSDebug(PLUGIN_NAME,"couldn't retrieve request url");
+ goto release_hdr;
+ }
+
+ field_loc = TSMimeHdrFieldFind(reqp, hdr_loc, TS_MIME_FIELD_HOST, TS_MIME_LEN_HOST);
+
+ if (!field_loc) {
+ TSDebug(PLUGIN_NAME,"couldn't retrieve request HOST header");
+ goto release_url;
+ }
+
+ if (TSMimeHdrFieldValueStringGet (reqp, hdr_loc, field_loc, 0, &request_host, &request_host_length) != TS_SUCCESS) {
+ TSDebug(PLUGIN_NAME,"couldn't find request HOST header");
+ goto release_field;
+ }
+
+ request_scheme = TSUrlSchemeGet(reqp,url_loc,&request_scheme_length);
+ request_port = TSUrlPortGet(reqp,url_loc);
+
+ TSDebug(PLUGIN_NAME," +++++MYSQL REMAP+++++ ");
+
+ TSDebug(PLUGIN_NAME,"\nINCOMING REQUEST ->\n ::: from_scheme_desc: %.*s\n ::: from_hostname: %.*s\n ::: from_port: %d",\
+ request_scheme_length,\
+ request_scheme,\
+ request_host_length,\
+ request_host,\
+ request_port
+ );
+
+ snprintf(query,QSIZE," \
+ SELECT \
+ t_scheme.scheme_desc, \
+ t_host.hostname, \
+ to_port \
+ FROM map \
+ INNER JOIN scheme as t_scheme ON (map.to_scheme_id = t_scheme.id) \
+ INNER JOIN scheme as f_scheme ON (map.from_scheme_id = f_scheme.id) \
+ INNER JOIN hostname as t_host ON (map.to_hostname_id = t_host.id) \
+ INNER JOIN hostname as f_host ON (map.from_hostname_id = f_host.id) \
+ WHERE \
+ is_enabled=1 \
+ AND f_host.hostname = '%.*s' \
+ AND f_scheme.id = %d \
+ AND from_port = %d \
+ LIMIT 1", \
+ request_host_length, \
+ request_host, \
+ (strcmp(request_scheme,"https") == 0) ? 2:1, \
+ request_port \
+ );
+
+ mysql_real_query(&mysql,query,(unsigned int)strlen(query));
+ res = mysql_use_result(&mysql);
+
+ if (!res) goto not_found; //TODO: define a fallback
+
+ do {
+ row = mysql_fetch_row(res);
+ if (!row) goto not_found;
+ TSDebug(PLUGIN_NAME,"\nOUTGOING REQUEST ->\n ::: to_scheme_desc: %s\n ::: to_hostname: %s\n ::: to_port: %s",row[0],row[1],row[2]);
+ TSMimeHdrFieldValueStringSet(reqp, hdr_loc, field_loc, 0,row[1],-1);
+ TSUrlHostSet(reqp,url_loc,row[1],-1);
+ TSUrlSchemeSet(reqp,url_loc,row[0],-1);
+ TSUrlPortSet(reqp,url_loc,atoi(row[2]));
+ } while(0);
+
+ ret_val = true;
+
+not_found:
+ if (!ret_val) {
+ //lets build up a nice 404 message for someone
+ TSHttpHdrStatusSet(reqp,hdr_loc,TS_HTTP_STATUS_NOT_FOUND);
+ TSHttpTxnSetHttpRetStatus(txnp,TS_HTTP_STATUS_NOT_FOUND);
+ }
+free_stuff:
+ if (res)
+ mysql_free_result(res);
+ if (request_host)
+ TSHandleStringRelease(reqp, hdr_loc, request_host);
+ if (request_scheme)
+ TSHandleStringRelease(reqp, hdr_loc, request_scheme);
+release_field:
+ if (field_loc)
+ TSHandleMLocRelease(reqp, hdr_loc, field_loc);
+release_url:
+ if (url_loc)
+ TSHandleMLocRelease(reqp, hdr_loc, url_loc);
+release_hdr:
+ if (hdr_loc)
+ TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);
+
+ return ret_val;
+}
+
+static int
+mysql_remap (TSCont contp, TSEvent event, void *edata) {
+ TSHttpTxn txnp = (TSHttpTxn) edata;
+ TSEvent reenable = TS_EVENT_HTTP_CONTINUE;
+
+ switch(event) {
+ case TS_EVENT_HTTP_READ_REQUEST_HDR:
+ TSDebug(PLUGIN_NAME,"Reading Request");
+ TSSkipRemappingSet(txnp,1);
+ if (!do_mysql_remap(contp,txnp)) {
+ reenable = TS_EVENT_HTTP_ERROR;
+ }
+ break;
+ }
+
+ TSHttpTxnReenable(txnp, reenable);
+ return 1;
+}
+
+void
+TSPluginInit(int argc, const char *argv[]) {
+ dictionary * ini;
+ const char * host;
+ int port;
+ const char * username;
+ const char * password;
+ const char * db;
+
+ my_data * data = (my_data*) malloc(1*sizeof(my_data));
+
+ TSPluginRegistrationInfo info;
+ my_bool reconnect = 1;
+
+ info.plugin_name = const_cast<char*>(PLUGIN_NAME);
+ info.vendor_name = const_cast<char*>("Apache Software Foundation");
+ info.support_email = const_cast<char*>("eric@ericbalsa.com");
+
+ if (!TSPluginRegister(TS_SDK_VERSION_2_0 , &info)) {
+ TSError("mysql_remap: plugin registration failed.\n");
+ }
+
+ if (argc != 2) {
+ TSError( "usage: %s /path/to/sample.ini\n", argv[0] );
+ return;
+ }
+
+ ini = iniparser_load(argv[1]);
+ if (!ini) {
+ TSError("Error with ini file (1)");
+ TSDebug(PLUGIN_NAME,"Error parsing ini file(1)");
+ return;
+ }
+
+ host = iniparser_getstring(ini, "mysql_remap:mysql_host", (char*)"localhost");
+ port = iniparser_getint(ini,"mysql_remap:mysql_port",3306);
+ username = iniparser_getstring(ini, "mysql_remap:mysql_username", NULL);
+ password = iniparser_getstring(ini, "mysql_remap:mysql_password", NULL);
+ db = iniparser_getstring(ini, "mysql_remap:mysql_database", (char*)"mysql_remap");
+
+ if (mysql_library_init(0, NULL, NULL)) {
+ TSError("Error initializing mysql client library");
+ TSDebug(PLUGIN_NAME,"Error initializing mysql client library");
+ return;
+ }
+
+ if (!mysql_init(&mysql)) {
+ TSError("Could not initialize MySQL");
+ TSDebug(PLUGIN_NAME,"Could not initialize MySQL");
+ return;
+ }
+
+ mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);
+
+ if (!mysql_real_connect(&mysql,host,username,password,db,port,NULL,0)) {
+ TSError("Could not connect to mysql");
+ TSDebug(PLUGIN_NAME,"Could not connect to mysql: %s",mysql_error(&mysql));
+ return;
+ }
+
+ data->query = (char*)TSmalloc(QSIZE * sizeof(char)); //TODO: malloc smarter sizes
+
+ TSDebug(PLUGIN_NAME, "h: %s; u: %s; p: %s; p:%d; d:%s",host,username,password,port,db);
+ TSCont cont = TSContCreate(mysql_remap, TSMutexCreate());
+
+ TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, cont);
+
+ TSContDataSet (cont, (void *)data);
+
+ TSDebug(PLUGIN_NAME, "plugin is succesfully initialized [plugin mode]");
+ iniparser_freedict(ini);
+ return;
+}
Added: trafficserver/plugins/mysql_remap/sample.ini
URL: http://svn.apache.org/viewvc/trafficserver/plugins/mysql_remap/sample.ini?rev=1036750&view=auto
==============================================================================
--- trafficserver/plugins/mysql_remap/sample.ini (added)
+++ trafficserver/plugins/mysql_remap/sample.ini Fri Nov 19 07:17:55 2010
@@ -0,0 +1,6 @@
+[mysql_remap]
+mysql_host = localhost #default
+mysql_port = 3306 #default
+mysql_username = root
+mysql_password =
+mysql_database = mysql_remap #default
Added: trafficserver/plugins/mysql_remap/schema/import.sql
URL: http://svn.apache.org/viewvc/trafficserver/plugins/mysql_remap/schema/import.sql?rev=1036750&view=auto
==============================================================================
--- trafficserver/plugins/mysql_remap/schema/import.sql (added)
+++ trafficserver/plugins/mysql_remap/schema/import.sql Fri Nov 19 07:17:55 2010
@@ -0,0 +1,116 @@
+-- MySQL dump 10.13 Distrib 5.1.48, for apple-darwin10.4.0 (i386)
+--
+-- Host: localhost Database: mysql_remap
+-- ------------------------------------------------------
+-- Server version 5.1.48-log
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `hostname`
+--
+
+DROP TABLE IF EXISTS `hostname`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `hostname` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `hostname` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `hostname` (`hostname`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `hostname`
+--
+
+LOCK TABLES `hostname` WRITE;
+/*!40000 ALTER TABLE `hostname` DISABLE KEYS */;
+INSERT INTO `hostname` VALUES (1,'www.ericbalsa.com'),(2,'www.google.com');
+/*!40000 ALTER TABLE `hostname` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `map`
+--
+
+DROP TABLE IF EXISTS `map`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `map` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `from_scheme_id` int(10) unsigned NOT NULL DEFAULT '1',
+ `from_hostname_id` int(10) unsigned NOT NULL,
+ `from_port` int(5) unsigned NOT NULL,
+ `to_scheme_id` int(10) unsigned NOT NULL DEFAULT '1',
+ `to_hostname_id` int(10) unsigned NOT NULL,
+ `to_port` int(5) unsigned NOT NULL DEFAULT '80',
+ `is_enabled` tinyint(1) unsigned NOT NULL DEFAULT '1',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `from_unique` (`from_scheme_id`,`from_hostname_id`,`from_port`),
+ UNIQUE KEY `to_unique` (`to_scheme_id`,`to_hostname_id`,`to_port`),
+ UNIQUE KEY `unique_across_everything` (`from_scheme_id`,`from_hostname_id`,`from_port`,`to_scheme_id`,`to_hostname_id`,`to_port`),
+ KEY `to_hostname_id` (`to_hostname_id`),
+ KEY `from_hostname_id` (`from_hostname_id`),
+ CONSTRAINT `map_ibfk_1` FOREIGN KEY (`from_scheme_id`) REFERENCES `scheme` (`id`) ON UPDATE CASCADE,
+ CONSTRAINT `map_ibfk_3` FOREIGN KEY (`to_scheme_id`) REFERENCES `scheme` (`id`) ON UPDATE CASCADE,
+ CONSTRAINT `map_ibfk_4` FOREIGN KEY (`to_hostname_id`) REFERENCES `hostname` (`id`) ON UPDATE CASCADE,
+ CONSTRAINT `map_ibfk_5` FOREIGN KEY (`from_hostname_id`) REFERENCES `hostname` (`id`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `map`
+--
+
+LOCK TABLES `map` WRITE;
+/*!40000 ALTER TABLE `map` DISABLE KEYS */;
+INSERT INTO `map` VALUES (1,1,2,80,1,1,80,1);
+/*!40000 ALTER TABLE `map` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `scheme`
+--
+
+DROP TABLE IF EXISTS `scheme`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `scheme` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `scheme_desc` varchar(5) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `desc` (`scheme_desc`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `scheme`
+--
+
+LOCK TABLES `scheme` WRITE;
+/*!40000 ALTER TABLE `scheme` DISABLE KEYS */;
+INSERT INTO `scheme` VALUES (1,'http'),(2,'https');
+/*!40000 ALTER TABLE `scheme` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2010-11-15 21:08:43
Propchange: trafficserver/plugins/mysql_remap/schema/import.sql
------------------------------------------------------------------------------
svn:eol-style = native