用 CocoaHttpServer 实现 https 服务

来源:互联网 发布:雷欧mac全灭图解 编辑:程序博客网 时间:2024/06/05 00:24

继承 HTTPConnection 类:

@interface MyHTTPConnection : HTTPConnection

HTTPConnection 子类中,实现 - (BOOL)isSecureServer 方法并返回 YES,表示支持 https。

制作一个 SSL 自签名证书,安装到钥匙串,然后导出为 .p12 文件,记住导出密码。

制作证书时需要注意 /CN 参数必须指定主机名,比如 /CN 参数指定为 127.0.0.1,则访问时只能用 https://127.0.0.1,而不能用 https://localhost 替代。

实现 sslIdentityAndCertificates 方法:

- (NSArray *)sslIdentityAndCertificates{    SecIdentityRef identityRef = NULL;    SecCertificateRef certificateRef = NULL;    SecTrustRef trustRef = NULL;    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"127.0.0.1" ofType:@"p12"];    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;    CFStringRef password = CFSTR("你导出 .p12 的密码");    const void *keys[] = { kSecImportExportPassphrase };    const void *values[] = { password };    CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);    OSStatus securityError = errSecSuccess;    securityError =  SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);    if (securityError == 0) {        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);        const void *tempIdentity = NULL;        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);        identityRef = (SecIdentityRef)tempIdentity;        const void *tempTrust = NULL;        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);        trustRef = (SecTrustRef)tempTrust;    } else {        NSLog(@"Failed with error code %d",(int)securityError);        return nil;    }    SecIdentityCopyCertificate(identityRef, &certificateRef);    NSArray *result = [[NSArray alloc] initWithObjects:(__bridge id)identityRef, (__bridge id)certificateRef, nil];    return result;}

复制 HTTPConnetion.m 中的 startConnection 方法和 startReadingRequest 方法代码。
找到 startConnection 方法中如下语句:

[settings setObject:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL                            forKey:(NSString *)kCFStreamSSLLevel]

替换为:

[settings setObject:[NSNumber numberWithInteger:2] forKey:GCDAsyncSocketSSLProtocolVersionMin];[settings setObject:[NSNumber numberWithInteger:2] forKey:GCDAsyncSocketSSLProtocolVersionMax];

在启动 HTTPServer (调用 startServer )之前,使用 setConnectionClass 方法将 HTTPConnecdtion 替换为 MyHTTPConnection:

[httpServer setConnectionClass:[MyHTTPConnection class]];
0 0
原创粉丝点击