2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/http-stream-wrapper.h"
19 #include "hphp/runtime/base/comparisons.h"
20 #include "hphp/runtime/base/ini-setting.h"
21 #include "hphp/runtime/base/runtime-option.h"
22 #include "hphp/runtime/base/string-util.h"
23 #include "hphp/runtime/base/thread-info.h"
24 #include "hphp/runtime/base/url-file.h"
25 #include "hphp/runtime/ext/stream/ext_stream.h"
26 #include "hphp/runtime/ext/url/ext_url.h"
27 #include "hphp/runtime/server/cli-server.h"
31 ///////////////////////////////////////////////////////////////////////////////
38 s_ignore_errors("ignore_errors"),
39 s_max_redirects("max_redirects"),
43 s_user_agent("user_agent"),
44 s_User_Agent("User-Agent");
46 req::ptr
<File
> HttpStreamWrapper::open(const String
& filename
,
47 const String
& mode
, int /*options*/,
48 const req::ptr
<StreamContext
>& context
) {
49 if (RuntimeOption::ServerHttpSafeMode
&& !is_cli_mode()) {
53 if (strncmp(filename
.data(), "http://", sizeof("http://") - 1) &&
54 strncmp(filename
.data(), "https://", sizeof("https://") - 1)) {
59 String method
= s_GET
;
60 String post_data
= null_string
;
67 bool ignore_errors
= false;
69 if (context
&& !context
->getOptions().isNull() &&
70 !context
->getOptions()[s_http
].isNull()) {
71 Array opts
= context
->getOptions()[s_http
].toArray();
72 if (opts
.exists(s_method
)) {
73 method
= opts
[s_method
].toString();
75 if (opts
.exists(s_header
)) {
77 if (opts
[s_header
].isString()) {
78 lines
= StringUtil::Explode(
79 opts
[s_header
].toString(), "\r\n").toArray();
80 } else if (opts
[s_header
].isArray()) {
81 lines
= opts
[s_header
];
84 for (ArrayIter
it(lines
); it
; ++it
) {
85 Array parts
= StringUtil::Explode(
86 it
.second().toString(), ":", 2).toArray();
87 headers
.set(parts
.rvalAt(0).unboxed().tv(), parts
.rvalAt(1).tv());
90 if (opts
.exists(s_user_agent
) && !headers
.exists(s_User_Agent
)) {
91 headers
.set(s_User_Agent
, opts
[s_user_agent
]);
93 if (opts
.exists(s_max_redirects
)) {
94 max_redirs
= opts
[s_max_redirects
].toInt64();
96 if (opts
.exists(s_timeout
)) {
97 timeout
= opts
[s_timeout
].toInt64();
99 if (opts
.exists(s_ignore_errors
)) {
100 ignore_errors
= opts
[s_ignore_errors
].toBoolean();
102 if (opts
.exists(s_proxy
)) {
103 Variant host
= f_parse_url(opts
[s_proxy
].toString(), k_PHP_URL_HOST
);
104 Variant port
= f_parse_url(opts
[s_proxy
].toString(), k_PHP_URL_PORT
);
105 if (!same(host
, false) && !same(port
, false)) {
106 proxy_host
= host
.toString();
107 proxy_port
= port
.toInt64();
108 Variant user
= f_parse_url(opts
[s_proxy
].toString(), k_PHP_URL_USER
);
109 Variant pass
= f_parse_url(opts
[s_proxy
].toString(), k_PHP_URL_PASS
);
110 if (!same(user
, false) && !same(pass
, false)) {
111 proxy_user
= user
.toString();
112 proxy_pass
= pass
.toString();
116 post_data
= opts
[s_content
].toString();
119 if (!headers
.exists(s_User_Agent
)) {
120 auto default_user_agent
= ThreadInfo::s_threadInfo
.getNoCheck()
121 ->m_reqInjectionData
.getUserAgent();
122 if (!default_user_agent
.empty()) {
123 headers
.set(s_User_Agent
, default_user_agent
);
126 auto file
= req::make
<UrlFile
>(method
.data(), headers
,
127 post_data
, max_redirs
,
128 timeout
, ignore_errors
);
129 file
->setStreamContext(context
);
130 file
->setProxy(proxy_host
, proxy_port
, proxy_user
, proxy_pass
);
131 bool ret
= file
->open(filename
, mode
);
133 raise_warning("Failed to open %s (%s)", filename
.data(),
134 file
->getLastError().c_str());
140 ///////////////////////////////////////////////////////////////////////////////