/* * Copyright [2019] [Doric.Pub] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // // DoricLocalServer.m // Doric // // Created by pengfei.zhou on 2019/8/14. // #import "DoricLocalServer.h" #import "GCDWebServer.h" #import "GCDWebServerDataResponse.h" #import "DoricUtil.h" #import "DoricContextManager.h" #include #include #include typedef id (^ServerHandler)(GCDWebServerRequest *request); @interface DoricLocalServer () @property(nonatomic, strong) GCDWebServer *server; @property(nonatomic, strong) NSMutableDictionary *handlers; @end @implementation DoricLocalServer - (instancetype)init { if (self = [super init]) { _server = [[GCDWebServer alloc] init]; _handlers = [[NSMutableDictionary alloc] init]; [self configurate]; } return self; } - (NSString *)localIPAddress { NSString *localIP = nil; struct ifaddrs *addrs; if (getifaddrs(&addrs) == 0) { const struct ifaddrs *cursor = addrs; while (cursor != NULL) { if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0) { //NSString *name = [NSString stringWithUTF8String:cursor->ifa_name]; //if ([name isEqualToString:@"en0"]) // Wi-Fi adapter { localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *) cursor->ifa_addr)->sin_addr)]; break; } } cursor = cursor->ifa_next; } freeifaddrs(addrs); } return localIP; } - (GCDWebServerResponse *)handleRequest:(GCDWebServerRequest *)request { if ([request.path hasPrefix:@"/api/"]) { NSString *command = [request.path substringFromIndex:@"/api/".length]; ServerHandler handler = [self.handlers objectForKey:command]; if (handler) { id dic = handler(request); return [GCDWebServerDataResponse responseWithJSONObject:dic]; } return [GCDWebServerDataResponse responseWithHTML:@"

It's a API request.

"]; } NSBundle *bundle = DoricBundle(); NSString *filePath = [NSString stringWithFormat:@"%@/dist%@", bundle.bundlePath, request.path]; NSData *data = [NSData dataWithContentsOfFile:filePath]; NSURL *url = [NSURL fileURLWithPath:filePath]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; NSHTTPURLResponse *response; [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:nil]; return [GCDWebServerDataResponse responseWithData:data contentType:response.MIMEType]; } - (void)configurate { __weak typeof(self) _self = self; [self.server addDefaultHandlerForMethod:@"GET" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) { __strong typeof(_self) self = _self; return [self handleRequest:request]; }]; [self.handlers setObject:^id(GCDWebServerRequest *request) { NSMutableArray *array = [[NSMutableArray alloc] init]; for (NSValue *value in [[DoricContextManager instance] aliveContexts]) { DoricContext *context = value.nonretainedObjectValue; [array addObject:@{ @"source": context.source, @"id": context.contextId, }]; } return array; } forKey:@"allContexts"]; [self.handlers setObject:^id(GCDWebServerRequest *request) { NSString *contextId = [request.query objectForKey:@"id"]; DoricContext *context = [[DoricContextManager instance] getContext:contextId]; return @{ @"id": context.contextId, @"source": context.source, @"script": context.script }; } forKey:@"context"]; } - (void)startWithPort:(NSUInteger)port { [self.server startWithPort:port bonjourName:nil]; DoricLog(@"Start Server At %@:%d", [self localIPAddress], port); } @end