Example #1
0
 /**
  * Fetches the content and returns it as-is using the headers as returned
  * by the remote host.
  *
  * @param string $url the url to retrieve
  */
 public function fetch($url)
 {
     // TODO: Check to see if we can just use MakeRequestOptions::fromCurrentRequest
     $st = isset($_GET['st']) ? $_GET['st'] : (isset($_POST['st']) ? $_POST['st'] : false);
     $body = isset($_GET['postData']) ? $_GET['postData'] : (isset($_POST['postData']) ? $_POST['postData'] : false);
     $authz = isset($_GET['authz']) ? $_GET['authz'] : (isset($_POST['authz']) ? $_POST['authz'] : null);
     $headers = isset($_GET['headers']) ? $_GET['headers'] : (isset($_POST['headers']) ? $_POST['headers'] : null);
     $params = new MakeRequestOptions($url);
     $params->setSecurityTokenString($st)->setAuthz($authz)->setRequestBody($body)->setHttpMethod('GET')->setFormEncodedRequestHeaders($headers)->setNoCache($this->context->getIgnoreCache());
     $result = $this->makeRequest->fetch($this->context, $params);
     $httpCode = (int) $result->getHttpCode();
     $cleanedResponseHeaders = $this->makeRequest->cleanResponseHeaders($result->getResponseHeaders());
     $isShockwaveFlash = false;
     foreach ($cleanedResponseHeaders as $key => $val) {
         header("{$key}: {$val}", true);
         if (strtoupper($key) == 'CONTENT-TYPE' && strtolower($val) == 'application/x-shockwave-flash') {
             // We're skipping the content disposition header for flash due to an issue with Flash player 10
             // This does make some sites a higher value phishing target, but this can be mitigated by
             // additional referer checks.
             $isShockwaveFlash = true;
         }
     }
     if (!$isShockwaveFlash && !Config::get('debug')) {
         header('Content-Disposition: attachment;filename=p.txt');
     }
     $lastModified = $result->getResponseHeader('Last-Modified') != null ? $result->getResponseHeader('Last-Modified') : gmdate('D, d M Y H:i:s', $result->getCreated()) . ' GMT';
     $notModified = false;
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $lastModified && !isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
         $if_modified_since = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
         // Use the request's Last-Modified, otherwise fall back on our internal time keeping (the time the request was created)
         $lastModified = strtotime($lastModified);
         if ($lastModified <= $if_modified_since) {
             $notModified = true;
         }
     }
     if ($httpCode == 200) {
         // only set caching headers if the result was 'OK'
         $this->setCachingHeaders($lastModified);
         // was the &gadget=<gadget url> specified in the request? if so parse it and check the rewrite settings
         if (isset($_GET['gadget'])) {
             $this->rewriteContent($_GET['gadget'], $result);
         }
     }
     // If the cached file time is within the refreshInterval params value, return not-modified
     if ($notModified) {
         header('HTTP/1.0 304 Not Modified', true);
         header('Content-Length: 0', true);
     } else {
         header("HTTP/1.1 {$httpCode} " . $result->getHttpCodeMsg());
         // then echo the content
         echo $result->getResponseContent();
     }
 }
