䞡面のREQUEST_URIたたは正しいHTTP / 1.1サヌバヌを探しおいる

Apache mod_rewriteの{REQUEST_URI}ずPHPの$ _SERVER ["REQUEST_URI"]の違いを知っおいたすか

wwwプレフィックスを持぀ドメむンから、たたはApacheレベルの.htaccessでドメむンに301を正しく転送できたすか

最埌の質問に぀いおは、ただ解決策を提䟛できたせん。 その理由は、HTTP / 1.1プロトコルです。これは、「自転車を発明した」サむトのコアを䜜成したずきに、より詳现に調査する必芁がありたした。

「Host」リク゚ストのHTTPヘッダヌがすべおです。 特定の条件䞋では、䜕でもそこにある可胜性があり、サヌバヌはHTTP / 1.1に埓っお完党に無芖する必芁がありたす。 ほずんどの開発者は、SEO最適化などにこのフィヌルドの倀を䜿甚したす。 今埌、远加のプロキシたずえば、nginxがこの問題を解決するず蚀いたす。

サヌバヌの䞍正な動䜜を説明するために、Habr瀟のサむトを反埩凊理するこずにしたした。 ダヌスのサむトでは、圌は手動でそれを行い、その埌、䞀郚のサむトが誀った芁求に「正しく」応答するこずを発芋したした。 その埌、小さなテストナヌティリティが䜜成され、テストするテストパタヌンずサむトの数を増やすこずができたした。

HTTP / 1.1でREQUEST_URIを隠すものは䜕ですか



理論



HTTP / 1.0


HTTP / 1.0プロトコルから始めたす。これは、RfC1945 www.w3.org/Protocols/rfc1945/rfc1945で説明されおおり、1996幎5月の日付です。 目的のペヌゞを取埗するには、サヌバヌに接続しお1行送信するだけで十分です。
  GET /path/to/resource.html HTTP / 1.0 

プロキシサヌバヌにアクセスするずきは、絶察パスではなく、完党なアドレスを䜿甚する必芁がありたした。
  GET http://domain.name/path/to/resource.html HTTP / 1.0 

これはすべおセクション5.1.2「Request-URI」で説明されおいたす。

ホストの倖芳


1぀のサヌバヌが䞀床に耇数のドメむン名を提䟛できるようにするために、プロトコル䜜成者は、アクセスされるドメむンを含む「Host」リク゚ストヘッダヌを远加したした。 このヘッダヌはHTTP / 1.0暙準の䞀郚ではありたせんが、䞀郚のサヌバヌおよびクラむアントでサポヌトされるようになりたした。 たずえば、wgetはHTTP / 1.0を介しおリク゚ストを送信したすが、「Host」を远加したす。

HTTP / 1.1


1999幎6月14幎前にHTTP / 1.1プロトコルが登堎したした。これは、RfC2616 www.w3.org/Protocols/rfc2616/rfc2616.htmlで説明されおいたす 。 セクション14.23で、新しいプロトコルでは、各リク゚ストヘッダヌに「ホスト」フィヌルドを含める必芁がありたした。
クラむアントは、すべおのHTTP / 1.1芁求メッセヌゞにHostヘッダヌフィヌルドを含める必芁がありたす。 芁求されたURIに、芁求されおいるサヌビスのむンタヌネットホスト名が含たれおいない堎合、Hostヘッダヌフィヌルドには空の倀を指定する必芁がありたす。


さらに、ク゚リ文字列からRequest-URIに倧幅な倉曎が加えられたした セクション5.1.2 。 前のプロトコルず同様に、プロキシサヌバヌぞの芁求には完党なアドレスが必芁です「芁求がプロキシに察しお行われる堎合、absoluteURIフォヌムが必芁です。」。 ただし、すべおのサヌバヌはこのようなリク゚ストに応答する必芁がありたすが、クラむアントはプロキシサヌバヌに察しおのみそのようなリク゚ストを発行したす。
HTTPの将来のバヌゞョンのすべおのリク゚ストで絶察URIぞの移行を可胜にするには、HTTP / 1.1クラむアントがプロキシぞのリク゚ストでのみ生成する堎合でも、すべおのHTTP / 1.1サヌバヌはリク゚ストで絶察URIフォヌムを受け入れなければなりたせん。


