/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) | | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.zend.com/license/2_00.txt. | | If you did not receive a copy of the Zend license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ */ #include "hphp/runtime/base/url_file.h" #include "hphp/runtime/base/hphp_system.h" #include "hphp/runtime/base/http_client.h" #include "hphp/runtime/base/runtime_error.h" namespace HPHP { IMPLEMENT_OBJECT_ALLOCATION(UrlFile) /////////////////////////////////////////////////////////////////////////////// StaticString UrlFile::s_class_name("UrlFile"); /////////////////////////////////////////////////////////////////////////////// UrlFile::UrlFile(const char *method /* = "GET" */, CArrRef headers /* = null_array */, CStrRef postData /* = null_string */, int maxRedirect /* = 20 */, int timeout /* = -1 */) { m_get = (method == nullptr || strcasecmp(method, "GET") == 0); m_headers = headers; m_postData = postData; m_maxRedirect = maxRedirect; m_timeout = timeout; } bool UrlFile::open(CStrRef url, CStrRef mode) { const char* modestr = mode.c_str(); if (strchr(modestr, '+') || strchr(modestr, 'a') || strchr(modestr, 'w')) { std::string msg = "cannot open a url stream for write/append operation: "; msg += url.c_str(); m_error = msg; return false; } HttpClient http(m_timeout, m_maxRedirect); m_response.reset(); HeaderMap *pHeaders = nullptr; HeaderMap requestHeaders; if (!m_headers.empty()) { pHeaders = &requestHeaders; for (ArrayIter iter(m_headers); iter; ++iter) { requestHeaders[string(iter.first().toString().data())]. push_back(iter.second().toString().data()); } } int code; vector responseHeaders; if (m_get) { code = http.get(url.c_str(), m_response, pHeaders, &responseHeaders); } else { code = http.post(url.c_str(), m_postData.data(), m_postData.size(), m_response, pHeaders, &responseHeaders); } static const StaticString s_http_response_header("http_response_header"); GlobalVariables *g = get_global_variables(); Variant &r = g->getRef(s_http_response_header); r = Array::Create(); for (unsigned int i = 0; i < responseHeaders.size(); i++) { r.append(responseHeaders[i]); } m_responseHeaders = r; if (code == 200) { m_name = (std::string) url; m_data = const_cast(m_response.data()); m_len = m_response.size(); return true; } else { m_error = http.getLastError().c_str(); return false; } } int64_t UrlFile::writeImpl(const char *buffer, int64_t length) { assert(m_len != -1); throw FatalErrorException((string("cannot write a url stream: ") + m_name).c_str()); } bool UrlFile::flush() { assert(m_len != -1); throw FatalErrorException((string("cannot flush a url stream: ") + m_name).c_str()); } String UrlFile::getLastError() { return m_error; } /////////////////////////////////////////////////////////////////////////////// }