Example #2
0
 public function doGet()
 {
     try {
         $this->noHeaders = true;
         $context = new GadgetContext('GADGET');
         $makeRequestParams = MakeRequestOptions::fromCurrentRequest();
         $makeRequestHandler = new MakeRequestHandler($context);
         $makeRequestHandler->fetchJson($makeRequestParams);
     } catch (MakeRequestParameterException $e) {
         // Something was misconfigured in the request
         header("HTTP/1.0 400 Bad Request", true);
         echo "<html><body><h1>400 - Bad request</h1><p>" . $e->getMessage() . "</body></html>";
     } catch (Exception $e) {
         // catch all exceptions and give a 500 server error
         header("HTTP/1.0 500 Internal Server Error");
         echo "<html><body><h1>Internal server error</h1><p>" . $e->getMessage() . "</p></body></html>";
     }
 }
 /**
  * Processes an RPC request for http data.
  *
  * @param RequestItem $requestItem The request parameters.
  * @return array An array of content, status code, and headers from the
  *     response.  The expected structure is undocumented in the spec, sadly.
  *     TODO: Filter some/most headers from the response (waste of bandwidth).
  */
 public function handleItem(RequestItem $requestItem)
 {
     try {
         // We should only get RPC requests at this point.  There's a class cast
         // here from RequestItem->RpcRequestItem, but PHP doesn't seem to
         // complain.
         $options = MakeRequestOptions::fromRpcRequestItem($requestItem);
         $makeRequest = new MakeRequest();
         $context = new GadgetContext('GADGET');
         $response = $makeRequest->fetch($context, $options);
         $result = array('content' => $response->getResponseContent(), 'status' => $response->getHttpCode(), 'headers' => $response->getResponseHeaders());
     } catch (SocialSpiException $e) {
         $result = new ResponseItem($e->getCode(), $e->getMessage());
     } catch (Exception $e) {
         $result = new ResponseItem(ResponseError::$INTERNAL_ERROR, "Internal error: " . $e->getMessage());
     }
     return $result;
 }
 /**
  * Processes an RPC request for http data.
  *
  * @param RequestItem $requestItem The request parameters.
  * @return array An array of content, status code, and headers from the
  *     response.  The expected structure is undocumented in the spec, sadly.
  *     TODO: Filter some/most headers from the response (waste of bandwidth).
  */
 public function handleItem(RequestItem $requestItem)
 {
     try {
         // We should only get RPC requests at this point.  There's a class cast
         // here from RequestItem->RpcRequestItem, but PHP doesn't seem to
         // complain.
         $options = MakeRequestOptions::fromRpcRequestItem($requestItem);
         $makeRequestClass = Config::get('makerequest_class');
         $makeRequest = new $makeRequestClass();
         $contextClass = Config::get('gadget_context_class');
         $context = new $contextClass('GADGET');
         $response = $makeRequest->fetch($context, $options);
         // try to decode json object here since in order
         // to not break gadgets.io.makeRequest functionality
         // $response->getResponseContent() has to return a string
         $content = json_decode($response->getResponseContent(), true);
         $result = array('content' => $content ? $content : $response->getResponseContent(), 'status' => $response->getHttpCode(), 'headers' => $response->getResponseHeaders());
     } catch (SocialSpiException $e) {
         $result = new ResponseItem($e->getCode(), $e->getMessage());
     } catch (Exception $e) {
         $result = new ResponseItem(ResponseError::$INTERNAL_ERROR, "Internal error: " . $e->getMessage());
     }
     return $result;
 }
 /**
  * Builds a MakeRequestOptions object from a RequestItem instance.  This is
  * a helper for dealing with Handler services which need to call MakeRequest.
  * The parameter names were taken from the osapi.http spec documents, although
  * several parameters not in the spec are also supported to allow full
  * functionality.
  *
  * @param RpcRequestItem $request The RpcRequestItem to parse.  The reason
  *     RpcRequestItem is needed is because of the way getService() and
  *     getMethod() are overloaded in the RequestItem subclasses.  This
  *     function needs a reliable way to get the http method.
  * @return MakeRequestOptions An object initialized from the current request.
  * @throws MakeRequestParameterException If any of the parameters were
  *     invalid.
  */
 public static function fromRpcRequestItem(RpcRequestItem $request)
 {
     $href = $request->getParameter('href');
     if (!isset($href)) {
         $href = $request->getParameter('url');
     }
     $options = new MakeRequestOptions($href);
     $options->setHttpMethod($request->getMethod())->setRequestBody($request->getParameter('body'))->setRequestHeaders($request->getParameter('headers', array()))->setResponseFormat($request->getParameter('format'))->setAuthz($request->getParameter('authz'))->setSignViewer($request->getParameter('sign_viewer'))->setSignOwner($request->getParameter('sign_owner'))->setNumEntries($request->getParameter('numEntries'))->setGetSummaries($request->getParameter('getSummaries'))->setRefreshInterval($request->getParameter('refreshInterval'))->setNoCache($request->getParameter('nocache'))->setOAuthServiceName($request->getParameter('oauth_service_name'))->setOAuthTokenName($request->getParameter('oauth_token_name'))->setOAuthRequestToken($request->getParameter('oauth_request_token'))->setOAuthRequestTokenSecret($request->getParameter('oauth_request_token_secret'))->setOAuthUseToken($request->getParameter('oauth_use_token'))->setOAuthReceivedCallback($request->getParameter('oauth_received_callback'))->setOAuthClientState($request->getParameter('oauth_state'))->setSecurityTokenString($request->getToken()->toSerialForm());
     return $options;
 }
 /**
  * Builds a request to retrieve the actual content.
  *
  * @param GadgetContext $context The rendering context.
  * @param MakeRequestOptions $params Options for crafting the request.
  * @param SecurityTokenDecoder $signer A signer needed for signed requests.
  * @return RemoteContentRequest An initialized request object.
  */
 public function buildRequest(GadgetContext $context, MakeRequestOptions $params, SecurityTokenDecoder $signer = null)
 {
     // Check the protocol requested - curl doesn't really support file://
     // requests but the 'error' should be handled properly
     $protocolSplit = explode('://', $params->getHref(), 2);
     if (count($protocolSplit) < 2) {
         throw new Exception("Invalid protocol specified");
     }
     $protocol = strtoupper($protocolSplit[0]);
     if ($protocol != "HTTP" && $protocol != "HTTPS") {
         throw new Exception("Invalid protocol specified in url: " . htmlentities($protocol));
     }
     $method = $params->getHttpMethod();
     if ($method == 'POST' || $method == 'PUT') {
         // even if postData is an empty string, it will still post
         // (since RemoteContentRquest checks if its false)
         // so the request to POST is still honored
         $request = new RemoteContentRequest($params->getHref(), null, $params->getRequestBody());
     } else {
         if ($method == 'DELETE' || $method == 'GET' || $method == 'HEAD') {
             $request = new RemoteContentRequest($params->getHref());
         } else {
             throw new Exception("Invalid HTTP method.");
         }
     }
     $request->setMethod($method);
     if ($signer) {
         switch ($params->getAuthz()) {
             case 'SIGNED':
                 $request->setAuthType(RemoteContentRequest::$AUTH_SIGNED);
                 break;
             case 'OAUTH':
                 $request->setAuthType(RemoteContentRequest::$AUTH_OAUTH);
                 $request->setOAuthRequestParams($params->getOAuthRequestParameters());
                 break;
         }
         $st = $params->getSecurityTokenString();
         if ($st === false) {
             throw new Exception("A security token is required for signed requests");
         }
         $token = $context->validateToken($st, $signer);
         $request->setToken($token);
     }
     // Strip invalid request headers.  This limits the utility of the
     // MakeRequest class a little bit, but ensures that none of the invalid
     // headers are present in any request going through this class.
     $headers = $params->getRequestHeadersArray();
     if ($headers !== false) {
         $headers = $this->stripInvalidArrayKeys($headers, MakeRequest::$BAD_REQUEST_HEADERS);
         $params->setRequestHeaders($headers);
     }
     // The request expects headers to be stored as a normal header text blob.
     // ex: Content-Type: application/atom+xml
     //     Accept-Language: en-us
     $formattedHeaders = $params->getFormattedRequestHeaders();
     if ($formattedHeaders !== false) {
         $request->setHeaders($formattedHeaders);
     }
     return $request;
 }
 public function testResponseHeaders()
 {
     $params = new MakeRequestOptions('http://www.example.com');
     $params->setNoCache(true);
     $headers = array('Content-Type' => 'text/plain');
     $this->response->setResponseHeaders($headers);
     $this->fetcher->enqueueResponse($this->response);
     $result = $this->makeRequest->fetch($this->context, $params);
     $response_headers = $result->getResponseHeaders();
     $this->assertArrayHasKey('Content-Type', $response_headers);
     $this->assertEquals('text/plain', $response_headers['Content-Type']);
 }