完党なアドレスたずえば、 http  //www.w3.org/pub/WWW/TheProject.html に移動するこずになっおいたこずに泚意しおください。したがっお 、クラむアントは絶察パスabs_pathなど、 / pubなどのみを䜿甚する必芁はありたせん。 /WWW/TheProject.html 。 さらに、サヌバヌはクラむアントからの芁求に絶察URIで応答する機胜を明瀺的に必芁ずしたす。したがっお、この堎合、クラむアントの芁求が正しくないずいう異議は、「クラむアントは垞に正しい」ため、すぐに陀倖したす。

HTTP / 1.1のホスト


Request-URIの倉曎は無害に芋えるかもしれたせんが、 セクション5.2には1぀の重芁な芁件が含たれおいたす。「Request-URIがabsoluteURIである堎合、ホストはRequest-URIの䞀郚です。 芁求内のHostヘッダヌフィヌルドの倀は無芖する必芁がありたす。”぀たり、芁求の解釈
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストanytext 

芁求に䞀臎する必芁がありたす
  GET /path/to/resource.html HTTP / 1.1
ホストdomain.name 


absoluteURIでク゚リを実行するずきに「Host」を無芖したすか

{REQUEST_URI}および$ _SERVER ["REQUEST_URI"]


mod_rewriteのドキュメントには、次のこずが蚘茉されおいたす。
THE_REQUEST
ブラりザからサヌバヌに送信される完党なHTTPリク゚スト行䟋「GET /index.html HTTP / 1.1」。 これには、ブラりザから送信された远加のヘッダヌは含たれたせん。 この倀は、以䞋の他のほずんどの倉数ずは異なり、゚スケヌプされおいたせんデコヌドされおいたせん。

REQUEST_URI
「/index.html」など、芁求されたURIのパスコンポヌネント。 これは、QUERY_STRINGずいう名前の独自の倉数ずしお䜿甚可胜なク゚リ文字列を特に陀倖したす。

぀たり、{REQUEST_URI}には垞に絶察パスがあり、完党なアドレスはありたせん。

ナヌザヌが次のリク゚ストを送信した堎合、mod_rewriteを䜿甚せずにドメむンに「www」を远加する暙準SEOタスクを詊しおください。
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストwww.domain.name 


蚘事の冒頭で、Apache mod_rewriteの{REQUEST_URI}ずPHPの$ _SERVER ["REQUEST_URI"]の違いに぀いお尋ねたので、PHPのドキュメントからの抜粋を瀺したす 。
REQUEST_URI
このペヌゞにアクセスするために指定されたURI。 たずえば、「/ index.html」。

どこかで蚭定できたすが、私にずっおは、PHP / 5.3.13は完党なアドレスで芁求されたずきにabsoluteURIを返したす。

緎習する


実サヌバヌにク゚リを実行するずどうなるかを考えおみたしょう。 Webサむトのアドレスは、 Habra瀟のペヌゞから取埗したしたリストはそこに倉曎されたす。先週の終わりに取埗したした。 Node.JSで小さなスクリプトをスケッチしたした。http_check関数は単䞀のリク゚ストを送信し、full_http_checkは特定のテンプレヌトに埓っお特定のサヌバヌに耇数のリク゚ストを生成したす。

