HTTPクライアント:HTTP Status Lineを表示(Core Foundation)

CF系APIを使ってHTTPクライアントを作る方法です。 エラー処理等かなりいい加減なのでご注意下さい。

サンプルコード

指定したURLからデータを取得しつつ、writeシステムコールを使いながら結果を標準出力に表示しています。 最終的にHTTPステータスライン文字列を表示しています。 単純なデータ取得サンプルと違う部分を強調してあります。


#import <Cocoa/Cocoa.h>

int
main()
{
  CFStringRef urlstr = CFSTR("http://www.example.com/");
  if (urlstr == nil) {
    return 1;
  }

  CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault,urlstr,NULL);
  if (url == nil) {
    return 1;
  }

  CFStringRef reqMethod = CFSTR("GET");
  if (reqMethod == nil) {
    return 1;
  }

  CFHTTPMessageRef req = CFHTTPMessageCreateRequest(kCFAllocatorDefault,reqMethod,url,kCFHTTPVersion1_1);
  if (req == nil) {
    return 1;
  }

  CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault,req);
  if (rs == nil) {
    return 1;
  }

  if (!CFReadStreamOpen(rs)) {
    CFStreamError err = CFReadStreamGetError(rs);
    printf("error\n");

    if (err.domain == kCFStreamErrorDomainPOSIX) {
      int eno = err.error;
      printf("UNIX errno\n");
      printf("%s\n", strerror(err.error));
    } else if (err.domain == kCFStreamErrorDomainMacOSStatus) {
      OSStatus macerr = (OSStatus)err.error;
      printf("MacOS error code\n");
    } else if (err.domain == kCFStreamErrorDomainHTTP) {
    } else {
      printf("other error domain\n");
    }
  }

  UInt8 buf[8192];
  CFIndex n;

  while (1) {
    n = CFReadStreamRead(rs,buf,sizeof(buf));
    printf("%d\n", n);
    if (n <= 0) {
      if (n == 0) {
        break;
      }

      CFStreamError err = CFReadStreamGetError(rs);
      printf("err : %d\n", err.error);
    if (err.domain == kCFStreamErrorDomainPOSIX) {
      int eno = err.error;
      printf("UNIX errno\n");
      printf("%s\n", strerror(err.error));
    } else if (err.domain == kCFStreamErrorDomainMacOSStatus) {
      OSStatus macerr = (OSStatus)err.error;
      printf("MacOS error code\n");
    } else if (err.domain == kCFStreamErrorDomainHTTP) {
    } else {
      printf("other error domain\n");
    }
      break;
    }

    write(fileno(stdout), buf, n);
  }


  CFHTTPMessageRef resp =
     (CFHTTPMessageRef)CFReadStreamCopyProperty(rs,kCFStreamPropertyHTTPResponseHeader);
  if (resp == nil) {
    CFStreamError err = CFReadStreamGetError(rs);
    printf("error : %d\n", err.error);
  }

  CFStringRef statusline = CFHTTPMessageCopyResponseStatusLine(resp);
  CFShow(statusline);

}


IPv6基礎検定

YouTubeチャンネルやってます!