• ベストアンサー

Winsockでステータスコードを受信するには

タイトルの件でおうかがいします。 httpサーバにGETなりPOSTのリクエストをしたときのHTTPステータスコードは、どのようにして取得すればよいでしょうか? 「200 OK」とか「403 Forbidden」とかいうのを取得したいのですが…。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.5

#3#4に誤記があったので訂正します。 プロトコル名称 誤 HTTP0.9 正 HTTP/0.9 誤 HTTP1.0 正 HTTP/1.0 HTTP/1.0のGET書式について 誤 GET {URL-Path} HTTP/1.0\r\n {Header: Header-value\r\n} \r\n 正 GET {URL_PATH}[?{QUERY_STRING}] HTTP/1.0\r\n [Host: {Host_name}\r\n] [{Other-header}: {Other-header-value}\r\n] \r\n 誤 相手がバーチャルホストだとHTTP/1.1でないとダメ。 でも必須ヘッダに注意。 正 相手がバーチャルホストだとHTTP/1.0以降でないとダメ。 Host:ヘッダを送る必要あり。 送らないとデフォルトのホストと解釈される。 HTTP/1.1ではHost:ヘッダは必須。

mangos
質問者

お礼

お礼が遅くなりました。#3~#5までのお答えありがとうございます。 私の参考にしていた書籍の出来が悪かったようです。 (HTTP/1.0を指定してGETしているサンプルコードや解説がまったく載っていません) 省略時のデフォルトがHTTP/0.9で解釈されるのも今回はじめて知りました。 本当に助かりました! ありがとうございます。

その他の回答 (4)

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.4

#1の補足にHEADと書いてありましたが、 ちなみにHTTP/0.9にHEADはないです。 一回は試してから質問しましょう。 実際にやろうとすると以下のような結果。 $telnet oshiete1.goo.ne.jp 80 Trying 202.210.169.11... Connected to oshiete1.goo.ne.jp. Escape character is '^]'. HEAD /kotaeru_reply.php3?q=1293173 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <HTML><HEAD> <TITLE>400 Bad Request</TITLE> </HEAD><BODY> <H1>Bad Request</H1> Your browser sent a request that this server could not understand.<P> client sent invalid HTTP/0.9 request: HEAD /kotaeru_reply.php3<P> </BODY></HTML> Connection closed by foreign host. $ HTTP/1.0では次のような結果。 $telnet oshiete1.goo.ne.jp 80 Trying 202.210.169.11... Connected to oshiete1.goo.ne.jp. Escape character is '^]'. HEAD /kotaeru_reply.php3?q=1293173 HTTP/1.0 HTTP/1.1 302 Found Date: Wed, 30 Mar 2005 11:48:24 GMT Server: Apache X-Powered-By: PHP/4.3.10 X-Accelerated-By: PHPA/1.3.3r2 Location: http://oshiete.goo.ne.jp/jsp/certify.jsp?return_url=http://oshiete1.go o.ne.jp/goo_jumpin.php3&next_to=/kotaeru_reply.php3&arg=q-1293173 Connection: close Content-Type: text/html; charset=EUC-JP Connection closed by foreign host. $ 相手がバーチャルホストだとHTTP/1.1でないとダメ。 でも必須ヘッダに注意。 $telnet oshiete1.goo.ne.jp 80 Trying 202.210.169.11... Connected to oshiete1.goo.ne.jp. Escape character is '^]'. HEAD /kotaeru_reply.php3?q=1293173 HTTP/1.1 HTTP/1.1 400 Bad Request Date: Wed, 30 Mar 2005 11:50:00 GMT Server: Apache Connection: close Content-Type: text/html; charset=iso-8859-1 Connection closed by foreign host. $ HTTP/1.1は最低限以下のように取得するべき。 $telnet oshiete1.goo.ne.jp 80 Trying 202.210.169.11... Connected to oshiete1.goo.ne.jp. Escape character is '^]'. HEAD /kotaeru_reply.php3?q=1293173 HTTP/1.1 Host: oshiete1.goo.ne.jp Connection: close HTTP/1.1 302 Found Date: Wed, 30 Mar 2005 11:51:24 GMT Server: Apache X-Powered-By: PHP/4.3.10 X-Accelerated-By: PHPA/1.3.3r2 Location: http://oshiete.goo.ne.jp/jsp/certify.jsp?return_url=http://oshiete1.go o.ne.jp/goo_jumpin.php3&next_to=/kotaeru_reply.php3&arg=q-1293173 Content-Type: text/html; charset=EUC-JP Connection closed by foreign host. $

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.3

