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);
}