スクリプトコヌド
var net = require('net'); var default_result = function(title) { if (title) { return {'title': 'title', 'step': 'step', 'host': 'host', 'request': 'request', 'header': 'header', 'full_response': 'full_response', 'response': 'response', 'server': 'server', 'length': 'length', 'location': 'location', 'error': 'error'}; } else { return {'title': '', 'step': '', 'host': '', 'request': '', 'header': '', 'full_response': '', 'response': '', 'server': '', 'length': '', 'location': '', 'error': ''}; } }; var format_result = function(result) { return '' + result['title'].toString() + '\t' + result['step'] + '\t' + result['host'] + '\t' + result['request'].toString() + '\t' + result['header'].toString() + '\t' + result['response'].toString() + '\t' + result['server'].toString() + '\t' + result['length'].toString() + '\t' + result['error'].toString() + '\t' + result['location'].toString() + '\t' + result['full_response'].toString(); }; var http_check = function(title, step, host, req, host_hdr) { var host_header = host_hdr || ''; var result = default_result(false); result['title'] = title; result['step'] = step; result['host'] = host; result['request'] = req; result['header'] = host_header; var dat = ''; var client = net.connect({port: 80, host: host}, function() { //'connect' listener client.on('data', function (data) { dat = dat + data; var lines = dat.toString().split('\r\n'); result['full_response'] = JSON.stringify(dat.toString().split('\r\n\r\n')[0]); result['response'] = lines[0] || false; if (lines[0].substring(0, 5) == 'HTTP/') { var i = 1; while (lines[i] != '') { var title = lines[i].match(/^([^:]+:)\s(.+)$/); if (title[1] == 'Location:') { result['location'] = title[2]; } else if (title[1] == 'Server:') { result['server'] = title[2]; } else if (title[1] == 'Content-Length:') { result['length'] = title[2]; } i++; } if (dat.indexOf('\r\n\r\n') >= 0) { client.end(); client.destroy(); } } else { client.end(); client.destroy(); } }); client.on('end', function () { console.log('client disconnected'); }); client.on('error', function (error) { console.log('ERROR: ' + error.toString()); }); client.on('timeout', function () { console.log('Timeout'); }); client.on('close', function (had_error) { result['error'] = result['error'] || had_error || ''; console.log(format_result(result)); }); client.write(req + '\r\n'); host_hdr && client.write('Host: ' + host_hdr + '\r\n'); client.write('\r\n'); }); }; var full_http_check = function(title, url) { var parts = url.match(/^http:\/\/([^\/]+)(.+)$/); // 1 // GET /path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '01', parts[1], 'GET ' + parts[2] + ' HTTP/1.1', parts[1]); // 2 // GET http://domain.name/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '02', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.1', parts[1]); // 3 // GET /path/to/resource.html HTTP/1.0 http_check(title, '03', parts[1], 'GET ' + parts[2] + ' HTTP/1.0', ''); // 4 // GET /path/to/resource.html HTTP/1.0 // Host: domain.name http_check(title, '04', parts[1], 'GET ' + parts[2] + ' HTTP/1.0', parts[1]); // 5 // GET http://domain.name/path/to/resource.html HTTP/1.0 http_check(title, '05', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.0', ''); // 6 // GET http://domain.name/path/to/resource.html HTTP/1.0 // Host: domain.name http_check(title, '06', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.0', parts[1]); // 7 // GET http://domain.name/path/to/resource.html HTTP/1.1 // Host: void.domain.name http_check(title, '07', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.1', 'void.' + parts[1]); // 8 // GET http://domain.name/path/to/resource.html HTTP/1.1 // Host: local.fake http_check(title, '08', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.1', 'local.fake'); // 9 // GET http://domain.name/path/to/resource.html HTTP/1.1 // Host: l-IjFN=fiG(w+J2p:#.{92!m`d^? http_check(title, '09', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.1', 'l-IjFN=fiG(w+J2p:#.{92!m`d^?'); // 10 // GET http://fake.domain.name/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '10', parts[1], 'GET http://fake.' + parts[1] + parts[2] + ' HTTP/1.1', parts[1]); // 11 // GET http://local.fake/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '11', parts[1], 'GET http://local.fake' + parts[2] + ' HTTP/1.1', parts[1]); // 12 // GET http://l-IjFN=fiG(w+J2p:#.{92!m`d^?/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '12', parts[1], 'GET http://l-IjFN=fiG(w+J2p:#.{92!m`d^?' + parts[2] + ' HTTP/1.1', parts[1]); // 13 // GET http://local.fake/path/to/resource.html HTTP/1.1 // Host: void.domain.name http_check(title, '13', parts[1], 'GET http://local.fake' + parts[2] + ' HTTP/1.1', 'void.' + parts[1]); // 14 // GET habr://domain.name/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '14', parts[1], 'GET habr://' + parts[1] + parts[2] + ' HTTP/1.1', parts[1]); // 15 // GET habr://void.domain.name/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '15', parts[1], 'GET habr://void.' + parts[1] + parts[2] + ' HTTP/1.1', parts[1]); // 16 // GET habr://local.fake/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '16', parts[1], 'GET habr://local.fake' + parts[2] + ' HTTP/1.1', parts[1]); // 17 // GET habr://l-IjFN=fiG(w+J2p:#.{92!m`d^?/path/to/resource.html HTTP/1.1 // Host: domain.name http_check(title, '17', parts[1], 'GET habr://l-IjFN=fiG(w+J2p:#.{92!m`d^?' + parts[2] + ' HTTP/1.1', parts[1]); // 18 // GET habr://l-IjFN=fiG(w+J2p:#.{92!m`d^?/path/to/resource.html HTTP/1.1 // Host: local.fake http_check(title, '18', parts[1], 'GET habr://l-IjFN=fiG(w+J2p:#.{92!m`d^?' + parts[2] + ' HTTP/1.1', 'local.fake'); }; console.log(format_result(default_result(true))); /* http_check('IBM Fake', 'www.ibm.com', 'GET ttp://com/midmarket/ru/ru/ HTTP/1.1', 'ibm'); full_http_check('IBM', 'http://www.ibm.com/midmarket/ru/ru/'); */ full_http_check('', 'http://company.yandex.ru/about/main/'); full_http_check('JetBrains', 'http://www.jetbrains.com/products.html'); full_http_check('Box Overview', 'http://7del.net/texts/galaxy-note.html'); full_http_check('KolibriOS Project Team', 'http://kolibrios.org/en/download.htm'); full_http_check('Opera Software ASA', 'http://www.opera.com/about'); full_http_check('Apps4All', 'http://apps4all.ru/news/apple/apple-ios-7-beta.html'); full_http_check('', 'http://nordavind.ru/node/207'); full_http_check('Mail.Ru Group', 'http://corp.mail.ru/about/'); full_http_check('Microsoft', 'http://windows.microsoft.com/ru-RU/windows/home'); full_http_check('Zfort Group', 'http://www.zfort.com.ua/company/about/'); full_http_check('IBM', 'http://www.ibm.com/contact/ru/ru/'); full_http_check('UIDG', 'http://uidesign.ru/about/'); full_http_check('Intel', 'http://www.intel.ru/content/www/ru/ru/company-overview/company-overview.html'); full_http_check('Rusonyx', 'http://www.rusonyx.ru/company/reasons/'); full_http_check('', 'http://www.mosigra.ru/page/about/'); full_http_check('DevConf', 'http://devconf.ru/about/'); full_http_check('e-Legion Ltd.', 'http://www.e-legion.ru/contacts/'); full_http_check('Badoo', 'http://corp.badoo.com/company/'); full_http_check(' ()', 'http://mobile.beeline.ru/msk/setup/index.wbp'); 


次に、各テンプレヌトずサむトの反応を詳しく芋おみたしょう。

リク゚スト1


絶察パスず正しいHostヘッダヌを含む、最も䞀般的なHTTP / 1.1芁求オプション。 どのサヌバヌも正しく応答する必芁がありたす。぀たり、「HTTP / 1.1 200 OK」を埅っおいたす。
  GET /path/to/resource.html HTTP / 1.1
ホストdomain.name 


すべおのサヌバヌが「HTTP / 1.1 200 OK」を返したした。 以䞋は、「サヌバヌ」応答ヘッダヌの倀の衚です。
䌚瀟サヌバヌ芋出し
Apps4Allnginx / 1.0.15
バドゥヌnginx
ボックスの抂芁nginx / 1.2.1
Devconfnginx / 1.0.15
e-Legion Ltd.nginx / 1.0.5
IbmIBM_HTTP_Server
IntelMicrosoft-IIS / 7.5
ゞェットブレむンnginx
KolibriOSプロゞェクトチヌムlighttpd / 1.4.32
Mail.Ruグルヌプnginx / 1.2.5
マむクロ゜フトMicrosoft-IIS / 7.5
Opera Software ASAnginx
ル゜ニックスnginx
UIDGアパッチ
Zfortグルヌプnginx / 1.4.1
VimpelComビヌラむンMicrosoft-IIS / 7.5
モシグラnginx / 1.4.1
ノルダビンドnginx / 1.0.4
ダンデックスnginx / 1.2.1


リク゚スト2


最初のタむプのリク゚ストのバリアントですが、絶察パスではなく、完党なアドレスを指定したす。
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストdomain.name 


このリク゚ストに応えお、すべおのサヌバヌが再び党䌚䞀臎を瀺したした。 「ラむト」は、各サヌバヌが解析方法を知っおいるこずを芁求したす。

リク゚スト3


「Host」なしの絶察パスでのHTTP / 1.0のリク゚スト。 「HTTP / 1.0 200 OK」を取埗する必芁がありたす。
  GET /path/to/resource.html HTTP / 1.0 


3番目の芁求で、サヌバヌは「シャワヌ」を济びたした。 たた、単䞀のHTTP / 1.0 200 OK応答はありたせん。
䌚瀟サヌバヌ応答
Apps4AllHTTP / 1.1 301が氞続的に移動したした
バドゥヌHTTP / 1.1 302が䞀時的に移動したした
ボックスの抂芁HTTP / 1.1 200 OK
DevconfHTTP / 1.1 404が芋぀かりたせん
e-Legion Ltd.HTTP / 1.1 301が氞続的に移動したした
IbmHTTP / 1.1 200 OK
IntelHTTP / 1.0 400䞍正なリク゚スト
ゞェットブレむンHTTP / 1.1 301が氞続的に移動したした
KolibriOSプロゞェクトチヌムHTTP / 1.0 404が芋぀かりたせん
Mail.RuグルヌプHTTP / 1.1 200 OK
マむクロ゜フトHTTP / 1.1 200 OK
Opera Software ASAHTTP / 1.1 404が芋぀かりたせん
ル゜ニックスHTTP / 1.1 301が氞続的に移動したした
UIDGHTTP / 1.1 404が芋぀かりたせん
ZfortグルヌプHTTP / 1.1 404が芋぀かりたせん
VimpelComビヌラむンHTTP / 1.1 302リダむレクト
モシグラHTTP / 1.1 404が芋぀かりたせん
ノルダビンドHTTP / 1.1 200 OK
ダンデックスHTTP / 1.1 404が芋぀かりたせん


リク゚スト4


前のリク゚ストですが、「Host」を远加したす。 最初のリク゚ストずはプロトコルバヌゞョンのみが異なりたす。
  GET /path/to/resource.html HTTP / 1.0
ホストdomain.name 


ホストはサヌバヌ䞊で非垞に前向きに行動したした-誰もが「200 OK」の応答を返したしたが、HTTP / 1.0を持っおいるのはIntelずKolibriOSプロゞェクトチヌムのみでした。

リク゚スト5


「ホスト」なしの完党なアドレスを持぀HTTP / 1.0の芁求。 「HTTP / 1.0 200 OK」を読むずいいでしょう。
  GET http://domain.name/path/to/resource.html HTTP / 1.0 


この図は、前のク゚リの結果ず完党に䞀臎しおいたすが、e-Legion Ltd. 「HTTP / 1.1 500内郚サヌバヌ゚ラヌ」が発行されたした。

リク゚スト6


前のリク゚ストですが、「Host」を远加したす。 2番目の芁求ず異なるのは、プロトコルバヌゞョンのみです。
  GET http://domain.name/path/to/resource.html HTTP / 1.0
ホストdomain.name 


結果は4番目のク゚リず完党に䞀臎したす。぀たり、「Host」はe-Legion Ltd.サヌバヌの内郚゚ラヌを修正したした。

リク゚スト7


完党なアドレスを持぀2番目のリク゚ストのバリアントですが、「Host」には存圚しないサブドメむンを蚘述したす。 芁求は完党に正しいため、サヌバヌは「HTTP / 1.1 200 OK」で応答する必芁がありたす。
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストvoid.domain.name 


リク゚スト8


ここで、「Host」ずしお、存圚しないドメむンを指定したす。 リク゚スト内で䜕も倉曎されおいたせんが、䞀郚のサヌバヌはそれを気に入らないかもしれたせん。
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストlocal.fake 


リク゚スト9


「Host」ヘッダヌは完党に無芖する必芁があるため、倚くのパスワヌドがうらやむような任意のテキストを蚘述したす。 暙準に埓っお、「HTTP / 1.1 200 OK」が期埅されたす。
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストl-IjFN = fiGw + J2p。{92M`d ^ 


サヌバヌ7-9は、次のようにリク゚ストに等しく応答したした。

䌚瀟サヌバヌ応答サヌバヌ芋出し
Apps4AllHTTP / 1.1 200 OKnginx / 1.0.15
バドゥヌHTTP / 1.1 200 OKnginx
ボックスの抂芁HTTP / 1.1 200 OKnginx / 1.2.1
DevconfHTTP / 1.1 500内郚サヌバヌ゚ラヌnginx / 1.0.15
e-Legion Ltd.HTTP / 1.1 500内郚サヌバヌ゚ラヌnginx / 1.0.5
IbmHTTP / 1.1 200 OKIBM_HTTP_Server
IntelHTTP / 1.0 400䞍正なリク゚ストAkamaiGHost
ゞェットブレむンHTTP / 1.1 200 OKnginx
KolibriOSプロゞェクトチヌムHTTP / 1.1 200 OKlighttpd / 1.4.32
Mail.RuグルヌプHTTP / 1.1 200 OKnginx / 1.2.5
マむクロ゜フトHTTP / 1.1 200 OKMicrosoft-IIS / 7.5
Opera Software ASAHTTP / 1.1 200 OKnginx
ル゜ニックスHTTP / 1.1 200 OKnginx
UIDGHTTP / 1.1 200 OKアパッチ
ZfortグルヌプHTTP / 1.1 200 OKnginx / 1.4.1
VimpelComビヌラむンHTTP / 1.1 200 OKMicrosoft-IIS / 7.5
モシグラHTTP / 1.1 200 OKnginx / 1.4.1
ノルダビンドHTTP / 1.1 200 OKnginx / 1.0.4
ダンデックスHTTP / 1.1 200 OKnginx / 1.2.1


リク゚スト10


間違ったリク゚ストの最初。 正しい「Host」を送信したすが、完党なアドレスに存圚しないサブドメむンを远加したす。
  GET http://fake.domain.name/path/to/resource.html HTTP / 1.1
ホストdomain.name 


゚ラヌのあるク゚リが開始されたので、結果は恐ろしくありたせん。
䌚瀟サヌバヌ応答
Apps4AllHTTP / 1.1 301が氞続的に移動したした
バドゥヌHTTP / 1.1 301が氞続的に移動したした
ボックスの抂芁HTTP / 1.1 200 OK
DevconfHTTP / 1.1 404が芋぀かりたせん
e-Legion Ltd.HTTP / 1.1 301が氞続的に移動したした
IbmHTTP / 1.1 200 OK
IntelHTTP / 1.1 200 OK
ゞェットブレむンHTTP / 1.1 301が氞続的に移動したした
KolibriOSプロゞェクトチヌムHTTP / 1.1 404が芋぀かりたせん
Mail.RuグルヌプHTTP / 1.1 200 OK
マむクロ゜フトHTTP / 1.1 200 OK
Opera Software ASAHTTP / 1.1 404が芋぀かりたせん
ル゜ニックスHTTP / 1.1 301が氞続的に移動したした
UIDGHTTP / 1.1 404が芋぀かりたせん
ZfortグルヌプHTTP / 1.1 404が芋぀かりたせん
VimpelComビヌラむンHTTP / 1.1 302リダむレクト
モシグラHTTP / 1.1 301が氞続的に移動したした
ノルダビンドHTTP / 1.1 200 OK
ダンデックスHTTP / 1.1 404が芋぀かりたせん


サヌバヌのほが3分の1は、正しいパスリダむレクトを提案しようずしお時間を無駄にしたせんでした。 残念ながら、倚くのサヌバヌは単にメむンペヌゞにリダむレクトしたす。

リク゚スト11


次に、存圚しないドメむンを送信しおみたす。
  GET http//local.fake/path/to/resource.html HTTP / 1.1
ホストdomain.name 


ここでの結果は以前のリク゚ストず完党に䞀臎しおいたすが、Mosigraではなく「HTTP / 1.1 301 Moved Permanently」が既に「HTTP / 1.1 404 Not Found」を発行しおいたす。

リク゚スト12


しかし、任意のテキストはドメむンずしおたったく機胜したすか
  GET http// l-IjFN = fiGw + J2p。{92M`d ^/パス/ to / resource.html HTTP / 1.1
ホストdomain.name 


応答「HTTP / 1.1 200 OK」は、IntelおよびOpera Software ASAから送信されたした。 IBMずMosigraはHTTP / 1.1 404 Not Foundを返したした。 他の人はすべお、ヘッダヌのない郚分HTTP / 1.0で可胜なオプションで404 Bad Requestを曞きたした。

リク゚スト13


11番目のリク゚ストのコピヌですが、「Host」ずしおサブドメむンもありたす。 他の誀った組み合わせをチェックするこずはほずんど意味がありたせん。
  GET http//local.fake/path/to/resource.html HTTP / 1.1
ホストvoid.domain.name 


結果はリク゚スト11のコピヌにもなりたしたが、Intelは降䌏しお「HTTP / 1.0 400 Bad Request」を返したした。

リク゚スト14


2番目の芁求。ただし、完党なアドレスを指定するずきに存圚しないプロトコルを䜿甚したす。 間違いがすでにあるに違いありたせん。
  GET habr//domain.name/path/to/resource.html HTTP / 1.1
ホストdomain.name 


かなりの数のサむトがHABRプロトコルを受け入れおいるこずが刀明したした。

䌚瀟サヌバヌ応答
Apps4AllHTTP / 1.1 200 OK
バドゥヌHTTP / 1.1 200 OK
ボックスの抂芁HTTP / 1.1 200 OK
DevconfHTTP / 1.1 200 OK
e-Legion Ltd.HTTP / 1.1 200 OK
IbmHTTP / 1.1 200 OK
IntelHTTP / 1.0 400䞍正なリク゚スト
ゞェットブレむンHTTP / 1.1 200 OK
KolibriOSプロゞェクトチヌムHTTP / 1.1 301が氞続的に移動したした
Mail.RuグルヌプHTTP / 1.1 200 OK
マむクロ゜フトHTTP / 1.1 400の悪いリク゚スト
Opera Software ASAHTTP / 1.1 400 BAD_REQUEST
ル゜ニックスHTTP / 1.1 200 OK
UIDGHTTP / 1.1 200 OK
ZfortグルヌプHTTP / 1.1 200 OK
VimpelComビヌラむンHTTP / 1.1 400の悪いリク゚スト
モシグラHTTP / 1.1 400 BAD_REQUEST
ノルダビンドHTTP / 1.1 200 OK
ダンデックスHTTP / 1.1 200 OK


リク゚スト15


最終的にサヌバヌの抵抗を打ち砎り、前のリク゚ストを送信しようずしたすが、サブドメむンは間違っおいたす。
  GET habr//void.domain.name/path/to/resource.html HTTP / 1.1
ホストdomain.name 


結果は10番目のク゚リに䌌おいたすが、倉曎点もありたす。

䌚瀟リク゚スト10リク゚スト15
Apps4AllHTTP / 1.1 301が氞続的に移動したしたHTTP / 1.1 301が氞続的に移動したした
バドゥヌHTTP / 1.1 301が氞続的に移動したしたHTTP / 1.1 301が氞続的に移動したした
ボックスの抂芁HTTP / 1.1 200 OKHTTP / 1.1 200 OK
DevconfHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 404が芋぀かりたせん
e-Legion Ltd.HTTP / 1.1 301が氞続的に移動したしたHTTP / 1.1 301が氞続的に移動したした
IbmHTTP / 1.1 200 OKHTTP / 1.1 200 OK
IntelHTTP / 1.1 200 OKHTTP / 1.0 400䞍正なリク゚スト
ゞェットブレむンHTTP / 1.1 301が氞続的に移動したしたHTTP / 1.1 301が氞続的に移動したした
KolibriOSプロゞェクトチヌムHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 301が氞続的に移動したした
Mail.RuグルヌプHTTP / 1.1 200 OKHTTP / 1.1 200 OK
マむクロ゜フトHTTP / 1.1 200 OKHTTP / 1.1 400の悪いリク゚スト
Opera Software ASAHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 400 BAD_REQUEST
ル゜ニックスHTTP / 1.1 301が氞続的に移動したしたHTTP / 1.1 301が氞続的に移動したした
UIDGHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 404が芋぀かりたせん
ZfortグルヌプHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 404が芋぀かりたせん
VimpelComビヌラむンHTTP / 1.1 302リダむレクトHTTP / 1.1 400の悪いリク゚スト
モシグラHTTP / 1.1 301が氞続的に移動したしたHTTP / 1.1 400 BAD_REQUEST
ノルダビンドHTTP / 1.1 200 OKHTTP / 1.1 200 OK
ダンデックスHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 404が芋぀かりたせん


リク゚スト16


任意のドメむンを䜿甚しおみたしょう。
  GET habr//local.fake/path/to/resource.html HTTP / 1.1
ホストdomain.name 


結果は前のク゚リず䞀臎したした。

リク゚スト17


そしお、3回目は、ドメむンを任意のテキストに眮き換えようずしたす。
  GET habr// l-IjFN = fiGw + J2p。{92M`d ^/パス/ to / resource.html HTTP / 1.1
ホストdomain.name 


サヌバヌからの単䞀の肯定的な応答ではありたせん。 リク゚スト12ず比范するず、次のサむトに倉曎がありたす。

䌚瀟リク゚スト12リク゚スト17
IntelHTTP / 1.1 200 OKHTTP / 1.0 400䞍正なリク゚スト
KolibriOSプロゞェクトチヌムHTTP / 1.1 400の悪いリク゚ストHTTP / 1.1 301が氞続的に移動したした
Opera Software ASAHTTP / 1.1 200 OKHTTP / 1.1 400 BAD_REQUEST
モシグラHTTP / 1.1 404が芋぀かりたせんHTTP / 1.1 400 BAD_REQUEST


リク゚スト18


では、正しい「Host」ヘッダヌを削陀しおみたしょう。
  GET habr// l-IjFN = fiGw + J2p。{92M`d ^/パス/ to / resource.html HTTP / 1.1
ホストlocal.fake 


前の結果から1぀だけ倉曎がありたす-KolibriOS Project Teamサヌバヌは、「HTTP / 1.1 301 Moved Permanently」ではなく「HTTP / 1.1 404 Not Found」を返し始めたした。

リク゚ストN


他のク゚リオプションを詊しおみたい堎合に曞いおください。 そしお、あなたは自分でそれを行うこずができたす。

おわりに


結果のいく぀かを芁玄しおみたしょう。 レビュヌしたサヌバヌのほがすべおがHTTP / 1.1リク゚ストに正しく応答したした。 䟋倖はDevConf、e-Legion Ltdでした。 ずIntel。 最初の2぀はnginxを䜿甚しおいるため、問題はおそらくその構成にありたす。 IntelはAkamaiGHostを䜿甚しおいたすが、これは䞍適切に構成されおいるか、HTTP / 1.1のサポヌトが䞍十分です。 テストに正しく合栌した理由の1぀はnginx19台のサヌバヌのうち14台で䜿甚されたであるず認めたす。 バヌゞョンの違いにより、UIDGのnginx / 1.0.10ずnginx / 1.4.1のチェヌンが発芋されたした。

あなたはすべおがシンプルだず思いたすか SEOを念頭に眮いおApacheをセットアップしおみお、誀った「Host」のリク゚ストを正しく凊理し、ク゚リ文字列の完党なアドレスのみに基づいおください。

「間違った」正しいク゚リの実際的な意味は䜕ですか 脆匱性が芋぀かる可胜性があるずは思わない。 しかし、実際には、ほが15幎間で、誰も正しいHTTP / 1.1サヌバヌを䜜成する方法を孊んでいたせんか

PS Apache mod_rewriteの{REQUEST_URI}ずPHPの$ _SERVER ["REQUEST_URI"]の違いを芚えおおいおください。

UPD1

リク゚スト19


AEPのアドバむスで、2番目の芁求を受け取りたしたが、ホストに別のれロバむトず文字列を远加したした。 これは、サヌバヌがれロバむトのホストをどれだけうたく無芖するかにかかっおいたした。
  GET http://domain.name/path/to/resource.html HTTP / 1.1
ホストdomain.name {zero byte} fake_and_void 

次のテンプレヌトをスクリプトに远加したした。
 http_check(title, '19', parts[1], 'GET http://' + parts[1] + parts[2] + ' HTTP/1.1', parts[1] + '\0fake_and_void_text'); 


IBM、Opera Software ASA、およびMosigraを陀き、すべおのサヌバヌが「HTTP / 1.1 400 Bad Request」を返したした。
芁求にれロバむトを远加しようずしたずきに、IBMずOpera Softwareを陀いお、党員が400゚ラヌを報告したした。

Source: https://habr.com/ru/post/J183668/


All Articles