├── .appveyor.yml ├── .cproject ├── .gitignore ├── .project ├── .travis.yml ├── example ├── addons.make ├── bin │ └── data │ │ └── ofw-logo.gif ├── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h └── upload.php ├── index.html └── src ├── ofxHttpTypes.h ├── ofxHttpUtils.cpp └── ofxHttpUtils.h /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | os: Visual Studio 2015 RC 3 | 4 | environment: 5 | global: 6 | APPVEYOR_OS_NAME: windows 7 | matrix: 8 | #MSYS2 Building 9 | - platform: x86 10 | BUILDER: MSYS2 11 | 12 | #VisualStudio Building 13 | - platform: x86 14 | BUILDER : VS 15 | BITS: 32 16 | - platform: x64 17 | BUILDER : VS 18 | BITS: 64 19 | 20 | configuration: Debug 21 | shallow_clone: true 22 | clone_depth: 10 23 | init: 24 | - set MSYS2_PATH=c:\msys64 25 | - set CHERE_INVOKING=1 26 | - if "%BUILDER%_%PLATFORM%"=="MSYS2_x86" set MSYSTEM=MINGW32 27 | - if "%BUILDER%_%PLATFORM%"=="MSYS2_x64" set MSYSTEM=MINGW64 28 | - if "%BUILDER%"=="VS" set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% 29 | 30 | install: 31 | - cd .. 32 | - git clone --depth=1 --branch=master https://github.com/openframeworks/openFrameworks 33 | - call openFrameworks\scripts\ci\addons\install.cmd 34 | 35 | build_script: 36 | - cd %OF_PATH% 37 | - scripts\ci\addons\build.cmd 38 | 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Debug*/ 2 | Release*/ 3 | bin/ 4 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ofxHttpUtils 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/OpenCvExample/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | 73 | 74 | 75 | 76 | 77 | org.eclipse.cdt.core.cnature 78 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 79 | org.eclipse.cdt.core.ccnature 80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 81 | 82 | 83 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This file allows testing your addon using travis CI servers to use it you'll need to 2 | # create an account in travis.org and enable your addon there. 3 | # 4 | # By default it will test linux 64bit and osx against the master and stable OF branches. 5 | # Other platforms can be enabled by uncommenting the corresponding sections. 6 | # 7 | # If any extra install is needed to use the addon it can be included in the corresponding 8 | # install script in: 9 | # 10 | # scripts/ci/$TARGET/install.sh 11 | # 12 | 13 | 14 | language: c++ 15 | compiler: gcc 16 | sudo: true 17 | matrix: 18 | include: 19 | # fully specify builds, include can't dynamically expand matrix entries 20 | # relative order of sudo and env is important so that addons: is recognized 21 | 22 | # Linux 64bit, OF master 23 | - os: linux 24 | dist: trusty 25 | sudo: required 26 | env: TARGET="linux64" OF_BRANCH="master" 27 | addons: 28 | apt: 29 | sources: 30 | - ubuntu-toolchain-r-test 31 | packages: 32 | - gcc-4.9 33 | - g++-4.9 34 | - gdb 35 | 36 | # Linux 64bit, OF stable: Not supported yet 37 | # - os: linux 38 | # dist: trusty 39 | # sudo: required 40 | # env: TARGET="linux64" OF_BRANCH="stable" 41 | # addons: 42 | # apt: 43 | # sources: 44 | # - ubuntu-toolchain-r-test 45 | # packages: 46 | # - gcc-4.9 47 | # - g++-4.9 48 | # - gdb 49 | 50 | # OSX, OF master 51 | - os: osx 52 | osx_image: xcode8 53 | compiler: clang 54 | env: TARGET="osx" OF_BRANCH="master" 55 | 56 | # OSX, OF stable: Not supported yet 57 | # - os: osx 58 | # osx_image: xcode8 59 | # compiler: clang 60 | # env: TARGET="osx" OF_BRANCH="stable" 61 | 62 | # Linux ARM6, OF master: Uncomment following lines to enable 63 | # - os: linux 64 | # sudo: required 65 | # dist: trusty 66 | # env: TARGET="linuxarmv6l" OF_BRANCH="master" 67 | 68 | 69 | # Linux ARM6, OF stable: Not supported yet 70 | # - os: linux 71 | # sudo: required 72 | # dist: trusty 73 | # env: TARGET="linuxarmv6l" OF_BRANCH="stable" 74 | 75 | # Linux ARM7, OF master: Uncomment following lines to enable 76 | # - os: linux 77 | # sudo: false 78 | # env: TARGET="linuxarmv7l" OF_BRANCH="master" 79 | # cache: 80 | # directories: 81 | # - ~/rpi2_toolchain 82 | # - ~/firmware-master 83 | # - ~/archlinux 84 | 85 | # Linux ARM7, OF stable: Not supported yet 86 | # - os: linux 87 | # sudo: false 88 | # env: TARGET="linuxarmv7l" OF_BRANCH="stable" 89 | # cache: 90 | # directories: 91 | # - ~/rpi2_toolchain 92 | # - ~/firmware-master 93 | # - ~/archlinux 94 | 95 | 96 | # Emscripten, OF master: Uncomment following lines to enable 97 | # - os: linux 98 | # sudo: false 99 | # env: TARGET="emscripten" OF_BRANCH="master" 100 | # addons: 101 | # apt: 102 | # sources: 103 | # - ubuntu-toolchain-r-test 104 | # packages: 105 | # - libstdc++6 106 | 107 | 108 | # Emscripten, OF stable: Not supported yet 109 | # - os: linux 110 | # sudo: false 111 | # env: TARGET="emscripten" OF_BRANCH="stable" 112 | # addons: 113 | # apt: 114 | # sources: 115 | # - ubuntu-toolchain-r-test 116 | # packages: 117 | # - libstdc++6 118 | 119 | 120 | # iOS, OF master: Not supported yet 121 | # - os: osx 122 | # osx_image: xcode8 123 | # compiler: clang 124 | # env: TARGET="ios" OF_BRANCH="master" 125 | 126 | 127 | # iOS, OF stable: Not supported yet 128 | # - os: osx 129 | # osx_image: xcode8 130 | # compiler: clang 131 | # env: TARGET="ios" OF_BRANCH="stable" 132 | 133 | 134 | # tvOS, OF master: Not supported yet 135 | # - os: osx 136 | # osx_image: xcode8 137 | # compiler: clang 138 | # env: TARGET="tvos" OF_BRANCH="master" 139 | 140 | 141 | # tvOS, OF stable: Not supported yet 142 | # - os: osx 143 | # osx_image: xcode8 144 | # compiler: clang 145 | # env: TARGET="tvos" OF_BRANCH="stable" 146 | 147 | 148 | # Android armv7, OF master: Uncomment following lines to enable 149 | # - os: linux 150 | # sudo: false 151 | # env: TARGET="android" OPT="armv7" OF_BRANCH="master" 152 | # cache: 153 | # directories: 154 | # - ~/android-ndk-r12b 155 | 156 | 157 | # Android armv7, OF stable: Not supported yet 158 | # - os: linux 159 | # sudo: false 160 | # env: TARGET="android" OPT="armv7" OF_BRANCH="stable" 161 | # cache: 162 | # directories: 163 | # - ~/android-ndk-r12b 164 | 165 | 166 | # Android x86, OF master: Uncomment following lines to enable 167 | # - os: linux 168 | # sudo: false 169 | # env: TARGET="android" OPT="x86" OF_BRANCH="master" 170 | # cache: 171 | # directories: 172 | # - ~/android-ndk-r12b 173 | 174 | 175 | # Android x86, OF stable: Not supported yet 176 | # - os: linux 177 | # sudo: false 178 | # env: TARGET="android" OPT="x86" OF_BRANCH="stable" 179 | # cache: 180 | # directories: 181 | # - ~/android-ndk-r12b 182 | 183 | 184 | # Exclude the default build that would otherwise be generated 185 | # see https://github.com/travis-ci/travis-ci/issues/1228 186 | exclude: 187 | - compiler: gcc 188 | 189 | install: 190 | - cd ~ 191 | - git clone --depth=1 --branch=$OF_BRANCH https://github.com/openframeworks/openFrameworks 192 | - cd openFrameworks 193 | - scripts/ci/addons/install.sh 194 | 195 | script: 196 | - scripts/ci/addons/build.sh 197 | 198 | git: 199 | depth: 10 200 | -------------------------------------------------------------------------------- /example/addons.make: -------------------------------------------------------------------------------- 1 | ofxHttpUtils 2 | ofxPoco 3 | -------------------------------------------------------------------------------- /example/bin/data/ofw-logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arturoc/ofxHttpUtils/1c1e44adf6f385861b173cfb2d54f2d415b94e0a/example/bin/data/ofw-logo.gif -------------------------------------------------------------------------------- /example/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup(){ 6 | ofSetVerticalSync(true); 7 | 8 | action_url = "http://localhost/of-test/upload.php"; 9 | ofAddListener(httpUtils.newResponseEvent,this,&ofApp::newResponse); 10 | httpUtils.start(); 11 | 12 | ofBackground(255,255,255); 13 | ofSetColor(0,0,0); 14 | } 15 | 16 | //-------------------------------------------------------------- 17 | void ofApp::update(){ 18 | 19 | } 20 | 21 | //-------------------------------------------------------------- 22 | void ofApp::draw(){ 23 | ofDrawBitmapString(requestStr,20,20); 24 | ofDrawBitmapString(responseStr,20,60); 25 | } 26 | 27 | //-------------------------------------------------------------- 28 | void ofApp::newResponse(ofxHttpResponse & response){ 29 | responseStr = ofToString(response.status) + ": " + (string)response.responseBody; 30 | } 31 | 32 | //-------------------------------------------------------------- 33 | void ofApp::keyPressed (int key){ 34 | ofxHttpForm form; 35 | form.action = action_url; 36 | form.method = OFX_HTTP_POST; 37 | form.addFormField("number", ofToString(counter)); 38 | form.addFile("file","ofw-logo.gif"); 39 | httpUtils.addForm(form); 40 | requestStr = "message sent: " + ofToString(counter); 41 | counter++; 42 | } 43 | 44 | //-------------------------------------------------------------- 45 | void ofApp::mouseMoved(int x, int y ){ 46 | } 47 | 48 | //-------------------------------------------------------------- 49 | void ofApp::mouseDragged(int x, int y, int button){ 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::mousePressed(int x, int y, int button){ 54 | } 55 | 56 | //-------------------------------------------------------------- 57 | void ofApp::mouseReleased(int x, int y, int button){ 58 | 59 | } 60 | 61 | //-------------------------------------------------------------- 62 | void ofApp::windowResized(int w, int h){ 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /example/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | 3 | #include "ofxHttpUtils.h" 4 | 5 | class ofApp : public ofBaseApp{ 6 | 7 | public: 8 | 9 | void setup(); 10 | void update(); 11 | void draw(); 12 | 13 | void keyPressed (int key); 14 | void mouseMoved(int x, int y ); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | 20 | void newResponse(ofxHttpResponse & response); 21 | 22 | ofxHttpUtils httpUtils; 23 | int counter; 24 | string responseStr; 25 | string requestStr; 26 | string action_url; 27 | 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /example/upload.php: -------------------------------------------------------------------------------- 1 | 0) 3 | { 4 | echo "Error: " . $_FILES["file"]["error"] . "
"; 5 | } 6 | else 7 | { 8 | echo "Upload: " . $_FILES["file"]["name"] . "
"; 9 | echo "Type: " . $_FILES["file"]["type"] . "
"; 10 | echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb
"; 11 | echo "Stored in: " . $_FILES["file"]["tmp_name"]; 12 | } 13 | ?> -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | arturoc/ofxHttpUtils @ GitHub 9 | 10 | 33 | 34 | 35 | 36 | 37 | Fork me on GitHub 38 | 39 |
40 | 41 |
42 | 43 | 44 | 45 | 46 |
47 | 48 |

