├── LICENSE ├── README.markdown ├── Requests-1.6.0 ├── .coveralls.yml ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin │ └── create_pear_package.php ├── composer.json ├── docs │ ├── README.md │ ├── authentication-custom.md │ ├── authentication.md │ ├── goals.md │ ├── hooks.md │ ├── proxy.md │ ├── usage-advanced.md │ ├── usage.md │ └── why-requests.md ├── examples │ ├── basic-auth.php │ ├── get.php │ ├── multiple.php │ ├── post.php │ ├── proxy.php │ └── session.php ├── library │ ├── Requests.php │ └── Requests │ │ ├── Auth.php │ │ ├── Auth │ │ └── Basic.php │ │ ├── Cookie.php │ │ ├── Cookie │ │ └── Jar.php │ │ ├── Exception.php │ │ ├── Exception │ │ ├── HTTP.php │ │ └── HTTP │ │ │ ├── 400.php │ │ │ ├── 401.php │ │ │ ├── 402.php │ │ │ ├── 403.php │ │ │ ├── 404.php │ │ │ ├── 405.php │ │ │ ├── 406.php │ │ │ ├── 407.php │ │ │ ├── 408.php │ │ │ ├── 409.php │ │ │ ├── 410.php │ │ │ ├── 411.php │ │ │ ├── 412.php │ │ │ ├── 413.php │ │ │ ├── 414.php │ │ │ ├── 415.php │ │ │ ├── 416.php │ │ │ ├── 417.php │ │ │ ├── 418.php │ │ │ ├── 428.php │ │ │ ├── 429.php │ │ │ ├── 431.php │ │ │ ├── 500.php │ │ │ ├── 501.php │ │ │ ├── 502.php │ │ │ ├── 503.php │ │ │ ├── 504.php │ │ │ ├── 505.php │ │ │ ├── 511.php │ │ │ └── Unknown.php │ │ ├── Hooker.php │ │ ├── Hooks.php │ │ ├── IDNAEncoder.php │ │ ├── IPv6.php │ │ ├── IRI.php │ │ ├── Proxy.php │ │ ├── Proxy │ │ └── HTTP.php │ │ ├── Response.php │ │ ├── Response │ │ └── Headers.php │ │ ├── SSL.php │ │ ├── Session.php │ │ ├── Transport.php │ │ ├── Transport │ │ ├── cURL.php │ │ ├── cacert.pem │ │ └── fsockopen.php │ │ └── Utility │ │ ├── CaseInsensitiveDictionary.php │ │ └── FilteredIterator.php ├── package.xml.tpl └── tests │ ├── Auth │ └── Basic.php │ ├── ChunkedEncoding.php │ ├── Cookies.php │ ├── Encoding.php │ ├── IDNAEncoder.php │ ├── IRI.php │ ├── Requests.php │ ├── Response │ └── Headers.php │ ├── SSL.php │ ├── Session.php │ ├── Transport │ ├── Base.php │ ├── cURL.php │ └── fsockopen.php │ ├── bootstrap.php │ └── phpunit.xml.dist ├── themes └── .gitignore ├── update └── zips └── .gitignore /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | WordPress Theme Directory Slurper 2 | ================================== 3 | 4 | A command line PHP script that downloads and updates a copy of the latest stable 5 | version of every theme in the [WordPress.org theme repository][repo]. 6 | 7 | Really handy for doing local searches across all WordPress themes. 8 | 9 | [repo]: http://wordpress.org/themes/ 10 | 11 | Requirements 12 | ------------ 13 | 14 | * PHP 5.2 15 | * wget 16 | * Unix system (only tested on Mac OS X) 17 | 18 | Instructions 19 | ------------ 20 | 21 | 1. `cd WordPress-Theme-Directory-Slurper` 22 | 2. `./update` 23 | 24 | The `theme/` directory will contain all the themes, when the script is done. 25 | 26 | FAQ 27 | ---- 28 | 29 | ### Why download the zip files? Why not use SVN? ### 30 | 31 | An SVN checkout of the entire repository is a BEAST of a thing. Additionally, not all themes listed in the svn repositoriy are currently active. 32 | 33 | ### Why not just do an SVN export of each themes's trunk? ### 34 | 35 | There is no guarantee that the theme's trunk is the approved version. All themes must go through an approval process. Using the zip file gets around this as it uses the theme API to figure it all out and gives you the latest stable version 36 | 37 | ### How long will it take? ### 38 | 39 | Your first update will take a while. You'd be well-advised to let it run overnight. But subsequent updates are smart. The script tracks the SVN revision number of your latest update and then asks the Theme Trac install for a list of themes that have changed since. Only those changed themes are updated after the initial sync. 40 | 41 | ### How much disk space do I need? ### 42 | 43 | As of early 2015, it takes up about 3.7GB. 44 | 45 | ### Something went wrong, how do I do a partial update? ### 46 | 47 | The last successful update revision number is stored in `themes/.last-revision`. You can just overwrite that and the next `update` will start after that revision. 48 | 49 | ### What if I want Plugins instead of Themes? ### 50 | Check out the [WordPress-Plugin-Directory-Slurper][https://github.com/markjaquith/WordPress-Plugin-Directory-Slurper]. 51 | 52 | Copyright & License 53 | ------------------- 54 | Copyright (C) 2015 Aaron Jorbin 55 | 56 | Based on [WordPress-Plugin-Directory-Slurper][https://github.com/markjaquith/WordPress-Plugin-Directory-Slurper] which is Copyright (C) 2011 Mark Jaquith 57 | 58 | This program is free software; you can redistribute it and/or 59 | modify it under the terms of the GNU General Public License 60 | as published by the Free Software Foundation; either version 2 61 | of the License, or (at your option) any later version. 62 | 63 | This program is distributed in the hope that it will be useful, 64 | but WITHOUT ANY WARRANTY; without even the implied warranty of 65 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 66 | GNU General Public License for more details. 67 | 68 | You should have received a copy of the GNU General Public License 69 | along with this program; if not, write to the Free Software 70 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 71 | -------------------------------------------------------------------------------- /Requests-1.6.0/.coveralls.yml: -------------------------------------------------------------------------------- 1 | src_dir: library 2 | coverage_clover: tests/clover.xml 3 | json_path: tests/coveralls.json 4 | service_name: travis-ci -------------------------------------------------------------------------------- /Requests-1.6.0/.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | before_script: 3 | - phpenv local 5.4 4 | - composer install --dev --no-interaction 5 | - phpenv local --unset 6 | - cd tests 7 | script: 8 | - phpunit --coverage-clover clover.xml 9 | after_script: 10 | - cd .. 11 | - phpenv local 5.4 12 | - php vendor/bin/coveralls -v 13 | - phpenv local --unset 14 | php: 15 | - 5.2 16 | - 5.3 17 | - 5.4 18 | - 5.5 19 | -------------------------------------------------------------------------------- /Requests-1.6.0/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 1.6.0 5 | ----- 6 | - [Add multiple request support][#23] - Send multiple HTTP requests with both 7 | fsockopen and cURL, transparently falling back to synchronous when 8 | not supported. 9 | 10 | - [Add proxy support][#70] - HTTP proxies are now natively supported via a 11 | [high-level API][docs/proxy]. Major props to Ozh for his fantastic work 12 | on this. 13 | 14 | - [Verify host name for SSL requests][#63] - Requests is now the first and only 15 | standalone HTTP library to fully verify SSL hostnames even with socket 16 | connections. Thanks to Michael Adams, Dion Hulse, Jon Cave, and Pádraic Brady 17 | for reviewing the crucial code behind this. 18 | 19 | - [Add cookie support][#64] - Adds built-in support for cookies (built entirely 20 | as a high-level API) 21 | 22 | - [Add sessions][#62] - To compliment cookies, [sessions][docs/usage-advanced] 23 | can be created with a base URL and default options, plus a shared cookie jar. 24 | 25 | - Add [PUT][#1], [DELETE][#3], and [PATCH][#2] request support 26 | 27 | - [Add Composer support][#6] - You can now install Requests via the 28 | `rmccue/requests` package on Composer 29 | 30 | [docs/proxy]: http://requests.ryanmccue.info/docs/proxy.html 31 | [docs/usage-advanced]: http://requests.ryanmccue.info/docs/usage-advanced.html 32 | 33 | [#1]: https://github.com/rmccue/Requests/issues/1 34 | [#2]: https://github.com/rmccue/Requests/issues/2 35 | [#3]: https://github.com/rmccue/Requests/issues/3 36 | [#6]: https://github.com/rmccue/Requests/issues/6 37 | [#9]: https://github.com/rmccue/Requests/issues/9 38 | [#23]: https://github.com/rmccue/Requests/issues/23 39 | [#62]: https://github.com/rmccue/Requests/issues/62 40 | [#63]: https://github.com/rmccue/Requests/issues/63 41 | [#64]: https://github.com/rmccue/Requests/issues/64 42 | [#70]: https://github.com/rmccue/Requests/issues/70 43 | 44 | [View all changes][https://github.com/rmccue/Requests/compare/v1.5.0...v1.6.0] 45 | 46 | 1.5.0 47 | ----- 48 | Initial release! -------------------------------------------------------------------------------- /Requests-1.6.0/LICENSE: -------------------------------------------------------------------------------- 1 | Requests 2 | ======== 3 | 4 | Copyright (c) 2010-2012 Ryan McCue and contributors 5 | 6 | Permission to use, copy, modify, and/or distribute this software for any 7 | purpose with or without fee is hereby granted, provided that the above 8 | copyright notice and this permission notice appear in all copies. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | ComplexPie IRI Parser 20 | ===================== 21 | 22 | Copyright (c) 2007-2010, Geoffrey Sneddon and Steve Minutillo. 23 | All rights reserved. 24 | 25 | Redistribution and use in source and binary forms, with or without 26 | modification, are permitted provided that the following conditions are met: 27 | 28 | * Redistributions of source code must retain the above copyright notice, 29 | this list of conditions and the following disclaimer. 30 | 31 | * Redistributions in binary form must reproduce the above copyright notice, 32 | this list of conditions and the following disclaimer in the documentation 33 | and/or other materials provided with the distribution. 34 | 35 | * Neither the name of the SimplePie Team nor the names of its contributors 36 | may be used to endorse or promote products derived from this software 37 | without specific prior written permission. 38 | 39 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 40 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 42 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE 43 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 44 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 45 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 46 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 47 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49 | POSSIBILITY OF SUCH DAMAGE. 50 | -------------------------------------------------------------------------------- /Requests-1.6.0/README.md: -------------------------------------------------------------------------------- 1 | Requests for PHP 2 | ================ 3 | 4 | Requests is a HTTP library written in PHP, for human beings. It is roughly 5 | based on the API from the excellent [Requests Python 6 | library](http://python-requests.org/). Requests is [ISC 7 | Licensed](https://github.com/rmccue/Requests/blob/master/LICENSE) (similar to 8 | the new BSD license) and has no dependencies, except for PHP 5.2+. 9 | 10 | Despite PHP's use as a language for the web, its tools for sending HTTP requests 11 | are severely lacking. cURL has an 12 | [interesting API](http://php.net/manual/en/function.curl-setopt.php), to say the 13 | least, and you can't always rely on it being available. Sockets provide only low 14 | level access, and require you to build most of the HTTP response parsing 15 | yourself. 16 | 17 | We all have better things to do. That's why Requests was born. 18 | 19 | ```php 20 | $headers = array('Accept' => 'application/json'); 21 | $options = array('auth' => array('user', 'pass')); 22 | $request = Requests::get('https://api.github.com/gists', $headers, $options); 23 | 24 | var_dump($request->status_code); 25 | // int(200) 26 | 27 | var_dump($request->headers['content-type']); 28 | // string(31) "application/json; charset=utf-8" 29 | 30 | var_dump($request->body); 31 | // string(26891) "[...]" 32 | ``` 33 | 34 | Requests allows you to send **HEAD**, **GET**, **POST**, **PUT**, **DELETE**, 35 | and **PATCH** HTTP requests. You can add headers, form data, multipart files, 36 | and parameters with simple arrays, and access the response data in the same way. 37 | Requests uses cURL and fsockopen, depending on what your system has available, 38 | but abstracts all the nasty stuff out of your way, providing a consistent API. 39 | 40 | 41 | Features 42 | -------- 43 | 44 | - International Domains and URLs 45 | - Browser-style SSL Verification 46 | - Basic/Digest Authentication 47 | - Automatic Decompression 48 | - Connection Timeouts 49 | 50 | 51 | Installation 52 | ------------ 53 | 54 | ### Install with Composer 55 | If you're using [Composer](https://github.com/composer/composer) to manage 56 | dependencies, you can add Requests with it. 57 | 58 | { 59 | "require": { 60 | "rmccue/requests": ">=1.0" 61 | }, 62 | "autoload": { 63 | "psr-0": {"Requests": "library/"} 64 | } 65 | } 66 | 67 | ### Install source from GitHub 68 | To install the source code: 69 | 70 | $ git clone git://github.com/rmccue/Requests.git 71 | 72 | And include it in your scripts: 73 | 74 | require_once '/path/to/Requests/library/Requests.php'; 75 | 76 | You'll probably also want to register an autoloader: 77 | 78 | Requests::register_autoloader(); 79 | 80 | 81 | ### Install source from zip/tarball 82 | Alternatively, you can fetch a [tarball][] or [zipball][]: 83 | 84 | $ curl -L https://github.com/rmccue/Requests/tarball/master | tar xzv 85 | (or) 86 | $ wget https://github.com/rmccue/Requests/tarball/master -O - | tar xzv 87 | 88 | [tarball]: https://github.com/rmccue/Requests/tarball/master 89 | [zipball]: https://github.com/rmccue/Requests/zipball/master 90 | 91 | 92 | ### Using a Class Loader 93 | If you're using a class loader (e.g., [Symfony Class Loader][]) for 94 | [PSR-0][]-style class loading: 95 | 96 | $loader->registerPrefix('Requests', 'path/to/vendor/Requests/library'); 97 | 98 | [Symfony Class Loader]: https://github.com/symfony/ClassLoader 99 | [PSR-0]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md 100 | 101 | 102 | Documentation 103 | ------------- 104 | The best place to start is our [prose-based documentation][], which will guide 105 | you through using Requests. 106 | 107 | After that, take a look at [the documentation for 108 | `Requests::request()`][request_method], where all the parameters are fully 109 | documented. 110 | 111 | Requests is [100% documented with PHPDoc](http://requests.ryanmccue.info/api/). 112 | If you find any problems with it, [create a new 113 | issue](https://github.com/rmccue/Requests/issues/new)! 114 | 115 | [prose-based documentation]: https://github.com/rmccue/Requests/blob/master/docs/README.md 116 | [request_method]: http://requests.ryanmccue.info/api/class-Requests.html#_request 117 | 118 | Testing 119 | ------- 120 | [![Build Status](https://secure.travis-ci.org/rmccue/Requests.png?branch=master)](http://travis-ci.org/rmccue/Requests) 121 | [![Coverage Status](https://coveralls.io/repos/rmccue/Requests/badge.png?branch=master)][coveralls] 122 | 123 | Requests strives to have 100% code-coverage of the library with an extensive 124 | set of tests. We're not quite there yet, but [we're getting close][coveralls]. 125 | 126 | [coveralls]: https://coveralls.io/r/rmccue/Requests?branch=master 127 | 128 | To run the test suite, simply: 129 | 130 | $ cd tests 131 | $ phpunit 132 | 133 | If you'd like to run a single set of tests, specify just the name: 134 | 135 | $ phpunit Transport/cURL 136 | 137 | Contribute 138 | ---------- 139 | 140 | 1. Check for open issues or open a new issue for a feature request or a bug 141 | 2. Fork [the repository][] on Github to start making your changes to the 142 | `master` branch (or branch off of it) 143 | 3. Write a test which shows that the bug was fixed or that the feature works as expected 144 | 4. Send a pull request and bug me until I merge it 145 | 146 | [the repository]: https://github.com/rmccue/Requests 147 | -------------------------------------------------------------------------------- /Requests-1.6.0/bin/create_pear_package.php: -------------------------------------------------------------------------------- 1 | ' . PHP_EOL; 13 | echo PHP_EOL; 14 | echo ' version:' . PHP_EOL; 15 | echo ' Version of the package, in the form of major.minor.bug' . PHP_EOL; 16 | echo PHP_EOL; 17 | echo ' stability:' . PHP_EOL; 18 | echo ' One of alpha, beta, stable' . PHP_EOL; 19 | die(); 20 | } 21 | 22 | if (!isset($argv[2])) { 23 | die('You must provide the stability (alpha, beta, or stable)'); 24 | } 25 | 26 | $context = array( 27 | 'date' => gmdate('Y-m-d'), 28 | 'time' => gmdate('H:m:00'), 29 | 'version' => $argv[1], 30 | 'api_version' => $argv[1], 31 | 'stability' => $argv[2], 32 | 'api_stability' => $argv[2], 33 | ); 34 | 35 | $context['files'] = ''; 36 | $path = realpath(dirname(__FILE__).'/../library/Requests'); 37 | foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { 38 | if (preg_match('/\.php$/', $file)) { 39 | $name = str_replace($path . DIRECTORY_SEPARATOR, '', $file); 40 | $name = str_replace(DIRECTORY_SEPARATOR, '/', $name); 41 | $context['files'][] = "\t\t\t\t\t" . ''; 42 | } 43 | } 44 | 45 | $context['files'] = implode("\n", $context['files']); 46 | 47 | $template = file_get_contents(dirname(__FILE__).'/../package.xml.tpl'); 48 | $content = preg_replace_callback('/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/', 'replace_parameters', $template); 49 | file_put_contents(dirname(__FILE__).'/../package.xml', $content); 50 | 51 | function replace_parameters($matches) { 52 | global $context; 53 | 54 | return isset($context[$matches[1]]) ? $context[$matches[1]] : null; 55 | } 56 | -------------------------------------------------------------------------------- /Requests-1.6.0/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rmccue/requests", 3 | "description": "A HTTP library written in PHP, for human beings.", 4 | "homepage": "http://github.com/rmccue/Requests", 5 | "license": "ISC", 6 | "keywords": ["http", "idna", "iri", "ipv6", "curl", "sockets", "fsockopen"], 7 | "authors": [ 8 | { 9 | "name": "Ryan McCue", 10 | "homepage": "http://ryanmccue.info" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.2" 15 | }, 16 | "require-dev": { 17 | "satooshi/php-coveralls": "dev-master" 18 | }, 19 | "type": "library", 20 | "autoload": { 21 | "psr-0": {"Requests": "library/"} 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Requests-1.6.0/docs/README.md: -------------------------------------------------------------------------------- 1 | Documentation 2 | ============= 3 | 4 | If you're here, you're looking for documentation for Requests! The documents 5 | here are prose; you might also want to check out the [API documentation][]. 6 | 7 | [API documentation]: http://requests.ryanmccue.info/api/ 8 | 9 | * Introduction 10 | * [Goals][goals] 11 | * [Why should I use Requests instead of X?][why-requests] 12 | * Usage 13 | * [Making a request][usage] 14 | * [Advanced usage][usage-advanced] 15 | * [Authenticating your request][authentication] 16 | * Advanced Usage 17 | * [Custom authentication][authentication-custom] 18 | * [Requests through proxy][proxy] 19 | * [Hooking system][hooks] 20 | 21 | [goals]: goals.md 22 | [why-requests]: why-requests.md 23 | [usage]: usage.md 24 | [usage-advanced]: usage-advanced.md 25 | [authentication]: authentication.md 26 | [authentication-custom]: authentication-custom.md 27 | [hooks]: hooks.md 28 | [proxy]: proxy.md -------------------------------------------------------------------------------- /Requests-1.6.0/docs/authentication-custom.md: -------------------------------------------------------------------------------- 1 | Custom Authentication 2 | ===================== 3 | Custom authentication handlers are designed to be extremely simple to write. 4 | In order to write a handler, you'll need to implement the `Requests_Auth` 5 | interface. 6 | 7 | An instance of this handler is then passed in by the user via the `auth` 8 | option, just like for normal authentication. 9 | 10 | Let's say we have a HTTP endpoint that checks for the `Hotdog` header and 11 | authenticates you if said header is set to `Yummy`. (I don't know of any 12 | services that do this; perhaps this is a market waiting to be tapped?) 13 | 14 | ```php 15 | class MySoftware_Auth_Hotdog implements Requests_Auth { 16 | protected $password; 17 | 18 | public function __construct($password) { 19 | $this->password = $password; 20 | } 21 | 22 | public function register(Requests_Hooks &$hooks) { 23 | $hooks->register('requests.before_request', array(&$this, 'before_request')); 24 | } 25 | 26 | public function before_request(&$url, &$headers, &$data, &$type, &$options) { 27 | $headers['Hotdog'] = $this->password; 28 | } 29 | } 30 | ``` 31 | 32 | We then use this in our request calls: 33 | 34 | ``` 35 | $options = array( 36 | 'auth' => new MySoftware_Auth_Hotdog('yummy') 37 | ); 38 | $response = Requests::get('http://hotdogbin.org/admin', array(), $options); 39 | ``` 40 | 41 | (For more information on how to register and use hooks, see the [hooking 42 | system documentation][hooks]) 43 | 44 | [hooks]: hooks.md -------------------------------------------------------------------------------- /Requests-1.6.0/docs/authentication.md: -------------------------------------------------------------------------------- 1 | Authentication 2 | ============== 3 | Many requests that you make will require authentication of some type. Requests 4 | includes support out of the box for HTTP Basic authentication, with more 5 | built-ins coming soon. 6 | 7 | Making a Basic authenticated call is ridiculously easy: 8 | 9 | ```php 10 | $options = array( 11 | 'auth' => new Requests_Auth_Basic(array('user', 'password')) 12 | ); 13 | Requests::get('http://httpbin.org/basic-auth/user/password', array(), $options); 14 | ``` 15 | 16 | As Basic authentication is usually what you want when you specify a username 17 | and password, you can also just pass in an array as a shorthand: 18 | 19 | ```php 20 | $options = array( 21 | 'auth' => array('user', 'password') 22 | ); 23 | Requests::get('http://httpbin.org/basic-auth/user/password', array(), $options); 24 | ``` 25 | 26 | Note that POST/PUT can also take a data parameter, so you also need that 27 | before `$options`: 28 | 29 | ```php 30 | Requests::get('http://httpbin.org/basic-auth/user/password', array(), null, $options); 31 | ``` -------------------------------------------------------------------------------- /Requests-1.6.0/docs/goals.md: -------------------------------------------------------------------------------- 1 | Goals 2 | ===== 3 | 4 | 1. **Simple interface** 5 | 6 | Requests is designed to provide a simple, unified interface to making 7 | requests, regardless of what is available on the system. This means not worrying. 8 | 9 | 2. **Fully tested code** 10 | 11 | Requests strives to have 90%+ code coverage from the unit tests, aiming for 12 | the ideal 100%. Introducing new features always means introducing new tests 13 | 14 | (Note: some parts of the code are not covered by design. These sections are 15 | marked with `@codeCoverageIgnore` tags) 16 | 17 | 3. **Maximum compatibility** 18 | 19 | No matter what you have installed on your system, you should be able to run 20 | Requests. We use cURL if it's available, and fallback to sockets otherwise. 21 | We require only a baseline of PHP 5.2, leaving the choice of PHP minimum 22 | requirement fully in your hands, and giving you the ability to support many 23 | more hosts. 24 | 25 | 4. **No dependencies** 26 | 27 | Requests is designed to be entirely self-contained and doesn't require 28 | anything else at all. You can run Requests on an entirely stock PHP build 29 | without any additional extensions outside the standard library. 30 | -------------------------------------------------------------------------------- /Requests-1.6.0/docs/hooks.md: -------------------------------------------------------------------------------- 1 | Hooks 2 | ===== 3 | Requests has a hook system that you can use to manipulate parts of the request 4 | process along with internal transport hooks. 5 | 6 | Check out the [API documentation for `Requests_Hooks`][requests_hooks] for more 7 | information on how to use the hook system. 8 | 9 | Available Hooks 10 | --------------- 11 | 12 | * `requests.before_request` 13 | 14 | Alter the request before it's sent to the transport. 15 | 16 | Parameters: `string &$url`, `array &$headers`, `array|string &$data`, 17 | `string &$type`, `array &$options` 18 | 19 | * `requests.before_parse` 20 | 21 | Alter the raw HTTP response before parsing 22 | 23 | Parameters: `string &$response` 24 | 25 | * `requests.after_request` 26 | 27 | Alter the response object before it's returned to the user 28 | 29 | Parameters: `Requests_Response &$return` 30 | 31 | * `curl.before_request` 32 | 33 | Set cURL options before the transport sets any (note that Requests may 34 | override these) 35 | 36 | Parameters: `cURL resource &$fp` 37 | 38 | * `curl.before_send` 39 | 40 | Set cURL options just before the request is actually sent via `curl_exec` 41 | 42 | Parameters: `cURL resource &$fp` 43 | 44 | * `curl.after_request` 45 | 46 | Alter the raw HTTP response before returning for parsing 47 | 48 | Parameters: `string &$response` 49 | 50 | * `fsockopen.before_request` 51 | 52 | Run events before the transport does anything 53 | 54 | * `fsockopen.after_headers` 55 | 56 | Add extra headers before the body begins (i.e. before `\r\n\r\n`) 57 | 58 | Parameters: `string &$out` 59 | 60 | * `fsockopen.before_send` 61 | 62 | Add body data before sending the request 63 | 64 | Parameters: `string &$out` 65 | 66 | * `fsockopen.after_send` 67 | 68 | Run events after writing the data to the socket 69 | 70 | * `fsockopen.after_request` 71 | 72 | Alter the raw HTTP response before returning for parsing 73 | 74 | Parameters: `string &$response` 75 | 76 | 77 | Registering Hooks 78 | ----------------- 79 | Note: if you're doing this in an authentication handler, see the [Custom 80 | Authentication guide][authentication-custom] instead. 81 | 82 | [authentication-custom]: authentication-custom.md 83 | 84 | In order to register your own hooks, you need to instantiate `Requests_hooks` 85 | and pass this in via the 'hooks' option. 86 | 87 | ```php 88 | $hooks = new Requests_Hooks(); 89 | $hooks->register('requests.after_request', 'mycallback'); 90 | 91 | $request = Requests::get('http://httpbin.org/get', array(), array('hooks' => $hooks)); 92 | ``` -------------------------------------------------------------------------------- /Requests-1.6.0/docs/proxy.md: -------------------------------------------------------------------------------- 1 | Proxy Support 2 | ============= 3 | 4 | You can easily make requests through HTTP proxies. 5 | 6 | To make requests through an open proxy, specify the following options: 7 | 8 | ```php 9 | $options = array( 10 | 'proxy' => '127.0.0.1:3128' 11 | ); 12 | Requests::get('http://httpbin.org/ip', array(), $options); 13 | ``` 14 | 15 | If your proxy needs you to authenticate, the option will become an array like 16 | the following: 17 | 18 | ```php 19 | $options = array( 20 | 'proxy' => array( '127.0.0.1:3128', 'my_username', 'my_password' ) 21 | ); 22 | Requests::get('http://httpbin.org/ip', array(), $options); 23 | ``` 24 | -------------------------------------------------------------------------------- /Requests-1.6.0/docs/usage-advanced.md: -------------------------------------------------------------------------------- 1 | Advanced Usage 2 | ============== 3 | 4 | Session Handling 5 | ---------------- 6 | Making multiple requests to the same site with similar options can be a pain, 7 | since you end up repeating yourself. The Session object can be used to set 8 | default parameters for these. 9 | 10 | Let's simulate communicating with GitHub. 11 | 12 | ```php 13 | $session = new Requests_Session('https://api.github.com/'); 14 | $session->headers['X-ContactAuthor'] = 'rmccue'; 15 | $session->useragent = 'My-Awesome-App'; 16 | 17 | $response = $session->get('/zen'); 18 | ``` 19 | 20 | You can use the `url`, `headers`, `data` and `options` properties of the Session 21 | object to set the defaults for this session, and the constructor also takes 22 | parameters in the same order as `Requests::request()`. Accessing any other 23 | properties will set the corresponding key in the options array; that is: 24 | 25 | ```php 26 | // Setting the property... 27 | $session->useragent = 'My-Awesome-App'; 28 | 29 | // ...is the same as setting the option 30 | $session->options['useragent'] = 'My-Awesome-App'; 31 | ``` 32 | 33 | 34 | Secure Requests with SSL 35 | ------------------------ 36 | By default, HTTPS requests will use the most secure options available: 37 | 38 | ```php 39 | $response = Requests::get('https://httpbin.org/'); 40 | ``` 41 | 42 | Requests bundles certificates from the [Mozilla certificate authority list][], 43 | which is the same list of root certificates used in most browsers. If you're 44 | accessing sites with certificates from other CAs, or self-signed certificates, 45 | you can point Requests to a custom CA list in PEM form (the same format 46 | accepted by cURL and OpenSSL): 47 | 48 | ```php 49 | $options = array( 50 | 'verify' => '/path/to/cacert.pem' 51 | ); 52 | $response = Requests::get('https://httpbin.org/', array(), $options); 53 | ``` 54 | 55 | Alternatively, if you want to disable verification completely, this is possible 56 | with `'verify' => false`, but note that this is extremely insecure and should be 57 | avoided. 58 | 59 | ### Security Note 60 | Requests supports SSL across both cURL and fsockopen in a transparent manner. 61 | Unlike other PHP HTTP libraries, support for verifying the certificate name is 62 | built-in; that is, a request for `https://github.com/` will actually verify the 63 | certificate's name even with the fsockopen transport. This makes Requests the 64 | first and currently only PHP HTTP library that supports full SSL verification. 65 | 66 | (Note that WordPress now also supports this verification, thanks to efforts by 67 | the Requests development team.) 68 | 69 | (See also the [related PHP][php-bug-47030] and [OpenSSL-related][php-bug-55820] 70 | bugs in PHP for more information on Subject Alternate Name field.) 71 | 72 | [Mozilla certificate authority list]: http://www.mozilla.org/projects/security/certs/ 73 | [php-bug-47030]: https://bugs.php.net/bug.php?id=47030 74 | [php-bug-55820]:https://bugs.php.net/bug.php?id=55820 75 | -------------------------------------------------------------------------------- /Requests-1.6.0/docs/usage.md: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | Ready to go? Make sure you have Requests installed before attempting any of the 5 | steps in this guide. 6 | 7 | 8 | Loading Requests 9 | ---------------- 10 | Before we can load Requests up, we'll need to make sure it's loaded. This is a 11 | simple two-step: 12 | 13 | ```php 14 | // First, include Requests 15 | include('/path/to/library/Requests.php'); 16 | 17 | // Next, make sure Requests can load internal classes 18 | Requests::register_autoloader(); 19 | ``` 20 | 21 | If you'd like to bring along your own autoloader, you can forget about this 22 | completely. 23 | 24 | 25 | Make a GET Request 26 | ------------------ 27 | One of the most basic things you can do with HTTP is make a GET request. 28 | 29 | Let's grab GitHub's public timeline: 30 | 31 | ```php 32 | $response = Requests::get('https://github.com/timeline.json'); 33 | ``` 34 | 35 | `$response` is now a **Requests_Response** object. Response objects are what 36 | you'll be working with whenever you want to get data back from your request. 37 | 38 | 39 | Using the Response Object 40 | ------------------------- 41 | Now that we have the response from GitHub, let's get the body of the response. 42 | 43 | ```php 44 | var_dump($response->body); 45 | // string(42865) "[{"repository":{"url":"... 46 | ``` 47 | 48 | 49 | Custom Headers 50 | -------------- 51 | If you want to add custom headers to the request, simply pass them in as an 52 | associative array as the second parameter: 53 | 54 | ```php 55 | $response = Requests::get('https://github.com/timeline.json', array('X-Requests' => 'Is Awesome!')); 56 | ``` 57 | 58 | 59 | Make a POST Request 60 | ------------------- 61 | Making a POST request is very similar to making a GET: 62 | 63 | ```php 64 | $response = Requests::post('http://httpbin.org/post'); 65 | ``` 66 | 67 | You'll probably also want to pass in some data. You can pass in either a 68 | string, an array or an object (Requests uses [`http_build_query`][build_query] 69 | internally) as the third parameter (after the URL and headers): 70 | 71 | [build_query]: http://php.net/http_build_query 72 | 73 | ```php 74 | $data = array('key1' => 'value1', 'key2' => 'value2'); 75 | $response = Requests::post('http://httpbin.org/post', array(), $data); 76 | var_dump($response->body); 77 | ``` 78 | 79 | This gives the output: 80 | 81 | string(503) "{ 82 | "origin": "124.191.162.147", 83 | "files": {}, 84 | "form": { 85 | "key2": "value2", 86 | "key1": "value1" 87 | }, 88 | "headers": { 89 | "Content-Length": "23", 90 | "Accept-Encoding": "deflate;q=1.0, compress;q=0.5, gzip;q=0.5", 91 | "X-Forwarded-Port": "80", 92 | "Connection": "keep-alive", 93 | "User-Agent": "php-requests/1.6-dev", 94 | "Host": "httpbin.org", 95 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" 96 | }, 97 | "url": "http://httpbin.org/post", 98 | "args": {}, 99 | "data": "" 100 | }" 101 | 102 | To send raw data, simply pass in a string instead. You'll probably also want to 103 | set the Content-Type header to ensure the remote server knows what you're 104 | sending it: 105 | 106 | ```php 107 | $url = 'https://api.github.com/some/endpoint'; 108 | $headers = array('Content-Type' => 'application/json'); 109 | $data = array('some' => 'data'); 110 | $response = Requests::post($url, $headers, json_encode($data)); 111 | ``` 112 | 113 | Note that if you don't manually specify a Content-Type header, Requests has 114 | undefined behaviour for the header. It may be set to various values depending 115 | on the internal execution path, so it's recommended to set this explicitly if 116 | you need to. 117 | 118 | 119 | Status Codes 120 | ------------ 121 | The Response object also gives you access to the status code: 122 | 123 | ```php 124 | var_dump($response->status_code); 125 | // int(200) 126 | ``` 127 | 128 | You can also easily check if this status code is a success code, or if it's an 129 | error: 130 | 131 | ```php 132 | var_dump($response->success); 133 | // bool(true) 134 | ``` 135 | 136 | 137 | Response Headers 138 | ---------------- 139 | We can also grab headers pretty easily: 140 | 141 | ```php 142 | var_dump($response->headers['Date']); 143 | // string(29) "Thu, 09 Feb 2012 15:22:06 GMT" 144 | ``` 145 | 146 | Note that this is case-insensitive, so the following are all equivalent: 147 | 148 | * `$response->headers['Date']` 149 | * `$response->headers['date']` 150 | * `$response->headers['DATE']` 151 | * `$response->headers['dAtE']` 152 | 153 | If a header isn't set, this will give `null`. You can also check with 154 | `isset($response->headers['date'])` 155 | -------------------------------------------------------------------------------- /Requests-1.6.0/docs/why-requests.md: -------------------------------------------------------------------------------- 1 | Why Requests Instead of X? 2 | ========================== 3 | This is a quick look at why you should use Requests instead of another 4 | solution. Keep in mind though that these are my point of view, and they may not 5 | be issues for you. 6 | 7 | As always with software, you should choose what you think is best. 8 | 9 | 10 | Why should I use Requests? 11 | -------------------------- 12 | 1. **Designed for maximum compatibility** 13 | 14 | The realities of working with widely deployable software mean that awesome 15 | PHP features aren't always available. PHP 5.3, cURL, OpenSSL and more are not 16 | necessarily going to be available on every system. While you're welcome to 17 | require PHP 5.3, 5.4 or even 5.5, it's not our job to force you to use those. 18 | 19 | (The WordPress project estimates [about 60%][wpstats] of hosts are running 20 | PHP 5.2, so this is a serious issue for developers working on large 21 | deployable projects.) 22 | 23 | Don't worry though, Requests will automatically use better features where 24 | possible, giving you an extra speed boost with cURL. 25 | 26 | 2. **Simple API** 27 | 28 | Requests' API is designed to be able to be learnt in 10 minutes. Everything 29 | from basic requests all the way up to advanced usage involving custom SSL 30 | certificates and stored cookies is handled by a simple API. 31 | 32 | Other HTTP libraries optimize for the library developer's time; **Requests 33 | optimizes for your time**. 34 | 35 | 3. **Thoroughly tested** 36 | 37 | Requests is [continuously integrated with Travis][travis] and test coverage 38 | is [constantly monitored with Coveralls][coveralls] to give you confidence in 39 | the library. We aim for test coverage **over 90%** at all times, and new 40 | features require new tests to go along with them. This ensures that you can 41 | be confident in the quality of the code, as well as being able to update to 42 | the latest version of Requests without worrying about compatibility. 43 | 44 | 4. **Secure by default** 45 | 46 | Unlike other HTTP libraries, Requests is secure by default. Requests is the 47 | **first and currently only** standalone HTTP library to 48 | **[fully verify][requests_ssl] all HTTPS requests** even without cURL. We 49 | also bundle the latest root certificate authorities to ensure that your 50 | secure requests are actually secure. 51 | 52 | (Of note is that WordPress as of version 3.7 also supports full checking of 53 | the certificates, thanks to [evangelism efforts on our behalf][wpssl]. 54 | Together, we are the only HTTP libraries in PHP to fully verify certificates 55 | to the same level as browsers.) 56 | 57 | 5. **Extensible from the core** 58 | 59 | If you need low-level access to Requests' internals, simply plug your 60 | callbacks in via the built-in [hooking system][] and mess around as much as 61 | you want. Requests' simple hooking system is so powerful that both 62 | authentication handlers and cookie support is actually handled internally 63 | with hooks. 64 | 65 | [coveralls]: https://coveralls.io/r/rmccue/Requests 66 | [hooking system]: hooks.md 67 | [requests_ssl]: https://github.com/rmccue/Requests/blob/master/library/Requests/SSL.php 68 | [travis]: https://travis-ci.org/rmccue/Requests 69 | [wpssl]: http://core.trac.wordpress.org/ticket/25007 70 | 71 | 72 | Why shouldn't I use... 73 | ---------------------- 74 | Requests isn't the first or only HTTP library in PHP and it's important to 75 | acknowledge the other solutions out there. Here's why you should use Requests 76 | instead of something else, in our opinion. 77 | 78 | 79 | ### cURL 80 | 81 | 1. **Not every host has cURL installed** 82 | 83 | cURL is far from being ubiquitous, so you can't rely on it always being 84 | available when distributing software. Anecdotal data collected from various 85 | projects indicates that cURL is available on roughly 90% of hosts, but that 86 | leaves 10% of hosts without it. 87 | 88 | 2. **cURL's interface sucks** 89 | 90 | cURL's interface was designed for PHP 4, and hence uses resources with 91 | horrible functions such as `curl_setopt()`. Combined with that, it uses 229 92 | global constants, polluting the global namespace horribly. 93 | 94 | Requests, on the other hand, exposes only a handful of classes to the 95 | global namespace, most of which are for internal use. You can learn to use 96 | the `Requests::request()` method and the `Requests_Response` object in the 97 | space of 10 minutes and you already know how to use Requests. 98 | 99 | 100 | ### Guzzle 101 | 102 | 1. **Requires cURL and PHP 5.3+** 103 | 104 | Guzzle is designed to be a client to fit a large number of installations, but 105 | as a result of optimizing for Guzzle developer time, it uses cURL as an 106 | underlying transport. As noted above, this is a majority of systems, but 107 | far from all. 108 | 109 | The same is true for PHP 5.3+. While we'd all love to rely on PHP's newer 110 | features, the fact is that a huge percentage of hosts are still running on 111 | PHP 5.2. (The WordPress project estimates [about 60%][wpstats] of hosts are 112 | running PHP 5.2.) 113 | 114 | 2. **Not just a HTTP client** 115 | 116 | Guzzle is not intended to just be a HTTP client, but rather to be a 117 | full-featured REST client. Requests is just a HTTP client, intentionally. Our 118 | development strategy is to act as a low-level library that REST clients can 119 | easily be built on, not to provide the whole kitchen sink for you. 120 | 121 | If you want to rapidly develop a web service client using a framework, Guzzle 122 | will suit you perfectly. On the other hand, if you want a HTTP client without 123 | all the rest, Requests is the way to go. 124 | 125 | [wpstats]: http://wordpress.org/about/stats/ 126 | 127 | 128 | ### Buzz 129 | 130 | 1. **Requires PHP 5.3+** 131 | 132 | As with Guzzle, while PHP 5.3+ is awesome, you can't always rely on it being 133 | on a host. With widely distributable software, this is a huge problem. 134 | 135 | 2. **Not transport-transparent** 136 | 137 | For making certain types of requests, such as multi-requests, you can't rely 138 | on a high-level abstraction and instead have to use the low-level transports. 139 | This really gains nothing (other than a fancy interface) over just using the 140 | methods directly and means that you can't rely on features to be available. 141 | 142 | 143 | ### fsockopen 144 | 145 | 1. **Very low-level** 146 | 147 | fsockopen is used for working with sockets directly, so it only knows about 148 | the transport layer (TCP in our case), not anything higher (i.e. HTTP on the 149 | application layer). To be able to use fsockopen as a HTTP client, you need 150 | to write all the HTTP code yourself, and once you're done, you'll end up 151 | with something that is almost exactly like Requests. 152 | 153 | 154 | ### PEAR HTTP_Request2 155 | 156 | 1. **Requires PEAR** 157 | 158 | PEAR is (in theory) a great distribution system (with a less than wonderful 159 | implementation), however it is not ubiquitous, as many hosts disable it to 160 | save on space that most people aren't going to use anyway. 161 | 162 | PEAR is also a pain for users. Users want to be able to download a zip of 163 | your project without needing to install anything else from PEAR. 164 | 165 | (If you really want though, Requests is available via PEAR. Check the README 166 | to see how to grab it.) 167 | 168 | 2. **Depends on other PEAR utilities** 169 | 170 | HTTP\_Request2 requires Net_URL2 in order to function, locking you in to 171 | using PEAR for your project. 172 | 173 | Requests is entirely self-contained, and includes all the libraries it needs 174 | (for example, Requests\_IRI is based on ComplexPie\_IRI by Geoffrey Sneddon). 175 | 176 | 177 | ### PECL HttpRequest 178 | 179 | 1. **Requires a PECL extension** 180 | 181 | Similar to PEAR, users aren't big fans of installing extra libraries. Unlike 182 | PEAR though, PECL extensions require compiling, which end users will be 183 | unfamiliar with. In addition, on systems where users do not have full 184 | control over PHP, they will be unable to install custom extensions. 185 | 186 | 187 | ### Zend Framework's Zend\_Http\_Client 188 | 189 | 1. **Requires other parts of the Zend Framework** 190 | 191 | Similar to HTTP_Request2, Zend's client is not fully self-contained and 192 | requires other components from the framework. 193 | -------------------------------------------------------------------------------- /Requests-1.6.0/examples/basic-auth.php: -------------------------------------------------------------------------------- 1 | array('someuser', 'password') 12 | ); 13 | $request = Requests::get('http://httpbin.org/basic-auth/someuser/password', array(), $options); 14 | 15 | // Check what we received 16 | var_dump($request); -------------------------------------------------------------------------------- /Requests-1.6.0/examples/get.php: -------------------------------------------------------------------------------- 1 | 'application/json')); 11 | 12 | // Check what we received 13 | var_dump($request); -------------------------------------------------------------------------------- /Requests-1.6.0/examples/multiple.php: -------------------------------------------------------------------------------- 1 | 'http://httpbin.org/get', 13 | 'headers' => array('Accept' => 'application/javascript'), 14 | ), 15 | 'post' => array( 16 | 'url' => 'http://httpbin.org/post', 17 | 'data' => array('mydata' => 'something'), 18 | ), 19 | 'delayed' => array( 20 | 'url' => 'http://httpbin.org/delay/10', 21 | 'options' => array( 22 | 'timeout' => 20, 23 | ), 24 | ), 25 | ); 26 | 27 | // Setup a callback 28 | function my_callback(&$request, $id) { 29 | var_dump($id, $request); 30 | } 31 | 32 | // Tell Requests to use the callback 33 | $options = array( 34 | 'complete' => 'my_callback', 35 | ); 36 | 37 | // Send the request! 38 | $responses = Requests::request_multiple($requests, $options); 39 | 40 | // Note: the response from the above call will be an associative array matching 41 | // $requests with the response data, however we've already handled it in 42 | // my_callback() anyway! 43 | // 44 | // If you don't believe me, uncomment this: 45 | # var_dump($responses); -------------------------------------------------------------------------------- /Requests-1.6.0/examples/post.php: -------------------------------------------------------------------------------- 1 | 'something')); 11 | 12 | // Check what we received 13 | var_dump($request); -------------------------------------------------------------------------------- /Requests-1.6.0/examples/proxy.php: -------------------------------------------------------------------------------- 1 | '127.0.0.1:8080', // syntax: host:port, eg 12.13.14.14:8080 or someproxy.com:3128 12 | // If you need to authenticate, use the following syntax: 13 | // 'proxy' => array( '127.0.0.1:8080', 'username', 'password' ), 14 | ); 15 | $request = Requests::get('http://httpbin.org/ip', array(), $options ); 16 | 17 | // See result 18 | var_dump($request->body); 19 | -------------------------------------------------------------------------------- /Requests-1.6.0/examples/session.php: -------------------------------------------------------------------------------- 1 | headers['Accept'] = 'application/json'; 12 | $session->useragent = 'Awesomesauce'; 13 | 14 | // Now let's make a request! 15 | $request = $session->get('/get'); 16 | 17 | // Check what we received 18 | var_dump($request); 19 | 20 | // Let's check our user agent! 21 | $request = $session->get('/user-agent'); 22 | 23 | // And check again 24 | var_dump($request); 25 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Auth.php: -------------------------------------------------------------------------------- 1 | user, $this->pass) = $args; 46 | } 47 | } 48 | 49 | /** 50 | * Register the necessary callbacks 51 | * 52 | * @see curl_before_send 53 | * @see fsockopen_header 54 | * @param Requests_Hooks $hooks Hook system 55 | */ 56 | public function register(Requests_Hooks &$hooks) { 57 | $hooks->register('curl.before_send', array(&$this, 'curl_before_send')); 58 | $hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header')); 59 | } 60 | 61 | /** 62 | * Set cURL parameters before the data is sent 63 | * 64 | * @param resource $handle cURL resource 65 | */ 66 | public function curl_before_send(&$handle) { 67 | curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 68 | curl_setopt($handle, CURLOPT_USERPWD, $this->getAuthString()); 69 | } 70 | 71 | /** 72 | * Add extra headers to the request before sending 73 | * 74 | * @param string $out HTTP header string 75 | */ 76 | public function fsockopen_header(&$out) { 77 | $out .= "Authorization: Basic " . base64_encode($this->getAuthString()) . "\r\n"; 78 | } 79 | 80 | /** 81 | * Get the authentication string (user:pass) 82 | * 83 | * @return string 84 | */ 85 | public function getAuthString() { 86 | return $this->user . ':' . $this->pass; 87 | } 88 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Cookie.php: -------------------------------------------------------------------------------- 1 | name = $name; 46 | $this->value = $value; 47 | $this->attributes = $attributes; 48 | } 49 | 50 | /** 51 | * Format a cookie for a Cookie header 52 | * 53 | * This is used when sending cookies to a server. 54 | * 55 | * @return string Cookie formatted for Cookie header 56 | */ 57 | public function formatForHeader() { 58 | return sprintf('%s=%s', $this->name, $this->value); 59 | } 60 | 61 | /** 62 | * Format a cookie for a Set-Cookie header 63 | * 64 | * This is used when sending cookies to clients. This isn't really 65 | * applicable to client-side usage, but might be handy for debugging. 66 | * 67 | * @return string Cookie formatted for Set-Cookie header 68 | */ 69 | public function formatForSetCookie() { 70 | $header_value = $this->formatForHeader(); 71 | if (!empty($this->attributes)) { 72 | $parts = array(); 73 | foreach ($this->attributes as $key => $value) { 74 | // Ignore non-associative attributes 75 | if (is_numeric($key)) { 76 | $parts[] = $value; 77 | } 78 | else { 79 | $parts[] = sprintf('%s=%s', $key, $value); 80 | } 81 | } 82 | 83 | $header_value .= '; ' . implode('; ', $parts); 84 | } 85 | return $header_value; 86 | } 87 | 88 | /** 89 | * Get the cookie value 90 | * 91 | * Attributes and other data can be accessed via methods. 92 | */ 93 | public function __toString() { 94 | return $this->value; 95 | } 96 | 97 | /** 98 | * Parse a cookie string into a cookie object 99 | * 100 | * Based on Mozilla's parsing code in Firefox and related projects, which 101 | * is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265 102 | * specifies some of this handling, but not in a thorough manner. 103 | * 104 | * @param string Cookie header value (from a Set-Cookie header) 105 | * @return Requests_Cookie Parsed cookie object 106 | */ 107 | public static function parse($string, $name = '') { 108 | $parts = explode(';', $string); 109 | $kvparts = array_shift($parts); 110 | 111 | if (!empty($name)) { 112 | $value = $string; 113 | } 114 | elseif (strpos($kvparts, '=') === false) { 115 | // Some sites might only have a value without the equals separator. 116 | // Deviate from RFC 6265 and pretend it was actually a blank name 117 | // (`=foo`) 118 | // 119 | // https://bugzilla.mozilla.org/show_bug.cgi?id=169091 120 | $name = ''; 121 | $value = $kvparts; 122 | } 123 | else { 124 | list($name, $value) = explode('=', $kvparts, 2); 125 | } 126 | $name = trim($name); 127 | $value = trim($value); 128 | 129 | // Attribute key are handled case-insensitively 130 | $attributes = new Requests_Utility_CaseInsensitiveDictionary(); 131 | 132 | if (!empty($parts)) { 133 | foreach ($parts as $part) { 134 | if (strpos($part, '=') === false) { 135 | $part_key = $part; 136 | $part_value = true; 137 | } 138 | else { 139 | list($part_key, $part_value) = explode('=', $part, 2); 140 | $part_value = trim($part_value); 141 | } 142 | 143 | $part_key = trim($part_key); 144 | $attributes[$part_key] = $part_value; 145 | } 146 | } 147 | 148 | return new Requests_Cookie($name, $value, $attributes); 149 | } 150 | 151 | /** 152 | * Parse all Set-Cookie headers from request headers 153 | * 154 | * @param Requests_Response_Headers $headers 155 | * @return array 156 | */ 157 | public static function parseFromHeaders(Requests_Response_Headers $headers) { 158 | $cookie_headers = $headers->getValues('Set-Cookie'); 159 | if (empty($cookie_headers)) { 160 | return array(); 161 | } 162 | 163 | $cookies = array(); 164 | foreach ($cookie_headers as $header) { 165 | $parsed = self::parse($header); 166 | $cookies[$parsed->name] = $parsed; 167 | } 168 | 169 | return $cookies; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Cookie/Jar.php: -------------------------------------------------------------------------------- 1 | cookies = $cookies; 30 | } 31 | 32 | /** 33 | * Normalise cookie data into a Requests_Cookie 34 | * 35 | * @param string|Requests_Cookie $cookie 36 | * @return Requests_Cookie 37 | */ 38 | public function normalizeCookie($cookie, $key = null) { 39 | if ($cookie instanceof Requests_Cookie) { 40 | return $cookie; 41 | } 42 | 43 | return Requests_Cookie::parse($cookie, $key); 44 | } 45 | 46 | /** 47 | * Check if the given item exists 48 | * 49 | * @param string $key Item key 50 | * @return boolean Does the item exist? 51 | */ 52 | public function offsetExists($key) { 53 | return isset($this->cookies[$key]); 54 | } 55 | 56 | /** 57 | * Get the value for the item 58 | * 59 | * @param string $key Item key 60 | * @return string Item value 61 | */ 62 | public function offsetGet($key) { 63 | if (!isset($this->cookies[$key])) 64 | return null; 65 | 66 | return $this->cookies[$key]; 67 | } 68 | 69 | /** 70 | * Set the given item 71 | * 72 | * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`) 73 | * 74 | * @param string $key Item name 75 | * @param string $value Item value 76 | */ 77 | public function offsetSet($key, $value) { 78 | if ($key === null) { 79 | throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset'); 80 | } 81 | 82 | $this->cookies[$key] = $value; 83 | } 84 | 85 | /** 86 | * Unset the given header 87 | * 88 | * @param string $key 89 | */ 90 | public function offsetUnset($key) { 91 | unset($this->cookies[$key]); 92 | } 93 | 94 | /** 95 | * Get an iterator for the data 96 | * 97 | * @return ArrayIterator 98 | */ 99 | public function getIterator() { 100 | return new ArrayIterator($this->cookies); 101 | } 102 | 103 | /** 104 | * Register the cookie handler with the request's hooking system 105 | * 106 | * @param Requests_Hooker $hooks Hooking system 107 | */ 108 | public function register(Requests_Hooker $hooks) { 109 | $hooks->register('requests.before_request', array($this, 'before_request')); 110 | $hooks->register('requests.before_redirect_check', array($this, 'before_redirect_check')); 111 | } 112 | 113 | /** 114 | * Add Cookie header to a request if we have any 115 | * 116 | * As per RFC 6265, cookies are separated by '; ' 117 | * 118 | * @param string $url 119 | * @param array $headers 120 | * @param array $data 121 | * @param string $type 122 | * @param array $options 123 | */ 124 | public function before_request(&$url, &$headers, &$data, &$type, &$options) { 125 | if (!empty($this->cookies)) { 126 | $cookies = array(); 127 | foreach ($this->cookies as $key => $cookie) { 128 | $cookie = $this->normalizeCookie($cookie, $key); 129 | $cookies[] = $cookie->formatForHeader(); 130 | } 131 | 132 | $headers['Cookie'] = implode('; ', $cookies); 133 | } 134 | } 135 | 136 | /** 137 | * Parse all cookies from a response and attach them to the response 138 | * 139 | * @var Requests_Response $response 140 | */ 141 | public function before_redirect_check(Requests_Response &$return) { 142 | $cookies = Requests_Cookie::parseFromHeaders($return->headers); 143 | $this->cookies = array_merge($this->cookies, $cookies); 144 | $return->cookies = $this; 145 | } 146 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Exception.php: -------------------------------------------------------------------------------- 1 | type = $type; 40 | $this->data = $data; 41 | } 42 | 43 | /** 44 | * Like {@see getCode()}, but a string code. 45 | * 46 | * @codeCoverageIgnore 47 | * @return string 48 | */ 49 | public function getType() { 50 | return $this->type; 51 | } 52 | 53 | /** 54 | * Gives any relevant data 55 | * 56 | * @codeCoverageIgnore 57 | * @return mixed 58 | */ 59 | public function getData() { 60 | return $this->data; 61 | } 62 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Exception/HTTP.php: -------------------------------------------------------------------------------- 1 | reason = $reason; 40 | } 41 | 42 | $message = sprintf('%d %s', $this->code, $this->reason); 43 | parent::__construct($message, 'httpresponse', $data, $this->code); 44 | } 45 | 46 | /** 47 | * Get the status message 48 | */ 49 | public function getReason() { 50 | return $this->reason; 51 | } 52 | 53 | /** 54 | * Get the correct exception class for a given error code 55 | * 56 | * @param int $code HTTP status code 57 | * @return string Exception class name to use 58 | */ 59 | public static function get_class($code) { 60 | $class = sprintf('Requests_Exception_HTTP_%d', $code); 61 | if (class_exists($class)) { 62 | return $class; 63 | } 64 | 65 | return 'Requests_Exception_HTTP_Unknown'; 66 | } 67 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Exception/HTTP/400.php: -------------------------------------------------------------------------------- 1 | code = $data->status_code; 40 | } 41 | 42 | parent::__construct($reason, $data); 43 | } 44 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Hooker.php: -------------------------------------------------------------------------------- 1 | 0 is executed later 22 | */ 23 | public function register($hook, $callback, $priority = 0); 24 | 25 | /** 26 | * Dispatch a message 27 | * 28 | * @param string $hook Hook name 29 | * @param array $parameters Parameters to pass to callbacks 30 | * @return boolean Successfulness 31 | */ 32 | public function dispatch($hook, $parameters = array()); 33 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Hooks.php: -------------------------------------------------------------------------------- 1 | 0 is executed later 29 | */ 30 | public function register($hook, $callback, $priority = 0) { 31 | if (!isset($this->hooks[$hook])) { 32 | $this->hooks[$hook] = array(); 33 | } 34 | if (!isset($this->hooks[$hook][$priority])) { 35 | $this->hooks[$hook][$priority] = array(); 36 | } 37 | 38 | $this->hooks[$hook][$priority][] = $callback; 39 | } 40 | 41 | /** 42 | * Dispatch a message 43 | * 44 | * @param string $hook Hook name 45 | * @param array $parameters Parameters to pass to callbacks 46 | * @return boolean Successfulness 47 | */ 48 | public function dispatch($hook, $parameters = array()) { 49 | if (empty($this->hooks[$hook])) { 50 | return false; 51 | } 52 | 53 | foreach ($this->hooks[$hook] as $priority => $hooked) { 54 | foreach ($hooked as $callback) { 55 | call_user_func_array($callback, $parameters); 56 | } 57 | } 58 | 59 | return true; 60 | } 61 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/IDNAEncoder.php: -------------------------------------------------------------------------------- 1 | 0) { 177 | if ($position + $length > $strlen) { 178 | throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character); 179 | } 180 | for ($position++; $remaining > 0; $position++) { 181 | $value = ord($input[$position]); 182 | 183 | // If it is invalid, count the sequence as invalid and reprocess the current byte: 184 | if (($value & 0xC0) !== 0x80) { 185 | throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character); 186 | } 187 | 188 | $character |= ($value & 0x3F) << (--$remaining * 6); 189 | } 190 | $position--; 191 | } 192 | 193 | if ( 194 | // Non-shortest form sequences are invalid 195 | $length > 1 && $character <= 0x7F 196 | || $length > 2 && $character <= 0x7FF 197 | || $length > 3 && $character <= 0xFFFF 198 | // Outside of range of ucschar codepoints 199 | // Noncharacters 200 | || ($character & 0xFFFE) === 0xFFFE 201 | || $character >= 0xFDD0 && $character <= 0xFDEF 202 | || ( 203 | // Everything else not in ucschar 204 | $character > 0xD7FF && $character < 0xF900 205 | || $character < 0x20 206 | || $character > 0x7E && $character < 0xA0 207 | || $character > 0xEFFFD 208 | ) 209 | ) { 210 | throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character); 211 | } 212 | 213 | $codepoints[] = $character; 214 | } 215 | 216 | return $codepoints; 217 | } 218 | 219 | /** 220 | * RFC3492-compliant encoder 221 | * 222 | * @internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code 223 | * @throws Requests_Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`) 224 | * 225 | * @param string $input UTF-8 encoded string to encode 226 | * @return string Punycode-encoded string 227 | */ 228 | public static function punycode_encode($input) { 229 | $output = ''; 230 | # let n = initial_n 231 | $n = self::BOOTSTRAP_INITIAL_N; 232 | # let delta = 0 233 | $delta = 0; 234 | # let bias = initial_bias 235 | $bias = self::BOOTSTRAP_INITIAL_BIAS; 236 | # let h = b = the number of basic code points in the input 237 | $h = $b = 0; // see loop 238 | # copy them to the output in order 239 | $codepoints = self::utf8_to_codepoints($input); 240 | 241 | foreach ($codepoints as $char) { 242 | if ($char < 128) { 243 | // Character is valid ASCII 244 | // TODO: this should also check if it's valid for a URL 245 | $output .= chr($char); 246 | $h++; 247 | } 248 | // Check if the character is non-ASCII, but below initial n 249 | // This never occurs for Punycode, so ignore in coverage 250 | // @codeCoverageIgnoreStart 251 | elseif ($char < $n) { 252 | throw new Requests_Exception('Invalid character', 'idna.character_outside_domain', $char); 253 | } 254 | // @codeCoverageIgnoreEnd 255 | else { 256 | $extended[$char] = true; 257 | } 258 | } 259 | $extended = array_keys($extended); 260 | sort($extended); 261 | $b = $h; 262 | # [copy them] followed by a delimiter if b > 0 263 | if (strlen($output) > 0) { 264 | $output .= '-'; 265 | } 266 | # {if the input contains a non-basic code point < n then fail} 267 | # while h < length(input) do begin 268 | while ($h < count($codepoints)) { 269 | # let m = the minimum code point >= n in the input 270 | $m = array_shift($extended); 271 | //printf('next code point to insert is %s' . PHP_EOL, dechex($m)); 272 | # let delta = delta + (m - n) * (h + 1), fail on overflow 273 | $delta += ($m - $n) * ($h + 1); 274 | # let n = m 275 | $n = $m; 276 | # for each code point c in the input (in order) do begin 277 | for ($num = 0; $num < count($codepoints); $num++) { 278 | $c = $codepoints[$num]; 279 | # if c < n then increment delta, fail on overflow 280 | if ($c < $n) { 281 | $delta++; 282 | } 283 | # if c == n then begin 284 | elseif ($c === $n) { 285 | # let q = delta 286 | $q = $delta; 287 | # for k = base to infinity in steps of base do begin 288 | for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) { 289 | # let t = tmin if k <= bias {+ tmin}, or 290 | # tmax if k >= bias + tmax, or k - bias otherwise 291 | if ($k <= ($bias + self::BOOTSTRAP_TMIN)) { 292 | $t = self::BOOTSTRAP_TMIN; 293 | } 294 | elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) { 295 | $t = self::BOOTSTRAP_TMAX; 296 | } 297 | else { 298 | $t = $k - $bias; 299 | } 300 | # if q < t then break 301 | if ($q < $t) { 302 | break; 303 | } 304 | # output the code point for digit t + ((q - t) mod (base - t)) 305 | $digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t)); 306 | //printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($digit)); 307 | $output .= self::digit_to_char($digit); 308 | # let q = (q - t) div (base - t) 309 | $q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t)); 310 | # end 311 | } 312 | # output the code point for digit q 313 | $output .= self::digit_to_char($q); 314 | //printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($q)); 315 | # let bias = adapt(delta, h + 1, test h equals b?) 316 | $bias = self::adapt($delta, $h + 1, $h === $b); 317 | //printf('bias becomes %d' . PHP_EOL, $bias); 318 | # let delta = 0 319 | $delta = 0; 320 | # increment h 321 | $h++; 322 | # end 323 | } 324 | # end 325 | } 326 | # increment delta and n 327 | $delta++; 328 | $n++; 329 | # end 330 | } 331 | 332 | return $output; 333 | } 334 | 335 | /** 336 | * Convert a digit to its respective character 337 | * 338 | * @see http://tools.ietf.org/html/rfc3492#section-5 339 | * @throws Requests_Exception On invalid digit (`idna.invalid_digit`) 340 | * 341 | * @param int $digit Digit in the range 0-35 342 | * @return string Single character corresponding to digit 343 | */ 344 | protected static function digit_to_char($digit) { 345 | // @codeCoverageIgnoreStart 346 | // As far as I know, this never happens, but still good to be sure. 347 | if ($digit < 0 || $digit > 35) { 348 | throw new Requests_Exception(sprintf('Invalid digit %d', $digit), 'idna.invalid_digit', $digit); 349 | } 350 | // @codeCoverageIgnoreEnd 351 | $digits = 'abcdefghijklmnopqrstuvwxyz0123456789'; 352 | return substr($digits, $digit, 1); 353 | } 354 | 355 | /** 356 | * Adapt the bias 357 | * 358 | * @see http://tools.ietf.org/html/rfc3492#section-6.1 359 | * @param int $delta 360 | * @param int $numpoints 361 | * @param bool $firsttime 362 | * @return int New bias 363 | */ 364 | protected static function adapt($delta, $numpoints, $firsttime) { 365 | # function adapt(delta,numpoints,firsttime): 366 | # if firsttime then let delta = delta div damp 367 | if ($firsttime) { 368 | $delta = floor($delta / self::BOOTSTRAP_DAMP); 369 | } 370 | # else let delta = delta div 2 371 | else { 372 | $delta = floor($delta / 2); 373 | } 374 | # let delta = delta + (delta div numpoints) 375 | $delta += floor($delta / $numpoints); 376 | # let k = 0 377 | $k = 0; 378 | # while delta > ((base - tmin) * tmax) div 2 do begin 379 | $max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2); 380 | while ($delta > $max) { 381 | # let delta = delta div (base - tmin) 382 | $delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN)); 383 | # let k = k + base 384 | $k += self::BOOTSTRAP_BASE; 385 | # end 386 | } 387 | # return k + (((base - tmin + 1) * delta) div (delta + skew)) 388 | return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW)); 389 | } 390 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/IPv6.php: -------------------------------------------------------------------------------- 1 | FF01:0:0:0:0:0:0:101 28 | * ::1 -> 0:0:0:0:0:0:0:1 29 | * 30 | * @author Alexander Merz 31 | * @author elfrink at introweb dot nl 32 | * @author Josh Peck 33 | * @copyright 2003-2005 The PHP Group 34 | * @license http://www.opensource.org/licenses/bsd-license.php 35 | * @param string $ip An IPv6 address 36 | * @return string The uncompressed IPv6 address 37 | */ 38 | public static function uncompress($ip) 39 | { 40 | $c1 = -1; 41 | $c2 = -1; 42 | if (substr_count($ip, '::') === 1) 43 | { 44 | list($ip1, $ip2) = explode('::', $ip); 45 | if ($ip1 === '') 46 | { 47 | $c1 = -1; 48 | } 49 | else 50 | { 51 | $c1 = substr_count($ip1, ':'); 52 | } 53 | if ($ip2 === '') 54 | { 55 | $c2 = -1; 56 | } 57 | else 58 | { 59 | $c2 = substr_count($ip2, ':'); 60 | } 61 | if (strpos($ip2, '.') !== false) 62 | { 63 | $c2++; 64 | } 65 | // :: 66 | if ($c1 === -1 && $c2 === -1) 67 | { 68 | $ip = '0:0:0:0:0:0:0:0'; 69 | } 70 | // ::xxx 71 | else if ($c1 === -1) 72 | { 73 | $fill = str_repeat('0:', 7 - $c2); 74 | $ip = str_replace('::', $fill, $ip); 75 | } 76 | // xxx:: 77 | else if ($c2 === -1) 78 | { 79 | $fill = str_repeat(':0', 7 - $c1); 80 | $ip = str_replace('::', $fill, $ip); 81 | } 82 | // xxx::xxx 83 | else 84 | { 85 | $fill = ':' . str_repeat('0:', 6 - $c2 - $c1); 86 | $ip = str_replace('::', $fill, $ip); 87 | } 88 | } 89 | return $ip; 90 | } 91 | 92 | /** 93 | * Compresses an IPv6 address 94 | * 95 | * RFC 4291 allows you to compress consecutive zero pieces in an address to 96 | * '::'. This method expects a valid IPv6 address and compresses consecutive 97 | * zero pieces to '::'. 98 | * 99 | * Example: FF01:0:0:0:0:0:0:101 -> FF01::101 100 | * 0:0:0:0:0:0:0:1 -> ::1 101 | * 102 | * @see uncompress() 103 | * @param string $ip An IPv6 address 104 | * @return string The compressed IPv6 address 105 | */ 106 | public static function compress($ip) 107 | { 108 | // Prepare the IP to be compressed 109 | $ip = self::uncompress($ip); 110 | $ip_parts = self::split_v6_v4($ip); 111 | 112 | // Replace all leading zeros 113 | $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]); 114 | 115 | // Find bunches of zeros 116 | if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) 117 | { 118 | $max = 0; 119 | $pos = null; 120 | foreach ($matches[0] as $match) 121 | { 122 | if (strlen($match[0]) > $max) 123 | { 124 | $max = strlen($match[0]); 125 | $pos = $match[1]; 126 | } 127 | } 128 | 129 | $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max); 130 | } 131 | 132 | if ($ip_parts[1] !== '') 133 | { 134 | return implode(':', $ip_parts); 135 | } 136 | else 137 | { 138 | return $ip_parts[0]; 139 | } 140 | } 141 | 142 | /** 143 | * Splits an IPv6 address into the IPv6 and IPv4 representation parts 144 | * 145 | * RFC 4291 allows you to represent the last two parts of an IPv6 address 146 | * using the standard IPv4 representation 147 | * 148 | * Example: 0:0:0:0:0:0:13.1.68.3 149 | * 0:0:0:0:0:FFFF:129.144.52.38 150 | * 151 | * @param string $ip An IPv6 address 152 | * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part 153 | */ 154 | private static function split_v6_v4($ip) 155 | { 156 | if (strpos($ip, '.') !== false) 157 | { 158 | $pos = strrpos($ip, ':'); 159 | $ipv6_part = substr($ip, 0, $pos); 160 | $ipv4_part = substr($ip, $pos + 1); 161 | return array($ipv6_part, $ipv4_part); 162 | } 163 | else 164 | { 165 | return array($ip, ''); 166 | } 167 | } 168 | 169 | /** 170 | * Checks an IPv6 address 171 | * 172 | * Checks if the given IP is a valid IPv6 address 173 | * 174 | * @param string $ip An IPv6 address 175 | * @return bool true if $ip is a valid IPv6 address 176 | */ 177 | public static function check_ipv6($ip) 178 | { 179 | $ip = self::uncompress($ip); 180 | list($ipv6, $ipv4) = self::split_v6_v4($ip); 181 | $ipv6 = explode(':', $ipv6); 182 | $ipv4 = explode('.', $ipv4); 183 | if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) 184 | { 185 | foreach ($ipv6 as $ipv6_part) 186 | { 187 | // The section can't be empty 188 | if ($ipv6_part === '') 189 | return false; 190 | 191 | // Nor can it be over four characters 192 | if (strlen($ipv6_part) > 4) 193 | return false; 194 | 195 | // Remove leading zeros (this is safe because of the above) 196 | $ipv6_part = ltrim($ipv6_part, '0'); 197 | if ($ipv6_part === '') 198 | $ipv6_part = '0'; 199 | 200 | // Check the value is valid 201 | $value = hexdec($ipv6_part); 202 | if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) 203 | return false; 204 | } 205 | if (count($ipv4) === 4) 206 | { 207 | foreach ($ipv4 as $ipv4_part) 208 | { 209 | $value = (int) $ipv4_part; 210 | if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) 211 | return false; 212 | } 213 | } 214 | return true; 215 | } 216 | else 217 | { 218 | return false; 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Proxy.php: -------------------------------------------------------------------------------- 1 | proxy = $args; 60 | } 61 | elseif (is_array($args)) { 62 | if (count($args) == 1) { 63 | list($this->proxy) = $args; 64 | } 65 | elseif (count($args) == 3) { 66 | list($this->proxy, $this->user, $this->pass) = $args; 67 | $this->use_authentication = true; 68 | } 69 | else { 70 | throw new Requests_Exception( 'Invalid number of arguments', 'proxyhttpbadargs'); 71 | } 72 | } 73 | } 74 | 75 | /** 76 | * Register the necessary callbacks 77 | * 78 | * @since 1.6 79 | * @see curl_before_send 80 | * @see fsockopen_remote_socket 81 | * @see fsockopen_remote_host_path 82 | * @see fsockopen_header 83 | * @param Requests_Hooks $hooks Hook system 84 | */ 85 | public function register(Requests_Hooks &$hooks) { 86 | $hooks->register('curl.before_send', array(&$this, 'curl_before_send')); 87 | 88 | $hooks->register('fsockopen.remote_socket', array(&$this, 'fsockopen_remote_socket')); 89 | $hooks->register('fsockopen.remote_host_path', array(&$this, 'fsockopen_remote_host_path')); 90 | if( $this->use_authentication ) { 91 | $hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header')); 92 | } 93 | } 94 | 95 | /** 96 | * Set cURL parameters before the data is sent 97 | * 98 | * @since 1.6 99 | * @param resource $handle cURL resource 100 | */ 101 | public function curl_before_send(&$handle) { 102 | curl_setopt($handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); 103 | curl_setopt($handle, CURLOPT_PROXY, $this->proxy); 104 | 105 | if ($this->use_authentication) { 106 | curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY); 107 | curl_setopt($handle, CURLOPT_PROXYUSERPWD, $this->get_auth_string()); 108 | } 109 | } 110 | 111 | /** 112 | * Alter remote socket information before opening socket connection 113 | * 114 | * @since 1.6 115 | * @param string $out HTTP header string 116 | */ 117 | public function fsockopen_remote_socket( &$remote_socket ) { 118 | $remote_socket = $this->proxy; 119 | } 120 | 121 | /** 122 | * Alter remote path before getting stream data 123 | * 124 | * @since 1.6 125 | * @param string $out HTTP header string 126 | */ 127 | public function fsockopen_remote_host_path( &$path, $url ) { 128 | $path = $url; 129 | } 130 | 131 | /** 132 | * Add extra headers to the request before sending 133 | * 134 | * @since 1.6 135 | * @param string $out HTTP header string 136 | */ 137 | public function fsockopen_header( &$out ) { 138 | $out .= "Proxy-Authorization: Basic " . base64_encode($this->get_auth_string()) . "\r\n"; 139 | } 140 | 141 | /** 142 | * Get the authentication string (user:pass) 143 | * 144 | * @since 1.6 145 | * @return string 146 | */ 147 | public function get_auth_string() { 148 | return $this->user . ':' . $this->pass; 149 | } 150 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Response.php: -------------------------------------------------------------------------------- 1 | headers = new Requests_Response_Headers(); 21 | } 22 | 23 | /** 24 | * Response body 25 | * @var string 26 | */ 27 | public $body = ''; 28 | 29 | /** 30 | * Raw HTTP data from the transport 31 | * @var string 32 | */ 33 | public $raw = ''; 34 | 35 | /** 36 | * Headers, as an associative array 37 | * @var array 38 | */ 39 | public $headers = array(); 40 | 41 | /** 42 | * Status code, false if non-blocking 43 | * @var integer|boolean 44 | */ 45 | public $status_code = false; 46 | 47 | /** 48 | * Whether the request succeeded or not 49 | * @var boolean 50 | */ 51 | public $success = false; 52 | 53 | /** 54 | * Number of redirects the request used 55 | * @var integer 56 | */ 57 | public $redirects = 0; 58 | 59 | /** 60 | * URL requested 61 | * @var string 62 | */ 63 | public $url = ''; 64 | 65 | /** 66 | * Previous requests (from redirects) 67 | * @var array Array of Requests_Response objects 68 | */ 69 | public $history = array(); 70 | 71 | /** 72 | * Cookies from the request 73 | */ 74 | public $cookies = array(); 75 | 76 | /** 77 | * Throws an exception if the request was not successful 78 | * 79 | * @throws Requests_Exception If `$allow_redirects` is false, and code is 3xx (`response.no_redirects`) 80 | * @throws Requests_Exception_HTTP On non-successful status code. Exception class corresponds to code (e.g. {@see Requests_Exception_HTTP_404}) 81 | * @param boolean $allow_redirects Set to false to throw on a 3xx as well 82 | */ 83 | public function throw_for_status($allow_redirects = true) { 84 | if ($this->status_code >= 300 && $this->status_code < 400) { 85 | if (!$allow_redirects) { 86 | throw new Requests_Exception('Redirection not allowed', 'response.no_redirects', $this); 87 | } 88 | } 89 | 90 | elseif (!$this->success) { 91 | $exception = Requests_Exception_HTTP::get_class($this->status_code); 92 | throw new $exception(null, $this); 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Response/Headers.php: -------------------------------------------------------------------------------- 1 | data[$key])) 29 | return null; 30 | 31 | return $this->flatten($this->data[$key]); 32 | } 33 | 34 | /** 35 | * Set the given item 36 | * 37 | * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`) 38 | * 39 | * @param string $key Item name 40 | * @param string $value Item value 41 | */ 42 | public function offsetSet($key, $value) { 43 | if ($key === null) { 44 | throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset'); 45 | } 46 | 47 | $key = strtolower($key); 48 | 49 | if (!isset($this->data[$key])) { 50 | $this->data[$key] = array(); 51 | } 52 | 53 | $this->data[$key][] = $value; 54 | } 55 | 56 | /** 57 | * Get all values for a given header 58 | * 59 | * @param string $key 60 | * @return array Header values 61 | */ 62 | public function getValues($key) { 63 | $key = strtolower($key); 64 | if (!isset($this->data[$key])) 65 | return null; 66 | 67 | return $this->data[$key]; 68 | } 69 | 70 | /** 71 | * Flattens a value into a string 72 | * 73 | * Converts an array into a string by imploding values with a comma, as per 74 | * RFC2616's rules for folding headers. 75 | * 76 | * @param string|array $value Value to flatten 77 | * @return string Flattened value 78 | */ 79 | public function flatten($value) { 80 | if (is_array($value)) 81 | $value = implode(',', $value); 82 | 83 | return $value; 84 | } 85 | 86 | /** 87 | * Get an iterator for the data 88 | * 89 | * Converts the internal 90 | * @return ArrayIterator 91 | */ 92 | public function getIterator() { 93 | return new Requests_Utility_FilteredIterator($this->data, array($this, 'flatten')); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/SSL.php: -------------------------------------------------------------------------------- 1 | useragent = 'X';` 53 | * 54 | * @var array 55 | */ 56 | public $options = array(); 57 | 58 | /** 59 | * Create a new session 60 | * 61 | * @param string|null $url Base URL for requests 62 | * @param array $headers Default headers for requests 63 | * @param array $data Default data for requests 64 | * @param array $options Default options for requests 65 | */ 66 | public function __construct($url = null, $headers = array(), $data = array(), $options = array()) { 67 | $this->url = $url; 68 | $this->headers = $headers; 69 | $this->data = $data; 70 | $this->options = $options; 71 | 72 | if (empty($this->options['cookies'])) { 73 | $this->options['cookies'] = new Requests_Cookie_Jar(); 74 | } 75 | } 76 | 77 | /** 78 | * Get a property's value 79 | * 80 | * @param string $key Property key 81 | * @return mixed|null Property value, null if none found 82 | */ 83 | public function __get($key) { 84 | if (isset($this->options[$key])) 85 | return $this->options[$key]; 86 | 87 | return null; 88 | } 89 | 90 | /** 91 | * Set a property's value 92 | * 93 | * @param string $key Property key 94 | * @param mixed $value Property value 95 | */ 96 | public function __set($key, $value) { 97 | $this->options[$key] = $value; 98 | } 99 | 100 | /** 101 | * Remove a property's value 102 | * 103 | * @param string $key Property key 104 | */ 105 | public function __isset($key) { 106 | return isset($this->options[$key]); 107 | } 108 | 109 | /** 110 | * Remove a property's value 111 | * 112 | * @param string $key Property key 113 | */ 114 | public function __unset($key) { 115 | $this->options[$key] = null; 116 | } 117 | 118 | /**#@+ 119 | * @see request() 120 | * @param string $url 121 | * @param array $headers 122 | * @param array $options 123 | * @return Requests_Response 124 | */ 125 | /** 126 | * Send a GET request 127 | */ 128 | public function get($url, $headers = array(), $options = array()) { 129 | return $this->request($url, $headers, null, Requests::GET, $options); 130 | } 131 | 132 | /** 133 | * Send a HEAD request 134 | */ 135 | public function head($url, $headers = array(), $options = array()) { 136 | return $this->request($url, $headers, null, Requests::HEAD, $options); 137 | } 138 | 139 | /** 140 | * Send a DELETE request 141 | */ 142 | public function delete($url, $headers = array(), $options = array()) { 143 | return $this->request($url, $headers, null, Requests::DELETE, $options); 144 | } 145 | /**#@-*/ 146 | 147 | /**#@+ 148 | * @see request() 149 | * @param string $url 150 | * @param array $headers 151 | * @param array $data 152 | * @param array $options 153 | * @return Requests_Response 154 | */ 155 | /** 156 | * Send a POST request 157 | */ 158 | public function post($url, $headers = array(), $data = array(), $options = array()) { 159 | return $this->request($url, $headers, $data, Requests::POST, $options); 160 | } 161 | 162 | /** 163 | * Send a PUT request 164 | */ 165 | public function put($url, $headers = array(), $data = array(), $options = array()) { 166 | return $this->request($url, $headers, $data, Requests::PUT, $options); 167 | } 168 | 169 | /** 170 | * Send a PATCH request 171 | * 172 | * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the 173 | * specification recommends that should send an ETag 174 | * 175 | * @link http://tools.ietf.org/html/rfc5789 176 | */ 177 | public function patch($url, $headers, $data = array(), $options = array()) { 178 | return $this->request($url, $headers, $data, Requests::PATCH, $options); 179 | } 180 | /**#@-*/ 181 | 182 | /** 183 | * Main interface for HTTP requests 184 | * 185 | * This method initiates a request and sends it via a transport before 186 | * parsing. 187 | * 188 | * @see Requests::request() 189 | * 190 | * @throws Requests_Exception On invalid URLs (`nonhttp`) 191 | * 192 | * @param string $url URL to request 193 | * @param array $headers Extra headers to send with the request 194 | * @param array $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests 195 | * @param string $type HTTP request type (use Requests constants) 196 | * @param array $options Options for the request (see {@see Requests::request}) 197 | * @return Requests_Response 198 | */ 199 | public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) { 200 | $request = $this->merge_request(compact('url', 'headers', 'data', 'options')); 201 | 202 | return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']); 203 | } 204 | 205 | /** 206 | * Send multiple HTTP requests simultaneously 207 | * 208 | * @see Requests::request_multiple() 209 | * 210 | * @param array $requests Requests data (see {@see Requests::request_multiple}) 211 | * @param array $options Global and default options (see {@see Requests::request}) 212 | * @return array Responses (either Requests_Response or a Requests_Exception object) 213 | */ 214 | public function request_multiple($requests, $options = array()) { 215 | foreach ($requests as $key => $request) { 216 | $requests[$key] = $this->merge_request($request, false); 217 | } 218 | 219 | $options = array_merge($this->options, $options); 220 | 221 | // Disallow forcing the type, as that's a per request setting 222 | unset($options['type']); 223 | 224 | return Requests::request_multiple($requests, $options); 225 | } 226 | 227 | /** 228 | * Merge a request's data with the default data 229 | * 230 | * @param array $request Request data (same form as {@see request_multiple}) 231 | * @param boolean $merge_options Should we merge options as well? 232 | * @return array Request data 233 | */ 234 | protected function merge_request($request, $merge_options = true) { 235 | if ($this->url !== null) { 236 | $request['url'] = Requests_IRI::absolutize($this->url, $request['url']); 237 | $request['url'] = $request['url']->uri; 238 | } 239 | $request['headers'] = array_merge($this->headers, $request['headers']); 240 | 241 | if (is_array($request['data']) && is_array($this->data)) { 242 | $request['data'] = array_merge($this->data, $request['data']); 243 | } 244 | 245 | if ($merge_options !== false) { 246 | $request['options'] = array_merge($this->options, $request['options']); 247 | 248 | // Disallow forcing the type, as that's a per request setting 249 | unset($request['options']['type']); 250 | } 251 | return $request; 252 | } 253 | } -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Transport.php: -------------------------------------------------------------------------------- 1 | version = $curl['version']; 64 | $this->fp = curl_init(); 65 | 66 | curl_setopt($this->fp, CURLOPT_HEADER, false); 67 | curl_setopt($this->fp, CURLOPT_RETURNTRANSFER, 1); 68 | if (version_compare($this->version, '7.10.5', '>=')) { 69 | curl_setopt($this->fp, CURLOPT_ENCODING, ''); 70 | } 71 | if (version_compare($this->version, '7.19.4', '>=')) { 72 | curl_setopt($this->fp, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); 73 | } 74 | } 75 | 76 | /** 77 | * Perform a request 78 | * 79 | * @throws Requests_Exception On a cURL error (`curlerror`) 80 | * 81 | * @param string $url URL to request 82 | * @param array $headers Associative array of request headers 83 | * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD 84 | * @param array $options Request options, see {@see Requests::response()} for documentation 85 | * @return string Raw HTTP result 86 | */ 87 | public function request($url, $headers = array(), $data = array(), $options = array()) { 88 | $this->setup_handle($url, $headers, $data, $options); 89 | 90 | $options['hooks']->dispatch('curl.before_send', array(&$this->fp)); 91 | 92 | if ($options['filename'] !== false) { 93 | $this->stream_handle = fopen($options['filename'], 'wb'); 94 | curl_setopt($this->fp, CURLOPT_FILE, $this->stream_handle); 95 | } 96 | 97 | if (isset($options['verify'])) { 98 | if ($options['verify'] === false) { 99 | curl_setopt($this->fp, CURLOPT_SSL_VERIFYHOST, 0); 100 | curl_setopt($this->fp, CURLOPT_SSL_VERIFYPEER, 0); 101 | 102 | } elseif (is_string($options['verify'])) { 103 | curl_setopt($this->fp, CURLOPT_CAINFO, $options['verify']); 104 | } 105 | } 106 | 107 | if (isset($options['verifyname']) && $options['verifyname'] === false) { 108 | curl_setopt($this->fp, CURLOPT_SSL_VERIFYHOST, 0); 109 | } 110 | 111 | $response = curl_exec($this->fp); 112 | 113 | $options['hooks']->dispatch('curl.after_send', array(&$fake_headers)); 114 | 115 | if (curl_errno($this->fp) === 23 || curl_errno($this->fp) === 61) { 116 | curl_setopt($this->fp, CURLOPT_ENCODING, 'none'); 117 | $response = curl_exec($this->fp); 118 | } 119 | 120 | $this->process_response($response, $options); 121 | return $this->headers; 122 | } 123 | 124 | /** 125 | * Send multiple requests simultaneously 126 | * 127 | * @param array $requests Request data 128 | * @param array $options Global options 129 | * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well) 130 | */ 131 | public function request_multiple($requests, $options) { 132 | $multihandle = curl_multi_init(); 133 | $subrequests = array(); 134 | $subhandles = array(); 135 | 136 | $class = get_class($this); 137 | foreach ($requests as $id => $request) { 138 | $subrequests[$id] = new $class(); 139 | $subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']); 140 | $request['options']['hooks']->dispatch('curl.before_multi_add', array(&$subhandles[$id])); 141 | curl_multi_add_handle($multihandle, $subhandles[$id]); 142 | } 143 | 144 | $completed = 0; 145 | $responses = array(); 146 | 147 | $request['options']['hooks']->dispatch('curl.before_multi_exec', array(&$multihandle)); 148 | 149 | do { 150 | $active = false; 151 | 152 | do { 153 | $status = curl_multi_exec($multihandle, $active); 154 | } 155 | while ($status === CURLM_CALL_MULTI_PERFORM); 156 | 157 | $to_process = array(); 158 | 159 | // Read the information as needed 160 | while ($done = curl_multi_info_read($multihandle)) { 161 | $key = array_search($done['handle'], $subhandles, true); 162 | if (!isset($to_process[$key])) { 163 | $to_process[$key] = $done; 164 | } 165 | } 166 | 167 | // Parse the finished requests before we start getting the new ones 168 | foreach ($to_process as $key => $done) { 169 | $options = $requests[$key]['options']; 170 | $responses[$key] = $subrequests[$key]->process_response(curl_multi_getcontent($done['handle']), $options); 171 | 172 | $options['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$key], $requests[$key])); 173 | 174 | curl_multi_remove_handle($multihandle, $done['handle']); 175 | curl_close($done['handle']); 176 | 177 | if (!is_string($responses[$key])) { 178 | $options['hooks']->dispatch('multiple.request.complete', array(&$responses[$key], $key)); 179 | } 180 | $completed++; 181 | } 182 | } 183 | while ($active || $completed < count($subrequests)); 184 | 185 | $request['options']['hooks']->dispatch('curl.after_multi_exec', array(&$multihandle)); 186 | 187 | curl_multi_close($multihandle); 188 | 189 | return $responses; 190 | } 191 | 192 | /** 193 | * Get the cURL handle for use in a multi-request 194 | * 195 | * @param string $url URL to request 196 | * @param array $headers Associative array of request headers 197 | * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD 198 | * @param array $options Request options, see {@see Requests::response()} for documentation 199 | * @return resource Subrequest's cURL handle 200 | */ 201 | public function &get_subrequest_handle($url, $headers, $data, $options) { 202 | $this->setup_handle($url, $headers, $data, $options); 203 | 204 | if ($options['filename'] !== false) { 205 | $this->stream_handle = fopen($options['filename'], 'wb'); 206 | curl_setopt($this->fp, CURLOPT_FILE, $this->stream_handle); 207 | } 208 | 209 | return $this->fp; 210 | } 211 | 212 | /** 213 | * Setup the cURL handle for the given data 214 | * 215 | * @param string $url URL to request 216 | * @param array $headers Associative array of request headers 217 | * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD 218 | * @param array $options Request options, see {@see Requests::response()} for documentation 219 | */ 220 | protected function setup_handle($url, $headers, $data, $options) { 221 | $options['hooks']->dispatch('curl.before_request', array(&$this->fp)); 222 | 223 | $headers = Requests::flatten($headers); 224 | if (in_array($options['type'], array(Requests::HEAD, Requests::GET, Requests::DELETE)) & !empty($data)) { 225 | $url = self::format_get($url, $data); 226 | } 227 | elseif (!empty($data) && !is_string($data)) { 228 | $data = http_build_query($data, null, '&'); 229 | } 230 | 231 | switch ($options['type']) { 232 | case Requests::POST: 233 | curl_setopt($this->fp, CURLOPT_POST, true); 234 | curl_setopt($this->fp, CURLOPT_POSTFIELDS, $data); 235 | break; 236 | case Requests::PATCH: 237 | case Requests::PUT: 238 | curl_setopt($this->fp, CURLOPT_CUSTOMREQUEST, $options['type']); 239 | curl_setopt($this->fp, CURLOPT_POSTFIELDS, $data); 240 | break; 241 | case Requests::DELETE: 242 | curl_setopt($this->fp, CURLOPT_CUSTOMREQUEST, 'DELETE'); 243 | break; 244 | case Requests::HEAD: 245 | curl_setopt($this->fp, CURLOPT_NOBODY, true); 246 | break; 247 | } 248 | 249 | curl_setopt($this->fp, CURLOPT_URL, $url); 250 | curl_setopt($this->fp, CURLOPT_TIMEOUT, $options['timeout']); 251 | curl_setopt($this->fp, CURLOPT_CONNECTTIMEOUT, $options['timeout']); 252 | curl_setopt($this->fp, CURLOPT_REFERER, $url); 253 | curl_setopt($this->fp, CURLOPT_USERAGENT, $options['useragent']); 254 | curl_setopt($this->fp, CURLOPT_HTTPHEADER, $headers); 255 | 256 | if (true === $options['blocking']) { 257 | curl_setopt($this->fp, CURLOPT_HEADERFUNCTION, array(&$this, 'stream_headers')); 258 | } 259 | } 260 | 261 | public function process_response($response, $options) { 262 | if ($options['blocking'] === false) { 263 | curl_close($this->fp); 264 | $fake_headers = ''; 265 | $options['hooks']->dispatch('curl.after_request', array(&$fake_headers)); 266 | return false; 267 | } 268 | if ($options['filename'] !== false) { 269 | fclose($this->stream_handle); 270 | $this->headers = trim($this->headers); 271 | } 272 | else { 273 | $this->headers .= $response; 274 | } 275 | 276 | if (curl_errno($this->fp)) { 277 | throw new Requests_Exception('cURL error ' . curl_errno($this->fp) . ': ' . curl_error($this->fp), 'curlerror', $this->fp); 278 | return; 279 | } 280 | $this->info = curl_getinfo($this->fp); 281 | 282 | curl_close($this->fp); 283 | $options['hooks']->dispatch('curl.after_request', array(&$this->headers)); 284 | return $this->headers; 285 | } 286 | 287 | /** 288 | * Collect the headers as they are received 289 | * 290 | * @param resource $handle cURL resource 291 | * @param string $headers Header string 292 | * @return integer Length of provided header 293 | */ 294 | protected function stream_headers($handle, $headers) { 295 | // Why do we do this? cURL will send both the final response and any 296 | // interim responses, such as a 100 Continue. We don't need that. 297 | // (We may want to keep this somewhere just in case) 298 | if ($this->done_headers) { 299 | $this->headers = ''; 300 | $this->done_headers = false; 301 | } 302 | $this->headers .= $headers; 303 | 304 | if ($headers === "\r\n") { 305 | $this->done_headers = true; 306 | } 307 | return strlen($headers); 308 | } 309 | 310 | /** 311 | * Format a URL given GET data 312 | * 313 | * @param string $url 314 | * @param array|object $data Data to build query using, see {@see http://php.net/http_build_query} 315 | * @return string URL with data 316 | */ 317 | protected static function format_get($url, $data) { 318 | if (!empty($data)) { 319 | $url_parts = parse_url($url); 320 | if (empty($url_parts['query'])) { 321 | $query = $url_parts['query'] = ''; 322 | } 323 | else { 324 | $query = $url_parts['query']; 325 | } 326 | 327 | $query .= '&' . http_build_query($data, null, '&'); 328 | $query = trim($query, '&'); 329 | 330 | if (empty($url_parts['query'])) { 331 | $url .= '?' . $query; 332 | } 333 | else { 334 | $url = str_replace($url_parts['query'], $query, $url); 335 | } 336 | } 337 | return $url; 338 | } 339 | 340 | /** 341 | * Whether this transport is valid 342 | * 343 | * @codeCoverageIgnore 344 | * @return boolean True if the transport is valid, false otherwise. 345 | */ 346 | public static function test() { 347 | return (function_exists('curl_init') && function_exists('curl_exec')); 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Transport/fsockopen.php: -------------------------------------------------------------------------------- 1 | dispatch('fsockopen.before_request'); 46 | 47 | $url_parts = parse_url($url); 48 | $host = $url_parts['host']; 49 | $context = stream_context_create(); 50 | $verifyname = false; 51 | 52 | // HTTPS support 53 | if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') { 54 | $remote_socket = 'ssl://' . $host; 55 | $url_parts['port'] = 443; 56 | 57 | $context_options = array( 58 | 'verify_peer' => true, 59 | // 'CN_match' => $host, 60 | 'capture_peer_cert' => true 61 | ); 62 | $verifyname = true; 63 | 64 | // SNI, if enabled (OpenSSL >=0.9.8j) 65 | if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) { 66 | $context_options['SNI_enabled'] = true; 67 | if (isset($options['verifyname']) && $options['verifyname'] === false) { 68 | $context_options['SNI_enabled'] = false; 69 | } 70 | } 71 | 72 | if (isset($options['verify'])) { 73 | if ($options['verify'] === false) { 74 | $context_options['verify_peer'] = false; 75 | } elseif (is_string($options['verify'])) { 76 | $context_options['cafile'] = $options['verify']; 77 | } 78 | } 79 | 80 | if (isset($options['verifyname']) && $options['verifyname'] === false) { 81 | $verifyname = false; 82 | } 83 | 84 | stream_context_set_option($context, array('ssl' => $context_options)); 85 | } 86 | else { 87 | $remote_socket = 'tcp://' . $host; 88 | } 89 | 90 | $proxy = isset( $options['proxy'] ); 91 | $proxy_auth = $proxy && isset( $options['proxy_username'] ) && isset( $options['proxy_password'] ); 92 | 93 | if (!isset($url_parts['port'])) { 94 | $url_parts['port'] = 80; 95 | } 96 | $remote_socket .= ':' . $url_parts['port']; 97 | 98 | set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE); 99 | 100 | $options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket)); 101 | 102 | $fp = stream_socket_client($remote_socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT, $context); 103 | 104 | restore_error_handler(); 105 | 106 | if ($verifyname) { 107 | if (!$this->verify_certificate_from_context($host, $context)) { 108 | throw new Requests_Exception('SSL certificate did not match the requested domain name', 'ssl.no_match'); 109 | } 110 | } 111 | 112 | if (!$fp) { 113 | if ($errno === 0) { 114 | // Connection issue 115 | throw new Requests_Exception(rtrim($this->connect_error), 'fsockopen.connect_error'); 116 | } 117 | else { 118 | throw new Requests_Exception($errstr, 'fsockopenerror'); 119 | return; 120 | } 121 | } 122 | 123 | $request_body = ''; 124 | $out = ''; 125 | switch ($options['type']) { 126 | case Requests::POST: 127 | case Requests::PUT: 128 | case Requests::PATCH: 129 | if (isset($url_parts['path'])) { 130 | $path = $url_parts['path']; 131 | if (isset($url_parts['query'])) { 132 | $path .= '?' . $url_parts['query']; 133 | } 134 | } 135 | else { 136 | $path = '/'; 137 | } 138 | 139 | $options['hooks']->dispatch( 'fsockopen.remote_host_path', array( &$path, $url ) ); 140 | $out = $options['type'] . " $path HTTP/1.0\r\n"; 141 | 142 | if (is_array($data)) { 143 | $request_body = http_build_query($data, null, '&'); 144 | } 145 | else { 146 | $request_body = $data; 147 | } 148 | if (empty($headers['Content-Length'])) { 149 | $headers['Content-Length'] = strlen($request_body); 150 | } 151 | if (empty($headers['Content-Type'])) { 152 | $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; 153 | } 154 | break; 155 | case Requests::HEAD: 156 | case Requests::GET: 157 | case Requests::DELETE: 158 | $path = self::format_get($url_parts, $data); 159 | $options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url)); 160 | $out = $options['type'] . " $path HTTP/1.0\r\n"; 161 | break; 162 | } 163 | $out .= "Host: {$url_parts['host']}"; 164 | 165 | if ($url_parts['port'] !== 80) { 166 | $out .= ":{$url_parts['port']}"; 167 | } 168 | $out .= "\r\n"; 169 | 170 | $out .= "User-Agent: {$options['useragent']}\r\n"; 171 | $accept_encoding = $this->accept_encoding(); 172 | if (!empty($accept_encoding)) { 173 | $out .= "Accept-Encoding: $accept_encoding\r\n"; 174 | } 175 | 176 | $headers = Requests::flatten($headers); 177 | 178 | if (!empty($headers)) { 179 | $out .= implode($headers, "\r\n") . "\r\n"; 180 | } 181 | 182 | $options['hooks']->dispatch('fsockopen.after_headers', array(&$out)); 183 | 184 | if (substr($out, -2) !== "\r\n") { 185 | $out .= "\r\n"; 186 | } 187 | 188 | $out .= "Connection: Close\r\n\r\n" . $request_body; 189 | 190 | $options['hooks']->dispatch('fsockopen.before_send', array(&$out)); 191 | 192 | fwrite($fp, $out); 193 | $options['hooks']->dispatch('fsockopen.after_send', array(&$fake_headers)); 194 | 195 | if (!$options['blocking']) { 196 | fclose($fp); 197 | $fake_headers = ''; 198 | $options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers)); 199 | return ''; 200 | } 201 | stream_set_timeout($fp, $options['timeout']); 202 | 203 | $this->info = stream_get_meta_data($fp); 204 | 205 | $this->headers = ''; 206 | $this->info = stream_get_meta_data($fp); 207 | if (!$options['filename']) { 208 | while (!feof($fp)) { 209 | $this->info = stream_get_meta_data($fp); 210 | if ($this->info['timed_out']) { 211 | throw new Requests_Exception('fsocket timed out', 'timeout'); 212 | } 213 | 214 | $this->headers .= fread($fp, 1160); 215 | } 216 | } 217 | else { 218 | $download = fopen($options['filename'], 'wb'); 219 | $doingbody = false; 220 | $response = ''; 221 | while (!feof($fp)) { 222 | $this->info = stream_get_meta_data($fp); 223 | if ($this->info['timed_out']) { 224 | throw new Requests_Exception('fsocket timed out', 'timeout'); 225 | } 226 | 227 | $block = fread($fp, 1160); 228 | if ($doingbody) { 229 | fwrite($download, $block); 230 | } 231 | else { 232 | $response .= $block; 233 | if (strpos($response, "\r\n\r\n")) { 234 | list($this->headers, $block) = explode("\r\n\r\n", $response, 2); 235 | $doingbody = true; 236 | fwrite($download, $block); 237 | } 238 | } 239 | } 240 | fclose($download); 241 | } 242 | fclose($fp); 243 | 244 | $options['hooks']->dispatch('fsockopen.after_request', array(&$this->headers)); 245 | return $this->headers; 246 | } 247 | 248 | /** 249 | * Send multiple requests simultaneously 250 | * 251 | * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request} 252 | * @param array $options Global options, see {@see Requests::response()} for documentation 253 | * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well) 254 | */ 255 | public function request_multiple($requests, $options) { 256 | $responses = array(); 257 | $class = get_class($this); 258 | foreach ($requests as $id => $request) { 259 | try { 260 | $handler = new $class(); 261 | $responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']); 262 | 263 | $request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request)); 264 | } 265 | catch (Requests_Exception $e) { 266 | $responses[$id] = $e; 267 | } 268 | 269 | if (!is_string($responses[$id])) { 270 | $request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id)); 271 | } 272 | } 273 | 274 | return $responses; 275 | } 276 | 277 | /** 278 | * Retrieve the encodings we can accept 279 | * 280 | * @return string Accept-Encoding header value 281 | */ 282 | protected static function accept_encoding() { 283 | $type = array(); 284 | if (function_exists('gzinflate')) { 285 | $type[] = 'deflate;q=1.0'; 286 | } 287 | 288 | if (function_exists('gzuncompress')) { 289 | $type[] = 'compress;q=0.5'; 290 | } 291 | 292 | $type[] = 'gzip;q=0.5'; 293 | 294 | return implode(', ', $type); 295 | } 296 | 297 | /** 298 | * Format a URL given GET data 299 | * 300 | * @param array $url_parts 301 | * @param array|object $data Data to build query using, see {@see http://php.net/http_build_query} 302 | * @return string URL with data 303 | */ 304 | protected static function format_get($url_parts, $data) { 305 | if (!empty($data)) { 306 | if (empty($url_parts['query'])) 307 | $url_parts['query'] = ''; 308 | 309 | $url_parts['query'] .= '&' . http_build_query($data, null, '&'); 310 | $url_parts['query'] = trim($url_parts['query'], '&'); 311 | } 312 | if (isset($url_parts['path'])) { 313 | if (isset($url_parts['query'])) { 314 | $get = $url_parts['path'] . '?' . $url_parts['query']; 315 | } 316 | else { 317 | $get = $url_parts['path']; 318 | } 319 | } 320 | else { 321 | $get = '/'; 322 | } 323 | return $get; 324 | } 325 | 326 | /** 327 | * Error handler for stream_socket_client() 328 | * 329 | * @param int $errno Error number (e.g. E_WARNING) 330 | * @param string $errstr Error message 331 | */ 332 | public function connect_error_handler($errno, $errstr) { 333 | // Double-check we can handle it 334 | if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) { 335 | // Return false to indicate the default error handler should engage 336 | return false; 337 | } 338 | 339 | $this->connect_error .= $errstr . "\n"; 340 | return true; 341 | } 342 | 343 | /** 344 | * Verify the certificate against common name and subject alternative names 345 | * 346 | * Unfortunately, PHP doesn't check the certificate against the alternative 347 | * names, leading things like 'https://www.github.com/' to be invalid. 348 | * Instead 349 | * 350 | * @see http://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1 351 | * 352 | * @throws Requests_Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`) 353 | * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`) 354 | * @param string $host Host name to verify against 355 | * @param resource $context Stream context 356 | * @return bool 357 | */ 358 | public function verify_certificate_from_context($host, $context) { 359 | $meta = stream_context_get_options($context); 360 | 361 | // If we don't have SSL options, then we couldn't make the connection at 362 | // all 363 | if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) { 364 | throw new Requests_Exception(rtrim($this->connect_error), 'ssl.connect_error'); 365 | } 366 | 367 | $cert = openssl_x509_parse($meta['ssl']['peer_certificate']); 368 | 369 | return Requests_SSL::verify_certificate($host, $cert); 370 | } 371 | 372 | /** 373 | * Whether this transport is valid 374 | * 375 | * @codeCoverageIgnore 376 | * @return boolean True if the transport is valid, false otherwise. 377 | */ 378 | public static function test() { 379 | return function_exists('fsockopen'); 380 | } 381 | } 382 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Utility/CaseInsensitiveDictionary.php: -------------------------------------------------------------------------------- 1 | data[$key]); 32 | } 33 | 34 | /** 35 | * Get the value for the item 36 | * 37 | * @param string $key Item key 38 | * @return string Item value 39 | */ 40 | public function offsetGet($key) { 41 | $key = strtolower($key); 42 | if (!isset($this->data[$key])) 43 | return null; 44 | 45 | return $this->data[$key]; 46 | } 47 | 48 | /** 49 | * Set the given item 50 | * 51 | * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`) 52 | * 53 | * @param string $key Item name 54 | * @param string $value Item value 55 | */ 56 | public function offsetSet($key, $value) { 57 | if ($key === null) { 58 | throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset'); 59 | } 60 | 61 | $key = strtolower($key); 62 | $this->data[$key] = $value; 63 | } 64 | 65 | /** 66 | * Unset the given header 67 | * 68 | * @param string $key 69 | */ 70 | public function offsetUnset($key) { 71 | unset($this->data[strtolower($key)]); 72 | } 73 | 74 | /** 75 | * Get an iterator for the data 76 | * 77 | * @return ArrayIterator 78 | */ 79 | public function getIterator() { 80 | return new ArrayIterator($this->data); 81 | } 82 | 83 | /** 84 | * Get the headers as an array 85 | * 86 | * @return array Header data 87 | */ 88 | public function getAll() { 89 | return $this->data; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Requests-1.6.0/library/Requests/Utility/FilteredIterator.php: -------------------------------------------------------------------------------- 1 | callback = $callback; 26 | } 27 | 28 | /** 29 | * Get the current item's value after filtering 30 | * 31 | * @return string 32 | */ 33 | public function current() { 34 | $value = parent::current(); 35 | $value = call_user_func($this->callback, $value); 36 | return $value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Requests-1.6.0/package.xml.tpl: -------------------------------------------------------------------------------- 1 | 2 | 8 | Requests 9 | pear.ryanmccue.info 10 | A HTTP library written in PHP, for human beings. 11 | 12 | Requests is a HTTP library written in PHP, for human beings. It is 13 | roughly based on the API from the excellent Requests Python library. 14 | Requests is ISC Licensed (similar to the new BSD license) and has 15 | no dependencies. 16 | 17 | 18 | Ryan McCue 19 | rmccue 20 | me+pear@ryanmccue dot info 21 | yes 22 | 23 | {{ date }} 24 | 25 | 26 | {{ version }} 27 | {{ api_version }} 28 | 29 | 30 | {{ stability }} 31 | {{ stability }} 32 | 33 | ISC 34 | - 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | {{ files }} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 5.2.0 53 | 54 | 55 | 1.4.0 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Auth/Basic.php: -------------------------------------------------------------------------------- 1 | markTestSkipped($transport . ' is not available'); 18 | return; 19 | } 20 | 21 | $options = array( 22 | 'auth' => array('user', 'passwd'), 23 | 'transport' => $transport, 24 | ); 25 | $request = Requests::get('http://httpbin.org/basic-auth/user/passwd', array(), $options); 26 | $this->assertEquals(200, $request->status_code); 27 | 28 | $result = json_decode($request->body); 29 | $this->assertEquals(true, $result->authenticated); 30 | $this->assertEquals('user', $result->user); 31 | } 32 | 33 | /** 34 | * @dataProvider transportProvider 35 | */ 36 | public function testUsingInstantiation($transport) { 37 | if (!call_user_func(array($transport, 'test'))) { 38 | $this->markTestSkipped($transport . ' is not available'); 39 | return; 40 | } 41 | 42 | $options = array( 43 | 'auth' => new Requests_Auth_Basic(array('user', 'passwd')), 44 | 'transport' => $transport, 45 | ); 46 | $request = Requests::get('http://httpbin.org/basic-auth/user/passwd', array(), $options); 47 | $this->assertEquals(200, $request->status_code); 48 | 49 | $result = json_decode($request->body); 50 | $this->assertEquals(true, $result->authenticated); 51 | $this->assertEquals('user', $result->user); 52 | } 53 | 54 | /** 55 | * @dataProvider transportProvider 56 | */ 57 | public function testPOSTUsingInstantiation($transport) { 58 | if (!call_user_func(array($transport, 'test'))) { 59 | $this->markTestSkipped($transport . ' is not available'); 60 | return; 61 | } 62 | 63 | $options = array( 64 | 'auth' => new Requests_Auth_Basic(array('user', 'passwd')), 65 | 'transport' => $transport, 66 | ); 67 | $data = 'test'; 68 | $request = Requests::post('http://httpbin.org/post', array(), $data, $options); 69 | $this->assertEquals(200, $request->status_code); 70 | 71 | $result = json_decode($request->body); 72 | 73 | $auth = $result->headers->Authorization; 74 | $auth = explode(' ', $auth); 75 | 76 | $this->assertEquals(base64_encode('user:passwd'), $auth[1]); 77 | $this->assertEquals('test', $result->data); 78 | } 79 | 80 | /** 81 | * @expectedException Requests_Exception 82 | */ 83 | public function testMissingPassword() { 84 | $auth = new Requests_Auth_Basic(array('user')); 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /Requests-1.6.0/tests/ChunkedEncoding.php: -------------------------------------------------------------------------------- 1 | body = $body; 27 | $transport->chunked = true; 28 | 29 | $options = array( 30 | 'transport' => $transport 31 | ); 32 | $response = Requests::get('http://example.com/', array(), $options); 33 | 34 | $this->assertEquals($expected, $response->body); 35 | } 36 | 37 | /** 38 | * Response says it's chunked, but actually isn't 39 | */ 40 | public function testNotActuallyChunked() { 41 | $transport = new MockTransport(); 42 | $transport->body = 'Hello! This is a non-chunked response!'; 43 | $transport->chunked = true; 44 | 45 | $options = array( 46 | 'transport' => $transport 47 | ); 48 | $response = Requests::get('http://example.com/', array(), $options); 49 | 50 | $this->assertEquals($transport->body, $response->body); 51 | } 52 | 53 | /** 54 | * Response says it's chunked and starts looking like it is, but turns out 55 | * that they're lying to us 56 | */ 57 | public function testMixedChunkiness() { 58 | $transport = new MockTransport(); 59 | $transport->body = "02\r\nab\r\nNot actually chunked!"; 60 | $transport->chunked = true; 61 | 62 | $options = array( 63 | 'transport' => $transport 64 | ); 65 | $response = Requests::get('http://example.com/', array(), $options); 66 | $this->assertEquals($transport->body, $response->body); 67 | } 68 | } -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Cookies.php: -------------------------------------------------------------------------------- 1 | assertEquals('requests-testcookie', $cookie->name); 8 | $this->assertEquals('testvalue', $cookie->value); 9 | $this->assertEquals('testvalue', (string) $cookie); 10 | 11 | $this->assertEquals('requests-testcookie=testvalue', $cookie->formatForHeader()); 12 | $this->assertEquals('requests-testcookie=testvalue', $cookie->formatForSetCookie()); 13 | } 14 | 15 | public function testCookieWithAttributes() { 16 | $attributes = array( 17 | 'httponly', 18 | 'path' => '/' 19 | ); 20 | $cookie = new Requests_Cookie('requests-testcookie', 'testvalue', $attributes); 21 | 22 | $this->assertEquals('requests-testcookie=testvalue', $cookie->formatForHeader()); 23 | $this->assertEquals('requests-testcookie=testvalue; httponly; path=/', $cookie->formatForSetCookie()); 24 | } 25 | 26 | public function testEmptyCookieName() { 27 | $cookie = Requests_Cookie::parse('test'); 28 | $this->assertEquals('', $cookie->name); 29 | $this->assertEquals('test', $cookie->value); 30 | } 31 | 32 | public function testEmptyAttributes() { 33 | $cookie = Requests_Cookie::parse('foo=bar; HttpOnly'); 34 | $this->assertTrue($cookie->attributes['httponly']); 35 | } 36 | 37 | public function testCookieJarSetter() { 38 | $jar1 = new Requests_Cookie_Jar(); 39 | $jar1['requests-testcookie'] = 'testvalue'; 40 | 41 | $jar2 = new Requests_Cookie_Jar(array( 42 | 'requests-testcookie' => 'testvalue', 43 | )); 44 | $this->assertEquals($jar1, $jar2); 45 | } 46 | 47 | public function testCookieJarUnsetter() { 48 | $jar = new Requests_Cookie_Jar(); 49 | $jar['requests-testcookie'] = 'testvalue'; 50 | 51 | $this->assertEquals('testvalue', $jar['requests-testcookie']); 52 | 53 | unset($jar['requests-testcookie']); 54 | $this->assertEmpty($jar['requests-testcookie']); 55 | $this->assertFalse(isset($jar['requests-testcookie'])); 56 | } 57 | 58 | /** 59 | * @expectedException Requests_Exception 60 | */ 61 | public function testCookieJarAsList() { 62 | $cookies = new Requests_Cookie_Jar(); 63 | $cookies[] = 'requests-testcookie1=testvalue1'; 64 | } 65 | 66 | public function testCookieJarIterator() { 67 | $cookies = array( 68 | 'requests-testcookie1' => 'testvalue1', 69 | 'requests-testcookie2' => 'testvalue2', 70 | ); 71 | $jar = new Requests_Cookie_Jar($cookies); 72 | 73 | foreach ($jar as $key => $value) { 74 | $this->assertEquals($cookies[$key], $value); 75 | } 76 | } 77 | 78 | public function testReceivingCookies() { 79 | $options = array( 80 | 'follow_redirects' => false, 81 | ); 82 | $url = 'http://httpbin.org/cookies/set?requests-testcookie=testvalue'; 83 | 84 | $response = Requests::get($url, array(), $options); 85 | 86 | $cookie = $response->cookies['requests-testcookie']; 87 | $this->assertNotEmpty( $cookie ); 88 | $this->assertEquals( 'testvalue', $cookie->value ); 89 | } 90 | 91 | public function testPersistenceOnRedirect() { 92 | $options = array( 93 | 'follow_redirects' => true, 94 | ); 95 | $url = 'http://httpbin.org/cookies/set?requests-testcookie=testvalue'; 96 | 97 | $response = Requests::get($url, array(), $options); 98 | 99 | $cookie = $response->cookies['requests-testcookie']; 100 | $this->assertNotEmpty( $cookie ); 101 | $this->assertEquals( 'testvalue', $cookie->value ); 102 | } 103 | 104 | protected function setCookieRequest($cookies) { 105 | $options = array( 106 | 'cookies' => $cookies, 107 | ); 108 | $response = Requests::get('http://httpbin.org/cookies/set', array(), $options); 109 | 110 | $data = json_decode($response->body, true); 111 | $this->assertInternalType('array', $data); 112 | $this->assertArrayHasKey('cookies', $data); 113 | return $data['cookies']; 114 | } 115 | 116 | public function testSendingCookie() { 117 | $cookies = array( 118 | 'requests-testcookie1' => 'testvalue1', 119 | ); 120 | 121 | $data = $this->setCookieRequest($cookies); 122 | 123 | $this->assertArrayHasKey('requests-testcookie1', $data); 124 | $this->assertEquals('testvalue1', $data['requests-testcookie1']); 125 | } 126 | 127 | public function testSendingCookieWithJar() { 128 | $cookies = new Requests_Cookie_Jar(array( 129 | 'requests-testcookie1' => 'testvalue1', 130 | )); 131 | $data = $this->setCookieRequest($cookies); 132 | 133 | $this->assertArrayHasKey('requests-testcookie1', $data); 134 | $this->assertEquals('testvalue1', $data['requests-testcookie1']); 135 | } 136 | 137 | public function testSendingMultipleCookies() { 138 | $cookies = array( 139 | 'requests-testcookie1' => 'testvalue1', 140 | 'requests-testcookie2' => 'testvalue2', 141 | ); 142 | $data = $this->setCookieRequest($cookies); 143 | 144 | $this->assertArrayHasKey('requests-testcookie1', $data); 145 | $this->assertEquals('testvalue1', $data['requests-testcookie1']); 146 | 147 | $this->assertArrayHasKey('requests-testcookie2', $data); 148 | $this->assertEquals('testvalue2', $data['requests-testcookie2']); 149 | } 150 | 151 | public function testSendingMultipleCookiesWithJar() { 152 | $cookies = new Requests_Cookie_Jar(array( 153 | 'requests-testcookie1' => 'testvalue1', 154 | 'requests-testcookie2' => 'testvalue2', 155 | )); 156 | $data = $this->setCookieRequest($cookies); 157 | 158 | $this->assertArrayHasKey('requests-testcookie1', $data); 159 | $this->assertEquals('testvalue1', $data['requests-testcookie1']); 160 | 161 | $this->assertArrayHasKey('requests-testcookie2', $data); 162 | $this->assertEquals('testvalue2', $data['requests-testcookie2']); 163 | } 164 | 165 | public function testSendingPrebakedCookie() { 166 | $cookies = new Requests_Cookie_Jar(array( 167 | new Requests_Cookie('requests-testcookie', 'testvalue'), 168 | )); 169 | $data = $this->setCookieRequest($cookies); 170 | 171 | $this->assertArrayHasKey('requests-testcookie', $data); 172 | $this->assertEquals('testvalue', $data['requests-testcookie']); 173 | } 174 | } -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Encoding.php: -------------------------------------------------------------------------------- 1 | $set) { 66 | $real_set = self::mapData($key, $set); 67 | $data = array_merge($data, $real_set); 68 | } 69 | return $data; 70 | } 71 | 72 | /** 73 | * @dataProvider encodedData 74 | */ 75 | public function testDecompress($original, $encoded) { 76 | $decoded = Requests::decompress($encoded); 77 | $this->assertEquals($original, $decoded); 78 | } 79 | 80 | /** 81 | * @dataProvider encodedData 82 | */ 83 | public function testCompatibleInflate($original, $encoded) { 84 | $decoded = Requests::compatible_gzinflate($encoded); 85 | $this->assertEquals($original, $decoded); 86 | } 87 | 88 | protected function bin2hex($field) { 89 | $field = bin2hex($field); 90 | $field = chunk_split($field,2,"\\x"); 91 | $field = "\\x" . substr($field,0,-2); 92 | return $field; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Requests-1.6.0/tests/IDNAEncoder.php: -------------------------------------------------------------------------------- 1 | assertEquals($expected, $result); 23 | } 24 | 25 | /** 26 | * @expectedException Requests_Exception 27 | */ 28 | public function testASCIITooLong() { 29 | $data = str_repeat("abcd", 20); 30 | $result = Requests_IDNAEncoder::encode($data); 31 | } 32 | 33 | /** 34 | * @expectedException Requests_Exception 35 | */ 36 | public function testEncodedTooLong() { 37 | $data = str_repeat("\xe4\xbb\x96", 60); 38 | $result = Requests_IDNAEncoder::encode($data); 39 | } 40 | 41 | /** 42 | * @expectedException Requests_Exception 43 | */ 44 | public function testAlreadyPrefixed() { 45 | $result = Requests_IDNAEncoder::encode("xn--\xe4\xbb\x96"); 46 | } 47 | 48 | public function testASCIICharacter() { 49 | $result = Requests_IDNAEncoder::encode("a"); 50 | $this->assertEquals('a', $result); 51 | } 52 | 53 | public function testTwoByteCharacter() { 54 | $result = Requests_IDNAEncoder::encode("\xc2\xb6"); // Pilcrow character 55 | $this->assertEquals('xn--tba', $result); 56 | } 57 | 58 | public function testThreeByteCharacter() { 59 | $result = Requests_IDNAEncoder::encode("\xe2\x82\xac"); // Euro symbol 60 | $this->assertEquals('xn--lzg', $result); 61 | } 62 | 63 | public function testFourByteCharacter() { 64 | $result = Requests_IDNAEncoder::encode("\xf0\xa4\xad\xa2"); // Chinese symbol? 65 | $this->assertEquals('xn--ww6j', $result); 66 | } 67 | 68 | /** 69 | * @expectedException Requests_Exception 70 | */ 71 | public function testFiveByteCharacter() { 72 | $result = Requests_IDNAEncoder::encode("\xfb\xb6\xb6\xb6\xb6"); 73 | } 74 | 75 | /** 76 | * @expectedException Requests_Exception 77 | */ 78 | public function testSixByteCharacter() { 79 | $result = Requests_IDNAEncoder::encode("\xfd\xb6\xb6\xb6\xb6\xb6"); 80 | } 81 | 82 | /** 83 | * @expectedException Requests_Exception 84 | */ 85 | public function testInvalidASCIICharacterWithMultibyte() { 86 | $result = Requests_IDNAEncoder::encode("\0\xc2\xb6"); 87 | } 88 | 89 | /** 90 | * @expectedException Requests_Exception 91 | */ 92 | public function testUnfinishedMultibyte() { 93 | $result = Requests_IDNAEncoder::encode("\xc2"); 94 | } 95 | 96 | /** 97 | * @expectedException Requests_Exception 98 | */ 99 | public function testPartialMultibyte() { 100 | $result = Requests_IDNAEncoder::encode("\xc2\xc2\xb6"); 101 | } 102 | } -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Requests.php: -------------------------------------------------------------------------------- 1 | assertEquals(200, $request->status_code); 14 | } 15 | 16 | /** 17 | * Standard response header parsing 18 | */ 19 | public function testHeaderParsing() { 20 | $transport = new RawTransport(); 21 | $transport->data = 22 | "HTTP/1.0 200 OK\r\n". 23 | "Host: localhost\r\n". 24 | "Host: ambiguous\r\n". 25 | "Nospace:here\r\n". 26 | "Muchspace: there \r\n". 27 | "Empty:\r\n". 28 | "Empty2: \r\n". 29 | "Folded: one\r\n". 30 | "\ttwo\r\n". 31 | " three\r\n\r\n". 32 | "stop\r\n"; 33 | 34 | $options = array( 35 | 'transport' => $transport 36 | ); 37 | $response = Requests::get('http://example.com/', array(), $options); 38 | $expected = new Requests_Response_Headers(); 39 | $expected['host'] = 'localhost,ambiguous'; 40 | $expected['nospace'] = 'here'; 41 | $expected['muchspace'] = 'there'; 42 | $expected['empty'] = ''; 43 | $expected['empty2'] = ''; 44 | $expected['folded'] = 'one two three'; 45 | foreach ($expected as $key => $value) { 46 | $this->assertEquals($value, $response->headers[$key]); 47 | } 48 | 49 | foreach ($response->headers as $key => $value) { 50 | $this->assertEquals($value, $expected[$key]); 51 | } 52 | } 53 | 54 | public function testRawAccess() { 55 | $transport = new RawTransport(); 56 | $transport->data = 57 | "HTTP/1.0 200 OK\r\n". 58 | "Host: localhost\r\n\r\n". 59 | "Test"; 60 | 61 | $options = array( 62 | 'transport' => $transport 63 | ); 64 | $response = Requests::get('http://example.com/', array(), $options); 65 | $this->assertEquals($transport->data, $response->raw); 66 | } 67 | 68 | /** 69 | * Headers with only \n delimiting should be treated as if they're \r\n 70 | */ 71 | public function testHeaderOnlyLF() { 72 | $transport = new RawTransport(); 73 | $transport->data = "HTTP/1.0 200 OK\r\nTest: value\nAnother-Test: value\r\n\r\n"; 74 | 75 | $options = array( 76 | 'transport' => $transport 77 | ); 78 | $response = Requests::get('http://example.com/', array(), $options); 79 | $this->assertEquals('value', $response->headers['test']); 80 | $this->assertEquals('value', $response->headers['another-test']); 81 | } 82 | 83 | /** 84 | * Check that invalid protocols are not accepted 85 | * 86 | * We do not support HTTP/0.9. If this is really an issue for you, file a 87 | * new issue, and update your server/proxy to support a proper protocol. 88 | * 89 | * @expectedException Requests_Exception 90 | */ 91 | public function testInvalidProtocolVersion() { 92 | $transport = new RawTransport(); 93 | $transport->data = "HTTP/0.9 200 OK\r\n\r\n

