Apache2-ApacheMobileFilter-4.20/000755 000765 000024 00000000000 13064525445 020200 5ustar00idelfuschinistaff000000 000000 Apache2-ApacheMobileFilter-4.20/.DS_Store000644 000765 000024 00000044004 13054033630 021652 0ustar00idelfuschinistaff000000 000000 Bud1@@  0 tclsvpblobdoclsvpblobbplist00 `abcd(_useRelativeDates_showIconPreview_calculateAllSizesWcolumns_scrollPositionYXtextSize_scrollPositionXZsortColumnXiconSize_viewOptionsVersion !)19AIQYXcommentsTname[dateCreatedTsizeUlabelTkindWversion^dateLastOpened\dateModified  WvisibleUwidthYascendingUindex, "#$ & (WvisibleUwidthYascending | *+, . 0WvisibleUwidthYascending234 6 8WvisibleUwidthYascending a:;< > @WvisibleUwidthYascendingd BCD F HWvisibleUwidthYascending s JKL N PWvisibleUwidthYascendingK RST V XWvisibleUwidthYascendingZ[\ . _WvisibleUwidthYascending ##@(#\dateModified#@00BV^py !)/9?@CDFOW]ghklnw !+,./1:BHRSUVXaioyz{}e mobilefilter4ph1ScompIlocblobr  @ @ @ @$ NextReleaseIlocblob\ NextReleasebwspblobbplist00  \WindowBounds[ShowSidebar]ShowStatusBar[ShowPathbar[ShowToolbar\SidebarWidth_{{2277, 240}, {1093, 753}}  ".? UwidthYascendingWversionK CDE UwidthYascendingXcomments IJKL UwidthYascending^dateLastOpenedPQR UwidthYascendingYdateAdded#@#@(##@00BV^py&()*39COPQZ`joqrs| )+,-6<FPQR[dmvZxPHPlsvpblob>bplist00 XYZ[%_useRelativeDates_showIconPreview_calculateAllSizesWcolumns_scrollPositionYXtextSize_scrollPositionXZsortColumnXiconSize_viewOptionsVersion !(/6=DKRXcommentsTname[dateCreatedTsizeUlabelTkindWversion^dateLastOpened\dateModified  WvisibleUwidthYascendingUindex, "#$% UwidthYascendingWvisible )* , .UwidthYascending01 3 5UwidthYascending a78 : ? A CUwidthYascending s EF H JUwidthYascendingK LM O QUwidthYascendingST , WUwidthYascending #@#@(##@00BV^py !)/9?@CDFOU_gijktz "#%.4>?@BKT]\fPHPmoDDdutcPHPmodDdutcPHPph1ScompPHPvSrnlong pm_to_blibIlocblobREADMEIlocblobrsecond_response.txtIlocblob| SOURCE_STATSlg1Scomp SOURCE_STATSmoDDdutcP SOURCE_STATSmodDdutcP SOURCE_STATSph1ScompSuiteIlocblob$Suitelg1ScompSuitemoDDdutcSuitemodDdutcSuiteph1ScompToBeDoneIlocblobAMF_HomeIlocblob\AMF_Homebwspblobbplist00  ]ShowStatusBar[ShowSidebar[ShowToolbar[ShowTabView_ContainerShowSidebar\WindowBounds[ShowPathbar  _{{1770, 807}, {1717, 920}}%1=I`myz{|}~AMF_HomedsclboolAMF_HomefdscboolAMF_Homelg1Scomp'PAMF_HomelsvCblobbplist00 KLK! N_viewOptionsVersion_showIconPreview_calculateAllSizesWcolumns_scrollPositionYXtextSize_scrollPositionXZsortColumn_useRelativeDatesXiconSize  %).38=BG  WvisibleUwidthYascendingZidentifier  Tname UwidthYascendingWvisibleXubiquity#!" \dateModified &" [dateCreated*+ Tsizea /0 Tkinds 45 Ulabeld 9: WversionK >? Xcomments, CD ^dateLastOpenedH" YdateAdded##@( #@02DX`r{ $&'(1>@ABKWXYbgijkty{|}O AMF_Homelsvpblobbplist00 GHG J_viewOptionsVersion_showIconPreview_calculateAllSizesWcolumns_scrollPositionYXtextSize_scrollPositionXZsortColumn_useRelativeDatesXiconSize !%*/49>CXcommentsTname[dateCreatedTsizeUlabelTkindWversion^dateLastOpened\dateModified  WvisibleUwidthYascendingUindex,  "   ' ) , . a 1 3d  6 8 s  ; =K  @ B ' F ##@( #@02DX`r{ "*0:@ADEGPSTU^_abdmnpqs|}KAMF_HomemoDDdutc輚AMF_HomemodDdutc輚AMF_Homeph1ScompAMF_HomevSrnlongApacheMobileFilter.kpfIlocblobrblibIlocblob$bliblg1Scomp blibmoDDdutcblibmodDdutcblibph1ScomppCHANGEIlocblob~ CHANGE copyIlocblobCommandLineTestIlocblob|CommandLineTestlg1ScompCommandLineTestmoDDdutcCommandLineTestmodDdutcCommandLineTestph1Scompcopia_percvs.shIlocblob|docIlocblobr|docbwspblobbplist00  ]ShowStatusBar[ShowPathbar[ShowToolbar[ShowTabView_ContainerShowSidebar\WindowBounds\SidebarWidth[ShowSidebar  _{{100, 92}, {1258, 742}} '3?Kbo|docdsclbooldoclg1ScompU&XdoclsvPblobbplist00 ^_`abc_useRelativeDates_showIconPreview_calculateAllSizesWcolumns_scrollPositionYXtextSize_scrollPositionXZsortColumnXiconSize_viewOptionsVersion  '/7?GOW  WvisibleUwidthYascendingZidentifier | Tname  WvisibleUwidthYascending \dateModified!"#  &WvisibleUwidthYascending[dateCreated()* , .WvisibleUwidthYascending aTsize012 4 6WvisibleUwidthYascending s Tkind89: < >WvisibleUwidthYascendingd Ulabel@AB D FWvisibleUwidthYascendingK WversionHIJ L NWvisibleUwidthYascending, XcommentsPQR T VWvisibleUwidthYascending^dateLastOpenedXYZ  ]WvisibleUwidthYascendingYdateAdded##@(#\dateModified#@00BV^py *3;AKLMYbjpz{}~&'*+4=EKUVXYhqyd0docmoDDdutcdocmodDdutcdocph1ScompcdocvSrnlongFilterIlocblob$|Filterlg1ScompFiltermoDDdutcFiltermodDdutcFilterph1ScompidelioIlocblob\ideliolg1ScompJideliomoDDdutcideliomodDdutcidelioph1Scomp0libIlocbloblibbwspblobbplist00  \WindowBounds[ShowSidebar]ShowStatusBar[ShowPathbar[ShowToolbar\SidebarWidth_{{62, 251}, {1429, 868}}  ".WvisibleUwidthYascendingd Ulabel@AB D FWvisibleUwidthYascendingK WversionHIJ L NWvisibleUwidthYascending, XcommentsPQR T VWvisibleUwidthYascending^dateLastOpenedXYZ  ]WvisibleUwidthYascendingYdateAdded##@(#\dateModified#@00BV^py *3;AKLMYbjpz{}~&'*+4=EKUVXYhqyd@ E  0 DSDB `HP` @ @6Mobilebwspblobbplist00  \WindowBounds[ShowSidebar]ShowStatusBar[ShowPathbar[ShowToolbar\SidebarWidth_{{931, 62}, {1060, 1095}}  ". for example: j2me_midp_2_0 is AMF_J2ME_MIDP_2_0 if Parameter CapabilityList is setted with value all show all capabilies of wurfl. Fixed some BUG WURFLFilter 1.70 In this version you can specify on the query string of the URI of an image the the percentage of width of the device that the filter must resize WURFLFilter 1.61 Change algorithm to identify the UserAgent Added Parameter DetectAccuracy to set the accuracy of device detection (default is false) WURFLFilter 1.60 Added parameter for setting "Apache Mobile Filter" into httpd.conf Added Parameter LoadWebPatch to set if you want to load a patch file (default is false) Added Parameter DirWebPatch to set where you set your patch file Added Parameter PatchWurflNetDownload to set if you download from net the patch file (default is false) Added Parameter PatchWurflUrl to set the url of the patch file Added Parameter RedirectTranscoder to set if you want to redirect if it access with a transcoder system Added Parameter RedirectTranscoderUrl to set the url where you want to redirect the transcoder WURFLFilter 1.55 Fixed critical bugs now is recognize correctly FullBrowser WURFLFilter 1.54 Delete Parameter XML_CONFIG now the configuration of the filter is possible only in httpd.conf file WURFLFilter 1.53 Fixed Bugs Convert all messages from warn to debug, only warn message is for new o strange User Agent WURFLFilter 1.52 Fixed Bugs Parse Wurfl.xml method more clean WURFLFilter 1.51 Fixed Bugs WURFLFilter 1.5 Add a new method call IdentifyUAMethod, with this method increase the performance of device identification Deprecated FirstMethod Deprecated SecondMethod WURFLFilter 1.42 Fixed bug for try to read zip file like an xml file (case is DownloadZipFile setted false) WURFLFilter 1.41 Fixed bugs for internal redirect feature and for images mechanism WURFLFilter 1.4 Increase performance with a new cache system mechanism WURFLFilter 1.31 After talking with Gianugo R. it's possible to configure the filter into httpd.conf file Added Parameter XML_CONFIG to set where to read WURFLFilter configuration (to set in httpd.conf) Added Parameter CapabilityList the same of the old attribute "capability" in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter XHTMLUrl the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter WMLUrl the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter CHTMLUrl the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter MobileVersionUrl the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter IntelliSwitch the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter FullBrowserUrl the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter CookieSet the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter PassQueryStringSet the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter ShowDefaultVariable the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter WurflNetDownload the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter DownloadWurflURL the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter DownloadZipFile the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter ConvertImage the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter ResizeImageDirectory the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter WebAppConvertImages the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter WebAppDirectory the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter ConvertOnlyImages the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) Added Parameter Log4WurflNoDeviceDetect the same of the old attribute with the same name in WURFLFilterConfig.configure (to set in httpd.conf) WURFLFilter 1.21 Optimized code WURFLFilter 1.2 AddedAttribute Log4WurflNoDeviceDetect it's a necessary log for detect new device that WURFL not has included Fixed some bugs WURFLFilter 1.1 Added Attribute WebAppConvertImages if you use an application server site Added Attribute WebAppDirectory for specify the directory of WebApp Added Attribute ConvertOnlyImages if you want to use the filter only for the images and not for other content WURFLFilter 1.0 Added Attribute DownloadZipFile for download zip file of WURFL DB Add function to download zip file and uncompress it WURFLFilter 0.6 Added Attribut cHTML for CHTML layout WURFLFilter 0.54 Fixed several Bugs WURFLFilter 0.53 Fixed several Bugs WURFLFilter 0.52 Fixed Bugs if cookie is true now the images is visible WURFLFilter 0.51 Fixed Bugs of resize image, now it take the correct capability on WURFL Fixed Bugs if image to transform not found return correct message Fixed other little bugs WURFLFilter 0.5 adaptation function image dynamic for the screen size of the device tested with PNG and GIF image type Added Attribute ConvertImage into config file for activate the adaptation image Added Attribute ResizeImageDirectory into config file for specify the destination of images WURFLFilter 0.41 the filter trace in error_log file the "user agent" that not are present in WURFL WURFLFilter 0.4 Correct fix bugs Added Attribute WMLUrl for WML layout Change Attribute IntelliUrl in XHTMLUrl for XHTML layout WURFLFilter 0.3 Optimization of storage data in memroy Correct README file WURFLFilter 0.2 Read directly the WURFL.xml file from URL. This option is configurable into WURFLConfig.xml file. WURFLFilter 0.1 The First EditionApache2-ApacheMobileFilter-4.20/lib/000755 000765 000024 00000000000 13064525445 020746 5ustar00idelfuschinistaff000000 000000 Apache2-ApacheMobileFilter-4.20/Makefile.PL000644 000765 000024 00000003754 12070702221 022144 0ustar00idelfuschinistaff000000 000000 use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. print << 'EOT1'; Apache Mobile Filter (idel@idelfuschini.it) Documentation: http://wiki.apachemobilefilter.org DemoSite: http://www.apachemobilefilter.org To try quickly the AMF add on httpd.conf this few rows: PerlSetEnv AMFMobileHome /home/AMF PerlSetEnv WURFLNetDownload true PerlSetEnv DownloadWurflURL http://downloads.sourceforge.net/wurfl/wurfl-latest.zip PerlSetEnv CacheDirectoryStore /tmp PerlTransHandler +Apache2::AMFWURFLFilter Note: Download Cache::Memcached library if you want use memcached (http://memcached.org) Download Cache::Cache library if you want use filesystem for caching In this moment AMFDeviceMonitor is only for filesystem cache EOT1 WriteMakefile( NAME => 'Apache Mobile Filter Suite', VERSION_FROM => 'lib/Apache2/AMFWURFLFilter.pm', DISTNAME => "Apache2-ApacheMobileFilter", dist => {COMPRESS => 'gzip', SUFFIX => 'gz'}, PREREQ_PM => { 'POSIX' => 0, 'Apache2::Filter' => 0, 'Apache2::RequestRec' => 0, 'Apache2::RequestUtil' => 0, 'Apache2::SubRequest' => 0, 'Apache2::Connection' => 0, 'CGI::Cookie' => 0, 'APR::Table' => 0, 'Apache2::Const' => 0, 'Image::Resize' => 0, 'Image::Scale' => 0, 'Imager' => 0, 'LWP::Simple' => 0, 'File::Copy' => 0, 'IO::Uncompress::Unzip' => 0, 'IO::Uncompress::Gunzip' => 0, 'Cache::Memcached' => "1.27", 'Cache::FileBackend' => 0, 'LWP::Protocol::https' => 0, 'Digest::MD5' => 0 }, AUTHOR => 'Idel Fuschini (idel@idelfuschini.it)' ); Apache2-ApacheMobileFilter-4.20/MANIFEST000644 000765 000024 00000001322 13064525445 021327 0ustar00idelfuschinistaff000000 000000 .DS_Store lib/Apache2/AMFWURFLFilter.pm lib/Apache2/AMFWURFLFilterMemcached.pm lib/Apache2/AMFDetectRightFilter.pm lib/Apache2/AMFDetectRightFilterMemcached.pm lib/Apache2/AMF51DegreesFilter.pm lib/Apache2/AMF51DegreesFilterMemcached.pm lib/Apache2/AMFImageRendering.pm lib/Apache2/AMFSwitcher.pm lib/Apache2/AMFCarrierDetection.pm lib/Apache2/AMFDeviceMonitor.pm lib/Apache2/AMFCommonLib.pm lib/Apache2/AMFMobileCachingMemcached.pm lib/Apache2/AMFTrace.pm lib/Apache2/AMFWebService.pm lib/Apache2/AMFLiteDetectionFilter.pm Makefile.PL MANIFEST CHANGE README META.yml Module meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Apache2-ApacheMobileFilter-4.20/META.json000644 000765 000024 00000003053 13064525445 021622 0ustar00idelfuschinistaff000000 000000 { "abstract" : "unknown", "author" : [ "Idel Fuschini (idel@idelfuschini.it)" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Apache2-ApacheMobileFilter", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "APR::Table" : "0", "Apache2::Connection" : "0", "Apache2::Const" : "0", "Apache2::Filter" : "0", "Apache2::RequestRec" : "0", "Apache2::RequestUtil" : "0", "Apache2::SubRequest" : "0", "CGI::Cookie" : "0", "Cache::FileBackend" : "0", "Cache::Memcached" : "1.27", "Digest::MD5" : "0", "File::Copy" : "0", "IO::Uncompress::Gunzip" : "0", "IO::Uncompress::Unzip" : "0", "Image::Resize" : "0", "Image::Scale" : "0", "Imager" : "0", "LWP::Protocol::https" : "0", "LWP::Simple" : "0", "POSIX" : "0" } } }, "release_status" : "stable", "version" : "4.20" } Apache2-ApacheMobileFilter-4.20/META.yml000644 000765 000024 00000001647 13064525445 021461 0ustar00idelfuschinistaff000000 000000 --- abstract: unknown author: - 'Idel Fuschini (idel@idelfuschini.it)' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Apache2-ApacheMobileFilter no_index: directory: - t - inc requires: APR::Table: '0' Apache2::Connection: '0' Apache2::Const: '0' Apache2::Filter: '0' Apache2::RequestRec: '0' Apache2::RequestUtil: '0' Apache2::SubRequest: '0' CGI::Cookie: '0' Cache::FileBackend: '0' Cache::Memcached: '1.27' Digest::MD5: '0' File::Copy: '0' IO::Uncompress::Gunzip: '0' IO::Uncompress::Unzip: '0' Image::Resize: '0' Image::Scale: '0' Imager: '0' LWP::Protocol::https: '0' LWP::Simple: '0' POSIX: '0' version: '4.20' Apache2-ApacheMobileFilter-4.20/README000644 000765 000024 00000002101 12557613070 021050 0ustar00idelfuschinistaff000000 000000 Apache Mobile Filter is the easiest way to detect mobile devices. AMF is a suite of tools that allow access to a Device Repository (such as WURFL, DetectRight, 51Degrees or others) directly from Apache: now you can detect devices no matter what language your website uses. Apache Mobile Filter site: http://www.apachemobilefilter.org Documentation site: http://wiki.apachemobilefilter.org Demo site: http://litedetection.apachemobilefilter.org http://fiftyone.apachemobilefilter.org http://w.apachemobilefilter.org Support: http://groups.google.com/group/amf-device-detection?hl=en AVAILABILITY The latest version of Apache Mobile Filter is available from the CPAN or http://www.sourceforge.net/projects/mobilefilter/files/latest/download COPYRIGHT Copyright 2009-2010-2011-2012-2013-2014-2015 Idel Fuschini This package is free software and is provided "as is" without express or implied warranty. You can redistribute it and/or modify it under the same terms as Perl itself. Apache2-ApacheMobileFilter-4.20/lib/Apache2/000755 000765 000024 00000000000 13064525445 022211 5ustar00idelfuschinistaff000000 000000 Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMF51DegreesFilter.pm000644 000765 000024 00000072764 13064524645 026006 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMF51DegreesFilter.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 08/12/11 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMF51DegreesFilter; use strict; use warnings; use threads; use threads::shared; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple qw($ua get); use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ; use constant BUFF_LEN => 1024; use Cache::FileBackend; # # Define the global environment # use vars qw($VERSION); $VERSION= "4.20";;; my $CommonLib = new Apache2::AMFCommonLib (); # this is the environment........ my %Capability ; my %Array_fb ; my %Array_id ; my %Array_fullua_id ; my %Array_DDRcapability ; my %MobileArray=$CommonLib->getMobileArray; my %PCArray=$CommonLib->getPCArray; my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoder="true"; my $redirecttranscoderurl="none"; my $resizeimagedirectory="none"; my $Degreesnetdownload="false"; my $download51Degreesurl="https://51degrees.mobi/Products/Downloads/Premium.aspx"; my $listall="false"; my $cookiecachesystem="false"; my $DegreesVersion="unknown"; my $personal51Degreesurl='unknown'; my $cachedirectorystore="/tmp"; my $capabilitylist="none"; my $restmode='false'; my $deepSearch=0; my $checkVersion='false'; my $mobilenable="false"; #details my %PCDetails; $PCDetails{'google_chrome'}='Chrome|Google'; $PCDetails{'google_chrome_0'}='Chrome|Google'; $PCDetails{'google_chrome_1'}='Chrome|Google'; $PCDetails{'google_chrome_2'}='Chrome|Google'; $PCDetails{'google_chrome_3'}='Chrome|Google'; $PCDetails{'msie'}="Microsoft Explorer|Microsoft"; $PCDetails{'safari'}='Safari|Apple'; $PCDetails{'opera'}='Opera|Opera Software'; $PCDetails{'konqueror'}='Konqueror|Mozilla'; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMF51DegreesFilter module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($checkVersion eq 'true') { $CommonLib->printLog("Check on apchemobilefilter.org if the installed AMF is the last version"); $CommonLib->printLog("Try to download http://www.apachemobilefilter.org/param/amf.config"); my $url="http://www.apachemobilefilter.org/param/amf.config"; my $content = get ($url); $content =~ s/\n//g; my $check_version=0; if ($content) { $check_version=$content; } if ($check_version > $VERSION && $check_version ne 0) { $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----- There is a new version of AMF V$check_version online ----"); $CommonLib->printLog("---------------------------------------------------------------------------"); } else { $CommonLib->printLog("AMF installed is the last version"); } } else { $CommonLib->printLog("AMFCheckVersion is false, AMF don't check the last version."); } if ($ENV{ResizeImageDirectory}) { $Capability{'max_image_width'}="max_image_width"; $Capability{'max_image_height'}="max_image_width"; $resizeimagedirectory=$ENV{ResizeImageDirectory}; } if (($ENV{FullBrowserUrl}) || ($ENV{MobileVersionUrl})) { $Capability{'device_claims_web_support'}="device_claims_web_support"; $Capability{'is_wireless_device'}="is_wireless_device"; $fullbrowserurl=$ENV{FullBrowserUrl} } if ($ENV{RedirectTranscoderUrl}) { $Capability{'is_transcoder'}="is_transcoder"; $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; } # # Check if AMFMobileHome and CacheDirectoryStore is setting in apache httpd.conf file for example: # PerlSetEnv AMFMobileHome /MobileFilter # if ($ENV{CacheDirectoryStore}) { $cachedirectorystore=$ENV{CacheDirectoryStore}; $CommonLib->printLog("CacheDirectoryStore is: $cachedirectorystore"); } else { $CommonLib->printLog("CacheDirectoryStore not exist. Please set the variable CacheDirectoryStore into httpd.conf, (the directory must be writeable)"); ModPerl::Util::exit(); } # # Define the cache system directory # my $cacheSystem = new Cache::FileBackend( $cachedirectorystore, 3, 000 ); $cacheSystem->store( '51Degrees-id', 'device_not_found', "id=device_not_found&device=false&device_claims_web_support=true&is_wireless_device=false"); if ($cacheSystem->restore('51Degrees-conf','ver')) { } else { $CommonLib->printLog('Create new wurf-con store'); $cacheSystem->store('51Degrees-conf', 'ver', 'null'); $cacheSystem->store('51Degrees-conf', 'caplist', 'null'); $cacheSystem->store('51Degrees-conf', 'listall', 'null'); $cacheSystem->store('51Degrees-conf', 'RedirectTranscoderUrl','null'); $cacheSystem->store('51Degrees-conf', 'MobileVersionUrl','null'); $cacheSystem->store('51Degrees-conf', 'FullBrowserUrl','null'); $cacheSystem->store('51Degrees-conf', 'ResizeImageDirectory','null'); } if ($ENV{AMFMobileHome}) { &loadConfigFile("$ENV{AMFMobileHome}/51Degrees.xml"); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my ($file51Degrees) = @_; my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("Start read configuration from httpd.conf"); if ($ENV{Degrees51NetDownload}) { if ($ENV{Degrees51NetDownload} eq 'true' || $ENV{Degrees51NetDownload} eq 'false') { $Degreesnetdownload=$ENV{Degrees51NetDownload}; $CommonLib->printLog("51DegreesNetDownload is: $Degreesnetdownload"); } else { $CommonLib->printLog("Error 51DegreesNetDownload parmeter must set to true or false"); ModPerl::Util::exit(); } } if ($ENV{Download51DegreesURL}) { $download51Degreesurl=$ENV{Download51DegreesURL}; $CommonLib->printLog("Download51DegreesURL is: $download51Degreesurl"); } if ($Degreesnetdownload eq 'true') { if ($ENV{Key51Degrees}) { $download51Degreesurl=$download51Degreesurl."?LicenseKeys=".$ENV{Key51Degrees}."&Type=XML&Download=True"; $CommonLib->printLog("Key51Degrees is: $ENV{Key51Degrees}"); } else { $CommonLib->printLog("Error Key51Degrees parmeter must be setted "); ModPerl::Util::exit(); } } if ($ENV{CapabilityList}) { my @dummycapability = split(/,/, $ENV{CapabilityList}); $capabilitylist=$ENV{CapabilityList}; foreach $dummy (@dummycapability) { if ($dummy eq "all") { $listall="true"; } $Capability{$dummy}=$dummy; $CommonLib->printLog("CapabilityList is: $dummy"); } } else { $listall="true"; $CommonLib->printLog('CapabilityList not setted so the default value is "all"'); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode (the CookieCacheSystem is deprecated) is not setted the default value is $cookiecachesystem"); } if ($ENV{Personal51DegreesFileName}) { $personal51Degreesurl=$ENV{AMFMobileHome}."/".$ENV{Personal51DegreesFileName}; $CommonLib->printLog("Personal51DegreesFileName is: $ENV{Personal51DegreesFileName}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDeepParse}) { $deepSearch=$ENV{AMFDeepParse}; $CommonLib->printLog("AMFDeepParse is: $deepSearch"); } else { $CommonLib->printLog("AMFDeepParse is not setted the default value is $deepSearch"); } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable=true"); } $CommonLib->printLog("Finish loading parameter"); $CommonLib->printLog("---------------------------------------------------------------------------"); if ($Degreesnetdownload eq "true") { $CommonLib->printLog("Start process downloading 51Degrees.xml from $download51Degreesurl"); $CommonLib->printLog ("Test the URL"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($download51Degreesurl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $download51Degreesurl."); $CommonLib->printLog("Take the last version downloaded."); # ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL is correct"); $CommonLib->printLog("The size of document 51Degrees file: $document_length bytes"); } if ($content_type eq 'application/octet-stream') { $CommonLib->printLog("The file is a zip file."); $CommonLib->printLog ("Start downloading"); my @dummypairs = split(/\//, $download51Degreesurl); my ($ext_zip) = $download51Degreesurl =~ /\.(\w+)$/; my $filezip=$dummypairs[-1]; my $tmp_dir=$ENV{AMFMobileHome}; $filezip="$tmp_dir/$filezip"; my $status = getstore ($download51Degreesurl,$filezip); my $output="$tmp_dir/51Degrees.xml"; gunzip $filezip => $output or die "gzip failed: $GunzipError\n"; $CommonLib->printLog("Finish downloading 51Degrees from $download51Degreesurl"); } else { $CommonLib->printLog("Error download 51Degrees device repository, check the premium keys. AMF try to load the previous version."); } } if (-e "$file51Degrees") { $CommonLib->printLog("Start loading 51Degrees.xml"); if (open (IN,"$file51Degrees")) { my $filesize= -s $file51Degrees; read (IN,my $content,$filesize); close IN; if ($content =~ /\') + 9 ,index($content,'') - index($content,'') - 9); } else { $DegreesVersion=substr($content,index($content,'') + 9 ,index($content,'') - index($content,'') - 9); } $content =~ s/\n//g; $content =~ s/>/>\n/g; my @rows = split(/\n/, $content); my $numberRow=scalar(@rows); my $progress=0; foreach my $row (@rows){ $r_id=parse51DegreesFile($row,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } } else { $CommonLib->printLog("Error open file:$file51Degrees"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $file51Degrees not found"); ModPerl::Util::exit(); } close IN; my $arrLen = scalar %Array_fb; ($arrLen,$dummy)= split(/\//, $arrLen); if ($arrLen == 0) { $CommonLib->printLog("Error the file probably is not a 51Degrees file, control the url or path"); $CommonLib->printLog("Control also if the file is compress file, and DownloadZipFile parameter is seted false"); ModPerl::Util::exit(); } $CommonLib->printLog("51Degrees version: $DegreesVersion"); if ($cacheSystem->restore('51Degrees-conf', 'amfver') ne $VERSION|| $cacheSystem->restore('51Degrees-conf', 'ResizeImageDirectory') ne $resizeimagedirectory|| $cacheSystem->restore('51Degrees-conf', 'Download51DegreesURL') ne $download51Degreesurl|| $cacheSystem->restore('51Degrees-conf', 'FullBrowserUrl') ne $fullbrowserurl|| $cacheSystem->restore('51Degrees-conf', 'RedirectTranscoderUrl') ne $redirecttranscoderurl|| $cacheSystem->restore('51Degrees-conf', 'ver') ne $DegreesVersion || $cacheSystem->restore('51Degrees-conf', 'caplist') ne $capabilitylist|| $cacheSystem->restore('51Degrees-conf', 'listall') ne $listall) { $CommonLib->printLog("********************************************************************************************************"); $CommonLib->printLog("* This is a new version of 51Degrees or you change some parameter value or it's a new version of AMF, now the old cache must be deleted *"); $CommonLib->printLog("********************************************************************************************************"); $cacheSystem->store('51Degrees-conf', 'ver', $DegreesVersion); $cacheSystem->store('51Degrees-conf', 'amfver', $VERSION); $cacheSystem->store('51Degrees-conf', 'caplist', $capabilitylist); $cacheSystem->store('51Degrees-conf', 'listall', $listall); $cacheSystem->store('51Degrees-conf', 'RedirectTranscoderUrl', $redirecttranscoderurl); $cacheSystem->store('51Degrees-conf', 'FullBrowserUrl', $fullbrowserurl); $cacheSystem->store('51Degrees-conf', 'Download51DegreesURL', $download51Degreesurl); $cacheSystem->store('51Degrees-conf', 'ResizeImageDirectory', $resizeimagedirectory); $cacheSystem->delete_namespace( '51Degrees-id' ); $cacheSystem->delete_namespace( '51Degrees-ua' ); } $CommonLib->printLog("This version of 51Degrees has $arrLen UserAgent"); $CommonLib->printLog("End loading 51Degrees.xml"); if ($personal51Degreesurl ne 'unknown') { $CommonLib->printLog("---------------------------------------------------------------------------"); if (-e "$personal51Degreesurl") { $CommonLib->printLog("Start loading $ENV{Personal51DegreesFileName}"); if (open (IN,"$personal51Degreesurl")) { my $filesize= -s $personal51Degreesurl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); my $progress=0; my $numberRow=scalar(@arrayFile); foreach my $line (@arrayFile) { $r_id=parse51DegreesFile($line,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } } else { $CommonLib->printLog("Error open file:$personal51Degreesurl"); ModPerl::Util::exit(); } $CommonLib->printLog("END loading $ENV{Personal51DegreesFileName}"); close IN; } else { $CommonLib->printLog("File $personal51Degreesurl not found"); ModPerl::Util::exit(); } } } sub callparse51DegreesFile { my ($output) = @_; my $r_id; if (open (IN,"$output")) { my $filesize= -s $output; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parse51DegreesFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$output"); ModPerl::Util::exit(); } } sub parse51DegreesFile { my ($record,$val) = @_; my $null=""; my $null2=""; my $null3=""; my $uagent=""; my $fb=""; my $value=""; my $id; my $name=""; my $version=""; if ($val) { $id="$val"; } if ($record =~ /\-1 ) { $uagent=substr($uagent,index($uagent,'blackberry')); } ($uagent,$version)=$CommonLib->androidDetection($uagent); } if ($field[1]) { $id=$field[1]; if ($id eq '1') { $id='generic_web_browser'; } } if ($field[3]) { $fb=$field[3]; if ($fb eq '1') { $fb='generic_web_browser'; } } if (($fb) && ($id)) { $Array_fb{"$id"}=$fb; } if (($field[5]) && ($id)) { my %ParseUA=$CommonLib->GetMultipleUa($uagent,$deepSearch); my $pair; my $arrUaLen = scalar %ParseUA; my $contaUA=0; my $Array_fullua_id=$uagent; foreach $pair (reverse sort { $a <=> $b } keys %ParseUA) { my $dummy=$ParseUA{$pair}; if ($Array_id{$dummy}) {} else { $Array_id{$dummy}=$id; } $contaUA=$contaUA-1; } } } if ($record =~ /\/o) { $DegreesVersion=substr($record,index($record,'') + 9 ,index($record,'') -13); } return $id; } sub FallBack { my ($idToFind) = @_; my $dummy_id; my $dummy; my $dummy2; my $LOOP; my %ArrayCapFoundToPass; my $capability; foreach $capability (sort keys %Capability) { $dummy_id=$idToFind; $LOOP=0; while ($LOOP<2) { $dummy="$dummy_id|$capability"; if ($Array_DDRcapability{$dummy}) { $LOOP=2; $dummy2="$dummy_id|$capability"; $ArrayCapFoundToPass{$capability}=$Array_DDRcapability{$dummy2}; } else { if ($Array_fb{$dummy_id}) { $dummy_id=$Array_fb{$dummy_id}; } else { $dummy_id="generic_web_browser"; } if ($dummy_id eq "generic_web_browser") { $LOOP++; } } } } return %ArrayCapFoundToPass; } sub IdentifyUAMethod { my ($UserAgent) = @_; my $ind=0; my %ArrayPM; my $pair; my $pair2; my $id_find=""; my $dummy; my $uagent_toMatch; my $near_toFind=100; my $near_toMatch; my %ArrayUAType=$CommonLib->GetMultipleUa(lc($UserAgent),$deepSearch); foreach $pair (reverse sort { $a <=> $b } keys %ArrayUAType) { my $dummy=$ArrayUAType{$pair}; if ($Array_id{$dummy}) { if (!$id_find) { $id_find=$Array_id{$dummy}; } } } return $id_find; } sub IdentifyPCUAMethod { my ($UserAgent) = @_; my $ind=0; my $id_find="none"; my $pair; my $length=0; foreach $pair (sort keys %PCArray) { if ($UserAgent =~ m/$pair/ && $id_find eq 'none') { $id_find=$PCArray{$pair}; } } if ($id_find) {}else{$id_find="";}; return $id_find; } sub handler { my $f = shift; my $capability2; my $variabile=""; my $user_agent=lc($f->headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; $ArrayCapFound{'IsMobile'}='true'; my %ArrayQuery; my $var; my $version=""; my $realPCbrowser='none'; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; $id=$CommonLib->readCookie($cookie); my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=lc($user_agent); if ($user_agent =~ m/blackberry/i) { $user_agent=substr($user_agent,index($user_agent,'blackberry')); } if ($user_agent =~ m/up.link/i ) { $user_agent=substr($user_agent,0,index($user_agent,'up.link') - 1); } if ($user_agent =~ m/c4_acer_mozilla/i ) { $user_agent=substr($user_agent,index($user_agent,'mozilla')); } ($user_agent,$version)=$CommonLib->androidDetection($user_agent); if ($cacheSystem->restore( '51Degrees-ua', $user_agent )) { # # cookie is not empty so I try to read in memory cache on my httpd cache # $id=$cacheSystem->restore( '51Degrees-ua', $user_agent ); if ($cacheSystem->restore( '51Degrees-id', $id )) { # # I'm here only for old device # my @pairs = split(/&/, $cacheSystem->restore( '51Degrees-id', $id )); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); if ($dummy) { $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes($string_tofound => $ArrayCapFound{$string_tofound}); } } $id=$ArrayCapFound{id}; if ($ArrayCapFound{realpcbrowser} ne 'none') { $id=$realPCbrowser; $ArrayCapFound{'IsMobile'}='false'; } } } else { if ($id eq "") { if ($user_agent) { my $pair; my $lcuser_agent=lc($user_agent); if (!$id) {$id="";}; if ($id eq "") { $id=IdentifyUAMethod($user_agent); } if ($id eq "") { $id='generic_web_browser'; } else { #this check the correct version of Android if ($version) { if ($version ne 'nc') { my $lengthId=length($version); my $count=0; while($count<$lengthId) { my $idToCheck=$id."_sub".substr($version,0,length($version)-$count); if ($Array_fb{$idToCheck}) { $id=$idToCheck; $count=$lengthId; } $count++; } } } } $cacheSystem->store( '51Degrees-ua', $user_agent, $id); } } if ($id ne "") { # # device detected # if ($cacheSystem->restore( '51Degrees-id', $id )) { # # I'm here only for old device looking in cache # my @pairs = split(/&/, $cacheSystem->restore( '51Degrees-id', $id )); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes("$string_tofound" => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } else { %ArrayCapFound=FallBack($id); foreach $capability2 (sort keys %ArrayCapFound) { $variabile2="$variabile2$capability2=$ArrayCapFound{$capability2}&"; my $upper=uc($capability2); $f->subprocess_env("AMF_$upper" => $ArrayCapFound{$capability2}); $f->pnotes("$capability2" => $ArrayCapFound{$capability2}); } $variabile2="id=$id&$variabile2&realpcbrowser=$realPCbrowser"; $f->subprocess_env("AMF_ID" => $id); $f->pnotes('id' => $id); $cacheSystem->store( '51Degrees-id', $id, $variabile2 ); $cacheSystem->store( '51Degrees-ua', $user_agent, $id); } if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amf=$id; path=/;"); } } } if ($ArrayCapFound{'ScreenPixelsWidth'} ne 'Unknown') { $f->pnotes("max_image_width" => $ArrayCapFound{'ScreenPixelsWidth'}); $f->pnotes("max_image_height" => $ArrayCapFound{'ScreenPixelsHeight'}); } if ($ArrayCapFound{'IsTablet'}) { $f->pnotes("is_tablet" => lc($ArrayCapFound{'IsTablet'})); $f->subprocess_env("AMF_DEVICE_IS_TABLET" => lc($ArrayCapFound{'IsTablet'})); } if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } $f->pnotes("amf_device_ismobile" => lc($ArrayCapFound{'IsMobile'})); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => lc($ArrayCapFound{'IsMobile'})); $f->subprocess_env("AMF_VER" => $VERSION); $f->subprocess_env("AMF_DEGREES51_VER" => $DegreesVersion); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMF51DegreesFilter - The module detects the mobile device and passes the 51Degrees capabilities on to the other web application as environment variables =head1 DESCRIPTION Module for device detection, the cache is based on file system h=head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMF51DegreesFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMF51DegreesFilterMemcached.pm000644 000765 000024 00000061635 13064524645 027570 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMF51DegreesFilterMemcached.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 08/12/11 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMF51DegreesFilterMemcached; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use APR::Table (); use LWP::Simple qw($ua get); use Apache2::Const -compile => qw(DECLINED); use constant BUFF_LEN => 1024; use Cache::Memcached; use Digest::MD5 qw(md5_hex); use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ; # # Define the global environment # use vars qw($VERSION); my $CommonLib = new Apache2::AMFCommonLib (); $VERSION= "4.20";;; my %Capability; my %Array_fb; my %Array_id; my %Array_fullua_id; my %Array_DDRcapability; my %MobileArray=$CommonLib->getMobileArray; my %PCArray=$CommonLib->getPCArray; my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoder="true"; my $redirecttranscoderurl="none"; my $resizeimagedirectory="none"; my $Degreesnetdownload="false"; my $download51Degreesurl="https://51degrees.mobi/Products/Downloads/Premium.aspx"; my $listall="false"; my $cookiecachesystem="false"; my $DegreesVersion="unknown"; my $personal51Degreesurl='unknown'; my $serverMemCache; my $restmode='false'; my $deepSearch=0; my $checkVersion='false'; my $mobilenable="false"; #details my %PCDetails; $PCDetails{'google_chrome'}='Chrome|Google'; $PCDetails{'google_chrome_0'}='Chrome|Google'; $PCDetails{'google_chrome_1'}='Chrome|Google'; $PCDetails{'google_chrome_2'}='Chrome|Google'; $PCDetails{'google_chrome_3'}='Chrome|Google'; $PCDetails{'msie'}="Microsoft Explorer|Microsoft"; $PCDetails{'safari'}='Safari|Apple'; $PCDetails{'opera'}='Opera|Opera Software'; $PCDetails{'konqueror'}='Konqueror|Mozilla'; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMF51DegreesFilterMemcached module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($checkVersion eq 'true') { $CommonLib->printLog("Check on apchemobilefilter.org if the installed AMF is the last version"); $CommonLib->printLog("Try to download http://www.apachemobilefilter.org/param/amf.config"); my $url="http://www.apachemobilefilter.org/param/amf.config"; my $content = get ($url); $content =~ s/\n//g; my $check_version=0; if ($content) { $check_version=$content; } if ($check_version > $VERSION && $check_version ne 0) { $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----- There is a new version of AMF V$check_version online ----"); $CommonLib->printLog("---------------------------------------------------------------------------"); } else { $CommonLib->printLog("AMF installed is the last version"); } } else { $CommonLib->printLog("AMFCheckVersion is false, AMF don't check the last version."); } if ($ENV{ResizeImageDirectory}) { $Capability{'max_image_width'}="max_image_width"; $Capability{'max_image_height'}="max_image_width"; $resizeimagedirectory=$ENV{ResizeImageDirectory}; } if (($ENV{FullBrowserUrl}) || ($ENV{MobileVersionUrl})) { $Capability{'device_claims_web_support'}="device_claims_web_support"; $Capability{'is_wireless_device'}="is_wireless_device"; $fullbrowserurl=$ENV{FullBrowserUrl} } if ($ENV{RedirectTranscoderUrl}) { $Capability{'is_transcoder'}="is_transcoder"; $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; } # # Check if AMFMobileHome and CacheDirectoryStore is setting in apache httpd.conf file for example: # PerlSetEnv AMFMobileHome /MobileFilter # my @Server; if ($ENV{ServerMemCached}) { $serverMemCache=$ENV{ServerMemCached}; @Server = split(/,/, $ENV{ServerMemCached}); $CommonLib->printLog("ServerMemCached is: $serverMemCache"); } else { $CommonLib->printLog("ServerMemCached is not setted. Please set the variable ServerMemCached into httpd.conf, example \"PerlSetEnv ServerMemCached 10.10.10.10:11211\""); ModPerl::Util::exit(); } my $memd = new Cache::Memcached { 'debug' => 0, 'compress_threshold' => 10_000, 'enable_compress' => 1, }; $memd->set_servers(\@Server); if ($ENV{AMFMobileHome}) { &loadConfigFile("$ENV{AMFMobileHome}/51Degrees.xml"); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my ($file51Degrees) = @_; my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("Start read configuration from httpd.conf"); if ($ENV{Degrees51NetDownload}) { if ($ENV{Degrees51NetDownload} eq 'true' || $ENV{Degrees51NetDownload} eq 'false') { $Degreesnetdownload=$ENV{Degrees51NetDownload}; $CommonLib->printLog("51DegreesNetDownload is: $Degreesnetdownload"); } else { $CommonLib->printLog("Error 51DegreesNetDownload parmeter must set to true or false"); ModPerl::Util::exit(); } } if ($ENV{Download51DegreesURL}) { $download51Degreesurl=$ENV{Download51DegreesURL}; $CommonLib->printLog("Download51DegreesURL is: $download51Degreesurl"); } if ($Degreesnetdownload eq 'true') { if ($ENV{Key51Degrees}) { $download51Degreesurl=$download51Degreesurl."?LicenseKeys=".$ENV{Key51Degrees}."&Type=XML&Download=True"; $CommonLib->printLog("Key51Degrees is: $ENV{Key51Degrees}"); } else { $CommonLib->printLog("Error Key51Degrees parmeter must be setted "); ModPerl::Util::exit(); } } if ($ENV{CapabilityList}) { my @dummycapability = split(/,/, $ENV{CapabilityList}); foreach $dummy (@dummycapability) { if ($dummy eq "all") { $listall="true"; } $Capability{$dummy}=$dummy; $CommonLib->printLog("CapabilityList is: $dummy"); } } else { $listall="true"; $CommonLib->printLog('CapabilityList not setted so the default value is "all"'); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode (the CookieCacheSystem is deprecated) is not setted the default value is $cookiecachesystem"); } if ($ENV{Personal51DegreesFileName}) { $personal51Degreesurl=$ENV{AMFMobileHome}."/".$ENV{Personal51DegreesFileName}; $CommonLib->printLog("Personal51DegreesFileName is: $ENV{Personal51DegreesFileName}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDeepParse}) { $deepSearch=$ENV{AMFDeepParse}; $CommonLib->printLog("AMFDeepParse is: $deepSearch"); } else { $CommonLib->printLog("AMFDeepParse is not setted the default value is 3"); } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable"); } $CommonLib->printLog("Finish loading parameter"); $CommonLib->printLog("---------------------------------------------------------------------------"); if ($Degreesnetdownload eq "true") { $CommonLib->printLog("Start process downloading 51Degrees.xml from $download51Degreesurl"); $CommonLib->printLog ("Test the URL"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($download51Degreesurl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $download51Degreesurl."); $CommonLib->printLog("Take the last version downloaded."); #ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL is correct"); $CommonLib->printLog("The size of document 51Degrees file: $document_length bytes"); } if ($content_type eq 'application/octet-stream') { $CommonLib->printLog("The file is a zip file."); $CommonLib->printLog ("Start downloading"); my @dummypairs = split(/\//, $download51Degreesurl); my ($ext_zip) = $download51Degreesurl =~ /\.(\w+)$/; my $filezip=$dummypairs[-1]; my $tmp_dir=$ENV{AMFMobileHome}; $filezip="$tmp_dir/$filezip"; my $status = getstore ($download51Degreesurl,$filezip); my $output="$tmp_dir/51Degrees.xml"; gunzip $filezip => $output or die "gzip failed: $GunzipError\n"; $CommonLib->printLog("Finish downloading 51Degrees from $download51Degreesurl"); } else { $CommonLib->printLog("Error download 51Degrees device repository, check the premium keys. AMF try to load the previous version."); } } if (-e "$file51Degrees") { $CommonLib->printLog("Start loading 51Degrees.xml"); if (open (IN,"$file51Degrees")) { my $filesize= -s $file51Degrees; read (IN,my $content,$filesize); close IN; if ($content =~ /\') + 9 ,index($content,'') - index($content,'') - 9); } else { $DegreesVersion=substr($content,index($content,'') + 9 ,index($content,'') - index($content,'') - 9); } $content =~ s/\n//g; $content =~ s/>/>\n/g; my @rows = split(/\n/, $content); my $numberRow=scalar(@rows); my $progress=0; foreach my $row (@rows){ $r_id=parse51DegreesFile($row,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } close IN; } else { $CommonLib->printLog("Error open file:$file51Degrees"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $file51Degrees not found"); ModPerl::Util::exit(); } close IN; my $arrLen = scalar %Array_fb; ($arrLen,$dummy)= split(/\//, $arrLen); if ($arrLen == 0) { $CommonLib->printLog("Error the file probably is not a 51Degrees file, control the url or path"); $CommonLib->printLog("Control also if the file is compress file, and DownloadZipFile parameter is seted false"); #ModPerl::Util::exit(); } $CommonLib->printLog("51Degrees version: $DegreesVersion"); $CommonLib->printLog("This version of 51Degrees has $arrLen UserAgent"); $CommonLib->printLog("End loading 51Degrees.xml"); if ($personal51Degreesurl ne 'unknown') { $CommonLib->printLog("---------------------------------------------------------------------------"); if (-e "$personal51Degreesurl") { $CommonLib->printLog("Start loading $ENV{Personal51DegreesFileName}"); if (open (IN,"$personal51Degreesurl")) { my $filesize= -s $personal51Degreesurl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parse51DegreesFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$personal51Degreesurl"); ModPerl::Util::exit(); } $CommonLib->printLog("END loading $ENV{Personal51DegreesFileName}"); close IN; } else { $CommonLib->printLog("File $personal51Degreesurl not found"); ModPerl::Util::exit(); } } } sub FallBack { my ($idToFind) = @_; my $dummy_id; my $dummy; my $dummy2; my $LOOP; my %ArrayCapFoundToPass; my $capability; foreach $capability (sort keys %Capability) { $dummy_id=$idToFind; $LOOP=0; while ($LOOP<2) { $dummy="$dummy_id|$capability"; if ($Array_DDRcapability{$dummy}) { $LOOP=2; $dummy2="$dummy_id|$capability"; $ArrayCapFoundToPass{$capability}=$Array_DDRcapability{$dummy2}; } else { if ($Array_fb{$dummy_id}) { $dummy_id=$Array_fb{$dummy_id}; } else { $dummy_id="generic_web_browser"; } if ($dummy_id eq "generic_web_browser") { $LOOP++; } } } } return %ArrayCapFoundToPass; } sub IdentifyUAMethod { my ($UserAgent) = @_; my $ind=0; my %ArrayPM; my $pair; my $pair2; my $id_find=""; my $dummy; my $uagent_toMatch; my $near_toFind=100; my $near_toMatch; my %ArrayUAType=$CommonLib->GetMultipleUa(lc($UserAgent),$deepSearch); foreach $pair (reverse sort { $a <=> $b } keys %ArrayUAType) { my $dummy=$ArrayUAType{$pair}; if ($Array_id{$dummy}) { if (!$id_find) { $id_find=$Array_id{$dummy}; } } } return $id_find; } sub IdentifyPCUAMethod { my ($UserAgent) = @_; my $ind=0; my $id_find="none"; my $pair; my $length=0; foreach $pair (sort keys %PCArray) { if ($UserAgent =~ m/$pair/ && $id_find eq 'none') { $id_find=$PCArray{$pair}; } } if (!$id_find) {$id_find="";} return $id_find; } sub callparse51DegreesFile { my ($output) = @_; my $r_id; if (open (IN,"$output")) { my $filesize= -s $output; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parse51DegreesFile($line,$r_id); } close IN; } else { $CommonLib->printLog("Error open file:$output"); ModPerl::Util::exit(); } } sub parse51DegreesFile { my ($record,$val) = @_; my $null=""; my $null2=""; my $null3=""; my $uagent=""; my $fb=""; my $value=""; my $id; my $name=""; my $version=""; if ($val) { $id="$val"; } if ($record =~ /\-1 ) { $uagent=substr($uagent,index($uagent,'blackberry')); } ($uagent,$version)=$CommonLib->androidDetection($uagent); $uagent=$CommonLib->CleanUa($uagent); } if ($field[1]) { $id=$field[1]; if ($id eq '1') { $id='generic_web_browser'; } } if ($field[3]) { $fb=$field[3]; if ($fb eq '1') { $fb='generic_web_browser'; } } if (($fb) && ($id)) { $Array_fb{"$id"}=$fb; } if (($field[5]) && ($id)) { my %ParseUA=$CommonLib->GetMultipleUa($uagent,$deepSearch); my $pair; my $arrUaLen = scalar %ParseUA; my $contaUA=0; my $Array_fullua_id=$uagent; foreach $pair (reverse sort { $a <=> $b } keys %ParseUA) { my $dummy=$ParseUA{$pair}; if ($Array_id{$dummy}) {} else { $Array_id{$dummy}=$id; } $contaUA=$contaUA-1; } } } if ($record =~ /\headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; $ArrayCapFound{'IsMobile'}='true'; my %ArrayQuery; my $var; my $version=""; my $realPCbrowser='none'; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; $id=$CommonLib->readCookie($cookie); my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=lc($user_agent); if ($user_agent =~ m/blackberry/i) { $user_agent=substr($user_agent,index($user_agent,'blackberry')); } if ($user_agent =~ m/up.link/i ) { $user_agent=substr($user_agent,0,index($user_agent,'up.link') - 1); } if ($user_agent =~ m/c4_acer_mozilla/i ) { $user_agent=substr($user_agent,index($user_agent,'mozilla')); } $user_agent=$CommonLib->CleanUa($user_agent); ($user_agent,$version)=$CommonLib->androidDetection($user_agent); if ($id eq ""){ if ($user_agent) { if (!$id) {$id="";}; if ($id eq "") { $id=IdentifyUAMethod($user_agent); } if ($id eq "") { $id='generic_web_browser'; } else { #this check the correct version of Android if ($version) { if ($version ne 'nc') { my $lengthId=length($version); my $count=0; while($count<$lengthId) { my $idToCheck=$id."_sub".substr($version,0,length($version)-$count); if ($Array_fb{$idToCheck}) { $id=$idToCheck; $count=$lengthId; } $count++; } } } } } } if ($id ne "") { # # device detected # if ($realPCbrowser ne 'none') { $id=$realPCbrowser; } my $var=$memd->get("D51_$id"); if ($var) { my @pairs = split(/&/, $var); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes("$string_tofound" => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } else { %ArrayCapFound=FallBack($id); foreach $capability2 (sort keys %ArrayCapFound) { $variabile2="$variabile2$capability2=$ArrayCapFound{$capability2}&"; my $upper=uc($capability2); $f->subprocess_env("AMF_$upper" => $ArrayCapFound{$capability2}); $f->pnotes("$capability2" => $ArrayCapFound{$capability2}); } $variabile2="id=$id&$variabile2"; $f->subprocess_env("AMF_ID" => $id); $f->pnotes('id' => $id); $memd->set("D51_$id",$variabile2); } if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amf=$id; path=/;"); } } if ($ArrayCapFound{'ScreenPixelsWidth'} ne 'Unknown') { $f->pnotes("max_image_width" => $ArrayCapFound{'ScreenPixelsWidth'}); $f->pnotes("max_image_height" => $ArrayCapFound{'ScreenPixelsHeight'}); } if ($ArrayCapFound{'IsTablet'}) { $f->pnotes("is_tablet" => lc($ArrayCapFound{'IsTablet'})); $f->subprocess_env("AMF_DEVICE_IS_TABLET" => lc($ArrayCapFound{'IsTablet'})); } if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } $f->pnotes("amf_device_ismobile" => lc($ArrayCapFound{'IsMobile'})); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => lc($ArrayCapFound{'IsMobile'})); $f->subprocess_env("AMF_VER" => $VERSION); $f->subprocess_env("AMF_DEGREES51_VER" => $DegreesVersion); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMF51DegreesFilterMemcached - The module detects the mobile device and passes the 51Degrees capabilities on to the other web application as environment variables =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMF51DegreesFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFCarrierDetection.pm000644 000765 000024 00000011625 13064524645 026327 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFCarrierDetection.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFCarrierDetection; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use Apache2::Connection (); use APR::Table (); use LWP::Simple; use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use vars qw($VERSION); $VERSION= "4.20";;; # # Define the global environment # my $CommonLib = new Apache2::AMFCommonLib (); my $filecarriernetdownload="none"; my %CarrierIP; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFCarrierDetection Version $VERSION"); if ($ENV{AMFMobileHome}) { &loadConfigFile(); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); $CommonLib->printLog("Pre-Requisite: WURFLFilter must be activated"); ModPerl::Util::exit(); } sub loadConfigFile { my $dummy; my $carrier; my $nation; my $ip; my $row; my @rows; my $carriernetdownload="none"; my $carrierurl; my $total_carrier_ip=0; my $ip2; $CommonLib->printLog("AMFCarrierDetection: Start read configuration from httpd.conf"); if ($ENV{CarrierNetDownload}) { $carriernetdownload=$ENV{CarrierNetDownload}; $CommonLib->printLog("CarrierNetDownload is: $carriernetdownload"); } if (($ENV{CarrierUrl}) && $carriernetdownload eq 'true') { $carrierurl=$ENV{CarrierUrl}; $CommonLib->printLog("CarrierUrl is: $carrierurl"); } if ($carriernetdownload eq "true") { $CommonLib->printLog("Start downloading Carrier DB from $carrierurl"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($carrierurl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $carrierurl."); ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL for download Carrier DB is correct"); $CommonLib->printLog("The size of document is: $document_length bytes"); } my $content = get ($carrierurl); $CommonLib->printLog("Finish downloading Carrier DB"); if ($content eq "") { $CommonLib->printLog("Couldn't get Data DB from $carrierurl."); ModPerl::Util::exit(); } @rows = split(/\n/, $content); my $count=0; foreach $row (@rows){ ($carrier,$nation,$ip)=split(/\|/, $row); $CarrierIP{"$ip"}="$carrier|$nation"; $total_carrier_ip++; } } else { my $fileCarrier="$ENV{AMFMobileHome}/carrier-data.txt"; if (-e "$fileCarrier") { $CommonLib->printLog("Start loading carrier-data.txt"); if (open (IN,"$fileCarrier")) { while () { #$ip=~s/\n/-/ ; $ip=substr($_,0,10); my $lunghezza= length($_) - 2; my $string=substr($_, 0, $lunghezza); ($carrier,$nation,$ip)=split(/\|/, $string); $CarrierIP{$ip}="$carrier|$nation"; $total_carrier_ip++; } close IN; } else { $CommonLib->printLog("Error open file:$fileCarrier"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $fileCarrier not found"); ModPerl::Util::exit(); } } $CommonLib->printLog("Total of Carrier IP: $total_carrier_ip"); $CommonLib->printLog("Finish loading parameter"); } sub handler { my $f = shift; my $return_value=Apache2::Const::DECLINED; my $c = $f->connection; my $remote_ip=$c->remote_ip(); my $nation="none"; my $carrier="none"; if ($CarrierIP{"$remote_ip"}) { ($nation, $carrier) = split(/\|/, $CarrierIP{"$remote_ip"}); } $f->subprocess_env("AMF_CARRIER_NAME" => $carrier); $f->subprocess_env("AMF_CARRIER_NATION" => $nation); return $return_value; } 1; =head1 NAME Apache2::AMFCarrierDetection - This module has the scope to identify by ip address the carrier and the nation. =head1 DESCRIPTION This module has the scope to identify by ip address the carrier and the nation. NOTE: this software need carrier-data.txt you can download it directly from this site: http://www.andymoore.info/carrier-data.txt or you can set the filter to download it directly. =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFCarrierDetection =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFCommonLib.pm000644 000765 000024 00000017417 13064524645 024765 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFCommonLib.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFCommonLib; use strict; use warnings; use vars qw($VERSION); $VERSION= "4.20";;; sub new { my $package = shift; return bless({}, $package); } sub getMobileArray { my %MobileArray; my $mobileParam="android,bolt,brew,docomo,foma,hiptop,htc,ipod,ipad,kddi,kindle,lge,maemo,midp,mobi,netfront,nintendo,nokia,novarra,openweb,palm,phone,playstation,psp,samsung,sanyo,softbank,sony,symbian,up.browser,up.link,wap,webos,windows ce,wireless,xv6875.1,mini,mobi,symbos,touchpad,rim,arm,zune,spv,blackberry,mitsu,siem,sama,sch-,moto,ipaq,sec-,sgh-,gradiente,alcat,mot-,sagem,ericsson,lg-,lg/,nec-,philips,panasonic,kwc-,portalm,telit,ericy,zte,hutc,qc-,sharp,vodafone,compal,dbtel,sendo,benq,bird,amoi,becker,lenovo,tsm"; my @dummyMobileKeys = split(/,/, $mobileParam); foreach my $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } return %MobileArray; } sub getPCArray { my %PCArray; $PCArray{'chrome'}='google_chrome'; my $i=0; while ($i < 28) { $PCArray{"chrome/$i"}="google_chrome_$i"; $i++; } $i=4; $PCArray{'firefox'}='firefox'; $PCArray{'firefox/1.0'}='firefox_1'; $PCArray{'firefox/2.0'}='firefox_2'; $PCArray{'firefox/3.0'}='firefox_3'; $PCArray{'firefox/3.5'}='firefox_3_5'; while ($i < 12) { $PCArray{"firefox/$i.0"}="firefox_".$i."_0"; $i++; } $PCArray{'chrome/'}='google_chrome_'; $PCArray{'msie'}='msie'; $PCArray{'msie 5'}='msie_5'; $PCArray{'msie 6'}='msie_6'; $PCArray{'msie 7'}='msie_7'; $PCArray{'msie 8'}='msie_8'; $PCArray{'msie 9'}='msie_9'; $PCArray{'opera'}='opera'; $PCArray{'konqueror'}='konqueror'; return %PCArray; } sub getMD5 { my $self = shift; my $file; if (@_) { $file = shift; } open(FILE, $file) or die "Can't open '$file': $!"; binmode(FILE); my $returnMD5=Digest::MD5->new->addfile(*FILE)->hexdigest; return $returnMD5; } sub Data { my $_sec; my $_min; my $_hour; my $_mday; my $_day; my $_mon; my $_year; my $_wday; my $_yday; my $_isdst; my $_data; ($_sec,$_min,$_hour,$_mday,$_mon,$_year,$_wday,$_yday,$_isdst) = localtime(time); $_mon=$_mon+1; $_year=substr($_year,1); $_mon=&correct_number($_mon); $_mday=&correct_number($_mday); $_hour=&correct_number($_hour); $_min=&correct_number($_min); $_sec=&correct_number($_sec); $_data="$_mday/$_mon/$_year - $_hour:$_min:$_sec"; return $_data; } sub correct_number { my ($number) = @_; if ($number < 10) { $number="0$number"; } return $number; } sub printLog { my $self = shift; if (@_) { $self->{'printLog'} = shift; } my $data=Data(); print "$data - $self->{'printLog'}\n"; } sub CleanUa { my $self = shift; my $UserAgent; if (@_) { $UserAgent = shift; } my $string=""; $UserAgent =~ s/\ //g; #$UserAgent =~ s/([0-9\\.]+).*?//g; $UserAgent =~ s/iemobile \/([0-9\\.]+).*?/iemobile /g; $UserAgent =~ s/series40\/([0-9\\.]+)...(!?abc)*?/series40/g; $UserAgent =~ s/series60\/([0-9\\.]+)...(!?abc)*?/series60/g; if ( $UserAgent =~ m/^outlook/i ) { $UserAgent=substr($UserAgent,index($UserAgent,'(') + 1,length($UserAgent) - index($UserAgent,'(') -2); } if ( $UserAgent =~ m/windows nt/i) { my $first=substr($UserAgent,0,index($UserAgent,'windows nt') + 12); my $second=""; if (length($UserAgent) > index($UserAgent,'windows nt') + 14) { $second=substr($UserAgent,index($UserAgent,'windows nt') + 14); } $UserAgent=$first.$second; } my @arrayFile=split(/\ /, $UserAgent); foreach my $field (@arrayFile) { if ($field =~ m/applewebkit/i || $field =~ m/chrome/i || $field =~ m/safari/i) { my ($first,$second)=split(/\//, $field); $string=$string." ".$first; } else { $string=$string." ".$field; } } $string=substr($string,1); return $string; } sub GetMultipleUa { my $self = shift; my $UserAgent; my $deep; my $count=0; if (@_) { $UserAgent = shift; $deep = shift; } my $length=length($UserAgent); my %ArrayUAparse; if (substr($UserAgent,$length-1,1) eq ')') { $UserAgent=substr($UserAgent,0,$length-1); } $UserAgent =~ s/\ /|/g; $UserAgent =~ s/\//|/g; $UserAgent =~ s/\-/|/g; $UserAgent =~ s/\_/|/g; $UserAgent =~ s/\./|/g; my @pairs = split(/\|/, $UserAgent); my $deep_to_verify=scalar(@pairs) - $deep - 1; my $ind=0; my $string=""; if ($deep > scalar(@pairs)) { $deep=scalar(@pairs) - 1; } foreach my $key (@pairs) { if ($ind==0) { $string=$key; } else { $string=$string." ".$key; } if ($ind > $deep - 1) { $ArrayUAparse{$ind}=$string; } $ind++; } return %ArrayUAparse; } sub androidDetection { my $self = shift; my $ua=""; if (@_) { $ua = shift; } #print "$ua----------\n"; my $version='nc'; my $os='nc'; if (index($ua,'android') > -1 ) { #my $string_to_parse=substr($ua,index($ua,'(') + 1,index($ua,')')); my @param=split(/\;/,$ua); #my ($dummy1,$dummy2,$vers,$lan,$dummy5)=split(/\;/,$string_to_parse); my $element=scalar @param; my $count=0; my $count_add=0; my @param_ua; if ($element > 0) { while ($count<$element) { if (index($param[$count],'-')>-1 && length($param[$count])==6) { } elsif (length($param[$count])==2) { } elsif (index($param[$count],'android')>-1) { ($os,$version)=split(/ /,$param[$count]); if ($version) { if (index($version,'.') > -1) { $version =~ s/\.//g; } } $param_ua[$count_add]="android xx"; $count_add++; } else { $param_ua[$count_add]=$param[$count]; $count_add++; } $count++; } $count=0; $element=scalar @param_ua; $ua = ""; while ($count < $element) { $ua=$ua." ".$param_ua[$count]; $count++; } $ua=substr($ua,1); } #print $ua."\n"; } return ($ua,$version); } sub botDetection { my $self = shift; my $ua=""; my @arrayBot = ('googlebot','google web preview','msnbot','google.com/bot','ia_archiver','yahoo!','webalta crawler','flickysearchbot','yanga worldsearch','stackrambler','mail.ru','yandex'); if (@_) { $ua = shift; } foreach my $pair (@arrayBot) { if (index($ua,$pair) > -1 ) { $ua='It is a bot'; } } return $ua; } sub readCookie { my $self = shift; my $cookie_search; if (@_) { $cookie_search = shift; } my $param_tofound; my $string_tofound; my $value=""; my $id_return=""; my @pairs = split(/;/, $cookie_search); my $name; foreach $param_tofound (@pairs) { ($string_tofound,$value)=split(/=/, $param_tofound); if ($string_tofound =~ "amfID") { $id_return=$value; } } return $id_return; } sub readCookie_fullB { my $self = shift; my $cookie_search; if (@_) { $cookie_search = shift; } my $param_tofound; my $string_tofound; my $value=""; my $id_return=""; my @pairs = split(/;/, $cookie_search); my $name; foreach $param_tofound (@pairs) { ($string_tofound,$value)=split(/=/, $param_tofound); if ($string_tofound =~ "amfFull") { $id_return=$value; } } return $id_return; } 1; =head1 NAME Apache2::AMFCommonLib - Common Library That AMF uses. =head1 DESCRIPTION Is a simple Common Library for AMF =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cutApache2-ApacheMobileFilter-4.20/lib/Apache2/AMFDetectRightFilter.pm000644 000765 000024 00000072017 13064524645 026457 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFDetectRightFilter.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 15/10/11 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFDetectRightFilter; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple qw($ua get); use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use Cache::FileBackend; # # Define the global environment # use vars qw($VERSION); $VERSION= "4.20";;; my $CommonLib = new Apache2::AMFCommonLib (); my %Capability; my %Array_fb; my %Array_id; my %Array_fullua_id; my %Array_DDRcapability; my %MobileArray=$CommonLib->getMobileArray; my %PCArray=$CommonLib->getPCArray; my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoder="true"; my $redirecttranscoderurl="none"; my $resizeimagedirectory="none"; my $DetectRightnetdownload="false"; my $downloadDetectRighturl="false"; my $listall="false"; my $cookiecachesystem="false"; my $DetectRightVersion="unknown"; my $personalDetectRighturl='unknown'; my $cachedirectorystore="/tmp"; my $capabilitylist="none"; my $restmode='false'; my $deepSearch=2; my $checkVersion='false'; my $mobilenable="false"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFDetectRightFilter module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($checkVersion eq 'true') { $CommonLib->printLog("Check on apchemobilefilter.org if the installed AMF is the last version"); $CommonLib->printLog("Try to download http://www.apachemobilefilter.org/param/amf.config"); my $url="http://www.apachemobilefilter.org/param/amf.config"; my $content = get ($url); $content =~ s/\n//g; my $check_version=0; if ($content) { $check_version=$content; } if ($check_version > $VERSION && $check_version ne 0) { $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----- There is a new version of AMF V$check_version online ----"); $CommonLib->printLog("---------------------------------------------------------------------------"); } else { $CommonLib->printLog("AMF installed is the last version"); } } else { $CommonLib->printLog("AMFCheckVersion is false, AMF don't check the last version."); } if ($ENV{ResizeImageDirectory}) { $Capability{'max_image_width'}="max_image_width"; $Capability{'max_image_height'}="max_image_width"; $resizeimagedirectory=$ENV{ResizeImageDirectory}; } if (($ENV{FullBrowserUrl}) || ($ENV{MobileVersionUrl})) { $Capability{'device_claims_web_support'}="device_claims_web_support"; $Capability{'is_wireless_device'}="is_wireless_device"; $fullbrowserurl=$ENV{FullBrowserUrl} } if ($ENV{RedirectTranscoderUrl}) { $Capability{'is_transcoder'}="is_transcoder"; $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; } # # Check if AMFMobileHome and CacheDirectoryStore is setting in apache httpd.conf file for example: # PerlSetEnv AMFMobileHome /MobileFilter # if ($ENV{CacheDirectoryStore}) { $cachedirectorystore=$ENV{CacheDirectoryStore}; $CommonLib->printLog("CacheDirectoryStore is: $cachedirectorystore"); } else { $CommonLib->printLog("CacheDirectoryStore not exist. Please set the variable CacheDirectoryStore into httpd.conf, (the directory must be writeable)"); ModPerl::Util::exit(); } # # Define the cache system directory # my $cacheSystem = new Cache::FileBackend( $cachedirectorystore, 3, 000 ); $cacheSystem->store( 'DetectRight-id', 'device_not_found', "id=device_not_found&device=false&device_claims_web_support=true&is_wireless_device=false"); if ($cacheSystem->restore('DetectRight-conf','ver')) { } else { $CommonLib->printLog('Create new wurf-con store'); $cacheSystem->store('DetectRight-conf', 'ver', 'null'); $cacheSystem->store('DetectRight-conf', 'caplist', 'null'); $cacheSystem->store('DetectRight-conf', 'listall', 'null'); $cacheSystem->store('DetectRight-conf', 'RedirectTranscoderUrl','null'); $cacheSystem->store('DetectRight-conf', 'MobileVersionUrl','null'); $cacheSystem->store('DetectRight-conf', 'FullBrowserUrl','null'); $cacheSystem->store('DetectRight-conf', 'ResizeImageDirectory','null'); } if ($ENV{AMFMobileHome}) { &loadConfigFile("$ENV{AMFMobileHome}/DetectRightAMF.xml"); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my ($fileDetectRight) = @_; my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("Start read configuration from httpd.conf"); if ($ENV{DetectRightNetDownload}) { if ($ENV{DetectRightNetDownload} eq 'true' || $ENV{DetectRightNetDownload} eq 'false') { $DetectRightnetdownload=$ENV{DetectRightNetDownload}; $CommonLib->printLog("DetectRightNetDownload is: $DetectRightnetdownload"); } else { $CommonLib->printLog("Error DetectRightNetDownload parmeter must set to true or false"); ModPerl::Util::exit(); } } if ($ENV{DownloadDetectRightURL}) { $downloadDetectRighturl=$ENV{DownloadDetectRightURL}; $CommonLib->printLog("DownloadDetectRightURL is: $downloadDetectRighturl"); } if ($ENV{CapabilityList}) { my @dummycapability = split(/,/, $ENV{CapabilityList}); $capabilitylist=$ENV{CapabilityList}; foreach $dummy (@dummycapability) { if ($dummy eq "all") { $listall="true"; } $Capability{$dummy}=$dummy; $CommonLib->printLog("CapabilityList is: $dummy"); } } else { $listall="true"; $CommonLib->printLog('CapabilityList not setted so the default value is "all"'); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode (the CookieCacheSystem is deprecated) is not setted the default value is $cookiecachesystem"); } if ($ENV{PersonalDetectRightFileName}) { $personalDetectRighturl=$ENV{AMFMobileHome}."/".$ENV{PersonalDetectRightFileName}; $CommonLib->printLog("PersonalDetectRightFileName is: $ENV{PersonalDetectRightFileName}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDeepParse}) { $deepSearch=$ENV{AMFDeepParse}; $CommonLib->printLog("AMFDeepParse is: $deepSearch"); } else { $CommonLib->printLog("AMFDeepParse is not setted the default value is 3"); } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable=true"); } $CommonLib->printLog("Finish loading parameter"); $CommonLib->printLog("---------------------------------------------------------------------------"); if ($DetectRightnetdownload eq "true") { $CommonLib->printLog("Start process downloading DetectRightAMF.xml from $downloadDetectRighturl"); $CommonLib->printLog ("Test the URL"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($downloadDetectRighturl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $downloadDetectRighturl."); ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL is correct"); $CommonLib->printLog("The size of document wurf file: $document_length bytes"); } if ($content_type eq 'application/zip') { $CommonLib->printLog("The file is a zip file."); $CommonLib->printLog ("Start downloading"); my @dummypairs = split(/\//, $downloadDetectRighturl); my ($ext_zip) = $downloadDetectRighturl =~ /\.(\w+)$/; my $filezip=$dummypairs[-1]; my $tmp_dir=$ENV{AMFMobileHome}; $filezip="$tmp_dir/$filezip"; my $status = getstore ($downloadDetectRighturl,$filezip); my $output="$tmp_dir/tmp_DetectRightAMF.xml"; unzip $filezip => $output or die "unzip failed: $UnzipError\n"; # # call parseDetectRightFile # callparseDetectRightFile($output); } else { $CommonLib->printLog("The file is a xml file."); my $content = get ($downloadDetectRighturl); $content =~ s/\n//g; $content =~ s/>/>\n/g; my @rows = split(/\n/, $content); my $row; my $count=0; my $numberRow=scalar(@rows); my $progress=0; foreach $row (@rows){ $r_id=parseDetectRightFile($row,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } } $CommonLib->printLog("Finish downloading DetectRight from $downloadDetectRighturl"); } else { if (-e "$fileDetectRight") { $CommonLib->printLog("Start loading DetectRightAMF.xml"); if (open (IN,"$fileDetectRight")) { my $filesize= -s $fileDetectRight; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); my $numberRow=scalar(@arrayFile); my $progress=0; foreach my $line (@arrayFile) { $r_id=parseDetectRightFile($line,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } } else { $CommonLib->printLog("Error open file:$fileDetectRight"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $fileDetectRight not found"); ModPerl::Util::exit(); } } close IN; my $arrLen = scalar %Array_fb; ($arrLen,$dummy)= split(/\//, $arrLen); if ($arrLen == 0) { $CommonLib->printLog("Error the file probably is not a DetectRight file, control the url or path"); $CommonLib->printLog("Control also if the file is compress file, and DownloadZipFile parameter is seted false"); ModPerl::Util::exit(); } $CommonLib->printLog("DetectRight version: $DetectRightVersion"); if ($cacheSystem->restore('DetectRight-conf', 'amfver') ne $VERSION|| $cacheSystem->restore('DetectRight-conf', 'ResizeImageDirectory') ne $resizeimagedirectory|| $cacheSystem->restore('DetectRight-conf', 'DownloadDetectRightURL') ne $downloadDetectRighturl|| $cacheSystem->restore('DetectRight-conf', 'FullBrowserUrl') ne $fullbrowserurl|| $cacheSystem->restore('DetectRight-conf', 'RedirectTranscoderUrl') ne $redirecttranscoderurl|| $cacheSystem->restore('DetectRight-conf', 'ver') ne $DetectRightVersion || $cacheSystem->restore('DetectRight-conf', 'caplist') ne $capabilitylist|| $cacheSystem->restore('DetectRight-conf', 'listall') ne $listall) { $CommonLib->printLog("********************************************************************************************************"); $CommonLib->printLog("* This is a new version of DetectRight or you change some parameter value or it's a new version of AMF, now the old cache must be deleted *"); $CommonLib->printLog("********************************************************************************************************"); $cacheSystem->store('DetectRight-conf', 'ver', $DetectRightVersion); $cacheSystem->store('DetectRight-conf', 'amfver', $VERSION); $cacheSystem->store('DetectRight-conf', 'caplist', $capabilitylist); $cacheSystem->store('DetectRight-conf', 'listall', $listall); $cacheSystem->store('DetectRight-conf', 'RedirectTranscoderUrl', $redirecttranscoderurl); $cacheSystem->store('DetectRight-conf', 'FullBrowserUrl', $fullbrowserurl); $cacheSystem->store('DetectRight-conf', 'DownloadDetectRightURL', $downloadDetectRighturl); $cacheSystem->store('DetectRight-conf', 'ResizeImageDirectory', $resizeimagedirectory); $cacheSystem->delete_namespace( 'DetectRight-id' ); $cacheSystem->delete_namespace( 'DetectRight-ua' ); } $CommonLib->printLog("This version of DetectRight has $arrLen UserAgent"); $CommonLib->printLog("End loading DetectRightAMF.xml"); if ($personalDetectRighturl ne 'unknown') { $CommonLib->printLog("---------------------------------------------------------------------------"); if (-e "$personalDetectRighturl") { $CommonLib->printLog("Start loading $ENV{PersonalDetectRightFileName}"); if (open (IN,"$personalDetectRighturl")) { my $filesize= -s $personalDetectRighturl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { #print "$line\n"; $r_id=parseDetectRightFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$personalDetectRighturl"); ModPerl::Util::exit(); } $CommonLib->printLog("END loading $ENV{PersonalDetectRightFileName}"); close IN; } else { $CommonLib->printLog("File $personalDetectRighturl not found"); ModPerl::Util::exit(); } } } sub callparseDetectRightFile { my ($output) = @_; my $r_id; if (open (IN,"$output")) { my $filesize= -s $output; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parseDetectRightFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$output"); ModPerl::Util::exit(); } } sub parseDetectRightFile { my ($record,$val) = @_; my $null=""; my $null2=""; my $null3=""; my $uagent=""; my $fb=""; my $value=""; my $id; my $name=""; my $version=""; if ($val) { $id="$val"; } if ($record =~ /\ -1 ) { $uagent=lc(substr($record,index($record,'user_agent') + 12,index($record,'"',index($record,'user_agent')+ 13)- index($record,'user_agent') - 12)); if (index($uagent,'blackberry') >-1 ) { $uagent=substr($uagent,index($uagent,'blackberry')); } ($uagent,$version)=$CommonLib->androidDetection($uagent); } if (index($record,'id') > -1 ) { $id=substr($record,index($record,'id') + 4,index($record,'"',index($record,'id')+ 5)- index($record,'id') - 4); } if (index($record,'fall_back') > -1 ) { $fb=substr($record,index($record,'fall_back') + 11,index($record,'"',index($record,'fall_back')+ 12)- index($record,'fall_back') - 11); } if (($fb) && ($id)) { $Array_fb{"$id"}=$fb; } if (($uagent) && ($id)) { my %ParseUA=$CommonLib->GetMultipleUa($uagent,$deepSearch); my $pair; my $arrUaLen = scalar %ParseUA; my $contaUA=0; my $Array_fullua_id=$uagent; foreach $pair (reverse sort { $a <=> $b } keys %ParseUA) { my $dummy=$ParseUA{$pair}; if ($Array_id{$dummy}) {} else { $Array_id{$dummy}=$id; } $contaUA=$contaUA-1; } } } if ($record =~ /\/o) { $DetectRightVersion=substr($record,index($record,'') + 5,index($record,'') - 9); } return $id; } sub FallBack { my ($idToFind) = @_; my $dummy_id; my $dummy; my $dummy2; my $LOOP; my %ArrayCapFoundToPass; my $capability; foreach $capability (sort keys %Capability) { $dummy_id=$idToFind; $LOOP=0; while ($LOOP<2) { $dummy="$dummy_id|$capability"; if ($Array_DDRcapability{$dummy}) { $LOOP=2; $dummy2="$dummy_id|$capability"; $ArrayCapFoundToPass{$capability}=$Array_DDRcapability{$dummy2}; } else { if ($Array_fb{$dummy_id}) { $dummy_id=$Array_fb{$dummy_id}; } else { $dummy_id="root"; } if ($dummy_id eq "root" || $dummy_id eq "generic") { $LOOP++; } } } } return %ArrayCapFoundToPass; } sub IdentifyUAMethod { my ($UserAgent) = @_; my $ind=0; my %ArrayPM; my $pair; my $pair2; my $id_find=""; my $dummy; my $uagent_toMatch; my $near_toFind=100; my $near_toMatch; my %ArrayUAType=$CommonLib->GetMultipleUa(lc($UserAgent),$deepSearch); foreach $pair (reverse sort { $a <=> $b } keys %ArrayUAType) { my $dummy=$ArrayUAType{$pair}; if ($Array_id{$dummy}) { if (!$id_find) { $id_find=$Array_id{$dummy}; } } } return $id_find; } sub IdentifyPCUAMethod { my ($UserAgent) = @_; my $ind=0; my $id_find="none"; my $pair; my $length=0; foreach $pair (sort keys %PCArray) { if ($UserAgent =~ m/$pair/ && $id_find eq 'none') { $id_find=$PCArray{$pair}; } } if ($id_find) {}else{$id_find="";}; return $id_find; } sub handler { my $f = shift; my $capability2; my $variabile=""; my $user_agent=lc($f->headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; $ArrayCapFound{'device_claims_web_support'}='none'; $ArrayCapFound{'is_wireless_device'}='none'; my %ArrayQuery; my $var; my $mobile=0; my $version=""; my $realPCbrowser='none'; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; $id=$CommonLib->readCookie($cookie); my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=lc($user_agent); if ($user_agent =~ m/blackberry/i) { $user_agent=substr($user_agent,index($user_agent,'blackberry')); $mobile=1; } if ($user_agent =~ m/up.link/i ) { $user_agent=substr($user_agent,0,index($user_agent,'up.link') - 1); $mobile=1; } ($user_agent,$version)=$CommonLib->androidDetection($user_agent); if ($cacheSystem->restore( 'DetectRight-ua', $user_agent )) { # # cookie is not empty so I try to read in memory cache on my httpd cache # $id=$cacheSystem->restore( 'DetectRight-ua', $user_agent ); if ($cacheSystem->restore( 'DetectRight-id', $id )) { # # I'm here only for old device # my @pairs = split(/&/, $cacheSystem->restore( 'DetectRight-id', $id )); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); if ($dummy) { $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes($string_tofound => $ArrayCapFound{$string_tofound}); } } $id=$ArrayCapFound{id}; if ($ArrayCapFound{realpcbrowser} ne 'none') { $ArrayCapFound{'is_wireless_device'}='false'; $ArrayCapFound{'device_claims_web_support'}='true'; } } } else { if ($id eq "") { if ($user_agent) { my $pair; my $lcuser_agent=lc($user_agent); if ($mobile==0) { foreach $pair (%MobileArray) { if ($user_agent =~ m/$pair/i) { $mobile=1; } } if ($mobile==0) { $user_agent=$CommonLib->botDetection($user_agent); $realPCbrowser=IdentifyPCUAMethod($user_agent); if ($realPCbrowser ne "none") { $id="generic_web_browser"; $mobile=-1; } } } if (!$id) {$id="";}; if ($id eq "") { $id=IdentifyUAMethod($user_agent); } if ($id eq "") { $id='generic_web_browser'; } else { #this check the correct version of Android if ($version) { if ($version ne 'nc') { my $lengthId=length($version); my $count=0; while($count<$lengthId) { my $idToCheck=$id."_sub".substr($version,0,length($version)-$count); if ($Array_fb{$idToCheck}) { $id=$idToCheck; $count=$lengthId; } $count++; } } } } $cacheSystem->store( 'DetectRight-ua', $user_agent, $id); } } if ($id ne "") { # # device detected # if ($realPCbrowser ne 'none') { $id=$realPCbrowser; } if ($cacheSystem->restore( 'DetectRight-id', $id )) { # # I'm here only for old device looking in cache # my @pairs = split(/&/, $cacheSystem->restore( 'DetectRight-id', $id )); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes("$string_tofound" => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } else { if ($mobile == -1) { %ArrayCapFound=FallBack('generic_web_browser'); } else { %ArrayCapFound=FallBack($id); } foreach $capability2 (sort keys %ArrayCapFound) { $variabile2="$variabile2$capability2=$ArrayCapFound{$capability2}&"; my $upper=uc($capability2); $f->subprocess_env("AMF_$upper" => $ArrayCapFound{$capability2}); $f->pnotes("$capability2" => $ArrayCapFound{$capability2}); } if ($realPCbrowser ne 'none') { $id=$realPCbrowser; $ArrayCapFound{'is_wireless_device'}='false'; $ArrayCapFound{'device_claims_web_support'}='true'; } $variabile2="id=$id&$variabile2&realpcbrowser=$realPCbrowser"; $f->subprocess_env("AMF_ID" => $id); $f->pnotes('id' => $id); $cacheSystem->store( 'DetectRight-id', $id, $variabile2 ); $cacheSystem->store( 'DetectRight-ua', $user_agent, $id); } if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amfID=$id; path=/;"); } } } my $amf_device_ismobile = 'true'; if ($ArrayCapFound{'device_claims_web_support'} eq 'true' && $ArrayCapFound{'is_wireless_device'} eq 'false') { $amf_device_ismobile = 'false'; } if ($ArrayCapFound{'is_tablet'}) { $f->subprocess_env("AMF_DEVICE_IS_TABLET" => lc($ArrayCapFound{'is_tablet'})); } if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } $f->pnotes("amf_device_ismobile" => $amf_device_ismobile); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => $amf_device_ismobile); $f->subprocess_env("AMF_VER" => $VERSION); $f->subprocess_env("AMF_DETECT_RIGHT_VER" => $DetectRightVersion); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMFDetectRightFilter - The module detects the mobile device and passes the DetectRight capabilities on to the other web application as environment variables =head1 DESCRIPTION Module for device detection, the cache is based on file system =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFDetectRightFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFDetectRightFilterMemcached.pm000644 000765 000024 00000061474 13064524645 030253 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFDetectRightFilterMemcached.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 15/10/11 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFDetectRightFilterMemcached; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple qw($ua get); use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use Cache::Memcached; use Digest::MD5 qw(md5_hex); # # Define the global environment # use vars qw($VERSION); my $CommonLib = new Apache2::AMFCommonLib (); $VERSION= "4.20";;; my %Capability; my %Array_fb; my %Array_id; my %Array_fullua_id; my %Array_DDRcapability; my %MobileArray=$CommonLib->getMobileArray; my %PCArray=$CommonLib->getPCArray; my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoder="true"; my $redirecttranscoderurl="none"; my $resizeimagedirectory="none"; my $DetectRightnetdownload="false"; my $downloadDetectRighturl="false"; my $listall="false"; my $cookiecachesystem="false"; my $DetectRightVersion="unknown"; my $personalDetectRighturl='unknown'; my $serverMemCache; my $restmode='false'; my $deepSearch=2; my $checkVersion='false'; my $mobilenable="false"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFDetectRightFilterMemcached module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($checkVersion eq 'true') { $CommonLib->printLog("Check on apchemobilefilter.org if the installed AMF is the last version"); $CommonLib->printLog("Try to download http://www.apachemobilefilter.org/param/amf.config"); my $url="http://www.apachemobilefilter.org/param/amf.config"; my $content = get ($url); $content =~ s/\n//g; my $check_version=0; if ($content) { $check_version=$content; } if ($check_version > $VERSION && $check_version ne 0) { $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----- There is a new version of AMF V$check_version online ----"); $CommonLib->printLog("---------------------------------------------------------------------------"); } else { $CommonLib->printLog("AMF installed is the last version"); } } else { $CommonLib->printLog("AMFCheckVersion is false, AMF don't check the last version."); } if ($ENV{ResizeImageDirectory}) { $Capability{'max_image_width'}="max_image_width"; $Capability{'max_image_height'}="max_image_width"; $resizeimagedirectory=$ENV{ResizeImageDirectory}; } if (($ENV{FullBrowserUrl}) || ($ENV{MobileVersionUrl})) { $Capability{'device_claims_web_support'}="device_claims_web_support"; $Capability{'is_wireless_device'}="is_wireless_device"; $fullbrowserurl=$ENV{FullBrowserUrl} } if ($ENV{RedirectTranscoderUrl}) { $Capability{'is_transcoder'}="is_transcoder"; $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; } # # Check if AMFMobileHome and CacheDirectoryStore is setting in apache httpd.conf file for example: # PerlSetEnv AMFMobileHome /MobileFilter # my @Server; if ($ENV{ServerMemCached}) { $serverMemCache=$ENV{ServerMemCached}; @Server = split(/,/, $ENV{ServerMemCached}); $CommonLib->printLog("ServerMemCached is: $serverMemCache"); } else { $CommonLib->printLog("ServerMemCached is not setted. Please set the variable ServerMemCached into httpd.conf, example \"PerlSetEnv ServerMemCached 10.10.10.10.:11211\""); ModPerl::Util::exit(); } my $memd = new Cache::Memcached { 'debug' => 0, 'compress_threshold' => 10_000, 'enable_compress' => 1, }; $memd->set_servers(\@Server); if ($ENV{AMFMobileHome}) { &loadConfigFile("$ENV{AMFMobileHome}/DetectRightAMF.xml"); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my ($fileDetectRight) = @_; my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("Start read configuration from httpd.conf"); if ($ENV{DetectRightNetDownload}) { if ($ENV{DetectRightNetDownload} eq 'true' || $ENV{DetectRightNetDownload} eq 'false') { $DetectRightnetdownload=$ENV{DetectRightNetDownload}; $CommonLib->printLog("DetectRightNetDownload is: $DetectRightnetdownload"); } else { $CommonLib->printLog("Error DetectRightNetDownload parmeter must set to true or false"); ModPerl::Util::exit(); } } if ($ENV{DownloadDetectRightURL}) { $downloadDetectRighturl=$ENV{DownloadDetectRightURL}; $CommonLib->printLog("DownloadDetectRightURL is: $downloadDetectRighturl"); } if ($ENV{CapabilityList}) { my @dummycapability = split(/,/, $ENV{CapabilityList}); foreach $dummy (@dummycapability) { if ($dummy eq "all") { $listall="true"; } $Capability{$dummy}=$dummy; $CommonLib->printLog("CapabilityList is: $dummy"); } } else { $listall="true"; $CommonLib->printLog('CapabilityList not setted so the default value is "all"'); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode (the CookieCacheSystem is deprecated) is not setted the default value is $cookiecachesystem"); } if ($ENV{PersonalDetectRightFileName}) { $personalDetectRighturl=$ENV{AMFMobileHome}."/".$ENV{PersonalDetectRightFileName}; $CommonLib->printLog("PersonalDetectRightFileName is: $ENV{PersonalDetectRightFileName}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDeepParse}) { $deepSearch=$ENV{AMFDeepParse}; $CommonLib->printLog("AMFDeepParse is: $deepSearch"); } else { $CommonLib->printLog("AMFDeepParse is not setted the default value is 3"); } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable=true"); } $CommonLib->printLog("Finish loading parameter"); $CommonLib->printLog("---------------------------------------------------------------------------"); if ($DetectRightnetdownload eq "true") { $CommonLib->printLog("Start process downloading DetectRightAMF.xml from $downloadDetectRighturl"); $CommonLib->printLog ("Test the URL"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($downloadDetectRighturl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $downloadDetectRighturl."); ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL is correct"); $CommonLib->printLog("The size of document wurf file: $document_length bytes"); } if ($content_type eq 'application/zip') { $CommonLib->printLog("The file is a zip file."); $CommonLib->printLog ("Start downloading"); my @dummypairs = split(/\//, $downloadDetectRighturl); my ($ext_zip) = $downloadDetectRighturl =~ /\.(\w+)$/; my $filezip=$dummypairs[-1]; my $tmp_dir=$ENV{AMFMobileHome}; $filezip="$tmp_dir/$filezip"; my $status = getstore ($downloadDetectRighturl,$filezip); my $output="$tmp_dir/tmp_DetectRightAMF.xml"; unzip $filezip => $output or die "unzip failed: $UnzipError\n"; # # call parseDetectRightFile # callparseDetectRightFile($output); } else { $CommonLib->printLog("The file is a xml file."); my $content = get ($downloadDetectRighturl); $content =~ s/\n//g; $content =~ s/>/>\n/g; my @rows = split(/\n/, $content); my $row; my $count=0; foreach $row (@rows){ $r_id=parseDetectRightFile($row,$r_id); } } $CommonLib->printLog("Finish downloading DetectRight from $downloadDetectRighturl"); } else { if (-e "$fileDetectRight") { $CommonLib->printLog("Start loading DetectRightAMF.xml"); if (open (IN,"$fileDetectRight")) { my $filesize= -s $fileDetectRight; read (IN,my $string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @rows = split(/\n/, $string_file); my $numberRow=scalar(@rows); my $progress=0; foreach my $row (@rows){ $r_id=parseDetectRightFile($row,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } close IN; } else { $CommonLib->printLog("Error open file:$fileDetectRight"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $fileDetectRight not found"); ModPerl::Util::exit(); } } close IN; my $arrLen = scalar %Array_fb; ($arrLen,$dummy)= split(/\//, $arrLen); if ($arrLen == 0) { $CommonLib->printLog("Error the file probably is not a DetectRight file, control the url or path"); $CommonLib->printLog("Control also if the file is compress file, and DownloadZipFile parameter is seted false"); #ModPerl::Util::exit(); } $CommonLib->printLog("DetectRight version: $DetectRightVersion"); $CommonLib->printLog("This version of DetectRight has $arrLen UserAgent"); $CommonLib->printLog("End loading DetectRightAMF.xml"); if ($personalDetectRighturl ne 'unknown') { $CommonLib->printLog("---------------------------------------------------------------------------"); if (-e "$personalDetectRighturl") { $CommonLib->printLog("Start loading $ENV{PersonalDetectRightFileName}"); if (open (IN,"$personalDetectRighturl")) { my $filesize= -s $personalDetectRighturl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { #print "$line\n"; $r_id=parseDetectRightFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$personalDetectRighturl"); ModPerl::Util::exit(); } $CommonLib->printLog("END loading $ENV{PersonalDetectRightFileName}"); close IN; } else { $CommonLib->printLog("File $personalDetectRighturl not found"); ModPerl::Util::exit(); } } } sub FallBack { my ($idToFind) = @_; my $dummy_id; my $dummy; my $dummy2; my $LOOP; my %ArrayCapFoundToPass; my $capability; foreach $capability (sort keys %Capability) { $dummy_id=$idToFind; $LOOP=0; while ($LOOP<2) { $dummy="$dummy_id|$capability"; if ($Array_DDRcapability{$dummy}) { $LOOP=2; $dummy2="$dummy_id|$capability"; $ArrayCapFoundToPass{$capability}=$Array_DDRcapability{$dummy2}; } else { if ($Array_fb{$dummy_id}) { $dummy_id=$Array_fb{$dummy_id}; } else { $dummy_id="root"; } if ($dummy_id eq "root" || $dummy_id eq "generic") { $LOOP++; } } } } return %ArrayCapFoundToPass; } sub IdentifyUAMethod { my ($UserAgent) = @_; my $ind=0; my %ArrayPM; my $pair; my $pair2; my $id_find=""; my $dummy; my $uagent_toMatch; my $near_toFind=100; my $near_toMatch; my %ArrayUAType=$CommonLib->GetMultipleUa(lc($UserAgent),$deepSearch); foreach $pair (reverse sort { $a <=> $b } keys %ArrayUAType) { my $dummy=$ArrayUAType{$pair}; if ($Array_id{$dummy}) { if (!$id_find) { $id_find=$Array_id{$dummy}; } } } return $id_find; } sub IdentifyPCUAMethod { my ($UserAgent) = @_; my $ind=0; my $id_find="none"; my $pair; my $length=0; foreach $pair (sort keys %PCArray) { if ($UserAgent =~ m/$pair/ && $id_find eq 'none') { $id_find=$PCArray{$pair}; } } if (!$id_find) {$id_find="";} return $id_find; } sub callparseDetectRightFile { my ($output) = @_; my $r_id; if (open (IN,"$output")) { my $filesize= -s $output; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parseDetectRightFile($line,$r_id); } close IN; } else { $CommonLib->printLog("Error open file:$output"); ModPerl::Util::exit(); } } sub parseDetectRightFile { my ($record,$val) = @_; my $null=""; my $null2=""; my $null3=""; my $uagent=""; my $fb=""; my $value=""; my $id; my $name=""; my $version=""; my $lan_sub="xx-xx"; if ($val) { $id="$val"; } if ($record =~ /\ -1 ) { $uagent=lc(substr($record,index($record,'user_agent') + 12,index($record,'"',index($record,'user_agent')+ 13)- index($record,'user_agent') - 12)); if (index($uagent,'blackberry') > -1 ) { $uagent=substr($uagent,index($uagent,'blackberry')); } ($uagent,$version)=$CommonLib->androidDetection($uagent); } if (index($record,'id') > 0 ) { $id=substr($record,index($record,'id') + 4,index($record,'"',index($record,'id')+ 5)- index($record,'id') - 4); } if (index($record,'fall_back') > 0 ) { $fb=substr($record,index($record,'fall_back') + 11,index($record,'"',index($record,'fall_back')+ 12)- index($record,'fall_back') - 11); } if (($fb) && ($id)) { $Array_fb{"$id"}=$fb; } if (($uagent) && ($id)) { my %ParseUA=$CommonLib->GetMultipleUa($uagent,$deepSearch); my $pair; my $arrUaLen = scalar %ParseUA; my $contaUA=0; my $Array_fullua_id=$uagent; foreach $pair (reverse sort { $a <=> $b } keys %ParseUA) { my $dummy=$ParseUA{$pair}; if ($Array_id{$dummy}) {} else { $Array_id{$dummy}=$id; } $contaUA=$contaUA-1; } } } if ($record =~ /\/o) { $DetectRightVersion=substr($record,index($record,'') + 5,index($record,"") - 9); } return $id; } sub handler { my $f = shift; my $capability2; my $variabile=""; my $user_agent=lc($f->headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; $ArrayCapFound{'device_claims_web_support'}='none'; $ArrayCapFound{'is_wireless_device'}='none'; my %ArrayQuery; my $var; my $mobile=0; my $version=""; my $realPCbrowser='none'; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; $id=$CommonLib->readCookie($cookie); my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=lc($user_agent); if ($user_agent =~ m/blackberry/i) { $user_agent=substr($user_agent,index($user_agent,'blackberry')); $mobile=1; } if ($user_agent =~ m/up.link/i ) { $user_agent=substr($user_agent,0,index($user_agent,'up.link') - 1); $mobile=1; } ($user_agent,$version)=$CommonLib->androidDetection($user_agent); if ($id eq ""){ if ($user_agent) { if ($mobile==0) { foreach my $pair (%MobileArray) { if ($user_agent =~ m/$pair/i) { $mobile=1; } } if ($mobile==0) { $user_agent=$CommonLib->botDetection($user_agent); $realPCbrowser=IdentifyPCUAMethod($user_agent); if ($realPCbrowser ne "none") { $id="generic_web_browser"; $mobile=-1; } } } if (!$id) {$id="";}; if ($id eq "") { $id=IdentifyUAMethod($user_agent); } if ($id eq "") { $id='generic_web_browser'; } else { #this check the correct version of Android if ($version) { if ($version ne 'nc') { my $lengthId=length($version); my $count=0; while($count<$lengthId) { my $idToCheck=$id."_sub".substr($version,0,length($version)-$count); if ($Array_fb{$idToCheck}) { $id=$idToCheck; $count=$lengthId; } $count++; } } } } } } if ($id ne "") { # # device detected # if ($realPCbrowser ne 'none') { $id=$realPCbrowser; } my $var=$memd->get("DR_$id"); if ($var) { my @pairs = split(/&/, $var); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes("$string_tofound" => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } else { if ($mobile == -1) { %ArrayCapFound=FallBack('generic_web_browser'); } else { %ArrayCapFound=FallBack($id); } if ($realPCbrowser ne 'none') { $id=$realPCbrowser; $ArrayCapFound{'is_wireless_device'}='false'; $ArrayCapFound{'device_claims_web_support'}='true'; } foreach $capability2 (sort keys %ArrayCapFound) { $variabile2="$variabile2$capability2=$ArrayCapFound{$capability2}&"; my $upper=uc($capability2); $f->subprocess_env("AMF_$upper" => $ArrayCapFound{$capability2}); $f->pnotes("$capability2" => $ArrayCapFound{$capability2}); } $variabile2="id=$id&$variabile2"; $f->subprocess_env("AMF_ID" => $id); $f->pnotes('id' => $id); $memd->set("DR_$id",$variabile2); } if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amfID=$id; path=/;"); } } my $amf_device_ismobile = 'true'; if ($ArrayCapFound{'device_claims_web_support'} eq 'true' && $ArrayCapFound{'is_wireless_device'} eq 'false') { $amf_device_ismobile = 'false'; } if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } if ($ArrayCapFound{'is_tablet'}) { $f->subprocess_env("AMF_DEVICE_IS_TABLET" => lc($ArrayCapFound{'is_tablet'})); } $f->pnotes("amf_device_ismobile" => $amf_device_ismobile); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => $amf_device_ismobile); $f->subprocess_env("AMF_VER" => $VERSION); $f->subprocess_env("AMF_DETECT_RIGHT_VER" => $DetectRightVersion); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMFDetectRightFilterMemcached - The module detects the mobile device and passes the DetectRight capabilities on to the other web application as environment variables =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFDetectRightFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFDeviceMonitor.pm000644 000765 000024 00000016472 13064524645 025655 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFDeviceMonitor.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFDeviceMonitor; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::Filter (); use Apache2::RequestRec (); use APR::Table (); use Cache::FileBackend; use Apache2::Const -compile => qw(OK); use constant BUFF_LEN => 1024; use vars qw($VERSION); $VERSION= "4.20";;; # # Define the global environment # my $CommonLib = new Apache2::AMFCommonLib (); my $cachedirectorystore="notdefined"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFDeviceMonitor Version $VERSION"); if ($ENV{CacheDirectoryStore}) { $cachedirectorystore=$ENV{CacheDirectoryStore}; $CommonLib->printLog("CacheDirectoryStore is: $cachedirectorystore"); } else { $CommonLib->printLog("CacheDirectoryStore not exist. Please set the variable CacheDirectoryStore into httpd.conf, (the directory must be writeable)"); ModPerl::Util::exit(); } my $cacheSystem = new Cache::FileBackend( $cachedirectorystore, 3, 000 ); sub handler { my $f = shift; my $query_string=$f->args; my $id; my $ua; my $capab; my %ArrayQuery; my %ArrayForSort; $ArrayQuery{page}=0; if ($query_string) { my @vars = split(/&/, $query_string); foreach my $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } my $page_html="Apache Mobile Filter - Device Monitor System V$VERSION"; $page_html=$page_html.''; $page_html=$page_html."Apache Mobile Filter
Device Monitor System V$VERSION
home | detected devices | devices not found
"; my $dummy="null"; my $count=0; my $page_number=30; my $min=$ArrayQuery{page}; my $max=$ArrayQuery{page} + $page_number; my $back=$ArrayQuery{page}-$page_number; my $forward=$ArrayQuery{page}+$page_number; if ($ArrayQuery{form}) { if ($ArrayQuery{form} eq "3") { my @pairs = split(/&/, $cacheSystem->restore( 'wurfl-id', $ArrayQuery{deviceid})); my $param_tofound; my $string_tofound; $page_html=$page_html.""; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $page_html=$page_html.""; } $page_html=$page_html."
ParameterValue
$string_tofound$dummy
"; } else { if ($ArrayQuery{form} eq "1") { $page_html=$page_html.'
Search device id
'; } $page_html=$page_html.""; $page_html=$page_html.""; foreach $ua ( sort $cacheSystem->get_keys( 'wurfl-ua' ) ) { $id =$cacheSystem->restore( 'wurfl-ua', $ua ); if ($ArrayQuery{form} eq "2" && $id eq 'device_not_found'){ $count++; if ($count > $min - 1 && $count < $max + 1) { $page_html=$page_html.""; } } if ($ArrayQuery{form} eq "1" && $id ne 'device_not_found') { if ($ArrayQuery{search}) { if ($id =~ m/$ArrayQuery{search}/i) { $count++; if ($count > $min && $count < $max + 1) { $page_html=$page_html.""; } } } else { $count++; if ($count > $min - 1 && $count < $max + 1) { $page_html=$page_html.""; } } } } } $page_html=$page_html."
n.device idUser Agent
$count$id$ua
$count$id$ua
$count$id$ua
"; if ( $min > 0) { $page_html=$page_html.""; } if ($forward < $count) { $page_html=$page_html.""; } $page_html=$page_html."
backforward>
"; } else { $page_html=$page_html.'



Apache Mobile Filter

Open Source Project: http://www.idelfuschini.it/en/apache-mobile-filter-v2x.html
'; } my $len_bytes=length $page_html; $f->headers_out->set("Content-Length"=>$len_bytes); $f->headers_out->set("Last-Modified" => time()); $f->content_type('text/html'); $f->print($page_html); return Apache2::Const::OK; } 1; =head1 NAME Apache2::AMFDeviceMonitor - This module is an admin tool to control the devices access that Apache Mobile Filter has detected. =head1 DESCRIPTION This module is an admin tool to control the devices access that Apache Mobile Filter has detected. =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFDeviceMonitor =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFImageRendering.pm000644 000765 000024 00000024455 13064524645 025766 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFImageRendering.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFImageRendering; use strict; use warnings; use POSIX qw(ceil); use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple; use Image::Resize; use Image::Scale; use File::Copy; use Imager; use Apache2::Const -compile => qw(OK REDIRECT DECLINED HTTP_MOVED_TEMPORARILY); use constant BUFF_LEN => 1024; # # Define the global environment # use vars qw($VERSION); $VERSION= "4.20";;; my $CommonLib = new Apache2::AMFCommonLib (); my %Capability; my %Array_fb; my %Array_id; my %Array_fullua_id; my %Array_DDRcapability; my %XHTMLUrl; my %WMLUrl; my %CHTMLUrl; my %ImageType; my %cacheArray; my %cacheArray_toview; my $intelliswitch="false"; my $mobileversionurl; my $fullbrowserurl; my $querystring="false"; my $showdefaultvariable="false"; my $wurflnetdownload="false"; my $downloadwurflurl="false"; my $resizeimagedirectory=""; my $downloadzipfile="true"; my $virtualdirectoryimages="false"; my $virtualdirectory=""; my $repasshanlder=0; my $globalpassvariable=""; my $log4wurfl=""; my $loadwebpatch="false"; my $dirwebpatch=""; my $patchwurflnetdownload="false"; my $patchwurflurl=""; my $redirecttranscoder="true"; my $redirecttranscoderurl=""; my $detectaccuracy="false"; my $listall="false"; my $resizeimagesmall="false"; my $par_height='height'; my $par_width='width'; my $par_perc='dim'; $ImageType{'image/png'}="png"; $ImageType{'image/gif'}="gif"; $ImageType{'image/jpg'}="jpg"; $ImageType{'image/jpeg'}="jpeg"; # # Check if MOBILE_HOME is setting in apache httpd.conf file for example: # PerlSetEnv MOBILE_HOME /MobileFilter # $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFImageRendering Version $VERSION"); if ($ENV{AMFMobileHome}) { &loadConfigFile(); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("ResizeImageDirectory: Start read configuration from httpd.conf"); if ($ENV{ResizeImageDirectory}) { $resizeimagedirectory=$ENV{ResizeImageDirectory}; $CommonLib->printLog("ResizeImageDirectory is: $resizeimagedirectory"); } else { $CommonLib->printLog("ERROR: ResizeImageDirectory parameter must be setted"); ModPerl::Util::exit(); } if ($ENV{ResizeSmallImage}) { $resizeimagesmall=$ENV{ResizeSmallImage}; $CommonLib->printLog("ResizeSmallImage is: $resizeimagesmall. The image smallest of device screensize is also resized (low quality)"); } if ($ENV{ImageParamWidth}) { $par_width=$ENV{ImageParamWidth}; $CommonLib->printLog("ImageParamWidth is: $par_width. To force the width of image the url must be ?$par_width="); } if ($ENV{ImageParamHeight}) { $par_height=$ENV{ImageParamHeight}; $CommonLib->printLog("ImageParamHeight is: $par_height. To force the height of image the url must be ?$par_width="); } if ($ENV{ImageParamPerc}) { $par_perc=$ENV{ImageParamPerc}; $CommonLib->printLog("ImageParamPerc is: $par_perc. To force the percentage of image the url must be ?$par_perc="); } $CommonLib->printLog("Finish loading parameter"); } sub handler { my $f = shift; my $capability2; my $s = $f->r->server; my $query_string=$f->r->args; my $uri = $f->r->uri(); $uri =~ s/\//_/g; my $content_type=$f->r->content_type(); my @fileArray = split(/\//, $uri); my $file=$fileArray[-1]; my $docroot = $f->r->document_root(); $docroot =~ s/\//_/g; my $servername=$f->r->get_server_name(); my $id=""; my $method=""; my $location; my $width_toSearch; my $type_redirect="internal"; my $return_value=Apache2::Const::DECLINED; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; my %ArrayQuery; my $var; my $cookie = $f->r->headers_in->{Cookie} || ''; my $width=1000; my $height=1000; my $image2=""; my $device_claims_web_support='null'; my $is_wireless_device='null'; my $isMobile='true'; $content_type=lc($content_type); if ($f->r->pnotes('max_image_width')) { $width=$f->r->pnotes('max_image_width') } if ($f->r->pnotes('max_image_height')) { $height=$f->r->pnotes('max_image_height'); } if ($f->r->pnotes('amf_device_ismobile')) { $isMobile=$f->r->pnotes('amf_device_ismobile'); } $repasshanlder=$repasshanlder + 1; $return_value=Apache2::Const::DECLINED; # # Reading value of query string # if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } if ($ImageType{$content_type}) { my $imageToConvert; my $imagefile=""; if ($ArrayQuery{par_height}) { if ( $ArrayQuery{$par_height} =~ /^-?\d/) { $height=$ArrayQuery{par_height}; } } $imageToConvert=$f->r->filename(); if ($isMobile eq 'false') { my $image = Image::Resize->new("$imageToConvert"); $width=$image->width(); } if ($ArrayQuery{$par_width}) { if ( $ArrayQuery{$par_width} =~ /^-?\d/) { $width=$ArrayQuery{$par_width}; } } if ($ArrayQuery{$par_perc}) { if ( $ArrayQuery{$par_perc} =~ /^-?\d/) { $width=$ArrayQuery{$par_perc} * $width / 100; } } $imagefile="$resizeimagedirectory/$docroot-$uri.$width"; # # control if image exist # if ( -e "$imageToConvert") { my $filesize; if ( -e "$imagefile") { } else { my $image = Image::Resize->new("$imageToConvert"); if ($image->width() < $width && $resizeimagesmall eq 'false') { copy($imageToConvert, $imagefile); } else { if ($content_type eq "image/gif") { my @in = Imager->read_multi(file => $imageToConvert) or die "Cannot read image file: ", Imager->errstr, "\n"; $in[0]->tags(name => 'i_format') eq 'gif' or die "File $imageToConvert is not a GIF image"; my $src_screen_width = $in[0]->tags(name => 'gif_screen_width'); my $src_screen_height = $in[0]->tags(name => 'gif_screen_height'); my $factor=$width/$src_screen_width; my $out_screen_width = ceil($src_screen_width * $factor); my $out_screen_height = ceil($src_screen_height * $factor); my @out; for my $in (@in) { my $scaled = $in->scale(scalefactor => $factor, qtype=>'mixing'); # roughly preserve the relative position $scaled->settag(name => 'gif_left', value => $factor * $in->tags(name => 'gif_left')); $scaled->settag(name => 'gif_top', value => $factor * $in->tags(name => 'gif_top')); $scaled->settag(name => 'gif_screen_width', value => $out_screen_width); $scaled->settag(name => 'gif_screen_height', value => $out_screen_height); # set some other tags from the source for my $tag (qw/gif_delay gif_user_input gif_loop gif_disposal/) { $scaled->settag(name => $tag, value => $in->tags(name => $tag)); } if ($in->tags(name => 'gif_local_map')) { $scaled->settag(name => 'gif_local_map', value => 1); } push @out, $scaled; } my $dummy=$imagefile.".gif"; Imager->write_multi({ file => $dummy }, @out) or die "Cannot save $imagefile: ", Imager->errstr, "\n"; rename($dummy, $imagefile); } if ($content_type eq "image/png") { my $img = Image::Scale->new("$imageToConvert") ; $img->resize_gd( { width => $width } ); $img->save_png("$imagefile"); } if ($content_type eq "image/jpeg") { my $img = Image::Scale->new("$imageToConvert") ; $img->resize_gd( { width => $width } ); $img->save_jpeg("$imagefile"); } } } unless( $f->ctx ) { $f->r->headers_out->unset('Content-Length'); $f->ctx(1); } $filesize = -s "$imagefile"; $f->r->headers_out->set("Content-Length"=>$filesize); $f->r->content_type($content_type); open (FH,"$imagefile") or die ("couldn't open $imagefile\n"); read (FH,$image2,$filesize) ; close FH; $f->print($image2); $return_value=Apache2::Const::OK; } } } return $return_value; } 1; =head1 NAME Apache2::AMFImageRendering - Used to resize images (jpg, png, gif gifanimated) on the fly to adapt to the screen size of the mobile device =head1 DESCRIPTION This module have the scope to manage with AMF51DegreesFilter, AMFDetectRightFilter and AMFWURFLFilter module the images for mobile devices. For more details: http://wiki.apachemobilefilter.org =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFImageRendering =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFLiteDetectionFilter.pm000644 000765 000024 00000054550 13064524645 027007 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFLiteDetectionFilter.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFLiteDetectionFilter; use strict; use warnings; use MIME::Base64 qw(encode_base64); use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple (); use LWP::UserAgent; use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use Cache::FileBackend; # # Define the global environment # use vars qw($VERSION); $VERSION= "4.20";;; my $CommonLib = new Apache2::AMFCommonLib (); my %MobileArray;#=$CommonLib->getMobileArray; my %MobileTabletArray; my %MobileTouchArray; my %MobileTVArray; my $cookiecachesystem="false"; my $restmode='false'; my $downloadparam='true'; my $configMobileFile; my $forcetablet='true'; my $configTabletFile; my $configTouchFile; my $configTVFile; my $checkVersion='true'; my $mobilenable="false"; my $hostNames = "sourceforge.net"; my @hostName = split(/,/, $hostNames); my $numberOfAvaiableHosts=@hostName; my $correctHost=0; my $correctHostName=$hostName[$correctHost]; my $hostServer="http://".$correctHostName."/projects/mobilefilter/files/AMFRepository/"; my $urlmobile=$hostServer."litemobiledetection.config/download"; my $urlTablet=$hostServer."litetabletdetection.config/download"; my $urlTouch=$hostServer."litetouchdetection.config/download"; my $urlTv=$hostServer."litetvdetection.config/download"; my $urlBot=$hostServer."litebotdetection.config/download"; my $forceBlockDownload="false"; my $ua=LWP::UserAgent->new; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----------------- AMF Lite Detection (not DR required) -------------------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFLiteDetectionFilter module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); $ua->proxy('https','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFMobileHome}) { $configMobileFile="$ENV{AMFMobileHome}/amflitedetection.config"; $configTabletFile="$ENV{AMFMobileHome}/amflitedetection_tablet.config"; $configTouchFile="$ENV{AMFMobileHome}/amflitedetection_touch.config"; $configTVFile="$ENV{AMFMobileHome}/amflitedetection_tv.config"; } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode is not setted the default value is $cookiecachesystem"); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach my $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDownloadParam}) { $downloadparam=$ENV{AMFDownloadParam}; $CommonLib->printLog("DownloadAMFParam is: $downloadparam"); } if ($downloadparam eq 'true' && $forceBlockDownload eq "false") { &readMobileParamFromUrl; &readTabletParamFromUrl; &readTouchParamFromUrl; &readTVParamFromUrl; } else { &readMobileParamFromFile; &readTabletParamFromFile; &readTouchParamFromFile; &readTVParamFromFile; } if ($ENV{ForceTabletAsFullBrowser}) { if ($ENV{ForceTabletAsFullBrowser} eq 'true') { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); $forcetablet="true"; } else { $forcetablet="false"; } } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable=true"); } sub readMobileParamFromUrl { $CommonLib->printLog("Read data from ".$urlmobile); my $req = HTTP::Request->new(HEAD => $urlmobile); $req->header('Accept' => 'text/html'); my $res = $ua->request($req); if ($res->is_success) { $CommonLib->printLog("Redirect to:" . $res->request()->uri()); $urlmobile=$res->request()->uri(); my $request = $ua->get ($urlmobile); my $content=$request->content; if ($content) { $CommonLib->printLog("Download OK"); $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } open (MYFILE, ">$configMobileFile") || die ("Cannot Open File: $configMobileFile"); print MYFILE $content; close (MYFILE); } else { $CommonLib->printLog("Download error ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readMobileParamFromFile; } } else { $CommonLib->printLog("Download error ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readMobileParamFromFile; } } sub readMobileParamFromFile { $CommonLib->printLog("Read for mobile data from $configMobileFile"); my $content=""; if (open (IN,$configMobileFile)) { while () { $content=$content.$_; } close IN; } else { $CommonLib->printLog("Error open file:$configMobileFile"); ModPerl::Util::exit(); } $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } } sub readTabletParamFromUrl { $CommonLib->printLog("Read data for tablet detection from ".$urlTablet); my $req = HTTP::Request->new(HEAD => $urlTablet); $req->header('Accept' => 'text/html'); my $res = $ua->request($req); if ($res->is_success) { $CommonLib->printLog("Redirect to:" . $res->request()->uri()); $urlTablet=$res->request()->uri(); my $request = $ua->get ($urlTablet); my $content=$request->content; if ($content) { $CommonLib->printLog("Download OK"); $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileTabletArray{$dummy}='mobile'; } open (MYFILE, ">$configTabletFile") || die ("Cannot Open File: $configMobileFile"); print MYFILE $content; close (MYFILE); } else { $CommonLib->printLog("Download error from ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readTabletParamFromFile; } } else { $CommonLib->printLog("Error: " . $res->status_line); $CommonLib->printLog("Download error from ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readTabletParamFromFile; } } sub readTabletParamFromFile { $CommonLib->printLog("Read for tablet data from $configTabletFile"); my $content=""; if (open (IN,$configTabletFile)) { while () { $content=$content.$_; } close IN; } else { $CommonLib->printLog("Error open file:$configTabletFile"); ModPerl::Util::exit(); } $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileTabletArray{$dummy}='mobile'; } } sub readTouchParamFromUrl { $CommonLib->printLog("Read for touch data for touch detection from ".$urlTouch); my $req = HTTP::Request->new(HEAD => $urlTouch); $req->header('Accept' => 'text/html'); my $res = $ua->request($req); if ($res->is_success) { $CommonLib->printLog("Redirect to:" . $res->request()->uri()); $urlmobile=$urlmobile; my $request = $ua->get ($urlTouch); my $content=$request->content; if ($content) { $CommonLib->printLog("Download OK"); $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileTouchArray{$dummy}='mobile'; } open (MYFILE, ">$configTouchFile") || die ("Cannot Open File: $configMobileFile"); print MYFILE $content; close (MYFILE); } else { $CommonLib->printLog("Download error from ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readTouchParamFromFile; } } else { $CommonLib->printLog("Error: " . $res->status_line); $CommonLib->printLog("Download error from ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readTouchParamFromFile; } } sub readTouchParamFromFile { $CommonLib->printLog("Read data from $configTouchFile"); my $content=""; if (open (IN,$configTouchFile)) { while () { $content=$content.$_; } close IN; } else { $CommonLib->printLog("Error open file:$configTouchFile"); ModPerl::Util::exit(); } $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileTouchArray{$dummy}='mobile'; } } sub readTVParamFromUrl { $CommonLib->printLog("Read data for TV detection from ".$urlTv); my $req = HTTP::Request->new(HEAD => $urlTv); $req->header('Accept' => 'text/html'); my $res = $ua->request($req); if ($res->is_success) { $CommonLib->printLog("Redirect to:" . $res->request()->uri()); $urlmobile= $res->request()->uri(); my $request = $ua->get ($urlTv); my $content=$request->content; if ($content) { $CommonLib->printLog("Download OK"); $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileTVArray{$dummy}='mobile'; } open (MYFILE, ">$configTVFile") || die ("Cannot Open File: $configTVFile"); print MYFILE $content; close (MYFILE); } else { $CommonLib->printLog("Download error from ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readTVParamFromFile; } } else { $CommonLib->printLog("Error: " . $res->status_line); $CommonLib->printLog("Download error from ".$correctHostName); $CommonLib->printLog("Try download previews version"); &readTVParamFromFile; } } sub readTVParamFromFile { $CommonLib->printLog("Read for tv data from $configTVFile"); my $content=""; if (open (IN,$configTVFile)) { while () { $content=$content.$_; } close IN; } else { $CommonLib->printLog("Error open file:$configTVFile"); ModPerl::Util::exit(); } $content =~ s/\n//g; my @dummyMobileKeys = split(/,/, lc($content)); foreach my $dummy (@dummyMobileKeys) { $MobileTVArray{$dummy}='mobile'; } } sub isMobile { my ($UserAgent) = @_; my $ind=0; my $isMobileValue='false'; my $pair; my $length=0; foreach $pair (sort keys %MobileArray) { if ($UserAgent =~ m/$pair/) { $isMobileValue='true'; } } return $isMobileValue; } sub isTablet { my ($UserAgent) = @_; my $ind=0; my $isTabletValue='false'; my $pair; my $length=0; foreach $pair (sort keys %MobileTabletArray) { if ($UserAgent =~ m/$pair/) { $isTabletValue='true'; } } return $isTabletValue; } sub isTouch { my ($UserAgent) = @_; my $ind=0; my $isTouchValue='false'; my $pair; my $length=0; foreach $pair (sort keys %MobileTouchArray) { if ($UserAgent =~ m/$pair/) { $isTouchValue='true'; } } return $isTouchValue; } sub isTV { my ($UserAgent) = @_; my $ind=0; my $isTVValue='false'; my $pair; my $length=0; foreach $pair (sort keys %MobileTVArray) { if ($UserAgent =~ m/$pair/) { $isTVValue='true'; } } return $isTVValue; } sub cleanUA { my ($UserAgent) = @_; $UserAgent =~ s/google favicon//g; return $UserAgent; } sub getOperativeSystem { my ($UserAgent) = @_; my $returnValue="nc"; my @osTypesArray = split(/,/, "android,iphone|ipad|ipod,windows phone,symbianos,blackberry,kindle"); my $osNumber=0; foreach my $os (@osTypesArray){ if ($UserAgent =~ /$os/) { if ($osNumber == 0 ) { $returnValue="android"; } elsif ($osNumber == 1 ) { $returnValue="ios"; } elsif ($osNumber == 2 ) { $returnValue="windows phone"; } elsif ($osNumber == 3 ) { $returnValue="symbian"; } elsif ($osNumber == 4 ) { $returnValue="kindle"; } return $returnValue; } $osNumber++; } return $returnValue; } sub getOperativeSystemVersion { my ($UserAgent, $os) = (@_); my $matchOS=0; my $regex_param=''; my $return_value="nc"; if ($os eq 'android') { $regex_param="android ([0-9]\\.[0-9](\\.[0-9])?)"; $matchOS=1; } elsif ($os eq 'ios') { $regex_param="os ((\\d+_?){2,3})\\s"; $matchOS=1; } elsif ($os eq 'windows phone') { $regex_param="( phone| phone os) ([0-9]\\.[0-9](\\.[0-9])?)"; $matchOS=1; } elsif ($os eq 'symbian') { $regex_param="symbianos/([0-9]\\.[0-9](\\.[0-9])?)"; $matchOS=1; } elsif ($os eq 'mac') { $regex_param="os x ([0-9]([0-9]?)(_|.)([0-9]?)([0-9]?)(_?|.?)([0-9]?)([0-9]?))"; $matchOS=1; } if ($matchOS == 1) { ($return_value) = ($UserAgent =~ /$regex_param/i); } return $return_value; } sub getOperativeDesktopSystem { my ($UserAgent, $os) = (@_); my $returnValue="nc"; my @osTypesArray = split(/,/, "windows,mac,linux"); my $osNumber=0; foreach my $os (@osTypesArray){ if ($UserAgent =~ /$os/) { if ($osNumber == 0 ) { $returnValue="windows"; } elsif ($osNumber == 1 ) { $returnValue="mac"; } elsif ($osNumber == 2 ) { $returnValue="windows"; } return $returnValue; } $osNumber++; } return $returnValue; } sub getBrowserVersion { my ($UserAgent, $os) = (@_); my $regex="(firefox|msie|chrome|chromium|safari|edge|seamonkey|opera)\\/(([0-9]?)([0-9]?)([0-9]?)(.?)([0-9]?)([0-9]?)([0-9]?)(.?)([0-9]?)([0-9]?)([0-9]?)(.?)([0-9]?)([0-9]?)([0-9]?)(.?)([0-9]?)([0-9]?)([0-9]?))"; my $regex2='(msie|(?!gecko.+)firefox|(?!applewebkit.+chrome.+)safari|(?!applewebkit.+)chrome|applewebkit(?!.+chrome|.+safari)|gecko(?!.+firefox))(?: |\/)([\d\.apre]+)'; my $type="nc"; my $version="nc"; my ($mtype,$mversion)=($UserAgent =~ /$regex/i); if (!$mtype) { my ($mtype2,$mversion2)=($UserAgent =~ /$regex2/i); if ($mtype2) { $type=$mtype2; $version=$mversion2; } } else { $type=$mtype; $version=$mversion; } print $type."\n"; print $version."\n"; return ($type,$version); } sub handler { my $f = shift; my $capability2; my $variabile=""; my $user_agent=lc($f->headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $isTablet="false"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; my %ArrayQuery; my $var; my $mobile=0; my $amf_device_istablet='false'; my $amf_device_istouch='false'; my $amf_device_ismobile=''; my $amf_device_istv=''; my $version=""; my $amf_device_os='nc'; my $amf_device_os_version='nc'; my $amf_browser_type='nc'; my $amf_browser_version='nc'; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; if ($CommonLib->readCookie($cookie) eq 'true' || $CommonLib->readCookie($cookie) eq 'false') { $amf_device_ismobile=$CommonLib->readCookie($cookie); } my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=&cleanUA($user_agent); if ($amf_device_ismobile eq "") { $amf_device_ismobile = &isMobile($user_agent); if ($amf_device_ismobile eq 'true') { $amf_device_istouch = &isTouch($user_agent); $amf_device_istablet=&isTablet($user_agent); $amf_device_os=&getOperativeSystem($user_agent); } else { $amf_device_os=&getOperativeDesktopSystem($user_agent); } $amf_device_os_version=&getOperativeSystemVersion($user_agent,$amf_device_os); $amf_device_istv = &isTV($user_agent); if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amfID=$id; path=/;"); } } ($amf_browser_type,$amf_browser_version)=&getBrowserVersion($user_agent); if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } $f->pnotes('is_tablet' => $amf_device_istablet); $f->pnotes("amf_device_ismobile" => $amf_device_ismobile); $f->pnotes("is_touch" => $amf_device_istouch); $f->subprocess_env("AMF_ID" => "amf_lite_detection"); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => $amf_device_ismobile); $f->subprocess_env("AMF_DEVICE_IS_TABLET" => $amf_device_istablet); $f->subprocess_env("AMF_DEVICE_IS_TOUCH" => $amf_device_istouch); $f->subprocess_env("AMF_DEVICE_IS_TV" => $amf_device_istv); $f->subprocess_env("AMF_DEVICE_OS" => $amf_device_os); $f->subprocess_env("AMF_DEVICE_OS_VERSION" => $amf_device_os_version); $f->subprocess_env("AMF_BROWSER_TYPE" => $amf_browser_type); $f->subprocess_env("AMF_BROWSER_VERSION" => $amf_browser_version); $f->subprocess_env("AMF_VER" => $VERSION); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } else { $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMFLiteDetectionFilter - The module detects in lite mode the mobile device and passes few capabilities on to the other web application as environment variables =head1 DESCRIPTION Module for device detection, parse the user agent and decide if the device is mobile, touch or tablet. =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFLiteDetectionFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFMobileCachingMemcached.pm000644 000765 000024 00000010623 13064524645 027351 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFMobileCachingMemcached.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFMobileCachingMemcached; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use Apache2::Connection (); use APR::Table (); use LWP::Simple; use Cache::Memcached; use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use vars qw($VERSION); $VERSION= "4.20";;; # # Define the global environment # my $CommonLib = new Apache2::AMFCommonLib (); my $SetCacheTime="900"; my $serverMemCache; my @Server; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFMobileCachingMemcached Version $VERSION"); if ($ENV{AMFMobileHome}) { &loadConfigFile(); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); $CommonLib->printLog("Pre-Requisite: WURFLFilter must be activated"); ModPerl::Util::exit(); } if ($ENV{ServerMemCached}) { $serverMemCache=$ENV{ServerMemCached}; @Server = split(/,/, $ENV{ServerMemCached}); $CommonLib->printLog("ServerMemCached is: $serverMemCache"); } else { $CommonLib->printLog("ServerMemCached is not setted. Please set the variable ServerMemCached into httpd.conf, example \"PerlSetEnv ServerMemCached 10.10.10.10:11211\""); ModPerl::Util::exit(); } my $memd = new Cache::Memcached { 'debug' => 0, 'compress_threshold' => 10_000, 'enable_compress' => 1, }; $memd->set_servers(\@Server); sub loadConfigFile { my $dummy; my $carrier; my $nation; my $ip; my $row; my @rows; my $carriernetdownload="none"; my $carrierurl; my $total_carrier_ip=0; my $ip2; $CommonLib->printLog("AMFCarrierDetection: Start read configuration from httpd.conf"); if ($ENV{SetCacheTime}) { $SetCacheTime=$ENV{SetCacheTime}; $CommonLib->printLog("SetCacheTime is: $SetCacheTime (seconds)"); } else { $CommonLib->printLog("SetCacheTime is not setted. So, the default timeout is: $SetCacheTime seconds"); } $CommonLib->printLog("Finish loading parameter"); } sub handler { my $f = shift; my $r = $f->r; my $finfo = $r->finfo; my $uri = $f->r->uri(); my $s = $f->r->server; my $content_type=$f->r->content_type(); my $hostname=$f->r->hostname(); my $port=$f->r->get_server_port(); my $id='null'; my $query_string=$f->r->args; if ($query_string) { } else { $query_string = ""; } $hostname="$hostname:$port"; if ($f->r->pnotes('id')) { $id=$f->r->pnotes('id') } else { $s->warn("AMF error - probably the AMFWURFLFilter is not started"); } unless( $f->ctx ) { $f->r->headers_out->unset('Content-Length'); $f->ctx(1); } my $key="$hostname:$id:$uri:$query_string"; my $page=$f->read(my $buf, BUFF_LEN); my $var=$memd->get($key); if ($var) { my $hash_dummy=$var; my %hash=%$hash_dummy; my $content_type = $hash{'content_type'}; $buf = $hash{'page'}; } else { my %hash=('content_type',$content_type,'page',$buf); $memd->set($key,\%hash, time + $SetCacheTime); } $f->r->content_type($content_type); #$f->r->headers_out->set("Content-Length"=>$buf); $f->print($buf); return Apache2::Const::OK; } 1; =head1 NAME Apache2::AMFMobileCachingMemcached - This module has the scope to cache the static in content in different layout for mobile. =head1 DESCRIPTION This module has the scope to cache the static in content in different layout for mobile. For more details: http://wiki.apachemobilefilter.org =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFMobileCaching =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cutApache2-ApacheMobileFilter-4.20/lib/Apache2/AMFSwitcher.pm000644 000765 000024 00000021675 13064524645 024677 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFSwitcher.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFSwitcher; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple; use Apache2::Const -compile => qw(REDIRECT DECLINED HTTP_TEMPORARY_REDIRECT HTTP_MOVED_PERMANENTLY HTTP_MOVED_TEMPORARILY HTTP_SEE_OTHER HTTP_NOT_MODIFIED HTTP_USE_PROXY); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use vars qw($VERSION); $VERSION= "4.20";;; # # Define the global environment # my $CommonLib = new Apache2::AMFCommonLib (); my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoderurl="none"; my $redirecttranscoder="false"; my $wildcardredirect="false"; my $mobileversionurl_ck="/"; my $fullbrowserurl_ck="/"; my $redirecttranscoderurl_ck="/"; my @IncludeString; my @ExcludeString; my $mobilenable="false"; my $mobileDomain="none"; my $fullbrowserDomain="none"; my $transcoderDomain="none"; my $forcetablet="false"; my $return_http_switch=Apache2::Const::REDIRECT; my %ArrayPath; $ArrayPath{1}='none'; $ArrayPath{2}='none'; $ArrayPath{3}='none'; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFSwitcher Version $VERSION"); if ($ENV{AMFMobileHome}) { } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); $CommonLib->printLog("Pre-Requisite: WURFLFilter must be activated"); ModPerl::Util::exit(); } $CommonLib->printLog("If you use AMFWURFLFilter is better to use WebPatch LoadWebPatch not exist."); $CommonLib->printLog("Pre-Requisite: WURFLFilter must be activated"); &loadConfigFile(); sub loadConfigFile { my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; $CommonLib->printLog("AMFSwitcher: Start read configuration from httpd.conf"); if ($ENV{TypeRedirect}) { if ($ENV{TypeRedirect} eq "301") { $return_http_switch=Apache2::Const::HTTP_MOVED_PERMANENTLY; } elsif ($ENV{TypeRedirect} eq "302") { $return_http_switch=Apache2::Const::HTTP_MOVED_TEMPORARILY; } elsif ($ENV{TypeRedirect} eq "303") { $return_http_switch=Apache2::Const::HTTP_SEE_OTHER; } elsif ($ENV{TypeRedirect} eq "304") { $return_http_switch=Apache2::Const::HTTP_NOT_MODIFIED; } elsif ($ENV{TypeRedirect} eq "305") { $return_http_switch=Apache2::Const::HTTP_USE_PROXY; } elsif ($ENV{TypeRedirect} eq "307") { $return_http_switch=Apache2::Const::HTTP_TEMPORARY_REDIRECT; } } if ($ENV{FullBrowserUrl}) { $fullbrowserurl=$ENV{FullBrowserUrl}; $ArrayPath{2}=$ENV{FullBrowserUrl}; $CommonLib->printLog("FullBrowserUrl is: $fullbrowserurl"); $fullbrowserurl_ck=$ENV{FullBrowserUrl}; if (substr ($fullbrowserurl,0,5) eq "http:") { my ($dummy,$dummy2,$url_domain,$dummy3)=split(/\//, $fullbrowserurl); $fullbrowserDomain=$url_domain; } } if ($ENV{RedirectTranscoderUrl}) { $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; $ArrayPath{3}=$ENV{RedirectTranscoderUrl}; $redirecttranscoder="true"; $redirecttranscoderurl_ck=$ENV{RedirectTranscoderUrl}; $CommonLib->printLog("RedirectTranscoderUrl is: $redirecttranscoderurl"); if (substr ($redirecttranscoderurl,0,5) eq "http:") { my ($dummy,$dummy2,$url_domain,$dummy3)=split(/\//, $redirecttranscoderurl); $transcoderDomain=$url_domain; } } if ($ENV{"AMFSwitcherExclude"}){ @ExcludeString=split(/,/, $ENV{AMFSwitcherExclude}); $CommonLib->printLog("SwitcherExclude is: $ENV{AMFSwitcherExclude}"); } if ($ENV{WildCardRedirect}) { if ($ENV{WildCardRedirect} eq 'true') { $wildcardredirect="true"; } else { $wildcardredirect="false"; } $CommonLib->printLog("WildCardRedirect is: $wildcardredirect"); } if ($ENV{ForceTabletAsFullBrowser}) { if ($ENV{ForceTabletAsFullBrowser} eq 'true') { $forcetablet="true"; } else { $forcetablet="false"; } $CommonLib->printLog("ForceTabletAsFullBrowser is: $forcetablet"); } if ($ENV{MobileVersionUrl}) { $mobileversionurl=$ENV{MobileVersionUrl}; $ArrayPath{1}=$ENV{MobileVersionUrl}; $CommonLib->printLog("MobileVersionUrl is: $mobileversionurl"); $mobileversionurl_ck=$ENV{MobileVersionUrl}; push(@ExcludeString,$ENV{MobileVersionUrl}); if (substr ($mobileversionurl,0,5) eq "http:") { my ($dummy,$dummy2,$url_domain,$dummy3)=split(/\//, $mobileversionurl); $mobileDomain=$url_domain; } } $CommonLib->printLog("Finish loading parameter"); } sub handler { my $f = shift; my $capability2; my $query_string=$f->args; my $device_claims_web_support="null"; my $is_wireless_device="null"; my $is_transcoder="null"; my $location="none"; my $return_value=Apache2::Const::DECLINED; my $device_type=1; my $no_redirect=1; my $uri=$f->unparsed_uri(); my $servername=$f->get_server_name(); my $uriAppend=""; my $filter="true"; my %ArrayQuery; my $isTablet="null"; my $amf_device_ismobile = "true"; my $amf_force_to_mobile = "false"; if ($query_string) { my @vars = split(/&/, $query_string); foreach my $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; } $ArrayQuery{$v}="ok"; } } } if ($f->pnotes('is_tablet')) { $isTablet=$f->pnotes('is_tablet') } if ($f->pnotes('is_transcoder')) { $is_transcoder=$f->pnotes('is_transcoder'); } if ($f->pnotes('amf_force_to_desktop')) { $amf_force_to_mobile=$f->pnotes('amf_force_to_desktop'); } if ($f->pnotes('amf_device_ismobile')) { $amf_device_ismobile=$f->pnotes('amf_device_ismobile'); } foreach my $string (@ExcludeString) { if (index($uri,$string) > -1) { $filter="false"; } } if ($filter eq "true"){ if ($amf_device_ismobile eq 'false'|| ($isTablet eq "true" && $forcetablet eq "true")) { if ($fullbrowserDomain ne $servername) { if ($fullbrowserurl ne 'none') { if ($wildcardredirect eq 'true'){ $location=$uri; if ($location =~ /$mobileversionurl_ck/o) { $location =~ s/$mobileversionurl_ck/$fullbrowserurl/; } else { $location = $fullbrowserurl; } } else { $location = $fullbrowserurl; } } $device_type=2; } } else { if ($mobileDomain ne $servername) { if ($wildcardredirect eq 'true'){ $location=$uri; if ($location =~ /$fullbrowserurl_ck/o) { $location =~ s/$fullbrowserurl_ck/$mobileversionurl/; } else { $location = $mobileversionurl; } } else { $location = $mobileversionurl; } } else { if (substr ($mobileversionurl,0,4) eq "http") { $location = $mobileversionurl; } } $device_type=1; } if ($is_transcoder eq 'true') { if ($transcoderDomain ne $servername) { if ($redirecttranscoderurl ne 'none') { if ($wildcardredirect eq 'true'){ $location=$uri; if ($location =~ /$fullbrowserurl_ck/o) { $location =~ s/$fullbrowserurl_ck/$redirecttranscoderurl/; } else { $location = $redirecttranscoderurl; } } } $device_type=3; } } if ($ArrayPath{$device_type} eq substr($uri,0,length($ArrayPath{$device_type}))) { $no_redirect=0; } if ($location ne "none" && $amf_force_to_mobile eq 'false') { if (substr ($location,0,4) eq "http") { $f->headers_out->set(Location => $location); $f->status($return_http_switch); $return_value=$return_http_switch; } else { if ($no_redirect==1) { $f->headers_out->set(Location => $location); $f->status($return_http_switch); $return_value=$return_http_switch; } } } } return $return_value; } 1; =head1 NAME Apache2::AMFSwitcher - Used to switch the device to the apropriate content (mobile, fullbrowser or for transcoder) =head1 DESCRIPTION This module has the scope to manage with WURFLFilter.pm module the group of device (MobileDevice, PC and transcoder). =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFSwitcher =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFTrace.pm000644 000765 000024 00000006007 13064524645 024135 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFTrace.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFTrace; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use Apache2::Connection (); use APR::Table (); use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use vars qw($VERSION); $VERSION= "4.20";;; # # Define the global environment # my $CommonLib = new Apache2::AMFCommonLib (); my $TraceDebug='false'; my @TraceCapability; my $TraceFS="\|"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFTrace Version $VERSION"); if ($ENV{AMFTraceDebug}) { $TraceDebug=$ENV{AMFTraceDebug}; } if ($ENV{AMFTraceFS}) { $TraceFS=$ENV{AMFTraceFS}; } if ($ENV{AMFTraceCapability}) { #$TraceCapability=$ENV{AMFTraceCapability}; @TraceCapability = split(/,/, $ENV{AMFTraceCapability}); $CommonLib->printLog("TraceCapabilityList is: $ENV{AMFTraceCapability}"); } else { $CommonLib->printLog("AMFTraceCapability is not setted, the default value is: id"); $TraceCapability[0]='id'; } $CommonLib->printLog("AMFTraceDebug is: $TraceDebug"); sub handler { my $f = shift; my $user_agent=$f->headers_in->{'User-Agent'}|| ''; my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; if ($x_user_agent) { $f->log->warn("Warn probably transcoder: $x_user_agent"); $user_agent=$x_user_agent; } if ($TraceDebug eq 'false') { if ($f->pnotes('id')) { if ($f->pnotes('id') eq 'device_not_found') { $f->log->warn("AMFTrace device_not_found - User_Agent:$user_agent"); } } else { $f->log->warn("AMFTrace device_not_found - User_Agent:$user_agent"); } } else { my $msg=""; foreach my $key ( @TraceCapability) { if ($f->pnotes("$key")) { $msg=$msg.$key."=".$f->pnotes("$key").$TraceFS; } else { if ($key eq 'id') { $msg=$msg."id=device_not_found".$TraceFS; } } } $f->log->warn("AMFTrace - $msg User_Agent:$user_agent"); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMFTrace - This module has the scope to trace the not detected devices and to statistic or debugging scope. =head1 DESCRIPTION This module has the scope to trace info for debug. =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFTrace =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cutApache2-ApacheMobileFilter-4.20/lib/Apache2/AMFWebService.pm000644 000765 000024 00000011330 13064524644 025127 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFWebService.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFWebService; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::Filter (); use Apache2::RequestIO (); use APR::Table (); use Cache::FileBackend; use Apache2::Const -compile => qw(OK); use constant BUFF_LEN => 1024; use vars qw($VERSION); $VERSION= "4.20";;; # # Define the global environment # my $CommonLib = new Apache2::AMFCommonLib (); my $cachedirectorystore="notdefined"; my $cachedirective="no-cache"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFWebService Version $VERSION"); if ($ENV{RestMode}) { } else { $CommonLib->printLog("RestMode must be setted not exist. Please set the variable RestMode into httpd.conf"); } if ($ENV{AMFWSCacheControl}) { $cachedirective=$ENV{AMFWSCacheControl}; $CommonLib->printLog("AMFWSCacheControl is: $cachedirective"); } else { $CommonLib->printLog("AMFWSCacheControl is not setted."); } sub handler { my $f = shift; my $query_string=$f->args; my $id; my $ua; my $capab; my %ArrayQuery; my %ArrayForSort; my %ArrayPnotes; my %ArrayCapability; my $type="xml"; my $capabilityList="all"; if ($query_string) { my @vars = split(/&/, $query_string); foreach my $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } if ($ArrayQuery{type}) { $type=$ArrayQuery{type}; } if ($ArrayQuery{capabilityList}) { my @capability = split(/,/, $ArrayQuery{capabilityList}); $capabilityList="no"; foreach my $var (sort @capability){ if ($var) { $var=~ tr/[a-z]/[A-Z]/; $ArrayCapability{$var}='ok'; } } } } my $Hash=$f->subprocess_env(); my $html_page; my $content_type="text/xml"; if ($type ne 'json' && $type ne 'xml') { $type='xml'; } if ($type eq 'json') { $content_type="text/plain"; } if ($type eq 'xml') { $html_page=''; } if ($type eq 'json') { $html_page='{"AMF_DEVICE_DETECTION": {'."\n"; } my $count=0; while ( my ($key, $value) = each(%$Hash) ) { if (substr($key,0,4) eq 'AMF_') { $key=substr($key,4,length($key)); if ($count > 0) { $html_page=$html_page.",\n"; $count=0; } if ($type eq 'xml' && ($capabilityList eq 'all' || ($ArrayCapability{$key}))) { $html_page=$html_page."<$key>$value"; } if ($type eq 'json' && ($capabilityList eq 'all' || ($ArrayCapability{$key}))) { $html_page=$html_page." \"$key\":\"$value\""; $count++; } } } if ($type eq 'xml') { $html_page=$html_page.''; } if ($type eq 'json') { $html_page=substr($html_page,0,length($html_page)-2); $html_page=$html_page."\n }\n}"; } $f->headers_out->set("Last-Modified" => time()); if ($ENV{AMFWSCacheControl}) { $f->err_headers_out->set('Cache-Control' => $cachedirective); } $f->content_type($content_type); $f->print($html_page); return Apache2::Const::OK; } 1; =head1 NAME Apache2::AMFWebService - This module give the result of Device Detection as WebService =head1 DESCRIPTION This module give the info as WebService =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFWebService =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cutApache2-ApacheMobileFilter-4.20/lib/Apache2/AMFWURFLFilter.pm000644 000765 000024 00000066244 13064524644 025154 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFWURFLFilter.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.apachemobilefilter.org # Mail: idel.fuschini@gmail.com package Apache2::AMFWURFLFilter; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use Apache2::SubRequest (); use Apache2::Log; use Apache2::Filter (); use APR::Table (); use LWP::Simple qw($ua get); use Apache2::Const -compile => qw(OK REDIRECT DECLINED); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; use constant BUFF_LEN => 1024; use Cache::FileBackend; # # Define the global environment # use vars qw($VERSION); $VERSION= "4.20";;; my $CommonLib = new Apache2::AMFCommonLib (); my %Capability; my %Array_fb; my %Array_id; my %Array_fullua_id; my %Array_DDRcapability; my %MobileArray=$CommonLib->getMobileArray; my %PCArray=$CommonLib->getPCArray; my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoder="true"; my $redirecttranscoderurl="none"; my $resizeimagedirectory="none"; my $wurflnetdownload="false"; my $downloadwurflurl="false"; my $listall="false"; my $cookiecachesystem="false"; my $WURFLVersion="unknown"; my $personalwurflurl='unknown'; my $cachedirectorystore="/tmp"; my $capabilitylist="none"; my $restmode='false'; my $deepSearch=0; my $checkVersion='false'; my $mobilenable="false"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("--- The license of the wurfl.xml file is now changed. ---"); $CommonLib->printLog("--- The WURFL file is the Copyright of ScientiaMobile, read the license ---"); $CommonLib->printLog("--- For more info: http://www.scientiamobile.com. ---"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFWURFLFilter module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($checkVersion eq 'true') { $CommonLib->printLog("Check on apchemobilefilter.org if the installed AMF is the last version"); $CommonLib->printLog("Try to download http://www.apachemobilefilter.org/param/amf.config"); my $url="http://www.apachemobilefilter.org/param/amf.config"; my $content = get ($url); $content =~ s/\n//g; my $check_version=0; if ($content) { $check_version=$content; } if ($check_version > $VERSION && $check_version ne 0) { $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----- There is a new version of AMF V$check_version online ----"); $CommonLib->printLog("---------------------------------------------------------------------------"); } else { $CommonLib->printLog("AMF installed is the last version"); } } else { $CommonLib->printLog("AMFCheckVersion is false, AMF don't check the last version."); } if ($ENV{ResizeImageDirectory}) { $Capability{'max_image_width'}="max_image_width"; $Capability{'max_image_height'}="max_image_width"; $resizeimagedirectory=$ENV{ResizeImageDirectory}; } if (($ENV{FullBrowserUrl}) || ($ENV{MobileVersionUrl})) { $Capability{'device_claims_web_support'}="device_claims_web_support"; $Capability{'is_wireless_device'}="is_wireless_device"; $fullbrowserurl=$ENV{FullBrowserUrl} } if ($ENV{RedirectTranscoderUrl}) { $Capability{'is_transcoder'}="is_transcoder"; $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; } # # Check if AMFMobileHome and CacheDirectoryStore is setting in apache httpd.conf file for example: # PerlSetEnv AMFMobileHome /MobileFilter # if ($ENV{CacheDirectoryStore}) { $cachedirectorystore=$ENV{CacheDirectoryStore}; $CommonLib->printLog("CacheDirectoryStore is: $cachedirectorystore"); } else { $CommonLib->printLog("CacheDirectoryStore not exist. Please set the variable CacheDirectoryStore into httpd.conf, (the directory must be writeable)"); ModPerl::Util::exit(); } # # Define the cache system directory # my $cacheSystem = new Cache::FileBackend( $cachedirectorystore, 3, 000 ); $cacheSystem->store( 'wurfl-id', 'device_not_found', "id=device_not_found&device=false&device_claims_web_support=true&is_wireless_device=false"); if ($cacheSystem->restore('wurfl-conf','ver')) { } else { $CommonLib->printLog('Create new wurf-con store'); $cacheSystem->store('wurfl-conf', 'ver', 'null'); $cacheSystem->store('wurfl-conf', 'caplist', 'null'); $cacheSystem->store('wurfl-conf', 'listall', 'null'); $cacheSystem->store('wurfl-conf', 'RedirectTranscoderUrl','null'); $cacheSystem->store('wurfl-conf', 'MobileVersionUrl','null'); $cacheSystem->store('wurfl-conf', 'FullBrowserUrl','null'); $cacheSystem->store('wurfl-conf', 'ResizeImageDirectory','null'); } if ($ENV{AMFMobileHome}) { &loadConfigFile("$ENV{AMFMobileHome}/wurfl.xml"); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my ($fileWurfl) = @_; my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("Start read configuration from httpd.conf"); if ($ENV{WurflNetDownload}) { if ($ENV{WurflNetDownload} eq 'true' || $ENV{WurflNetDownload} eq 'false') { $wurflnetdownload=$ENV{WurflNetDownload}; $CommonLib->printLog("WurflNetDownload is: $wurflnetdownload"); } else { $CommonLib->printLog("Error WurflNetDownload parmeter must set to true or false"); ModPerl::Util::exit(); } } if ($ENV{DownloadWurflURL}) { $downloadwurflurl=$ENV{DownloadWurflURL}; $CommonLib->printLog("DownloadWurflURL is: $downloadwurflurl"); } if ($ENV{CapabilityList}) { my @dummycapability = split(/,/, $ENV{CapabilityList}); $capabilitylist=$ENV{CapabilityList}; foreach $dummy (@dummycapability) { if ($dummy eq "all") { $listall="true"; } $Capability{$dummy}=$dummy; $CommonLib->printLog("CapabilityList is: $dummy"); } } else { $listall="true"; $CommonLib->printLog('CapabilityList not setted so the default value is "all"'); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode (the CookieCacheSystem is deprecated) is not setted the default value is $cookiecachesystem"); } if ($ENV{PersonalWurflFileName}) { $personalwurflurl=$ENV{AMFMobileHome}."/".$ENV{PersonalWurflFileName}; $CommonLib->printLog("PersonalWurflFileName is: $ENV{PersonalWurflFileName}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDeepParse}) { $deepSearch=$ENV{AMFDeepParse}; $CommonLib->printLog("AMFDeepParse is: $deepSearch"); } else { $CommonLib->printLog("AMFDeepParse is not setted the default value is 0"); } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable=true"); } $CommonLib->printLog("Finish loading parameter"); $CommonLib->printLog("---------------------------------------------------------------------------"); if ($wurflnetdownload eq "true") { $CommonLib->printLog("Start process downloading WURFL.xml from $downloadwurflurl"); $CommonLib->printLog ("Test the URL"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($downloadwurflurl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $downloadwurflurl."); ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL is correct"); $CommonLib->printLog("The size of document wurf file: $document_length bytes"); } if ($content_type eq 'application/zip') { $CommonLib->printLog("The file is a zip file."); $CommonLib->printLog ("Start downloading"); my @dummypairs = split(/\//, $downloadwurflurl); my ($ext_zip) = $downloadwurflurl =~ /\.(\w+)$/; my $filezip=$dummypairs[-1]; my $tmp_dir=$ENV{AMFMobileHome}; $filezip="$tmp_dir/$filezip"; my $status = getstore ($downloadwurflurl,$filezip); my $output="$tmp_dir/tmp_wurfl.xml"; unzip $filezip => $output or die "unzip failed: $UnzipError\n"; # # call parseWURFLFile # callparseWURFLFile($output); } else { $CommonLib->printLog("The file is a xml file."); my $content = get ($downloadwurflurl); $content =~ s/\n//g; $content =~ s/>/>\n/g; my @rows = split(/\n/, $content); my $row; my $count=0; my $numberRow=scalar(@rows); my $progress=0; foreach $row (@rows){ $r_id=parseWURFLFile($row,$r_id); my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; $progress++; } } $CommonLib->printLog("Finish downloading WURFL from $downloadwurflurl"); } else { if (-e "$fileWurfl") { $CommonLib->printLog("Start loading WURFL.xml"); if (open (IN,"$fileWurfl")) { my $filesize= -s $fileWurfl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); my $numberRow=scalar(@arrayFile); my $progress=0; foreach my $line (@arrayFile) { $r_id=parseWURFLFile($line,$r_id); my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; $progress++; } } else { $CommonLib->printLog("Error open file:$fileWurfl"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $fileWurfl not found"); ModPerl::Util::exit(); } } close IN; my $arrLen = scalar %Array_fb; ($arrLen,$dummy)= split(/\//, $arrLen); if ($arrLen == 0) { $CommonLib->printLog("Error the file probably is not a wurfl file, control the url or path"); $CommonLib->printLog("Control also if the file is compress file, and DownloadZipFile parameter is seted false"); ModPerl::Util::exit(); } $CommonLib->printLog("WURFL version: $WURFLVersion"); if ($cacheSystem->restore('wurfl-conf', 'amfver') ne $VERSION||$cacheSystem->restore('wurfl-conf', 'ResizeImageDirectory') ne $resizeimagedirectory||$cacheSystem->restore('wurfl-conf', 'DownloadWurflURL') ne $downloadwurflurl||$cacheSystem->restore('wurfl-conf', 'FullBrowserUrl') ne $fullbrowserurl||$cacheSystem->restore('wurfl-conf', 'RedirectTranscoderUrl') ne $redirecttranscoderurl || $cacheSystem->restore('wurfl-conf', 'ver') ne $WURFLVersion || $cacheSystem->restore('wurfl-conf', 'caplist') ne $capabilitylist||$cacheSystem->restore('wurfl-conf', 'listall') ne $listall) { $CommonLib->printLog("********************************************************************************************************"); $CommonLib->printLog("* This is a new version of WURFL or you change some parameter value or it's a new version of AMF, now the old cache must be deleted *"); $CommonLib->printLog("********************************************************************************************************"); $cacheSystem->store('wurfl-conf', 'ver', $WURFLVersion); $cacheSystem->store('wurfl-conf', 'amfver', $VERSION); $cacheSystem->store('wurfl-conf', 'caplist', $capabilitylist); $cacheSystem->store('wurfl-conf', 'listall', $listall); $cacheSystem->store('wurfl-conf', 'RedirectTranscoderUrl', $redirecttranscoderurl); $cacheSystem->store('wurfl-conf', 'FullBrowserUrl', $fullbrowserurl); $cacheSystem->store('wurfl-conf', 'DownloadWurflURL', $downloadwurflurl); $cacheSystem->store('wurfl-conf', 'ResizeImageDirectory', $resizeimagedirectory); $cacheSystem->delete_namespace( 'WURFL-id' ); $cacheSystem->delete_namespace( 'WURFL-ua' ); } $CommonLib->printLog("This version of WURFL has $arrLen UserAgent"); $CommonLib->printLog("End loading WURFL.xml"); if ($personalwurflurl ne 'unknown') { $CommonLib->printLog("---------------------------------------------------------------------------"); if (-e "$personalwurflurl") { $CommonLib->printLog("Start loading $ENV{PersonalWurflFileName}"); if (open (IN,"$personalwurflurl")) { my $filesize= -s $personalwurflurl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parseWURFLFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$personalwurflurl"); ModPerl::Util::exit(); } $CommonLib->printLog("END loading $ENV{PersonalWurflFileName}"); close IN; } else { $CommonLib->printLog("File $personalwurflurl not found"); ModPerl::Util::exit(); } } } sub callparseWURFLFile { my ($output) = @_; my $r_id; if (open (IN,"$output")) { my $filesize= -s $output; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parseWURFLFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$output"); ModPerl::Util::exit(); } } sub parseWURFLFile { my ($record,$val) = @_; my $null=""; my $null2=""; my $null3=""; my $uagent=""; my $fb=""; my $value=""; my $id; my $name=""; my $version=""; if ($val) { $id="$val"; } if ($record =~ /\ -1 ) { $uagent=lc(substr($record,index($record,'user_agent') + 12,index($record,'"',index($record,'user_agent')+ 13)- index($record,'user_agent') - 12)); if (index($uagent,'blackberry') >-1 ) { $uagent=substr($uagent,index($uagent,'blackberry')); } ($uagent,$version)=$CommonLib->androidDetection($uagent); } if (index($record,'id') > -1 ) { $id=substr($record,index($record,'id') + 4,index($record,'"',index($record,'id')+ 5)- index($record,'id') - 4); } if (index($record,'fall_back') > -1 ) { $fb=substr($record,index($record,'fall_back') + 11,index($record,'"',index($record,'fall_back')+ 12)- index($record,'fall_back') - 11); } if (($fb) && ($id)) { $Array_fb{"$id"}=$fb; } if (($uagent) && ($id)) { my %ParseUA=$CommonLib->GetMultipleUa($uagent,$deepSearch); my $pair; my $arrUaLen = scalar %ParseUA; my $contaUA=0; my $Array_fullua_id=$uagent; foreach $pair (reverse sort { $a <=> $b } keys %ParseUA) { my $dummy=$ParseUA{$pair}; if ($Array_id{$dummy}) {} else { $Array_id{$dummy}=$id; } $contaUA=$contaUA-1; } } } if ($record =~ /\/o) { $WURFLVersion=substr($record,index($record,'') + 1,index($record,'') - 9); } return $id; } sub FallBack { my ($idToFind) = @_; my $dummy_id; my $dummy; my $dummy2; my $LOOP; my %ArrayCapFoundToPass; my $capability; foreach $capability (sort keys %Capability) { $dummy_id=$idToFind; $LOOP=0; while ($LOOP<2) { $dummy="$dummy_id|$capability"; if ($Array_DDRcapability{$dummy}) { $LOOP=2; $dummy2="$dummy_id|$capability"; $ArrayCapFoundToPass{$capability}=$Array_DDRcapability{$dummy2}; } else { if ($Array_fb{$dummy_id}) { $dummy_id=$Array_fb{$dummy_id}; } else { $dummy_id="root"; } if ($dummy_id eq "root" || $dummy_id eq "generic") { $LOOP++; } } } } return %ArrayCapFoundToPass; } sub IdentifyUAMethod { my ($UserAgent) = @_; my $ind=0; my %ArrayPM; my $pair; my $pair2; my $id_find=""; my $dummy; my $uagent_toMatch; my $near_toFind=100; my $near_toMatch; my %ArrayUAType=$CommonLib->GetMultipleUa(lc($UserAgent),$deepSearch); foreach $pair (reverse sort { $a <=> $b } keys %ArrayUAType) { my $dummy=$ArrayUAType{$pair}; if ($Array_id{$dummy}) { if (!$id_find) { $id_find=$Array_id{$dummy}; } } } return $id_find; } sub IdentifyPCUAMethod { my ($UserAgent) = @_; my $ind=0; my $id_find=""; my $pair; my $length=0; foreach $pair (sort keys %PCArray) { if ($UserAgent =~ m/$pair/) { $id_find=$PCArray{$pair}; } } if ($id_find eq "") { if ($UserAgent =~ m/safari/ && !($UserAgent =~ m/kftt/)) { $id_find='safari'; } } return $id_find; } sub handler { my $f = shift; my $capability2; my $variabile=""; my $user_agent=lc($f->headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; $ArrayCapFound{'device_claims_web_support'}='none'; $ArrayCapFound{'is_wireless_device'}='none'; my %ArrayQuery; my $var; my $mobile=0; my $version=""; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; $id=$CommonLib->readCookie($cookie); my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=lc($user_agent); if ($user_agent =~ m/blackberry/i) { $user_agent=substr($user_agent,index($user_agent,'blackberry')); $mobile=1; } if ($user_agent =~ m/up.link/i ) { $user_agent=substr($user_agent,0,index($user_agent,'up.link') - 1); $mobile=1; } ($user_agent,$version)=$CommonLib->androidDetection($user_agent); if ($cacheSystem->restore( 'wurfl-ua', $user_agent )) { # # cookie is not empty so I try to read in memory cache on my httpd cache # $id=$cacheSystem->restore( 'wurfl-ua', $user_agent ); if ($cacheSystem->restore( 'wurfl-id', $id )) { # # I'm here only for old device # my @pairs = split(/&/, $cacheSystem->restore( 'wurfl-id', $id )); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes($string_tofound => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } } else { if ($id eq "") { if ($user_agent) { my $pair; my $lcuser_agent=lc($user_agent); if ($mobile==0) { foreach $pair (%MobileArray) { if ($user_agent =~ m/$pair/i) { $mobile=1; } } if ($mobile==0) { $user_agent=$CommonLib->botDetection($user_agent); $id=IdentifyPCUAMethod($user_agent); } } if (!$id) {$id="";}; if ($id eq "") { $id=IdentifyUAMethod($user_agent); } if ($id eq "") { $id='generic_web_browser'; } else { #this check the correct version of Android if ($version) { if ($version ne 'nc') { my $lengthId=length($version); my $count=0; while($count<$lengthId) { my $idToCheck=$id."_sub".substr($version,0,length($version)-$count); if ($Array_fb{$idToCheck}) { $id=$idToCheck; $count=$lengthId; } $count++; } } } } $cacheSystem->store( 'wurfl-ua', $user_agent, $id); } } if ($id ne "") { # # device detected # if ($cacheSystem->restore( 'wurfl-id', $id )) { # # I'm here only for old device looking in cache # my @pairs = split(/&/, $cacheSystem->restore( 'wurfl-id', $id )); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes("$string_tofound" => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } else { %ArrayCapFound=FallBack($id); foreach $capability2 (sort keys %ArrayCapFound) { $variabile2="$variabile2$capability2=$ArrayCapFound{$capability2}&"; my $upper=uc($capability2); $f->subprocess_env("AMF_$upper" => $ArrayCapFound{$capability2}); $f->pnotes("$capability2" => $ArrayCapFound{$capability2}); } $variabile2="id=$id&$variabile2"; $f->subprocess_env("AMF_ID" => $id); $f->pnotes('id' => $id); $cacheSystem->store( 'wurfl-id', $id, $variabile2 ); $cacheSystem->store( 'wurfl-ua', $user_agent, $id); } if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amfID=$id; path=/;"); } } } my $amf_device_ismobile = 'true'; if (($ArrayCapFound{'device_claims_web_support'}) && ($ArrayCapFound{'device_claims_web_support'})) { if ($ArrayCapFound{'device_claims_web_support'} eq 'true' && $ArrayCapFound{'is_wireless_device'} eq 'false') { $amf_device_ismobile = 'false'; } } if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } if ($ArrayCapFound{'is_tablet'}) { $f->subprocess_env("AMF_DEVICE_IS_TABLET" => lc($ArrayCapFound{'is_tablet'})); } $f->pnotes("amf_device_ismobile" => $amf_device_ismobile); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => $amf_device_ismobile); $f->subprocess_env("AMF_VER" => $VERSION); $f->subprocess_env("AMF_WURFLVER" => $WURFLVersion); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMFWURFLFilter - The module detects the mobile device and passes the WURFL capabilities on to the other web application as environment variables =head1 DESCRIPTION Module for device detection, the cache is based on file system =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFWURFLFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut Apache2-ApacheMobileFilter-4.20/lib/Apache2/AMFWURFLFilterMemcached.pm000644 000765 000024 00000056541 13064524637 026744 0ustar00idelfuschinistaff000000 000000 #file:Apache2/AMFWURFLFilterMemcached.pm; #-------------------------------- # # Created by Idel Fuschini # Date: 01/08/10 # Site: http://www.idelfuschini.it # Mail: idel.fuschini@gmail.com package Apache2::AMFWURFLFilterMemcached; use strict; use warnings; use Apache2::AMFCommonLib (); use Apache2::RequestRec (); use Apache2::RequestUtil (); use APR::Table (); use LWP::Simple qw($ua get); use Apache2::Const -compile => qw(DECLINED); use constant BUFF_LEN => 1024; use Cache::Memcached; use Digest::MD5 qw(md5_hex); use IO::Uncompress::Unzip qw(unzip $UnzipError) ; # # Define the global environment # use vars qw($VERSION); my $CommonLib = new Apache2::AMFCommonLib (); $VERSION= "4.20"; my %Capability; my %Array_fb; my %Array_id; my %Array_fullua_id; my %Array_DDRcapability; my %MobileArray=$CommonLib->getMobileArray; my %PCArray=$CommonLib->getPCArray; my $mobileversionurl="none"; my $fullbrowserurl="none"; my $redirecttranscoder="true"; my $redirecttranscoderurl="none"; my $resizeimagedirectory="none"; my $wurflnetdownload="false"; my $downloadwurflurl="false"; my $listall="false"; my $cookiecachesystem="false"; my $WURFLVersion="unknown"; my $personalwurflurl='unknown'; my $serverMemCache; my $restmode='false'; my $deepSearch=0; my $checkVersion='false'; my $mobilenable="false"; $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("------- APACHE MOBILE FILTER V$VERSION -------"); $CommonLib->printLog("------- support http://groups.google.com/group/amf-device-detection -------"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("--- The license of the wurfl.xml file is now changed. ---"); $CommonLib->printLog("--- The WURFL file is the Copyright of ScientiaMobile, read the license ---"); $CommonLib->printLog("--- For more info: http://www.scientiamobile.com. ---"); $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("AMFWURFLFilterMemcached module Version $VERSION"); if (($ENV{AMFSetProxy}) && $ENV{AMFSetProxy} eq 'true' ) { $CommonLib->printLog("AMFSetHttpProxy is ".$ENV{AMFSetHttpProxy}); my $port=3128; my $default=""; if ($ENV{AMFSetHttpProxyPort}) { $port=$ENV{AMFSetHttpProxyPort}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetHttpProxyPort is ".$port.$default); $ua->proxy('http','http://'.$ENV{AMFSetHttpProxy}.':'.$port); } my $timeoutinsecond=5; my $default=""; if ($ENV{AMFSetGetParameterTimeoOut}) { $timeoutinsecond=$ENV{AMFSetGetParameterTimeoOut}; } else { $default=' (default)'; } $CommonLib->printLog("AMFSetGetParameterTimeoOut is ".$timeoutinsecond.'s'.$default); $ua->timeout($timeoutinsecond); if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($ENV{AMFCheckVersion}) { $checkVersion=$ENV{AMFCheckVersion}; } if ($checkVersion eq 'true') { $CommonLib->printLog("Check on apchemobilefilter.org if the installed AMF is the last version"); $CommonLib->printLog("Try to download http://www.apachemobilefilter.org/param/amf.config"); my $url="http://www.apachemobilefilter.org/param/amf.config"; my $content = get ($url); $content =~ s/\n//g; my $check_version=0; if ($content) { $check_version=$content; } if ($check_version > $VERSION && $check_version ne 0) { $CommonLib->printLog("---------------------------------------------------------------------------"); $CommonLib->printLog("----- There is a new version of AMF V$check_version online ----"); $CommonLib->printLog("---------------------------------------------------------------------------"); } else { $CommonLib->printLog("AMF installed is the last version"); } } else { $CommonLib->printLog("AMFCheckVersion is false, AMF don't check the last version."); } if ($ENV{ResizeImageDirectory}) { $Capability{'max_image_width'}="max_image_width"; $Capability{'max_image_height'}="max_image_width"; $resizeimagedirectory=$ENV{ResizeImageDirectory}; } if (($ENV{FullBrowserUrl}) || ($ENV{MobileVersionUrl})) { $Capability{'device_claims_web_support'}="device_claims_web_support"; $Capability{'is_wireless_device'}="is_wireless_device"; $fullbrowserurl=$ENV{FullBrowserUrl} } if ($ENV{RedirectTranscoderUrl}) { $Capability{'is_transcoder'}="is_transcoder"; $redirecttranscoderurl=$ENV{RedirectTranscoderUrl}; } # # Check if AMFMobileHome and CacheDirectoryStore is setting in apache httpd.conf file for example: # PerlSetEnv AMFMobileHome /MobileFilter # my $memd = new Cache::Memcached { 'debug' => 0, 'compress_threshold' => 10_000, 'enable_compress' => 1, 'namespace' => "wurfl", }; if ($ENV{ServerMemCached}) { $serverMemCache=$ENV{ServerMemCached}; my @Server = split(/,/, $ENV{ServerMemCached}); $memd->set_servers(\@Server); $CommonLib->printLog("ServerMemCached is: $serverMemCache"); } else { $CommonLib->printLog("ServerMemCached is not setted. Please set the variable ServerMemCached into httpd.conf, example \"PerlSetEnv ServerMemCached 10.10.10.10:11211\""); ModPerl::Util::exit(); } if ($ENV{AMFMobileHome}) { &loadConfigFile("$ENV{AMFMobileHome}/wurfl.xml"); } else { $CommonLib->printLog("AMFMobileHome not exist. Please set the variable AMFMobileHome into httpd.conf"); ModPerl::Util::exit(); } sub loadConfigFile { my ($fileWurfl) = @_; my $null=""; my $null2=""; my $null3=""; my $val; my $capability; my $r_id; my $dummy; #The filter $CommonLib->printLog("Start read configuration from httpd.conf"); if ($ENV{WurflNetDownload}) { if ($ENV{WurflNetDownload} eq 'true' || $ENV{WurflNetDownload} eq 'false') { $wurflnetdownload=$ENV{WurflNetDownload}; $CommonLib->printLog("WurflNetDownload is: $wurflnetdownload"); } else { $CommonLib->printLog("Error WurflNetDownload parmeter must set to true or false"); ModPerl::Util::exit(); } } if ($ENV{DownloadWurflURL}) { $downloadwurflurl=$ENV{DownloadWurflURL}; $CommonLib->printLog("DownloadWurflURL is: $downloadwurflurl"); } if ($ENV{CapabilityList}) { my @dummycapability = split(/,/, $ENV{CapabilityList}); foreach $dummy (@dummycapability) { if ($dummy eq "all") { $listall="true"; } $Capability{$dummy}=$dummy; $CommonLib->printLog("CapabilityList is: $dummy"); } } else { $listall="true"; $CommonLib->printLog('CapabilityList not setted so the default value is "all"'); } if ($ENV{AMFMobileKeys}) { my @dummyMobileKeys = split(/,/, $ENV{AMFMobileKeys}); foreach $dummy (@dummyMobileKeys) { $MobileArray{$dummy}='mobile'; } $CommonLib->printLog("AMFMobileKeys is: $ENV{AMFMobileKeys}"); } if ($ENV{AMFProductionMode}) { $cookiecachesystem=$ENV{AMFProductionMode}; $CommonLib->printLog("AMFProductionMode is: $cookiecachesystem"); } else { $CommonLib->printLog("AMFProductionMode (the CookieCacheSystem is deprecated) is not setted the default value is $cookiecachesystem"); } if ($ENV{PersonalWurflFileName}) { $personalwurflurl=$ENV{AMFMobileHome}."/".$ENV{PersonalWurflFileName}; $CommonLib->printLog("PersonalWurflFileName is: $ENV{PersonalWurflFileName}"); } if ($ENV{RestMode}) { $restmode=$ENV{RestMode}; $CommonLib->printLog("RestMode is: $restmode"); } if ($ENV{AMFDeepParse}) { $deepSearch=$ENV{AMFDeepParse}; $CommonLib->printLog("AMFDeepParse is: $deepSearch"); } else { $CommonLib->printLog("AMFDeepParse is not setted the default value is 0"); } if ($ENV{FullBrowserMobileAccessKey}) { $mobilenable="$ENV{FullBrowserMobileAccessKey}"; $CommonLib->printLog("FullBrowserMobileAccessKey is: $ENV{FullBrowserMobileAccessKey}"); $CommonLib->printLog("For access the device to fullbrowser set the link: ?$mobilenable=true"); } $CommonLib->printLog("Finish loading parameter"); $CommonLib->printLog("---------------------------------------------------------------------------"); if ($wurflnetdownload eq "true") { $CommonLib->printLog("Start process downloading WURFL.xml from $downloadwurflurl"); $CommonLib->printLog ("Test the URL"); my ($content_type, $document_length, $modified_time, $expires, $server) = head($downloadwurflurl); if ($content_type eq "") { $CommonLib->printLog("Couldn't get $downloadwurflurl."); ModPerl::Util::exit(); } else { $CommonLib->printLog("The URL is correct"); $CommonLib->printLog("The size of document wurf file: $document_length bytes"); } if ($content_type eq 'application/zip') { $CommonLib->printLog("The file is a zip file."); $CommonLib->printLog ("Start downloading"); my @dummypairs = split(/\//, $downloadwurflurl); my ($ext_zip) = $downloadwurflurl =~ /\.(\w+)$/; my $filezip=$dummypairs[-1]; my $tmp_dir=$ENV{AMFMobileHome}; $filezip="$tmp_dir/$filezip"; my $status = getstore ($downloadwurflurl,$filezip); my $output="$tmp_dir/tmp_wurfl.xml"; unzip $filezip => $output or die "unzip failed: $UnzipError\n"; # # call parseWURFLFile # callparseWURFLFile($output); } else { $CommonLib->printLog("The file is a xml file."); my $content = get ($downloadwurflurl); $content =~ s/\n//g; $content =~ s/>/>\n/g; my @rows = split(/\n/, $content); my $row; my $count=0; my $numberRow=scalar(@rows); my $progress=0; foreach my $row (@rows){ $r_id=parseWURFLFile($row,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } } $CommonLib->printLog("Finish downloading WURFL from $downloadwurflurl"); } else { if (-e "$fileWurfl") { $CommonLib->printLog("Start loading WURFL.xml"); if (open (IN,"$fileWurfl")) { my $filesize= -s $fileWurfl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @rows=split(/\n/, $string_file); my $numberRow=scalar(@rows); my $progress=0; foreach my $line (@rows) { $r_id=parseWURFLFile($line,$r_id); $progress++; my $perc=int(($progress/$numberRow)*100); print "Percent loaded: ".$perc."%\r"; } } else { $CommonLib->printLog("Error open file:$fileWurfl"); ModPerl::Util::exit(); } } else { $CommonLib->printLog("File $fileWurfl not found"); ModPerl::Util::exit(); } } close IN; my $arrLen = scalar %Array_fb; ($arrLen,$dummy)= split(/\//, $arrLen); if ($arrLen == 0) { $CommonLib->printLog("Error the file probably is not a wurfl file, control the url or path"); $CommonLib->printLog("Control also if the file is compress file, and DownloadZipFile parameter is seted false"); #ModPerl::Util::exit(); } $CommonLib->printLog("WURFL version: $WURFLVersion"); $CommonLib->printLog("This version of WURFL has $arrLen UserAgent"); $CommonLib->printLog("End loading WURFL.xml"); if ($personalwurflurl ne 'unknown') { $CommonLib->printLog("---------------------------------------------------------------------------"); if (-e "$personalwurflurl") { $CommonLib->printLog("Start loading $ENV{PersonalWurflFileName}"); if (open (IN,"$personalwurflurl")) { my $filesize= -s $personalwurflurl; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parseWURFLFile($line,$r_id); } } else { $CommonLib->printLog("Error open file:$personalwurflurl"); ModPerl::Util::exit(); } $CommonLib->printLog("END loading $ENV{PersonalWurflFileName}"); close IN; } else { $CommonLib->printLog("File $personalwurflurl not found"); ModPerl::Util::exit(); } } } sub FallBack { my ($idToFind) = @_; my $dummy_id; my $dummy; my $dummy2; my $LOOP; my %ArrayCapFoundToPass; my $capability; foreach $capability (sort keys %Capability) { $dummy_id=$idToFind; $LOOP=0; while ($LOOP<2) { $dummy="$dummy_id|$capability"; if ($Array_DDRcapability{$dummy}) { $LOOP=2; $dummy2="$dummy_id|$capability"; $ArrayCapFoundToPass{$capability}=$Array_DDRcapability{$dummy2}; } else { if ($Array_fb{$dummy_id}) { $dummy_id=$Array_fb{$dummy_id}; } else { $dummy_id="root"; } if ($dummy_id eq "root" || $dummy_id eq "generic") { $LOOP++; } } } } return %ArrayCapFoundToPass; } sub IdentifyUAMethod { my ($UserAgent) = @_; my $ind=0; my %ArrayPM; my $pair; my $pair2; my $id_find=""; my $dummy; my $uagent_toMatch; my $near_toFind=100; my $near_toMatch; my %ArrayUAType=$CommonLib->GetMultipleUa(lc($UserAgent),$deepSearch); foreach $pair (reverse sort { $a <=> $b } keys %ArrayUAType) { my $dummy=$ArrayUAType{$pair}; if ($Array_id{$dummy}) { if (!$id_find) { $id_find=$Array_id{$dummy}; } } } return $id_find; } sub IdentifyPCUAMethod { my ($UserAgent) = @_; my $ind=0; my $id_find=""; my $pair; my $length=0; foreach $pair (sort keys %PCArray) { if ($UserAgent =~ m/$pair/) { $id_find=$PCArray{$pair}; } } if ($id_find eq "") { if ($UserAgent =~ m/safari/ && !($UserAgent =~ m/kftt/)) { $id_find='safari'; } } return $id_find; } sub callparseWURFLFile { my ($output) = @_; my $r_id; if (open (IN,"$output")) { my $filesize= -s $output; my $string_file; read (IN,$string_file,$filesize); close IN; $string_file =~ s/\n//g; $string_file =~ s/>/>\n/g; my @arrayFile=split(/\n/, $string_file); foreach my $line (@arrayFile) { $r_id=parseWURFLFile($line,$r_id); } close IN; } else { $CommonLib->printLog("Error open file:$output"); ModPerl::Util::exit(); } } sub parseWURFLFile { my ($record,$val) = @_; my $null=""; my $null2=""; my $null3=""; my $uagent=""; my $fb=""; my $value=""; my $id; my $name=""; my $version=""; my $lan_sub="xx-xx"; if ($val) { $id="$val"; } if ($record =~ /\ -1 ) { $uagent=lc(substr($record,index($record,'user_agent') + 12,index($record,'"',index($record,'user_agent')+ 13)- index($record,'user_agent') - 12)); if (index($uagent,'blackberry') > -1 ) { $uagent=substr($uagent,index($uagent,'blackberry')); } ($uagent,$version)=$CommonLib->androidDetection($uagent); } if (index($record,'id') > 0 ) { $id=substr($record,index($record,'id') + 4,index($record,'"',index($record,'id')+ 5)- index($record,'id') - 4); } if (index($record,'fall_back') > 0 ) { $fb=substr($record,index($record,'fall_back') + 11,index($record,'"',index($record,'fall_back')+ 12)- index($record,'fall_back') - 11); } if (($fb) && ($id)) { $Array_fb{"$id"}=$fb; } if (($uagent) && ($id)) { my %ParseUA=$CommonLib->GetMultipleUa($uagent,$deepSearch); my $pair; my $arrUaLen = scalar %ParseUA; my $contaUA=0; my $Array_fullua_id=$uagent; foreach $pair (reverse sort { $a <=> $b } keys %ParseUA) { my $dummy=$ParseUA{$pair}; if ($Array_id{$dummy}) {} else { $Array_id{$dummy}=$id; } $contaUA=$contaUA-1; } } } if ($record =~ /\/o) { $WURFLVersion=substr($record,index($record,'') + 1,index($record,"") - 9); } return $id; } sub handler { my $f = shift; my $capability2; my $variabile=""; my $user_agent=lc($f->headers_in->{'User-Agent'}|| ''); my $x_user_agent=$f->headers_in->{'X-Device-User-Agent'}|| ''; my $x_operamini_phone_ua=$f->headers_in->{'X-OperaMini-Phone-Ua'}|| ''; my $x_operamini_ua=$f->headers_in->{'X-OperaMini-Ua'}|| ''; my $query_string=$f->args; my $docroot = $f->document_root(); my $id=""; my $location="none"; my $width_toSearch; my $type_redirect="internal"; my $return_value; my $dummy=""; my $variabile2=""; my %ArrayCapFound; my $controlCookie; my $query_img=""; $ArrayCapFound{is_transcoder}='false'; my %ArrayQuery; my $var; my $mobile=0; my $version=""; if ($user_agent eq "") { $user_agent="no useragent found"; } if ($x_user_agent) { $user_agent=lc($x_user_agent); } if ($x_operamini_phone_ua) { $user_agent=lc($x_operamini_phone_ua); } my $cookie = $f->headers_in->{Cookie} || ''; $id=$CommonLib->readCookie($cookie); my $amfFull=$CommonLib->readCookie_fullB($cookie); if ($query_string) { my @vars = split(/&/, $query_string); foreach $var (sort @vars){ if ($var) { my ($v,$i) = split(/=/, $var); $v =~ tr/+/ /; $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($i) { $i =~ tr/+/ /; $i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $i =~ s///g; $ArrayQuery{$v}=$i; } } } if (($ArrayQuery{amf}) && $restmode eq 'true') { $user_agent=lc($ArrayQuery{amf}); } if ($ArrayQuery{$mobilenable}) { $f->err_headers_out->set('Set-Cookie' => "amfFull=false; path=/;"); $amfFull='ok'; } } $user_agent=lc($user_agent); if ($user_agent =~ m/blackberry/i) { $user_agent=substr($user_agent,index($user_agent,'blackberry')); $mobile=1; } if ($user_agent =~ m/up.link/i ) { $user_agent=substr($user_agent,0,index($user_agent,'up.link') - 1); $mobile=1; } ($user_agent,$version)=$CommonLib->androidDetection($user_agent); if ($id eq ""){ if ($user_agent) { if ($mobile==0) { foreach my $pair (%MobileArray) { if ($user_agent =~ m/$pair/i) { $mobile=1; } } if ($mobile==0) { $user_agent=$CommonLib->botDetection($user_agent); $id=IdentifyPCUAMethod($user_agent); } } if (!$id) {$id="";}; if ($id eq "") { $id=IdentifyUAMethod($user_agent); } if ($id eq "") { $id='generic_web_browser'; } else { #this check the correct version of Android if ($version) { if ($version ne 'nc') { my $lengthId=length($version); my $count=0; while($count<$lengthId) { my $idToCheck=$id."_sub".substr($version,0,length($version)-$count); if ($Array_fb{$idToCheck}) { $id=$idToCheck; $count=$lengthId; } $count++; } } } } } } if ($id ne "") { # # device detected # my $var=$memd->get("WURFL_$id"); if ($var) { my @pairs = split(/&/, $var); my $param_tofound; my $string_tofound; foreach $param_tofound (@pairs) { ($string_tofound,$dummy)=split(/=/, $param_tofound); $ArrayCapFound{$string_tofound}=$dummy; my $upper2=uc($string_tofound); $f->subprocess_env("AMF_$upper2" => $ArrayCapFound{$string_tofound}); $f->pnotes("$string_tofound" => $ArrayCapFound{$string_tofound}); } $id=$ArrayCapFound{id}; } else { %ArrayCapFound=FallBack($id); foreach $capability2 (sort keys %ArrayCapFound) { $variabile2="$variabile2$capability2=$ArrayCapFound{$capability2}&"; my $upper=uc($capability2); $f->subprocess_env("AMF_$upper" => $ArrayCapFound{$capability2}); $f->pnotes("$capability2" => $ArrayCapFound{$capability2}); } $variabile2="id=$id&$variabile2"; $f->subprocess_env("AMF_ID" => $id); $f->pnotes('id' => $id); $memd->set("WURFL_$id",$variabile2); } if ($cookiecachesystem eq "true") { $f->err_headers_out->set('Set-Cookie' => "amfID=$id; path=/;"); } } my $amf_device_ismobile = 'true'; if (($ArrayCapFound{'device_claims_web_support'}) && ($ArrayCapFound{'device_claims_web_support'})) { if ($ArrayCapFound{'device_claims_web_support'} eq 'true' && $ArrayCapFound{'is_wireless_device'} eq 'false') { $amf_device_ismobile = 'false'; } } if ($amfFull ne "") { $f->subprocess_env("AMF_FORCE_TO_DESKTOP" => 'true'); $f->pnotes("amf_force_to_desktop" => 'true'); } if ($ArrayCapFound{'is_tablet'}) { $f->subprocess_env("AMF_DEVICE_IS_TABLET" => lc($ArrayCapFound{'is_tablet'})); } $f->pnotes("amf_device_ismobile" => $amf_device_ismobile); $f->subprocess_env("AMF_DEVICE_IS_MOBILE" => $amf_device_ismobile); $f->subprocess_env("AMF_VER" => $VERSION); $f->subprocess_env("AMF_WURFLVER" => $WURFLVersion); $f->headers_out->set("AMF-Ver"=> $VERSION); if ($x_operamini_ua) { $f->subprocess_env("AMF_MOBILE_BROWSER" => $x_operamini_ua); $f->pnotes("mobile_browser" => $x_operamini_ua); $f->subprocess_env("AMF_IS_TRANCODER" => 'true'); $f->pnotes("is_transcoder" => 'true'); } return Apache2::Const::DECLINED; } 1; =head1 NAME Apache2::AMFWURFLFilterMemcached - The module detects the mobile device and passes the WURFL capabilities on to the other web application as environment variables =head1 AMF PROJECT SITE http://www.apachemobilefilter.org =head1 DOCUMENTATION http://wiki.apachemobilefilter.org Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFWURFLFilter =head1 AUTHOR Idel Fuschini (idel.fuschini [at] gmail [dot] com) =head1 COPYRIGHT You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut