flycast/shell/apple/common/http_client.mm

160 lines
6.8 KiB
Plaintext

/*
Copyright 2022 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#import <Foundation/Foundation.h>
#include "oslib/http_client.h"
namespace http {
int get(const std::string& url, std::vector<u8>& content, std::string& contentType)
{
NSString *nsurl = [NSString stringWithCString:url.c_str()
encoding:[NSString defaultCStringEncoding]];
NSString *userAgent = [NSString stringWithCString:getUserAgent().c_str()
encoding:[NSString defaultCStringEncoding]];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:nsurl]];
[urlRequest setValue:userAgent forHTTPHeaderField:@"User-Agent"];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
if (error != nil)
return 500;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.MIMEType != nil)
contentType = std::string([httpResponse.MIMEType UTF8String]);
else
contentType.clear();
content.clear();
content.insert(content.begin(), (const u8 *)[data bytes], (const u8 *)[data bytes] + [data length]);
return [httpResponse statusCode];
}
int post(const std::string& url, const char *payload, const char *contentType, std::vector<u8>& reply)
{
NSString *nsurl = [NSString stringWithCString:url.c_str()
encoding:[NSString defaultCStringEncoding]];
NSString *userAgent = [NSString stringWithCString:getUserAgent().c_str()
encoding:[NSString defaultCStringEncoding]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:nsurl]];
[request setHTTPMethod:@"POST"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
size_t payloadSize = strlen(payload);
[request setHTTPBody:[NSData dataWithBytes:payload length:payloadSize]];
NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)payloadSize];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
NSString *nscontentType = contentType != nullptr ? [NSString stringWithCString:contentType
encoding:[NSString defaultCStringEncoding]]
: @"application/x-www-form-urlencoded";
[request setValue:nscontentType forHTTPHeaderField:@"Content-Type"];
[request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error != nil)
return 500;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
reply.clear();
reply.insert(reply.begin(), (const u8 *)[data bytes], (const u8 *)[data bytes] + [data length]);
return [httpResponse statusCode];
}
int post(const std::string& url, const std::vector<PostField>& fields)
{
NSString *nsurl = [NSString stringWithCString:url.c_str()
encoding:[NSString defaultCStringEncoding]];
NSString *userAgent = [NSString stringWithCString:getUserAgent().c_str()
encoding:[NSString defaultCStringEncoding]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:nsurl]];
[request setHTTPMethod:@"POST"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
NSString *boundary = @"----flycast-boundary-7192397596";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
[request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
NSMutableData *body = [NSMutableData data];
for (const PostField& field : fields)
{
NSString *value = [NSString stringWithCString:field.value.c_str()
encoding:[NSString defaultCStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"", [NSString stringWithCString:field.name.c_str()
encoding:[NSString defaultCStringEncoding]]] dataUsingEncoding:NSUTF8StringEncoding]];
if (!field.contentType.empty())
{
[body appendData:[[NSString stringWithFormat:@"; filename=\"%@\"\r\n", value] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Type: %@", [NSString stringWithCString:field.contentType.c_str()
encoding:[NSString defaultCStringEncoding]]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[@"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
if (field.contentType.empty())
{
[body appendData:[value dataUsingEncoding:NSUTF8StringEncoding]];
}
else
{
NSError* error = nil;
NSData *filedata = [NSData dataWithContentsOfFile:value options:0 error:&error];
if (error != nil)
return 500;
[body appendData:filedata];
}
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
NSURLResponse *response = nil;
NSError *error = nil;
[NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error != nil)
return 500;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
return [httpResponse statusCode];
}
void init() {
}
void term() {
}
}