mirror of https://github.com/axmolengine/axmol.git
iOS HttpClient replace libcurl
This commit is contained in:
parent
bc77d87a8e
commit
7426b5c4b5
|
@ -704,7 +704,6 @@
|
|||
15AE1BAE19AADFDF00C27E9E /* UILayoutParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FD18CF08D000240AA3 /* UILayoutParameter.h */; };
|
||||
15AE1BAF19AADFDF00C27E9E /* UILayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29CB8F4A1929D1BB00C841D6 /* UILayoutManager.cpp */; };
|
||||
15AE1BB019AADFDF00C27E9E /* UILayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 29CB8F4B1929D1BB00C841D6 /* UILayoutManager.h */; };
|
||||
15AE1BB119AADFEF00C27E9E /* HttpClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5362180E3374000584C8 /* HttpClient.cpp */; };
|
||||
15AE1BB219AADFEF00C27E9E /* HttpClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5363180E3374000584C8 /* HttpClient.h */; };
|
||||
15AE1BB319AADFEF00C27E9E /* HttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5364180E3374000584C8 /* HttpRequest.h */; };
|
||||
15AE1BB419AADFEF00C27E9E /* HttpResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5365180E3374000584C8 /* HttpResponse.h */; };
|
||||
|
@ -712,7 +711,6 @@
|
|||
15AE1BB619AADFEF00C27E9E /* SocketIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5367180E3374000584C8 /* SocketIO.h */; };
|
||||
15AE1BB719AADFEF00C27E9E /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5368180E3374000584C8 /* WebSocket.cpp */; };
|
||||
15AE1BB819AADFEF00C27E9E /* WebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5369180E3374000584C8 /* WebSocket.h */; };
|
||||
15AE1BB919AADFF000C27E9E /* HttpClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5362180E3374000584C8 /* HttpClient.cpp */; };
|
||||
15AE1BBA19AADFF000C27E9E /* HttpClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5363180E3374000584C8 /* HttpClient.h */; };
|
||||
15AE1BBB19AADFF000C27E9E /* HttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5364180E3374000584C8 /* HttpRequest.h */; };
|
||||
15AE1BBC19AADFF000C27E9E /* HttpResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5365180E3374000584C8 /* HttpResponse.h */; };
|
||||
|
@ -1749,6 +1747,12 @@
|
|||
50ED2BE519BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDE19BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp */; };
|
||||
50ED2BE619BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDF19BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp */; };
|
||||
50ED2BE719BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDF19BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp */; };
|
||||
52B47A1E1A53489B004E4C60 /* HttpClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A1D1A53489B004E4C60 /* HttpClient.cpp */; };
|
||||
52B47A2E1A5349A3004E4C60 /* HttpAsynConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B47A291A5349A3004E4C60 /* HttpAsynConnection.h */; };
|
||||
52B47A2F1A5349A3004E4C60 /* HttpAsynConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2A1A5349A3004E4C60 /* HttpAsynConnection.m */; };
|
||||
52B47A301A5349A3004E4C60 /* HttpClientIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2B1A5349A3004E4C60 /* HttpClientIOS.mm */; };
|
||||
52B47A311A5349A3004E4C60 /* HttpCookie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2C1A5349A3004E4C60 /* HttpCookie.cpp */; };
|
||||
52B47A321A5349A3004E4C60 /* HttpCookie.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B47A2D1A5349A3004E4C60 /* HttpCookie.h */; };
|
||||
5E9F61261A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
|
||||
5E9F61271A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
|
||||
5E9F61281A3FFE3D0038DE01 /* CCFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */; };
|
||||
|
@ -2276,7 +2280,6 @@
|
|||
1A9DCA03180E6955007A3AD4 /* CCGLBufferedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGLBufferedNode.h; sourceTree = "<group>"; };
|
||||
1AAF5351180E3060000584C8 /* AssetsManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AssetsManager.cpp; sourceTree = "<group>"; };
|
||||
1AAF5352180E3060000584C8 /* AssetsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssetsManager.h; sourceTree = "<group>"; };
|
||||
1AAF5362180E3374000584C8 /* HttpClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpClient.cpp; sourceTree = "<group>"; };
|
||||
1AAF5363180E3374000584C8 /* HttpClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpClient.h; sourceTree = "<group>"; };
|
||||
1AAF5364180E3374000584C8 /* HttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpRequest.h; sourceTree = "<group>"; };
|
||||
1AAF5365180E3374000584C8 /* HttpResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpResponse.h; sourceTree = "<group>"; };
|
||||
|
@ -2929,6 +2932,12 @@
|
|||
50FCEB9018C72017004AD434 /* WidgetReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WidgetReader.cpp; sourceTree = "<group>"; };
|
||||
50FCEB9118C72017004AD434 /* WidgetReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetReader.h; sourceTree = "<group>"; };
|
||||
50FCEB9218C72017004AD434 /* WidgetReaderProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetReaderProtocol.h; sourceTree = "<group>"; };
|
||||
52B47A1D1A53489B004E4C60 /* HttpClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpClient.cpp; sourceTree = "<group>"; };
|
||||
52B47A291A5349A3004E4C60 /* HttpAsynConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpAsynConnection.h; sourceTree = "<group>"; };
|
||||
52B47A2A1A5349A3004E4C60 /* HttpAsynConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpAsynConnection.m; sourceTree = "<group>"; };
|
||||
52B47A2B1A5349A3004E4C60 /* HttpClientIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HttpClientIOS.mm; sourceTree = "<group>"; };
|
||||
52B47A2C1A5349A3004E4C60 /* HttpCookie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpCookie.cpp; sourceTree = "<group>"; };
|
||||
52B47A2D1A5349A3004E4C60 /* HttpCookie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpCookie.h; sourceTree = "<group>"; };
|
||||
5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCFrustum.cpp; sourceTree = "<group>"; };
|
||||
5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCFrustum.h; sourceTree = "<group>"; };
|
||||
5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPlane.cpp; sourceTree = "<group>"; };
|
||||
|
@ -3904,7 +3913,12 @@
|
|||
1AAF5360180E3374000584C8 /* network */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1AAF5362180E3374000584C8 /* HttpClient.cpp */,
|
||||
52B47A291A5349A3004E4C60 /* HttpAsynConnection.h */,
|
||||
52B47A2A1A5349A3004E4C60 /* HttpAsynConnection.m */,
|
||||
52B47A2B1A5349A3004E4C60 /* HttpClientIOS.mm */,
|
||||
52B47A2C1A5349A3004E4C60 /* HttpCookie.cpp */,
|
||||
52B47A2D1A5349A3004E4C60 /* HttpCookie.h */,
|
||||
52B47A1D1A53489B004E4C60 /* HttpClient.cpp */,
|
||||
1AAF5363180E3374000584C8 /* HttpClient.h */,
|
||||
1AAF5364180E3374000584C8 /* HttpRequest.h */,
|
||||
1AAF5365180E3374000584C8 /* HttpResponse.h */,
|
||||
|
@ -5973,6 +5987,7 @@
|
|||
15AE1C1819AAE2C700C27E9E /* CCPhysicsSprite.h in Headers */,
|
||||
15AE1BC819AAE00000C27E9E /* AssetsManager.h in Headers */,
|
||||
B29A7E0419EE1B7700872B35 /* BoundingBoxAttachment.h in Headers */,
|
||||
52B47A2E1A5349A3004E4C60 /* HttpAsynConnection.h in Headers */,
|
||||
15AE1BBC19AADFF000C27E9E /* HttpResponse.h in Headers */,
|
||||
15AE186019AAD31200C27E9E /* SimpleAudioEngine_objc.h in Headers */,
|
||||
50ABBDA61925AB4100A911A9 /* CCQuadCommand.h in Headers */,
|
||||
|
@ -6057,6 +6072,7 @@
|
|||
5034CA2C191D591100CE6051 /* ccShader_PositionTextureA8Color.vert in Headers */,
|
||||
50ABBE981925AB6F00A911A9 /* CCProtocols.h in Headers */,
|
||||
50CB247A19D9C5A100687767 /* AudioEngine-inl.h in Headers */,
|
||||
52B47A321A5349A3004E4C60 /* HttpCookie.h in Headers */,
|
||||
50ABBD431925AB0000A911A9 /* CCMathBase.h in Headers */,
|
||||
15EFA214198A2BB5000C57D3 /* CCProtectedNode.h in Headers */,
|
||||
15AE194419AAD35100C27E9E /* CCComBase.h in Headers */,
|
||||
|
@ -6618,7 +6634,6 @@
|
|||
1A570296180BCCAB0088DEC7 /* CCAnimationCache.cpp in Sources */,
|
||||
B29A7E1B19EE1B7700872B35 /* SkeletonJson.c in Sources */,
|
||||
50ABBE351925AB6F00A911A9 /* CCConsole.cpp in Sources */,
|
||||
15AE1BB119AADFEF00C27E9E /* HttpClient.cpp in Sources */,
|
||||
50ABBEAF1925AB6F00A911A9 /* CCUserDefault.cpp in Sources */,
|
||||
15AE1BCB19AAE01E00C27E9E /* CCControlButton.cpp in Sources */,
|
||||
50ABBE791925AB6F00A911A9 /* CCEventMouse.cpp in Sources */,
|
||||
|
@ -6690,6 +6705,7 @@
|
|||
50ABBEB31925AB6F00A911A9 /* CCUserDefault-apple.mm in Sources */,
|
||||
50ABBEB51925AB6F00A911A9 /* CCUserDefault-android.cpp in Sources */,
|
||||
5E9F61261A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */,
|
||||
52B47A1E1A53489B004E4C60 /* HttpClient.cpp in Sources */,
|
||||
29394CF619B01DBA00D2DE1A /* UIWebViewImpl-ios.mm in Sources */,
|
||||
382383FC1A258FA7002C4610 /* idl_gen_text.cpp in Sources */,
|
||||
50ABBE831925AB6F00A911A9 /* ccFPSImages.c in Sources */,
|
||||
|
@ -6891,6 +6907,7 @@
|
|||
1A570072180BC5A10088DEC7 /* CCActionGrid.cpp in Sources */,
|
||||
15AE1ABC19AAD40300C27E9E /* b2PolygonAndCircleContact.cpp in Sources */,
|
||||
15AE1ADA19AAD41000C27E9E /* b2Rope.cpp in Sources */,
|
||||
52B47A301A5349A3004E4C60 /* HttpClientIOS.mm in Sources */,
|
||||
B29A7E1619EE1B7700872B35 /* BoundingBoxAttachment.c in Sources */,
|
||||
382384081A25900F002C4610 /* FlatBuffersSerialize.cpp in Sources */,
|
||||
DABC9FAA19E7DFA900FA252C /* CCClippingRectangleNode.cpp in Sources */,
|
||||
|
@ -6947,7 +6964,6 @@
|
|||
B29A7E2619EE1B7700872B35 /* Attachment.c in Sources */,
|
||||
15AE18C119AAD33D00C27E9E /* CCLayerColorLoader.cpp in Sources */,
|
||||
B37510851823ACA100B3BA6A /* CCPhysicsWorldInfo_chipmunk.cpp in Sources */,
|
||||
15AE1BB919AADFF000C27E9E /* HttpClient.cpp in Sources */,
|
||||
50ABBD551925AB0000A911A9 /* TransformUtils.cpp in Sources */,
|
||||
292DB14419B4574100A80320 /* UIEditBoxImpl-android.cpp in Sources */,
|
||||
15AE193619AAD35100C27E9E /* CCArmature.cpp in Sources */,
|
||||
|
@ -7201,6 +7217,7 @@
|
|||
50ABBD451925AB0000A911A9 /* CCVertex.cpp in Sources */,
|
||||
50ABBEB01925AB6F00A911A9 /* CCUserDefault.cpp in Sources */,
|
||||
50ABBE521925AB6F00A911A9 /* CCEventDispatcher.cpp in Sources */,
|
||||
52B47A2F1A5349A3004E4C60 /* HttpAsynConnection.m in Sources */,
|
||||
15AE1B8019AADA9A00C27E9E /* UITextAtlas.cpp in Sources */,
|
||||
15AE195919AAD35100C27E9E /* CCProcessBase.cpp in Sources */,
|
||||
15AE18D319AAD33D00C27E9E /* CCParticleSystemQuadLoader.cpp in Sources */,
|
||||
|
@ -7222,6 +7239,7 @@
|
|||
503DD8E71926736A00CD74DD /* CCEAGLView-ios.mm in Sources */,
|
||||
3E2BDAEC19C0436F0055CDCD /* AudioEngine.cpp in Sources */,
|
||||
382383F11A258FA7002C4610 /* flatc.cpp in Sources */,
|
||||
52B47A311A5349A3004E4C60 /* HttpCookie.cpp in Sources */,
|
||||
15B3707919EE414C00ABE682 /* AssetsManagerEx.cpp in Sources */,
|
||||
50ABBDA41925AB4100A911A9 /* CCQuadCommand.cpp in Sources */,
|
||||
15AE18C319AAD33D00C27E9E /* CCLayerGradientLoader.cpp in Sources */,
|
||||
|
|
|
@ -793,6 +793,7 @@
|
|||
527B1F4119EFAD44000A1F82 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 527B1F3F19EFAD44000A1F82 /* Default-736h@3x.png */; };
|
||||
527B1F4419EFAE13000A1F82 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 527B1F4219EFAE13000A1F82 /* Default-667h@2x.png */; };
|
||||
527B1F4519EFAE13000A1F82 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 527B1F4319EFAE13000A1F82 /* Default-736h@3x.png */; };
|
||||
52B47A341A534B2B004E4C60 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52B47A331A534B2B004E4C60 /* Security.framework */; };
|
||||
59620E8F1921E5CF002021B6 /* Bug-Child.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59620E8D1921E5CF002021B6 /* Bug-Child.cpp */; };
|
||||
59620E901921E5CF002021B6 /* Bug-Child.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59620E8D1921E5CF002021B6 /* Bug-Child.cpp */; };
|
||||
5EBEECB01995247000429821 /* DrawNode3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EBEECAE1995247000429821 /* DrawNode3D.cpp */; };
|
||||
|
@ -1724,6 +1725,7 @@
|
|||
527B1F3F19EFAD44000A1F82 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; };
|
||||
527B1F4219EFAE13000A1F82 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = "<group>"; };
|
||||
527B1F4319EFAE13000A1F82 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; };
|
||||
52B47A331A534B2B004E4C60 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
|
||||
59620E8D1921E5CF002021B6 /* Bug-Child.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "Bug-Child.cpp"; sourceTree = "<group>"; };
|
||||
59620E8E1921E5CF002021B6 /* Bug-Child.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Bug-Child.h"; sourceTree = "<group>"; };
|
||||
5EBEECAE1995247000429821 /* DrawNode3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DrawNode3D.cpp; path = Sprite3DTest/DrawNode3D.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1931,6 +1933,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
52B47A341A534B2B004E4C60 /* Security.framework in Frameworks */,
|
||||
15EE465B19A7200300AF29F1 /* libcurl.a in Frameworks */,
|
||||
3EA0FB66191B933000B170C8 /* MediaPlayer.framework in Frameworks */,
|
||||
1AAF5400180E39D4000584C8 /* libcocos2d iOS.a in Frameworks */,
|
||||
|
@ -3676,6 +3679,7 @@
|
|||
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
52B47A331A534B2B004E4C60 /* Security.framework */,
|
||||
15EE465A19A7200300AF29F1 /* libcurl.a */,
|
||||
15CBA9DC196EEAA6005877BB /* libz.dylib */,
|
||||
15CBA9DA196EEA90005877BB /* CoreMotion.framework */,
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#ifndef __HTTPASYNCONNECTION_H__
|
||||
#define __HTTPASYNCONNECTION_H__
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
@interface HttpAsynConnection : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||
{
|
||||
}
|
||||
|
||||
// The original URL to download. Due to redirects the actual content may come from another URL
|
||||
@property (strong) NSString *srcURL;
|
||||
|
||||
@property (strong) NSString *sslFile;
|
||||
|
||||
@property (strong) NSDictionary *responseHeader;
|
||||
|
||||
@property (strong) NSMutableData *responseData;
|
||||
|
||||
@property (readonly) NSInteger getDataTime;
|
||||
|
||||
@property (readonly) NSInteger responseCode;
|
||||
|
||||
@property (strong) NSError *responseError;
|
||||
|
||||
@property (strong) NSURLConnection *conn;
|
||||
|
||||
@property bool finish;
|
||||
|
||||
@property (strong) NSRunLoop *runLoop;
|
||||
|
||||
// instructs the class to start the request.
|
||||
-(void) startRequest:(NSURLRequest*)request;
|
||||
|
||||
@end
|
||||
|
||||
#endif //__HTTPASYNCONNECTION_H__
|
|
@ -0,0 +1,176 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#import "HttpAsynConnection.h"
|
||||
|
||||
@implementation HttpAsynConnection
|
||||
|
||||
@synthesize srcURL;
|
||||
@synthesize sslFile;
|
||||
@synthesize responseHeader;
|
||||
@synthesize responseData;
|
||||
@synthesize getDataTime;
|
||||
@synthesize responseCode;
|
||||
@synthesize responseError;
|
||||
@synthesize conn;
|
||||
@synthesize finish;
|
||||
@synthesize runLoop;
|
||||
|
||||
- (void) startRequest:(NSURLRequest *)request
|
||||
{
|
||||
NSLog(@"Starting to load %@", srcURL);
|
||||
finish = false;
|
||||
|
||||
responseData = [NSMutableData new];
|
||||
getDataTime = 0;
|
||||
responseError = nil;
|
||||
|
||||
// create the connection with the target request and this class as the delegate
|
||||
self.conn = [[NSURLConnection alloc] initWithRequest:request
|
||||
delegate:self
|
||||
startImmediately:NO];
|
||||
|
||||
[self.conn scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
|
||||
// start the connection
|
||||
[self.conn start];
|
||||
}
|
||||
|
||||
#pragma mark NSURLConnectionDelegate methods
|
||||
/**
|
||||
* This delegate method is called when the NSURLConnection connects to the server. It contains the
|
||||
* NSURLResponse object with the headers returned by the server. This method may be called multiple times.
|
||||
* Therefore, it is important to reset the data on each call. Do not assume that it is the first call
|
||||
* of this method.
|
||||
**/
|
||||
- (void) connection:(NSURLConnection *)connection
|
||||
didReceiveResponse:(NSURLResponse *)response {
|
||||
NSLog(@"Received response from request to url %@", srcURL);
|
||||
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
//NSLog(@"All headers = %@", [httpResponse allHeaderFields]);
|
||||
responseHeader = [[httpResponse allHeaderFields] copy];
|
||||
|
||||
responseCode = httpResponse.statusCode;
|
||||
if (responseCode != 200)
|
||||
{// something went wrong, abort the whole thing
|
||||
|
||||
[connection cancel];
|
||||
finish = true;
|
||||
return;
|
||||
}
|
||||
|
||||
[responseData setLength:0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This delegate method is called for each chunk of data received from the server. The chunk size
|
||||
* is dependent on the network type and the server configuration.
|
||||
*/
|
||||
- (void)connection:(NSURLConnection *)connection
|
||||
didReceiveData:(NSData *)data
|
||||
{
|
||||
//NSLog(@"get some data");
|
||||
[responseData appendData:data];
|
||||
getDataTime++;
|
||||
}
|
||||
|
||||
/**
|
||||
* This delegate methodis called if the connection cannot be established to the server.
|
||||
* The error object will have a description of the error
|
||||
**/
|
||||
- (void)connection:(NSURLConnection *)connection
|
||||
didFailWithError:(NSError *)error
|
||||
{
|
||||
//NSLog(@"Load failed with error %@", [error localizedDescription]);
|
||||
responseError = [error copy];
|
||||
|
||||
finish = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This delegate method is called when the data load is complete. The delegate will be released
|
||||
* following this call
|
||||
**/
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
|
||||
{
|
||||
finish = true;
|
||||
}
|
||||
|
||||
//Server evaluates client's certificate
|
||||
- (BOOL) shouldTrustProtectionSpace:(NSURLProtectionSpace*)protectionSpace
|
||||
{
|
||||
if(sslFile == nil)
|
||||
return YES;
|
||||
//load the bundle client certificate
|
||||
NSString *certPath = [[NSBundle mainBundle] pathForResource:sslFile ofType:@"der"];
|
||||
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath];
|
||||
CFDataRef certDataRef = (CFDataRef)certData;
|
||||
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
|
||||
|
||||
//Establish a chain of trust anchored on our bundled certificate
|
||||
CFArrayRef certArrayRef = CFArrayCreate(NULL, (void*)&cert, 1, NULL);
|
||||
SecTrustRef serverTrust = protectionSpace.serverTrust;
|
||||
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
|
||||
|
||||
//Verify that trust
|
||||
SecTrustResultType trustResult;
|
||||
SecTrustEvaluate(serverTrust, &trustResult);
|
||||
|
||||
if(trustResult == kSecTrustResultRecoverableTrustFailure)
|
||||
{
|
||||
CFDataRef errDataRef = SecTrustCopyExceptions(serverTrust);
|
||||
SecTrustSetExceptions(serverTrust, errDataRef);
|
||||
|
||||
SecTrustEvaluate(serverTrust, &trustResult);
|
||||
}
|
||||
|
||||
//Did our custom trust chain evaluate successfully?
|
||||
return trustResult = kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed;
|
||||
}
|
||||
|
||||
- (void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
|
||||
{
|
||||
id <NSURLAuthenticationChallengeSender> sender = challenge.sender;
|
||||
NSURLProtectionSpace *protectionSpace = challenge.protectionSpace;
|
||||
|
||||
//Should server trust client?
|
||||
if([self shouldTrustProtectionSpace:protectionSpace])
|
||||
{
|
||||
SecTrustRef trust = [protectionSpace serverTrust];
|
||||
//
|
||||
// SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0);
|
||||
//
|
||||
// NSData *serverCertificateData = (NSData*)SecCertificateCopyData(certificate);
|
||||
// NSString *serverCertificateDataHash = [[serverCertificateData base64EncodedString] ]
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
|
||||
[sender useCredential:credential forAuthenticationChallenge:challenge];
|
||||
}
|
||||
else
|
||||
{
|
||||
[sender cancelAuthenticationChallenge:challenge];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,518 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2012 greathqy
|
||||
Copyright (c) 2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "HttpClient.h"
|
||||
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#import "HttpAsynConnection.h"
|
||||
#include "HttpCookie.h"
|
||||
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCScheduler.h"
|
||||
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
#define ERROR_SIZE 256
|
||||
|
||||
namespace network {
|
||||
|
||||
static std::mutex s_requestQueueMutex;
|
||||
static std::mutex s_responseQueueMutex;
|
||||
|
||||
static std::condition_variable_any s_SleepCondition;
|
||||
|
||||
static Vector<HttpRequest*>* s_requestQueue = nullptr;
|
||||
static Vector<HttpResponse*>* s_responseQueue = nullptr;
|
||||
|
||||
static HttpClient *s_pHttpClient = nullptr; // pointer to singleton
|
||||
|
||||
static HttpAsynConnection *httpAsynConn = nullptr;
|
||||
static HttpCookie *s_cookie = nullptr;
|
||||
|
||||
static char s_errorBuffer[ERROR_SIZE] = {0};
|
||||
|
||||
static std::string s_cookieFilename = "";
|
||||
|
||||
static std::string s_sslCaFilename = "";
|
||||
|
||||
|
||||
static int processTask(HttpRequest *request, NSString *requestType, void *stream, long *errorCode, void *headerStream, char *errorBuffer);
|
||||
|
||||
static void processResponse(HttpResponse* response, char* errorBuffer);
|
||||
|
||||
static HttpRequest *s_requestSentinel = new HttpRequest;
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThread()
|
||||
{
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
|
||||
while (true)
|
||||
{
|
||||
HttpRequest *request;
|
||||
|
||||
// step 1: send http request if the requestQueue isn't empty
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
while (s_requestQueue->empty()) {
|
||||
s_SleepCondition.wait(s_requestQueueMutex);
|
||||
}
|
||||
request = s_requestQueue->at(0);
|
||||
s_requestQueue->erase(0);
|
||||
}
|
||||
|
||||
if (request == s_requestSentinel) {
|
||||
break;
|
||||
}
|
||||
|
||||
// step 2: libcurl sync access
|
||||
|
||||
// Create a HttpResponse object, the default setting is http access failed
|
||||
HttpResponse *response = new (std::nothrow) HttpResponse(request);
|
||||
|
||||
processResponse(response, s_errorBuffer);
|
||||
|
||||
// add response packet into queue
|
||||
s_responseQueueMutex.lock();
|
||||
s_responseQueue->pushBack(response);
|
||||
s_responseQueueMutex.unlock();
|
||||
|
||||
if (nullptr != s_pHttpClient) {
|
||||
scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup: if worker thread received quit signal, clean up un-completed request queue
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->clear();
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
|
||||
if (s_requestQueue != nullptr) {
|
||||
delete s_requestQueue;
|
||||
s_requestQueue = nullptr;
|
||||
delete s_responseQueue;
|
||||
s_responseQueue = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThreadAlone(HttpRequest* request)
|
||||
{
|
||||
// Create a HttpResponse object, the default setting is http access failed
|
||||
HttpResponse *response = new (std::nothrow) HttpResponse(request);
|
||||
char errorBuffer[ERROR_SIZE] = { 0 };
|
||||
processResponse(response, errorBuffer);
|
||||
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
scheduler->performFunctionInCocosThread([response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(s_pHttpClient, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(s_pHttpClient, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
}
|
||||
|
||||
//Process Request
|
||||
static int processTask(HttpRequest *request, NSString* requestType, void *stream, long *responseCode, void *headerStream, char *errorBuffer)
|
||||
{
|
||||
//create request with url
|
||||
NSString* urlstring = [NSString stringWithUTF8String:request->getUrl()];
|
||||
NSURL *url = [NSURL URLWithString:urlstring];
|
||||
|
||||
NSMutableURLRequest *nsrequest = [NSMutableURLRequest requestWithURL:url
|
||||
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
|
||||
timeoutInterval:HttpClient::getInstance()->getTimeoutForConnect()];
|
||||
|
||||
//set request type
|
||||
[nsrequest setHTTPMethod:requestType];
|
||||
|
||||
//if request type is post or put,set header and data
|
||||
if([requestType isEqual: @"POST"] || [requestType isEqual: @"PUT"])
|
||||
{
|
||||
/* get custom header data (if set) */
|
||||
std::vector<std::string> headers=request->getHeaders();
|
||||
if(!headers.empty())
|
||||
{
|
||||
/* append custom headers one by one */
|
||||
for (std::vector<std::string>::iterator it = headers.begin(); it != headers.end(); ++it)
|
||||
{
|
||||
unsigned long i = it->find(':', 0);
|
||||
unsigned long length = it->size();
|
||||
std::string field = it->substr(0, i);
|
||||
std::string value = it->substr(i+1, length-i);
|
||||
NSString *headerField = [NSString stringWithUTF8String:field.c_str()];
|
||||
NSString *headerValue = [NSString stringWithUTF8String:value.c_str()];
|
||||
[nsrequest setValue:headerValue forHTTPHeaderField:headerField];
|
||||
}
|
||||
}
|
||||
|
||||
NSString* requestData = [NSString stringWithUTF8String:request->getRequestData()];
|
||||
NSData *postData = [requestData dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[nsrequest setHTTPBody:postData];
|
||||
}
|
||||
|
||||
//read cookie propertities from file and set cookie
|
||||
if(!s_cookieFilename.empty())
|
||||
{
|
||||
CookiesInfo* cookieInfo = s_cookie->getMatchCookie(request->getUrl());
|
||||
if(cookieInfo != nullptr)
|
||||
{
|
||||
NSString *domain = [NSString stringWithCString:cookieInfo->domain.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
NSString *path = [NSString stringWithCString:cookieInfo->path.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
NSString *value = [NSString stringWithCString:cookieInfo->value.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
NSString *name = [NSString stringWithCString:cookieInfo->name.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
|
||||
// create the properties for a cookie
|
||||
NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys: name,NSHTTPCookieName,
|
||||
value, NSHTTPCookieValue, path, NSHTTPCookiePath,
|
||||
domain, NSHTTPCookieDomain,
|
||||
nil];
|
||||
|
||||
// create the cookie from the properties
|
||||
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:properties];
|
||||
|
||||
// add the cookie to the cookie storage
|
||||
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
|
||||
}
|
||||
}
|
||||
|
||||
httpAsynConn = [HttpAsynConnection new];
|
||||
httpAsynConn.srcURL = urlstring;
|
||||
httpAsynConn.sslFile = nil;
|
||||
NSString *sslFile = nil;
|
||||
if(!s_sslCaFilename.empty())
|
||||
{
|
||||
long len = s_sslCaFilename.length();
|
||||
long pos = s_sslCaFilename.rfind('.', len-1);
|
||||
[sslFile initWithUTF8String:s_sslCaFilename.substr(0, pos-1).c_str()];
|
||||
httpAsynConn.sslFile = sslFile;
|
||||
}
|
||||
[httpAsynConn startRequest:nsrequest];
|
||||
|
||||
while( httpAsynConn.finish != true)
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||
}
|
||||
|
||||
//if http connection return error
|
||||
if (httpAsynConn.responseError != nil)
|
||||
{
|
||||
NSString* errorString = [httpAsynConn.responseError localizedDescription];
|
||||
strcpy(errorBuffer, [errorString UTF8String]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*responseCode = httpAsynConn.responseCode;
|
||||
|
||||
//add cookie to cookies vector
|
||||
if(!s_cookieFilename.empty())
|
||||
{
|
||||
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpAsynConn.responseHeader forURL:url];
|
||||
for (NSHTTPCookie *cookie in cookies)
|
||||
{
|
||||
//NSLog(@"Cookie: %@", cookie);
|
||||
NSString *domain = cookie.domain;
|
||||
//BOOL session = cookie.sessionOnly;
|
||||
NSString *path = cookie.path;
|
||||
BOOL secure = cookie.secure;
|
||||
NSDate *date = cookie.expiresDate;
|
||||
NSString *name = cookie.name;
|
||||
NSString *value = cookie.value;
|
||||
|
||||
CookiesInfo cookieInfo;
|
||||
cookieInfo.domain = [domain cStringUsingEncoding: NSUTF8StringEncoding];
|
||||
cookieInfo.path = [path cStringUsingEncoding: NSUTF8StringEncoding];
|
||||
cookieInfo.secure = (secure == YES) ? true : false;
|
||||
cookieInfo.expires = [[NSString stringWithFormat:@"%ld", (long)[date timeIntervalSince1970]] cStringUsingEncoding: NSUTF8StringEncoding];
|
||||
cookieInfo.name = [name cStringUsingEncoding: NSUTF8StringEncoding];
|
||||
cookieInfo.value = [value cStringUsingEncoding: NSUTF8StringEncoding];
|
||||
cookieInfo.tailmatch = true;
|
||||
|
||||
s_cookie->updateOrAddCookie(&cookieInfo);
|
||||
}
|
||||
}
|
||||
|
||||
//handle response header
|
||||
NSMutableString *header = [NSMutableString new];
|
||||
for (id key in httpAsynConn.responseHeader)
|
||||
{
|
||||
[header appendFormat:@"%@: %@\n", key, [httpAsynConn.responseHeader objectForKey:key]];
|
||||
}
|
||||
if (header.length > 0)
|
||||
{
|
||||
NSRange range = NSMakeRange(header.length-1, 1);
|
||||
[header deleteCharactersInRange:range];
|
||||
}
|
||||
NSData *headerData = [header dataUsingEncoding:NSUTF8StringEncoding];
|
||||
std::vector<char> *headerBuffer = (std::vector<char>*)headerStream;
|
||||
const void* headerptr = [headerData bytes];
|
||||
long headerlen = [headerData length];
|
||||
headerBuffer->insert(headerBuffer->end(), (char*)headerptr, (char*)headerptr+headerlen);
|
||||
|
||||
//handle response data
|
||||
std::vector<char> *recvBuffer = (std::vector<char>*)stream;
|
||||
const void* ptr = [httpAsynConn.responseData bytes];
|
||||
long len = [httpAsynConn.responseData length];
|
||||
recvBuffer->insert(recvBuffer->end(), (char*)ptr, (char*)ptr+len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Process Response
|
||||
static void processResponse(HttpResponse* response, char* errorBuffer)
|
||||
{
|
||||
auto request = response->getHttpRequest();
|
||||
long responseCode = -1;
|
||||
int retValue = 0;
|
||||
NSString* requestType = nil;
|
||||
|
||||
// Process the request -> get response packet
|
||||
switch (request->getRequestType())
|
||||
{
|
||||
case HttpRequest::Type::GET: // HTTP GET
|
||||
requestType = @"GET";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::POST: // HTTP POST
|
||||
requestType = @"POST";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::PUT:
|
||||
requestType = @"PUT";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::DELETE:
|
||||
requestType = @"DELETE";
|
||||
break;
|
||||
|
||||
default:
|
||||
CCASSERT(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
|
||||
break;
|
||||
}
|
||||
|
||||
retValue = processTask(request,
|
||||
requestType,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
response->getResponseHeader(),
|
||||
errorBuffer);
|
||||
|
||||
// write data to HttpResponse
|
||||
response->setResponseCode(responseCode);
|
||||
|
||||
if (retValue != 0)
|
||||
{
|
||||
response->setSucceed(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
response->setSucceed(false);
|
||||
response->setErrorBuffer(errorBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// HttpClient implementation
|
||||
HttpClient* HttpClient::getInstance()
|
||||
{
|
||||
if (s_pHttpClient == nullptr) {
|
||||
s_pHttpClient = new (std::nothrow) HttpClient();
|
||||
}
|
||||
|
||||
return s_pHttpClient;
|
||||
}
|
||||
|
||||
void HttpClient::destroyInstance()
|
||||
{
|
||||
CC_SAFE_DELETE(s_pHttpClient);
|
||||
}
|
||||
|
||||
void HttpClient::enableCookies(const char* cookieFile) {
|
||||
if (cookieFile) {
|
||||
s_cookieFilename = std::string(cookieFile);
|
||||
s_cookieFilename = FileUtils::getInstance()->fullPathForFilename(s_cookieFilename);
|
||||
}
|
||||
else {
|
||||
s_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
}
|
||||
|
||||
s_cookie = new(std::nothrow)HttpCookie;
|
||||
s_cookie->setCookieFileName(s_cookieFilename);
|
||||
s_cookie->readFile();
|
||||
}
|
||||
|
||||
void HttpClient::setSSLVerification(const std::string& caFile)
|
||||
{
|
||||
s_sslCaFilename = caFile;
|
||||
}
|
||||
|
||||
HttpClient::HttpClient()
|
||||
: _timeoutForConnect(30)
|
||||
, _timeoutForRead(60)
|
||||
{
|
||||
}
|
||||
|
||||
HttpClient::~HttpClient()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
s_requestQueue->pushBack(s_requestSentinel);
|
||||
}
|
||||
s_SleepCondition.notify_one();
|
||||
}
|
||||
|
||||
s_pHttpClient = nullptr;
|
||||
|
||||
if(!s_cookieFilename.empty())
|
||||
{
|
||||
s_cookie->writeFile();
|
||||
//delete s_cookie;
|
||||
}
|
||||
//s_cookie = nullptr;
|
||||
}
|
||||
|
||||
//Lazy create semaphore & mutex & thread
|
||||
bool HttpClient::lazyInitThreadSemphore()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
return true;
|
||||
} else {
|
||||
|
||||
s_requestQueue = new (std::nothrow) Vector<HttpRequest*>();
|
||||
s_responseQueue = new (std::nothrow) Vector<HttpResponse*>();
|
||||
|
||||
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
|
||||
t.detach();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Add a get task to queue
|
||||
void HttpClient::send(HttpRequest* request)
|
||||
{
|
||||
if (false == lazyInitThreadSemphore())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
request->retain();
|
||||
|
||||
if (nullptr != s_requestQueue) {
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->pushBack(request);
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
s_SleepCondition.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::sendImmediate(HttpRequest* request)
|
||||
{
|
||||
if(!request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
request->retain();
|
||||
auto t = std::thread(&HttpClient::networkThreadAlone, this, request);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
// Poll and notify main thread if responses exists in queue
|
||||
void HttpClient::dispatchResponseCallbacks()
|
||||
{
|
||||
// log("CCHttpClient::dispatchResponseCallbacks is running");
|
||||
//occurs when cocos thread fires but the network thread has already quited
|
||||
if (nullptr == s_responseQueue) {
|
||||
return;
|
||||
}
|
||||
HttpResponse* response = nullptr;
|
||||
|
||||
s_responseQueueMutex.lock();
|
||||
|
||||
if (!s_responseQueue->empty())
|
||||
{
|
||||
response = s_responseQueue->at(0);
|
||||
s_responseQueue->erase(0);
|
||||
}
|
||||
|
||||
s_responseQueueMutex.unlock();
|
||||
|
||||
if (response)
|
||||
{
|
||||
HttpRequest *request = response->getHttpRequest();
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(this, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(this, response);
|
||||
}
|
||||
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "HttpCookie.h"
|
||||
#include "CCFileUtils.h"
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
void HttpCookie::readFile()
|
||||
{
|
||||
std::string inString = cocos2d::FileUtils::getInstance()->getStringFromFile(_cookieFileName);
|
||||
if(inString.length() != 0)
|
||||
{
|
||||
std::vector<std::string> cookiesVec;
|
||||
cookiesVec.clear();
|
||||
|
||||
std::stringstream stream(inString);
|
||||
std::string item;
|
||||
while(std::getline(stream, item, '\n'))
|
||||
{
|
||||
cookiesVec.push_back(item);
|
||||
}
|
||||
|
||||
if(cookiesVec.empty())
|
||||
return;
|
||||
|
||||
_cookies.clear();
|
||||
|
||||
for(auto iter = cookiesVec.begin();iter != cookiesVec.end(); iter++)
|
||||
{
|
||||
std::string cookie = *iter;
|
||||
|
||||
if(cookie.length() == 0)
|
||||
continue;
|
||||
|
||||
if(cookie.find("#HttpOnly_") != std::string::npos)
|
||||
{
|
||||
cookie = cookie.substr(10);
|
||||
}
|
||||
|
||||
if(cookie.at(0) == '#')
|
||||
continue;
|
||||
|
||||
CookiesInfo co;
|
||||
std::stringstream streamInfo(cookie);
|
||||
std::vector<std::string> elems;
|
||||
std::string elemsItem;
|
||||
|
||||
while (std::getline(streamInfo, elemsItem, '\t'))
|
||||
{
|
||||
elems.push_back(elemsItem);
|
||||
}
|
||||
|
||||
co.domain = elems[0];
|
||||
if (co.domain.at(0) == '.')
|
||||
{
|
||||
co.domain = co.domain.substr(1);
|
||||
}
|
||||
co.tailmatch = strcmp("TRUE", elems[1].c_str())?true: false;
|
||||
co.path = elems[2];
|
||||
co.secure = strcmp("TRUE", elems[3].c_str())?true: false;
|
||||
co.expires = elems[4];
|
||||
co.name = elems[5];
|
||||
co.value = elems[6];
|
||||
_cookies.push_back(co);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CookiesInfo>* HttpCookie::getCookies()
|
||||
{
|
||||
return &_cookies;
|
||||
}
|
||||
|
||||
CookiesInfo* HttpCookie::getMatchCookie(const std::string& url)
|
||||
{
|
||||
for(auto iter = _cookies.begin(); iter != _cookies.end(); iter++)
|
||||
{
|
||||
if(url.find(iter->domain) != std::string::npos)
|
||||
return &(*iter);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void HttpCookie::updateOrAddCookie(CookiesInfo* cookie)
|
||||
{
|
||||
for(auto iter = _cookies.begin(); iter != _cookies.end(); iter++)
|
||||
{
|
||||
if(cookie->domain == iter->domain)
|
||||
{
|
||||
*iter = *cookie;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_cookies.push_back(*cookie);
|
||||
}
|
||||
|
||||
void HttpCookie::writeFile()
|
||||
{
|
||||
FILE *out;
|
||||
out = fopen(_cookieFileName.c_str(), "w");
|
||||
fputs("# Netscape HTTP Cookie File\n"
|
||||
"# http://curl.haxx.se/docs/http-cookies.html\n"
|
||||
"# This file was generated by cocos2d-x! Edit at your own risk.\n"
|
||||
"# Test cocos2d-x cookie write.\n\n",
|
||||
out);
|
||||
|
||||
std::string line;
|
||||
for(auto iter = _cookies.begin(); iter != _cookies.end(); iter++)
|
||||
{
|
||||
line.clear();
|
||||
line.append(iter->domain);
|
||||
line.append(1, '\t');
|
||||
iter->tailmatch ? line.append("TRUE") : line.append("FALSE");
|
||||
line.append(1, '\t');
|
||||
line.append(iter->path);
|
||||
line.append(1, '\t');
|
||||
iter->secure ? line.append("TRUE") : line.append("FALSE");
|
||||
line.append(1, '\t');
|
||||
line.append(iter->expires);
|
||||
line.append(1, '\t');
|
||||
line.append(iter->name);
|
||||
line.append(1, '\t');
|
||||
line.append(iter->value);
|
||||
//line.append(1, '\n');
|
||||
|
||||
fprintf(out, "%s\n", line.c_str());
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void HttpCookie::setCookieFileName(std::string filename)
|
||||
{
|
||||
_cookieFileName = filename;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef HTTP_COOKIE_H
|
||||
#define HTTP_COOKIE_H
|
||||
|
||||
struct CookiesInfo
|
||||
{
|
||||
std::string domain;
|
||||
bool tailmatch;
|
||||
std::string path;
|
||||
bool secure;
|
||||
std::string name;
|
||||
std::string value;
|
||||
std::string expires;
|
||||
};
|
||||
|
||||
class HttpCookie
|
||||
{
|
||||
public:
|
||||
void readFile();
|
||||
|
||||
void writeFile();
|
||||
void setCookieFileName(const std::string fileName);
|
||||
|
||||
std::vector<CookiesInfo>* getCookies();
|
||||
CookiesInfo* getMatchCookie(const std::string& url);
|
||||
void updateOrAddCookie(CookiesInfo* cookie);
|
||||
|
||||
private:
|
||||
std::string _cookieFileName;
|
||||
std::vector<CookiesInfo> _cookies;
|
||||
};
|
||||
|
||||
#endif /* HTTP_COOKIE_H */
|
Loading…
Reference in New Issue