0

編集:答えは、マークされた答えへのコメントにあります。

現在、モバイル Web サイトのいくつかの主要コンポーネントの更新に取り組んでいます。このサイトでは、別のサーバーからのデータを使用して生徒のスケジュールを表示しています。最近、この別のサイト (私はまったく制御できません) が大幅にオーバーホールされ、当然のことながら、モバイル Web サイトを更新する必要が生じました。

私がやろうとしているのは、iCal ファイルにアクセスして解析することです。私が取り組んでいるサイトは、curl-library も fopen ラッパーも適切にセットアップされていない環境で実行されているため、ここで説明する方法(番号 4、ソケットを直接使用) に頼っています。

私の現在の問題は、iCal ファイルを取得する代わりに 301 エラーが発生することです。ただし、Web ブラウザーで (同じ URL を介して) 同じファイルにアクセスしようとすると、問題なく動作します。

編集:私は少しのロギングを追加しました。これがその結果です:

------------- 
Querying url:      
https://someUrl/schema/ri654Q055ZQZ60QbQ0ygnQ70cWny067Z0109Zx4h0Z7o525Y407Q.ics  
Response:   
HTTP/1.1 301 Moved Permanently  
Server: nginx/1.2.8  
Date: Sun, 11 Aug 2013 14:08:36 GMT  
Content-Type: text/html  
Content-Length: 184  
Connection: close  
Location:   
https://someUrl/schema/ri654Q055ZQZ60QbQ0ygnQ70cWny067Z0109Zx4h0Z7o525Y407Q.ics

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.2.8</center>
</body>
</html>

Redirect url found: https://someUrl/schema/ri654Q055ZQZ60QbQ0ygnQ70cWny067Z0109Zx4h0Z7o525Y407Q.ics

私が取得している新しい場所は、元の場所と同じです。

これは使用されるコードです:

function getRemoteFile($url)
{

    error_log("------------- \r\nQuerying url: " . $url, 3, "error_log.log");
  // get the host name and url path
  $parsedUrl = parse_url($url);
  $host = $parsedUrl['host']; 
  if (isset($parsedUrl['path'])) {
     $path = $parsedUrl['path'];
  } else {
     // the url is pointing to the host like http://www.mysite.com
     $path = '/';
  }
  if (isset($parsedUrl['query'])) {
     $path .= '?' . $parsedUrl['query'];
  } 

  if (isset($parsedUrl['port'])) {
     $port = $parsedUrl['port'];
  } else {
     // most sites use port 80
     // but we want port 443 because we are using https
     error_log("Using port 443\r\n" . $url, 3, "error_log.log");
     $port = 443;
  }
  $timeout = 10;
  $response = '';
  // connect to the remote server 
  $fp = fsockopen($host, $port, $errno, $errstr, $timeout );
  if( !$fp ) { 
     echo "Cannot retrieve $url";
  } else {
    $payload = "GET $path HTTP/1.0\r\n" .
                "Host: $host\r\n" .
                "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3\r\n" .
                "Accept: */*\r\n" .
                "Accept-Language: sv-SE,sv;q=0.8,en-us,en;q=0.3\r\n" .
                "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" .
                "Referer: https://$host\r\n\r\n";
    error_log("\nPAYLOAD: " . $payload, 3, "error_log.log");
     // send the necessary headers to get the file 
     fputs($fp, $payload);
     // retrieve the response from the remote server 
     while ( $line = stream_socket_recvfrom( $fp, 4096 ) ) {
        $response .= $line;
     }
     fclose( $fp );
     // naively find location redirect
     $location_pos = strpos($response, "Location:");
     if($location_pos){
        $location_pos += 10;
        $new_url = substr($response, $location_pos, strpos($response, "\r\n\r\n") - $location_pos);
        error_log("\nRedirect url found: " . $new_url, 3, "error_log.log");
     }else{
        //log the response
        error_log($response, 3, "error_log.log");
     }


     // strip the headers
     $pos      = strpos($response, "\r\n\r\n");
     $response = substr($response, $pos + 4);
  }
  // return the file content 
  return $response;
}
4

1 に答える 1

0

HTTP 応答コード 301は永続的なリダイレクトであり、エラーではありません。

リソースにアクセスするには、コードがそのリダイレクトに従う必要があります。

たとえば、 http: //google.com/は 301 を返し、代わりにユーザーをhttp://www.google.com/にリダイレクトします。

$ curl -I http://google.com/
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sun, 11 Aug 2013 01:25:34 GMT
Expires: Tue, 10 Sep 2013 01:25:34 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Alternate-Protocol: 80:quic

2 行目に 301 応答があり、その後に Location ヘッダーが続き、Web ブラウザーに移動先を伝えます。

おそらく起こったことは、この大規模なオーバーホール中に、リソースを別の場所に移動したことです。ユーザーのブックマークやカレンダーを壊さないようにするために、301 リダイレクトを使用して、クライアントが新しい場所からリソースを自動的にフェッチするようにしました。

于 2013-08-11T01:23:10.733 に答える