あなたが行っているのは、HTTP0.9要求だからです。 HTTP0.9ではステータスコードは帰ってきません。 HTTP1.0要求を行ってください。 HTTP1.0のGET 書式 GET {URL-Path} HTTP/1.0\r\n {Header: Header-value\r\n} \r\n 例: http://oshiete1.goo.ne.jp/kotaeru_reply.php3?q=1293173をtelnetを使って取得する $telnet oshiete1.goo.ne.jp 80 GET /kotaeru_reply.php3?q=1293173 HTTP/1.0 Host: oshiete1.goo.ne.jp HTTP/1.1 302 Found Date: Wed, 30 Mar 2005 11:33:55 GMT Server: Apache X-Powered-By: PHP/4.3.10 X-Accelerated-By: PHPA/1.3.3r2 Location: http://oshiete.goo.ne.jp/jsp/certify.jsp?return_url=http://oshiete1.go o.ne.jp/goo_jumpin.php3&next_to=/kotaeru_reply.php3&arg=q-1293173 Connection: close Content-Type: text/html; charset=EUC-JP Connection closed by foreign host. $ telnetで以上のように動きます。ちなみに、このリダイレクト応答には本文がないので、HTTP0.9要求"GET /kotaeru_reply.php3?q=1293173"では何も帰ってきません。

回答No.2

まず、ソケットを使って接続完了後、そのHTMLボディ部を受け取るまでの処理はどうやっているでしょうか。(ソースを載せてくれるとご質問に答えやすくなると思いますが) 思うに、すべて自分で書いたというより、どこかのライブラリかソースをコピペなりしていませんか? もしそうだとしたら、汎用がきく(?)ようにHTMLボディー部から拾うように出来ているものを使用している気が・・・。 たとえば、Telnetでgoogleにアクセスした場合、GETであれば、 HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html Set-Cookie: PREF=ID=d37975a7cb05646c:TM=1111932479:LM=1111932479:S=SItAnaSA4YV3K HZr; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com Server: GWS/2.1 Transfer-Encoding: chunked Date: Sun, 27 Mar 2005 14:07:59 GMT こんな感じに出力されます。 最初の空行までは、処理しないようなプログラムを記述していないかご確認ください。

mangos
質問者

補足

ソースコードなんですがこんな感じです。 これはクラスメンバなんですがバッファにひたすら継ぎ足してるだけで特別な処理はしてないつもりですけどヘッダは取れません。 ツールはC++Builderです。 // 指定URLからドキュメントをGETする int __fastcall ConnHttpSock::GetDataFromUrl(AnsiString& document) { AnsiString send_str; AnsiString data_body; data_body = GetNormalPostData(); send_str = "GET " + ExtractFilePath(CurrentUrl) + "\n"; nRtn = send(s, send_str.c_str(), (int)send_str.Length(), 0); document = ""; // データ取得 while(1) { memset(szStrRcv, '\0', sizeof(szStrRcv)); nRtn = recv(s, szStrRcv, (int)sizeof(szStrRcv) - 1, 0); document += AnsiString(szStrRcv); if(0 == nRtn) { // データ取得成功 break; } if(SOCKET_ERROR == nRtn) { // エラー! return -1; } } return 0; }

回答No.1

こんにちは。 おっしゃることがいまいちわかりませんが、Winsockを使って送信・受信する方法でしょうか? ステータスコードは、そのデータを解析して(たとえば200という数字ではじまるか含まれるとか)、という処理をすればよいと思いますが。 http://home.a03.itscom.net/tsuzu/programing/tips34.htm http://www.02.246.ne.jp/~torutk/cxx/socket/win32_socket.html http://www.kt.rim.or.jp/~ksk/wskfaq-ja/newbie.html#samples ここいらへんにWinsockの使い方や説明が載っています。 ご参考にしてください。

mangos
質問者

補足

早速ありがとうございます。 受信したデータにはそもそもステータスデータが含まれていないんです。(いきなりHTMLボディから始まっています) 普通にGETリクエストは出しているんですが何故でしょう? 受信するには、GETと別にいちいちHEADリクエストを発行するしか方法がないのでしょうか? よろしくお願いします。

関連するQ&A