Merge pull request #1 from anmol26s/master
Made changes so that app works again
25
LICENSE
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
|
||||
__ ______ _ _ _____ _ _____
|
||||
\ \ / / __ \| | | | __ \| | / ____|
|
||||
\ \_/ / | | | | | | |__) | | | (___
|
||||
\ /| | | | | | | _ /| | \___ \
|
||||
| | | |__| | |__| | | \ \| |____ ____) |
|
||||
|_| \____/ \____/|_| \_\______|_____/
|
||||
|
||||
YOURLS - Your Own URL Shortener
|
||||
|
||||
Copyright (c) 2009-2017 by the contributors
|
||||
|
||||
This program is free software. Do whatever the hell you want with it.
|
||||
|
||||
This program is distributed under the terms of the MIT license, in the hope that it will be useful and/or fun to use. There is absolutely no guarantee of any kind about anything.
|
||||
|
||||
Wherever third party code has been used, credit has been given in the code comments.
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
7
README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
<h1>What is YOURLS?</h1>
|
||||
<p>YOURLS stands for Your Own URL Shortener. It is a small set of PHP scripts that will allow you to run your own URL shortening service (a la TinyURL or bitly).</p>
|
||||
|
||||
<p>Running your own URL shortener is fun, geeky and useful: you own your data and don't depend on third party services. It's also a great way to add branding to your short URLs, instead of using the same public URL shortener everyone uses.</p><br>
|
||||
<strong>For more information see:</strong>https://yourls.org/ <br>
|
||||
<strong>Github:</strong>https://github.com/YOURLS/YOURLS <br>
|
||||
<strong>Version:</strong>1.7.2
|
36
check_process
Normal file
|
@ -0,0 +1,36 @@
|
|||
# See here for more informations
|
||||
# https://github.com/YunoHost/package_check#syntax-check_process-file
|
||||
;; Test complet
|
||||
; Manifest
|
||||
domain="domain.tld" (DOMAIN)
|
||||
path="/path" (PATH)
|
||||
admin="john" (USER)
|
||||
; Checks
|
||||
pkg_linter=1
|
||||
setup_sub_dir=1
|
||||
setup_root=1
|
||||
setup_nourl=0
|
||||
setup_private=0
|
||||
setup_public=0
|
||||
upgrade=1
|
||||
backup_restore=1
|
||||
multi_instance=0
|
||||
incorrect_path=1
|
||||
port_already_use=0
|
||||
change_url=0
|
||||
;;; Levels
|
||||
Level 1=auto
|
||||
Level 2=auto
|
||||
Level 3=auto
|
||||
# Level 4:
|
||||
Level 4=0
|
||||
# Level 5:
|
||||
Level 5=auto
|
||||
Level 6=auto
|
||||
Level 7=auto
|
||||
Level 8=0
|
||||
Level 9=0
|
||||
Level 10=0
|
||||
;;; Options
|
||||
Email=anmol@datamol.in
|
||||
Notification=none
|
6
conf/app.src
Normal file
|
@ -0,0 +1,6 @@
|
|||
SOURCE_URL=https://github.com/YOURLS/YOURLS/archive/1.7.2.zip
|
||||
SOURCE_SUM=77c021774797f2afefe3a90ce99d048d
|
||||
SOURCE_SUM_PRG=md5sum
|
||||
SOURCE_FORMAT=zip
|
||||
SOURCE_IN_SUBDIR=true
|
||||
SOURCE_FILENAME=
|
|
@ -32,13 +32,13 @@ define( 'YOURLS_DB_PREFIX', 'yourls_' );
|
|||
define( 'YOURLS_SITE', 'https://yunodomain_yourlspath' );
|
||||
|
||||
/** Timezone GMT offset */
|
||||
define( 'YOURLS_HOURS_OFFSET', 0 );
|
||||
define( 'YOURLS_HOURS_OFFSET', 0 );
|
||||
|
||||
/** YOURLS language or "locale".
|
||||
** Change this setting to "localize" YOURLS (use a translation instead of the default English). A corresponding .mo file
|
||||
** must be installed in the user/language directory.
|
||||
** See http://yourls.org/translations for more information */
|
||||
define( 'YOURLS_LANG', '' );
|
||||
define( 'YOURLS_LANG', '' );
|
||||
|
||||
/** Allow multiple short URLs for a same long URL
|
||||
** Set to true to have only one pair of shortURL/longURL (default YOURLS behavior)
|
||||
|
@ -62,7 +62,7 @@ $yourls_user_passwords = array(
|
|||
/** Debug mode to output some internal information
|
||||
** Default is false for live site. Enable when coding or before submitting a new issue */
|
||||
define( 'YOURLS_DEBUG', false );
|
||||
|
||||
|
||||
/*
|
||||
** URL Shortening settings
|
||||
*/
|
||||
|
@ -75,7 +75,7 @@ define( 'YOURLS_URL_CONVERT', 36 );
|
|||
* Stick to one setting. It's best not to change after you've started creating links.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Reserved keywords (so that generated URLs won't match them)
|
||||
* Define here negative, unwanted or potentially misleading keywords.
|
||||
*/
|
||||
|
@ -88,4 +88,3 @@ $yourls_reserved_URL = array(
|
|||
*/
|
||||
|
||||
define( 'YOURLS_YUNOHOST_AUTH_ADMIN', 'yourlsuser' );
|
||||
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
location LOCATIONTOCHANGE {
|
||||
alias ALIASTOCHANGE/;
|
||||
|
||||
try_files $uri $uri/ PATHTOCHANGE/yourls-loader.php;
|
||||
|
||||
if ($scheme = http) {
|
||||
rewrite ^ https://$server_name$request_uri? permanent;
|
||||
}
|
||||
|
||||
try_files $uri $uri/ PATHTOCHANGE/yourls-loader.php;
|
||||
|
||||
|
||||
index index.php index.html index.htm;
|
||||
|
||||
location ~ [^/]\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param REMOTE_USER $remote_user;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
}
|
||||
|
||||
|
||||
location ~ [^/]\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param REMOTE_USER $remote_user;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
}
|
||||
|
||||
|
||||
# Include SSOWAT user panel.
|
||||
include conf.d/yunohost_panel.conf.inc;
|
||||
}
|
||||
|
|
|
@ -5,16 +5,26 @@
|
|||
"en": "An URL shortening service",
|
||||
"fr": "Un service de raccourcisseur d'url"
|
||||
},
|
||||
"url": "https://github.com/YOURLS/YOURLS",
|
||||
"license": "free",
|
||||
"developer": {
|
||||
"name": "courgette",
|
||||
"email": "courgette@farcie.fr",
|
||||
"url": "http://thomaslebeau.fr"
|
||||
"name": "Anmol Sharma",
|
||||
"email": "anmol@datamol.in"
|
||||
},
|
||||
"requirements": {
|
||||
"yunohost": ">> 2.5.6"
|
||||
},
|
||||
"multi_instance": "false",
|
||||
"services": [
|
||||
"nginx",
|
||||
"php5-fpm",
|
||||
"mysql"
|
||||
],
|
||||
"arguments": {
|
||||
"install" : [
|
||||
{
|
||||
"name": "domain",
|
||||
"type": "domain",
|
||||
"ask": {
|
||||
"en": "Choose a domain for Yourls",
|
||||
"fr": "Choisissez un domaine pour Yourls"
|
||||
|
@ -23,6 +33,7 @@
|
|||
},
|
||||
{
|
||||
"name": "path",
|
||||
"type": "path",
|
||||
"ask": {
|
||||
"en": "Choose a path for Yourls",
|
||||
"fr": "Choisissez un chemin pour Yourls"
|
||||
|
@ -32,6 +43,7 @@
|
|||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"type": "user",
|
||||
"ask": {
|
||||
"en": "Choose the Yourls administrator (must be an existing YunoHost user)",
|
||||
"fr": "Administrateur du site Yourls (doit être un utilisateur Yunohost existant)"
|
||||
|
|
112
scripts/_common.sh
Normal file
|
@ -0,0 +1,112 @@
|
|||
#!/bin/bash
|
||||
|
||||
# =============================================================================
|
||||
# YUNOHOST 2.7 FORTHCOMING HELPERS
|
||||
# =============================================================================
|
||||
|
||||
# Create a dedicated nginx config
|
||||
#
|
||||
# usage: ynh_add_nginx_config
|
||||
ynh_add_nginx_config () {
|
||||
finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||
ynh_backup_if_checksum_is_different "$finalnginxconf" 1
|
||||
sudo cp ../conf/nginx.conf "$finalnginxconf"
|
||||
|
||||
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
||||
# Substitute in a nginx config file only if the variable is not empty
|
||||
if test -n "${path_url:-}"; then
|
||||
ynh_replace_string "__PATH__" "$path_url" "$finalnginxconf"
|
||||
fi
|
||||
if test -n "${domain:-}"; then
|
||||
ynh_replace_string "__DOMAIN__" "$domain" "$finalnginxconf"
|
||||
fi
|
||||
if test -n "${port:-}"; then
|
||||
ynh_replace_string "__PORT__" "$port" "$finalnginxconf"
|
||||
fi
|
||||
if test -n "${app:-}"; then
|
||||
ynh_replace_string "__NAME__" "$app" "$finalnginxconf"
|
||||
fi
|
||||
if test -n "${final_path:-}"; then
|
||||
ynh_replace_string "__FINALPATH__" "$final_path" "$finalnginxconf"
|
||||
fi
|
||||
ynh_store_checksum_config "$finalnginxconf"
|
||||
|
||||
sudo systemctl reload nginx
|
||||
}
|
||||
|
||||
# Remove the dedicated nginx config
|
||||
#
|
||||
# usage: ynh_remove_nginx_config
|
||||
ynh_remove_nginx_config () {
|
||||
ynh_secure_remove "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||
sudo systemctl reload nginx
|
||||
}
|
||||
|
||||
# Create a dedicated php-fpm config
|
||||
#
|
||||
# usage: ynh_add_fpm_config
|
||||
ynh_add_fpm_config () {
|
||||
finalphpconf="/etc/php5/fpm/pool.d/$app.conf"
|
||||
ynh_backup_if_checksum_is_different "$finalphpconf" 1
|
||||
sudo cp ../conf/php-fpm.conf "$finalphpconf"
|
||||
ynh_replace_string "__NAMETOCHANGE__" "$app" "$finalphpconf"
|
||||
ynh_replace_string "__FINALPATH__" "$final_path" "$finalphpconf"
|
||||
ynh_replace_string "__USER__" "$app" "$finalphpconf"
|
||||
sudo chown root: "$finalphpconf"
|
||||
ynh_store_file_checksum "$finalphpconf"
|
||||
|
||||
if [ -e "../conf/php-fpm.ini" ]
|
||||
then
|
||||
finalphpini="/etc/php5/fpm/conf.d/20-$app.ini"
|
||||
ynh_compare_checksum_config "$finalphpini" 1
|
||||
sudo cp ../conf/php-fpm.ini "$finalphpini"
|
||||
sudo chown root: "$finalphpini"
|
||||
ynh_store_checksum_config "$finalphpini"
|
||||
fi
|
||||
|
||||
sudo systemctl reload php5-fpm
|
||||
}
|
||||
|
||||
# Remove the dedicated php-fpm config
|
||||
#
|
||||
# usage: ynh_remove_fpm_config
|
||||
ynh_remove_fpm_config () {
|
||||
ynh_secure_remove "/etc/php5/fpm/pool.d/$app.conf"
|
||||
ynh_secure_remove "/etc/php5/fpm/conf.d/20-$app.ini" 2>&1
|
||||
sudo systemctl reload php5-fpm
|
||||
}
|
||||
|
||||
# Create a dedicated systemd config
|
||||
#
|
||||
# usage: ynh_add_systemd_config
|
||||
ynh_add_systemd_config () {
|
||||
finalsystemdconf="/etc/systemd/system/$app.service"
|
||||
ynh_compare_checksum_config "$finalsystemdconf" 1
|
||||
sudo cp ../conf/systemd.service "$finalsystemdconf"
|
||||
|
||||
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
||||
# Substitute in a nginx config file only if the variable is not empty
|
||||
if test -n "${final_path:-}"; then
|
||||
ynh_replace_string "__FINALPATH__" "$final_path" "$finalsystemdconf"
|
||||
fi
|
||||
if test -n "${app:-}"; then
|
||||
ynh_replace_string "__APP__" "$app" "$finalsystemdconf"
|
||||
fi
|
||||
ynh_store_checksum_config "$finalsystemdconf"
|
||||
|
||||
sudo chown root: "$finalsystemdconf"
|
||||
sudo systemctl enable $app
|
||||
sudo systemctl daemon-reload
|
||||
}
|
||||
|
||||
# Remove the dedicated systemd config
|
||||
#
|
||||
# usage: ynh_remove_systemd_config
|
||||
ynh_remove_systemd_config () {
|
||||
finalsystemdconf="/etc/systemd/system/$app.service"
|
||||
if [ -e "$finalsystemdconf" ]; then
|
||||
sudo systemctl stop $app
|
||||
sudo systemctl disable $app
|
||||
ynh_secure_remove "$finalsystemdconf"
|
||||
fi
|
||||
}
|
54
scripts/backup
Normal file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
|
||||
#=================================================
|
||||
# GENERIC START
|
||||
#=================================================
|
||||
# MANAGE SCRIPT FAILURE
|
||||
#=================================================
|
||||
|
||||
# Exit on command errors and treat access to unset variables as an error
|
||||
set -eu
|
||||
|
||||
#=================================================
|
||||
# IMPORT GENERIC HELPERS
|
||||
#=================================================
|
||||
|
||||
if [ ! -e _common.sh ]; then
|
||||
# Get the _common.sh file if it's not in the current directory
|
||||
sudo cp ../settings/scripts/_common.sh ./_common.sh
|
||||
sudo chmod a+rx _common.sh
|
||||
fi
|
||||
source _common.sh
|
||||
source /usr/share/yunohost/helpers
|
||||
|
||||
#=================================================
|
||||
# LOAD SETTINGS
|
||||
#=================================================
|
||||
|
||||
app=$YNH_APP_INSTANCE_NAME
|
||||
|
||||
final_path=$(ynh_app_setting_get $app final_path)
|
||||
domain=$(ynh_app_setting_get $app domain)
|
||||
db_name=$(ynh_app_setting_get $app db_name)
|
||||
db_pwd=$(ynh_app_setting_get $app mysqlpwd)
|
||||
|
||||
#=================================================
|
||||
# STANDARD BACKUP STEPS
|
||||
#=================================================
|
||||
# BACKUP THE APP MAIN DIR
|
||||
#=================================================
|
||||
|
||||
ynh_backup "$final_path" "$final_path"
|
||||
|
||||
#=================================================
|
||||
# BACKUP THE NGINX CONFIGURATION
|
||||
#=================================================
|
||||
|
||||
ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||
|
||||
|
||||
#=================================================
|
||||
# BACKUP THE MYSQL DATABASE
|
||||
#=================================================
|
||||
|
||||
ynh_mysql_dump_db "$db_name" > db.sql
|
120
scripts/install
|
@ -1,40 +1,81 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Retrieve arguments
|
||||
domain=$1
|
||||
path=$2
|
||||
admin_user=$3
|
||||
#=================================================
|
||||
# GENERIC START
|
||||
#=================================================
|
||||
# IMPORT GENERIC HELPERS
|
||||
#=================================================
|
||||
|
||||
# Check domain/path availability
|
||||
sudo yunohost app checkurl $domain$path -a yourls
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
source _common.sh
|
||||
source /usr/share/yunohost/helpers
|
||||
|
||||
# Check that admin user is an existing account
|
||||
sudo yunohost user list --json | grep -qi "\"username\": \"$admin_user\""
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
echo "Error : the chosen admin user does not exist"
|
||||
exit 1
|
||||
fi
|
||||
# Save admin user
|
||||
sudo yunohost app setting yourls admin -v $admin_user
|
||||
#=================================================
|
||||
# MANAGE SCRIPT FAILURE
|
||||
#=================================================
|
||||
|
||||
# Generate random password
|
||||
db_pwd=$(dd if=/dev/urandom bs=1 count=200 2> /dev/null | tr -c -d 'A-Za-z0-9' | sed -n 's/\(.\{24\}\).*/\1/p')
|
||||
# Exit if an error occurs during the execution of the script
|
||||
ynh_abort_if_errors
|
||||
|
||||
# Use 'yourls' as database name and user
|
||||
db_user=yourls
|
||||
#=================================================
|
||||
# RETRIEVE ARGUMENTS FROM THE MANIFEST
|
||||
#=================================================
|
||||
|
||||
# Initialize database and store mysql password for upgrade
|
||||
sudo yunohost app initdb $db_user -p $db_pwd
|
||||
sudo yunohost app setting yourls mysqlpwd -v $db_pwd
|
||||
domain=$YNH_APP_ARG_DOMAIN
|
||||
path_url=$YNH_APP_ARG_PATH
|
||||
admin=$YNH_APP_ARG_ADMIN
|
||||
|
||||
# This is a multi-instance app, meaning it can be installed several times independently
|
||||
# The id of the app as stated in the manifest is available as $YNH_APP_ID
|
||||
# The instance number is available as $YNH_APP_INSTANCE_NUMBER (equals "1", "2", ...)
|
||||
# The app instance name is available as $YNH_APP_INSTANCE_NAME
|
||||
# - the first time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample
|
||||
# - the second time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample__2
|
||||
# - ynhexample__{N} for the subsequent installations, with N=3,4, ...
|
||||
# The app instance name is probably what you are interested the most, since this is
|
||||
# guaranteed to be unique. This is a good unique identifier to define installation path,
|
||||
# db names, ...
|
||||
app=$YNH_APP_INSTANCE_NAME
|
||||
|
||||
#=================================================
|
||||
# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
|
||||
#=================================================
|
||||
|
||||
# Normalize the url path syntax
|
||||
path_url=$(ynh_normalize_url_path $path_url)
|
||||
# Check web path availability
|
||||
ynh_webpath_available $domain $path_url
|
||||
# Register (book) web path
|
||||
ynh_webpath_register $app $domain $path_url
|
||||
|
||||
final_path=/var/www/$app
|
||||
test ! -e "$final_path" || ynh_die "This path already contains a folder"
|
||||
|
||||
#=================================================
|
||||
# STORE SETTINGS FROM MANIFEST
|
||||
#=================================================
|
||||
|
||||
ynh_app_setting_set $app domain $domain
|
||||
ynh_app_setting_set $app path $path_url
|
||||
ynh_app_setting_set $app admin $admin
|
||||
|
||||
#=================================================
|
||||
# CREATE A MYSQL DATABASE
|
||||
#=================================================
|
||||
# If your app uses a MySQL database, you can use these lines to bootstrap
|
||||
# a database, an associated user and save the password in app settings
|
||||
|
||||
db_name=$(ynh_sanitize_dbid $app)
|
||||
ynh_app_setting_set $app db_name $db_name
|
||||
ynh_mysql_setup_db $db_name $db_name
|
||||
|
||||
#=================================================
|
||||
# DOWNLOAD, CHECK AND UNPACK SOURCE
|
||||
#=================================================
|
||||
|
||||
ynh_app_setting_set $app final_path $final_path
|
||||
# Download, check integrity, uncompress and patch the source from app.src
|
||||
ynh_setup_source "$final_path"
|
||||
|
||||
# Copy files to the right place
|
||||
final_path=/var/www/yourls
|
||||
sudo mkdir -p $final_path
|
||||
sudo cp -a ../sources/* $final_path
|
||||
|
||||
sudo cp ../conf/index.php $final_path/
|
||||
sudo cp -r ../conf/yunohost_auth $final_path/user/plugins
|
||||
|
@ -42,36 +83,37 @@ sudo cp -r ../conf/yunohost_auth $final_path/user/plugins
|
|||
|
||||
# Change variable in yourls configuration
|
||||
sudo cp ../conf/config.php $final_path/user/config.php
|
||||
sudo sed -i "s/yunouser/$db_user/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunouser/$db_name/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunopass/$db_pwd/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunobase/$db_user/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunobase/$db_name/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunodomain/$domain/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yourlsuser/$admin_user/g" $final_path/user/config.php
|
||||
sudo sed -i "s@_yourlspath@$path@g" $final_path/user/config.php
|
||||
sudo sed -i "s/yourlsuser/$admin/g" $final_path/user/config.php
|
||||
sudo sed -i "s@_yourlspath@${path_url%/}@g" $final_path/user/config.php
|
||||
|
||||
# Set permissions
|
||||
sudo chown -R www-data: $final_path
|
||||
|
||||
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||
sed -i "s@LOCATIONTOCHANGE@$path@g" ../conf/nginx.conf*
|
||||
sed -i "s@PATHTOCHANGE@${path%/}@g" ../conf/nginx.conf*
|
||||
sed -i "s@LOCATIONTOCHANGE@$path_url@g" ../conf/nginx.conf*
|
||||
sed -i "s@PATHTOCHANGE@${path_url%/}@g" ../conf/nginx.conf*
|
||||
sed -i "s@DOMAINTOCHANGE@$domain@g" ../conf/nginx.conf*
|
||||
sed -i "s@ALIASTOCHANGE@$final_path@g" ../conf/nginx.conf*
|
||||
nginxconf=/etc/nginx/conf.d/$domain.d/yourls.conf
|
||||
nginxconf=/etc/nginx/conf.d/$domain.d/$app.conf
|
||||
sudo cp ../conf/nginx.conf $nginxconf
|
||||
sudo chown root: $nginxconf
|
||||
sudo chmod 600 $nginxconf
|
||||
|
||||
# Reload Nginx and regenerate SSOwat conf
|
||||
sudo service nginx reload
|
||||
sudo yunohost app setting yourls unprotected_uris -v "/"
|
||||
sudo yunohost app setting $app unprotected_uris -v "/"
|
||||
sudo yunohost app ssowatconf
|
||||
|
||||
# Start Yourls install (database table creation)
|
||||
curl --header "Host: $domain" -kL -X POST https://127.0.0.1$path/admin/install.php --data "install=Install+YOURLS" > /dev/null 2>&1
|
||||
curl -kL -X POST https://$domain$path_url/admin/install.php --data "install=dummy" > /dev/null 2>&1
|
||||
|
||||
# Activate auth plugin
|
||||
mysql -u $db_user -p$db_pwd $db_user < ../conf/activate_plugins.sql
|
||||
sudo yunohost app setting yourls protected_uris -v "/admin"
|
||||
ynh_mysql_connect_as "$db_name" "$db_pwd" "$db_name" < "../conf/activate_plugins.sql"
|
||||
|
||||
|
||||
sudo service nginx reload
|
||||
sudo yunohost app ssowatconf
|
||||
|
|
|
@ -1,11 +1,37 @@
|
|||
#!/bin/bash
|
||||
|
||||
db_user=yourls
|
||||
db_name=yourls
|
||||
root_pwd=$(sudo cat /etc/yunohost/mysql)
|
||||
domain=$(sudo yunohost app setting yourls domain)
|
||||
#=================================================
|
||||
# GENERIC START
|
||||
#=================================================
|
||||
# IMPORT GENERIC HELPERS
|
||||
#=================================================
|
||||
|
||||
mysql -u root -p$root_pwd -e "DROP DATABASE $db_name ; DROP USER $db_user@localhost ;"
|
||||
source _common.sh
|
||||
source /usr/share/yunohost/helpers
|
||||
|
||||
sudo rm -rf /var/www/yourls
|
||||
sudo rm -f /etc/nginx/conf.d/$domain.d/yourls.conf
|
||||
#=================================================
|
||||
# LOAD SETTINGS
|
||||
#=================================================
|
||||
|
||||
app=$YNH_APP_INSTANCE_NAME
|
||||
|
||||
domain=$(ynh_app_setting_get $app domain)
|
||||
db_name=$(ynh_app_setting_get $app db_name)
|
||||
|
||||
# Remove a database if it exists, along with the associated user
|
||||
ynh_mysql_remove_db $db_name $db_name
|
||||
|
||||
#=================================================
|
||||
# REMOVE APP MAIN DIR
|
||||
#=================================================
|
||||
|
||||
# Remove the app directory securely
|
||||
ynh_secure_remove "/var/www/$app"
|
||||
|
||||
|
||||
#=================================================
|
||||
# REMOVE NGINX CONFIGURATION
|
||||
#=================================================
|
||||
|
||||
# Remove the dedicated nginx config
|
||||
ynh_remove_nginx_config
|
||||
|
|
77
scripts/restore
Normal file
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
|
||||
#=================================================
|
||||
# GENERIC START
|
||||
#=================================================
|
||||
# MANAGE SCRIPT FAILURE
|
||||
#=================================================
|
||||
|
||||
# Exit on command errors and treat access to unset variables as an error
|
||||
set -eu
|
||||
|
||||
#=================================================
|
||||
# IMPORT GENERIC HELPERS
|
||||
#=================================================
|
||||
|
||||
if [ ! -e _common.sh ]; then
|
||||
# Get the _common.sh file if it's not in the current directory
|
||||
sudo cp ../settings/scripts/_common.sh ./_common.sh
|
||||
sudo chmod a+rx _common.sh
|
||||
fi
|
||||
source _common.sh
|
||||
source /usr/share/yunohost/helpers
|
||||
|
||||
#=================================================
|
||||
# LOAD SETTINGS
|
||||
#=================================================
|
||||
|
||||
app=$YNH_APP_INSTANCE_NAME
|
||||
|
||||
domain=$(ynh_app_setting_get $app domain)
|
||||
path_url=$(ynh_app_setting_get $app path)
|
||||
final_path=$(ynh_app_setting_get $app final_path)
|
||||
db_name=$(ynh_app_setting_get $app db_name)
|
||||
|
||||
#=================================================
|
||||
# CHECK IF THE APP CAN BE RESTORED
|
||||
#=================================================
|
||||
|
||||
sudo yunohost app checkurl "${domain}${path_url}" -a "$app" \
|
||||
|| ynh_die "Path not available: ${domain}${path_url}"
|
||||
test ! -d $final_path \
|
||||
|| ynh_die "There is already a directory: $final_path "
|
||||
|
||||
#=================================================
|
||||
# STANDARD RESTORATION STEPS
|
||||
#=================================================
|
||||
# RESTORE THE NGINX CONFIGURATION
|
||||
#=================================================
|
||||
|
||||
ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||
|
||||
#=================================================
|
||||
# RESTORE THE APP MAIN DIR
|
||||
#=================================================
|
||||
|
||||
ynh_restore_file "$final_path"
|
||||
sudo chown -R www-data: $final_path
|
||||
|
||||
|
||||
#=================================================
|
||||
# RESTORE THE MYSQL DATABASE
|
||||
#=================================================
|
||||
|
||||
db_pwd=$(ynh_app_setting_get $app mysqlpwd)
|
||||
ynh_mysql_setup_db $db_name $db_name $db_pwd
|
||||
ynh_mysql_connect_as $db_name $db_pwd $db_name < ./db.sql
|
||||
|
||||
|
||||
#=================================================
|
||||
# GENERIC FINALIZATION
|
||||
#=================================================
|
||||
# RELOAD NGINX AND PHP-FPM
|
||||
#=================================================
|
||||
sudo yunohost app setting $app unprotected_uris -v "/"
|
||||
|
||||
sudo systemctl reload php5-fpm
|
||||
sudo systemctl reload nginx
|
|
@ -1,47 +1,84 @@
|
|||
#!/bin/bash
|
||||
|
||||
#=================================================
|
||||
# GENERIC START
|
||||
#=================================================
|
||||
# IMPORT GENERIC HELPERS
|
||||
#=================================================
|
||||
|
||||
# Retrieve arguments
|
||||
domain=$(sudo yunohost app setting yourls domain)
|
||||
path=$(sudo yunohost app setting yourls path)
|
||||
db_user=yourls
|
||||
db_pwd=$(sudo yunohost app setting yourls mysqlpwd)
|
||||
admin_user=$(sudo yunohost app setting yourls admin)
|
||||
source _common.sh
|
||||
source /usr/share/yunohost/helpers
|
||||
|
||||
#=================================================
|
||||
# LOAD SETTINGS
|
||||
#=================================================
|
||||
|
||||
app=$YNH_APP_INSTANCE_NAME
|
||||
|
||||
domain=$(ynh_app_setting_get $app domain)
|
||||
path_url=$(ynh_app_setting_get $app path)
|
||||
admin=$(ynh_app_setting_get $app admin)
|
||||
final_path=$(ynh_app_setting_get $app final_path)
|
||||
db_name=$(ynh_app_setting_get $app db_name)
|
||||
|
||||
|
||||
# Copy files to the right place
|
||||
final_path=/var/www/yourls
|
||||
sudo mkdir -p $final_path
|
||||
sudo cp -a ../sources/* $final_path
|
||||
|
||||
sudo cp ../conf/index.php $final_path/
|
||||
sudo cp -r ../conf/yunohost_auth $final_path/user/plugins
|
||||
if [ -z $db_name ]; then # If db_name doesn't exist, create it
|
||||
db_name=$(ynh_sanitize_dbid $app)
|
||||
ynh_app_setting_set $app db_name $db_name
|
||||
fi
|
||||
|
||||
#=================================================
|
||||
# CHECK THE PATH
|
||||
#=================================================
|
||||
|
||||
# Change variable in yourls configuration
|
||||
sudo cp ../conf/config.php $final_path/user/config.php
|
||||
sudo sed -i "s/yunouser/$db_user/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunopass/$db_pwd/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunobase/$db_user/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yunodomain/$domain/g" $final_path/user/config.php
|
||||
sudo sed -i "s/yourlsuser/$admin_user/g" $final_path/user/config.php
|
||||
sudo sed -i "s@_yourlspath@$path@g" $final_path/user/config.php
|
||||
# Normalize the URL path syntax
|
||||
path_url=$(ynh_normalize_url_path $path_url)
|
||||
|
||||
# Set permissions
|
||||
#=================================================
|
||||
# STANDARD UPGRADE STEPS
|
||||
#=================================================
|
||||
# DOWNLOAD, CHECK AND UNPACK SOURCE
|
||||
#=================================================
|
||||
sudo mv ${final_path} ${final_path}.old
|
||||
|
||||
# Download, check integrity, uncompress and patch the source from app.src
|
||||
ynh_setup_source "$final_path"
|
||||
sudo cp -a ${final_path}.old/index.php ${final_path}
|
||||
sudo cp -a ${final_path}.old/user/plugins/yunohost_auth ${final_path}/user/plugins
|
||||
sudo cp -a ${final_path}.old/.htaccess ${final_path}
|
||||
sudo cp -a ${final_path}.old/user/config.php ${final_path}/user
|
||||
sudo chown -R www-data: $final_path
|
||||
|
||||
# delete temp directory
|
||||
sudo rm -Rf ${final_path}.old
|
||||
|
||||
#=================================================
|
||||
# NGINX CONFIGURATION
|
||||
#=================================================
|
||||
|
||||
# Create a dedicated nginx config
|
||||
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||
sed -i "s@LOCATIONTOCHANGE@$path@g" ../conf/nginx.conf*
|
||||
sed -i "s@PATHTOCHANGE@${path%/}@g" ../conf/nginx.conf*
|
||||
sed -i "s@LOCATIONTOCHANGE@$path_url@g" ../conf/nginx.conf*
|
||||
sed -i "s@PATHTOCHANGE@${path_url%/}@g" ../conf/nginx.conf*
|
||||
sed -i "s@DOMAINTOCHANGE@$domain@g" ../conf/nginx.conf*
|
||||
sed -i "s@ALIASTOCHANGE@$final_path@g" ../conf/nginx.conf*
|
||||
nginxconf=/etc/nginx/conf.d/$domain.d/yourls.conf
|
||||
nginxconf=/etc/nginx/conf.d/$domain.d/$app.conf
|
||||
sudo cp ../conf/nginx.conf $nginxconf
|
||||
sudo chown root: $nginxconf
|
||||
sudo chmod 600 $nginxconf
|
||||
|
||||
# Reload Nginx and regenerate SSOwat conf
|
||||
sudo service nginx reload
|
||||
sudo yunohost app setting yourls unprotected_uris -v "/"
|
||||
sudo yunohost app ssowatconf
|
||||
|
||||
#=================================================
|
||||
# SETUP SSOWAT
|
||||
#=================================================
|
||||
|
||||
|
||||
ynh_app_setting_set $app unprotected_uris "/"
|
||||
|
||||
|
||||
#=================================================
|
||||
# RELOAD NGINX
|
||||
#=================================================
|
||||
|
||||
sudo systemctl reload nginx
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
YOURLS Changelog
|
||||
================
|
||||
|
||||
_This file lists the main changes through all versions of YOURLS.
|
||||
For a much more detailed list, simply refer to [commit messages](https://github.com/YOURLS/YOURLS/commits/master)._
|
||||
|
||||
1.7
|
||||
---
|
||||
- added: support for PDO and MySQLi
|
||||
- added: social bookmarklets - share on Twitter, Facebook or Tumblr in a click
|
||||
- added: check api.yourls.org if a new version of YOURLS is available
|
||||
- added: proxy support - install YOURLS behind a firewall!
|
||||
- improved: security regarding SQL injections
|
||||
- improved: security regarding your credentials - now auto-encrypted
|
||||
- improved: external HTTP request handling
|
||||
- improved: ƒυηкƴ UTF-8 titles handling
|
||||
- fixed: compatibility with Apache mod_security blocking bookmarklets
|
||||
- fixed: lots of bugs
|
||||
|
||||
1.6
|
||||
---
|
||||
- added: مرحبا العالم! Hej verden! 你好世界! Kumusta mundo! Ciao mondo! Hello world! Translation API.
|
||||
- added: custom API actions
|
||||
- added: support for URLs with common protocols
|
||||
- fixed: search and pagination in the admin interface
|
||||
- updated: third party libs jQuery, ezSQL, GeoIP
|
||||
- improved: sanitizing and escaping functions
|
||||
|
||||
1.5.1
|
||||
-----
|
||||
- added: full jsonp support
|
||||
- added: ability to use encrypted passwords in the config file
|
||||
- fixed: support for http://www.sho.rt/bleh and http://sho.rt/bleh
|
||||
- added: support for any favicon dropped in the /user directory
|
||||
- updated: Google Visualization API instead of deprecated Google Charts
|
||||
- fixed: bugs, bugs, bugs
|
||||
- added: hooks, hooks, hooks
|
||||
- improved: things, things, things
|
||||
|
||||
1.5
|
||||
---
|
||||
- added: plugin architecture! OMG plugins!!1!!1!
|
||||
- added: directory /user, config.php can be moved there
|
||||
- added: new "instant bookmarklets"
|
||||
- added: 1 click copy-to-clipboard a la bitly
|
||||
- change in logic: now all request are handled by PHP and don't rely on .htaccess
|
||||
- added: saving URL titles
|
||||
- added: support for prefix-n-shorten: sho.rt/http://example.com/
|
||||
- added: core plugin to allow hyphens in URLs
|
||||
- added: core sample plugin to wrap redirected URLs in a social toolbar
|
||||
- added: core sample plugin to show how to create administration page in plugins
|
||||
- added: core plugin to display a random pretty background
|
||||
- changed: layout now using a more consistent palette, see http://yourls.org/palette
|
||||
- added: anti XSS and anti CSRF measures
|
||||
- added: interactive map if possible in stat traffic by countries
|
||||
- fixed: lots of bugs
|
||||
|
||||
1.4.3
|
||||
-----
|
||||
- fixed bug no-stats-showing-ffs due to inconsistency in DB schema
|
||||
- improve error reporting with API method url-stat
|
||||
|
||||
1.4.2
|
||||
-----
|
||||
- fixed: bug in auth function
|
||||
- added: sample public API file
|
||||
- added: check in API requests for WordPress plugin when adding a new short URL
|
||||
- prettier sample public interface
|
||||
|
||||
1.4.1
|
||||
-----
|
||||
- fixed: base 62 URLs (keywords with MiXeD CaSe)
|
||||
- new & secure auth method for API calls, with no need to use login & password combo
|
||||
- allow SSL enforcement for admin pages
|
||||
- new API method: stats for individual URL.
|
||||
- prevent internal redirection loops
|
||||
- filter and search URLs & short URLs by date
|
||||
|
||||
1.4
|
||||
---
|
||||
- added: an upgrader from 1.3 to 1.4
|
||||
- change in logic: now using a global object $ydb for everything related to DB and other globally needed stuff
|
||||
- change in logic: include "load-yourls.php" instead of "config.php" to start engine
|
||||
- change in DB schema: now storing URLs with their keyword as used in shorturl, allowing for any keyword length
|
||||
- change in DB schema: new table for storing various options including next_id, dropping table of the same name
|
||||
- change in DB schema: new table for storing hits (for stats)
|
||||
- improved the installer, with .htaccess file creation
|
||||
- layout tweak: now prettier, isn't it?
|
||||
- stats! OMG stats!
|
||||
|
||||
1.3-RC1
|
||||
-------
|
||||
- added bookmarklet and tools page
|
||||
- improved XSS filter when adding new URL
|
||||
- code cleanup in admin/index.php to separate code and display
|
||||
- added favicon
|
||||
- stricter coding to prevent notices with undefined indexes
|
||||
- hide PHP notices & SQL errors & warnings, unless YOURLS_DEBUG constant set to true
|
||||
|
||||
1.2
|
||||
---
|
||||
- don't remember. A few tiny stuff for sure.
|
||||
|
||||
1.1
|
||||
---
|
||||
- don't remember. Some little bugs I guess.
|
||||
|
||||
1.0.1
|
||||
-----
|
||||
- don't remember. Trivial stuff probably.
|
||||
|
||||
1.0
|
||||
---
|
||||
- initial release
|
|
@ -1,47 +0,0 @@
|
|||
Contributing to YOURLS
|
||||
======================
|
||||
|
||||
Please take a moment to review this document, or see your issue / pull request closed with *harsh comments* :-)
|
||||
|
||||
Following these guidelines helps to communicate that you respect the time of
|
||||
the developers managing and developing for free this open source project during their free time.
|
||||
Thank you for this, and in return we will reciprocate that respect in addressing your issue
|
||||
or assessing patches with goodwill.
|
||||
|
||||
Search before
|
||||
-------------
|
||||
|
||||
The issue tracker is the preferred channel for bug reports, features requests and submitting pull
|
||||
requests, but please respect the following restrictions:
|
||||
|
||||
* Please **do not** use the issue tracker for personal support requests. Use sites such as
|
||||
[Stack Overflow](http://stackoverflow.com) instead.
|
||||
* Please, please, please, **SEARCH** before you file a new issue or request.
|
||||
|
||||
Guidelines
|
||||
----------
|
||||
|
||||
Before using the issue tracker, we require you read the specific guidelines, depending on the topic:
|
||||
a bug report, a feature request or a pull request.
|
||||
|
||||
### Bug Report
|
||||
|
||||
Good bug reports are extremely helpful - thank you! Good bug reports are also quite rare.
|
||||
To help and raise the bug report quality, **you _must_ read the wiki document about [Bug Reports](https://github.com/YOURLS/YOURLS/wiki/Bug-Report).**
|
||||
|
||||
### Feature Request
|
||||
|
||||
Feature requests are welcome. But take a moment to find out whether your idea fits the scope and
|
||||
goals of the project. Check also the [Roadmap](https://github.com/YOURLS/YOURLS/wiki/Road-Map),
|
||||
maybe your idea is already planned.
|
||||
|
||||
It's up to you to make a strong case to convince the project's developers of the merits of this feature.
|
||||
Please provide as much detail and context as possible and get in touch. Feel free to detail how you envision
|
||||
things, be they about (pseudo)code, interface, mockup, etc...
|
||||
|
||||
### Pull Request
|
||||
|
||||
Good pull requests are a fantastic help. But please get in touch before you start working,
|
||||
it's always a sad moment to dismiss a patch for which a coder has spent a lot of time because
|
||||
it simply does not fit the project. Please read the wiki
|
||||
document about [Pull requests](https://github.com/YOURLS/YOURLS/wiki/Pull-Request).
|
|
@ -1,45 +0,0 @@
|
|||
__ ______ _ _ _____ _ _____
|
||||
\ \ / / __ \| | | | __ \| | / ____|
|
||||
\ \_/ / | | | | | | |__) | | | (___
|
||||
\ /| | | | | | | _ /| | \___ \
|
||||
| | | |__| | |__| | | \ \| |____ ____) |
|
||||
|_| \____/ \____/|_| \_\______|_____/
|
||||
|
||||
|
||||
YOURLS - Your Own URL Shortener
|
||||
===============================
|
||||
|
||||
Copyright (c) 2009-2013 by the contributors
|
||||
|
||||
This program is free software. Do whatever the hell you want with it.
|
||||
|
||||
This program is distributed under the terms of the MIT license, in the
|
||||
hope that it will be useful and/or fun to use. There is absolutely no
|
||||
guarantee of any kind about anything.
|
||||
|
||||
Wherever third party code has been used, credit has been given in the
|
||||
code comments.
|
||||
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright (c) 2009-2013 by the contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
![yourls](images/yourls-logo.png)
|
||||
[YOURLS](http://yourls.org) — [![Build Status](https://travis-ci.org/YOURLS/YOURLS.png?branch=master)](https://travis-ci.org/YOURLS/YOURLS)
|
||||
========
|
||||
**YOURLS** is a set of PHP scripts that will allow you to run Your Own URL Shortener. You'll have full control over your data, detailed stats and analytics, plugins, and more. It's free.
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
To get started, check [yourls.org](http://yourls.org)!
|
||||
Learn more tweaks in the [Wiki documentation](https://github.com/YOURLS/YOURLS/wiki/).
|
||||
|
||||
News
|
||||
----
|
||||
Keep track of development and community news.
|
||||
|
||||
* Follow [@yourls on Twitter](http://twitter.com/yourls).
|
||||
* Read and subscribe to the [The Official YOURLS Blog](http://blog.yourls.org).
|
||||
* Check [commit messages](https://github.com/YOURLS/YOURLS/commits/master).
|
||||
|
||||
Versioning
|
||||
----------
|
||||
For transparency and insight into our release cycle, and for striving to maintain backward compatibility, YOURLS will be maintained under the [Semantic Versioning](http://semver.org) guidelines as much as possible.
|
||||
|
||||
Releases will be numbered with the following format: `<major>.<minor>.<patch>`
|
||||
|
||||
And constructed with the following guidelines:
|
||||
* Breaking backward compatibility bumps the major (and resets the minor and patch)
|
||||
* New additions without breaking backward compatibility bumps the minor (and resets the patch)
|
||||
* Bug fixes and misc changes bumps the patch
|
||||
|
||||
*[Release Archive](https://github.com/YOURLS/YOURLS/releases)*
|
||||
|
||||
Bug Tracker
|
||||
-----------
|
||||
Have a bug or a feature request? [Please open a new issue](https://github.com/YOURLS/YOURLS/issues).
|
||||
__Before opening any issue, please search for existing issues and read the [Issue Guidelines](https://github.com/YOURLS/YOURLS/wiki/Bug-Report).__
|
||||
|
||||
License
|
||||
-------
|
||||
Free software. Do whatever the hell you want with it.
|
||||
The [license](LICENSE.md) under which YOURLS is released is the MIT license.
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
define( 'YOURLS_ADMIN', true );
|
||||
define( 'YOURLS_AJAX', true );
|
||||
require_once( dirname( dirname( __FILE__ ) ) .'/includes/load-yourls.php' );
|
||||
yourls_maybe_require_auth();
|
||||
|
||||
// This file will output a JSON string
|
||||
yourls_content_type_header( 'application/json' );
|
||||
|
||||
if( !isset( $_REQUEST['action'] ) )
|
||||
die();
|
||||
|
||||
// Pick action
|
||||
$action = $_REQUEST['action'];
|
||||
switch( $action ) {
|
||||
|
||||
case 'add':
|
||||
yourls_verify_nonce( 'add_url', $_REQUEST['nonce'], false, 'omg error' );
|
||||
$return = yourls_add_new_link( $_REQUEST['url'], $_REQUEST['keyword'] );
|
||||
echo json_encode($return);
|
||||
break;
|
||||
|
||||
case 'edit_display':
|
||||
yourls_verify_nonce( 'edit-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' );
|
||||
$row = yourls_table_edit_row ( $_REQUEST['keyword'] );
|
||||
echo json_encode( array('html' => $row) );
|
||||
break;
|
||||
|
||||
case 'edit_save':
|
||||
yourls_verify_nonce( 'edit-save_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' );
|
||||
$return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['keyword'], $_REQUEST['newkeyword'], $_REQUEST['title'] );
|
||||
echo json_encode($return);
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
yourls_verify_nonce( 'delete-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' );
|
||||
$query = yourls_delete_link_by_keyword( $_REQUEST['keyword'] );
|
||||
echo json_encode(array('success'=>$query));
|
||||
break;
|
||||
|
||||
case 'logout':
|
||||
// unused for the moment
|
||||
yourls_logout();
|
||||
break;
|
||||
|
||||
default:
|
||||
yourls_do_action( 'yourls_ajax_'.$action );
|
||||
|
||||
}
|
||||
|
||||
die();
|
|
@ -1,349 +0,0 @@
|
|||
<?php
|
||||
define( 'YOURLS_ADMIN', true );
|
||||
require_once( dirname( dirname( __FILE__ ) ).'/includes/load-yourls.php' );
|
||||
yourls_maybe_require_auth();
|
||||
|
||||
// Variables
|
||||
$table_url = YOURLS_DB_TABLE_URL;
|
||||
$where = $search_sentence = $search_text = $url = $keyword = '';
|
||||
$date_filter = $date_first = $date_second = '';
|
||||
$base_page = yourls_admin_url( 'index.php' );
|
||||
|
||||
// Default SQL behavior
|
||||
$search_in_text = yourls__( 'URL' );
|
||||
$search_in = 'url';
|
||||
$sort_by_text = yourls__( 'Short URL' );
|
||||
$sort_by = 'timestamp';
|
||||
$sort_order = 'desc';
|
||||
$page = ( isset( $_GET['page'] ) ? intval($_GET['page']) : 1 );
|
||||
$search = yourls_get_search_text();
|
||||
$perpage = ( isset( $_GET['perpage'] ) && intval( $_GET['perpage'] ) ? intval($_GET['perpage']) : 15 );
|
||||
$click_limit = ( isset( $_GET['click_limit'] ) && $_GET['click_limit'] !== '' ) ? intval( $_GET['click_limit'] ) : '' ;
|
||||
if ( $click_limit !== '' ) {
|
||||
$click_filter = ( isset( $_GET['click_filter'] ) && $_GET['click_filter'] == 'more' ? 'more' : 'less' ) ;
|
||||
$click_moreless = ( $click_filter == 'more' ? '>' : '<' );
|
||||
$where = " AND clicks $click_moreless $click_limit";
|
||||
} else {
|
||||
$click_filter = '';
|
||||
}
|
||||
|
||||
// Searching
|
||||
if( !empty( $search ) && !empty( $_GET['search_in'] ) ) {
|
||||
switch( $_GET['search_in'] ) {
|
||||
case 'keyword':
|
||||
$search_in_text = yourls__( 'Short URL' );
|
||||
$search_in = 'keyword';
|
||||
break;
|
||||
case 'url':
|
||||
$search_in_text = yourls__( 'URL' );
|
||||
$search_in = 'url';
|
||||
break;
|
||||
case 'title':
|
||||
$search_in_text = yourls__( 'Title' );
|
||||
$search_in = 'title';
|
||||
break;
|
||||
case 'ip':
|
||||
$search_in_text = yourls__( 'IP Address' );
|
||||
$search_in = 'ip';
|
||||
break;
|
||||
}
|
||||
$search_sentence = yourls_s( 'Searching for <strong>%1$s</strong> in <strong>%2$s</strong>.', yourls_esc_html( $search ), yourls_esc_html( $search_in_text ) );
|
||||
$search_url = yourls_sanitize_url( "&search=$search&search_in=$search_in" );
|
||||
$search_text = $search;
|
||||
$search = str_replace( '*', '%', '*' . yourls_escape( $search ) . '*' );
|
||||
$where .= " AND `$search_in` LIKE ('$search')";
|
||||
}
|
||||
|
||||
// Time span
|
||||
if( !empty( $_GET['date_filter'] ) ) {
|
||||
switch( $_GET['date_filter'] ) {
|
||||
case 'before':
|
||||
$date_filter = 'before';
|
||||
if( isset( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_first'] ) ) {
|
||||
$date_first = yourls_sanitize_date( $_GET['date_first'] );
|
||||
$date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] );
|
||||
$where .= " AND `timestamp` < '$date_first_sql'";
|
||||
}
|
||||
break;
|
||||
case 'after':
|
||||
$date_filter = 'after';
|
||||
if( isset( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_first'] ) ) {
|
||||
$date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] );
|
||||
$date_first = yourls_sanitize_date( $_GET['date_first'] );
|
||||
$where .= " AND `timestamp` > '$date_first_sql'";
|
||||
}
|
||||
break;
|
||||
case 'between':
|
||||
$date_filter = 'between';
|
||||
if( isset( $_GET['date_first'] ) && isset( $_GET['date_second'] ) && yourls_sanitize_date( $_GET['date_first'] ) && yourls_sanitize_date( $_GET['date_second'] ) ) {
|
||||
$date_first_sql = yourls_sanitize_date_for_sql( $_GET['date_first'] );
|
||||
$date_second_sql = yourls_sanitize_date_for_sql( $_GET['date_second'] );
|
||||
$date_first = yourls_sanitize_date( $_GET['date_first'] );
|
||||
$date_second = yourls_sanitize_date( $_GET['date_second'] );
|
||||
$where .= " AND `timestamp` BETWEEN '$date_first_sql' AND '$date_second_sql'";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Sorting
|
||||
if( !empty( $_GET['sort_by'] ) || !empty( $_GET['sort_order'] ) ) {
|
||||
switch( $_GET['sort_by'] ) {
|
||||
case 'keyword':
|
||||
$sort_by_text = yourls__( 'Short URL' );
|
||||
$sort_by = 'keyword';
|
||||
break;
|
||||
case 'url':
|
||||
$sort_by_text = yourls__( 'URL' );
|
||||
$sort_by = 'url';
|
||||
break;
|
||||
case 'timestamp':
|
||||
$sort_by_text = yourls__( 'Date' );
|
||||
$sort_by = 'timestamp';
|
||||
break;
|
||||
case 'ip':
|
||||
$sort_by_text = yourls__( 'IP Address' );
|
||||
$sort_by = 'ip';
|
||||
break;
|
||||
case 'clicks':
|
||||
$sort_by_text = yourls__( 'Clicks' );
|
||||
$sort_by = 'clicks';
|
||||
break;
|
||||
}
|
||||
switch( $_GET['sort_order'] ) {
|
||||
case 'asc':
|
||||
$sort_order = 'asc';
|
||||
break;
|
||||
case 'desc':
|
||||
$sort_order = 'desc';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get URLs Count for current filter, total links in DB & total clicks
|
||||
list( $total_urls, $total_clicks ) = array_values( yourls_get_db_stats() );
|
||||
if ( $where ) {
|
||||
list( $total_items, $total_items_clicks ) = array_values( yourls_get_db_stats( $where ) );
|
||||
} else {
|
||||
$total_items = $total_urls;
|
||||
$total_items_clicks = false;
|
||||
}
|
||||
|
||||
// This is a bookmarklet
|
||||
if ( isset( $_GET['u'] ) or isset( $_GET['up'] ) ) {
|
||||
$is_bookmark = true;
|
||||
yourls_do_action( 'bookmarklet' );
|
||||
|
||||
// No sanitization needed here: everything happens in yourls_add_new_link()
|
||||
if( isset( $_GET['u'] ) ) {
|
||||
// Old school bookmarklet: ?u=<url>
|
||||
$url = rawurldecode( $_GET['u'] );
|
||||
} else {
|
||||
// New style bookmarklet: ?up=<url protocol>&us=<url slashes>&ur=<url rest>
|
||||
$url = rawurldecode( $_GET['up'] . $_GET['us'] . $_GET['ur'] );
|
||||
}
|
||||
$keyword = ( isset( $_GET['k'] ) ? ( $_GET['k'] ) : '' );
|
||||
$title = ( isset( $_GET['t'] ) ? ( $_GET['t'] ) : '' );
|
||||
$return = yourls_add_new_link( $url, $keyword, $title );
|
||||
|
||||
// If fails because keyword already exist, retry with no keyword
|
||||
if ( isset( $return['status'] ) && $return['status'] == 'fail' && isset( $return['code'] ) && $return['code'] == 'error:keyword' ) {
|
||||
$msg = $return['message'];
|
||||
$return = yourls_add_new_link( $url, '', $ydb );
|
||||
$return['message'] .= ' ('.$msg.')';
|
||||
}
|
||||
|
||||
// Stop here if bookmarklet with a JSON callback function
|
||||
if( isset( $_GET['jsonp'] ) && $_GET['jsonp'] == 'yourls' ) {
|
||||
$short = $return['shorturl'] ? $return['shorturl'] : '';
|
||||
$message = $return['message'];
|
||||
yourls_content_type_header( 'application/javascript' );
|
||||
echo yourls_apply_filter( 'bookmarklet_jsonp', "yourls_callback({'short_url':'$short','message':'$message'});" );
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
// Now use the URL that has been sanitized and returned by yourls_add_new_link()
|
||||
$url = $return['url']['url'];
|
||||
$where = sprintf( " AND `url` LIKE '%s' ", yourls_escape( $url ) );
|
||||
|
||||
$page = $total_pages = $perpage = 1;
|
||||
$offset = 0;
|
||||
|
||||
$text = ( isset( $_GET['s'] ) ? stripslashes( $_GET['s'] ) : '' );
|
||||
|
||||
// Sharing with social bookmarklets
|
||||
if( !empty($_GET['share']) ) {
|
||||
yourls_do_action( 'pre_share_redirect' );
|
||||
switch ( $_GET['share'] ) {
|
||||
case 'twitter':
|
||||
// share with Twitter
|
||||
$destination = sprintf( "https://twitter.com/intent/tweet?url=%s&text=%s", urlencode( $return['shorturl'] ), urlencode( $title ) );
|
||||
yourls_redirect( $destination, 303 );
|
||||
|
||||
// Deal with the case when redirection failed:
|
||||
$return['status'] = 'error';
|
||||
$return['errorCode'] = 400;
|
||||
$return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Twitter' );
|
||||
break;
|
||||
|
||||
case 'facebook':
|
||||
// share with Facebook
|
||||
$destination = sprintf( "https://www.facebook.com/sharer/sharer.php?u=%s&t=%s", urlencode( $return['shorturl'] ), urlencode( $title ) );
|
||||
yourls_redirect( $destination, 303 );
|
||||
|
||||
// Deal with the case when redirection failed:
|
||||
$return['status'] = 'error';
|
||||
$return['errorCode'] = 400;
|
||||
$return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Facebook' );
|
||||
break;
|
||||
|
||||
case 'tumblr':
|
||||
// share with Tumblr
|
||||
$destination = sprintf( "http://www.tumblr.com/share?v=3&u=%s&t=%s&s=%s", urlencode( $return['shorturl'] ), urlencode( $title ), urlencode( $text ) );
|
||||
yourls_redirect( $destination, 303 );
|
||||
|
||||
// Deal with the case when redirection failed:
|
||||
$return['status'] = 'error';
|
||||
$return['errorCode'] = 400;
|
||||
$return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Tumblr' );
|
||||
break;
|
||||
|
||||
default:
|
||||
// Is there a custom registered social bookmark?
|
||||
yourls_do_action( 'share_redirect_' . $_GET['share'], $return );
|
||||
|
||||
// Still here? That was an unknown 'share' method, then.
|
||||
$return['status'] = 'error';
|
||||
$return['errorCode'] = 400;
|
||||
$return['message'] = yourls__( 'Unknown "Share" bookmarklet' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This is not a bookmarklet
|
||||
} else {
|
||||
$is_bookmark = false;
|
||||
|
||||
// Checking $page, $offset, $perpage
|
||||
if( empty($page) || $page == 0 ) {
|
||||
$page = 1;
|
||||
}
|
||||
if( empty($offset) ) {
|
||||
$offset = 0;
|
||||
}
|
||||
if( empty($perpage) || $perpage == 0) {
|
||||
$perpage = 50;
|
||||
}
|
||||
|
||||
// Determine $offset
|
||||
$offset = ( $page-1 ) * $perpage;
|
||||
|
||||
// Determine Max Number Of Items To Display On Page
|
||||
if( ( $offset + $perpage ) > $total_items ) {
|
||||
$max_on_page = $total_items;
|
||||
} else {
|
||||
$max_on_page = ( $offset + $perpage );
|
||||
}
|
||||
|
||||
// Determine Number Of Items To Display On Page
|
||||
if ( ( $offset + 1 ) > $total_items ) {
|
||||
$display_on_page = $total_items;
|
||||
} else {
|
||||
$display_on_page = ( $offset + 1 );
|
||||
}
|
||||
|
||||
// Determing Total Amount Of Pages
|
||||
$total_pages = ceil( $total_items / $perpage );
|
||||
}
|
||||
|
||||
|
||||
// Begin output of the page
|
||||
$context = ( $is_bookmark ? 'bookmark' : 'index' );
|
||||
yourls_html_head( $context );
|
||||
yourls_html_logo();
|
||||
yourls_html_menu() ;
|
||||
|
||||
yourls_do_action( 'admin_page_before_content' );
|
||||
|
||||
if ( !$is_bookmark ) { ?>
|
||||
<p><?php echo $search_sentence; ?></p>
|
||||
<p><?php
|
||||
printf( yourls__( 'Display <strong>%1$s</strong> to <strong class="increment">%2$s</strong> of <strong class="increment">%3$s</strong> URLs' ), $display_on_page, $max_on_page, $total_items );
|
||||
if( $total_items_clicks !== false )
|
||||
echo ", " . sprintf( yourls_n( 'counting <strong>1</strong> click', 'counting <strong>%s</strong> clicks', $total_items_clicks ), yourls_number_format_i18n( $total_items_clicks ) );
|
||||
?>.</p>
|
||||
<?php } ?>
|
||||
<p><?php printf( yourls__( 'Overall, tracking <strong class="increment">%1$s</strong> links, <strong>%2$s</strong> clicks, and counting!' ), yourls_number_format_i18n( $total_urls ), yourls_number_format_i18n( $total_clicks ) ); ?></p>
|
||||
<?php yourls_do_action( 'admin_page_before_form' ); ?>
|
||||
|
||||
<?php yourls_html_addnew(); ?>
|
||||
|
||||
<?php
|
||||
// If bookmarklet, add message. Otherwise, hide hidden share box.
|
||||
if ( !$is_bookmark ) {
|
||||
yourls_share_box( '', '', '', '', '', '', true );
|
||||
} else {
|
||||
echo '<script type="text/javascript">$(document).ready(function(){
|
||||
feedback( "' . $return['message'] . '", "'. $return['status'] .'");
|
||||
init_clipboard();
|
||||
});</script>';
|
||||
}
|
||||
|
||||
yourls_do_action( 'admin_page_before_table' );
|
||||
|
||||
yourls_table_head();
|
||||
|
||||
if ( !$is_bookmark ) {
|
||||
$params = array(
|
||||
'search' => $search,
|
||||
'search_text' => $search_text,
|
||||
'search_in' => $search_in,
|
||||
'sort_by' => $sort_by,
|
||||
'sort_order' => $sort_order,
|
||||
'page' => $page,
|
||||
'perpage' => $perpage,
|
||||
'click_filter' => $click_filter,
|
||||
'click_limit' => $click_limit,
|
||||
'total_pages' => $total_pages,
|
||||
'date_filter' => $date_filter,
|
||||
'date_first' => $date_first,
|
||||
'date_second' => $date_second,
|
||||
);
|
||||
yourls_html_tfooter( $params );
|
||||
}
|
||||
|
||||
yourls_table_tbody_start();
|
||||
|
||||
// Main Query
|
||||
$where = yourls_apply_filter( 'admin_list_where', $where );
|
||||
$url_results = $ydb->get_results( "SELECT * FROM `$table_url` WHERE 1=1 $where ORDER BY `$sort_by` $sort_order LIMIT $offset, $perpage;" );
|
||||
$found_rows = false;
|
||||
if( $url_results ) {
|
||||
$found_rows = true;
|
||||
foreach( $url_results as $url_result ) {
|
||||
$keyword = yourls_sanitize_string( $url_result->keyword );
|
||||
$timestamp = strtotime( $url_result->timestamp );
|
||||
$url = stripslashes( $url_result->url );
|
||||
$ip = $url_result->ip;
|
||||
$title = $url_result->title ? $url_result->title : '';
|
||||
$clicks = $url_result->clicks;
|
||||
|
||||
echo yourls_table_add_row( $keyword, $url, $title, $ip, $clicks, $timestamp );
|
||||
}
|
||||
}
|
||||
|
||||
$display = $found_rows ? 'display:none' : '';
|
||||
echo '<tr id="nourl_found" style="'.$display.'"><td colspan="6">' . yourls__('No URL') . '</td></tr>';
|
||||
|
||||
yourls_table_tbody_end();
|
||||
|
||||
yourls_table_end();
|
||||
|
||||
yourls_do_action( 'admin_page_after_table' );
|
||||
|
||||
if ( $is_bookmark )
|
||||
yourls_share_box( $url, $return['shorturl'], $title, $text );
|
||||
?>
|
||||
|
||||
<?php yourls_html_footer( ); ?>
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
define( 'YOURLS_ADMIN', true );
|
||||
define( 'YOURLS_INSTALLING', true );
|
||||
require_once( dirname(dirname(__FILE__)).'/includes/load-yourls.php' );
|
||||
require_once( YOURLS_INC.'/functions-install.php' );
|
||||
|
||||
$error = array();
|
||||
$warning = array();
|
||||
$success = array();
|
||||
|
||||
// Check pre-requisites
|
||||
if ( !yourls_check_database_version() ) {
|
||||
$error[] = yourls_s( '%s version is too old. Ask your server admin for an upgrade.', 'MySQL' );
|
||||
yourls_debug_log( 'MySQL version: ' . yourls_get_database_version() );
|
||||
}
|
||||
|
||||
if ( !yourls_check_php_version() ) {
|
||||
$error[] = yourls_s( '%s version is too old. Ask your server admin for an upgrade.', 'PHP' );
|
||||
yourls_debug_log( 'PHP version: ' . phpversion() );
|
||||
}
|
||||
|
||||
// Is YOURLS already installed ?
|
||||
if ( yourls_is_installed() ) {
|
||||
$error[] = yourls__( 'YOURLS already installed.' );
|
||||
// check if .htaccess exists, recreate otherwise. No error checking.
|
||||
if( !file_exists( YOURLS_ABSPATH.'/.htaccess' ) ) {
|
||||
yourls_create_htaccess();
|
||||
}
|
||||
}
|
||||
|
||||
// Start install if possible and needed
|
||||
if ( isset($_REQUEST['install']) && count( $error ) == 0 ) {
|
||||
// Create/update .htaccess file
|
||||
if ( yourls_create_htaccess() ) {
|
||||
$success[] = yourls__( 'File <tt>.htaccess</tt> successfully created/updated.' );
|
||||
} else {
|
||||
$warning[] = yourls__( 'Could not write file <tt>.htaccess</tt> in YOURLS root directory. You will have to do it manually. See <a href="http://yourls.org/htaccess">how</a>.' );
|
||||
}
|
||||
|
||||
// Create SQL tables
|
||||
$install = yourls_create_sql_tables();
|
||||
if ( isset( $install['error'] ) )
|
||||
$error = array_merge( $error, $install['error'] );
|
||||
if ( isset( $install['success'] ) )
|
||||
$success = array_merge( $success, $install['success'] );
|
||||
}
|
||||
|
||||
|
||||
// Start output
|
||||
yourls_html_head( 'install', yourls__( 'Install YOURLS' ) );
|
||||
?>
|
||||
<div id="login">
|
||||
<form method="post" action="?"><?php // reset any QUERY parameters ?>
|
||||
<p>
|
||||
<img src="<?php yourls_site_url(); ?>/images/yourls-logo.png" alt="YOURLS" title="YOURLS" />
|
||||
</p>
|
||||
<?php
|
||||
// Print errors, warnings and success messages
|
||||
foreach ( array ('error', 'warning', 'success') as $info ) {
|
||||
if ( count( $$info ) > 0 ) {
|
||||
echo "<ul class='$info'>";
|
||||
foreach( $$info as $msg ) {
|
||||
echo '<li>'.$msg."</li>\n";
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
}
|
||||
|
||||
// Display install button or link to admin area if applicable
|
||||
if( !yourls_is_installed() && !isset($_REQUEST['install']) ) {
|
||||
echo '<p style="text-align: center;"><input type="submit" name="install" value="' . yourls__( 'Install YOURLS') .'" class="button" /></p>';
|
||||
} else {
|
||||
if( count($error) == 0 )
|
||||
echo '<p style="text-align: center;">» <a href="'.yourls_admin_url().'" title="' . yourls__( 'YOURLS Administration Page') . '">' . yourls__( 'YOURLS Administration Page') . '</a></p>';
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
</div>
|
||||
<?php yourls_html_footer(); ?>
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
define( 'YOURLS_ADMIN', true );
|
||||
require_once( dirname( dirname( __FILE__ ) ).'/includes/load-yourls.php' );
|
||||
yourls_maybe_require_auth();
|
||||
|
||||
// Handle plugin administration pages
|
||||
if( isset( $_GET['page'] ) && !empty( $_GET['page'] ) ) {
|
||||
yourls_plugin_admin_page( $_GET['page'] );
|
||||
}
|
||||
|
||||
// Handle activation/deactivation of plugins
|
||||
if( isset( $_GET['action'] ) ) {
|
||||
|
||||
// Check nonce
|
||||
yourls_verify_nonce( 'manage_plugins', $_REQUEST['nonce'] );
|
||||
|
||||
// Check plugin file is valid
|
||||
if( isset( $_GET['plugin'] ) && yourls_validate_plugin_file( YOURLS_PLUGINDIR.'/'.$_GET['plugin'].'/plugin.php') ) {
|
||||
|
||||
global $ydb;
|
||||
// Activate / Deactive
|
||||
switch( $_GET['action'] ) {
|
||||
case 'activate':
|
||||
$result = yourls_activate_plugin( $_GET['plugin'].'/plugin.php' );
|
||||
if( $result === true )
|
||||
yourls_redirect( yourls_admin_url( 'plugins.php?success=activated' ), 302 );
|
||||
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
$result = yourls_deactivate_plugin( $_GET['plugin'].'/plugin.php' );
|
||||
if( $result === true )
|
||||
yourls_redirect( yourls_admin_url( 'plugins.php?success=deactivated' ), 302 );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$result = yourls__( 'Unsupported action' );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$result = yourls__( 'No plugin specified, or not a valid plugin' );
|
||||
}
|
||||
|
||||
yourls_add_notice( $result );
|
||||
}
|
||||
|
||||
// Handle message upon succesfull (de)activation
|
||||
if( isset( $_GET['success'] ) && ( ( $_GET['success'] == 'activated' ) OR ( $_GET['success'] == 'deactivated' ) ) ) {
|
||||
if( $_GET['success'] == 'activated' ) {
|
||||
$message = yourls__( 'Plugin has been activated' );
|
||||
} elseif ( $_GET['success'] == 'deactivated' ) {
|
||||
$message = yourls__( 'Plugin has been deactivated' );
|
||||
}
|
||||
yourls_add_notice( $message );
|
||||
}
|
||||
|
||||
yourls_html_head( 'plugins', yourls__( 'Manage Plugins' ) );
|
||||
yourls_html_logo();
|
||||
yourls_html_menu();
|
||||
?>
|
||||
|
||||
<h2><?php yourls_e( 'Plugins' ); ?></h2>
|
||||
|
||||
<?php
|
||||
$plugins = (array)yourls_get_plugins();
|
||||
uasort( $plugins, 'yourls_plugins_sort_callback' );
|
||||
|
||||
$count = count( $plugins );
|
||||
$plugins_count = sprintf( yourls_n( '%s plugin', '%s plugins', $count ), $count );
|
||||
$count_active = yourls_has_active_plugins();
|
||||
?>
|
||||
|
||||
<p id="plugin_summary"><?php /* //translators: "you have '3 plugins' installed and '1' activated" */ yourls_se( 'You currently have <strong>%1$s</strong> installed, and <strong>%2$s</strong> activated', $plugins_count, $count_active ); ?></p>
|
||||
|
||||
<table id="main_table" class="tblSorter" cellpadding="0" cellspacing="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php yourls_e( 'Plugin Name' ); ?></th>
|
||||
<th><?php yourls_e( 'Version' ); ?></th>
|
||||
<th><?php yourls_e( 'Description' ); ?></th>
|
||||
<th><?php yourls_e( 'Author' ); ?></th>
|
||||
<th><?php yourls_e( 'Action' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
$nonce = yourls_create_nonce( 'manage_plugins' );
|
||||
|
||||
foreach( $plugins as $file=>$plugin ) {
|
||||
|
||||
// default fields to read from the plugin header
|
||||
$fields = array(
|
||||
'name' => 'Plugin Name',
|
||||
'uri' => 'Plugin URI',
|
||||
'desc' => 'Description',
|
||||
'version' => 'Version',
|
||||
'author' => 'Author',
|
||||
'author_uri' => 'Author URI'
|
||||
);
|
||||
|
||||
// Loop through all default fields, get value if any and reset it
|
||||
foreach( $fields as $field=>$value ) {
|
||||
if( isset( $plugin[ $value ] ) ) {
|
||||
$data[ $field ] = $plugin[ $value ];
|
||||
} else {
|
||||
$data[ $field ] = '(no info)';
|
||||
}
|
||||
unset( $plugin[$value] );
|
||||
}
|
||||
|
||||
$plugindir = trim( dirname( $file ), '/' );
|
||||
|
||||
if( yourls_is_active_plugin( $file ) ) {
|
||||
$class = 'active';
|
||||
$action_url = yourls_nonce_url( 'manage_plugins', yourls_add_query_arg( array('action' => 'deactivate', 'plugin' => $plugindir ) ) );
|
||||
$action_anchor = yourls__( 'Deactivate' );
|
||||
} else {
|
||||
$class = 'inactive';
|
||||
$action_url = yourls_nonce_url( 'manage_plugins', yourls_add_query_arg( array('action' => 'activate', 'plugin' => $plugindir ) ) );
|
||||
$action_anchor = yourls__( 'Activate' );
|
||||
}
|
||||
|
||||
// Other "Fields: Value" in the header? Get them too
|
||||
if( $plugin ) {
|
||||
foreach( $plugin as $extra_field=>$extra_value ) {
|
||||
$data['desc'] .= "<br/>\n<em>$extra_field</em>: $extra_value";
|
||||
unset( $plugin[$extra_value] );
|
||||
}
|
||||
}
|
||||
|
||||
$data['desc'] .= '<br/><small>' . yourls_s( 'plugin file location: %s', $file) . '</small>';
|
||||
|
||||
printf( "<tr class='plugin %s'><td class='plugin_name'><a href='%s'>%s</a></td><td class='plugin_version'>%s</td><td class='plugin_desc'>%s</td><td class='plugin_author'><a href='%s'>%s</a></td><td class='plugin_actions actions'><a href='%s'>%s</a></td></tr>",
|
||||
$class, $data['uri'], $data['name'], $data['version'], $data['desc'], $data['author_uri'], $data['author'], $action_url, $action_anchor
|
||||
);
|
||||
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript">
|
||||
yourls_defaultsort = 0;
|
||||
yourls_defaultorder = 0;
|
||||
<?php if ($count_active) { ?>
|
||||
$('#plugin_summary').append('<span id="toggle_plugins">filter</span>');
|
||||
$('#toggle_plugins').css({'background':'transparent url("../images/filter.gif") top left no-repeat','display':'inline-block','text-indent':'-9999px','width':'16px','height':'16px','margin-left':'3px','cursor':'pointer'})
|
||||
.attr('title', '<?php echo yourls_esc_attr__( 'Toggle active/inactive plugins' ); ?>')
|
||||
.click(function(){
|
||||
$('#main_table tr.inactive').toggle();
|
||||
});
|
||||
<?php } ?>
|
||||
</script>
|
||||
|
||||
<p><?php yourls_e( 'If something goes wrong after you activate a plugin and you cannot use YOURLS or access this page, simply rename or delete its directory, or rename the plugin file to something different than <code>plugin.php</code>.' ); ?></p>
|
||||
|
||||
<h3><?php yourls_e( 'More plugins' ); ?></h3>
|
||||
|
||||
<p><?php yourls_e( 'For more plugins, head to the official <a href="http://yourls.org/pluginlist">Plugin list</a>.' ); ?></p>
|
||||
|
||||
|
||||
<?php yourls_html_footer(); ?>
|
|
@ -1,136 +0,0 @@
|
|||
<?php
|
||||
define( 'YOURLS_ADMIN', true );
|
||||
require_once( dirname( dirname( __FILE__ ) ).'/includes/load-yourls.php' );
|
||||
yourls_maybe_require_auth();
|
||||
|
||||
yourls_html_head( 'tools', yourls__( 'Cool YOURLS Tools' ) );
|
||||
yourls_html_logo();
|
||||
yourls_html_menu();
|
||||
?>
|
||||
|
||||
<div class="sub_wrap">
|
||||
|
||||
<h2><?php yourls_e( 'Bookmarklets' ); ?></h2>
|
||||
|
||||
<p><?php yourls_e( 'YOURLS comes with handy <span>bookmarklets</span> for easier link shortening and sharing.' ); ?></p>
|
||||
|
||||
<h3><?php yourls_e( 'Standard or Instant, Simple or Custom' ); ?></h3>
|
||||
|
||||
<ul>
|
||||
<li><?php yourls_e( 'The <span>Standard Bookmarklets</span> will take you to a page where you can easily edit or delete your brand new short URL.' ); ?></li>
|
||||
|
||||
<li><?php yourls_e( 'The <span>Instant Bookmarklets</span> will pop the short URL without leaving the page you are viewing.' ); ?></li>
|
||||
|
||||
<li><?php yourls_e( 'The <span>Simple Bookmarklets</span> will generate a short URL with a random or sequential keyword.' ); ?></li>
|
||||
|
||||
<li><?php yourls_e( 'The <span>Custom Keyword Bookmarklets</span> will prompt you for a custom keyword first.' ); ?></li>
|
||||
</ul>
|
||||
|
||||
<p><?php
|
||||
yourls_e( "If you want to share a description along with the link you're shortening, simply <span>select text</span> on the page you're viewing before clicking on your bookmarklet link" );
|
||||
?></p>
|
||||
|
||||
<h3><?php yourls_e( 'The Bookmarklets' ); ?></h3>
|
||||
|
||||
<p><?php yourls_e( 'Click and drag links to your toolbar (or right-click and bookmark it)' ); ?></p>
|
||||
|
||||
<table class="tblSorter" cellpadding="0" cellspacing="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<th><?php yourls_e( 'Standard (new page)' ); ?></th>
|
||||
<th><?php yourls_e( 'Instant (popup)' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="header"><?php yourls_e( 'Simple' ); ?></th>
|
||||
<td><a href="javascript:(function(){var%20d=document,w=window,enc=encodeURIComponent,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:enc(s)),f='<?php echo yourls_admin_url( 'index.php' ); ?>',l=d.location.href,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0],ur=l.split(new%20RegExp(ups))[1],ups=ups.split(/\:/),p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title)+'&s='+s2,u=f+p;try{throw('ozhismygod');}catch(z){a=function(){if(!w.open(u))l.href=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0);})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'Shorten' ); ?></a></td>
|
||||
<td><a href="javascript:(function(){var%20d=document,w=window,sc=d.createElement('script'),l=d.location.href,enc=encodeURIComponent,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0],ur=l.split(new%20RegExp(ups))[1],ups=ups.split(/\:/),p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title);w.yourls_callback=function(r){if(r.short_url){prompt(r.message,r.short_url);}else{alert('An%20error%20occured:%20'+r.message);}};sc.src='<?php echo yourls_admin_url( 'index.php' ); ?>'+p+'&jsonp=yourls';void(d.body.appendChild(sc));})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'Instant Shorten' ); ?></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="header"><?php yourls_e( 'Custom Keyword' ); ?></th>
|
||||
<td><a href="javascript:(function(){var%20d=document,enc=encodeURIComponent,e=window.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:enc(s)),f='<?php echo yourls_admin_url( 'index.php' ); ?>',l=d.location.href,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0],ur=l.split(new%20RegExp(ups))[1],ups=ups.split(/\:/),k=prompt('Custom%20URL'),k2=(k?'&k='+k:''),p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title)+'&s='+s2+k2,u=f+p;if(k!=null){try{throw('ozhismygod');}catch(z){a=function(){if(!w.open(u))l=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0)}})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'Custom shorten' ); ?></a></td>
|
||||
<td><a href="javascript:(function(){var%20d=document,l=d.location.href,k=prompt('Custom%20URL'),enc=encodeURIComponent,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0],ur=l.split(new%20RegExp(ups))[1],ups=ups.split(/\:/),p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title);sc=d.createElement('script');if(k!=null){window.yourls_callback=function(r){if(r.short_url){prompt(r.message,r.short_url);}else{alert('An%20error%20occured:%20'+r.message);}};sc.src='<?php echo yourls_admin_url( 'index.php' ); ?>'+p+'&k='+k+'&jsonp=yourls';void(d.body.appendChild(sc));}})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'Instant Custom Shorten' ); ?></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3><?php yourls_e( 'Social Bookmarklets' ); ?></h3>
|
||||
|
||||
<p><?php yourls_e( 'Create a short URL and share it on social networks, all in one click!' ); ?>
|
||||
<?php yourls_e( 'Click and drag links to your toolbar (or right-click and bookmark it)' ); ?></p>
|
||||
|
||||
<p><?php yourls_e( 'Shorten and share:' ); ?></p>
|
||||
|
||||
<p>
|
||||
|
||||
<a href="javascript:(function(){var%20d=document,enc=encodeURIComponent,share='facebook',f='<?php echo yourls_admin_url( 'index.php' ); ?>',l=d.location.href,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0];var%20ur=l.split(new%20RegExp(ups))[1];var%20ups=ups.split(/\:/);p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title)+'&share='+share,u=f+p;try{throw('ozhismygod');}catch(z){a=function(){if(!window.open(u,'Share','width=500,height=340,left=100','_blank'))l.href=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0);})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'YOURLS & Facebook' ); ?></a>
|
||||
|
||||
<a href="javascript:(function(){var%20d=document,w=window,enc=encodeURIComponent,share='twitter',e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:'%20%22'+enc(s)+'%22'),f='<?php echo yourls_admin_url( 'index.php' ); ?>',l=d.location.href,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0],ur=l.split(new%20RegExp(ups))[1],ups=ups.split(/\:/),p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title)+s2+'&share='+share,u=f+p;try{throw('ozhismygod');}catch(z){a=function(){if(!w.open(u,'Share','width=780,height=265,left=100','_blank'))l=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0);})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'YOURLS & Twitter' ); ?></a>
|
||||
|
||||
<a href="javascript:(function(){var%20d=document,w=window,enc=encodeURIComponent,share='tumblr',e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:'%20%22'+enc(s)+'%22'),f='<?php echo yourls_admin_url( 'index.php' ); ?>',l=d.location.href,ups=l.match(/^[a-zA-Z0-9\+\.-]+:(\/\/)?/)[0],ur=l.split(new%20RegExp(ups))[1],ups=ups.split(/\:/),p='?up='+enc(ups[0]+':')+'&us='+enc(ups[1])+'&ur='+enc(ur)+'&t='+enc(d.title)+'&s='+s2+'&share='+share,u=f+p;try{throw('ozhismygod');}catch(z){a=function(){if(!w.open(u,'Share','width=450,height=450,left=430','_blank'))l=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0);})();" class="bookmarklet" onclick="alert('<?php echo yourls_esc_attr__( 'Drag to your toolbar!' ); ?>');return false;"><?php yourls_e( 'YOURLS & Tumblr' ); ?></a>
|
||||
|
||||
<?php // Bookmarklets, unformatted for readability: https://gist.github.com/ozh/5495656 ?>
|
||||
|
||||
<?php yourls_do_action( 'social_bookmarklet_buttons_after' ); ?>
|
||||
|
||||
</p>
|
||||
|
||||
<h2><?php yourls_e( 'Prefix-n-Shorten' ); ?></h2>
|
||||
|
||||
<p><?php yourls_se( "When viewing a page, you can also prefix its full URL: just head to your browser's address bar, add \"<span>%s</span>\" to the beginning of the current URL (right before its 'http://' part) and hit enter.", preg_replace('@https?://@', '', YOURLS_SITE) . '/' ); ?></p>
|
||||
|
||||
<p><?php
|
||||
yourls_e( 'Note: this will probably not work if your web server is running on Windows' );
|
||||
if( yourls_is_windows() )
|
||||
yourls_e( ' (which seems to be the case here)' );
|
||||
?>.</p>
|
||||
|
||||
|
||||
<?php if( yourls_is_private() ) { ?>
|
||||
|
||||
<h2><?php yourls_e( 'Secure passwordless API call' ); ?></h2>
|
||||
|
||||
<p><?php
|
||||
yourls_e( 'YOURLS allows API calls the old fashioned way, using <tt>username</tt> and <tt>password</tt> parameters.' );
|
||||
echo "\n";
|
||||
yourls_e( "If you're worried about sending your credentials into the wild, you can also make API calls without using your login or your password, using a secret signature token." );
|
||||
?></p>
|
||||
|
||||
<p><?php
|
||||
yourls_se( 'Your secret signature token: <strong><code>%s</code></strong>', yourls_auth_signature() );
|
||||
yourls_e( "(It's a secret. Keep it secret) ");
|
||||
?></p>
|
||||
|
||||
<p><?php yourls_e( 'This signature token can only be used with the API, not with the admin interface.' ); ?></p>
|
||||
|
||||
<ul>
|
||||
<li><h3><?php yourls_e( 'Usage of the signature token' ); ?></h3>
|
||||
<p><?php yourls_e( 'Simply use parameter <tt>signature</tt> in your API requests. Example:' ); ?></p>
|
||||
<p><code><?php echo YOURLS_SITE; ?>/yourls-api.php?signature=<?php echo yourls_auth_signature(); ?>&action=...</code></p>
|
||||
</li>
|
||||
|
||||
<li><h3><?php yourls_e( 'Usage of a time limited signature token' ); ?></h3>
|
||||
<pre><code><?php
|
||||
$timestamp = time();
|
||||
<tt>// <?php yourls_e( 'actual value:' ); ?> $time = <?php $time = time(); echo $time; ?></tt>
|
||||
$signature = md5( $timestamp . '<?php echo yourls_auth_signature(); ?>' );
|
||||
<tt>// <?php yourls_e( 'actual value:' ); ?> $signature = "<?php $sign = md5( $time. yourls_auth_signature() ); echo $sign; ?>"</tt>
|
||||
?>
|
||||
</code></pre>
|
||||
<p><?php yourls_e( 'Now use parameters <tt>signature</tt> and <tt>timestamp</tt> in your API requests. Example:' ); ?></p>
|
||||
<p><code><?php echo YOURLS_SITE; ?>/yourls-api.php?timestamp=<strong>$timestamp</strong>&signature=<strong>$signature</strong>&action=...</code></p>
|
||||
<p><?php yourls_e( 'Actual values:' ); ?><br/>
|
||||
<tt><?php echo YOURLS_SITE; ?>/yourls-api.php?timestamp=<?php echo $time; ?>&signature=<?php echo $sign; ?>&action=...</tt></p>
|
||||
<p><?php yourls_se( 'This URL would be valid for only %s seconds', YOURLS_NONCE_LIFE ); ?></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p><?php yourls_se( 'See the <a href="%s">API documentation</a> for more', YOURLS_SITE . '/readme.html#API' ); ?></p>
|
||||
|
||||
</div>
|
||||
|
||||
<?php } // end is private ?>
|
||||
|
||||
<?php yourls_html_footer(); ?>
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
define( 'YOURLS_ADMIN', true );
|
||||
define( 'YOURLS_UPGRADING', true );
|
||||
require_once( dirname( dirname( __FILE__ ) ).'/includes/load-yourls.php' );
|
||||
require_once( YOURLS_INC.'/functions-upgrade.php' );
|
||||
require_once( YOURLS_INC.'/functions-install.php' );
|
||||
yourls_maybe_require_auth();
|
||||
|
||||
yourls_html_head( 'upgrade', yourls__( 'Upgrade YOURLS' ) );
|
||||
yourls_html_logo();
|
||||
yourls_html_menu();
|
||||
?>
|
||||
<h2><?php yourls_e( 'Upgrade YOURLS' ); ?></h2>
|
||||
<?php
|
||||
|
||||
// Check if upgrade is needed
|
||||
if ( !yourls_upgrade_is_needed() ) {
|
||||
echo '<p>' . yourls_s( 'Upgrade not required. Go <a href="%s">back to play</a>!', yourls_admin_url('index.php') ) . '</p>';
|
||||
|
||||
|
||||
} else {
|
||||
/*
|
||||
step 1: create new tables and populate them, update old tables structure,
|
||||
step 2: convert each row of outdated tables if needed
|
||||
step 3: - if applicable finish updating outdated tables (indexes etc)
|
||||
- update version & db_version in options, this is all done!
|
||||
*/
|
||||
|
||||
// From what are we upgrading?
|
||||
if ( isset( $_GET['oldver'] ) && isset( $_GET['oldsql'] ) ) {
|
||||
$oldver = yourls_sanitize_version( $_GET['oldver'] );
|
||||
$oldsql = yourls_sanitize_version( $_GET['oldsql'] );
|
||||
} else {
|
||||
list( $oldver, $oldsql ) = yourls_get_current_version_from_sql();
|
||||
}
|
||||
|
||||
// To what are we upgrading ?
|
||||
$newver = YOURLS_VERSION;
|
||||
$newsql = YOURLS_DB_VERSION;
|
||||
|
||||
// Verbose & ugly details
|
||||
$ydb->show_errors = true;
|
||||
|
||||
// Let's go
|
||||
$step = ( isset( $_GET['step'] ) ? intval( $_GET['step'] ) : 0 );
|
||||
switch( $step ) {
|
||||
|
||||
default:
|
||||
case 0:
|
||||
?>
|
||||
<p><?php yourls_e( 'Your current installation needs to be upgraded.' ); ?></p>
|
||||
<p><?php yourls_e( 'Please, pretty please, it is recommended that you <strong>backup</strong> your database<br/>(you should do this regularly anyway)' ); ?></p>
|
||||
<p><?php yourls_e( "Nothing awful <em>should</em> happen, but this doesn't mean it <em>won't</em> happen, right? ;)" ); ?></p>
|
||||
<p><?php yourls_e( "On every step, if <span class='error'>something goes wrong</span>, you'll see a message and hopefully a way to fix." ); ?></p>
|
||||
<p><?php yourls_e( 'If everything goes too fast and you cannot read, <span class="success">good for you</span>, let it go :)' ); ?></p>
|
||||
<p><?php yourls_e( 'Once you are ready, press "Upgrade" !' ); ?></p>
|
||||
<?php
|
||||
echo "
|
||||
<form action='upgrade.php?' method='get'>
|
||||
<input type='hidden' name='step' value='1' />
|
||||
<input type='hidden' name='oldver' value='$oldver' />
|
||||
<input type='hidden' name='newver' value='$newver' />
|
||||
<input type='hidden' name='oldsql' value='$oldsql' />
|
||||
<input type='hidden' name='newsql' value='$newsql' />
|
||||
<input type='submit' class='primary' value='" . yourls_esc_attr__( 'Upgrade' ) . "' />
|
||||
</form>";
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
$upgrade = yourls_upgrade( $step, $oldver, $newver, $oldsql, $newsql );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$upgrade = yourls_upgrade( 3, $oldver, $newver, $oldsql, $newsql );
|
||||
echo '<p>' . yourls__( 'Your installation is now up to date ! ' ) . '</p>';
|
||||
echo '<p>' . yourls_s( 'Go back to <a href="%s">the admin interface</a>', yourls_admin_url('index.php') ) . '</p>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<?php yourls_html_footer(); ?>
|
|
@ -1,14 +0,0 @@
|
|||
/* Calendar */
|
||||
.datepicker { border-collapse: collapse; border: 2px solid #999; position: absolute; width: 215px }
|
||||
.datepicker tr.controls th { height: 22px; font-size: 11px; }
|
||||
.datepicker select { font-size: 11px; }
|
||||
.datepicker tr.days th { height: 18px; }
|
||||
.datepicker tfoot td { height: 18px; text-align: center; text-transform: capitalize; }
|
||||
.datepicker th, .datepicker tfoot td { background: #eee; font: 10px/18px Verdana, Arial, Helvetica, sans-serif; }
|
||||
.datepicker th span, .datepicker tfoot td span { font-weight: bold; }
|
||||
.datepicker tbody td { width: 24px; height: 24px; border: 1px solid #ccc; font: 11px/22px Arial, Helvetica, sans-serif; text-align: center; background: #fff; }
|
||||
.datepicker tbody td.date { cursor: pointer; }
|
||||
.datepicker tbody td.date.over { background-color: #99ffff; }
|
||||
.datepicker tbody td.date.chosen { font-weight: bold; background-color: #ccffcc; }
|
||||
/* Form defaults */
|
||||
#date_and, #date_second {display:none}
|
|
@ -1,113 +0,0 @@
|
|||
h3 span.label {
|
||||
width:100px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
ul.toggle_display {
|
||||
display:none;
|
||||
list-style-type:none;
|
||||
margin-left:0;
|
||||
margin-right:23px;
|
||||
padding:12px 5px 3px;
|
||||
border-bottom:1px solid #C7E7FF;
|
||||
}
|
||||
ul.toggle_display li {
|
||||
padding:0;
|
||||
}
|
||||
#tabs ul#headers li, #tabs ul#headers li h2, #stats_lines li{
|
||||
display: inline;
|
||||
margin-right: 10px;
|
||||
}
|
||||
#tabs ul#headers {
|
||||
border-bottom:1px solid #E3F3FF;
|
||||
padding:12px 5px 3px 5px;
|
||||
float:left;
|
||||
}
|
||||
.wrap_unfloat {
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
#tabs ul#headers li a {
|
||||
color:#595441;
|
||||
border:1px solid #C7E7FF;
|
||||
-moz-border-radius:10px 10px 0 0;
|
||||
-webkit-border-radius:10px 10px 0 0;
|
||||
border-radius:10px 10px 0 0;
|
||||
padding:10px 5px 5px 15px;
|
||||
background:#E3F3FF;
|
||||
}
|
||||
|
||||
#tabs ul#headers li a:hover {
|
||||
text-decoration:none;
|
||||
background:#88C0EB;
|
||||
}
|
||||
|
||||
#tabs ul#headers li a.selected {
|
||||
border-bottom:2px solid #fff;
|
||||
background:#fff;
|
||||
}
|
||||
|
||||
#tabs ul#headers li a.selected:hover {
|
||||
background:#fff;
|
||||
}
|
||||
|
||||
#stats_lines li a {
|
||||
-moz-border-radius:10px 10px 0 0;
|
||||
-webkit-border-radius:10px 10px 0 0;
|
||||
border-radius:10px 10px 0 0;
|
||||
padding:3px 10px;
|
||||
background:#E3F3FF;
|
||||
border:1px solid #C7E7FF;
|
||||
}
|
||||
#stats_lines li a:hover {
|
||||
text-decoration:none;
|
||||
background:#C7E7FF;
|
||||
}
|
||||
#stats_lines li a.selected {
|
||||
background:#fff;
|
||||
border:1px solid #C7E7FF;
|
||||
border-bottom:1px solid white;
|
||||
}
|
||||
#stats_lines li a.selected:hover {
|
||||
background:#fff;
|
||||
}
|
||||
.tab {
|
||||
padding:10px;
|
||||
}
|
||||
li#sites_various { padding-left:22px; padding-top:4px;}
|
||||
|
||||
li.sites_list img, #longurl img {width:16px; height: 16px; display:inline-block;}
|
||||
|
||||
#referrer_cell { min-width: 300px;}
|
||||
|
||||
#details_clicks li.bestday, #details_clicks li span.best_month, #details_clicks li span.best_year {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
ul.no_bullet {
|
||||
list-style-type: none;
|
||||
margin-left:0;
|
||||
padding:0;
|
||||
}
|
||||
ul.no_bullet li {
|
||||
margin-bottom:5px;
|
||||
}
|
||||
#historical_clicks {
|
||||
float:left;
|
||||
margin:0;
|
||||
}
|
||||
#historical_clicks li {
|
||||
padding:2px 10px;
|
||||
margin:0;
|
||||
}
|
||||
#historical_clicks li:hover {
|
||||
background:#C7E7FF !important;
|
||||
}
|
||||
#historical_clicks span.historical_link {
|
||||
min-width:130px;
|
||||
display:inline-block;
|
||||
}
|
||||
#historical_clicks span.historical_count {
|
||||
min-width:100px;
|
||||
display:inline-block;
|
||||
}
|
Before Width: | Height: | Size: 10 KiB |
|
@ -1,65 +0,0 @@
|
|||
#shareboxes, #tweet {
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
#shareboxes{
|
||||
margin-top:15px;
|
||||
}
|
||||
|
||||
div.share {
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
border:2px solid #88c0eb;
|
||||
background:#fff;
|
||||
margin-right:1em;
|
||||
padding:0 1em;
|
||||
float:left;
|
||||
height:140px;
|
||||
}
|
||||
#origlink{
|
||||
display:inline-block;
|
||||
white-space:pre;
|
||||
width:183px;
|
||||
overflow:hidden;
|
||||
vertical-align:-2px;
|
||||
}
|
||||
#copybox {
|
||||
width:250px;
|
||||
}
|
||||
#sharebox {
|
||||
width:500px;
|
||||
}
|
||||
#tweet_body {
|
||||
float:left;
|
||||
width:450px;
|
||||
height:4em;
|
||||
font-size:12px;
|
||||
}
|
||||
#charcount {
|
||||
padding-left:5px;
|
||||
color:#88c0eb;
|
||||
}
|
||||
#charcount.negative {
|
||||
color:red;
|
||||
}
|
||||
#share_links a {
|
||||
padding:0 12px 0 18px;
|
||||
font-weight:bold
|
||||
}
|
||||
#share_links a:hover {
|
||||
background-position:2px center;
|
||||
}
|
||||
#share_tw {background:transparent url(../images/twitter.png) left center no-repeat;}
|
||||
#share_fb {background:transparent url(../images/facebook.png) left center no-repeat;}
|
||||
#share_ff {background:transparent url(../images/friendfeed.png) left center no-repeat;}
|
||||
|
||||
#copylink{
|
||||
cursor:pointer;
|
||||
background:transparent url(../images/copy.png) 130% center no-repeat;
|
||||
}
|
||||
|
||||
#copylink:hover, #copylink.hover {
|
||||
background-position:100% 50%;
|
||||
}
|
||||
|
|
@ -1,330 +0,0 @@
|
|||
body {
|
||||
font-family: Verdana, Arial;
|
||||
font-size: 12px;
|
||||
color: #595441;
|
||||
background:#e3f3ff;
|
||||
text-align:center;
|
||||
margin-top:0px;
|
||||
padding-top:10px;
|
||||
}
|
||||
#wrap {
|
||||
max-width:950px;
|
||||
min-height:150px;
|
||||
margin:0 auto;
|
||||
background:white;
|
||||
text-align:left;
|
||||
padding:5px 20px 10px 20px;
|
||||
border-left:3px solid #2a85b3;
|
||||
border-right:3px solid #2a85b3;
|
||||
border-bottom:3px solid #2a85b3;
|
||||
border-top:3px solid #2a85b3;
|
||||
-moz-border-radius:20px;
|
||||
-webkit-border-radius:20px;
|
||||
border-radius:20px;
|
||||
}
|
||||
.hide-if-no-js {display: none;}
|
||||
div, p, td {
|
||||
font-family: Verdana, Arial;
|
||||
font-size: 12px;
|
||||
}
|
||||
a, a:link, a:active, a:visited {
|
||||
color: #2a85b3;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
h1 {height:50px;margin:0;float:right;max-width:500px;}
|
||||
h1 a {text-align:right;font-size:20px;float:right;}
|
||||
h1 a, h1 a:link, h1 a:active, h1 a:visited {color:#2a85b3}
|
||||
h1 a:hover{text-decoration:none;}
|
||||
h1 a:hover span{text-decoration:underline;color:#88c0eb}
|
||||
|
||||
ul#admin_menu {
|
||||
min-height:100px;
|
||||
list-style-type:none;
|
||||
padding:0;
|
||||
font-size:105%;
|
||||
}
|
||||
ul#admin_menu li {
|
||||
color:#aaa;
|
||||
padding:1px 0;
|
||||
}
|
||||
ul#admin_menu li:hover {
|
||||
list-style-type:square;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
code {
|
||||
background:#eaeaef;
|
||||
padding:0 2px;
|
||||
}
|
||||
tt {
|
||||
background:#ffc;
|
||||
padding:0 2px;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
-moz-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
border-radius:3px;
|
||||
}
|
||||
Input.text, select, textarea {
|
||||
font-family: Verdana, Arial;
|
||||
font-size: 10px;
|
||||
color: #595441;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #88c0eb;
|
||||
margin:1px;
|
||||
}
|
||||
input.button {
|
||||
font-family: Verdana, Arial;
|
||||
font-size: 10px;
|
||||
color: #595441;
|
||||
font-weight: bold;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #88c0eb;
|
||||
cursor:pointer;
|
||||
}
|
||||
input.primary {
|
||||
border:2px solid #2A85B3;
|
||||
background:#fafafe;
|
||||
}
|
||||
input.text:focus, textarea:focus {
|
||||
border:2px solid #2A85B3;
|
||||
margin:0px;
|
||||
}
|
||||
tr.edit-row td {
|
||||
background:#e3f3ff !important;
|
||||
}
|
||||
#new_url {
|
||||
text-align:center;
|
||||
padding:1px;
|
||||
border:1px solid #CDCDCD;
|
||||
background:#fff;
|
||||
clear:both;
|
||||
}
|
||||
#new_url div {
|
||||
background:#C7E7FF;
|
||||
padding:4px;
|
||||
}
|
||||
#new_url_form {
|
||||
padding:4px;
|
||||
}
|
||||
#new_url #feedback {
|
||||
background:#ff8;
|
||||
color:#88c0eb;
|
||||
width:50%;
|
||||
margin:0px 25%;
|
||||
padding:2px;
|
||||
border:1px solid #ff8;
|
||||
}
|
||||
#new_url #feedback .fail {
|
||||
color:#f55;
|
||||
}
|
||||
#add-url {width:400px}
|
||||
td.url small a{
|
||||
color:#bbc;
|
||||
}
|
||||
body.desktop td.actions input,body.desktop td.actions a {
|
||||
visibility:hidden;
|
||||
}
|
||||
td.actions input.disabled, td.actions input.loading {
|
||||
visibility:visible;
|
||||
}
|
||||
tr:hover td.actions input, tr:hover td.actions a {
|
||||
visibility:visible;
|
||||
}
|
||||
td.actions .button {
|
||||
font-family: Verdana, Arial;
|
||||
font-size: 10px;
|
||||
color: #595441;
|
||||
font-weight: bold;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #88c0eb;
|
||||
-moz-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
border-radius:3px;
|
||||
cursor:pointer;
|
||||
height:22px;
|
||||
width:22px;
|
||||
margin-top:0px;
|
||||
margin-right:5px;
|
||||
display:block;
|
||||
float:left;
|
||||
text-indent:-9999px;
|
||||
outline:0px;
|
||||
}
|
||||
td.actions .button:active {
|
||||
border:1px solid #000;
|
||||
}
|
||||
td.actions .button:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
td.actions .button.disabled, #add-button.disabled {
|
||||
border:1px solid #333;
|
||||
background:#ccc;
|
||||
}
|
||||
td.actions .button.loading, #add-button.loading {
|
||||
background:#cc7 url(../images/loading.gif) center center no-repeat;
|
||||
color:#cc7;
|
||||
}
|
||||
td.actions .button_share {
|
||||
background:transparent url(../images/share.png) 2px center no-repeat;
|
||||
}
|
||||
td.actions .button_edit {
|
||||
background:transparent url(../images/pencil.png) 2px center no-repeat;
|
||||
}
|
||||
td.actions .button_delete {
|
||||
background:transparent url(../images/delete.png) 2px center no-repeat;
|
||||
}
|
||||
td.actions .button_stats {
|
||||
background:transparent url(../images/chart_bar.png) 2px center no-repeat;
|
||||
}
|
||||
#main_table tfoot th, #main_table tfoot th div {
|
||||
font-size:10px;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
background:#fee;
|
||||
}
|
||||
.warning {
|
||||
color: orange;
|
||||
background:#ffe9bf;
|
||||
}
|
||||
.success {
|
||||
color: green;
|
||||
background:#efe;
|
||||
}
|
||||
#login {
|
||||
width: 300px;
|
||||
margin: 200px auto 0px auto;
|
||||
}
|
||||
#login p{
|
||||
font-weight: bold;
|
||||
}
|
||||
#login .text {
|
||||
width: 100%;
|
||||
}
|
||||
#login ul {
|
||||
padding-left:0px;
|
||||
list-style-type:none;
|
||||
text-indent:0;
|
||||
}
|
||||
#login ul li {
|
||||
padding:0 0 5px 20px;
|
||||
}
|
||||
#login ul.error li {
|
||||
background:transparent url(../images/cancel.png) top left no-repeat;
|
||||
}
|
||||
#login ul.warning li {
|
||||
background:transparent url(../images/error.png) top left no-repeat;
|
||||
}
|
||||
#login ul.success li {
|
||||
background:transparent url(../images/accept.png) top left no-repeat;
|
||||
}
|
||||
.sub_wrap {
|
||||
max-width:580px;
|
||||
padding-bottom:30px;
|
||||
text-align:justify;
|
||||
}
|
||||
.sub_wrap span {
|
||||
background:#ffa;
|
||||
padding:0 2px;
|
||||
}
|
||||
a.bookmarklet {
|
||||
border:2px solid #2a85b3;
|
||||
-moz-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
border-radius:3px;
|
||||
padding:5px 5px 5px 20px;
|
||||
background:#eef url(../images/favicon.gif) 2px center no-repeat;
|
||||
margin:3px;
|
||||
display:inline-block;
|
||||
}
|
||||
a.bookmarklet:hover {
|
||||
text-decoration:none;
|
||||
background-position:3px center;
|
||||
}
|
||||
#footer {
|
||||
text-align:center;
|
||||
margin-top:20px;
|
||||
}
|
||||
#footer p {
|
||||
padding:10px;
|
||||
background:white;
|
||||
margin:0 auto;
|
||||
max-width:950px;
|
||||
-moz-border-radius:10px;
|
||||
-webkit-border-radius:10px;
|
||||
border-radius:10px;
|
||||
border:2px solid #2a85b3;
|
||||
-moz-border-radius-bottomleft:30px;
|
||||
-moz-border-radius-bottomright:30px;
|
||||
-webkit-border-bottom-left-radius:25px;
|
||||
-webkit-border-bottom-right-radius:25px;
|
||||
border-bottom-left-radius:25px;
|
||||
border-bottom-right-radius:25px;
|
||||
}
|
||||
#footer p a {
|
||||
background:#fff url(../images/favicon.gif) 2px center no-repeat;
|
||||
padding-left:20px;
|
||||
}
|
||||
|
||||
.notice {
|
||||
border:1px solid #2a85b3;
|
||||
background: #F3FAFD;
|
||||
-moz-border-radius:6px;
|
||||
-webkit-border-radius:6px;
|
||||
border-radius:6px;
|
||||
width:70%;
|
||||
margin-left:15%;
|
||||
padding-left:10px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
|
||||
|
||||
.jquery-notify-bar {
|
||||
width:100%;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
z-index:32768;
|
||||
background-color:#efefef;
|
||||
font-size:18px;
|
||||
color:#000;
|
||||
text-align:center;
|
||||
font-family: Arial, Verdana, sans-serif;
|
||||
padding:20px 0px;
|
||||
border-bottom:1px solid #bbb;
|
||||
filter:alpha(opacity=95);
|
||||
-moz-opacity:0.95;
|
||||
-khtml-opacity:0.95;
|
||||
opacity:0.95;
|
||||
-moz-box-shadow: 0 1px 5px rgba(0,0,0,0.5);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
|
||||
text-shadow: 0 1px 1px rgba(0,0,0,0.1);
|
||||
}
|
||||
.jquery-notify-bar.error ,.jquery-notify-bar.fail {
|
||||
color:#f00;
|
||||
background-color:#fdd;
|
||||
}
|
||||
.jquery-notify-bar.error span,.jquery-notify-bar.fail span{
|
||||
background:transparent url("../images/error.png") no-repeat left center;
|
||||
padding-left:20px;
|
||||
}.jquery-notify-bar.success span{
|
||||
background:transparent url("../images/accept.png") no-repeat left center;
|
||||
padding-left:20px;
|
||||
}
|
||||
.jquery-notify-bar.success {
|
||||
color:#060;
|
||||
background-color:#aea;
|
||||
}
|
||||
.notify-bar-close {
|
||||
position:absolute;
|
||||
left:95%;
|
||||
font-size:11px;
|
||||
}
|
||||
tr.plugin.active a{ font-weight:bolder;}
|
||||
body.desktop tr.plugin td.plugin_desc small{ visibility:hidden;}
|
||||
tr:hover.plugin td.plugin_desc small{ visibility:visible;}
|
|
@ -1,104 +0,0 @@
|
|||
/* jQuery Table Sorter */
|
||||
table.tblSorter {
|
||||
font-family:Verdana, Arial;
|
||||
background-color: #CDCDCD;
|
||||
margin:10px 0px 0px;
|
||||
font-size: 8pt;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
table.tblSorter thead tr th, table.tblSorter tfoot tr th, table.tblSorter th.header {
|
||||
background-color: #C7E7FF;
|
||||
border: 1px solid #FFF;
|
||||
font-size: 8pt;
|
||||
padding: 4px;
|
||||
}
|
||||
table.tblSorter tfoot tr th {
|
||||
background-color: #E3F3FF;
|
||||
}
|
||||
table.tblSorter thead tr .tablesorter-header {
|
||||
background-image: url('../images/bg.gif');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center right;
|
||||
cursor: pointer;
|
||||
padding-right:10px;
|
||||
}
|
||||
table.tblSorter thead tr .sorter-false {
|
||||
background-image: none;
|
||||
cursor:default;
|
||||
}
|
||||
table.tblSorter tbody td {
|
||||
color: #3D3D3D;
|
||||
padding: 4px;
|
||||
background-color: #FFF;
|
||||
vertical-align: top;
|
||||
}
|
||||
table.tblSorter tbody tr.normal-row td {
|
||||
background: #F1F9FF;
|
||||
}
|
||||
table.tblSorter tbody tr.alt-row td {
|
||||
|
||||
}
|
||||
table.tblSorter tbody tr.normal-row:hover td {
|
||||
background-color:#F1FFF6;
|
||||
}
|
||||
table.tblSorter tbody tr.alt-row:hover td {
|
||||
background-color:#F1FFF6;
|
||||
}
|
||||
table.tblSorter thead tr .tablesorter-headerDesc {
|
||||
background-image: url('../images/desc.gif');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center right;
|
||||
}
|
||||
table.tblSorter thead tr .tablesorter-headerAsc {
|
||||
background-image: url('../images/asc.gif');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center right;
|
||||
}
|
||||
table.tblSorter thead tr .tablesorter-headerAsc, table.tblSorter thead tr .tablesorter-headerDesc {
|
||||
background-color: #91C7F2;
|
||||
}
|
||||
table.tblSorter tfoot tr {
|
||||
background-color: #BCD9E8;
|
||||
}
|
||||
#filter_form{
|
||||
float:left;
|
||||
text-align:left;
|
||||
max-width:69%;
|
||||
}
|
||||
#filter_buttons{
|
||||
float:right;
|
||||
}
|
||||
#pagination{
|
||||
text-align:right;
|
||||
float:right;
|
||||
width:30%;
|
||||
}
|
||||
.navigation .nav_total{
|
||||
display:block;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.navigation .nav_link a, .navigation .nav_current {
|
||||
border:1px solid #CDCDCD;
|
||||
margin:0px 2px;
|
||||
padding:2px 1px;
|
||||
background:#fff;
|
||||
text-align:center;
|
||||
min-width:15px;
|
||||
display:inline-block;
|
||||
}
|
||||
.navigation .nav_current {
|
||||
border:0px;
|
||||
background:none;
|
||||
}
|
||||
.navigation .nav_first a, .navigation .nav_last a {
|
||||
padding:2px 2px;
|
||||
}
|
||||
.navigation .nav_prev:before, .navigation .nav_next:after {
|
||||
content:"...";
|
||||
}
|
||||
.navigation .nav_link a:hover {
|
||||
border:1px solid #BCD9E8;
|
||||
background:#BCD9E8;
|
||||
text-decoration:none;
|
||||
}
|
Before Width: | Height: | Size: 781 B |
Before Width: | Height: | Size: 54 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 42 B |
Before Width: | Height: | Size: 587 B |
Before Width: | Height: | Size: 541 B |
Before Width: | Height: | Size: 626 B |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 715 B |
Before Width: | Height: | Size: 54 B |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 318 B |
Before Width: | Height: | Size: 88 B |
Before Width: | Height: | Size: 870 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 771 B |
Before Width: | Height: | Size: 450 B |
Before Width: | Height: | Size: 1,007 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -1,10 +0,0 @@
|
|||
Requests for PHP
|
||||
================
|
||||
|
||||
**Requests** is a HTTP library written in PHP, for human beings. It is roughly
|
||||
based on the API from the excellent [Requests Python
|
||||
library](http://python-requests.org/). **Requests** is [ISC
|
||||
Licensed](https://github.com/rmccue/Requests/blob/master/LICENSE) (similar to
|
||||
the new BSD license) and has no dependencies, except for PHP 5.2+.
|
||||
|
||||
**Requests** can be found here : https://github.com/rmccue/Requests
|
|
@ -1,863 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Requests for PHP
|
||||
*
|
||||
* Inspired by Requests for Python.
|
||||
*
|
||||
* Based on concepts from SimplePie_File, RequestCore and WP_Http.
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Requests for PHP
|
||||
*
|
||||
* Inspired by Requests for Python.
|
||||
*
|
||||
* Based on concepts from SimplePie_File, RequestCore and WP_Http.
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests {
|
||||
/**
|
||||
* POST method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const POST = 'POST';
|
||||
|
||||
/**
|
||||
* PUT method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PUT = 'PUT';
|
||||
|
||||
/**
|
||||
* GET method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const GET = 'GET';
|
||||
|
||||
/**
|
||||
* HEAD method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HEAD = 'HEAD';
|
||||
|
||||
/**
|
||||
* DELETE method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DELETE = 'DELETE';
|
||||
|
||||
/**
|
||||
* PATCH method
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc5789
|
||||
* @var string
|
||||
*/
|
||||
const PATCH = 'PATCH';
|
||||
|
||||
/**
|
||||
* Current version of Requests
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.6';
|
||||
|
||||
/**
|
||||
* Registered transport classes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $transports = array();
|
||||
|
||||
/**
|
||||
* Selected transport name
|
||||
*
|
||||
* Use {@see get_transport()} instead
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public static $transport = null;
|
||||
|
||||
/**
|
||||
* This is a static class, do not instantiate it
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* Autoloader for Requests
|
||||
*
|
||||
* Register this with {@see register_autoloader()} if you'd like to avoid
|
||||
* having to create your own.
|
||||
*
|
||||
* (You can also use `spl_autoload_register` directly if you'd prefer.)
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $class Class name to load
|
||||
*/
|
||||
public static function autoloader($class) {
|
||||
// Check that the class starts with "Requests"
|
||||
if (strpos($class, 'Requests') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = str_replace('_', '/', $class);
|
||||
if (file_exists(dirname(__FILE__) . '/' . $file . '.php')) {
|
||||
require_once(dirname(__FILE__) . '/' . $file . '.php');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the built-in autoloader
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function register_autoloader() {
|
||||
spl_autoload_register(array('Requests', 'autoloader'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a transport
|
||||
*
|
||||
* @param string $transport Transport class to add, must support the Requests_Transport interface
|
||||
*/
|
||||
public static function add_transport($transport) {
|
||||
if (empty(self::$transports)) {
|
||||
self::$transports = array(
|
||||
'Requests_Transport_cURL',
|
||||
'Requests_Transport_fsockopen',
|
||||
);
|
||||
}
|
||||
|
||||
self::$transports = array_merge(self::$transports, array($transport));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a working transport
|
||||
*
|
||||
* @throws Requests_Exception If no valid transport is found (`notransport`)
|
||||
* @return Requests_Transport
|
||||
*/
|
||||
protected static function get_transport() {
|
||||
// Caching code, don't bother testing coverage
|
||||
// @codeCoverageIgnoreStart
|
||||
if (self::$transport !== null) {
|
||||
return new self::$transport();
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
if (empty(self::$transports)) {
|
||||
self::$transports = array(
|
||||
'Requests_Transport_cURL',
|
||||
'Requests_Transport_fsockopen',
|
||||
);
|
||||
}
|
||||
|
||||
// Find us a working transport
|
||||
foreach (self::$transports as $class) {
|
||||
if (!class_exists($class))
|
||||
continue;
|
||||
|
||||
$result = call_user_func(array($class, 'test'));
|
||||
if ($result) {
|
||||
self::$transport = $class;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (self::$transport === null) {
|
||||
throw new Requests_Exception('No working transports found', 'notransport', self::$transports);
|
||||
}
|
||||
|
||||
return new self::$transport();
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @see request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $options
|
||||
* @return Requests_Response
|
||||
*/
|
||||
/**
|
||||
* Send a GET request
|
||||
*/
|
||||
public static function get($url, $headers = array(), $options = array()) {
|
||||
return self::request($url, $headers, null, self::GET, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a HEAD request
|
||||
*/
|
||||
public static function head($url, $headers = array(), $options = array()) {
|
||||
return self::request($url, $headers, null, self::HEAD, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request
|
||||
*/
|
||||
public static function delete($url, $headers = array(), $options = array()) {
|
||||
return self::request($url, $headers, null, self::DELETE, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @see request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param array $options
|
||||
* @return Requests_Response
|
||||
*/
|
||||
/**
|
||||
* Send a POST request
|
||||
*/
|
||||
public static function post($url, $headers = array(), $data = array(), $options = array()) {
|
||||
return self::request($url, $headers, $data, self::POST, $options);
|
||||
}
|
||||
/**
|
||||
* Send a PUT request
|
||||
*/
|
||||
public static function put($url, $headers = array(), $data = array(), $options = array()) {
|
||||
return self::request($url, $headers, $data, self::PUT, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PATCH request
|
||||
*
|
||||
* Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
|
||||
* specification recommends that should send an ETag
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc5789
|
||||
*/
|
||||
public static function patch($url, $headers, $data = array(), $options = array()) {
|
||||
return self::request($url, $headers, $data, self::PATCH, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Main interface for HTTP requests
|
||||
*
|
||||
* This method initiates a request and sends it via a transport before
|
||||
* parsing.
|
||||
*
|
||||
* The `$options` parameter takes an associative array with the following
|
||||
* options:
|
||||
*
|
||||
* - `timeout`: How long should we wait for a response?
|
||||
* (integer, seconds, default: 10)
|
||||
* - `useragent`: Useragent to send to the server
|
||||
* (string, default: php-requests/$version)
|
||||
* - `follow_redirects`: Should we follow 3xx redirects?
|
||||
* (boolean, default: true)
|
||||
* - `redirects`: How many times should we redirect before erroring?
|
||||
* (integer, default: 10)
|
||||
* - `blocking`: Should we block processing on this request?
|
||||
* (boolean, default: true)
|
||||
* - `filename`: File to stream the body to instead.
|
||||
* (string|boolean, default: false)
|
||||
* - `auth`: Authentication handler or array of user/password details to use
|
||||
* for Basic authentication
|
||||
* (Requests_Auth|array|boolean, default: false)
|
||||
* - `proxy`: Proxy details to use for proxy by-passing and authentication
|
||||
* (Requests_Proxy|array|boolean, default: false)
|
||||
* - `idn`: Enable IDN parsing
|
||||
* (boolean, default: true)
|
||||
* - `transport`: Custom transport. Either a class name, or a
|
||||
* transport object. Defaults to the first working transport from
|
||||
* {@see getTransport()}
|
||||
* (string|Requests_Transport, default: {@see getTransport()})
|
||||
* - `hooks`: Hooks handler.
|
||||
* (Requests_Hooker, default: new Requests_Hooks())
|
||||
* - `verify`: Should we verify SSL certificates? Allows passing in a custom
|
||||
* certificate file as a string. (Using true uses the system-wide root
|
||||
* certificate store instead, but this may have different behaviour
|
||||
* across transports.)
|
||||
* (string|boolean, default: library/Requests/Transport/cacert.pem)
|
||||
* - `verifyname`: Should we verify the common name in the SSL certificate?
|
||||
* (boolean: default, true)
|
||||
*
|
||||
* @throws Requests_Exception On invalid URLs (`nonhttp`)
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Extra headers to send with the request
|
||||
* @param array $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
|
||||
* @param string $type HTTP request type (use Requests constants)
|
||||
* @param array $options Options for the request (see description for more information)
|
||||
* @return Requests_Response
|
||||
*/
|
||||
public static function request($url, $headers = array(), $data = array(), $type = self::GET, $options = array()) {
|
||||
if (empty($options['type'])) {
|
||||
$options['type'] = $type;
|
||||
}
|
||||
$options = array_merge(self::get_default_options(), $options);
|
||||
|
||||
self::set_defaults($url, $headers, $data, $type, $options);
|
||||
|
||||
$options['hooks']->dispatch('requests.before_request', array(&$url, &$headers, &$data, &$type, &$options));
|
||||
|
||||
if (!empty($options['transport'])) {
|
||||
$transport = $options['transport'];
|
||||
|
||||
if (is_string($options['transport'])) {
|
||||
$transport = new $transport();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$transport = self::get_transport();
|
||||
}
|
||||
$response = $transport->request($url, $headers, $data, $options);
|
||||
|
||||
$options['hooks']->dispatch('requests.before_parse', array(&$response, $url, $headers, $data, $type, $options));
|
||||
|
||||
return self::parse_response($response, $url, $headers, $data, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple HTTP requests simultaneously
|
||||
*
|
||||
* The `$requests` parameter takes an associative or indexed array of
|
||||
* request fields. The key of each request can be used to match up the
|
||||
* request with the returned data, or with the request passed into your
|
||||
* `multiple.request.complete` callback.
|
||||
*
|
||||
* The request fields value is an associative array with the following keys:
|
||||
*
|
||||
* - `url`: Request URL Same as the `$url` parameter to
|
||||
* {@see Requests::request}
|
||||
* (string, required)
|
||||
* - `headers`: Associative array of header fields. Same as the `$headers`
|
||||
* parameter to {@see Requests::request}
|
||||
* (array, default: `array()`)
|
||||
* - `data`: Associative array of data fields or a string. Same as the
|
||||
* `$data` parameter to {@see Requests::request}
|
||||
* (array|string, default: `array()`)
|
||||
* - `type`: HTTP request type (use Requests constants). Same as the `$type`
|
||||
* parameter to {@see Requests::request}
|
||||
* (string, default: `Requests::GET`)
|
||||
* - `data`: Associative array of options. Same as the `$options` parameter
|
||||
* to {@see Requests::request}
|
||||
* (array, default: see {@see Requests::request})
|
||||
* - `cookies`: Associative array of cookie name to value, or cookie jar.
|
||||
* (array|Requests_Cookie_Jar)
|
||||
*
|
||||
* If the `$options` parameter is specified, individual requests will
|
||||
* inherit options from it. This can be used to use a single hooking system,
|
||||
* or set all the types to `Requests::POST`, for example.
|
||||
*
|
||||
* In addition, the `$options` parameter takes the following global options:
|
||||
*
|
||||
* - `complete`: A callback for when a request is complete. Takes two
|
||||
* parameters, a Requests_Response/Requests_Exception reference, and the
|
||||
* ID from the request array (Note: this can also be overridden on a
|
||||
* per-request basis, although that's a little silly)
|
||||
* (callback)
|
||||
*
|
||||
* @param array $requests Requests data (see description for more information)
|
||||
* @param array $options Global and default options (see {@see Requests::request})
|
||||
* @return array Responses (either Requests_Response or a Requests_Exception object)
|
||||
*/
|
||||
public static function request_multiple($requests, $options = array()) {
|
||||
$options = array_merge(self::get_default_options(true), $options);
|
||||
|
||||
if (!empty($options['hooks'])) {
|
||||
$options['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
|
||||
if (!empty($options['complete'])) {
|
||||
$options['hooks']->register('multiple.request.complete', $options['complete']);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($requests as $id => &$request) {
|
||||
if (!isset($request['headers'])) {
|
||||
$request['headers'] = array();
|
||||
}
|
||||
if (!isset($request['data'])) {
|
||||
$request['data'] = array();
|
||||
}
|
||||
if (!isset($request['type'])) {
|
||||
$request['type'] = self::GET;
|
||||
}
|
||||
if (!isset($request['options'])) {
|
||||
$request['options'] = $options;
|
||||
$request['options']['type'] = $request['type'];
|
||||
}
|
||||
else {
|
||||
if (empty($request['options']['type'])) {
|
||||
$request['options']['type'] = $request['type'];
|
||||
}
|
||||
$request['options'] = array_merge($options, $request['options']);
|
||||
}
|
||||
|
||||
self::set_defaults($request['url'], $request['headers'], $request['data'], $request['type'], $request['options']);
|
||||
|
||||
// Ensure we only hook in once
|
||||
if ($request['options']['hooks'] !== $options['hooks']) {
|
||||
$request['options']['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
|
||||
if (!empty($request['options']['complete'])) {
|
||||
$request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($request);
|
||||
|
||||
if (!empty($options['transport'])) {
|
||||
$transport = $options['transport'];
|
||||
|
||||
if (is_string($options['transport'])) {
|
||||
$transport = new $transport();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$transport = self::get_transport();
|
||||
}
|
||||
$responses = $transport->request_multiple($requests, $options);
|
||||
|
||||
foreach ($responses as $id => &$response) {
|
||||
// If our hook got messed with somehow, ensure we end up with the
|
||||
// correct response
|
||||
if (is_string($response)) {
|
||||
$request = $requests[$id];
|
||||
self::parse_multiple($response, $request);
|
||||
$request['options']['hooks']->dispatch('multiple.request.complete', array(&$response, $id));
|
||||
}
|
||||
}
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default options
|
||||
*
|
||||
* @see Requests::request() for values returned by this method
|
||||
* @param boolean $multirequest Is this a multirequest?
|
||||
* @return array Default option values
|
||||
*/
|
||||
protected static function get_default_options($multirequest = false) {
|
||||
$defaults = array(
|
||||
'timeout' => 10,
|
||||
'useragent' => 'php-requests/' . self::VERSION,
|
||||
'redirected' => 0,
|
||||
'redirects' => 10,
|
||||
'follow_redirects' => true,
|
||||
'blocking' => true,
|
||||
'type' => self::GET,
|
||||
'filename' => false,
|
||||
'auth' => false,
|
||||
'proxy' => false,
|
||||
'cookies' => false,
|
||||
'idn' => true,
|
||||
'hooks' => null,
|
||||
'transport' => null,
|
||||
'verify' => dirname( __FILE__ ) . '/Requests/Transport/cacert.pem',
|
||||
'verifyname' => true,
|
||||
);
|
||||
if ($multirequest !== false) {
|
||||
$defaults['complete'] = null;
|
||||
}
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default values
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Extra headers to send with the request
|
||||
* @param array $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
|
||||
* @param string $type HTTP request type
|
||||
* @param array $options Options for the request
|
||||
* @return array $options
|
||||
*/
|
||||
protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) {
|
||||
if (!preg_match('/^http(s)?:\/\//i', $url)) {
|
||||
throw new Requests_Exception('Only HTTP requests are handled.', 'nonhttp', $url);
|
||||
}
|
||||
|
||||
if (empty($options['hooks'])) {
|
||||
$options['hooks'] = new Requests_Hooks();
|
||||
}
|
||||
|
||||
if (is_array($options['auth'])) {
|
||||
$options['auth'] = new Requests_Auth_Basic($options['auth']);
|
||||
}
|
||||
if ($options['auth'] !== false) {
|
||||
$options['auth']->register($options['hooks']);
|
||||
}
|
||||
|
||||
if (!empty($options['proxy'])) {
|
||||
$options['proxy'] = new Requests_Proxy_HTTP($options['proxy']);
|
||||
}
|
||||
if ($options['proxy'] !== false) {
|
||||
$options['proxy']->register($options['hooks']);
|
||||
}
|
||||
|
||||
if (is_array($options['cookies'])) {
|
||||
$options['cookies'] = new Requests_Cookie_Jar($options['cookies']);
|
||||
}
|
||||
elseif (empty($options['cookies'])) {
|
||||
$options['cookies'] = new Requests_Cookie_Jar();
|
||||
}
|
||||
if ($options['cookies'] !== false) {
|
||||
$options['cookies']->register($options['hooks']);
|
||||
}
|
||||
|
||||
if ($options['idn'] !== false) {
|
||||
$iri = new Requests_IRI($url);
|
||||
$iri->host = Requests_IDNAEncoder::encode($iri->ihost);
|
||||
$url = $iri->uri;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP response parser
|
||||
*
|
||||
* @throws Requests_Exception On missing head/body separator (`requests.no_crlf_separator`)
|
||||
* @throws Requests_Exception On missing head/body separator (`noversion`)
|
||||
* @throws Requests_Exception On missing head/body separator (`toomanyredirects`)
|
||||
*
|
||||
* @param string $headers Full response text including headers and body
|
||||
* @param string $url Original request URL
|
||||
* @param array $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects
|
||||
* @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects
|
||||
* @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects
|
||||
* @return Requests_Response
|
||||
*/
|
||||
protected static function parse_response($headers, $url, $req_headers, $req_data, $options) {
|
||||
$return = new Requests_Response();
|
||||
if (!$options['blocking']) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
$return->raw = $headers;
|
||||
$return->url = $url;
|
||||
|
||||
if (!$options['filename']) {
|
||||
if (($pos = strpos($headers, "\r\n\r\n")) === false) {
|
||||
// Crap!
|
||||
throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');
|
||||
}
|
||||
|
||||
$headers = substr($return->raw, 0, $pos);
|
||||
$return->body = substr($return->raw, $pos + strlen("\n\r\n\r"));
|
||||
}
|
||||
else {
|
||||
$return->body = '';
|
||||
}
|
||||
// Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
|
||||
$headers = str_replace("\r\n", "\n", $headers);
|
||||
// Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2)
|
||||
$headers = preg_replace('/\n[ \t]/', ' ', $headers);
|
||||
$headers = explode("\n", $headers);
|
||||
preg_match('#^HTTP/1\.\d[ \t]+(\d+)#i', array_shift($headers), $matches);
|
||||
if (empty($matches)) {
|
||||
throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);
|
||||
}
|
||||
$return->status_code = (int) $matches[1];
|
||||
if ($return->status_code >= 200 && $return->status_code < 300) {
|
||||
$return->success = true;
|
||||
}
|
||||
|
||||
foreach ($headers as $header) {
|
||||
list($key, $value) = explode(':', $header, 2);
|
||||
$value = trim($value);
|
||||
preg_replace('#(\s+)#i', ' ', $value);
|
||||
$return->headers[$key] = $value;
|
||||
}
|
||||
if (isset($return->headers['transfer-encoding'])) {
|
||||
$return->body = self::decode_chunked($return->body);
|
||||
unset($return->headers['transfer-encoding']);
|
||||
}
|
||||
if (isset($return->headers['content-encoding'])) {
|
||||
$return->body = self::decompress($return->body);
|
||||
}
|
||||
|
||||
//fsockopen and cURL compatibility
|
||||
if (isset($return->headers['connection'])) {
|
||||
unset($return->headers['connection']);
|
||||
}
|
||||
|
||||
$options['hooks']->dispatch('requests.before_redirect_check', array(&$return, $req_headers, $req_data, $options));
|
||||
|
||||
if ((in_array($return->status_code, array(300, 301, 302, 303, 307)) || $return->status_code > 307 && $return->status_code < 400) && $options['follow_redirects'] === true) {
|
||||
if (isset($return->headers['location']) && $options['redirected'] < $options['redirects']) {
|
||||
if ($return->status_code === 303) {
|
||||
$options['type'] = Requests::GET;
|
||||
}
|
||||
$options['redirected']++;
|
||||
$location = $return->headers['location'];
|
||||
if (strpos ($location, '/') === 0) {
|
||||
// relative redirect, for compatibility make it absolute
|
||||
$location = Requests_IRI::absolutize($url, $location);
|
||||
$location = $location->uri;
|
||||
}
|
||||
$redirected = self::request($location, $req_headers, $req_data, false, $options);
|
||||
$redirected->history[] = $return;
|
||||
return $redirected;
|
||||
}
|
||||
elseif ($options['redirected'] >= $options['redirects']) {
|
||||
throw new Requests_Exception('Too many redirects', 'toomanyredirects', $return);
|
||||
}
|
||||
}
|
||||
|
||||
$return->redirects = $options['redirected'];
|
||||
|
||||
$options['hooks']->dispatch('requests.after_request', array(&$return, $req_headers, $req_data, $options));
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for `transport.internal.parse_response`
|
||||
*
|
||||
* Internal use only. Converts a raw HTTP response to a Requests_Response
|
||||
* while still executing a multiple request.
|
||||
*
|
||||
* @param string $headers Full response text including headers and body
|
||||
* @param array $request Request data as passed into {@see Requests::request_multiple()}
|
||||
* @return null `$response` is either set to a Requests_Response instance, or a Requests_Exception object
|
||||
*/
|
||||
public static function parse_multiple(&$response, $request) {
|
||||
try {
|
||||
$response = self::parse_response($response, $request['url'], $request['headers'], $request['data'], $request['options']);
|
||||
}
|
||||
catch (Requests_Exception $e) {
|
||||
$response = $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoded a chunked body as per RFC 2616
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2616#section-3.6.1
|
||||
* @param string $data Chunked body
|
||||
* @return string Decoded body
|
||||
*/
|
||||
protected static function decode_chunked($data) {
|
||||
if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($data))) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$decoded = '';
|
||||
$encoded = $data;
|
||||
|
||||
while (true) {
|
||||
$is_chunked = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches );
|
||||
if (!$is_chunked) {
|
||||
// Looks like it's not chunked after all
|
||||
return $data;
|
||||
}
|
||||
|
||||
$length = hexdec(trim($matches[1]));
|
||||
if ($length === 0) {
|
||||
// Ignore trailer headers
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
$chunk_length = strlen($matches[0]);
|
||||
$decoded .= $part = substr($encoded, $chunk_length, $length);
|
||||
$encoded = substr($encoded, $chunk_length + $length + 2);
|
||||
|
||||
if (trim($encoded) === '0' || empty($encoded)) {
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
// We'll never actually get down here
|
||||
// @codeCoverageIgnoreStart
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
/**
|
||||
* Convert a key => value array to a 'key: value' array for headers
|
||||
*
|
||||
* @param array $array Dictionary of header values
|
||||
* @return array List of headers
|
||||
*/
|
||||
public static function flatten($array) {
|
||||
$return = array();
|
||||
foreach ($array as $key => $value) {
|
||||
$return[] = "$key: $value";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a key => value array to a 'key: value' array for headers
|
||||
*
|
||||
* @deprecated Misspelling of {@see Requests::flatten}
|
||||
* @param array $array Dictionary of header values
|
||||
* @return array List of headers
|
||||
*/
|
||||
public static function flattern($array) {
|
||||
return self::flatten($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress an encoded body
|
||||
*
|
||||
* Implements gzip, compress and deflate. Guesses which it is by attempting
|
||||
* to decode.
|
||||
*
|
||||
* @todo Make this smarter by defaulting to whatever the headers say first
|
||||
* @param string $data Compressed data in one of the above formats
|
||||
* @return string Decompressed string
|
||||
*/
|
||||
public static function decompress($data) {
|
||||
if (substr($data, 0, 2) !== "\x1f\x8b" && substr($data, 0, 2) !== "\x78\x9c") {
|
||||
// Not actually compressed. Probably cURL ruining this for us.
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (function_exists('gzdecode') && ($decoded = @gzdecode($data)) !== false) {
|
||||
return $decoded;
|
||||
}
|
||||
elseif (function_exists('gzinflate') && ($decoded = @gzinflate($data)) !== false) {
|
||||
return $decoded;
|
||||
}
|
||||
elseif (($decoded = self::compatible_gzinflate($data)) !== false) {
|
||||
return $decoded;
|
||||
}
|
||||
elseif (function_exists('gzuncompress') && ($decoded = @gzuncompress($data)) !== false) {
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompression of deflated string while staying compatible with the majority of servers.
|
||||
*
|
||||
* Certain Servers will return deflated data with headers which PHP's gzinflate()
|
||||
* function cannot handle out of the box. The following function has been created from
|
||||
* various snippets on the gzinflate() PHP documentation.
|
||||
*
|
||||
* Warning: Magic numbers within. Due to the potential different formats that the compressed
|
||||
* data may be returned in, some "magic offsets" are needed to ensure proper decompression
|
||||
* takes place. For a simple progmatic way to determine the magic offset in use, see:
|
||||
* http://core.trac.wordpress.org/ticket/18273
|
||||
*
|
||||
* @since 2.8.1
|
||||
* @link http://core.trac.wordpress.org/ticket/18273
|
||||
* @link http://au2.php.net/manual/en/function.gzinflate.php#70875
|
||||
* @link http://au2.php.net/manual/en/function.gzinflate.php#77336
|
||||
*
|
||||
* @param string $gzData String to decompress.
|
||||
* @return string|bool False on failure.
|
||||
*/
|
||||
public static function compatible_gzinflate($gzData) {
|
||||
// Compressed data might contain a full zlib header, if so strip it for
|
||||
// gzinflate()
|
||||
if ( substr($gzData, 0, 3) == "\x1f\x8b\x08" ) {
|
||||
$i = 10;
|
||||
$flg = ord( substr($gzData, 3, 1) );
|
||||
if ( $flg > 0 ) {
|
||||
if ( $flg & 4 ) {
|
||||
list($xlen) = unpack('v', substr($gzData, $i, 2) );
|
||||
$i = $i + 2 + $xlen;
|
||||
}
|
||||
if ( $flg & 8 )
|
||||
$i = strpos($gzData, "\0", $i) + 1;
|
||||
if ( $flg & 16 )
|
||||
$i = strpos($gzData, "\0", $i) + 1;
|
||||
if ( $flg & 2 )
|
||||
$i = $i + 2;
|
||||
}
|
||||
$decompressed = self::compatible_gzinflate( substr( $gzData, $i ) );
|
||||
if ( false !== $decompressed ) {
|
||||
return $decompressed;
|
||||
}
|
||||
}
|
||||
|
||||
// If the data is Huffman Encoded, we must first strip the leading 2
|
||||
// byte Huffman marker for gzinflate()
|
||||
// The response is Huffman coded by many compressors such as
|
||||
// java.util.zip.Deflater, Ruby’s Zlib::Deflate, and .NET's
|
||||
// System.IO.Compression.DeflateStream.
|
||||
//
|
||||
// See http://decompres.blogspot.com/ for a quick explanation of this
|
||||
// data type
|
||||
$huffman_encoded = false;
|
||||
|
||||
// low nibble of first byte should be 0x08
|
||||
list( , $first_nibble ) = unpack( 'h', $gzData );
|
||||
|
||||
// First 2 bytes should be divisible by 0x1F
|
||||
list( , $first_two_bytes ) = unpack( 'n', $gzData );
|
||||
|
||||
if ( 0x08 == $first_nibble && 0 == ( $first_two_bytes % 0x1F ) )
|
||||
$huffman_encoded = true;
|
||||
|
||||
if ( $huffman_encoded ) {
|
||||
if ( false !== ( $decompressed = @gzinflate( substr( $gzData, 2 ) ) ) )
|
||||
return $decompressed;
|
||||
}
|
||||
|
||||
if ( "\x50\x4b\x03\x04" == substr( $gzData, 0, 4 ) ) {
|
||||
// ZIP file format header
|
||||
// Offset 6: 2 bytes, General-purpose field
|
||||
// Offset 26: 2 bytes, filename length
|
||||
// Offset 28: 2 bytes, optional field length
|
||||
// Offset 30: Filename field, followed by optional field, followed
|
||||
// immediately by data
|
||||
list( , $general_purpose_flag ) = unpack( 'v', substr( $gzData, 6, 2 ) );
|
||||
|
||||
// If the file has been compressed on the fly, 0x08 bit is set of
|
||||
// the general purpose field. We can use this to differentiate
|
||||
// between a compressed document, and a ZIP file
|
||||
$zip_compressed_on_the_fly = ( 0x08 == (0x08 & $general_purpose_flag ) );
|
||||
|
||||
if ( ! $zip_compressed_on_the_fly ) {
|
||||
// Don't attempt to decode a compressed zip file
|
||||
return $gzData;
|
||||
}
|
||||
|
||||
// Determine the first byte of data, based on the above ZIP header
|
||||
// offsets:
|
||||
$first_file_start = array_sum( unpack( 'v2', substr( $gzData, 26, 4 ) ) );
|
||||
if ( false !== ( $decompressed = @gzinflate( substr( $gzData, 30 + $first_file_start ) ) ) ) {
|
||||
return $decompressed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finally fall back to straight gzinflate
|
||||
if ( false !== ( $decompressed = @gzinflate( $gzData ) ) ) {
|
||||
return $decompressed;
|
||||
}
|
||||
|
||||
// Fallback for all above failing, not expected, but included for
|
||||
// debugging and preventing regressions and to track stats
|
||||
if ( false !== ( $decompressed = @gzinflate( substr( $gzData, 2 ) ) ) ) {
|
||||
return $decompressed;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function match_domain($host, $reference) {
|
||||
// Check for a direct match
|
||||
if ($host === $reference) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the valid wildcard match if the host is not an IP address
|
||||
// Also validates that the host has 3 parts or more, as per Firefox's
|
||||
// ruleset.
|
||||
$parts = explode('.', $host);
|
||||
if (ip2long($host) === false && count($parts) >= 3) {
|
||||
$parts[0] = '*';
|
||||
$wildcard = implode('.', $parts);
|
||||
if ($wildcard === $reference) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Authentication provider interface
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
|
||||
/**
|
||||
* Authentication provider interface
|
||||
*
|
||||
* Implement this interface to act as an authentication provider.
|
||||
*
|
||||
* Parameters should be passed via the constructor where possible, as this
|
||||
* makes it much easier for users to use your provider.
|
||||
*
|
||||
* @see Requests_Hooks
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
interface Requests_Auth {
|
||||
/**
|
||||
* Register hooks as needed
|
||||
*
|
||||
* This method is called in {@see Requests::request} when the user has set
|
||||
* an instance as the 'auth' option. Use this callback to register all the
|
||||
* hooks you'll need.
|
||||
*
|
||||
* @see Requests_Hooks::register
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Basic Authentication provider
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic Authentication provider
|
||||
*
|
||||
* Provides a handler for Basic HTTP authentication via the Authorization
|
||||
* header.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
class Requests_Auth_Basic implements Requests_Auth {
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pass;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws Requests_Exception On incorrect number of arguments (`authbasicbadargs`)
|
||||
* @param array|null $args Array of user and password. Must have exactly two elements
|
||||
*/
|
||||
public function __construct($args = null) {
|
||||
if (is_array($args)) {
|
||||
if (count($args) !== 2) {
|
||||
throw new Requests_Exception('Invalid number of arguments', 'authbasicbadargs');
|
||||
}
|
||||
|
||||
list($this->user, $this->pass) = $args;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the necessary callbacks
|
||||
*
|
||||
* @see curl_before_send
|
||||
* @see fsockopen_header
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks) {
|
||||
$hooks->register('curl.before_send', array(&$this, 'curl_before_send'));
|
||||
$hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cURL parameters before the data is sent
|
||||
*
|
||||
* @param resource $handle cURL resource
|
||||
*/
|
||||
public function curl_before_send(&$handle) {
|
||||
curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($handle, CURLOPT_USERPWD, $this->getAuthString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra headers to the request before sending
|
||||
*
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_header(&$out) {
|
||||
$out .= "Authorization: Basic " . base64_encode($this->getAuthString()) . "\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication string (user:pass)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthString() {
|
||||
return $this->user . ':' . $this->pass;
|
||||
}
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Cookie storage object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cookie storage object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
class Requests_Cookie {
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Cookie attributes
|
||||
*
|
||||
* Valid keys are (currently) path, domain, expires, max-age, secure and
|
||||
* httponly.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $attributes = array();
|
||||
|
||||
/**
|
||||
* Create a new cookie object
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array $attributes Associative array of attribute data
|
||||
*/
|
||||
public function __construct($name, $value, $attributes = array()) {
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a cookie for a Cookie header
|
||||
*
|
||||
* This is used when sending cookies to a server.
|
||||
*
|
||||
* @return string Cookie formatted for Cookie header
|
||||
*/
|
||||
public function formatForHeader() {
|
||||
return sprintf('%s=%s', $this->name, $this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a cookie for a Set-Cookie header
|
||||
*
|
||||
* This is used when sending cookies to clients. This isn't really
|
||||
* applicable to client-side usage, but might be handy for debugging.
|
||||
*
|
||||
* @return string Cookie formatted for Set-Cookie header
|
||||
*/
|
||||
public function formatForSetCookie() {
|
||||
$header_value = $this->formatForHeader();
|
||||
if (!empty($this->attributes)) {
|
||||
$parts = array();
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
// Ignore non-associative attributes
|
||||
if (is_numeric($key)) {
|
||||
$parts[] = $value;
|
||||
}
|
||||
else {
|
||||
$parts[] = sprintf('%s=%s', $key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$header_value .= '; ' . implode('; ', $parts);
|
||||
}
|
||||
return $header_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie value
|
||||
*
|
||||
* Attributes and other data can be accessed via methods.
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a cookie string into a cookie object
|
||||
*
|
||||
* Based on Mozilla's parsing code in Firefox and related projects, which
|
||||
* is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265
|
||||
* specifies some of this handling, but not in a thorough manner.
|
||||
*
|
||||
* @param string Cookie header value (from a Set-Cookie header)
|
||||
* @return Requests_Cookie Parsed cookie object
|
||||
*/
|
||||
public static function parse($string, $name = '') {
|
||||
$parts = explode(';', $string);
|
||||
$kvparts = array_shift($parts);
|
||||
|
||||
if (!empty($name)) {
|
||||
$value = $string;
|
||||
}
|
||||
elseif (strpos($kvparts, '=') === false) {
|
||||
// Some sites might only have a value without the equals separator.
|
||||
// Deviate from RFC 6265 and pretend it was actually a blank name
|
||||
// (`=foo`)
|
||||
//
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=169091
|
||||
$name = '';
|
||||
$value = $kvparts;
|
||||
}
|
||||
else {
|
||||
list($name, $value) = explode('=', $kvparts, 2);
|
||||
}
|
||||
$name = trim($name);
|
||||
$value = trim($value);
|
||||
|
||||
// Attribute key are handled case-insensitively
|
||||
$attributes = new Requests_Utility_CaseInsensitiveDictionary();
|
||||
|
||||
if (!empty($parts)) {
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '=') === false) {
|
||||
$part_key = $part;
|
||||
$part_value = true;
|
||||
}
|
||||
else {
|
||||
list($part_key, $part_value) = explode('=', $part, 2);
|
||||
$part_value = trim($part_value);
|
||||
}
|
||||
|
||||
$part_key = trim($part_key);
|
||||
$attributes[$part_key] = $part_value;
|
||||
}
|
||||
}
|
||||
|
||||
return new Requests_Cookie($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all Set-Cookie headers from request headers
|
||||
*
|
||||
* @param Requests_Response_Headers $headers
|
||||
* @return array
|
||||
*/
|
||||
public static function parseFromHeaders(Requests_Response_Headers $headers) {
|
||||
$cookie_headers = $headers->getValues('Set-Cookie');
|
||||
if (empty($cookie_headers)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$cookies = array();
|
||||
foreach ($cookie_headers as $header) {
|
||||
$parsed = self::parse($header);
|
||||
$cookies[$parsed->name] = $parsed;
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Cookie holder object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cookie holder object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
class Requests_Cookie_Jar implements ArrayAccess, IteratorAggregate {
|
||||
/**
|
||||
* Actual item data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Create a new jar
|
||||
*
|
||||
* @param array $cookies Existing cookie values
|
||||
*/
|
||||
public function __construct($cookies = array()) {
|
||||
$this->cookies = $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise cookie data into a Requests_Cookie
|
||||
*
|
||||
* @param string|Requests_Cookie $cookie
|
||||
* @return Requests_Cookie
|
||||
*/
|
||||
public function normalizeCookie($cookie, $key = null) {
|
||||
if ($cookie instanceof Requests_Cookie) {
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
return Requests_Cookie::parse($cookie, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item exists
|
||||
*
|
||||
* @param string $key Item key
|
||||
* @return boolean Does the item exist?
|
||||
*/
|
||||
public function offsetExists($key) {
|
||||
return isset($this->cookies[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the item
|
||||
*
|
||||
* @param string $key Item key
|
||||
* @return string Item value
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
if (!isset($this->cookies[$key]))
|
||||
return null;
|
||||
|
||||
return $this->cookies[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*
|
||||
* @param string $key Item name
|
||||
* @param string $value Item value
|
||||
*/
|
||||
public function offsetSet($key, $value) {
|
||||
if ($key === null) {
|
||||
throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
$this->cookies[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the given header
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
public function offsetUnset($key) {
|
||||
unset($this->cookies[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the cookie handler with the request's hooking system
|
||||
*
|
||||
* @param Requests_Hooker $hooks Hooking system
|
||||
*/
|
||||
public function register(Requests_Hooker $hooks) {
|
||||
$hooks->register('requests.before_request', array($this, 'before_request'));
|
||||
$hooks->register('requests.before_redirect_check', array($this, 'before_redirect_check'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Cookie header to a request if we have any
|
||||
*
|
||||
* As per RFC 6265, cookies are separated by '; '
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*/
|
||||
public function before_request(&$url, &$headers, &$data, &$type, &$options) {
|
||||
if (!empty($this->cookies)) {
|
||||
$cookies = array();
|
||||
foreach ($this->cookies as $key => $cookie) {
|
||||
$cookie = $this->normalizeCookie($cookie, $key);
|
||||
$cookies[] = $cookie->formatForHeader();
|
||||
}
|
||||
|
||||
$headers['Cookie'] = implode('; ', $cookies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all cookies from a response and attach them to the response
|
||||
*
|
||||
* @var Requests_Response $response
|
||||
*/
|
||||
public function before_redirect_check(Requests_Response &$return) {
|
||||
$cookies = Requests_Cookie::parseFromHeaders($return->headers);
|
||||
$this->cookies = array_merge($this->cookies, $cookies);
|
||||
$return->cookies = $this;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for HTTP requests
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for HTTP requests
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception extends Exception {
|
||||
/**
|
||||
* Type of exception
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Data associated with the exception
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* @param string $message Exception message
|
||||
* @param string $type Exception type
|
||||
* @param mixed $data Associated data
|
||||
* @param integer $code Exception numerical code, if applicable
|
||||
*/
|
||||
public function __construct($message, $type, $data = null, $code = 0) {
|
||||
parent::__construct($message, $code);
|
||||
|
||||
$this->type = $type;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@see getCode()}, but a string code.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives any relevant data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception based on HTTP response
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception based on HTTP response
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP extends Requests_Exception {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* There is no mechanism to pass in the status code, as this is set by the
|
||||
* subclass used. Reason phrases can vary, however.
|
||||
*
|
||||
* @param string $reason Reason phrase
|
||||
* @param mixed $data Associated data
|
||||
*/
|
||||
public function __construct($reason = null, $data = null) {
|
||||
if ($reason !== null) {
|
||||
$this->reason = $reason;
|
||||
}
|
||||
|
||||
$message = sprintf('%d %s', $this->code, $this->reason);
|
||||
parent::__construct($message, 'httpresponse', $data, $this->code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status message
|
||||
*/
|
||||
public function getReason() {
|
||||
return $this->reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct exception class for a given error code
|
||||
*
|
||||
* @param int $code HTTP status code
|
||||
* @return string Exception class name to use
|
||||
*/
|
||||
public static function get_class($code) {
|
||||
$class = sprintf('Requests_Exception_HTTP_%d', $code);
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
return 'Requests_Exception_HTTP_Unknown';
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 400 Bad Request responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 400 Bad Request responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_400 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 400;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Bad Request';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 401 Unauthorized responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 401 Unauthorized responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_401 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 401;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unauthorized';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 402 Payment Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 402 Payment Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_402 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 402;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Payment Required';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 403 Forbidden responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 403 Forbidden responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_403 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 403;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Forbidden';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 404 Not Found responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 404 Not Found responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_404 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 404;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Found';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 405 Method Not Allowed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 405 Method Not Allowed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_405 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 405;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Method Not Allowed';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 406 Not Acceptable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 406 Not Acceptable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_406 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 406;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Acceptable';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 407 Proxy Authentication Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 407 Proxy Authentication Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_407 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 407;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Proxy Authentication Required';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 408 Request Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 408 Request Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_408 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 408;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Timeout';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 409 Conflict responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 409 Conflict responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_409 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 409;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Conflict';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 410 Gone responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 410 Gone responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_410 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 410;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Gone';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 411 Length Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 411 Length Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_411 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 411;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Length Required';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 412 Precondition Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 412 Precondition Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_412 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 412;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Precondition Failed';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 413 Request Entity Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 413 Request Entity Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_413 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 413;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Entity Too Large';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 414 Request-URI Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 414 Request-URI Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_414 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 414;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request-URI Too Large';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 415 Unsupported Media Type responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 415 Unsupported Media Type responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_415 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 415;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unsupported Media Type';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 416 Requested Range Not Satisfiable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 416 Requested Range Not Satisfiable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_416 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 416;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Requested Range Not Satisfiable';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 417 Expectation Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 417 Expectation Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_417 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 417;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Expectation Failed';
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 418 I'm A Teapot responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2324
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 418 I'm A Teapot responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2324
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_418 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 418;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = "I'm A Teapot";
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 428 Precondition Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 428 Precondition Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_428 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 428;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Precondition Required';
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 429 Too Many Requests responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/draft-nottingham-http-new-status-04
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 429 Too Many Requests responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/draft-nottingham-http-new-status-04
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_429 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 429;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Too Many Requests';
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 431 Request Header Fields Too Large responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 431 Request Header Fields Too Large responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_431 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 431;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Header Fields Too Large';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 500 Internal Server Error responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 500 Internal Server Error responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_500 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 500;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Internal Server Error';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 501 Not Implemented responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 501 Not Implemented responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_501 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 501;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Implemented';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 502 Bad Gateway responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 502 Bad Gateway responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_502 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 502;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Bad Gateway';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 503 Service Unavailable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 503 Service Unavailable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_503 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 503;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Service Unavailable';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 504 Gateway Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 504 Gateway Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_504 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 504;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Gateway Timeout';
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 505 HTTP Version Not Supported responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 505 HTTP Version Not Supported responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_505 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 505;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'HTTP Version Not Supported';
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for 511 Network Authentication Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 511 Network Authentication Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_511 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 511;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Network Authentication Required';
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Exception for unknown status responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for unknown status responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_Unknown extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* If `$data` is an instance of {@see Requests_Response}, uses the status
|
||||
* code from it. Otherwise, sets as 0
|
||||
*
|
||||
* @param string $reason Reason phrase
|
||||
* @param mixed $data Associated data
|
||||
*/
|
||||
public function __construct($reason = null, $data = null) {
|
||||
if ($data instanceof Requests_Response) {
|
||||
$this->code = $data->status_code;
|
||||
}
|
||||
|
||||
parent::__construct($reason, $data);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Event dispatcher
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Event dispatcher
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
interface Requests_Hooker {
|
||||
/**
|
||||
* Register a callback for a hook
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param callback $callback Function/method to call on event
|
||||
* @param int $priority Priority number. <0 is executed earlier, >0 is executed later
|
||||
*/
|
||||
public function register($hook, $callback, $priority = 0);
|
||||
|
||||
/**
|
||||
* Dispatch a message
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param array $parameters Parameters to pass to callbacks
|
||||
* @return boolean Successfulness
|
||||
*/
|
||||
public function dispatch($hook, $parameters = array());
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Handles adding and dispatching events
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles adding and dispatching events
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_Hooks implements Requests_Hooker {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
// pass
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback for a hook
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param callback $callback Function/method to call on event
|
||||
* @param int $priority Priority number. <0 is executed earlier, >0 is executed later
|
||||
*/
|
||||
public function register($hook, $callback, $priority = 0) {
|
||||
if (!isset($this->hooks[$hook])) {
|
||||
$this->hooks[$hook] = array();
|
||||
}
|
||||
if (!isset($this->hooks[$hook][$priority])) {
|
||||
$this->hooks[$hook][$priority] = array();
|
||||
}
|
||||
|
||||
$this->hooks[$hook][$priority][] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a message
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param array $parameters Parameters to pass to callbacks
|
||||
* @return boolean Successfulness
|
||||
*/
|
||||
public function dispatch($hook, $parameters = array()) {
|
||||
if (empty($this->hooks[$hook])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->hooks[$hook] as $priority => $hooked) {
|
||||
foreach ($hooked as $callback) {
|
||||
call_user_func_array($callback, $parameters);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,390 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* IDNA URL encoder
|
||||
*
|
||||
* Note: Not fully compliant, as nameprep does nothing yet.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
* @see http://tools.ietf.org/html/rfc3490 IDNA specification
|
||||
* @see http://tools.ietf.org/html/rfc3492 Punycode/Bootstrap specification
|
||||
*/
|
||||
class Requests_IDNAEncoder {
|
||||
/**
|
||||
* ACE prefix used for IDNA
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3490#section-5
|
||||
* @var string
|
||||
*/
|
||||
const ACE_PREFIX = 'xn--';
|
||||
|
||||
/**#@+
|
||||
* Bootstrap constant for Punycode
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3492#section-5
|
||||
* @var int
|
||||
*/
|
||||
const BOOTSTRAP_BASE = 36;
|
||||
const BOOTSTRAP_TMIN = 1;
|
||||
const BOOTSTRAP_TMAX = 26;
|
||||
const BOOTSTRAP_SKEW = 38;
|
||||
const BOOTSTRAP_DAMP = 700;
|
||||
const BOOTSTRAP_INITIAL_BIAS = 72;
|
||||
const BOOTSTRAP_INITIAL_N = 128;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Encode a hostname using Punycode
|
||||
*
|
||||
* @param string $string Hostname
|
||||
* @return string Punycode-encoded hostname
|
||||
*/
|
||||
public static function encode($string) {
|
||||
$parts = explode('.', $string);
|
||||
foreach ($parts as &$part) {
|
||||
$part = self::to_ascii($part);
|
||||
}
|
||||
return implode('.', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to an ASCII string using Punycode
|
||||
*
|
||||
* @throws Requests_Exception Provided string longer than 64 ASCII characters (`idna.provided_too_long`)
|
||||
* @throws Requests_Exception Prepared string longer than 64 ASCII characters (`idna.prepared_too_long`)
|
||||
* @throws Requests_Exception Provided string already begins with xn-- (`idna.provided_is_prefixed`)
|
||||
* @throws Requests_Exception Encoded string longer than 64 ASCII characters (`idna.encoded_too_long`)
|
||||
*
|
||||
* @param string $string ASCII or UTF-8 string (max length 64 characters)
|
||||
* @return string ASCII string
|
||||
*/
|
||||
public static function to_ascii($string) {
|
||||
// Step 1: Check if the string is already ASCII
|
||||
if (self::is_ascii($string)) {
|
||||
// Skip to step 7
|
||||
if (strlen($string) < 64) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
throw new Requests_Exception('Provided string is too long', 'idna.provided_too_long', $string);
|
||||
}
|
||||
|
||||
// Step 2: nameprep
|
||||
$string = self::nameprep($string);
|
||||
|
||||
// Step 3: UseSTD3ASCIIRules is false, continue
|
||||
// Step 4: Check if it's ASCII now
|
||||
if (self::is_ascii($string)) {
|
||||
// Skip to step 7
|
||||
if (strlen($string) < 64) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
throw new Requests_Exception('Prepared string is too long', 'idna.prepared_too_long', $string);
|
||||
}
|
||||
|
||||
// Step 5: Check ACE prefix
|
||||
if (strpos($string, self::ACE_PREFIX) === 0) {
|
||||
throw new Requests_Exception('Provided string begins with ACE prefix', 'idna.provided_is_prefixed', $string);
|
||||
}
|
||||
|
||||
// Step 6: Encode with Punycode
|
||||
$string = self::punycode_encode($string);
|
||||
|
||||
// Step 7: Prepend ACE prefix
|
||||
$string = self::ACE_PREFIX . $string;
|
||||
|
||||
// Step 8: Check size
|
||||
if (strlen($string) < 64) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
throw new Requests_Exception('Encoded string is too long', 'idna.encoded_too_long', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given string contains only ASCII characters
|
||||
*
|
||||
* @internal (Testing found regex was the fastest implementation)
|
||||
*
|
||||
* @param string $string
|
||||
* @return bool Is the string ASCII-only?
|
||||
*/
|
||||
protected static function is_ascii($string) {
|
||||
return (preg_match('/(?:[^\x00-\x7F])/', $string) !== 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a string for use as an IDNA name
|
||||
*
|
||||
* @todo Implement this based on RFC 3491 and the newer 5891
|
||||
* @param string $string
|
||||
* @return string Prepared string
|
||||
*/
|
||||
protected static function nameprep($string) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to a UCS-4 codepoint array
|
||||
*
|
||||
* Based on Requests_IRI::replace_invalid_with_pct_encoding()
|
||||
*
|
||||
* @throws Requests_Exception Invalid UTF-8 codepoint (`idna.invalidcodepoint`)
|
||||
* @param string $input
|
||||
* @return array Unicode code points
|
||||
*/
|
||||
protected static function utf8_to_codepoints($input) {
|
||||
$codepoints = array();
|
||||
|
||||
// Get number of bytes
|
||||
$strlen = strlen($input);
|
||||
|
||||
for ($position = 0; $position < $strlen; $position++) {
|
||||
$value = ord($input[$position]);
|
||||
|
||||
// One byte sequence:
|
||||
if ((~$value & 0x80) === 0x80) {
|
||||
$character = $value;
|
||||
$length = 1;
|
||||
$remaining = 0;
|
||||
}
|
||||
// Two byte sequence:
|
||||
elseif (($value & 0xE0) === 0xC0) {
|
||||
$character = ($value & 0x1F) << 6;
|
||||
$length = 2;
|
||||
$remaining = 1;
|
||||
}
|
||||
// Three byte sequence:
|
||||
elseif (($value & 0xF0) === 0xE0) {
|
||||
$character = ($value & 0x0F) << 12;
|
||||
$length = 3;
|
||||
$remaining = 2;
|
||||
}
|
||||
// Four byte sequence:
|
||||
elseif (($value & 0xF8) === 0xF0) {
|
||||
$character = ($value & 0x07) << 18;
|
||||
$length = 4;
|
||||
$remaining = 3;
|
||||
}
|
||||
// Invalid byte:
|
||||
else {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $value);
|
||||
}
|
||||
|
||||
if ($remaining > 0) {
|
||||
if ($position + $length > $strlen) {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
for ($position++; $remaining > 0; $position++) {
|
||||
$value = ord($input[$position]);
|
||||
|
||||
// If it is invalid, count the sequence as invalid and reprocess the current byte:
|
||||
if (($value & 0xC0) !== 0x80) {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
$character |= ($value & 0x3F) << (--$remaining * 6);
|
||||
}
|
||||
$position--;
|
||||
}
|
||||
|
||||
if (
|
||||
// Non-shortest form sequences are invalid
|
||||
$length > 1 && $character <= 0x7F
|
||||
|| $length > 2 && $character <= 0x7FF
|
||||
|| $length > 3 && $character <= 0xFFFF
|
||||
// Outside of range of ucschar codepoints
|
||||
// Noncharacters
|
||||
|| ($character & 0xFFFE) === 0xFFFE
|
||||
|| $character >= 0xFDD0 && $character <= 0xFDEF
|
||||
|| (
|
||||
// Everything else not in ucschar
|
||||
$character > 0xD7FF && $character < 0xF900
|
||||
|| $character < 0x20
|
||||
|| $character > 0x7E && $character < 0xA0
|
||||
|| $character > 0xEFFFD
|
||||
)
|
||||
) {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
$codepoints[] = $character;
|
||||
}
|
||||
|
||||
return $codepoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC3492-compliant encoder
|
||||
*
|
||||
* @internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code
|
||||
* @throws Requests_Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`)
|
||||
*
|
||||
* @param string $input UTF-8 encoded string to encode
|
||||
* @return string Punycode-encoded string
|
||||
*/
|
||||
public static function punycode_encode($input) {
|
||||
$output = '';
|
||||
# let n = initial_n
|
||||
$n = self::BOOTSTRAP_INITIAL_N;
|
||||
# let delta = 0
|
||||
$delta = 0;
|
||||
# let bias = initial_bias
|
||||
$bias = self::BOOTSTRAP_INITIAL_BIAS;
|
||||
# let h = b = the number of basic code points in the input
|
||||
$h = $b = 0; // see loop
|
||||
# copy them to the output in order
|
||||
$codepoints = self::utf8_to_codepoints($input);
|
||||
|
||||
foreach ($codepoints as $char) {
|
||||
if ($char < 128) {
|
||||
// Character is valid ASCII
|
||||
// TODO: this should also check if it's valid for a URL
|
||||
$output .= chr($char);
|
||||
$h++;
|
||||
}
|
||||
// Check if the character is non-ASCII, but below initial n
|
||||
// This never occurs for Punycode, so ignore in coverage
|
||||
// @codeCoverageIgnoreStart
|
||||
elseif ($char < $n) {
|
||||
throw new Requests_Exception('Invalid character', 'idna.character_outside_domain', $char);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
else {
|
||||
$extended[$char] = true;
|
||||
}
|
||||
}
|
||||
$extended = array_keys($extended);
|
||||
sort($extended);
|
||||
$b = $h;
|
||||
# [copy them] followed by a delimiter if b > 0
|
||||
if (strlen($output) > 0) {
|
||||
$output .= '-';
|
||||
}
|
||||
# {if the input contains a non-basic code point < n then fail}
|
||||
# while h < length(input) do begin
|
||||
while ($h < count($codepoints)) {
|
||||
# let m = the minimum code point >= n in the input
|
||||
$m = array_shift($extended);
|
||||
//printf('next code point to insert is %s' . PHP_EOL, dechex($m));
|
||||
# let delta = delta + (m - n) * (h + 1), fail on overflow
|
||||
$delta += ($m - $n) * ($h + 1);
|
||||
# let n = m
|
||||
$n = $m;
|
||||
# for each code point c in the input (in order) do begin
|
||||
for ($num = 0; $num < count($codepoints); $num++) {
|
||||
$c = $codepoints[$num];
|
||||
# if c < n then increment delta, fail on overflow
|
||||
if ($c < $n) {
|
||||
$delta++;
|
||||
}
|
||||
# if c == n then begin
|
||||
elseif ($c === $n) {
|
||||
# let q = delta
|
||||
$q = $delta;
|
||||
# for k = base to infinity in steps of base do begin
|
||||
for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
|
||||
# let t = tmin if k <= bias {+ tmin}, or
|
||||
# tmax if k >= bias + tmax, or k - bias otherwise
|
||||
if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
|
||||
$t = self::BOOTSTRAP_TMIN;
|
||||
}
|
||||
elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
|
||||
$t = self::BOOTSTRAP_TMAX;
|
||||
}
|
||||
else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
# if q < t then break
|
||||
if ($q < $t) {
|
||||
break;
|
||||
}
|
||||
# output the code point for digit t + ((q - t) mod (base - t))
|
||||
$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
|
||||
//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($digit));
|
||||
$output .= self::digit_to_char($digit);
|
||||
# let q = (q - t) div (base - t)
|
||||
$q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
|
||||
# end
|
||||
}
|
||||
# output the code point for digit q
|
||||
$output .= self::digit_to_char($q);
|
||||
//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($q));
|
||||
# let bias = adapt(delta, h + 1, test h equals b?)
|
||||
$bias = self::adapt($delta, $h + 1, $h === $b);
|
||||
//printf('bias becomes %d' . PHP_EOL, $bias);
|
||||
# let delta = 0
|
||||
$delta = 0;
|
||||
# increment h
|
||||
$h++;
|
||||
# end
|
||||
}
|
||||
# end
|
||||
}
|
||||
# increment delta and n
|
||||
$delta++;
|
||||
$n++;
|
||||
# end
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a digit to its respective character
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3492#section-5
|
||||
* @throws Requests_Exception On invalid digit (`idna.invalid_digit`)
|
||||
*
|
||||
* @param int $digit Digit in the range 0-35
|
||||
* @return string Single character corresponding to digit
|
||||
*/
|
||||
protected static function digit_to_char($digit) {
|
||||
// @codeCoverageIgnoreStart
|
||||
// As far as I know, this never happens, but still good to be sure.
|
||||
if ($digit < 0 || $digit > 35) {
|
||||
throw new Requests_Exception(sprintf('Invalid digit %d', $digit), 'idna.invalid_digit', $digit);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$digits = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
return substr($digits, $digit, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the bias
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3492#section-6.1
|
||||
* @param int $delta
|
||||
* @param int $numpoints
|
||||
* @param bool $firsttime
|
||||
* @return int New bias
|
||||
*/
|
||||
protected static function adapt($delta, $numpoints, $firsttime) {
|
||||
# function adapt(delta,numpoints,firsttime):
|
||||
# if firsttime then let delta = delta div damp
|
||||
if ($firsttime) {
|
||||
$delta = floor($delta / self::BOOTSTRAP_DAMP);
|
||||
}
|
||||
# else let delta = delta div 2
|
||||
else {
|
||||
$delta = floor($delta / 2);
|
||||
}
|
||||
# let delta = delta + (delta div numpoints)
|
||||
$delta += floor($delta / $numpoints);
|
||||
# let k = 0
|
||||
$k = 0;
|
||||
# while delta > ((base - tmin) * tmax) div 2 do begin
|
||||
$max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2);
|
||||
while ($delta > $max) {
|
||||
# let delta = delta div (base - tmin)
|
||||
$delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN));
|
||||
# let k = k + base
|
||||
$k += self::BOOTSTRAP_BASE;
|
||||
# end
|
||||
}
|
||||
# return k + (((base - tmin + 1) * delta) div (delta + skew))
|
||||
return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW));
|
||||
}
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses
|
||||
*
|
||||
* This was originally based on the PEAR class of the same name, but has been
|
||||
* entirely rewritten.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_IPv6
|
||||
{
|
||||
/**
|
||||
* Uncompresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress consecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and expands the '::' to
|
||||
* the required number of zero pieces.
|
||||
*
|
||||
* Example: FF01::101 -> FF01:0:0:0:0:0:0:101
|
||||
* ::1 -> 0:0:0:0:0:0:0:1
|
||||
*
|
||||
* @author Alexander Merz <alexander.merz@web.de>
|
||||
* @author elfrink at introweb dot nl
|
||||
* @author Josh Peck <jmp at joshpeck dot org>
|
||||
* @copyright 2003-2005 The PHP Group
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The uncompressed IPv6 address
|
||||
*/
|
||||
public static function uncompress($ip)
|
||||
{
|
||||
$c1 = -1;
|
||||
$c2 = -1;
|
||||
if (substr_count($ip, '::') === 1)
|
||||
{
|
||||
list($ip1, $ip2) = explode('::', $ip);
|
||||
if ($ip1 === '')
|
||||
{
|
||||
$c1 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c1 = substr_count($ip1, ':');
|
||||
}
|
||||
if ($ip2 === '')
|
||||
{
|
||||
$c2 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c2 = substr_count($ip2, ':');
|
||||
}
|
||||
if (strpos($ip2, '.') !== false)
|
||||
{
|
||||
$c2++;
|
||||
}
|
||||
// ::
|
||||
if ($c1 === -1 && $c2 === -1)
|
||||
{
|
||||
$ip = '0:0:0:0:0:0:0:0';
|
||||
}
|
||||
// ::xxx
|
||||
else if ($c1 === -1)
|
||||
{
|
||||
$fill = str_repeat('0:', 7 - $c2);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
// xxx::
|
||||
else if ($c2 === -1)
|
||||
{
|
||||
$fill = str_repeat(':0', 7 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
// xxx::xxx
|
||||
else
|
||||
{
|
||||
$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress consecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and compresses consecutive
|
||||
* zero pieces to '::'.
|
||||
*
|
||||
* Example: FF01:0:0:0:0:0:0:101 -> FF01::101
|
||||
* 0:0:0:0:0:0:0:1 -> ::1
|
||||
*
|
||||
* @see uncompress()
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The compressed IPv6 address
|
||||
*/
|
||||
public static function compress($ip)
|
||||
{
|
||||
// Prepare the IP to be compressed
|
||||
$ip = self::uncompress($ip);
|
||||
$ip_parts = self::split_v6_v4($ip);
|
||||
|
||||
// Replace all leading zeros
|
||||
$ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
|
||||
|
||||
// Find bunches of zeros
|
||||
if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$max = 0;
|
||||
$pos = null;
|
||||
foreach ($matches[0] as $match)
|
||||
{
|
||||
if (strlen($match[0]) > $max)
|
||||
{
|
||||
$max = strlen($match[0]);
|
||||
$pos = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
$ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
|
||||
}
|
||||
|
||||
if ($ip_parts[1] !== '')
|
||||
{
|
||||
return implode(':', $ip_parts);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $ip_parts[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an IPv6 address into the IPv6 and IPv4 representation parts
|
||||
*
|
||||
* RFC 4291 allows you to represent the last two parts of an IPv6 address
|
||||
* using the standard IPv4 representation
|
||||
*
|
||||
* Example: 0:0:0:0:0:0:13.1.68.3
|
||||
* 0:0:0:0:0:FFFF:129.144.52.38
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
|
||||
*/
|
||||
private static function split_v6_v4($ip)
|
||||
{
|
||||
if (strpos($ip, '.') !== false)
|
||||
{
|
||||
$pos = strrpos($ip, ':');
|
||||
$ipv6_part = substr($ip, 0, $pos);
|
||||
$ipv4_part = substr($ip, $pos + 1);
|
||||
return array($ipv6_part, $ipv4_part);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array($ip, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an IPv6 address
|
||||
*
|
||||
* Checks if the given IP is a valid IPv6 address
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return bool true if $ip is a valid IPv6 address
|
||||
*/
|
||||
public static function check_ipv6($ip)
|
||||
{
|
||||
$ip = self::uncompress($ip);
|
||||
list($ipv6, $ipv4) = self::split_v6_v4($ip);
|
||||
$ipv6 = explode(':', $ipv6);
|
||||
$ipv4 = explode('.', $ipv4);
|
||||
if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
|
||||
{
|
||||
foreach ($ipv6 as $ipv6_part)
|
||||
{
|
||||
// The section can't be empty
|
||||
if ($ipv6_part === '')
|
||||
return false;
|
||||
|
||||
// Nor can it be over four characters
|
||||
if (strlen($ipv6_part) > 4)
|
||||
return false;
|
||||
|
||||
// Remove leading zeros (this is safe because of the above)
|
||||
$ipv6_part = ltrim($ipv6_part, '0');
|
||||
if ($ipv6_part === '')
|
||||
$ipv6_part = '0';
|
||||
|
||||
// Check the value is valid
|
||||
$value = hexdec($ipv6_part);
|
||||
if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
|
||||
return false;
|
||||
}
|
||||
if (count($ipv4) === 4)
|
||||
{
|
||||
foreach ($ipv4 as $ipv4_part)
|
||||
{
|
||||
$value = (int) $ipv4_part;
|
||||
if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Proxy connection interface
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* Proxy connection interface
|
||||
*
|
||||
* Implement this interface to handle proxy settings and authentication
|
||||
*
|
||||
* Parameters should be passed via the constructor where possible, as this
|
||||
* makes it much easier for users to use your provider.
|
||||
*
|
||||
* @see Requests_Hooks
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
interface Requests_Proxy {
|
||||
/**
|
||||
* Register hooks as needed
|
||||
*
|
||||
* This method is called in {@see Requests::request} when the user has set
|
||||
* an instance as the 'auth' option. Use this callback to register all the
|
||||
* hooks you'll need.
|
||||
*
|
||||
* @see Requests_Hooks::register
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks);
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* HTTP Proxy connection interface
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTTP Proxy connection interface
|
||||
*
|
||||
* Provides a handler for connection via an HTTP proxy
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
class Requests_Proxy_HTTP implements Requests_Proxy {
|
||||
/**
|
||||
* Proxy host and port
|
||||
*
|
||||
* Notation: "host:port" (eg 127.0.0.1:8080 or someproxy.com:3128)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $proxy;
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pass;
|
||||
|
||||
/**
|
||||
* Do we need to authenticate? (ie username & password have been provided)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $use_authentication;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws Requests_Exception On incorrect number of arguments (`authbasicbadargs`)
|
||||
* @param array|null $args Array of user and password. Must have exactly two elements
|
||||
*/
|
||||
public function __construct($args = null) {
|
||||
if (is_string($args)) {
|
||||
$this->proxy = $args;
|
||||
}
|
||||
elseif (is_array($args)) {
|
||||
if (count($args) == 1) {
|
||||
list($this->proxy) = $args;
|
||||
}
|
||||
elseif (count($args) == 3) {
|
||||
list($this->proxy, $this->user, $this->pass) = $args;
|
||||
$this->use_authentication = true;
|
||||
}
|
||||
else {
|
||||
throw new Requests_Exception( 'Invalid number of arguments', 'proxyhttpbadargs');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the necessary callbacks
|
||||
*
|
||||
* @since 1.6
|
||||
* @see curl_before_send
|
||||
* @see fsockopen_remote_socket
|
||||
* @see fsockopen_remote_host_path
|
||||
* @see fsockopen_header
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks) {
|
||||
$hooks->register('curl.before_send', array(&$this, 'curl_before_send'));
|
||||
|
||||
$hooks->register('fsockopen.remote_socket', array(&$this, 'fsockopen_remote_socket'));
|
||||
$hooks->register('fsockopen.remote_host_path', array(&$this, 'fsockopen_remote_host_path'));
|
||||
if( $this->use_authentication ) {
|
||||
$hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cURL parameters before the data is sent
|
||||
*
|
||||
* @since 1.6
|
||||
* @param resource $handle cURL resource
|
||||
*/
|
||||
public function curl_before_send(&$handle) {
|
||||
curl_setopt($handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
curl_setopt($handle, CURLOPT_PROXY, $this->proxy);
|
||||
|
||||
if ($this->use_authentication) {
|
||||
curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_setopt($handle, CURLOPT_PROXYUSERPWD, $this->get_auth_string());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter remote socket information before opening socket connection
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_remote_socket( &$remote_socket ) {
|
||||
$remote_socket = $this->proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter remote path before getting stream data
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_remote_host_path( &$path, $url ) {
|
||||
$path = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra headers to the request before sending
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_header( &$out ) {
|
||||
$out .= "Proxy-Authorization: Basic " . base64_encode($this->get_auth_string()) . "\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication string (user:pass)
|
||||
*
|
||||
* @since 1.6
|
||||
* @return string
|
||||
*/
|
||||
public function get_auth_string() {
|
||||
return $this->user . ':' . $this->pass;
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* HTTP response class
|
||||
*
|
||||
* Contains a response from Requests::request()
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTTP response class
|
||||
*
|
||||
* Contains a response from Requests::request()
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Response {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->headers = new Requests_Response_Headers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Response body
|
||||
* @var string
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* Raw HTTP data from the transport
|
||||
* @var string
|
||||
*/
|
||||
public $raw = '';
|
||||
|
||||
/**
|
||||
* Headers, as an associative array
|
||||
* @var array
|
||||
*/
|
||||
public $headers = array();
|
||||
|
||||
/**
|
||||
* Status code, false if non-blocking
|
||||
* @var integer|boolean
|
||||
*/
|
||||
public $status_code = false;
|
||||
|
||||
/**
|
||||
* Whether the request succeeded or not
|
||||
* @var boolean
|
||||
*/
|
||||
public $success = false;
|
||||
|
||||
/**
|
||||
* Number of redirects the request used
|
||||
* @var integer
|
||||
*/
|
||||
public $redirects = 0;
|
||||
|
||||
/**
|
||||
* URL requested
|
||||
* @var string
|
||||
*/
|
||||
public $url = '';
|
||||
|
||||
/**
|
||||
* Previous requests (from redirects)
|
||||
* @var array Array of Requests_Response objects
|
||||
*/
|
||||
public $history = array();
|
||||
|
||||
/**
|
||||
* Cookies from the request
|
||||
*/
|
||||
public $cookies = array();
|
||||
|
||||
/**
|
||||
* Throws an exception if the request was not successful
|
||||
*
|
||||
* @throws Requests_Exception If `$allow_redirects` is false, and code is 3xx (`response.no_redirects`)
|
||||
* @throws Requests_Exception_HTTP On non-successful status code. Exception class corresponds to code (e.g. {@see Requests_Exception_HTTP_404})
|
||||
* @param boolean $allow_redirects Set to false to throw on a 3xx as well
|
||||
*/
|
||||
public function throw_for_status($allow_redirects = true) {
|
||||
if ($this->status_code >= 300 && $this->status_code < 400) {
|
||||
if (!$allow_redirects) {
|
||||
throw new Requests_Exception('Redirection not allowed', 'response.no_redirects', $this);
|
||||
}
|
||||
}
|
||||
|
||||
elseif (!$this->success) {
|
||||
$exception = Requests_Exception_HTTP::get_class($this->status_code);
|
||||
throw new $exception(null, $this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Response_Headers extends Requests_Utility_CaseInsensitiveDictionary {
|
||||
/**
|
||||
* Get the given header
|
||||
*
|
||||
* Unlike {@see self::getValues()}, this returns a string. If there are
|
||||
* multiple values, it concatenates them with a comma as per RFC2616.
|
||||
*
|
||||
* Avoid using this where commas may be used unquoted in values, such as
|
||||
* Set-Cookie headers.
|
||||
*
|
||||
* @param string $key
|
||||
* @return string Header value
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
$key = strtolower($key);
|
||||
if (!isset($this->data[$key]))
|
||||
return null;
|
||||
|
||||
return $this->flatten($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*
|
||||
* @param string $key Item name
|
||||
* @param string $value Item value
|
||||
*/
|
||||
public function offsetSet($key, $value) {
|
||||
if ($key === null) {
|
||||
throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!isset($this->data[$key])) {
|
||||
$this->data[$key] = array();
|
||||
}
|
||||
|
||||
$this->data[$key][] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values for a given header
|
||||
*
|
||||
* @param string $key
|
||||
* @return array Header values
|
||||
*/
|
||||
public function getValues($key) {
|
||||
$key = strtolower($key);
|
||||
if (!isset($this->data[$key]))
|
||||
return null;
|
||||
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens a value into a string
|
||||
*
|
||||
* Converts an array into a string by imploding values with a comma, as per
|
||||
* RFC2616's rules for folding headers.
|
||||
*
|
||||
* @param string|array $value Value to flatten
|
||||
* @return string Flattened value
|
||||
*/
|
||||
public function flatten($value) {
|
||||
if (is_array($value))
|
||||
$value = implode(',', $value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* Converts the internal
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new Requests_Utility_FilteredIterator($this->data, array($this, 'flatten'));
|
||||
}
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* SSL utilities for Requests
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* SSL utilities for Requests
|
||||
*
|
||||
* Collection of utilities for working with and verifying SSL certificates.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_SSL {
|
||||
/**
|
||||
* Verify the certificate against common name and subject alternative names
|
||||
*
|
||||
* Unfortunately, PHP doesn't check the certificate against the alternative
|
||||
* names, leading things like 'https://www.github.com/' to be invalid.
|
||||
* Instead
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
|
||||
*
|
||||
* @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
|
||||
* @param string $host Host name to verify against
|
||||
* @param resource $context Stream context
|
||||
* @return bool
|
||||
*/
|
||||
public static function verify_certificate($host, $cert) {
|
||||
// Calculate the valid wildcard match if the host is not an IP address
|
||||
$parts = explode('.', $host);
|
||||
if (ip2long($host) === false) {
|
||||
$parts[0] = '*';
|
||||
}
|
||||
$wildcard = implode('.', $parts);
|
||||
|
||||
$has_dns_alt = false;
|
||||
|
||||
// Check the subjectAltName
|
||||
if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
|
||||
$altnames = explode(',', $cert['extensions']['subjectAltName']);
|
||||
foreach ($altnames as $altname) {
|
||||
$altname = trim($altname);
|
||||
if (strpos($altname, 'DNS:') !== 0)
|
||||
continue;
|
||||
|
||||
$has_dns_alt = true;
|
||||
|
||||
// Strip the 'DNS:' prefix and trim whitespace
|
||||
$altname = trim(substr($altname, 4));
|
||||
|
||||
// Check for a match
|
||||
if (self::match_domain($host, $altname) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to checking the common name if we didn't get any dNSName
|
||||
// alt names, as per RFC2818
|
||||
if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
|
||||
// Check for a match
|
||||
if (self::match_domain($host, $cert['subject']['CN']) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a reference name is valid
|
||||
*
|
||||
* Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
|
||||
* - Wildcards can only occur in a name with more than 3 components
|
||||
* - Wildcards can only occur as the last character in the first
|
||||
* component
|
||||
* - Wildcards may be preceded by additional characters
|
||||
*
|
||||
* We modify these rules to be a bit stricter and only allow the wildcard
|
||||
* character to be the full first component; that is, with the exclusion of
|
||||
* the third rule.
|
||||
*
|
||||
* @param string $reference Reference dNSName
|
||||
* @return boolean Is the name valid?
|
||||
*/
|
||||
public static function verify_reference_name($reference) {
|
||||
$parts = explode('.', $reference);
|
||||
|
||||
// Check the first part of the name
|
||||
$first = array_shift($parts);
|
||||
|
||||
if (strpos($first, '*') !== false) {
|
||||
// Check that the wildcard is the full part
|
||||
if ($first !== '*') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that we have at least 3 components (including first)
|
||||
if (count($parts) < 2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the remaining parts
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '*') !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found, verified!
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a hostname against a dNSName reference
|
||||
*
|
||||
* @param string $host Requested host
|
||||
* @param string $reference dNSName to match against
|
||||
* @return boolean Does the domain match?
|
||||
*/
|
||||
public static function match_domain($host, $reference) {
|
||||
// Check if the reference is blacklisted first
|
||||
if (self::verify_reference_name($reference) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a direct match
|
||||
if ($host === $reference) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the valid wildcard match if the host is not an IP address
|
||||
// Also validates that the host has 3 parts or more, as per Firefox's
|
||||
// ruleset.
|
||||
if (ip2long($host) === false) {
|
||||
$parts = explode('.', $host);
|
||||
$parts[0] = '*';
|
||||
$wildcard = implode('.', $parts);
|
||||
if ($wildcard === $reference) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Session handler for persistent requests and default parameters
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Session Handler
|
||||
*/
|
||||
|
||||
/**
|
||||
* Session handler for persistent requests and default parameters
|
||||
*
|
||||
* Allows various options to be set as default values, and merges both the
|
||||
* options and URL properties together. A base URL can be set for all requests,
|
||||
* with all subrequests resolved from this. Base options can be set (including
|
||||
* a shared cookie jar), then overridden for individual requests.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Session Handler
|
||||
*/
|
||||
class Requests_Session {
|
||||
/**
|
||||
* Base URL for requests
|
||||
*
|
||||
* URLs will be made absolute using this as the base
|
||||
* @var string|null
|
||||
*/
|
||||
public $url = null;
|
||||
|
||||
/**
|
||||
* Base headers for requests
|
||||
* @var array
|
||||
*/
|
||||
public $headers = array();
|
||||
|
||||
/**
|
||||
* Base data for requests
|
||||
*
|
||||
* If both the base data and the per-request data are arrays, the data will
|
||||
* be merged before sending the request.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = array();
|
||||
|
||||
/**
|
||||
* Base options for requests
|
||||
*
|
||||
* The base options are merged with the per-request data for each request.
|
||||
* The only default option is a shared cookie jar between requests.
|
||||
*
|
||||
* Values here can also be set directly via properties on the Session
|
||||
* object, e.g. `$session->useragent = 'X';`
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* Create a new session
|
||||
*
|
||||
* @param string|null $url Base URL for requests
|
||||
* @param array $headers Default headers for requests
|
||||
* @param array $data Default data for requests
|
||||
* @param array $options Default options for requests
|
||||
*/
|
||||
public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
|
||||
$this->url = $url;
|
||||
$this->headers = $headers;
|
||||
$this->data = $data;
|
||||
$this->options = $options;
|
||||
|
||||
if (empty($this->options['cookies'])) {
|
||||
$this->options['cookies'] = new Requests_Cookie_Jar();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
* @return mixed|null Property value, null if none found
|
||||
*/
|
||||
public function __get($key) {
|
||||
if (isset($this->options[$key]))
|
||||
return $this->options[$key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
* @param mixed $value Property value
|
||||
*/
|
||||
public function __set($key, $value) {
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
*/
|
||||
public function __isset($key) {
|
||||
return isset($this->options[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
*/
|
||||
public function __unset($key) {
|
||||
$this->options[$key] = null;
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @see request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $options
|
||||
* @return Requests_Response
|
||||
*/
|
||||
/**
|
||||
* Send a GET request
|
||||
*/
|
||||
public function get($url, $headers = array(), $options = array()) {
|
||||
return $this->request($url, $headers, null, Requests::GET, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a HEAD request
|
||||
*/
|
||||
public function head($url, $headers = array(), $options = array()) {
|
||||
return $this->request($url, $headers, null, Requests::HEAD, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request
|
||||
*/
|
||||
public function delete($url, $headers = array(), $options = array()) {
|
||||
return $this->request($url, $headers, null, Requests::DELETE, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @see request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param array $options
|
||||
* @return Requests_Response
|
||||
*/
|
||||
/**
|
||||
* Send a POST request
|
||||
*/
|
||||
public function post($url, $headers = array(), $data = array(), $options = array()) {
|
||||
return $this->request($url, $headers, $data, Requests::POST, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request
|
||||
*/
|
||||
public function put($url, $headers = array(), $data = array(), $options = array()) {
|
||||
return $this->request($url, $headers, $data, Requests::PUT, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PATCH request
|
||||
*
|
||||
* Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
|
||||
* specification recommends that should send an ETag
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc5789
|
||||
*/
|
||||
public function patch($url, $headers, $data = array(), $options = array()) {
|
||||
return $this->request($url, $headers, $data, Requests::PATCH, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Main interface for HTTP requests
|
||||
*
|
||||
* This method initiates a request and sends it via a transport before
|
||||
* parsing.
|
||||
*
|
||||
* @see Requests::request()
|
||||
*
|
||||
* @throws Requests_Exception On invalid URLs (`nonhttp`)
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Extra headers to send with the request
|
||||
* @param array $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
|
||||
* @param string $type HTTP request type (use Requests constants)
|
||||
* @param array $options Options for the request (see {@see Requests::request})
|
||||
* @return Requests_Response
|
||||
*/
|
||||
public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) {
|
||||
$request = $this->merge_request(compact('url', 'headers', 'data', 'options'));
|
||||
|
||||
return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple HTTP requests simultaneously
|
||||
*
|
||||
* @see Requests::request_multiple()
|
||||
*
|
||||
* @param array $requests Requests data (see {@see Requests::request_multiple})
|
||||
* @param array $options Global and default options (see {@see Requests::request})
|
||||
* @return array Responses (either Requests_Response or a Requests_Exception object)
|
||||
*/
|
||||
public function request_multiple($requests, $options = array()) {
|
||||
foreach ($requests as $key => $request) {
|
||||
$requests[$key] = $this->merge_request($request, false);
|
||||
}
|
||||
|
||||
$options = array_merge($this->options, $options);
|
||||
|
||||
// Disallow forcing the type, as that's a per request setting
|
||||
unset($options['type']);
|
||||
|
||||
return Requests::request_multiple($requests, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a request's data with the default data
|
||||
*
|
||||
* @param array $request Request data (same form as {@see request_multiple})
|
||||
* @param boolean $merge_options Should we merge options as well?
|
||||
* @return array Request data
|
||||
*/
|
||||
protected function merge_request($request, $merge_options = true) {
|
||||
if ($this->url !== null) {
|
||||
$request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
|
||||
$request['url'] = $request['url']->uri;
|
||||
}
|
||||
$request['headers'] = array_merge($this->headers, $request['headers']);
|
||||
|
||||
if (is_array($request['data']) && is_array($this->data)) {
|
||||
$request['data'] = array_merge($this->data, $request['data']);
|
||||
}
|
||||
|
||||
if ($merge_options !== false) {
|
||||
$request['options'] = array_merge($this->options, $request['options']);
|
||||
|
||||
// Disallow forcing the type, as that's a per request setting
|
||||
unset($request['options']['type']);
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Base HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
interface Requests_Transport {
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*/
|
||||
public function request($url, $headers = array(), $data = array(), $options = array());
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
|
||||
* @param array $options Global options, see {@see Requests::response()} for documentation
|
||||
* @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
|
||||
*/
|
||||
public function request_multiple($requests, $options);
|
||||
|
||||
/**
|
||||
* Self-test whether the transport can be used
|
||||
* @return bool
|
||||
*/
|
||||
public static function test();
|
||||
}
|