Files
waf-platform/HttpDNSSDK/sdk/ios/NewHttpDNSTests/Network/HttpdnsNWHTTPClientTestHelper.m

169 lines
5.3 KiB
Objective-C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HttpdnsNWHTTPClientTestHelper.m
// TrustHttpDNSTests
//
// @author Created by Claude Code on 2025-11-01
// Copyright © 2025 trustapp.com. All rights reserved.
//
#import "HttpdnsNWHTTPClientTestHelper.h"
@implementation HttpdnsNWHTTPClientTestHelper
#pragma mark - HTTP å“<C3A5>应数æ<C2B0>®æž„é€?
+ (NSData *)createHTTPResponseWithStatus:(NSInteger)statusCode
statusText:(NSString *)statusText
headers:(nullable NSDictionary<NSString *, NSString *> *)headers
body:(nullable NSData *)body {
NSMutableString *response = [NSMutableString string];
// 状æ€<C3A6>行
[response appendFormat:@"HTTP/1.1 %ld %@\r\n", (long)statusCode, statusText ?: @"OK"];
// 头部
if (headers) {
for (NSString *key in headers) {
[response appendFormat:@"%@: %@\r\n", key, headers[key]];
}
}
// 如果�body 但没�Content-Length,自动添�
if (body && body.length > 0 && !headers[@"Content-Length"]) {
[response appendFormat:@"Content-Length: %lu\r\n", (unsigned long)body.length];
}
// 空行分隔头部�body
[response appendString:@"\r\n"];
NSMutableData *responseData = [[response dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
// 添加 body
if (body) {
[responseData appendData:body];
}
return [responseData copy];
}
+ (NSData *)createChunkedHTTPResponseWithStatus:(NSInteger)statusCode
headers:(nullable NSDictionary<NSString *, NSString *> *)headers
chunks:(NSArray<NSData *> *)chunks {
return [self createChunkedHTTPResponseWithStatus:statusCode
headers:headers
chunks:chunks
trailers:nil];
}
+ (NSData *)createChunkedHTTPResponseWithStatus:(NSInteger)statusCode
headers:(nullable NSDictionary<NSString *, NSString *> *)headers
chunks:(NSArray<NSData *> *)chunks
trailers:(nullable NSDictionary<NSString *, NSString *> *)trailers {
NSMutableString *response = [NSMutableString string];
// 状æ€<C3A6>行
[response appendFormat:@"HTTP/1.1 %ld OK\r\n", (long)statusCode];
// 头部
if (headers) {
for (NSString *key in headers) {
[response appendFormat:@"%@: %@\r\n", key, headers[key]];
}
}
// Transfer-Encoding 头部
[response appendString:@"Transfer-Encoding: chunked\r\n"];
// 空行
[response appendString:@"\r\n"];
NSMutableData *responseData = [[response dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
// 添加æ¯<C3A6>个 chunk
for (NSData *chunk in chunks) {
[responseData appendData:[self encodeChunk:chunk]];
}
// 添加终止 chunk
if (trailers) {
[responseData appendData:[self encodeLastChunkWithTrailers:trailers]];
} else {
[responseData appendData:[self encodeLastChunk]];
}
return [responseData copy];
}
#pragma mark - Chunked ç¼ç <C3A7>工具
+ (NSData *)encodeChunk:(NSData *)data {
return [self encodeChunk:data extension:nil];
}
+ (NSData *)encodeChunk:(NSData *)data extension:(nullable NSString *)extension {
NSMutableString *chunkString = [NSMutableString string];
// Chunk size(å<CB86><C3A5>å…­è¿åˆ¶ï¼‰
if (extension) {
[chunkString appendFormat:@"%lx;%@\r\n", (unsigned long)data.length, extension];
} else {
[chunkString appendFormat:@"%lx\r\n", (unsigned long)data.length];
}
NSMutableData *chunkData = [[chunkString dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
// Chunk data
[chunkData appendData:data];
// CRLF
[chunkData appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
return [chunkData copy];
}
+ (NSData *)encodeLastChunk {
return [@"0\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding];
}
+ (NSData *)encodeLastChunkWithTrailers:(NSDictionary<NSString *, NSString *> *)trailers {
NSMutableString *lastChunkString = [NSMutableString stringWithString:@"0\r\n"];
// 添加 trailer 头部
for (NSString *key in trailers) {
[lastChunkString appendFormat:@"%@: %@\r\n", key, trailers[key]];
}
// 空行终止
[lastChunkString appendString:@"\r\n"];
return [lastChunkString dataUsingEncoding:NSUTF8StringEncoding];
}
#pragma mark - æµè¯•æ•°æ<C2B0>®ç”Ÿæˆ<C3A6>
+ (NSData *)randomDataWithSize:(NSUInteger)size {
NSMutableData *data = [NSMutableData dataWithLength:size];
if (SecRandomCopyBytes(kSecRandomDefault, size, data.mutableBytes) != 0) {
// 如果 SecRandom 失败,使用简å<E282AC>•çš„éš<C3A9>机æ•?
uint8_t *bytes = data.mutableBytes;
for (NSUInteger i = 0; i < size; i++) {
bytes[i] = arc4random_uniform(256);
}
}
return [data copy];
}
+ (NSData *)jsonBodyWithDictionary:(NSDictionary *)dictionary {
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:&error];
if (error) {
NSLog(@"JSON serialization error: %@", error);
return nil;
}
return jsonData;
}
@end