Test"; 94 | 95 | $options = array( 96 | 'transport' => $transport 97 | ); 98 | $response = Requests::get('http://example.com/', array(), $options); 99 | } 100 | 101 | /** 102 | * HTTP/0.9 also appears to use a single CRLF instead of two 103 | * 104 | * @expectedException Requests_Exception 105 | */ 106 | public function testSingleCRLFSeparator() { 107 | $transport = new RawTransport(); 108 | $transport->data = "HTTP/0.9 200 OK\r\n

Test"; 109 | 110 | $options = array( 111 | 'transport' => $transport 112 | ); 113 | $response = Requests::get('http://example.com/', array(), $options); 114 | } 115 | 116 | /** 117 | * @expectedException Requests_Exception 118 | */ 119 | public function testInvalidStatus() { 120 | $transport = new RawTransport(); 121 | $transport->data = "HTTP/1.1 OK\r\nTest: value\nAnother-Test: value\r\n\r\nTest"; 122 | 123 | $options = array( 124 | 'transport' => $transport 125 | ); 126 | $response = Requests::get('http://example.com/', array(), $options); 127 | } 128 | 129 | public function test30xWithoutLocation() { 130 | $transport = new MockTransport(); 131 | $transport->code = 302; 132 | 133 | $options = array( 134 | 'transport' => $transport 135 | ); 136 | $response = Requests::get('http://example.com/', array(), $options); 137 | $this->assertEquals(302, $response->status_code); 138 | $this->assertEquals(0, $response->redirects); 139 | } 140 | } -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Response/Headers.php: -------------------------------------------------------------------------------- 1 | assertEquals('text/plain', $headers['Content-Type']); 9 | } 10 | public function testCaseInsensitiveArrayAccess() { 11 | $headers = new Requests_Response_Headers(); 12 | $headers['Content-Type'] = 'text/plain'; 13 | 14 | $this->assertEquals('text/plain', $headers['CONTENT-TYPE']); 15 | $this->assertEquals('text/plain', $headers['content-type']); 16 | } 17 | 18 | /** 19 | * @depends testArrayAccess 20 | */ 21 | public function testIteration() { 22 | $headers = new Requests_Response_Headers(); 23 | $headers['Content-Type'] = 'text/plain'; 24 | $headers['Content-Length'] = 10; 25 | 26 | foreach ($headers as $name => $value) { 27 | switch (strtolower($name)) { 28 | case 'content-type': 29 | $this->assertEquals('text/plain', $value); 30 | break; 31 | case 'content-length': 32 | $this->assertEquals(10, $value); 33 | break; 34 | default: 35 | throw new Exception('Invalid name: ' . $name); 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * @expectedException Requests_Exception 42 | */ 43 | public function testInvalidKey() { 44 | $headers = new Requests_Response_Headers(); 45 | $headers[] = 'text/plain'; 46 | } 47 | 48 | public function testMultipleHeaders() { 49 | $headers = new Requests_Response_Headers(); 50 | $headers['Accept'] = 'text/html;q=1.0'; 51 | $headers['Accept'] = '*/*;q=0.1'; 52 | 53 | $this->assertEquals('text/html;q=1.0,*/*;q=0.1', $headers['Accept']); 54 | } 55 | } -------------------------------------------------------------------------------- /Requests-1.6.0/tests/SSL.php: -------------------------------------------------------------------------------- 1 | assertTrue(Requests_SSL::match_domain($base, $dnsname)); 39 | } 40 | 41 | /** 42 | * @dataProvider domainNoMatchProvider 43 | */ 44 | public function testNoMatch($base, $dnsname) { 45 | $this->assertFalse(Requests_SSL::match_domain($base, $dnsname)); 46 | } 47 | 48 | protected function fakeCertificate($dnsname, $with_san = true) { 49 | $certificate = array( 50 | 'subject' => array( 51 | 'CN' => $dnsname 52 | ), 53 | ); 54 | 55 | if ($with_san !== false) { 56 | // If SAN is set to true, default it to the dNSName 57 | if ($with_san === true) { 58 | $with_san = $dnsname; 59 | } 60 | $certificate['extensions'] = array( 61 | 'subjectAltName' => 'DNS: ' . $with_san, 62 | ); 63 | } 64 | 65 | return $certificate; 66 | } 67 | 68 | /** 69 | * @dataProvider domainMatchProvider 70 | */ 71 | public function testMatchViaCertificate($base, $dnsname) { 72 | $certificate = $this->fakeCertificate($dnsname); 73 | $this->assertTrue(Requests_SSL::verify_certificate($base, $certificate)); 74 | } 75 | 76 | /** 77 | * @dataProvider domainNoMatchProvider 78 | */ 79 | public function testNoMatchViaCertificate($base, $dnsname) { 80 | $certificate = $this->fakeCertificate($dnsname); 81 | $this->assertFalse(Requests_SSL::verify_certificate($base, $certificate)); 82 | } 83 | 84 | public function testCNFallback() { 85 | $certificate = $this->fakeCertificate('example.com', false); 86 | $this->assertTrue(Requests_SSL::verify_certificate('example.com', $certificate)); 87 | } 88 | 89 | public function testInvalidCNFallback() { 90 | $certificate = $this->fakeCertificate('example.com', false); 91 | $this->assertFalse(Requests_SSL::verify_certificate('example.net', $certificate)); 92 | } 93 | 94 | /** 95 | * Test a certificate with both CN and SAN fields 96 | * 97 | * As per RFC2818, if the SAN field exists, we should parse that and ignore 98 | * the value of the CN field. 99 | * 100 | * @link http://tools.ietf.org/html/rfc2818#section-3.1 101 | */ 102 | public function testIgnoreCNWithSAN() { 103 | $certificate = $this->fakeCertificate('example.net', 'example.com'); 104 | 105 | $this->assertTrue(Requests_SSL::verify_certificate('example.com', $certificate), 'Checking SAN validation'); 106 | $this->assertFalse(Requests_SSL::verify_certificate('example.net', $certificate), 'Checking CN non-validation'); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Session.php: -------------------------------------------------------------------------------- 1 | 'testing', 7 | 'X-TestHeader2' => 'requests-test' 8 | ); 9 | $data = array( 10 | 'testdata' => 'value1', 11 | 'test2' => 'value2', 12 | 'test3' => array( 13 | 'foo' => 'bar', 14 | 'abc' => 'xyz' 15 | ) 16 | ); 17 | $options = array( 18 | 'testoption' => 'test', 19 | 'foo' => 'bar' 20 | ); 21 | 22 | $session = new Requests_Session('http://example.com/', $headers, $data, $options); 23 | $this->assertEquals('http://example.com/', $session->url); 24 | $this->assertEquals($headers, $session->headers); 25 | $this->assertEquals($data, $session->data); 26 | $this->assertEquals($options['testoption'], $session->options['testoption']); 27 | 28 | // Test via property access 29 | $this->assertEquals($options['testoption'], $session->testoption); 30 | 31 | // Test setting new property 32 | $session->newoption = 'foobar'; 33 | $options['newoption'] = 'foobar'; 34 | $this->assertEquals($options['newoption'], $session->options['newoption']); 35 | 36 | // Test unsetting property 37 | unset($session->newoption); 38 | $this->assertFalse(isset($session->newoption)); 39 | 40 | // Update property 41 | $session->testoption = 'foobar'; 42 | $options['testoption'] = 'foobar'; 43 | $this->assertEquals($options['testoption'], $session->testoption); 44 | 45 | // Test getting invalid property 46 | $this->assertNull($session->invalidoption); 47 | } 48 | 49 | public function testURLResolution() { 50 | $session = new Requests_Session('http://httpbin.org/'); 51 | 52 | // Set the cookies up 53 | $response = $session->get('/get'); 54 | $this->assertTrue($response->success); 55 | $this->assertEquals('http://httpbin.org/get', $response->url); 56 | 57 | $data = json_decode($response->body, true); 58 | $this->assertNotNull($data); 59 | $this->assertArrayHasKey('url', $data); 60 | $this->assertEquals('http://httpbin.org/get', $data['url']); 61 | } 62 | 63 | public function testSharedCookies() { 64 | $session = new Requests_Session('http://httpbin.org/'); 65 | 66 | $options = array( 67 | 'follow_redirects' => false 68 | ); 69 | $response = $session->get('/cookies/set?requests-testcookie=testvalue', array(), $options); 70 | $this->assertEquals(302, $response->status_code); 71 | 72 | // Check the cookies 73 | $response = $session->get('/cookies'); 74 | $this->assertTrue($response->success); 75 | 76 | // Check the response 77 | $data = json_decode($response->body, true); 78 | $this->assertNotNull($data); 79 | $this->assertArrayHasKey('cookies', $data); 80 | 81 | $cookies = array( 82 | 'requests-testcookie' => 'testvalue' 83 | ); 84 | $this->assertEquals($cookies, $data['cookies']); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Requests-1.6.0/tests/Transport/cURL.php: -------------------------------------------------------------------------------- 1 | skip_https = true; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Requests-1.6.0/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | '100 Continue', 28 | 101 => '101 Switching Protocols', 29 | 200 => '200 OK', 30 | 201 => '201 Created', 31 | 202 => '202 Accepted', 32 | 203 => '203 Non-Authoritative Information', 33 | 204 => '204 No Content', 34 | 205 => '205 Reset Content', 35 | 206 => '206 Partial Content', 36 | 300 => '300 Multiple Choices', 37 | 301 => '301 Moved Permanently', 38 | 302 => '302 Found', 39 | 303 => '303 See Other', 40 | 304 => '304 Not Modified', 41 | 305 => '305 Use Proxy', 42 | 306 => '306 (Unused)', 43 | 307 => '307 Temporary Redirect', 44 | 400 => '400 Bad Request', 45 | 401 => '401 Unauthorized', 46 | 402 => '402 Payment Required', 47 | 403 => '403 Forbidden', 48 | 404 => '404 Not Found', 49 | 405 => '405 Method Not Allowed', 50 | 406 => '406 Not Acceptable', 51 | 407 => '407 Proxy Authentication Required', 52 | 408 => '408 Request Timeout', 53 | 409 => '409 Conflict', 54 | 410 => '410 Gone', 55 | 411 => '411 Length Required', 56 | 412 => '412 Precondition Failed', 57 | 413 => '413 Request Entity Too Large', 58 | 414 => '414 Request-URI Too Long', 59 | 415 => '415 Unsupported Media Type', 60 | 416 => '416 Requested Range Not Satisfiable', 61 | 417 => '417 Expectation Failed', 62 | 500 => '500 Internal Server Error', 63 | 501 => '501 Not Implemented', 64 | 502 => '502 Bad Gateway', 65 | 503 => '503 Service Unavailable', 66 | 504 => '504 Gateway Timeout', 67 | 505 => '505 HTTP Version Not Supported', 68 | ); 69 | 70 | public function request($url, $headers = array(), $data = array(), $options = array()) { 71 | $status = self::$messages[$this->code]; 72 | $response = "HTTP/1.0 $status\r\n"; 73 | $response .= "Content-Type: text/plain\r\n"; 74 | if ($this->chunked) { 75 | $response .= "Transfer-Encoding: chunked\r\n"; 76 | } 77 | $response .= $this->raw_headers; 78 | $response .= "Connection: close\r\n\r\n"; 79 | $response .= $this->body; 80 | return $response; 81 | } 82 | 83 | public function request_multiple($requests, $options) { 84 | $responses = array(); 85 | foreach ($requests as $id => $request) { 86 | $handler = new MockTransport(); 87 | $handler->code = $request['options']['mock.code']; 88 | $handler->chunked = $request['options']['mock.chunked']; 89 | $handler->body = $request['options']['mock.body']; 90 | $handler->raw_headers = $request['options']['mock.raw_headers']; 91 | $responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']); 92 | 93 | if (!empty($options['mock.parse'])) { 94 | $request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request)); 95 | $request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id)); 96 | } 97 | } 98 | 99 | return $responses; 100 | } 101 | 102 | public static function test() { 103 | return true; 104 | } 105 | } 106 | 107 | class RawTransport implements Requests_Transport { 108 | public $data = ''; 109 | public function request($url, $headers = array(), $data = array(), $options = array()) { 110 | return $this->data; 111 | } 112 | public function request_multiple($requests, $options) { 113 | foreach ($requests as $id => &$request) { 114 | $handler = new RawTransport(); 115 | $handler->data = $request['options']['raw.data']; 116 | $request = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']); 117 | } 118 | 119 | return $requests; 120 | } 121 | public static function test() { 122 | return true; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Requests-1.6.0/tests/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Auth 6 | 7 | 8 | Transport 9 | 10 | 11 | ChunkedEncoding.php 12 | Cookies.php 13 | IDNAEncoder.php 14 | IRI.php 15 | Requests.php 16 | Response/Headers.php 17 | SSL.php 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | . 30 | 31 | 32 | ../library 33 | 34 | 35 | -------------------------------------------------------------------------------- /themes/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | getMessage() . "\r\n" ); 39 | } 40 | $svn_last_revision = (int) $matches[1]; 41 | echo "Most recent SVN revision: " . $svn_last_revision . "\r\n"; 42 | if ( file_exists( $directory . '/.last-revision' ) ) { 43 | $last_revision = (int) file_get_contents( $directory . '/.last-revision' ); 44 | echo "Last synced revision: " . $last_revision . "\r\n"; 45 | } else { 46 | $last_revision = false; 47 | echo "You have not yet performed a successful sync. Settle in. This will take a while.\r\n"; 48 | } 49 | 50 | $start_time = time(); 51 | 52 | if ( $last_revision != $svn_last_revision ) { 53 | if ( $last_revision ) { 54 | $changelog_url = sprintf( 'https://themes.trac.wordpress.org/log/?verbose=on&mode=follow_copy&format=changelog&rev=%d&limit=%d', $svn_last_revision, $svn_last_revision - $last_revision ); 55 | $changes = file_get_contents( $changelog_url ); 56 | preg_match_all( '#^' . "\t" . '*\* ([^/A-Z ]+)[ /].* \((added|modified|deleted|moved|copied)\)' . "\n" . '#m', $changes, $matches ); 57 | $plugins = array_unique( $matches[1] ); 58 | } else { 59 | $themes = file_get_contents( 'https://themes.svn.wordpress.org/' ); 60 | preg_match_all( '#

  • ([^/]+)/
  • #', $themes, $matches ); 61 | $themes = $matches[1]; 62 | } 63 | 64 | foreach ( $themes as $theme ) { 65 | $theme = urldecode( $theme ); 66 | echo "Updating " . $theme . "\n"; 67 | 68 | $output = null; $return = null; 69 | 70 | $args = ( array( 71 | 'slug' => $theme , 72 | 'fields' => array('sections' => false, 'tags' => false) 73 | ) ); 74 | $action = 'theme_information'; 75 | $data = array( 76 | 'action' => $action, 77 | 'request' => serialize( (object) $args ) 78 | ); 79 | $r = Requests::post( 'https://api.wordpress.org/themes/info/1.0/', array(), (object) $data ); 80 | $response = unserialize( $r->body ); 81 | if (false === $response ){ 82 | echo 'Unable to fetch ' . $theme . "\n"; 83 | continue; 84 | } 85 | 86 | exec( 'wget -q -np -O ' . escapeshellarg( sprintf($download, $theme) ) . ' ' . escapeshellarg( $response->download_link ) . ' > /dev/null', $output, $return ); 87 | 88 | if ( $return === 0 && file_exists( sprintf($download, $theme) ) ) { 89 | if ($type === 'all') { 90 | if ( file_exists( 'themes/' . $theme ) ) 91 | exec( 'rm -rf ' . escapeshellarg( 'themes/' . $theme ) ); 92 | 93 | exec( 'unzip -o -d themes ' . escapeshellarg( 'zips/' . $theme . '.zip' ) ); 94 | exec( 'rm -rf ' . escapeshellarg( 'zips/' . $theme . '.zip' ) ); 95 | } 96 | $success[] = $theme; 97 | } else { 98 | echo '... download failed.'; 99 | } 100 | echo "\r\n"; 101 | } 102 | 103 | if ( file_put_contents( $directory . '/.last-revision', $svn_last_revision ) ) 104 | echo "[CLEANUP] Updated $directory/.last-revision to " . $svn_last_revision . "\r\n"; 105 | else 106 | echo "[ERROR] Could not update $directory/.last-revision to " . $svn_last_revision . "\r\n"; 107 | } 108 | 109 | $end_time = time(); 110 | $minutes = ( $end_time - $start_time ) / 60; 111 | $seconds = ( $end_time - $start_time ) % 60; 112 | 113 | echo "[SUCCESS] Done updating Themes!\r\n"; 114 | echo "It took " . number_format( $minutes ) . " minute" . ( $minutes == 1 ? '' : 's' ) . " and " . $seconds . " second" . ( $seconds == 1 ? '' : 's' ) . " to update ". count( $success ) ." theme" . ( count( $success ) == 1 ? '' : 's') . "\r\n"; 115 | echo "[DONE]\r\n"; 116 | -------------------------------------------------------------------------------- /zips/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore --------------------------------------------------------------------------------