ofxHttpUtils 49 | by arturoc

50 | 51 |
52 | http access openframeworks addon 53 |
54 | 55 |

Contact

56 |

arturo (arturo@openframeworks.cc)

57 | 58 | 59 |

Download

60 |

61 | You can download this project in either 62 | zip or 63 | tar formats. 64 |

65 |

You can also clone the project with Git 66 | by running: 67 |

$ git clone git://github.com/arturoc/ofxHttpUtils
68 |

69 | 70 | 73 | 74 |
75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/ofxHttpTypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | ofxHttpUtils v0.3 3 | Chris O'Shea, Arturo, Jesus, CJ 4 | 5 | Modified: 16th March 2009 6 | openFrameworks 0.06 7 | 8 | */ 9 | #ifndef OFX_HTTP_TYPES 10 | #define OFX_HTTP_TYPES 11 | 12 | 13 | #define OFX_HTTP_GET 0 14 | #define OFX_HTTP_POST 1 15 | 16 | #include "ofUtils.h" 17 | 18 | struct ofxHttpForm{ 19 | 20 | 21 | int method; 22 | std::string action; 23 | std::string name; 24 | 25 | ofxHttpForm(){ 26 | method = OFX_HTTP_GET; 27 | expectBinaryResponse = false; 28 | } 29 | ~ofxHttpForm(){ 30 | clearFormFields(); 31 | } 32 | 33 | void addHeaderField(std::string id, std::string value) { 34 | headerIds.push_back(id); 35 | headerValues.push_back(value); 36 | } 37 | 38 | // ---------------------------------------------------------------------- 39 | void addFormField(std::string id, std::string value){ 40 | formIds.push_back( id ); 41 | formValues.push_back( value ); 42 | } 43 | // ---------------------------------------------------------------------- 44 | void clearFormFields(){ 45 | formIds.clear(); 46 | formValues.clear(); 47 | formFiles.clear(); 48 | } 49 | // ---------------------------------------------------------------------- 50 | void addFile(std::string fieldName, const std::filesystem::path & path){ 51 | formFiles[fieldName] = ofToDataPath(path); 52 | } 53 | 54 | std::string getFieldValue(std::string id){ 55 | for(unsigned int i=0;i formIds; 62 | std::vector formValues; 63 | std::vector headerIds; 64 | std::vector headerValues; 65 | std::map formFiles; 66 | bool expectBinaryResponse; 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/ofxHttpUtils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ofxHttpUtils v0.3 3 | Chris O'Shea, Arturo, Jesus, CJ 4 | 5 | Modified: 16th March 2009 6 | openFrameworks 0.06 7 | 8 | */ 9 | 10 | #undef verify 11 | 12 | #include "Poco/Net/SSLManager.h" 13 | #include "Poco/Net/HTTPSClientSession.h" 14 | #include "Poco/Net/ConsoleCertificateHandler.h" 15 | #include "Poco/Net/FilePartSource.h" 16 | #include "Poco/Net/StringPartSource.h" 17 | #include "Poco/Net/KeyConsoleHandler.h" 18 | #include "Poco/Net/HTTPSession.h" 19 | #include "Poco/Net/HTTPClientSession.h" 20 | #include "Poco/Net/HTTPRequest.h" 21 | #include "Poco/Net/HTMLForm.h" 22 | #include "Poco/StreamCopier.h" 23 | #include "Poco/Path.h" 24 | #include "Poco/URI.h" 25 | #include "Poco/Exception.h" 26 | 27 | #include "ofxHttpUtils.h" 28 | #include "ofEvents.h" 29 | #include "ofLog.h" 30 | #include "ofTypes.h" 31 | 32 | using namespace std; 33 | using namespace Poco; 34 | using namespace Poco::Net; 35 | 36 | bool ofxHttpUtils::initialized = false; 37 | 38 | // ---------------------------------------------------------------------- 39 | ofxHttpUtils::ofxHttpUtils(){ 40 | timeoutSeconds = 2; 41 | maxRetries = -1; // -1 means an infinite number of retries 42 | nbOfTries = 0; 43 | verbose = true; 44 | sendCookies = true; 45 | //start(); 46 | 47 | if(!initialized){ 48 | SharedPtr pConsoleHandler = new KeyConsoleHandler(false); 49 | SharedPtr pInvalidCertHandler = new ConsoleCertificateHandler(true); 50 | Context::Ptr pContext = new Context(Context::CLIENT_USE, "", Context::VERIFY_NONE); 51 | SSLManager::instance().initializeClient(pConsoleHandler, pInvalidCertHandler, pContext); 52 | initialized = true; 53 | } 54 | } 55 | 56 | // ---------------------------------------------------------------------- 57 | ofxHttpUtils::~ofxHttpUtils(){ 58 | } 59 | 60 | // ---------------------------------------------------------------------- 61 | ofxHttpResponse ofxHttpUtils::submitForm(ofxHttpForm form){ 62 | return doPostForm(form); 63 | } 64 | 65 | // ---------------------------------------------------------------------- 66 | void ofxHttpUtils::addForm(ofxHttpForm form){ 67 | lock(); 68 | forms.push(form); 69 | condition.signal(); 70 | unlock(); 71 | } 72 | 73 | // ---------------------------------------------------------------------- 74 | void ofxHttpUtils::start() { 75 | startThread(); 76 | } 77 | 78 | // ---------------------------------------------------------------------- 79 | void ofxHttpUtils::stop() { 80 | stopThread(); 81 | condition.signal(); 82 | } 83 | 84 | // ---------------------------------------------------------------------- 85 | void ofxHttpUtils::threadedFunction(){ 86 | lock(); 87 | while( isThreadRunning() ){ 88 | if(forms.size()>0){ 89 | ofxHttpForm form = forms.front(); 90 | ofxHttpResponse response; 91 | unlock(); 92 | if(form.method==OFX_HTTP_POST){ 93 | response = doPostForm(form); 94 | ofLogVerbose("ofxHttpUtils") << "(thread running) form submitted (post): " << form.name; 95 | }else{ 96 | string url = generateUrl(form); 97 | ofLogVerbose("ofxHttpUtils") << "form submitted (get):" << form.name; 98 | response = getUrl(url); 99 | } 100 | lock(); 101 | if(response.status!=-1) { 102 | nbOfTries = 0; 103 | forms.pop(); 104 | } 105 | else if (maxRetries >= 0) { 106 | nbOfTries++; 107 | ofLogWarning("ofxHttpUtils") << "The resquest did not succeed. We will try again " << maxRetries - nbOfTries << " time(s)"; 108 | if (nbOfTries >= maxRetries) { 109 | ofLogError("ofxHttpUtils") << "We pop that resquest. Too much retries -- " << form.action.c_str(); 110 | nbOfTries = 0; 111 | forms.pop(); 112 | } 113 | } 114 | 115 | } 116 | if(forms.empty()){ 117 | ofLogVerbose("ofxHttpUtils") << "empty, waiting"; 118 | condition.wait(mutex); 119 | } 120 | } 121 | unlock(); 122 | ofLogVerbose("ofxHttpUtils") << "thread finished"; 123 | } 124 | 125 | // ---------------------------------------------------------------------- 126 | int ofxHttpUtils::getQueueLength(){ 127 | Poco::ScopedLock lock(mutex); 128 | return forms.size(); 129 | } 130 | 131 | // ---------------------------------------------------------------------- 132 | void ofxHttpUtils::clearQueue(){ 133 | Poco::ScopedLock lock(mutex); 134 | while(!forms.empty()) forms.pop(); 135 | } 136 | 137 | // ---------------------------------------------------------------------- 138 | string ofxHttpUtils::generateUrl(ofxHttpForm & form) { 139 | // url to send to 140 | string url = form.action; 141 | 142 | // do we have any form fields? 143 | int numfields = form.formIds.size(); 144 | if(numfields > 0){ 145 | url += "?"; 146 | for(int i=0;i session; 183 | istream * rs; 184 | if(uri.getScheme()=="https"){ 185 | HTTPSClientSession * httpsSession = new HTTPSClientSession(uri.getHost(), uri.getPort());//,context); 186 | httpsSession->setTimeout(Poco::Timespan(20,0)); 187 | httpsSession->sendRequest(req) << data; 188 | rs = &httpsSession->receiveResponse(res); 189 | session = ofPtr(httpsSession); 190 | }else{ 191 | HTTPClientSession * httpSession = new HTTPClientSession(uri.getHost(), uri.getPort()); 192 | httpSession->setTimeout(Poco::Timespan(20,0)); 193 | httpSession->sendRequest(req) << data; 194 | rs = &httpSession->receiveResponse(res); 195 | session = ofPtr(httpSession); 196 | } 197 | 198 | response = ofxHttpResponse(res, *rs, url); 199 | 200 | if(sendCookies){ 201 | cookies.insert(cookies.begin(),response.cookies.begin(),response.cookies.end()); 202 | } 203 | 204 | if(response.status>=300 && response.status<400){ 205 | Poco::URI uri(req.getURI()); 206 | uri.resolve(res.get("Location")); 207 | response.location = uri.toString(); 208 | } 209 | 210 | ofNotifyEvent(newResponseEvent, response, this); 211 | }catch (Exception& exc){ 212 | 213 | ofLogError("ofxHttpUtils") << "ofxHttpUtils error postData --"; 214 | 215 | //ofNotifyEvent(notifyNewError, "time out", this); 216 | 217 | // for now print error, need to broadcast a response 218 | ofLogError("ofxHttpUtils") << exc.displayText(); 219 | response.status = -1; 220 | response.reasonForStatus = exc.displayText(); 221 | ofNotifyEvent(newResponseEvent, response, this); 222 | 223 | } 224 | return response; 225 | } 226 | 227 | // ---------------------------------------------------------------------- 228 | ofxHttpResponse ofxHttpUtils::doPostForm(ofxHttpForm & form){ 229 | ofxHttpResponse response; 230 | 231 | try{ 232 | URI uri( form.action.c_str() ); 233 | std::string path(uri.getPathAndQuery()); 234 | if (path.empty()) path = "/"; 235 | 236 | //HTTPClientSession session(uri.getHost(), uri.getPort()); 237 | HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1); 238 | if(auth.getUsername()!="") auth.authenticate(req); 239 | 240 | if(sendCookies){ 241 | for(unsigned i=0; i0) { 259 | pocoForm.setEncoding(HTMLForm::ENCODING_MULTIPART); 260 | } 261 | else { 262 | pocoForm.setEncoding(HTMLForm::ENCODING_URL); 263 | } 264 | 265 | // form values 266 | for(unsigned i=0; i::iterator it; 273 | for(it = form.formFiles.begin(); it!=form.formFiles.end(); it++){ 274 | string fileName = it->second.substr(it->second.find_last_of('/')+1); 275 | ofLogVerbose("ofxHttpUtils") << "adding file: " << fileName << " path: " << it->second; 276 | pocoForm.addPart(it->first,new FilePartSource(it->second)); 277 | } 278 | 279 | pocoForm.prepareSubmit(req); 280 | 281 | ofPtr session; 282 | istream * rs; 283 | if(uri.getScheme()=="https"){ 284 | HTTPSClientSession * httpsSession = new HTTPSClientSession(uri.getHost(), uri.getPort());//,context); 285 | httpsSession->setTimeout(Poco::Timespan(20,0)); 286 | pocoForm.write(httpsSession->sendRequest(req)); 287 | rs = &httpsSession->receiveResponse(res); 288 | session = ofPtr(httpsSession); 289 | }else{ 290 | HTTPClientSession * httpSession = new HTTPClientSession(uri.getHost(), uri.getPort()); 291 | httpSession->setTimeout(Poco::Timespan(20,0)); 292 | pocoForm.write(httpSession->sendRequest(req)); 293 | rs = &httpSession->receiveResponse(res); 294 | session = ofPtr(httpSession); 295 | } 296 | 297 | response = ofxHttpResponse(res, *rs, form.action); 298 | 299 | if(sendCookies){ 300 | cookies.insert(cookies.begin(),response.cookies.begin(),response.cookies.end()); 301 | } 302 | 303 | if(response.status>=300 && response.status<400){ 304 | Poco::URI uri(req.getURI()); 305 | uri.resolve(res.get("Location")); 306 | response.location = uri.toString(); 307 | } 308 | 309 | ofNotifyEvent(newResponseEvent, response, this); 310 | 311 | 312 | }catch (Exception& exc){ 313 | ofLogError("ofxHttpUtils") << "ofxHttpUtils error doPostForm -- " << form.action.c_str(); 314 | 315 | //ofNotifyEvent(notifyNewError, "time out", this); 316 | 317 | // for now print error, need to broadcast a response 318 | ofLogError("ofxHttpUtils") << exc.displayText(); 319 | response.status = -1; 320 | response.reasonForStatus = exc.displayText(); 321 | ofNotifyEvent(newResponseEvent, response, this); 322 | 323 | } 324 | 325 | return response; 326 | } 327 | 328 | // ---------------------------------------------------------------------- 329 | ofxHttpResponse ofxHttpUtils::getUrl(string url){ 330 | 331 | ofxHttpResponse response; 332 | try{ 333 | URI uri(url.c_str()); 334 | std::string path(uri.getPathAndQuery()); 335 | if (path.empty()) path = "/"; 336 | 337 | HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); 338 | 339 | if(auth.getUsername()!="") auth.authenticate(req); 340 | 341 | if(sendCookies){ 342 | for(unsigned i=0; i session; 351 | istream * rs; 352 | if(uri.getScheme()=="https"){ 353 | HTTPSClientSession * httpsSession = new HTTPSClientSession(uri.getHost(), uri.getPort());//,context); 354 | httpsSession->setTimeout(Poco::Timespan(timeoutSeconds,0)); 355 | httpsSession->sendRequest(req); 356 | rs = &httpsSession->receiveResponse(res); 357 | session = ofPtr(httpsSession); 358 | }else{ 359 | HTTPClientSession * httpSession = new HTTPClientSession(uri.getHost(), uri.getPort()); 360 | httpSession->setTimeout(Poco::Timespan(timeoutSeconds,0)); 361 | httpSession->sendRequest(req); 362 | rs = &httpSession->receiveResponse(res); 363 | session = ofPtr(httpSession); 364 | } 365 | 366 | response=ofxHttpResponse(res, *rs, url); 367 | 368 | if(sendCookies){ 369 | cookies.insert(cookies.begin(),response.cookies.begin(),response.cookies.end()); 370 | } 371 | 372 | if(response.status>=300 && response.status<400){ 373 | Poco::URI uri(req.getURI()); 374 | uri.resolve(res.get("Location")); 375 | response.location = uri.toString(); 376 | } 377 | 378 | ofNotifyEvent( newResponseEvent, response, this ); 379 | 380 | //std::cout << res.getStatus() << " " << res.getReason() << std::endl; 381 | //StreamCopier::copyStream(rs, std::cout); 382 | 383 | }catch (Exception& exc){ 384 | ofLogError("ofxHttpUtils") << exc.displayText(); 385 | response.status = -1; 386 | response.reasonForStatus = exc.displayText(); 387 | ofNotifyEvent(newResponseEvent, response, this); 388 | } 389 | return response; 390 | 391 | } 392 | 393 | // ---------------------------------------------------------------------- 394 | void ofxHttpUtils::addUrl(string url){ 395 | ofxHttpForm form; 396 | form.action=url; 397 | form.method=OFX_HTTP_GET; 398 | form.name=form.action; 399 | 400 | addForm(form); 401 | } 402 | 403 | // ---------------------------------------------------------------------- 404 | void ofxHttpUtils::sendReceivedCookies(){ 405 | sendCookies = true; 406 | } 407 | 408 | // ---------------------------------------------------------------------- 409 | void ofxHttpUtils::setBasicAuthentication(string user, string password){ 410 | auth.setUsername(user); 411 | auth.setPassword(password); 412 | } 413 | 414 | -------------------------------------------------------------------------------- /src/ofxHttpUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | ofxHttpUtils v0.3 3 | Chris O'Shea, Arturo, Jesus, CJ 4 | 5 | Modified: 16th March 2009 6 | openFrameworks 0.06 7 | 8 | */ 9 | 10 | #ifndef _OFX_HTTP_UTILS 11 | #define _OFX_HTTP_UTILS 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "Poco/Mutex.h" 19 | #include "Poco/Net/HTTPResponse.h" 20 | #include "Poco/Condition.h" 21 | #include "Poco/Net/HTTPBasicCredentials.h" 22 | 23 | #include "ofThread.h" 24 | #include "ofConstants.h" 25 | #include "ofxHttpTypes.h" 26 | #include "ofEvents.h" 27 | #include "ofFileUtils.h" 28 | 29 | class ofxHttpListener; 30 | class ofxHttpEventManager; 31 | 32 | struct ofxHttpResponse{ 33 | ofxHttpResponse(Poco::Net::HTTPResponse& pocoResponse, std::istream &bodyStream, std::string turl, bool binary=false){ 34 | status=pocoResponse.getStatus(); 35 | try{ 36 | timestamp=pocoResponse.getDate(); 37 | }catch(Poco::Exception & exc){ 38 | 39 | } 40 | reasonForStatus=pocoResponse.getReasonForStatus(pocoResponse.getStatus()); 41 | contentType = pocoResponse.getContentType(); 42 | responseBody.set(bodyStream); 43 | 44 | url = turl; 45 | pocoResponse.getCookies(cookies); 46 | } 47 | 48 | ofxHttpResponse(){} 49 | 50 | std::string getURLFilename(){ 51 | return url.substr(url.rfind('/')+1); 52 | } 53 | 54 | int status; // return code for the response ie: 200 = OK 55 | std::string reasonForStatus; // text explaining the status 56 | ofBuffer responseBody; // the actual response 57 | std::string contentType; // the mime type of the response 58 | Poco::Timestamp timestamp; // time of the response 59 | std::string url; 60 | std::vector cookies; 61 | std::string location; 62 | }; 63 | 64 | class ofxHttpUtils : public ofThread{ 65 | 66 | public: 67 | 68 | ofxHttpUtils(); 69 | ~ofxHttpUtils(); 70 | //------------------------------- 71 | // non blocking functions 72 | 73 | void addForm(ofxHttpForm form); 74 | void addUrl(std::string url); 75 | 76 | //------------------------------- 77 | // blocking functions 78 | ofxHttpResponse submitForm(ofxHttpForm form); 79 | ofxHttpResponse getUrl(std::string url); 80 | ofxHttpResponse postData(std::string url, const ofBuffer & data, std::string contentType=""); 81 | 82 | int getQueueLength(); 83 | void clearQueue(); 84 | 85 | //------------------------------- 86 | // threading stuff 87 | void threadedFunction(); 88 | 89 | //------------------------------ 90 | // events 91 | ofEvent newResponseEvent; 92 | 93 | // other stuff------------------- 94 | void setTimeoutSeconds(int t){ 95 | timeoutSeconds = t; 96 | } 97 | void setMaxRetries(int val){ // -1 means an infinite number of retries 98 | maxRetries = val; 99 | } 100 | void setVerbose(bool v){ 101 | verbose = v; 102 | } 103 | 104 | void sendReceivedCookies(); 105 | 106 | void setBasicAuthentication(std::string user, std::string password); 107 | 108 | 109 | void start(); 110 | void stop(); 111 | 112 | protected: 113 | 114 | bool verbose; 115 | int timeoutSeconds; 116 | int maxRetries; 117 | bool sendCookies; 118 | 119 | int nbOfTries; 120 | 121 | //-------------------------------- 122 | // http utils 123 | std::string generateUrl(ofxHttpForm & form); 124 | ofxHttpResponse doPostForm(ofxHttpForm & form); 125 | 126 | std::queue forms; 127 | std::vector cookies; 128 | Poco::Net::HTTPBasicCredentials auth; 129 | Poco::Condition condition; 130 | 131 | static bool initialized; 132 | 133 | }; 134 | #endif 135 | --------------------------------------------------------------------------------