├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE │ ├── bug_fix.md │ ├── documentation.md │ ├── feature_change.md │ └── performance_improvement.md └── workflows │ ├── codeql-analysis.yml │ └── verify-build.yml ├── .gitignore ├── .gitmodules ├── AUTHORS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── COPYING.LESSER ├── CPPLINT.cfg ├── ChangeLog ├── INSTALL ├── LICENSE ├── Makefile.am ├── Makefile.cvs ├── NEWS ├── PULL_REQUEST_TEMPLATE.md ├── README.CentOS-7 ├── README.FreeBSD ├── README.md ├── acinclude.m4 ├── aminclude.am ├── appveyor.yml ├── bootstrap ├── ci-report-coverage ├── cmakemodule └── FindLibHttpServer.cmake ├── codecov.yml ├── configure.ac ├── custom_iwyu.imp ├── doc ├── Makefile.am └── libhttpserver.3 ├── doxyconfig.in ├── examples ├── Makefile.am ├── README.md ├── allowing_disallowing_methods.cpp ├── basic_authentication.cpp ├── benchmark_nodelay.cpp ├── benchmark_select.cpp ├── benchmark_threads.cpp ├── cert.pem ├── custom_access_log.cpp ├── custom_error.cpp ├── deferred_with_accumulator.cpp ├── digest_authentication.cpp ├── file_upload.cpp ├── handlers.cpp ├── hello_with_get_arg.cpp ├── hello_world.cpp ├── key.pem ├── minimal_deferred.cpp ├── minimal_file_response.cpp ├── minimal_hello_world.cpp ├── minimal_https.cpp ├── minimal_ip_ban.cpp ├── service.cpp ├── setting_headers.cpp ├── test_content └── url_registration.cpp ├── libhttpserver.pc.in ├── m4 ├── ax_cxx_compile_stdcxx.m4 ├── ax_have_epoll.m4 ├── ax_valgrind_check.m4 └── python.m4 ├── msan_ignorelist.txt ├── src ├── Makefile.am ├── basic_auth_fail_response.cpp ├── deferred_response.cpp ├── details │ └── http_endpoint.cpp ├── digest_auth_fail_response.cpp ├── file_info.cpp ├── file_response.cpp ├── gettext.h ├── http_request.cpp ├── http_resource.cpp ├── http_response.cpp ├── http_utils.cpp ├── httpserver.hpp ├── httpserver │ ├── basic_auth_fail_response.hpp │ ├── create_webserver.hpp │ ├── deferred_response.hpp │ ├── details │ │ ├── http_endpoint.hpp │ │ └── modded_request.hpp │ ├── digest_auth_fail_response.hpp │ ├── file_info.hpp │ ├── file_response.hpp │ ├── http_arg_value.hpp │ ├── http_request.hpp │ ├── http_resource.hpp │ ├── http_response.hpp │ ├── http_utils.hpp │ ├── string_response.hpp │ ├── string_utilities.hpp │ └── webserver.hpp ├── string_response.cpp ├── string_utilities.cpp └── webserver.cpp └── test ├── CPPLINT.cfg ├── Makefile.am ├── cert.pem ├── integ ├── authentication.cpp ├── ban_system.cpp ├── basic.cpp ├── deferred.cpp ├── file_upload.cpp ├── nodelay.cpp ├── threaded.cpp └── ws_start_stop.cpp ├── key.pem ├── libhttpserver.supp ├── littletest.hpp ├── test_content ├── test_content_2 ├── test_content_empty ├── test_content_large ├── test_root_ca.pem └── unit ├── http_endpoint_test.cpp ├── http_resource_test.cpp ├── http_utils_test.cpp └── string_utilities_test.cpp /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] Title" 5 | labels: bug 6 | assignees: etr 7 | 8 | --- 9 | 10 | 17 | 18 | ### Prerequisites 19 | 20 | * [ ] Put an X between the brackets on this line if you have checked that your issue isn't already filed: https://github.com/search?l=&q=repo%3Aetr%2Flibhttpserver&type=Issues 21 | 22 | ### Description 23 | 24 | [Description of the issue] 25 | 26 | ### Steps to Reproduce 27 | 28 | 1. [First Step] 29 | 2. [Second Step] 30 | 3. [and so on...] 31 | 32 | **Expected behavior:** [What you expect to happen] 33 | 34 | **Actual behavior:** [What actually happens] 35 | 36 | **Reproduces how often:** [What percentage of the time does it reproduce?] 37 | 38 | ### Versions 39 | 40 | * OS version (if on linux, the output of "uname -a") 41 | * libhttpserver version (please specify whether compiled or packaged) 42 | * libmicrohttpd version (please specify whether compiled or packaged) 43 | 44 | If you have problems during build: 45 | * Compiler version 46 | * autotools version 47 | 48 | ### Additional Information 49 | 50 | Any additional information, configuration (especially build configuration flags if you compiled the libraries) or data that might be necessary to reproduce the issue. 51 | 52 | If you have problems during build, please attach your config.log and the full scope of your error from make. 53 | 54 | If you have problems at execution, please: 55 | * attach the stacktrace in case of crash (a coredump would be even better). 56 | * provide a main that reproduces the error. 57 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature-request 6 | assignees: etr 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe why the feature or enhancement you are proposing fits the library.** 14 | A clear and concise explanation of the reason it fits into the library's mission. 15 | 16 | **Describe the solution you'd like** 17 | A clear and concise description of what you want to happen. 18 | 19 | **Describe alternatives you've considered** 20 | A clear and concise description of any alternative solutions or features you've considered. 21 | 22 | **Additional context** 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/bug_fix.md: -------------------------------------------------------------------------------- 1 | ### Requirements for Contributing a Bug Fix 2 | 3 | * Fill out the template below. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. 4 | * The pull request must only fix an existing bug. To contribute other changes, you must use a different template. You can see all templates at https://github.com/etr/libhttpserver/tree/master/.github/PULL_REQUEST_TEMPLATE. 5 | * The pull request must update the test suite to demonstrate the changed functionality. 6 | * After you create the pull request, all status checks must be pass before a maintainer reviews your contribution. For more details, please see https://github.com/etr/libhttpserver/tree/master/CONTRIBUTING.md#pull-requests. 7 | 8 | ### Identify the Bug 9 | 10 | 18 | 19 | ### Description of the Change 20 | 21 | 26 | 27 | ### Alternate Designs 28 | 29 | 30 | 31 | ### Possible Drawbacks 32 | 33 | 34 | 35 | ### Verification Process 36 | 37 | 42 | 43 | ### Release Notes 44 | 45 | 60 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | ### Requirements for Contributing Documentation 2 | 3 | * Fill out the template below. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. 4 | * The pull request must only contribute documentation (for example, markdown files or API docs). To contribute other changes, you must use a different template. You can see all templates at https://github.com/etr/libhttpserver/tree/master/.github/PULL_REQUEST_TEMPLATE. 5 | 6 | ### Description of the Change 7 | 8 | 13 | 14 | ### Release Notes 15 | 16 | 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/feature_change.md: -------------------------------------------------------------------------------- 1 | ### Requirements for Adding, Changing, or Removing a Feature 2 | 3 | * Fill out the template below. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. 4 | * The pull request must contribute a change that has been endorsed by the maintainer team. See details in the template below. 5 | * The pull request must update the test suite to exercise the updated functionality. 6 | * After you create the pull request, all status checks must be pass before a maintainer reviews your contribution. For more details, please see https://github.com/etr/libhttpserver/tree/master/CONTRIBUTING.md#pull-requests. 7 | 8 | ### Issue or RFC Endorsed by Maintainers 9 | 10 | 15 | 16 | ### Description of the Change 17 | 18 | 23 | 24 | ### Alternate Designs 25 | 26 | 27 | 28 | ### Possible Drawbacks 29 | 30 | 31 | 32 | ### Verification Process 33 | 34 | 45 | 46 | ### Release Notes 47 | 48 | 63 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/performance_improvement.md: -------------------------------------------------------------------------------- 1 | ### Requirements for Contributing a Performance Improvement 2 | 3 | * Fill out the template below. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. 4 | * The pull request must only affect performance of existing functionality. To contribute other changes, you must use a different template. You can see all templates at https://github.com/etr/libhttpserver/tree/master/.github/PULL_REQUEST_TEMPLATE. 5 | * After you create the pull request, all status checks must be pass before a maintainer reviews your contribution. For more details, please see https://github.com/etr/libhttpserver/tree/master/CONTRIBUTING.md#pull-requests. 6 | 7 | ### Description of the Change 8 | 9 | 14 | 15 | ### Quantitative Performance Benefits 16 | 17 | 22 | 23 | ### Possible Drawbacks 24 | 25 | 26 | 27 | ### Verification Process 28 | 29 | 34 | 35 | ### Applicable Issues 36 | 37 | 38 | 39 | ### Release Notes 40 | 41 | 56 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [master] 9 | schedule: 10 | - cron: '0 4 * * 4' 11 | 12 | jobs: 13 | analyze: 14 | name: Analyze 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | # Override automatic language detection by changing the below list 21 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 22 | language: ['cpp'] 23 | # Learn more... 24 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 25 | 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v2 29 | with: 30 | # We must fetch at least the immediate parents so that if this is 31 | # a pull request then we can checkout the head. 32 | fetch-depth: 2 33 | 34 | # If this run was triggered by a pull request event, then checkout 35 | # the head of the pull request instead of the merge commit. 36 | - run: git checkout HEAD^2 37 | if: ${{ github.event_name == 'pull_request' }} 38 | 39 | - name: Install libmicrohttpd dependency 40 | run: | 41 | curl https://s3.amazonaws.com/libhttpserver/libmicrohttpd_releases/libmicrohttpd-0.9.64.tar.gz -o libmicrohttpd-0.9.64.tar.gz ; 42 | tar -xzf libmicrohttpd-0.9.64.tar.gz ; 43 | cd libmicrohttpd-0.9.64 ; 44 | ./configure --disable-examples ; 45 | make ; 46 | sudo make install ; 47 | 48 | # Initializes the CodeQL tools for scanning. 49 | - name: Initialize CodeQL 50 | uses: github/codeql-action/init@v1 51 | with: 52 | languages: ${{ matrix.language }} 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | #- name: Autobuild 57 | # uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | - name: Manual steps to build the library 67 | run: | 68 | ./bootstrap ; 69 | ./configure --enable-same-directory-build; 70 | make ; 71 | 72 | - name: Perform CodeQL Analysis 73 | uses: github/codeql-action/analyze@v1 74 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sw* 2 | *.*~ 3 | *.in 4 | *.php 5 | *.pm 6 | *.py 7 | *_wrap.* 8 | *.gcov 9 | *.gcno 10 | *.gcda 11 | *.o 12 | *.lo 13 | *.la 14 | .idea 15 | libhttpserver.iml 16 | build/* 17 | aclocal.m4 18 | autom4te.cache/ 19 | config.guess 20 | config.sub 21 | configure 22 | depcomp 23 | install-sh 24 | ltmain.sh 25 | m4/libtool.m4 26 | m4/ltoptions.m4 27 | m4/ltsugar.m4 28 | m4/ltversion.m4 29 | m4/lt~obsolete.m4 30 | missing 31 | src/core 32 | src/http_request_builder.cpp 33 | src/httpserver/core 34 | src/httpserver/http_request_builder.hpp 35 | src/.deps/ 36 | src/.libs/ 37 | test/Test 38 | test/core 39 | test/err 40 | test/test.txt 41 | Makefile 42 | src/Makefile 43 | stamp-h1 44 | test-driver 45 | test/.deps/ 46 | test/Makefile 47 | compile 48 | config.h 49 | config.log 50 | config.status 51 | debian/changelog 52 | debian/control 53 | debian/copyright 54 | debian/libhttpserver-dev.install 55 | debian/libhttpserver.install 56 | debian/rules 57 | redhat/libhttpserver.SPEC 58 | libhttpserver.pc 59 | libtool 60 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etr/libhttpserver/1b5fe8fb1389f6f9707b7b89c988ef37213b76b6/.gitmodules -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | - Primary developer: 2 | Sebastiano Merlino (maintainer) 3 | 4 | - Code contributions also came from: 5 | Dario Mazza 6 | Andrea Nicotra 7 | Jeff Waller 8 | Craig Minihan 9 | Guo Xiao 10 | Philipp Claßen 11 | Vitaut Bajaryn 12 | Felipe Zipitría 13 | Steven 'Steve' Kendall 14 | G. Mercat 15 | Thomas Schätzlein 16 | Matt van Niekerk 17 | Jim Phillips (https://github.com/jcphill) 18 | Ilya Brin (https://github.com/ilyabrin) 19 | 20 | - Support for building on MinGW/Cygwin systems 21 | Shane Peelar 22 | Dean M. Sands, III 23 | 24 | - Support for building on MaxOsX 25 | Jan Klimke 26 | 27 | - Example of SSL usage and operator<< on http_request and http_response 28 | Chris Love 29 | 30 | - Added proper error handling to tcp socket creation and binding 31 | Marcel Pursche 32 | 33 | - Fixed error management and regex handling 34 | Julian Picht 35 | 36 | - Fix string termination when loading files in memory 37 | martamoreton (Github: https://github.com/martamoreton) 38 | 39 | - Memory leaks 40 | rdiazmartin 41 | 42 | - Cleanup of multiple parts of the code. Improved testing. Fixed issues with family urls. 43 | bcsgh (Github: https://github.com/bcsgh) 44 | 45 | - Management of large uploads 46 | Walter Landry 47 | Jagat 48 | 49 | - Simplification of microhttpd dependency management 50 | Christian Grothoff 51 | 52 | - Fixes to the behavior of "Method Not Allowed" and other cleanups. Fixed the behavior of the server when receiving invalid responses from libmicrohttpd. Fixed the file_response to handle not existing files and directories. 53 | Alexander Dahl 54 | 55 | - General cleanup. Use of string_view. Support for handling of multiple arguments with the same name. 56 | stuart-byma (https://github.com/stuart-byma) 57 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at merlino.sebastiano@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | linelength=200 2 | headers=hpp 3 | extensions=cpp,hpp 4 | filter=-test/littletest.hpp 5 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of libhttpserver 3 | # Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | # not a GNU package. You can remove this line, if 20 | # have all needed files, that a GNU package needs 21 | 22 | LIBTOOL_DEPS = @LIBTOOL_DEPS@ 23 | 24 | AUTOMAKE_OPTIONS = foreign 1.4 25 | ACLOCAL_AMFLAGS = -I m4 26 | 27 | SUBDIRS = src 28 | DIST_SUBDIRS = src 29 | 30 | if !COND_CROSS_COMPILE 31 | SUBDIRS += test 32 | DIST_SUBDIRS += test 33 | 34 | if BUILD_EXAMPLES 35 | SUBDIRS += examples 36 | DIST_SUBDIRS += examples 37 | endif 38 | 39 | endif 40 | 41 | EXTRA_DIST = libhttpserver.pc.in $(DX_CONFIG) 42 | 43 | MOSTLYCLEANFILES = $(DX_CLEANFILES) *.gcda *.gcno *.gcov 44 | DISTCLEANFILES = DIST_REVISION 45 | 46 | pkgconfigdir = $(libdir)/pkgconfig 47 | pkgconfig_DATA = libhttpserver.pc 48 | 49 | cmakemoduledir = $(datadir)/cmake/Modules 50 | cmakemodule_DATA = cmakemodule/FindLibHttpServer.cmake 51 | 52 | include $(top_srcdir)/aminclude.am 53 | 54 | # Update libtool, if needed. 55 | libtool: $(LIBTOOL_DEPS) 56 | $(SHELL) ./config.status --recheck 57 | 58 | dist-hook: 59 | date >DIST_REVISION 60 | git branch -vv >>DIST_REVISION 61 | cp DIST_REVISION $(distdir)/ 62 | -------------------------------------------------------------------------------- /Makefile.cvs: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of libhttpserver 3 | # Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | default: all 20 | 21 | all: 22 | aclocal -I m4 23 | autoheader 24 | libtoolize --automake 25 | automake --add-missing 26 | autoconf 27 | 28 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etr/libhttpserver/1b5fe8fb1389f6f9707b7b89c988ef37213b76b6/NEWS -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Hello there! Welcome. Please follow the steps below to tell us about your contribution. 2 | 3 | 1. Copy the correct template for your contribution 4 | - Are you fixing a bug? Copy the template from https://raw.githubusercontent.com/etr/libhttpserver/master/.github/PULL_REQUEST_TEMPLATE/bug_fix.md 5 | - Are you improving performance? Copy the template https://raw.githubusercontent.com/etr/libhttpserver/master/.github/PULL_REQUEST_TEMPLATE/performance_improvement.md 6 | - Are you updating documentation? Copy the template from https://raw.githubusercontent.com/etr/libhttpserver/master/.github/PULL_REQUEST_TEMPLATE/documentation.md 7 | - Are you changing functionality? Copy the template from https://raw.githubusercontent.com/etr/libhttpserver/master/.github/PULL_REQUEST_TEMPLATE/feature_change.md 8 | 2. Replace this text with the contents of the template 9 | 3. Fill in all sections of the template 10 | 4. Click "Create pull request" 11 | -------------------------------------------------------------------------------- /README.CentOS-7: -------------------------------------------------------------------------------- 1 | ## Cent OS 7 / RHEL 7 2 | 3 | CentOS 7 has a lower version of gcc (4.8.7) that is barely C++11 capable and this library 4 | needs a better compiler. We recommend at least gcc 5+ 5 | 6 | We recommend installing devtoolset-8 7 | https://www.softwarecollections.org/en/scls/rhscl/devtoolset-8/ 8 | -------------------------------------------------------------------------------- /README.FreeBSD: -------------------------------------------------------------------------------- 1 | ## Building on FreeBSD (Tested on 12.0) 2 | 3 | # Due to the differences in the directory structures on BSD systems some minor tweaks need to occur 4 | # Also, FreeBSD and AIX "make" command is not compatible with gmake, like Linux and Mingw are 5 | 6 | export MAKE=gmake 7 | bootstrap 8 | configure CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib 9 | gmake 10 | -------------------------------------------------------------------------------- /aminclude.am: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2004 Oren Ben-Kiki 2 | # This file is distributed under the same terms as the Automake macro files. 3 | 4 | # Generate automatic documentation using Doxygen. Goals and variables values 5 | # are controlled by the various DX_COND_??? conditionals set by autoconf. 6 | # 7 | # The provided goals are: 8 | # doxygen-doc: Generate all doxygen documentation. 9 | # doxygen-run: Run doxygen, which will generate some of the documentation 10 | # (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post 11 | # processing required for the rest of it (PS, PDF, and some MAN). 12 | # doxygen-man: Rename some doxygen generated man pages. 13 | # doxygen-ps: Generate doxygen PostScript documentation. 14 | # doxygen-pdf: Generate doxygen PDF documentation. 15 | # 16 | # Note that by default these are not integrated into the automake goals. If 17 | # doxygen is used to generate man pages, you can achieve this integration by 18 | # setting man3_MANS to the list of man pages generated and then adding the 19 | # dependency: 20 | # 21 | # $(man3_MANS): doxygen-doc 22 | # 23 | # This will cause make to run doxygen and generate all the documentation. 24 | # 25 | # The following variable is intended for use in Makefile.am: 26 | # 27 | # DX_CLEANFILES = everything to clean. 28 | # 29 | # This is usually added to MOSTLYCLEANFILES. 30 | 31 | ## --------------------------------- ## 32 | ## Format-independent Doxygen rules. ## 33 | ## --------------------------------- ## 34 | 35 | if DX_COND_doc 36 | 37 | ## ------------------------------- ## 38 | ## Rules specific for HTML output. ## 39 | ## ------------------------------- ## 40 | 41 | if DX_COND_html 42 | 43 | DX_CLEAN_HTML = @DX_DOCDIR@/html 44 | 45 | endif DX_COND_html 46 | 47 | ## ------------------------------ ## 48 | ## Rules specific for CHM output. ## 49 | ## ------------------------------ ## 50 | 51 | if DX_COND_chm 52 | 53 | DX_CLEAN_CHM = @DX_DOCDIR@/chm 54 | 55 | if DX_COND_chi 56 | 57 | DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi 58 | 59 | endif DX_COND_chi 60 | 61 | endif DX_COND_chm 62 | 63 | ## ------------------------------ ## 64 | ## Rules specific for MAN output. ## 65 | ## ------------------------------ ## 66 | 67 | if DX_COND_man 68 | 69 | DX_CLEAN_MAN = @DX_DOCDIR@/man 70 | 71 | endif DX_COND_man 72 | 73 | ## ------------------------------ ## 74 | ## Rules specific for RTF output. ## 75 | ## ------------------------------ ## 76 | 77 | if DX_COND_rtf 78 | 79 | DX_CLEAN_RTF = @DX_DOCDIR@/rtf 80 | 81 | endif DX_COND_rtf 82 | 83 | ## ------------------------------ ## 84 | ## Rules specific for XML output. ## 85 | ## ------------------------------ ## 86 | 87 | if DX_COND_xml 88 | 89 | DX_CLEAN_XML = @DX_DOCDIR@/xml 90 | 91 | endif DX_COND_xml 92 | 93 | ## ----------------------------- ## 94 | ## Rules specific for PS output. ## 95 | ## ----------------------------- ## 96 | 97 | if DX_COND_ps 98 | 99 | DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps 100 | 101 | DX_PS_GOAL = doxygen-ps 102 | 103 | doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps 104 | 105 | @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag 106 | cd @DX_DOCDIR@/latex; \ 107 | rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ 108 | $(DX_LATEX) refman.tex; \ 109 | $(MAKEINDEX_PATH) refman.idx; \ 110 | $(DX_LATEX) refman.tex; \ 111 | countdown=5; \ 112 | while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ 113 | refman.log > /dev/null 2>&1 \ 114 | && test $$countdown -gt 0; do \ 115 | $(DX_LATEX) refman.tex; \ 116 | countdown=`expr $$countdown - 1`; \ 117 | done; \ 118 | $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi 119 | 120 | endif DX_COND_ps 121 | 122 | ## ------------------------------ ## 123 | ## Rules specific for PDF output. ## 124 | ## ------------------------------ ## 125 | 126 | if DX_COND_pdf 127 | 128 | DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf 129 | 130 | DX_PDF_GOAL = doxygen-pdf 131 | 132 | doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf 133 | 134 | @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag 135 | cd @DX_DOCDIR@/latex; \ 136 | rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ 137 | $(DX_PDFLATEX) refman.tex; \ 138 | $(DX_MAKEINDEX) refman.idx; \ 139 | $(DX_PDFLATEX) refman.tex; \ 140 | countdown=5; \ 141 | while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ 142 | refman.log > /dev/null 2>&1 \ 143 | && test $$countdown -gt 0; do \ 144 | $(DX_PDFLATEX) refman.tex; \ 145 | countdown=`expr $$countdown - 1`; \ 146 | done; \ 147 | mv refman.pdf ../@PACKAGE@.pdf 148 | 149 | endif DX_COND_pdf 150 | 151 | ## ------------------------------------------------- ## 152 | ## Rules specific for LaTeX (shared for PS and PDF). ## 153 | ## ------------------------------------------------- ## 154 | 155 | if DX_COND_latex 156 | 157 | DX_CLEAN_LATEX = @DX_DOCDIR@/latex 158 | 159 | endif DX_COND_latex 160 | 161 | .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) 162 | 163 | .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) 164 | 165 | doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag 166 | 167 | doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) 168 | 169 | @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) 170 | rm -rf @DX_DOCDIR@ 171 | $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) 172 | 173 | DX_CLEANFILES = \ 174 | @DX_DOCDIR@/@PACKAGE@.tag \ 175 | -r \ 176 | $(DX_CLEAN_HTML) \ 177 | $(DX_CLEAN_CHM) \ 178 | $(DX_CLEAN_CHI) \ 179 | $(DX_CLEAN_MAN) \ 180 | $(DX_CLEAN_RTF) \ 181 | $(DX_CLEAN_XML) \ 182 | $(DX_CLEAN_PS) \ 183 | $(DX_CLEAN_PDF) \ 184 | $(DX_CLEAN_LATEX) 185 | 186 | endif DX_COND_doc 187 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | platform: x64 2 | 3 | environment: 4 | matrix: 5 | - compiler: msys2 6 | MINGW_CHOST: x86_64-w64-mingw32 7 | MSYS2_ARCH: x86_64 8 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 9 | init: 10 | - 'echo Building libhttpserver %version% for Windows' 11 | - 'echo System architecture: %PLATFORM%' 12 | - 'echo Repo build branch is: %APPVEYOR_REPO_BRANCH%' 13 | - 'echo Build folder is: %APPVEYOR_BUILD_FOLDER%' 14 | - 'echo Repo build commit is: %APPVEYOR_REPO_COMMIT%' 15 | - 'echo Cygwin root is: %CYG_ROOT%' 16 | - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) 17 | install: 18 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -msys2 -c "pacman --noconfirm -S --needed mingw-w64-$MSYS2_ARCH-{libtool,make,pkg-config,libsystre,doxygen,gnutls,graphviz,curl}"' 19 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -msys2 -c "pacman --noconfirm -S --needed autotools"' 20 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER && curl https://s3.amazonaws.com/libhttpserver/libmicrohttpd_releases/libmicrohttpd-0.9.64.tar.gz -o libmicrohttpd-0.9.64.tar.gz"' 21 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER && tar -xzf libmicrohttpd-0.9.64.tar.gz"' 22 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER/libmicrohttpd-0.9.64 && ./configure --disable-examples --enable-poll=no --prefix /C/msys64 && make && make install"' 23 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER && ./bootstrap"' 24 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER && mkdir build && cd build && MANIFEST_TOOL=no; ../configure --disable-fastopen --prefix /C/msys64 CXXFLAGS=-I/C/msys64/include LDFLAGS=-L/C/msys64/lib; make"' 25 | build_script: 26 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER/build && make check"' 27 | - 'if "%compiler%"=="msys2" C:\msys64\msys2_shell.cmd -defterm -no-start -mingw64 -full-path -here -c "cd $APPVEYOR_BUILD_FOLDER/build && cat test/test-suite.log"' 28 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # This file is part of libhttpserver 4 | # Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 5 | # 6 | # This library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 of the License, or (at your option) any later version. 10 | # 11 | # This library is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this library; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | aclocal -I m4 21 | autoheader 22 | if [[ "$OSTYPE" == "darwin"* ]]; then 23 | glibtoolize --automake 24 | else 25 | libtoolize --automake 26 | fi 27 | automake --add-missing 28 | autoconf 29 | -------------------------------------------------------------------------------- /ci-report-coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | find ../ -name *.gcda 4 | 5 | echo "Copying files to the correct locations for correct gcov analysis" 6 | cp -R ../src/* ./src/ 7 | cp -R ../src/details/* ./src/details/ 8 | cp -R ../src/httpserver/* ./src/httpserver/ 9 | cp -R ../test/* ./test/ 10 | cp -R ../test/integ/* ./test/integ/ 11 | cp -R ../test/unit/* ./test/unit/ 12 | 13 | echo "Sending json report" 14 | for filename in `find . | egrep '\.cpp'`; 15 | do 16 | gcov -n -o . $filename > /dev/null; 17 | done 18 | 19 | codecov 20 | -------------------------------------------------------------------------------- /cmakemodule/FindLibHttpServer.cmake: -------------------------------------------------------------------------------- 1 | # - Find LibHttpServer 2 | 3 | if(LIBHTTPSERVER_INCLUDE_DIRS AND LIBHTTPSERVER_LIBRARIES) 4 | set(LIBHTTPSERVER_FOUND TRUE) 5 | 6 | else(LIBHTTPSERVER_INCLUDE_DIRS AND LIBHTTPSERVER_LIBRARIES) 7 | find_path(LIBHTTPSERVER_INCLUDE_DIRS httpserverpp 8 | /usr/include 9 | /usr/include/httpserver 10 | /usr/local/include/ 11 | /usr/local/include/httpserver 12 | ) 13 | 14 | find_library(LIBHTTPSERVER_LIBRARIES NAMES httpserver 15 | PATHS 16 | /usr/lib 17 | /usr/local/lib 18 | /opt/local/lib 19 | ) 20 | 21 | if(LIBHTTPSERVER_INCLUDE_DIRS AND LIBHTTPSERVER_LIBRARIES) 22 | set(LIBHTTPSERVER_FOUND TRUE) 23 | message(STATUS "Found libhttpserver: ${LIBHTTPSERVER_INCLUDE_DIRS}, ${LIBHTTPSERVER_LIBRARIES}") 24 | else(LIBHTTPSERVER_INCLUDE_DIRS AND LIBHTTPSERVER_LIBRARIES) 25 | set(LIBHTTPSERVER_FOUND FALSE) 26 | message(STATUS "libhttpserver not found.") 27 | endif(LIBHTTPSERVER_INCLUDE_DIRS AND LIBHTTPSERVER_LIBRARIES) 28 | 29 | mark_as_advanced(LIBHTTPSERVER_INCLUDE_DIRS LIBHTTPSERVER_LIBRARIES) 30 | 31 | endif(LIBHTTPSERVER_INCLUDE_DIRS AND LIBHTTPSERVER_LIBRARIES) 32 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: yes 3 | 4 | coverage: 5 | precision: 2 6 | round: down 7 | range: "70...100" 8 | 9 | parsers: 10 | gcov: 11 | branch_detection: 12 | conditional: yes 13 | loop: yes 14 | method: no 15 | macro: no 16 | 17 | comment: 18 | layout: "reach,diff,flags,files,footer" 19 | behavior: default 20 | require_changes: no 21 | -------------------------------------------------------------------------------- /custom_iwyu.imp: -------------------------------------------------------------------------------- 1 | [ 2 | { include: ["\"microhttpd.h\"", "private", "", "public"] }, 3 | { include: ["", "private", "", "public"] }, 4 | 5 | { symbol: ["std::exception", "private", "", "public"]}, 6 | { symbol: ["std::shared_ptr", "private", "", "public"]}, 7 | { symbol: ["std::uint16_t", "private", "", "public"]}, 8 | { symbol: ["std::uint64_t", "private", "", "public"]}, 9 | { symbol: ["std::istringstream", "private", "", "public"]}, 10 | { symbol: ["std::stringstream", "private", "", "public"]}, 11 | { symbol: ["std::ifstream", "private", "", "public"]}, 12 | 13 | { symbol: ["uint16_t", "private", "", "public"]}, 14 | { symbol: ["uint64_t", "private", "", "public"]}, 15 | 16 | { symbol: ["MHD_Connection", "private", "", "public"]}, 17 | ] 18 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of libhttpserver 3 | # Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | man_MANS = libhttpserver.3 20 | EXTRA_DIST = $(man_MANS) 21 | -------------------------------------------------------------------------------- /doc/libhttpserver.3: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2014, Sebastiano Merlino 2 | .\" 3 | .\" %%%LICENSE_START(VERBATIM) 4 | .\" Permission is granted to make and distribute verbatim copies of this 5 | .\" manual provided the copyright notice and this permission notice are 6 | .\" preserved on all copies. 7 | .\" 8 | .\" Permission is granted to copy and distribute modified versions of 9 | .\" this manual under the conditions for verbatim copying, provided that 10 | .\" the entire resulting derived work is distributed under the terms of 11 | .\" a permission notice identical to this one. 12 | .\" 13 | .\" Since the Linux kernel and libraries are constantly changing, this 14 | .\" manual page may be incorrect or out-of-date. The author(s) assume. 15 | .\" no responsibility for errors or omissions, or for damages resulting. 16 | .\" from the use of the information contained herein. The author(s) may. 17 | .\" not have taken the same level of care in the production of this. 18 | .\" manual, which is licensed free of charge, as they might when working. 19 | .\" professionally. 20 | .\" 21 | .\" Formatted or processed versions of this manual, if unaccompanied by 22 | .\" the source, must acknowledge the copyright and authors of this work. 23 | .\" %%%LICENSE_END 24 | 25 | .TH LIBHTTPSERVER "3" "02 Mar 2013 "libhttpserver" 26 | .SH "NAME" 27 | libhttpserver \- C++ library for creating an embedded Rest HTTP server (and more) 28 | .SH "SYNOPSIS" 29 | 30 | \fB#include 31 | 32 | .SH "DESCRIPTION" 33 | .P 34 | libhttpserver is an api made with the intent to allow to easily realize Rest based webservers. 35 | .P 36 | The details of the API are described in a detailed documentation and in doxygen generated code reference. 37 | .P 38 | .SH "SEE ALSO" 39 | \fBcurl\fP(1), \fBlibcurl\fP(3), \fBlibmicrohttpd\fP(3) 40 | 41 | .SH "LEGAL NOTICE" 42 | libhttpserver is released under the LGPL Version 2.1 or higher. For details on the license please read the appendix in the manual. 43 | 44 | .SH "FILES" 45 | .TP 46 | httpserver.hpp 47 | libhttpserver include file 48 | .TP 49 | libhttpserver.so 50 | libhttpserver library 51 | 52 | .SH "REPORTING BUGS" 53 | Report bugs by using github issue tracker . 54 | 55 | .SH "AUTHORS" 56 | GNU libhttpserver is designed and realized by Sebastiano Merlino . 57 | 58 | .SH "AVAILABILITY" 59 | You can obtain the latest version from https://github.com/etr/libhttpserver . 60 | -------------------------------------------------------------------------------- /examples/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of libhttpserver 3 | # Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | LDADD = $(top_builddir)/src/libhttpserver.la 20 | AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/ 21 | METASOURCES = AUTO 22 | noinst_PROGRAMS = hello_world service minimal_hello_world custom_error allowing_disallowing_methods handlers hello_with_get_arg setting_headers custom_access_log basic_authentication digest_authentication minimal_https minimal_file_response minimal_deferred url_registration minimal_ip_ban benchmark_select benchmark_threads benchmark_nodelay deferred_with_accumulator file_upload 23 | 24 | hello_world_SOURCES = hello_world.cpp 25 | service_SOURCES = service.cpp 26 | minimal_hello_world_SOURCES = minimal_hello_world.cpp 27 | custom_error_SOURCES = custom_error.cpp 28 | allowing_disallowing_methods_SOURCES = allowing_disallowing_methods.cpp 29 | handlers_SOURCES = handlers.cpp 30 | hello_with_get_arg_SOURCES = hello_with_get_arg.cpp 31 | setting_headers_SOURCES = setting_headers.cpp 32 | custom_access_log_SOURCES = custom_access_log.cpp 33 | basic_authentication_SOURCES = basic_authentication.cpp 34 | digest_authentication_SOURCES = digest_authentication.cpp 35 | minimal_https_SOURCES = minimal_https.cpp 36 | minimal_file_response_SOURCES = minimal_file_response.cpp 37 | minimal_deferred_SOURCES = minimal_deferred.cpp 38 | deferred_with_accumulator_SOURCES = deferred_with_accumulator.cpp 39 | url_registration_SOURCES = url_registration.cpp 40 | minimal_ip_ban_SOURCES = minimal_ip_ban.cpp 41 | benchmark_select_SOURCES = benchmark_select.cpp 42 | benchmark_threads_SOURCES = benchmark_threads.cpp 43 | benchmark_nodelay_SOURCES = benchmark_nodelay.cpp 44 | file_upload_SOURCES = file_upload.cpp 45 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | Example Programs 2 | ================ 3 | 4 | hello_world.cpp - a very simple example of using libhttpserver to 5 | create a Rest server capable of receiving and processing 6 | HTTP requests. The server will be listening on port 7 | 8080. 8 | 9 | 10 | service.cpp - an example using more of the libhttpserver API. 11 | This creates a Rest server capable of running with 12 | HTTP or HTTPS (provided that libhttpserver and 13 | libmicrohttpd have been compiled with SSL support. 14 | 15 | The server can be configured via command line 16 | arguments: 17 | 18 | -p - port number to listen on (default 8080) 19 | -s - enable HTTPS 20 | -k - server key filename (default "key.pem") 21 | -c - server certificate filename (default "cert.pem") 22 | 23 | Creating Certificates 24 | ===================== 25 | Self-signed certificates can be created using OpenSSL using the 26 | following steps: 27 | 28 | $ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048 29 | $ openssl rsa -passin pass:x -in server.pass.key -out server.key 30 | $ openssl req -new -key server.key -out server.csr 31 | $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt 32 | 33 | On the last step when prompted for a challenge password it can be left 34 | empty. 35 | 36 | Thanks to https://devcenter.heroku.com/articles/ssl-certificate-self 37 | for these instructions. 38 | 39 | Keystore configuration 40 | ====================== 41 | If using a local client such as RestClient 42 | (https://github.com/wiztools/rest-client) for testing the Rest server 43 | then a keystore needs to be established. These commands should be 44 | bundled with your Java installation. 45 | 46 | $ keytool -noprompt -import -keystore /path/to/restclient.store -alias 47 | restclient -file /path/to/server.crt 48 | 49 | The keys in the store can be listed as follows: 50 | 51 | $ keytool -list -v -keystore /path/to/restclient.store 52 | 53 | The client can then be configured to use this keystore. Thanks to 54 | http://rubensgomes.blogspot.com/2012/01/how-to-set-up-restclient-for-ssl.html 55 | for instructions on configuring RestClient. 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/allowing_disallowing_methods.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 27 | } 28 | }; 29 | 30 | int main() { 31 | httpserver::webserver ws = httpserver::create_webserver(8080); 32 | 33 | hello_world_resource hwr; 34 | hwr.disallow_all(); 35 | hwr.set_allowing("GET", true); 36 | ws.register_resource("/hello", &hwr); 37 | ws.start(true); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /examples/basic_authentication.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class user_pass_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render_GET(const httpserver::http_request& req) { 26 | if (req.get_user() != "myuser" || req.get_pass() != "mypass") { 27 | return std::shared_ptr(new httpserver::basic_auth_fail_response("FAIL", "test@example.com")); 28 | } 29 | 30 | return std::shared_ptr(new httpserver::string_response(std::string(req.get_user()) + " " + std::string(req.get_pass()), 200, "text/plain")); 31 | } 32 | }; 33 | 34 | int main() { 35 | httpserver::webserver ws = httpserver::create_webserver(8080); 36 | 37 | user_pass_resource hwr; 38 | ws.register_resource("/hello", &hwr); 39 | ws.start(true); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /examples/benchmark_nodelay.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #define PATH "/plaintext" 27 | #define BODY "Hello, World!" 28 | 29 | class hello_world_resource : public httpserver::http_resource { 30 | public: 31 | explicit hello_world_resource(const std::shared_ptr& resp): 32 | resp(resp) { 33 | } 34 | 35 | std::shared_ptr render(const httpserver::http_request&) { 36 | return resp; 37 | } 38 | 39 | private: 40 | std::shared_ptr resp; 41 | }; 42 | 43 | int main(int argc, char** argv) { 44 | std::ignore = argc; 45 | 46 | httpserver::webserver ws = httpserver::create_webserver(atoi(argv[1])) 47 | .start_method(httpserver::http::http_utils::INTERNAL_SELECT) 48 | .tcp_nodelay() 49 | .max_threads(atoi(argv[2])); 50 | 51 | std::shared_ptr hello = std::shared_ptr(new httpserver::string_response(BODY, 200)); 52 | hello->with_header("Server", "libhttpserver"); 53 | 54 | hello_world_resource hwr(hello); 55 | ws.register_resource(PATH, &hwr, false); 56 | 57 | ws.start(true); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /examples/benchmark_select.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #define PATH "/plaintext" 27 | #define BODY "Hello, World!" 28 | 29 | class hello_world_resource : public httpserver::http_resource { 30 | public: 31 | explicit hello_world_resource(const std::shared_ptr& resp): 32 | resp(resp) { 33 | } 34 | 35 | std::shared_ptr render(const httpserver::http_request&) { 36 | return resp; 37 | } 38 | 39 | private: 40 | std::shared_ptr resp; 41 | }; 42 | 43 | int main(int argc, char** argv) { 44 | std::ignore = argc; 45 | 46 | httpserver::webserver ws = httpserver::create_webserver(atoi(argv[1])) 47 | .start_method(httpserver::http::http_utils::INTERNAL_SELECT) 48 | .max_threads(atoi(argv[2])); 49 | 50 | std::shared_ptr hello = std::shared_ptr(new httpserver::string_response(BODY, 200)); 51 | hello->with_header("Server", "libhttpserver"); 52 | 53 | hello_world_resource hwr(hello); 54 | ws.register_resource(PATH, &hwr, false); 55 | 56 | ws.start(true); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /examples/benchmark_threads.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #define PATH "/plaintext" 27 | #define BODY "Hello, World!" 28 | 29 | class hello_world_resource : public httpserver::http_resource { 30 | public: 31 | explicit hello_world_resource(const std::shared_ptr& resp): 32 | resp(resp) { 33 | } 34 | 35 | std::shared_ptr render(const httpserver::http_request&) { 36 | return resp; 37 | } 38 | 39 | private: 40 | std::shared_ptr resp; 41 | }; 42 | 43 | int main(int argc, char** argv) { 44 | std::ignore = argc; 45 | 46 | httpserver::webserver ws = httpserver::create_webserver(atoi(argv[1])) 47 | .start_method(httpserver::http::http_utils::THREAD_PER_CONNECTION); 48 | 49 | std::shared_ptr hello = std::shared_ptr(new httpserver::string_response(BODY, 200)); 50 | hello->with_header("Server", "libhttpserver"); 51 | 52 | hello_world_resource hwr(hello); 53 | ws.register_resource(PATH, &hwr, false); 54 | 55 | ws.start(true); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /examples/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0 3 | MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC 4 | AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X 5 | fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud 6 | 3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/ 7 | GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv 8 | rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh 9 | siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O 10 | BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2 11 | RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN 12 | 8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/ 13 | 0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe 14 | JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3 15 | OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV 16 | RhZvQx74NQnS6g== 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /examples/custom_access_log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | #include 24 | 25 | void custom_access_log(const std::string& url) { 26 | std::cout << "ACCESSING: " << url << std::endl; 27 | } 28 | 29 | class hello_world_resource : public httpserver::http_resource { 30 | public: 31 | std::shared_ptr render(const httpserver::http_request&) { 32 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 33 | } 34 | }; 35 | 36 | int main() { 37 | httpserver::webserver ws = httpserver::create_webserver(8080) 38 | .log_access(custom_access_log); 39 | 40 | hello_world_resource hwr; 41 | ws.register_resource("/hello", &hwr); 42 | ws.start(true); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /examples/custom_error.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | std::shared_ptr not_found_custom(const httpserver::http_request&) { 24 | return std::shared_ptr(new httpserver::string_response("Not found custom", 404, "text/plain")); 25 | } 26 | 27 | std::shared_ptr not_allowed_custom(const httpserver::http_request&) { 28 | return std::shared_ptr(new httpserver::string_response("Not allowed custom", 405, "text/plain")); 29 | } 30 | 31 | class hello_world_resource : public httpserver::http_resource { 32 | public: 33 | std::shared_ptr render(const httpserver::http_request&) { 34 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 35 | } 36 | }; 37 | 38 | int main() { 39 | httpserver::webserver ws = httpserver::create_webserver(8080) 40 | .not_found_resource(not_found_custom) 41 | .method_not_allowed_resource(not_allowed_custom); 42 | 43 | hello_world_resource hwr; 44 | hwr.disallow_all(); 45 | hwr.set_allowing("GET", true); 46 | ws.register_resource("/hello", &hwr); 47 | ws.start(true); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /examples/deferred_with_accumulator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | // cpplint errors on chrono and thread because they are replaced (in Chromium) by other google libraries. 24 | // This is not an issue here. 25 | #include // NOLINT [build/c++11] 26 | #include // NOLINT [build/c++11] 27 | 28 | #include 29 | 30 | std::atomic counter; 31 | 32 | ssize_t test_callback(std::shared_ptr > closure_data, char* buf, size_t max) { 33 | int reqid; 34 | if (closure_data == nullptr) { 35 | reqid = -1; 36 | } else { 37 | reqid = *closure_data; 38 | } 39 | 40 | // only first 5 connections can be established 41 | if (reqid >= 5) { 42 | return -1; 43 | } else { 44 | // respond corresponding request IDs to the clients 45 | std::string str = ""; 46 | str += std::to_string(reqid) + " "; 47 | memset(buf, 0, max); 48 | std::copy(str.begin(), str.end(), buf); 49 | 50 | // keep sending reqid 51 | // sleep(1); ==> adapted for C++11 on non-*Nix systems 52 | std::this_thread::sleep_for(std::chrono::seconds(1)); 53 | 54 | return (ssize_t)max; 55 | } 56 | } 57 | 58 | class deferred_resource : public httpserver::http_resource { 59 | public: 60 | std::shared_ptr render_GET(const httpserver::http_request&) { 61 | std::shared_ptr > closure_data(new std::atomic(counter++)); 62 | return std::shared_ptr > >(new httpserver::deferred_response >(test_callback, closure_data, "cycle callback response")); 63 | } 64 | }; 65 | 66 | int main() { 67 | httpserver::webserver ws = httpserver::create_webserver(8080); 68 | 69 | deferred_resource hwr; 70 | ws.register_resource("/hello", &hwr); 71 | ws.start(true); 72 | 73 | return 0; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /examples/digest_authentication.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | #define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4" 24 | 25 | class digest_resource : public httpserver::http_resource { 26 | public: 27 | std::shared_ptr render_GET(const httpserver::http_request& req) { 28 | if (req.get_digested_user() == "") { 29 | return std::shared_ptr(new httpserver::digest_auth_fail_response("FAIL", "test@example.com", MY_OPAQUE, true)); 30 | } else { 31 | bool reload_nonce = false; 32 | if (!req.check_digest_auth("test@example.com", "mypass", 300, &reload_nonce)) { 33 | return std::shared_ptr(new httpserver::digest_auth_fail_response("FAIL", "test@example.com", MY_OPAQUE, reload_nonce)); 34 | } 35 | } 36 | return std::shared_ptr(new httpserver::string_response("SUCCESS", 200, "text/plain")); 37 | } 38 | }; 39 | 40 | int main() { 41 | httpserver::webserver ws = httpserver::create_webserver(8080); 42 | 43 | digest_resource hwr; 44 | ws.register_resource("/hello", &hwr); 45 | ws.start(true); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /examples/file_upload.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | class file_upload_resource : public httpserver::http_resource { 25 | public: 26 | std::shared_ptr render_GET(const httpserver::http_request&) { 27 | std::string get_response = "\n"; 28 | get_response += " \n"; 29 | get_response += "
\n"; 30 | get_response += "

Upload 1 (key is 'files', multiple files can be selected)


\n"; 31 | get_response += " \n"; 32 | get_response += "

\n"; 33 | get_response += "

Upload 2 (key is 'files2', multiple files can be selected)


\n"; 34 | get_response += "

\n"; 35 | get_response += " \n"; 36 | get_response += "
\n"; 37 | get_response += " \n"; 38 | get_response += "\n"; 39 | 40 | return std::shared_ptr(new httpserver::string_response(get_response, 200, "text/html")); 41 | } 42 | 43 | std::shared_ptr render_POST(const httpserver::http_request& req) { 44 | std::string post_response = "\n"; 45 | post_response += "\n"; 46 | post_response += " \n"; 52 | post_response += "\n"; 53 | post_response += "\n"; 54 | post_response += " Uploaded files:\n"; 55 | post_response += "

\n"; 56 | post_response += " \n"; 57 | post_response += " \n"; 58 | post_response += " \n"; 59 | post_response += " \n"; 60 | post_response += " \n"; 61 | post_response += " \n"; 62 | post_response += " \n"; 63 | post_response += " \n"; 64 | post_response += " \n"; 65 | 66 | for (auto &file_key : req.get_files()) { 67 | for (auto &files : file_key.second) { 68 | post_response += " \n"; 81 | } 82 | } 83 | 84 | post_response += "
KeyUploaded filenameFile system pathFile sizeContent typeTransfer encoding
"; 69 | post_response += file_key.first; 70 | post_response += ""; 71 | post_response += files.first; 72 | post_response += ""; 73 | post_response += files.second.get_file_system_file_name(); 74 | post_response += ""; 75 | post_response += std::to_string(files.second.get_file_size()); 76 | post_response += ""; 77 | post_response += files.second.get_content_type(); 78 | post_response += ""; 79 | post_response += files.second.get_transfer_encoding(); 80 | post_response += "


\n"; 85 | post_response += " back\n"; 86 | post_response += "\n"; 87 | return std::shared_ptr(new httpserver::string_response(post_response, 201, "text/html")); 88 | } 89 | }; 90 | 91 | int main(int argc, char** argv) { 92 | // this example needs a directory as parameter 93 | if (2 != argc) { 94 | std::cout << "Usage: file_upload " << std::endl; 95 | std::cout << std::endl; 96 | std::cout << " file_upload: writeable directory where uploaded files will be stored" << std::endl; 97 | return -1; 98 | } 99 | 100 | std::cout << "CAUTION: this example will create files in the directory " << std::string(argv[1]) << std::endl; 101 | std::cout << "These files won't be deleted at termination" << std::endl; 102 | std::cout << "Please make sure, that the given directory exists and is writeable" << std::endl; 103 | 104 | httpserver::webserver ws = httpserver::create_webserver(8080) 105 | .no_put_processed_data_to_content() 106 | .file_upload_dir(std::string(argv[1])) 107 | .generate_random_filename_on_upload() 108 | .file_upload_target(httpserver::FILE_UPLOAD_DISK_ONLY); 109 | 110 | file_upload_resource fur; 111 | ws.register_resource("/", &fur); 112 | ws.start(true); 113 | 114 | return 0; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /examples/handlers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render_GET(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::string_response("GET: Hello, World!")); 27 | } 28 | 29 | std::shared_ptr render(const httpserver::http_request&) { 30 | return std::shared_ptr(new httpserver::string_response("OTHER: Hello, World!")); 31 | } 32 | }; 33 | 34 | int main() { 35 | httpserver::webserver ws = httpserver::create_webserver(8080); 36 | 37 | hello_world_resource hwr; 38 | ws.register_resource("/hello", &hwr); 39 | ws.start(true); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /examples/hello_with_get_arg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request& req) { 26 | return std::shared_ptr(new httpserver::string_response("Hello: " + std::string(req.get_arg("name")))); 27 | } 28 | }; 29 | 30 | int main() { 31 | httpserver::webserver ws = httpserver::create_webserver(8080); 32 | 33 | hello_world_resource hwr; 34 | ws.register_resource("/hello", &hwr); 35 | ws.start(true); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /examples/hello_world.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | #include 24 | 25 | class hello_world_resource : public httpserver::http_resource { 26 | public: 27 | std::shared_ptr render(const httpserver::http_request&); 28 | void set_some_data(const std::string &s) {data = s;} 29 | std::string data; 30 | }; 31 | 32 | // Using the render method you are able to catch each type of request you receive 33 | std::shared_ptr hello_world_resource::render(const httpserver::http_request& req) { 34 | // It is possible to store data inside the resource object that can be altered through the requests 35 | std::cout << "Data was: " << data << std::endl; 36 | std::string_view datapar = req.get_arg("data"); 37 | set_some_data(datapar == "" ? "no data passed!!!" : std::string(datapar)); 38 | std::cout << "Now data is:" << data << std::endl; 39 | 40 | // It is possible to send a response initializing an http_string_response that reads the content to send in response from a string. 41 | return std::shared_ptr(new httpserver::string_response("Hello World!!!", 200)); 42 | } 43 | 44 | int main() { 45 | // It is possible to create a webserver passing a great number of parameters. In this case we are just passing the port and the number of thread running. 46 | httpserver::webserver ws = httpserver::create_webserver(8080).start_method(httpserver::http::http_utils::INTERNAL_SELECT).max_threads(5); 47 | 48 | hello_world_resource hwr; 49 | // This way we are registering the hello_world_resource to answer for the endpoint 50 | // "/hello". The requested method is called (if the request is a GET we call the render_GET 51 | // method. In case that the specific render method is not implemented, the generic "render" 52 | // method is called. 53 | ws.register_resource("/hello", &hwr, true); 54 | 55 | // This way we are putting the created webserver in listen. We pass true in order to have 56 | // a blocking call; if we want the call to be non-blocking we can just pass false to the method. 57 | ws.start(true); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /examples/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf 3 | qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I 4 | niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+ 5 | faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx 6 | 7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ 7 | vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj 8 | lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R 9 | EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l 10 | /5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx 11 | u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/ 12 | dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo 13 | 32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc 14 | +JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd 15 | RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6 16 | OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob 17 | XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF 18 | hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae 19 | SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b 20 | AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH 21 | 6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3 22 | QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG 23 | 7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj 24 | P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9 25 | /Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC 26 | eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /examples/minimal_deferred.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | static int counter = 0; 25 | 26 | ssize_t test_callback(std::shared_ptr closure_data, char* buf, size_t max) { 27 | std::ignore = closure_data; 28 | 29 | if (counter == 2) { 30 | return -1; 31 | } else { 32 | memset(buf, 0, max); 33 | snprintf(buf, max, "%s", " test "); 34 | counter++; 35 | return std::string(buf).size(); 36 | } 37 | } 38 | 39 | class deferred_resource : public httpserver::http_resource { 40 | public: 41 | std::shared_ptr render_GET(const httpserver::http_request&) { 42 | return std::shared_ptr >(new httpserver::deferred_response(test_callback, nullptr, "cycle callback response")); 43 | } 44 | }; 45 | 46 | int main() { 47 | httpserver::webserver ws = httpserver::create_webserver(8080); 48 | 49 | deferred_resource hwr; 50 | ws.register_resource("/hello", &hwr); 51 | ws.start(true); 52 | 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /examples/minimal_file_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class file_response_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render_GET(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::file_response("test_content", 200, "text/plain")); 27 | } 28 | }; 29 | 30 | int main() { 31 | httpserver::webserver ws = httpserver::create_webserver(8080); 32 | 33 | file_response_resource hwr; 34 | ws.register_resource("/hello", &hwr); 35 | ws.start(true); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /examples/minimal_hello_world.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 27 | } 28 | }; 29 | 30 | int main() { 31 | httpserver::webserver ws = httpserver::create_webserver(8080); 32 | 33 | hello_world_resource hwr; 34 | ws.register_resource("/hello", &hwr); 35 | ws.start(true); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /examples/minimal_https.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 27 | } 28 | }; 29 | 30 | int main() { 31 | httpserver::webserver ws = httpserver::create_webserver(8080) 32 | .use_ssl() 33 | .https_mem_key("key.pem") 34 | .https_mem_cert("cert.pem"); 35 | 36 | hello_world_resource hwr; 37 | ws.register_resource("/hello", &hwr); 38 | ws.start(true); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /examples/minimal_ip_ban.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 27 | } 28 | }; 29 | 30 | int main() { 31 | httpserver::webserver ws = httpserver::create_webserver(8080).default_policy(httpserver::http::http_utils::REJECT); 32 | 33 | ws.allow_ip("127.0.0.1"); 34 | 35 | hello_world_resource hwr; 36 | ws.register_resource("/hello", &hwr); 37 | ws.start(true); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /examples/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2014 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | bool verbose = false; 29 | 30 | class service_resource: public httpserver::http_resource { 31 | public: 32 | service_resource(); 33 | 34 | ~service_resource(); 35 | 36 | std::shared_ptr render_GET(const httpserver::http_request &req); 37 | std::shared_ptr render_PUT(const httpserver::http_request &req); 38 | std::shared_ptr render_POST(const httpserver::http_request &req); 39 | std::shared_ptr render(const httpserver::http_request &req); 40 | std::shared_ptr render_HEAD(const httpserver::http_request &req); 41 | std::shared_ptr render_OPTIONS(const httpserver::http_request &req); 42 | std::shared_ptr render_CONNECT(const httpserver::http_request &req); 43 | std::shared_ptr render_DELETE(const httpserver::http_request &req); 44 | }; 45 | 46 | service_resource::service_resource() { } 47 | 48 | service_resource::~service_resource() { } 49 | 50 | std::shared_ptr service_resource::render_GET(const httpserver::http_request &req) { 51 | std::cout << "service_resource::render_GET()" << std::endl; 52 | 53 | if (verbose) std::cout << req; 54 | httpserver::string_response* res = new httpserver::string_response("GET response", 200); 55 | 56 | if (verbose) std::cout << *res; 57 | 58 | return std::shared_ptr(res); 59 | } 60 | 61 | 62 | std::shared_ptr service_resource::render_PUT(const httpserver::http_request &req) { 63 | std::cout << "service_resource::render_PUT()" << std::endl; 64 | 65 | if (verbose) std::cout << req; 66 | 67 | httpserver::string_response* res = new httpserver::string_response("PUT response", 200); 68 | 69 | if (verbose) std::cout << *res; 70 | 71 | return std::shared_ptr(res); 72 | } 73 | 74 | std::shared_ptr service_resource::render_POST(const httpserver::http_request &req) { 75 | std::cout << "service_resource::render_POST()" << std::endl; 76 | 77 | if (verbose) std::cout << req; 78 | 79 | httpserver::string_response* res = new httpserver::string_response("POST response", 200); 80 | 81 | if (verbose) std::cout << *res; 82 | 83 | return std::shared_ptr(res); 84 | } 85 | 86 | std::shared_ptr service_resource::render(const httpserver::http_request &req) { 87 | std::cout << "service_resource::render()" << std::endl; 88 | 89 | if (verbose) std::cout << req; 90 | 91 | httpserver::string_response* res = new httpserver::string_response("generic response", 200); 92 | 93 | if (verbose) std::cout << *res; 94 | 95 | return std::shared_ptr(res); 96 | } 97 | 98 | std::shared_ptr service_resource::render_HEAD(const httpserver::http_request &req) { 99 | std::cout << "service_resource::render_HEAD()" << std::endl; 100 | 101 | if (verbose) std::cout << req; 102 | 103 | httpserver::string_response* res = new httpserver::string_response("HEAD response", 200); 104 | 105 | if (verbose) std::cout << *res; 106 | 107 | return std::shared_ptr(res); 108 | } 109 | 110 | std::shared_ptr service_resource::render_OPTIONS(const httpserver::http_request &req) { 111 | std::cout << "service_resource::render_OPTIONS()" << std::endl; 112 | 113 | if (verbose) std::cout << req; 114 | 115 | httpserver::string_response* res = new httpserver::string_response("OPTIONS response", 200); 116 | 117 | if (verbose) std::cout << *res; 118 | 119 | return std::shared_ptr(res); 120 | } 121 | 122 | std::shared_ptr service_resource::render_CONNECT(const httpserver::http_request &req) { 123 | std::cout << "service_resource::render_CONNECT()" << std::endl; 124 | 125 | if (verbose) std::cout << req; 126 | 127 | httpserver::string_response* res = new httpserver::string_response("CONNECT response", 200); 128 | 129 | if (verbose) std::cout << *res; 130 | 131 | return std::shared_ptr(res); 132 | } 133 | 134 | std::shared_ptr service_resource::render_DELETE(const httpserver::http_request &req) { 135 | std::cout << "service_resource::render_DELETE()" << std::endl; 136 | 137 | if (verbose) std::cout << req; 138 | 139 | httpserver::string_response* res = new httpserver::string_response("DELETE response", 200); 140 | 141 | if (verbose) std::cout << *res; 142 | 143 | return std::shared_ptr(res); 144 | } 145 | 146 | void usage() { 147 | std::cout << "Usage:" << std::endl 148 | << "service [-p ][-s [-k ][-c ]][-v]" << std::endl; 149 | } 150 | 151 | int main(int argc, char **argv) { 152 | uint16_t port = 8080; 153 | int c; 154 | const char *key = "key.pem"; 155 | const char *cert = "cert.pem"; 156 | bool secure = false; 157 | 158 | while ((c = getopt(argc, argv, "p:k:c:sv?")) != EOF) { 159 | switch (c) { 160 | case 'p': 161 | port = strtoul(optarg, nullptr, 10); 162 | break; 163 | case 'k': 164 | key = optarg; 165 | break; 166 | case 'c': 167 | cert = optarg; 168 | break; 169 | case 's': 170 | secure = true; 171 | break; 172 | case 'v': 173 | verbose = true; 174 | break; 175 | default: 176 | usage(); 177 | exit(1); 178 | break; 179 | } 180 | } 181 | 182 | std::cout << "Using port " << port << std::endl; 183 | if (secure) { 184 | std::cout << "Key: " << key << " Certificate: " << cert 185 | << std::endl; 186 | } 187 | 188 | // 189 | // Use builder to define webserver configuration options 190 | // 191 | httpserver::create_webserver cw = httpserver::create_webserver(port).max_threads(5); 192 | 193 | if (secure) { 194 | cw.use_ssl().https_mem_key(key).https_mem_cert(cert); 195 | } 196 | 197 | // 198 | // Create webserver using the configured options 199 | // 200 | httpserver::webserver ws = cw; 201 | 202 | // 203 | // Create and register service resource available at /service 204 | // 205 | service_resource res; 206 | ws.register_resource("/service", &res, true); 207 | 208 | // 209 | // Start and block the webserver 210 | // 211 | ws.start(true); 212 | 213 | return 0; 214 | } 215 | -------------------------------------------------------------------------------- /examples/setting_headers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request&) { 26 | std::shared_ptr response = std::shared_ptr(new httpserver::string_response("Hello, World!")); 27 | response->with_header("MyHeader", "MyValue"); 28 | return response; 29 | } 30 | }; 31 | 32 | int main() { 33 | httpserver::webserver ws = httpserver::create_webserver(8080); 34 | 35 | hello_world_resource hwr; 36 | ws.register_resource("/hello", &hwr); 37 | ws.start(true); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /examples/test_content: -------------------------------------------------------------------------------- 1 | test content of file 2 | -------------------------------------------------------------------------------- /examples/url_registration.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011, 2012, 2013, 2014, 2015 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | class hello_world_resource : public httpserver::http_resource { 24 | public: 25 | std::shared_ptr render(const httpserver::http_request&) { 26 | return std::shared_ptr(new httpserver::string_response("Hello, World!")); 27 | } 28 | }; 29 | 30 | class handling_multiple_resource : public httpserver::http_resource { 31 | public: 32 | std::shared_ptr render(const httpserver::http_request& req) { 33 | return std::shared_ptr(new httpserver::string_response("Your URL: " + std::string(req.get_path()))); 34 | } 35 | }; 36 | 37 | class url_args_resource : public httpserver::http_resource { 38 | public: 39 | std::shared_ptr render(const httpserver::http_request& req) { 40 | return std::shared_ptr(new httpserver::string_response("ARGS: " + std::string(req.get_arg("arg1")) + " and " + std::string(req.get_arg("arg2")))); 41 | } 42 | }; 43 | 44 | int main() { 45 | httpserver::webserver ws = httpserver::create_webserver(8080); 46 | 47 | hello_world_resource hwr; 48 | ws.register_resource("/hello", &hwr); 49 | 50 | handling_multiple_resource hmr; 51 | ws.register_resource("/family", &hmr, true); 52 | ws.register_resource("/with_regex_[0-9]+", &hmr); 53 | 54 | url_args_resource uar; 55 | ws.register_resource("/url/with/{arg1}/and/{arg2}", &uar); 56 | ws.register_resource("/url/with/parametric/args/{arg1|[0-9]+}/and/{arg2|[A-Z]+}", &uar); 57 | 58 | ws.start(true); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /libhttpserver.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libhttpserver 7 | Description: A C++ library for creating an embedded Rest HTTP server 8 | Version: @VERSION@ 9 | Requires: libmicrohttpd >= 0.9.52 10 | Conflicts: 11 | Libs: -L${libdir} -lhttpserver 12 | Libs.private: @LHT_LIBDEPS@ 13 | Cflags: -I${includedir} -I${includedir}/httpserver 14 | -------------------------------------------------------------------------------- /m4/ax_have_epoll.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_have_epoll.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_HAVE_EPOLL([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) 8 | # AX_HAVE_EPOLL_PWAIT([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) 9 | # 10 | # DESCRIPTION 11 | # 12 | # This macro determines whether the system supports the epoll I/O event 13 | # interface. A neat usage example would be: 14 | # 15 | # AX_HAVE_EPOLL( 16 | # [AX_CONFIG_FEATURE_ENABLE(epoll)], 17 | # [AX_CONFIG_FEATURE_DISABLE(epoll)]) 18 | # AX_CONFIG_FEATURE( 19 | # [epoll], [This platform supports epoll(7)], 20 | # [HAVE_EPOLL], [This platform supports epoll(7).]) 21 | # 22 | # The epoll interface was added to the Linux kernel in version 2.5.45, and 23 | # the macro verifies that a kernel newer than this is installed. This 24 | # check is somewhat unreliable if doesn't match the 25 | # running kernel, but it is necessary regardless, because glibc comes with 26 | # stubs for the epoll_create(), epoll_wait(), etc. that allow programs to 27 | # compile and link even if the kernel is too old; the problem would then 28 | # be detected only at runtime. 29 | # 30 | # Linux kernel version 2.6.19 adds the epoll_pwait() call in addition to 31 | # epoll_wait(). The availability of that function can be tested with the 32 | # second macro. Generally speaking, it is safe to assume that 33 | # AX_HAVE_EPOLL would succeed if AX_HAVE_EPOLL_PWAIT has, but not the 34 | # other way round. 35 | # 36 | # LICENSE 37 | # 38 | # Copyright (c) 2008 Peter Simons 39 | # 40 | # Copying and distribution of this file, with or without modification, are 41 | # permitted in any medium without royalty provided the copyright notice 42 | # and this notice are preserved. This file is offered as-is, without any 43 | # warranty. 44 | 45 | #serial 11 46 | 47 | AC_DEFUN([AX_HAVE_EPOLL], [dnl 48 | ax_have_epoll_cppflags="${CPPFLAGS}" 49 | AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"]) 50 | AC_MSG_CHECKING([for Linux epoll(7) interface]) 51 | AC_CACHE_VAL([ax_cv_have_epoll], [dnl 52 | AC_LINK_IFELSE([dnl 53 | AC_LANG_PROGRAM([dnl 54 | #include 55 | #ifdef HAVE_LINUX_VERSION_H 56 | # include 57 | # if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45) 58 | # error linux kernel version is too old to have epoll 59 | # endif 60 | #endif 61 | ], [dnl 62 | int fd, rc; 63 | struct epoll_event ev; 64 | fd = epoll_create(128); 65 | rc = epoll_wait(fd, &ev, 1, 0);])], 66 | [ax_cv_have_epoll=yes], 67 | [ax_cv_have_epoll=no])]) 68 | CPPFLAGS="${ax_have_epoll_cppflags}" 69 | AS_IF([test "${ax_cv_have_epoll}" = "yes"], 70 | [AC_MSG_RESULT([yes]) 71 | $1],[AC_MSG_RESULT([no]) 72 | $2]) 73 | ])dnl 74 | 75 | AC_DEFUN([AX_HAVE_EPOLL_PWAIT], [dnl 76 | ax_have_epoll_cppflags="${CPPFLAGS}" 77 | AC_CHECK_HEADER([linux/version.h], 78 | [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"]) 79 | AC_MSG_CHECKING([for Linux epoll(7) interface with signals extension]) 80 | AC_CACHE_VAL([ax_cv_have_epoll_pwait], [dnl 81 | AC_LINK_IFELSE([dnl 82 | AC_LANG_PROGRAM([dnl 83 | #ifdef HAVE_LINUX_VERSION_H 84 | # include 85 | # if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 86 | # error linux kernel version is too old to have epoll_pwait 87 | # endif 88 | #endif 89 | #include 90 | #include 91 | ], [dnl 92 | int fd, rc; 93 | struct epoll_event ev; 94 | fd = epoll_create(128); 95 | rc = epoll_wait(fd, &ev, 1, 0); 96 | rc = epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0));])], 97 | [ax_cv_have_epoll_pwait=yes], 98 | [ax_cv_have_epoll_pwait=no])]) 99 | CPPFLAGS="${ax_have_epoll_cppflags}" 100 | AS_IF([test "${ax_cv_have_epoll_pwait}" = "yes"], 101 | [AC_MSG_RESULT([yes]) 102 | $1],[AC_MSG_RESULT([no]) 103 | $2]) 104 | ])dnl 105 | -------------------------------------------------------------------------------- /m4/python.m4: -------------------------------------------------------------------------------- 1 | ## ------------------------ -*- Autoconf -*- 2 | ## Python file handling 3 | ## From Andrew Dalke 4 | ## Updated by James Henstridge 5 | ## ------------------------ 6 | # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 7 | # Free Software Foundation, Inc. 8 | # 9 | # This file is free software; the Free Software Foundation 10 | # gives unlimited permission to copy and/or distribute it, 11 | # with or without modifications, as long as this notice is preserved. 12 | 13 | # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) 14 | # --------------------------------------------------------------------------- 15 | # Adds support for distributing Python modules and packages. To 16 | # install modules, copy them to $(pythondir), using the python_PYTHON 17 | # automake variable. To install a package with the same name as the 18 | # automake package, install to $(pkgpythondir), or use the 19 | # pkgpython_PYTHON automake variable. 20 | # 21 | # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as 22 | # locations to install python extension modules (shared libraries). 23 | # Another macro is required to find the appropriate flags to compile 24 | # extension modules. 25 | # 26 | # If your package is configured with a different prefix to python, 27 | # users will have to add the install directory to the PYTHONPATH 28 | # environment variable, or create a .pth file (see the python 29 | # documentation for details). 30 | # 31 | # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will 32 | # cause an error if the version of python installed on the system 33 | # doesn't meet the requirement. MINIMUM-VERSION should consist of 34 | # numbers and dots only. 35 | AC_DEFUN([AM_PATH_PYTHON], 36 | [ 37 | dnl Find a Python interpreter. Python versions prior to 1.5 are not 38 | dnl supported because the default installation locations changed from 39 | dnl $prefix/lib/site-python in 1.4 to $prefix/lib/python1.5/site-packages 40 | dnl in 1.5. 41 | m4_define_default([_AM_PYTHON_INTERPRETER_LIST], 42 | [python python2 python2.5 python2.4 python2.3 python2.2 dnl 43 | python2.1 python2.0 python1.6 python1.5]) 44 | 45 | m4_if([$1],[],[ 46 | dnl No version check is needed. 47 | # Find any Python interpreter. 48 | if test -z "$PYTHON"; then 49 | AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) 50 | fi 51 | am_display_PYTHON=python 52 | ], [ 53 | dnl A version check is needed. 54 | if test -n "$PYTHON"; then 55 | # If the user set $PYTHON, use it and don't search something else. 56 | AC_MSG_CHECKING([whether $PYTHON version >= $1]) 57 | AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], 58 | [AC_MSG_RESULT(yes)], 59 | [AC_MSG_ERROR(too old)]) 60 | am_display_PYTHON=$PYTHON 61 | else 62 | # Otherwise, try each interpreter until we find one that satisfies 63 | # VERSION. 64 | AC_CACHE_CHECK([for a Python interpreter with version >= $1], 65 | [am_cv_pathless_PYTHON],[ 66 | for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do 67 | test "$am_cv_pathless_PYTHON" = none && break 68 | AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) 69 | done]) 70 | # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. 71 | if test "$am_cv_pathless_PYTHON" = none; then 72 | PYTHON=: 73 | else 74 | AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) 75 | fi 76 | am_display_PYTHON=$am_cv_pathless_PYTHON 77 | fi 78 | ]) 79 | 80 | if test "$PYTHON" = :; then 81 | dnl Run any user-specified action, or abort. 82 | m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) 83 | else 84 | 85 | dnl Query Python for its version number. Getting [:3] seems to be 86 | dnl the best way to do this; it's what "site.py" does in the standard 87 | dnl library. 88 | 89 | AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], 90 | [am_cv_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`]) 91 | AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) 92 | 93 | dnl Use the values of $prefix and $exec_prefix for the corresponding 94 | dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made 95 | dnl distinct variables so they can be overridden if need be. However, 96 | dnl general consensus is that you shouldn't need this ability. 97 | 98 | AC_SUBST([PYTHON_PREFIX], ['${prefix}']) 99 | AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) 100 | 101 | dnl At times (like when building shared libraries) you may want 102 | dnl to know which OS platform Python thinks this is. 103 | 104 | AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], 105 | [am_cv_python_platform=`$PYTHON -c "import sys; print sys.platform"`]) 106 | AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) 107 | 108 | 109 | dnl Set up 4 directories: 110 | 111 | dnl pythondir -- where to install python scripts. This is the 112 | dnl site-packages directory, not the python standard library 113 | dnl directory like in previous automake betas. This behavior 114 | dnl is more consistent with lispdir.m4 for example. 115 | dnl Query distutils for this directory. distutils does not exist in 116 | dnl Python 1.5, so we fall back to the hardcoded directory if it 117 | dnl doesn't work. 118 | AC_CACHE_CHECK([for $am_display_PYTHON script directory], 119 | [am_cv_python_pythondir], 120 | [am_cv_python_pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(0,0,prefix='$PYTHON_PREFIX')" 2>/dev/null || 121 | echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"`]) 122 | AC_SUBST([pythondir], [$am_cv_python_pythondir]) 123 | 124 | dnl pkgpythondir -- $PACKAGE directory under pythondir. Was 125 | dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is 126 | dnl more consistent with the rest of automake. 127 | 128 | AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) 129 | 130 | dnl pyexecdir -- directory for installing python extension modules 131 | dnl (shared libraries) 132 | dnl Query distutils for this directory. distutils does not exist in 133 | dnl Python 1.5, so we fall back to the hardcoded directory if it 134 | dnl doesn't work. 135 | AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], 136 | [am_cv_python_pyexecdir], 137 | [am_cv_python_pyexecdir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1,0,prefix='$PYTHON_EXEC_PREFIX')" 2>/dev/null || 138 | echo "${PYTHON_EXEC_PREFIX}/lib/python${PYTHON_VERSION}/site-packages"`]) 139 | AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) 140 | 141 | dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) 142 | 143 | AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) 144 | 145 | dnl Run any user-specified action. 146 | $2 147 | fi 148 | 149 | ]) 150 | 151 | 152 | # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) 153 | # --------------------------------------------------------------------------- 154 | # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. 155 | # Run ACTION-IF-FALSE otherwise. 156 | # This test uses sys.hexversion instead of the string equivalent (first 157 | # word of sys.version), in order to cope with versions such as 2.2c1. 158 | # hexversion has been introduced in Python 1.5.2; it's probably not 159 | # worth to support older versions (1.5.1 was released on October 31, 1998). 160 | AC_DEFUN([AM_PYTHON_CHECK_VERSION], 161 | [prog="import sys, string 162 | # split strings by '.' and convert to numeric. Append some zeros 163 | # because we need at least 4 digits for the hex conversion. 164 | minver = map(int, string.split('$2', '.')) + [[0, 0, 0]] 165 | minverhex = 0 166 | for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]] 167 | sys.exit(sys.hexversion < minverhex)" 168 | AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) 169 | -------------------------------------------------------------------------------- /msan_ignorelist.txt: -------------------------------------------------------------------------------- 1 | fun:__interceptor_strlen 2 | fun:__interceptor_fopen64 3 | fun:__interceptor_memcmp -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of libhttpserver 3 | # Copyright (C) 2011-2019 Sebastiano Merlino 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | AM_CPPFLAGS = -I../ -I$(srcdir)/httpserver/ 20 | METASOURCES = AUTO 21 | lib_LTLIBRARIES = libhttpserver.la 22 | libhttpserver_la_SOURCES = string_utilities.cpp webserver.cpp http_utils.cpp file_info.cpp http_request.cpp http_response.cpp string_response.cpp basic_auth_fail_response.cpp digest_auth_fail_response.cpp deferred_response.cpp file_response.cpp http_resource.cpp details/http_endpoint.cpp 23 | noinst_HEADERS = httpserver/string_utilities.hpp httpserver/details/modded_request.hpp gettext.h 24 | nobase_include_HEADERS = httpserver.hpp httpserver/create_webserver.hpp httpserver/webserver.hpp httpserver/http_utils.hpp httpserver/file_info.hpp httpserver/details/http_endpoint.hpp httpserver/http_request.hpp httpserver/http_response.hpp httpserver/http_resource.hpp httpserver/string_response.hpp httpserver/basic_auth_fail_response.hpp httpserver/digest_auth_fail_response.hpp httpserver/deferred_response.hpp httpserver/file_response.hpp httpserver/http_arg_value.hpp 25 | 26 | AM_CXXFLAGS += -fPIC -Wall 27 | 28 | if COND_GCOV 29 | AM_CFLAGS += -O0 --coverage --no-inline 30 | AM_CXXFLAGS += -O0 --coverage --no-inline 31 | AM_LDFLAGS += -O0 --coverage -lgcov --no-inline 32 | endif 33 | 34 | if !COND_CROSS_COMPILE 35 | libhttpserver_la_LIBADD = -lmicrohttpd 36 | endif 37 | 38 | libhttpserver_la_CFLAGS = $(AM_CFLAGS) 39 | libhttpserver_la_CXXFLAGS = $(AM_CXXFLAGS) 40 | libhttpserver_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined 41 | 42 | install-data-hook: 43 | (mkdir -p $(DESTDIR)$(includedir) && cd $(DESTDIR)$(includedir) && $(LN_S) -f httpserver.hpp httpserverpp) 44 | 45 | uninstall-hook: 46 | (cd $(DESTDIR)$(includedir) && rm -f httpserverpp) 47 | -------------------------------------------------------------------------------- /src/basic_auth_fail_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/basic_auth_fail_response.hpp" 22 | #include 23 | #include 24 | 25 | struct MHD_Connection; 26 | struct MHD_Response; 27 | 28 | namespace httpserver { 29 | 30 | int basic_auth_fail_response::enqueue_response(MHD_Connection* connection, MHD_Response* response) { 31 | return MHD_queue_basic_auth_fail_response(connection, realm.c_str(), response); 32 | } 33 | 34 | } // namespace httpserver 35 | -------------------------------------------------------------------------------- /src/deferred_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/deferred_response.hpp" 22 | #include 23 | #include 24 | 25 | struct MHD_Response; 26 | 27 | namespace httpserver { 28 | 29 | namespace details { 30 | 31 | MHD_Response* get_raw_response_helper(void* cls, ssize_t (*cb)(void*, uint64_t, char*, size_t)) { 32 | return MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 1024, cb, cls, nullptr); 33 | } 34 | 35 | } // namespace details 36 | 37 | } // namespace httpserver 38 | -------------------------------------------------------------------------------- /src/details/http_endpoint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | // Disabling lint error on regex (the only reason it errors is because the Chromium team prefers google/re2) 26 | #include // NOLINT [build/c++11] 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "httpserver/details/http_endpoint.hpp" 33 | #include "httpserver/http_utils.hpp" 34 | 35 | using std::string; 36 | using std::vector; 37 | 38 | namespace httpserver { 39 | 40 | namespace details { 41 | 42 | http_endpoint::~http_endpoint() { 43 | } 44 | 45 | http_endpoint::http_endpoint(const string& url, bool family, bool registration, bool use_regex): 46 | family_url(family), 47 | reg_compiled(false) { 48 | if (use_regex && !registration) { 49 | throw std::invalid_argument("Cannot use regex if not during registration"); 50 | } 51 | 52 | url_normalized = use_regex ? "^/" : "/"; 53 | vector parts; 54 | 55 | #ifdef CASE_INSENSITIVE 56 | string_utilities::to_lower_copy(url, url_complete); 57 | #else 58 | url_complete = url; 59 | #endif 60 | 61 | if (url_complete[url_complete.size() - 1] == '/') { 62 | url_complete = url_complete.substr(0, url_complete.size() - 1); 63 | } 64 | 65 | if (url_complete[0] != '/') { 66 | url_complete = "/" + url_complete; 67 | } 68 | 69 | parts = httpserver::http::http_utils::tokenize_url(url); 70 | string buffered; 71 | bool first = true; 72 | 73 | for (unsigned int i = 0; i < parts.size(); i++) { 74 | if (!registration) { 75 | url_normalized += (first ? "" : "/") + parts[i]; 76 | first = false; 77 | 78 | url_pieces.push_back(parts[i]); 79 | 80 | continue; 81 | } 82 | 83 | if ((parts[i] != "") && (parts[i][0] != '{')) { 84 | if (first) { 85 | url_normalized = (parts[i][0] == '^' ? "" : url_normalized) + parts[i]; 86 | first = false; 87 | } else { 88 | url_normalized += "/" + parts[i]; 89 | } 90 | url_pieces.push_back(parts[i]); 91 | 92 | continue; 93 | } 94 | 95 | if ((parts[i].size() < 3) || (parts[i][0] != '{') || (parts[i][parts[i].size() - 1] != '}')) { 96 | throw std::invalid_argument("Bad URL format"); 97 | } 98 | 99 | std::string::size_type bar = parts[i].find_first_of('|'); 100 | url_pars.push_back(parts[i].substr(1, bar != string::npos ? bar - 1 : parts[i].size() - 2)); 101 | url_normalized += (first ? "" : "/") + (bar != string::npos ? parts[i].substr(bar + 1, parts[i].size() - bar - 2) : "([^\\/]+)"); 102 | 103 | first = false; 104 | 105 | chunk_positions.push_back(i); 106 | 107 | url_pieces.push_back(parts[i]); 108 | } 109 | 110 | if (use_regex) { 111 | url_normalized += "$"; 112 | try { 113 | re_url_normalized = std::regex(url_normalized, std::regex::extended | std::regex::icase | std::regex::nosubs); 114 | } catch (std::regex_error& e) { 115 | throw std::invalid_argument("Not a valid regex in URL: " + url_normalized); 116 | } 117 | reg_compiled = true; 118 | } 119 | } 120 | 121 | http_endpoint::http_endpoint(const http_endpoint& h): 122 | url_complete(h.url_complete), 123 | url_normalized(h.url_normalized), 124 | url_pars(h.url_pars), 125 | url_pieces(h.url_pieces), 126 | chunk_positions(h.chunk_positions), 127 | re_url_normalized(h.re_url_normalized), 128 | family_url(h.family_url), 129 | reg_compiled(h.reg_compiled) { 130 | } 131 | 132 | http_endpoint& http_endpoint::operator =(const http_endpoint& h) { 133 | url_complete = h.url_complete; 134 | url_normalized = h.url_normalized; 135 | family_url = h.family_url; 136 | reg_compiled = h.reg_compiled; 137 | re_url_normalized = h.re_url_normalized; 138 | url_pars = h.url_pars; 139 | url_pieces = h.url_pieces; 140 | chunk_positions = h.chunk_positions; 141 | return *this; 142 | } 143 | 144 | bool http_endpoint::operator <(const http_endpoint& b) const { 145 | if (family_url != b.family_url) return family_url; 146 | COMPARATOR(url_normalized, b.url_normalized, std::toupper); 147 | } 148 | 149 | bool http_endpoint::match(const http_endpoint& url) const { 150 | if (!reg_compiled) throw std::invalid_argument("Cannot run match. Regex suppressed."); 151 | 152 | if (!family_url || url.url_pieces.size() < url_pieces.size()) { 153 | return regex_match(url.url_complete, re_url_normalized); 154 | } 155 | 156 | string nn = "/"; 157 | bool first = true; 158 | for (unsigned int i = 0; i < url_pieces.size(); i++) { 159 | nn += (first ? "" : "/") + url.url_pieces[i]; 160 | first = false; 161 | } 162 | return regex_match(nn, re_url_normalized); 163 | } 164 | 165 | } // namespace details 166 | 167 | } // namespace httpserver 168 | -------------------------------------------------------------------------------- /src/digest_auth_fail_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/digest_auth_fail_response.hpp" 22 | #include 23 | #include 24 | 25 | struct MHD_Connection; 26 | struct MHD_Response; 27 | 28 | namespace httpserver { 29 | 30 | int digest_auth_fail_response::enqueue_response(MHD_Connection* connection, MHD_Response* response) { 31 | return MHD_queue_auth_fail_response(connection, realm.c_str(), opaque.c_str(), response, reload_nonce ? MHD_YES : MHD_NO); 32 | } 33 | 34 | } // namespace httpserver 35 | -------------------------------------------------------------------------------- /src/file_info.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include "httpserver/file_info.hpp" 23 | 24 | namespace httpserver { 25 | namespace http { 26 | 27 | void file_info::set_file_system_file_name(const std::string& file_system_file_name) { 28 | _file_system_file_name = file_system_file_name; 29 | } 30 | 31 | void file_info::set_content_type(const std::string& content_type) { 32 | _content_type = content_type; 33 | } 34 | 35 | void file_info::set_transfer_encoding(const std::string& transfer_encoding) { 36 | _transfer_encoding = transfer_encoding; 37 | } 38 | 39 | void file_info::grow_file_size(size_t additional_file_size) { 40 | _file_size += additional_file_size; 41 | } 42 | size_t file_info::get_file_size() const { 43 | return _file_size; 44 | } 45 | const std::string file_info::get_file_system_file_name() const { 46 | return _file_system_file_name; 47 | } 48 | const std::string file_info::get_content_type() const { 49 | return _content_type; 50 | } 51 | const std::string file_info::get_transfer_encoding() const { 52 | return _transfer_encoding; 53 | } 54 | 55 | } // namespace http 56 | } // namespace httpserver 57 | -------------------------------------------------------------------------------- /src/file_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/file_response.hpp" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | struct MHD_Response; 31 | 32 | namespace httpserver { 33 | 34 | MHD_Response* file_response::get_raw_response() { 35 | struct stat sb; 36 | 37 | // Deny everything but regular files 38 | if (stat(filename.c_str(), &sb) == 0) { 39 | if (!S_ISREG(sb.st_mode)) return nullptr; 40 | } else { 41 | return nullptr; 42 | } 43 | 44 | int fd = open(filename.c_str(), O_RDONLY); 45 | if (fd == -1) return nullptr; 46 | 47 | off_t size = lseek(fd, 0, SEEK_END); 48 | if (size == (off_t) -1) return nullptr; 49 | 50 | if (size) { 51 | return MHD_create_response_from_fd(size, fd); 52 | } else { 53 | return MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); 54 | } 55 | } 56 | 57 | } // namespace httpserver 58 | -------------------------------------------------------------------------------- /src/gettext.h: -------------------------------------------------------------------------------- 1 | /* Convenience header for conditional use of GNU . 2 | Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2012 Free Software 3 | Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License along 16 | with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 | 19 | #ifndef _LIBGETTEXT_H 20 | #define _LIBGETTEXT_H 1 21 | 22 | /* NLS can be disabled through the configure --disable-nls option. */ 23 | #if ENABLE_NLS 24 | 25 | /* Get declarations of GNU message catalog functions. */ 26 | # include 27 | 28 | /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by 29 | the gettext() and ngettext() macros. This is an alternative to calling 30 | textdomain(), and is useful for libraries. */ 31 | # ifdef DEFAULT_TEXT_DOMAIN 32 | # undef gettext 33 | # define gettext(Msgid) \ 34 | dgettext (DEFAULT_TEXT_DOMAIN, Msgid) 35 | # undef ngettext 36 | # define ngettext(Msgid1, Msgid2, N) \ 37 | dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) 38 | # endif 39 | 40 | #else 41 | 42 | /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which 43 | chokes if dcgettext is defined as a macro. So include it now, to make 44 | later inclusions of a NOP. We don't include 45 | as well because people using "gettext.h" will not include , 46 | and also including would fail on SunOS 4, whereas 47 | is OK. */ 48 | #if defined(__sun) 49 | # include 50 | #endif 51 | 52 | /* Many header files from the libstdc++ coming with g++ 3.3 or newer include 53 | , which chokes if dcgettext is defined as a macro. So include 54 | it now, to make later inclusions of a NOP. */ 55 | #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) 56 | # include 57 | # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H 58 | # include 59 | # endif 60 | #endif 61 | 62 | /* Disabled NLS. 63 | The casts to 'const char *' serve the purpose of producing warnings 64 | for invalid uses of the value returned from these functions. 65 | On pre-ANSI systems without 'const', the config.h file is supposed to 66 | contain "#define const". */ 67 | # undef gettext 68 | # define gettext(Msgid) ((const char *) (Msgid)) 69 | # undef dgettext 70 | # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) 71 | # undef dcgettext 72 | # define dcgettext(Domainname, Msgid, Category) \ 73 | ((void) (Category), dgettext (Domainname, Msgid)) 74 | # undef ngettext 75 | # define ngettext(Msgid1, Msgid2, N) \ 76 | ((N) == 1 \ 77 | ? ((void) (Msgid2), (const char *) (Msgid1)) \ 78 | : ((void) (Msgid1), (const char *) (Msgid2))) 79 | # undef dngettext 80 | # define dngettext(Domainname, Msgid1, Msgid2, N) \ 81 | ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) 82 | # undef dcngettext 83 | # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ 84 | ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) 85 | # undef textdomain 86 | # define textdomain(Domainname) ((const char *) (Domainname)) 87 | # undef bindtextdomain 88 | # define bindtextdomain(Domainname, Dirname) \ 89 | ((void) (Domainname), (const char *) (Dirname)) 90 | # undef bind_textdomain_codeset 91 | # define bind_textdomain_codeset(Domainname, Codeset) \ 92 | ((void) (Domainname), (const char *) (Codeset)) 93 | 94 | #endif 95 | 96 | /* Prefer gnulib's setlocale override over libintl's setlocale override. */ 97 | #ifdef GNULIB_defined_setlocale 98 | # undef setlocale 99 | # define setlocale rpl_setlocale 100 | #endif 101 | 102 | /* A pseudo function call that serves as a marker for the automated 103 | extraction of messages, but does not call gettext(). The run-time 104 | translation is done at a different place in the code. 105 | The argument, String, should be a literal string. Concatenated strings 106 | and other string expressions won't work. 107 | The macro's expansion is not parenthesized, so that it is suitable as 108 | initializer for static 'char[]' or 'const char[]' variables. */ 109 | #define gettext_noop(String) String 110 | 111 | #endif /* _LIBGETTEXT_H */ 112 | -------------------------------------------------------------------------------- /src/http_resource.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | */ 20 | 21 | #include "httpserver/http_resource.hpp" 22 | #include 23 | #include 24 | #include 25 | #include "httpserver/string_response.hpp" 26 | 27 | namespace httpserver { class http_response; } 28 | 29 | namespace httpserver { 30 | 31 | // RESOURCE 32 | void resource_init(std::map* method_state) { 33 | (*method_state)[MHD_HTTP_METHOD_GET] = true; 34 | (*method_state)[MHD_HTTP_METHOD_POST] = true; 35 | (*method_state)[MHD_HTTP_METHOD_PUT] = true; 36 | (*method_state)[MHD_HTTP_METHOD_HEAD] = true; 37 | (*method_state)[MHD_HTTP_METHOD_DELETE] = true; 38 | (*method_state)[MHD_HTTP_METHOD_TRACE] = true; 39 | (*method_state)[MHD_HTTP_METHOD_CONNECT] = true; 40 | (*method_state)[MHD_HTTP_METHOD_OPTIONS] = true; 41 | (*method_state)[MHD_HTTP_METHOD_PATCH] = true; 42 | } 43 | 44 | namespace details { 45 | 46 | std::shared_ptr empty_render(const http_request&) { 47 | return std::make_shared(); 48 | } 49 | 50 | } // namespace details 51 | 52 | } // namespace httpserver 53 | -------------------------------------------------------------------------------- /src/http_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/http_response.hpp" 22 | #include 23 | #include 24 | #include 25 | #include "httpserver/http_utils.hpp" 26 | 27 | namespace httpserver { 28 | 29 | MHD_Response* http_response::get_raw_response() { 30 | return MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); 31 | } 32 | 33 | void http_response::decorate_response(MHD_Response* response) { 34 | std::map::iterator it; 35 | 36 | for (it=headers.begin() ; it != headers.end(); ++it) { 37 | MHD_add_response_header(response, (*it).first.c_str(), (*it).second.c_str()); 38 | } 39 | 40 | for (it=footers.begin() ; it != footers.end(); ++it) { 41 | MHD_add_response_footer(response, (*it).first.c_str(), (*it).second.c_str()); 42 | } 43 | 44 | for (it=cookies.begin(); it != cookies.end(); ++it) { 45 | MHD_add_response_header(response, "Set-Cookie", ((*it).first + "=" + (*it).second).c_str()); 46 | } 47 | } 48 | 49 | int http_response::enqueue_response(MHD_Connection* connection, MHD_Response* response) { 50 | return MHD_queue_response(connection, response_code, response); 51 | } 52 | 53 | void http_response::shoutCAST() { 54 | response_code |= http::http_utils::shoutcast_response; 55 | } 56 | 57 | namespace { 58 | static inline http::header_view_map to_view_map(const http::header_map& hdr_map) { 59 | http::header_view_map view_map; 60 | for (const auto& item : hdr_map) { 61 | view_map[std::string_view(item.first)] = std::string_view(item.second); 62 | } 63 | return view_map; 64 | } 65 | } 66 | 67 | std::ostream &operator<< (std::ostream& os, const http_response& r) { 68 | os << "Response [response_code:" << r.response_code << "]" << std::endl; 69 | 70 | http::dump_header_map(os, "Headers", to_view_map(r.headers)); 71 | http::dump_header_map(os, "Footers", to_view_map(r.footers)); 72 | http::dump_header_map(os, "Cookies", to_view_map(r.cookies)); 73 | 74 | return os; 75 | } 76 | 77 | } // namespace httpserver 78 | -------------------------------------------------------------------------------- /src/httpserver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #ifndef SRC_HTTPSERVER_HPP_ 22 | #define SRC_HTTPSERVER_HPP_ 23 | 24 | #if __cplusplus < 201703L 25 | # error("libhttpserver requires C++17 or later.") 26 | #endif 27 | 28 | #define _HTTPSERVER_HPP_INSIDE_ 29 | 30 | #include "httpserver/basic_auth_fail_response.hpp" 31 | #include "httpserver/deferred_response.hpp" 32 | #include "httpserver/digest_auth_fail_response.hpp" 33 | #include "httpserver/file_response.hpp" 34 | #include "httpserver/http_arg_value.hpp" 35 | #include "httpserver/http_request.hpp" 36 | #include "httpserver/http_resource.hpp" 37 | #include "httpserver/http_response.hpp" 38 | #include "httpserver/http_utils.hpp" 39 | #include "httpserver/file_info.hpp" 40 | #include "httpserver/string_response.hpp" 41 | #include "httpserver/webserver.hpp" 42 | 43 | #endif // SRC_HTTPSERVER_HPP_ 44 | -------------------------------------------------------------------------------- /src/httpserver/basic_auth_fail_response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_BASIC_AUTH_FAIL_RESPONSE_HPP_ 26 | #define SRC_HTTPSERVER_BASIC_AUTH_FAIL_RESPONSE_HPP_ 27 | 28 | #include 29 | #include "httpserver/http_utils.hpp" 30 | #include "httpserver/string_response.hpp" 31 | 32 | struct MHD_Connection; 33 | struct MHD_Response; 34 | 35 | namespace httpserver { 36 | 37 | class basic_auth_fail_response : public string_response { 38 | public: 39 | basic_auth_fail_response() = default; 40 | 41 | explicit basic_auth_fail_response( 42 | const std::string& content, 43 | const std::string& realm = "", 44 | int response_code = http::http_utils::http_ok, 45 | const std::string& content_type = http::http_utils::text_plain): 46 | string_response(content, response_code, content_type), 47 | realm(realm) { } 48 | 49 | basic_auth_fail_response(const basic_auth_fail_response& other) = default; 50 | basic_auth_fail_response(basic_auth_fail_response&& other) noexcept = default; 51 | basic_auth_fail_response& operator=(const basic_auth_fail_response& b) = default; 52 | basic_auth_fail_response& operator=(basic_auth_fail_response&& b) = default; 53 | 54 | ~basic_auth_fail_response() = default; 55 | 56 | int enqueue_response(MHD_Connection* connection, MHD_Response* response); 57 | 58 | private: 59 | std::string realm = ""; 60 | }; 61 | 62 | } // namespace httpserver 63 | #endif // SRC_HTTPSERVER_BASIC_AUTH_FAIL_RESPONSE_HPP_ 64 | -------------------------------------------------------------------------------- /src/httpserver/deferred_response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_DEFERRED_RESPONSE_HPP_ 26 | #define SRC_HTTPSERVER_DEFERRED_RESPONSE_HPP_ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "httpserver/http_utils.hpp" 34 | #include "httpserver/string_response.hpp" 35 | 36 | struct MHD_Response; 37 | 38 | namespace httpserver { 39 | 40 | namespace details { 41 | MHD_Response* get_raw_response_helper(void* cls, ssize_t (*cb)(void*, uint64_t, char*, size_t)); 42 | } 43 | 44 | template 45 | class deferred_response : public string_response { 46 | public: 47 | explicit deferred_response( 48 | ssize_t(*cycle_callback)(std::shared_ptr, char*, size_t), 49 | std::shared_ptr closure_data, 50 | const std::string& content = "", 51 | int response_code = http::http_utils::http_ok, 52 | const std::string& content_type = http::http_utils::text_plain): 53 | string_response(content, response_code, content_type), 54 | cycle_callback(cycle_callback), 55 | closure_data(closure_data) { } 56 | 57 | deferred_response(const deferred_response& other) = default; 58 | deferred_response(deferred_response&& other) noexcept = default; 59 | deferred_response& operator=(const deferred_response& b) = default; 60 | deferred_response& operator=(deferred_response&& b) = default; 61 | 62 | ~deferred_response() = default; 63 | 64 | MHD_Response* get_raw_response() { 65 | return details::get_raw_response_helper(reinterpret_cast(this), &cb); 66 | } 67 | 68 | private: 69 | ssize_t (*cycle_callback)(std::shared_ptr, char*, size_t); 70 | std::shared_ptr closure_data; 71 | 72 | static ssize_t cb(void* cls, uint64_t, char* buf, size_t max) { 73 | deferred_response* dfr = static_cast*>(cls); 74 | return dfr->cycle_callback(dfr->closure_data, buf, max); 75 | } 76 | }; 77 | 78 | } // namespace httpserver 79 | #endif // SRC_HTTPSERVER_DEFERRED_RESPONSE_HPP_ 80 | -------------------------------------------------------------------------------- /src/httpserver/details/http_endpoint.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_DETAILS_HTTP_ENDPOINT_HPP_ 26 | #define SRC_HTTPSERVER_DETAILS_HTTP_ENDPOINT_HPP_ 27 | 28 | // cpplint errors on regex because it is replaced (in Chromium) by re2 google library. 29 | // We don't have that alternative here (and we are actively avoiding dependencies). 30 | #include // NOLINT [build/c++11] 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | namespace httpserver { 37 | 38 | namespace details { 39 | 40 | class http_resource; 41 | 42 | /** 43 | * Class representing an Http Endpoint. It is an abstraction used by the APIs. 44 | **/ 45 | class http_endpoint { 46 | public: 47 | /** 48 | * Copy constructor. It is useful expecially to copy regex_t structure that contains dinamically allocated data. 49 | * @param h The http_endpoint to copy 50 | **/ 51 | http_endpoint(const http_endpoint& h); 52 | 53 | /** 54 | * Class Destructor 55 | **/ 56 | ~http_endpoint(); // if inlined it causes problems during ruby wrapper compiling 57 | 58 | /** 59 | * Operator overload for "less than operator". It is used to order endpoints in maps. 60 | * @param b The http_endpoint to compare to 61 | * @return boolean indicating if this is less than b. 62 | **/ 63 | bool operator <(const http_endpoint& b) const; 64 | 65 | /** 66 | * Operator overload for "assignment operator". It is used to copy endpoints to existing objects. 67 | * Is is functional expecially to copy regex_t structure that contains dinamically allocated data. 68 | * @param h The http_endpoint to copy 69 | * @return a reference to the http_endpoint obtained 70 | **/ 71 | http_endpoint& operator =(const http_endpoint& h); 72 | 73 | /** 74 | * Method indicating if this endpoint 'matches' with the one passed. A passed endpoint matches a registered endpoint if 75 | * the regex represented by the registered endpoint matches the passed one. 76 | * @param url The endpoint to match 77 | * @return true if the passed endpoint matches this. 78 | **/ 79 | bool match(const http_endpoint& url) const; 80 | 81 | /** 82 | * Method used to get the complete endpoint url 83 | * @return a string representing the url 84 | **/ 85 | const std::string& get_url_complete() const { 86 | return url_complete; 87 | } 88 | 89 | const std::string& get_url_normalized() const { 90 | return url_normalized; 91 | } 92 | 93 | /** 94 | * Method used to get all pars defined inside an url. 95 | * @return a vector of strings representing all found pars. 96 | **/ 97 | const std::vector& get_url_pars() const { 98 | return url_pars; 99 | } 100 | 101 | /** 102 | * Method used to get all pieces of an url; considering an url splitted by '/'. 103 | * @return a vector of strings representing all found pieces. 104 | **/ 105 | const std::vector& get_url_pieces() const { 106 | return url_pieces; 107 | } 108 | 109 | /** 110 | * Method used to get indexes of all parameters inside url 111 | * @return a vector of int indicating all positions. 112 | **/ 113 | const std::vector& get_chunk_positions() const { 114 | return chunk_positions; 115 | } 116 | 117 | bool is_family_url() const { 118 | return family_url; 119 | } 120 | 121 | bool is_regex_compiled() const { 122 | return reg_compiled; 123 | } 124 | 125 | /** 126 | * Default constructor of the class. 127 | **/ 128 | http_endpoint(): 129 | url_complete("/"), 130 | url_normalized("/"), 131 | re_url_normalized(std::regex("")), // initialize empty 132 | family_url(false), 133 | reg_compiled(false) { } 134 | 135 | /** 136 | * Constructor of the class http_endpoint. It is used to initialize an http_endpoint starting from a string form URL. 137 | * @param url The string representation of the endpoint. All endpoints are in the form "/path/to/resource". 138 | * @param family boolean that indicates if the endpoint is a family endpoint. 139 | * A family endpoint is an endpoint that identifies a root and all its child like the same resource. 140 | * For example, if I identify "/path/" like a family endpoint and I associate to it the resource "A", also 141 | * "/path/to/res/" is automatically associated to resource "A". Default is false. 142 | * @param registration boolean that indicates to the system if this is an endpoint that need to be registered to a webserver 143 | * or it is simply an endpoint to be used for comparisons. Default is false. 144 | * @param use_regex boolean that indicates if regexes are checked or not. Default is true. 145 | **/ 146 | http_endpoint(const std::string& url, 147 | bool family = false, 148 | bool registration = false, 149 | bool use_regex = false); 150 | 151 | private: 152 | /** 153 | * The complete url extracted 154 | **/ 155 | std::string url_complete; 156 | 157 | /** 158 | * The url standardized in order to use standard comparisons or regexes 159 | **/ 160 | std::string url_normalized; 161 | 162 | /** 163 | * Vector containing parameters extracted from url 164 | **/ 165 | std::vector url_pars; 166 | 167 | /** 168 | * Pieces the url can be splitted into (consider '/' as separator) 169 | **/ 170 | std::vector url_pieces; 171 | 172 | /** 173 | * Position of url pieces representing parameters 174 | **/ 175 | std::vector chunk_positions; 176 | 177 | /** 178 | * Regex used in comparisons 179 | **/ 180 | std::regex re_url_normalized; 181 | 182 | /** 183 | * Boolean indicating wheter the endpoint represents a family 184 | **/ 185 | bool family_url; 186 | 187 | /** 188 | * Boolean indicating if the regex is compiled 189 | **/ 190 | bool reg_compiled; 191 | }; 192 | 193 | } // namespace details 194 | 195 | } // namespace httpserver 196 | #endif // SRC_HTTPSERVER_DETAILS_HTTP_ENDPOINT_HPP_ 197 | -------------------------------------------------------------------------------- /src/httpserver/details/modded_request.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_DETAILS_MODDED_REQUEST_HPP_ 26 | #define SRC_HTTPSERVER_DETAILS_MODDED_REQUEST_HPP_ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "httpserver/http_request.hpp" 33 | 34 | namespace httpserver { 35 | 36 | namespace details { 37 | 38 | struct modded_request { 39 | struct MHD_PostProcessor *pp = nullptr; 40 | std::unique_ptr complete_uri; 41 | std::unique_ptr standardized_url; 42 | webserver* ws = nullptr; 43 | 44 | std::shared_ptr (httpserver::http_resource::*callback)(const httpserver::http_request&); 45 | 46 | std::unique_ptr dhr = nullptr; 47 | std::shared_ptr dhrs; 48 | bool has_body = false; 49 | 50 | std::string upload_key; 51 | std::string upload_filename; 52 | std::unique_ptr upload_ostrm; 53 | 54 | modded_request() = default; 55 | 56 | modded_request(const modded_request& b) = delete; 57 | modded_request(modded_request&& b) = default; 58 | 59 | modded_request& operator=(const modded_request& b) = delete; 60 | modded_request& operator=(modded_request&& b) = default; 61 | 62 | ~modded_request() { 63 | if (nullptr != pp) { 64 | MHD_destroy_post_processor(pp); 65 | } 66 | } 67 | }; 68 | 69 | } // namespace details 70 | 71 | } // namespace httpserver 72 | 73 | #endif // SRC_HTTPSERVER_DETAILS_MODDED_REQUEST_HPP_ 74 | -------------------------------------------------------------------------------- /src/httpserver/digest_auth_fail_response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_DIGEST_AUTH_FAIL_RESPONSE_HPP_ 26 | #define SRC_HTTPSERVER_DIGEST_AUTH_FAIL_RESPONSE_HPP_ 27 | 28 | #include 29 | #include "httpserver/http_utils.hpp" 30 | #include "httpserver/string_response.hpp" 31 | 32 | struct MHD_Connection; 33 | struct MHD_Response; 34 | 35 | namespace httpserver { 36 | 37 | class digest_auth_fail_response : public string_response { 38 | public: 39 | digest_auth_fail_response() = default; 40 | 41 | digest_auth_fail_response(const std::string& content, 42 | const std::string& realm = "", 43 | const std::string& opaque = "", 44 | bool reload_nonce = false, 45 | int response_code = http::http_utils::http_ok, 46 | const std::string& content_type = http::http_utils::text_plain): 47 | string_response(content, response_code, content_type), 48 | realm(realm), 49 | opaque(opaque), 50 | reload_nonce(reload_nonce) { } 51 | 52 | digest_auth_fail_response(const digest_auth_fail_response& other) = default; 53 | digest_auth_fail_response(digest_auth_fail_response&& other) noexcept = default; 54 | digest_auth_fail_response& operator=(const digest_auth_fail_response& b) = default; 55 | digest_auth_fail_response& operator=(digest_auth_fail_response&& b) = default; 56 | 57 | ~digest_auth_fail_response() = default; 58 | 59 | int enqueue_response(MHD_Connection* connection, MHD_Response* response); 60 | 61 | private: 62 | std::string realm = ""; 63 | std::string opaque = ""; 64 | bool reload_nonce = false; 65 | }; 66 | 67 | } // namespace httpserver 68 | 69 | #endif // SRC_HTTPSERVER_DIGEST_AUTH_FAIL_RESPONSE_HPP_ 70 | -------------------------------------------------------------------------------- /src/httpserver/file_info.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_FILE_INFO_HPP_ 26 | #define SRC_HTTPSERVER_FILE_INFO_HPP_ 27 | 28 | #include 29 | 30 | namespace httpserver { 31 | class webserver; 32 | 33 | namespace http { 34 | 35 | class file_info { 36 | public: 37 | size_t get_file_size() const; 38 | const std::string get_file_system_file_name() const; 39 | const std::string get_content_type() const; 40 | const std::string get_transfer_encoding() const; 41 | 42 | file_info() = default; 43 | 44 | private: 45 | size_t _file_size; 46 | std::string _file_system_file_name; 47 | std::string _content_type; 48 | std::string _transfer_encoding; 49 | 50 | void set_file_system_file_name(const std::string& file_system_file_name); 51 | void set_content_type(const std::string& content_type); 52 | void set_transfer_encoding(const std::string& transfer_encoding); 53 | void grow_file_size(size_t additional_file_size); 54 | 55 | friend class httpserver::webserver; 56 | }; 57 | 58 | } // namespace http 59 | } // namespace httpserver 60 | #endif // SRC_HTTPSERVER_FILE_INFO_HPP_ 61 | 62 | -------------------------------------------------------------------------------- /src/httpserver/file_response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_FILE_RESPONSE_HPP_ 26 | #define SRC_HTTPSERVER_FILE_RESPONSE_HPP_ 27 | 28 | #include 29 | #include "httpserver/http_utils.hpp" 30 | #include "httpserver/http_response.hpp" 31 | 32 | struct MHD_Response; 33 | 34 | namespace httpserver { 35 | 36 | class file_response : public http_response { 37 | public: 38 | file_response() = default; 39 | 40 | /** 41 | * Constructor of the class file_response. You usually use this to pass a 42 | * filename to the instance. 43 | * @param filename Name of the file which content should be sent with the 44 | * response. User must make sure file exists and is a 45 | * regular file, otherwise libhttpserver will return a 46 | * generic response with HTTP status 500 (Internal Server 47 | * Error). 48 | * @param response_code HTTP response code in good case, optional, 49 | * default is 200 (OK). 50 | * @param content_type Mime type of the file content, e.g. "text/html", 51 | * optional, default is "application/octet-stream". 52 | **/ 53 | explicit file_response( 54 | const std::string& filename, 55 | int response_code = http::http_utils::http_ok, 56 | const std::string& content_type = http::http_utils::application_octet_stream): 57 | http_response(response_code, content_type), 58 | filename(filename) { } 59 | 60 | file_response(const file_response& other) = default; 61 | file_response(file_response&& other) noexcept = default; 62 | 63 | file_response& operator=(const file_response& b) = default; 64 | file_response& operator=(file_response&& b) = default; 65 | 66 | ~file_response() = default; 67 | 68 | MHD_Response* get_raw_response(); 69 | 70 | private: 71 | std::string filename = ""; 72 | }; 73 | 74 | } // namespace httpserver 75 | #endif // SRC_HTTPSERVER_FILE_RESPONSE_HPP_ 76 | -------------------------------------------------------------------------------- /src/httpserver/http_arg_value.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_HTTP_ARG_VALUE_HPP_ 26 | #define SRC_HTTPSERVER_HTTP_ARG_VALUE_HPP_ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace httpserver { 33 | 34 | class http_arg_value { 35 | public: 36 | std::string_view get_flat_value() const { 37 | return values.empty() ? "" : values[0]; 38 | } 39 | 40 | std::vector get_all_values() const { 41 | return values; 42 | } 43 | 44 | operator std::string() const { 45 | return std::string(get_flat_value()); 46 | } 47 | 48 | operator std::string_view() const { 49 | return get_flat_value(); 50 | } 51 | 52 | operator std::vector() const { 53 | std::vector result; 54 | for (auto const & value : values) { 55 | result.push_back(std::string(value)); 56 | } 57 | return result; 58 | } 59 | 60 | std::vector values; 61 | }; 62 | 63 | } // end namespace httpserver 64 | 65 | #endif // SRC_HTTPSERVER_HTTP_ARG_VALUE_HPP_ 66 | -------------------------------------------------------------------------------- /src/httpserver/http_resource.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_HTTP_RESOURCE_HPP_ 26 | #define SRC_HTTPSERVER_HTTP_RESOURCE_HPP_ 27 | 28 | #ifdef DEBUG 29 | #include 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace httpserver { class http_request; } 39 | namespace httpserver { class http_response; } 40 | 41 | namespace httpserver { 42 | 43 | namespace details { std::shared_ptr empty_render(const http_request& r); } 44 | 45 | void resource_init(std::map* res); 46 | 47 | /** 48 | * Class representing a callable http resource. 49 | **/ 50 | class http_resource { 51 | public: 52 | /** 53 | * Class destructor 54 | **/ 55 | virtual ~http_resource() = default; 56 | 57 | /** 58 | * Method used to answer to a generic request 59 | * @param req Request passed through http 60 | * @return A http_response object 61 | **/ 62 | virtual std::shared_ptr render(const http_request& req) { 63 | return details::empty_render(req); 64 | } 65 | 66 | /** 67 | * Method used to answer to a GET request 68 | * @param req Request passed through http 69 | * @return A http_response object 70 | **/ 71 | virtual std::shared_ptr render_GET(const http_request& req) { 72 | return render(req); 73 | } 74 | 75 | /** 76 | * Method used to answer to a POST request 77 | * @param req Request passed through http 78 | * @return A http_response object 79 | **/ 80 | virtual std::shared_ptr render_POST(const http_request& req) { 81 | return render(req); 82 | } 83 | 84 | /** 85 | * Method used to answer to a PUT request 86 | * @param req Request passed through http 87 | * @return A http_response object 88 | **/ 89 | virtual std::shared_ptr render_PUT(const http_request& req) { 90 | return render(req); 91 | } 92 | 93 | /** 94 | * Method used to answer to a HEAD request 95 | * @param req Request passed through http 96 | * @return A http_response object 97 | **/ 98 | virtual std::shared_ptr render_HEAD(const http_request& req) { 99 | return render(req); 100 | } 101 | 102 | /** 103 | * Method used to answer to a DELETE request 104 | * @param req Request passed through http 105 | * @return A http_response object 106 | **/ 107 | virtual std::shared_ptr render_DELETE(const http_request& req) { 108 | return render(req); 109 | } 110 | 111 | /** 112 | * Method used to answer to a TRACE request 113 | * @param req Request passed through http 114 | * @return A http_response object 115 | **/ 116 | virtual std::shared_ptr render_TRACE(const http_request& req) { 117 | return render(req); 118 | } 119 | 120 | /** 121 | * Method used to answer to a OPTIONS request 122 | * @param req Request passed through http 123 | * @return A http_response object 124 | **/ 125 | virtual std::shared_ptr render_OPTIONS(const http_request& req) { 126 | return render(req); 127 | } 128 | 129 | /** 130 | * Method used to answer to a PATCH request 131 | * @param req Request passed through http 132 | * @return A http_response object 133 | **/ 134 | virtual std::shared_ptr render_PATCH(const http_request& req) { 135 | return render(req); 136 | } 137 | 138 | /** 139 | * Method used to answer to a CONNECT request 140 | * @param req Request passed through http 141 | * @return A http_response object 142 | **/ 143 | virtual std::shared_ptr render_CONNECT(const http_request& req) { 144 | return render(req); 145 | } 146 | 147 | /** 148 | * Method used to set if a specific method is allowed or not on this request 149 | * @param method method to set permission on 150 | * @param allowed boolean indicating if the method is allowed or not 151 | **/ 152 | void set_allowing(const std::string& method, bool allowed) { 153 | if (method_state.count(method)) { 154 | method_state[method] = allowed; 155 | } 156 | } 157 | 158 | /** 159 | * Method used to implicitly allow all methods 160 | **/ 161 | void allow_all() { 162 | std::map::iterator it; 163 | for (it=method_state.begin(); it != method_state.end(); ++it) { 164 | method_state[(*it).first] = true; 165 | } 166 | } 167 | 168 | /** 169 | * Method used to implicitly disallow all methods 170 | **/ 171 | void disallow_all() { 172 | std::map::iterator it; 173 | for (it=method_state.begin(); it != method_state.end(); ++it) { 174 | method_state[(*it).first] = false; 175 | } 176 | } 177 | 178 | /** 179 | * Method used to discover if an http method is allowed or not for this resource 180 | * @param method Method to discover allowings 181 | * @return true if the method is allowed 182 | **/ 183 | bool is_allowed(const std::string& method) { 184 | if (method_state.count(method)) { 185 | return method_state[method]; 186 | } else { 187 | #ifdef DEBUG 188 | std::map::iterator it; 189 | for (it = method_state.begin(); it != method_state.end(); ++it) { 190 | std::cout << (*it).first << " -> " << (*it).second << std::endl; 191 | } 192 | #endif // DEBUG 193 | return false; 194 | } 195 | } 196 | 197 | /** 198 | * Method used to return a list of currently allowed HTTP methods for this resource 199 | * @return vector of strings 200 | **/ 201 | std::vector get_allowed_methods() { 202 | std::vector allowed_methods; 203 | 204 | for (auto it = method_state.cbegin(); it != method_state.cend(); ++it) { 205 | if ( (*it).second ) { 206 | allowed_methods.push_back((*it).first); 207 | } 208 | } 209 | 210 | return allowed_methods; 211 | } 212 | 213 | protected: 214 | /** 215 | * Constructor of the class 216 | **/ 217 | http_resource() { 218 | resource_init(&method_state); 219 | } 220 | 221 | /** 222 | * Copy constructor 223 | **/ 224 | http_resource(const http_resource& b) = default; 225 | http_resource(http_resource&& b) noexcept = default; 226 | http_resource& operator=(const http_resource& b) = default; 227 | http_resource& operator=(http_resource&& b) = default; 228 | 229 | private: 230 | friend class webserver; 231 | friend void resource_init(std::map* res); 232 | std::map method_state; 233 | }; 234 | 235 | } // namespace httpserver 236 | #endif // SRC_HTTPSERVER_HTTP_RESOURCE_HPP_ 237 | -------------------------------------------------------------------------------- /src/httpserver/http_response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_HTTP_RESPONSE_HPP_ 26 | #define SRC_HTTPSERVER_HTTP_RESPONSE_HPP_ 27 | 28 | #include 29 | #include 30 | #include 31 | #include "httpserver/http_arg_value.hpp" 32 | #include "httpserver/http_utils.hpp" 33 | 34 | struct MHD_Connection; 35 | struct MHD_Response; 36 | 37 | namespace httpserver { 38 | 39 | /** 40 | * Class representing an abstraction for an Http Response. It is used from classes using these apis to send information through http protocol. 41 | **/ 42 | class http_response { 43 | public: 44 | http_response() = default; 45 | 46 | explicit http_response(int response_code, const std::string& content_type): 47 | response_code(response_code) { 48 | headers[http::http_utils::http_header_content_type] = content_type; 49 | } 50 | 51 | /** 52 | * Copy constructor 53 | * @param b The http_response object to copy attributes value from. 54 | **/ 55 | http_response(const http_response& b) = default; 56 | http_response(http_response&& b) noexcept = default; 57 | 58 | http_response& operator=(const http_response& b) = default; 59 | http_response& operator=(http_response&& b) noexcept = default; 60 | 61 | virtual ~http_response() = default; 62 | 63 | /** 64 | * Method used to get a specified header defined for the response 65 | * @param key The header identification 66 | * @return a string representing the value assumed by the header 67 | **/ 68 | const std::string& get_header(const std::string& key) { 69 | return headers[key]; 70 | } 71 | 72 | /** 73 | * Method used to get a specified footer defined for the response 74 | * @param key The footer identification 75 | * @return a string representing the value assumed by the footer 76 | **/ 77 | const std::string& get_footer(const std::string& key) { 78 | return footers[key]; 79 | } 80 | 81 | const std::string& get_cookie(const std::string& key) { 82 | return cookies[key]; 83 | } 84 | 85 | /** 86 | * Method used to get all headers passed with the request. 87 | * @return a map containing all headers. 88 | **/ 89 | const std::map& get_headers() const { 90 | return headers; 91 | } 92 | 93 | /** 94 | * Method used to get all footers passed with the request. 95 | * @return a map containing all footers. 96 | **/ 97 | const std::map& get_footers() const { 98 | return footers; 99 | } 100 | 101 | const std::map& get_cookies() const { 102 | return cookies; 103 | } 104 | 105 | /** 106 | * Method used to get the response code from the response 107 | * @return The response code 108 | **/ 109 | int get_response_code() const { 110 | return response_code; 111 | } 112 | 113 | void with_header(const std::string& key, const std::string& value) { 114 | headers[key] = value; 115 | } 116 | 117 | void with_footer(const std::string& key, const std::string& value) { 118 | footers[key] = value; 119 | } 120 | 121 | void with_cookie(const std::string& key, const std::string& value) { 122 | cookies[key] = value; 123 | } 124 | 125 | void shoutCAST(); 126 | 127 | virtual MHD_Response* get_raw_response(); 128 | virtual void decorate_response(MHD_Response* response); 129 | virtual int enqueue_response(MHD_Connection* connection, MHD_Response* response); 130 | 131 | private: 132 | int response_code = -1; 133 | 134 | http::header_map headers; 135 | http::header_map footers; 136 | http::header_map cookies; 137 | 138 | protected: 139 | friend std::ostream &operator<< (std::ostream &os, const http_response &r); 140 | }; 141 | 142 | std::ostream &operator<<(std::ostream &os, const http_response &r); 143 | 144 | } // namespace httpserver 145 | #endif // SRC_HTTPSERVER_HTTP_RESPONSE_HPP_ 146 | -------------------------------------------------------------------------------- /src/httpserver/string_response.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_STRING_RESPONSE_HPP_ 26 | #define SRC_HTTPSERVER_STRING_RESPONSE_HPP_ 27 | 28 | #include 29 | #include 30 | #include "httpserver/http_utils.hpp" 31 | #include "httpserver/http_response.hpp" 32 | 33 | struct MHD_Response; 34 | 35 | namespace httpserver { 36 | 37 | class string_response : public http_response { 38 | public: 39 | string_response() = default; 40 | 41 | explicit string_response( 42 | std::string content, 43 | int response_code = http::http_utils::http_ok, 44 | const std::string& content_type = http::http_utils::text_plain): 45 | http_response(response_code, content_type), 46 | content(std::move(content)) { } 47 | 48 | string_response(const string_response& other) = default; 49 | string_response(string_response&& other) noexcept = default; 50 | 51 | string_response& operator=(const string_response& b) = default; 52 | string_response& operator=(string_response&& b) = default; 53 | 54 | ~string_response() = default; 55 | 56 | MHD_Response* get_raw_response(); 57 | 58 | private: 59 | std::string content = ""; 60 | }; 61 | 62 | } // namespace httpserver 63 | #endif // SRC_HTTPSERVER_STRING_RESPONSE_HPP_ 64 | -------------------------------------------------------------------------------- /src/httpserver/string_utilities.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION) 22 | #error "Only or can be included directly." 23 | #endif 24 | 25 | #ifndef SRC_HTTPSERVER_STRING_UTILITIES_HPP_ 26 | #define SRC_HTTPSERVER_STRING_UTILITIES_HPP_ 27 | 28 | #include 29 | #include 30 | 31 | namespace httpserver { 32 | 33 | namespace string_utilities { 34 | 35 | /** 36 | * Function used to convert a string to its uppercase version. 37 | * It generates a new string in output 38 | * @param str The string to turn uppercase 39 | * @return a string that is the uppercase version of the previous 40 | **/ 41 | const std::string to_upper_copy(const std::string& str); 42 | const std::string to_lower_copy(const std::string& str); 43 | const std::vector string_split(const std::string& s, char sep = ' ', bool collapse = true); 44 | 45 | } // namespace string_utilities 46 | 47 | } // namespace httpserver 48 | 49 | #endif // SRC_HTTPSERVER_STRING_UTILITIES_HPP_ 50 | -------------------------------------------------------------------------------- /src/string_response.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/string_response.hpp" 22 | #include 23 | #include 24 | #include 25 | 26 | struct MHD_Response; 27 | 28 | namespace httpserver { 29 | 30 | MHD_Response* string_response::get_raw_response() { 31 | size_t size = &(*content.end()) - &(*content.begin()); 32 | // Need to use a const cast here to satisfy MHD interface that requires a void* 33 | return MHD_create_response_from_buffer(size, reinterpret_cast(const_cast(content.c_str())), MHD_RESPMEM_PERSISTENT); 34 | } 35 | 36 | } // namespace httpserver 37 | -------------------------------------------------------------------------------- /src/string_utilities.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/string_utilities.hpp" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace httpserver { 30 | namespace string_utilities { 31 | 32 | const std::string to_upper_copy(const std::string& str) { 33 | std::string result = str; 34 | std::transform(result.begin(), result.end(), result.begin(), (int(*)(int)) std::toupper); 35 | 36 | return result; 37 | } 38 | 39 | const std::string to_lower_copy(const std::string& str) { 40 | std::string result = str; 41 | std::transform(result.begin(), result.end(), result.begin(), (int(*)(int)) std::tolower); 42 | 43 | return result; 44 | } 45 | 46 | const std::vector string_split(const std::string& s, char sep, bool collapse) { 47 | std::vector result; 48 | 49 | std::istringstream buf(s); 50 | for (std::string token; getline(buf, token, sep); ) { 51 | if ((collapse && token != "") || !collapse) { 52 | result.push_back(token); 53 | } 54 | } 55 | return result; 56 | } 57 | 58 | } // namespace string_utilities 59 | } // namespace httpserver 60 | -------------------------------------------------------------------------------- /test/CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | exclude_files=littletest.hpp 2 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of libhttpserver 3 | # Copyright (C) 2011-2019 Sebastiano Merlino 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | LDADD = $(top_builddir)/src/libhttpserver.la 20 | AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/ 21 | METASOURCES = AUTO 22 | check_PROGRAMS = basic file_upload http_utils threaded nodelay string_utilities http_endpoint ban_system ws_start_stop authentication deferred http_resource 23 | 24 | MOSTLYCLEANFILES = *.gcda *.gcno *.gcov 25 | 26 | basic_SOURCES = integ/basic.cpp 27 | file_upload_SOURCES = integ/file_upload.cpp 28 | threaded_SOURCES = integ/threaded.cpp 29 | ban_system_SOURCES = integ/ban_system.cpp 30 | ws_start_stop_SOURCES = integ/ws_start_stop.cpp 31 | authentication_SOURCES = integ/authentication.cpp 32 | deferred_SOURCES = integ/deferred.cpp 33 | http_utils_SOURCES = unit/http_utils_test.cpp 34 | string_utilities_SOURCES = unit/string_utilities_test.cpp 35 | http_endpoint_SOURCES = unit/http_endpoint_test.cpp 36 | nodelay_SOURCES = integ/nodelay.cpp 37 | http_resource_SOURCES = unit/http_resource_test.cpp 38 | 39 | noinst_HEADERS = littletest.hpp 40 | AM_CXXFLAGS += -lcurl -Wall -fPIC 41 | 42 | if COND_GCOV 43 | AM_CFLAGS += -O0 --coverage --no-inline 44 | AM_CXXFLAGS += -O0 --coverage --no-inline 45 | AM_LDFLAGS += -O0 --coverage -lgcov --no-inline 46 | endif 47 | 48 | TESTS = $(check_PROGRAMS) 49 | 50 | @VALGRIND_CHECK_RULES@ 51 | VALGRIND_SUPPRESSIONS_FILES = libhttpserver.supp 52 | EXTRA_DIST = libhttpserver.supp 53 | -------------------------------------------------------------------------------- /test/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0 3 | MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC 4 | AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X 5 | fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud 6 | 3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/ 7 | GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv 8 | rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh 9 | siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O 10 | BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2 11 | RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN 12 | 8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/ 13 | 0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe 14 | JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3 15 | OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV 16 | RhZvQx74NQnS6g== 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /test/integ/ban_system.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "./httpserver.hpp" 27 | #include "httpserver/http_utils.hpp" 28 | #include "./littletest.hpp" 29 | 30 | using std::shared_ptr; 31 | 32 | using httpserver::webserver; 33 | using httpserver::create_webserver; 34 | using httpserver::http_resource; 35 | using httpserver::http_response; 36 | using httpserver::string_response; 37 | using httpserver::http_request; 38 | using httpserver::http::http_utils; 39 | 40 | #ifdef HTTPSERVER_PORT 41 | #define PORT HTTPSERVER_PORT 42 | #else 43 | #define PORT 8080 44 | #endif // PORT 45 | 46 | #define STR2(p) #p 47 | #define STR(p) STR2(p) 48 | #define PORT_STRING STR(PORT) 49 | 50 | size_t writefunc(void *ptr, size_t size, size_t nmemb, std::string *s) { 51 | s->append(reinterpret_cast(ptr), size*nmemb); 52 | return size*nmemb; 53 | } 54 | 55 | class ok_resource : public http_resource { 56 | public: 57 | shared_ptr render_GET(const http_request&) { 58 | return std::make_shared("OK", 200, "text/plain"); 59 | } 60 | }; 61 | 62 | LT_BEGIN_SUITE(ban_system_suite) 63 | void set_up() { 64 | } 65 | 66 | void tear_down() { 67 | } 68 | LT_END_SUITE(ban_system_suite) 69 | 70 | LT_BEGIN_AUTO_TEST(ban_system_suite, accept_default_ban_blocks) 71 | webserver ws = create_webserver(PORT).default_policy(http_utils::ACCEPT); 72 | ws.start(false); 73 | 74 | ok_resource resource; 75 | LT_ASSERT_EQ(true, ws.register_resource("base", &resource)); 76 | 77 | curl_global_init(CURL_GLOBAL_ALL); 78 | 79 | { 80 | std::string s; 81 | CURL *curl = curl_easy_init(); 82 | CURLcode res; 83 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 84 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 85 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 86 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 87 | res = curl_easy_perform(curl); 88 | LT_ASSERT_EQ(res, 0); 89 | LT_CHECK_EQ(s, "OK"); 90 | curl_easy_cleanup(curl); 91 | } 92 | 93 | { 94 | ws.ban_ip("127.0.0.1"); 95 | 96 | CURL *curl = curl_easy_init(); 97 | CURLcode res; 98 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 99 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 100 | res = curl_easy_perform(curl); 101 | LT_ASSERT_NEQ(res, 0); 102 | curl_easy_cleanup(curl); 103 | } 104 | 105 | { 106 | ws.unban_ip("127.0.0.1"); 107 | 108 | std::string s; 109 | CURL *curl = curl_easy_init(); 110 | CURLcode res; 111 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 112 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 113 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 114 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 115 | res = curl_easy_perform(curl); 116 | LT_ASSERT_EQ(res, 0); 117 | LT_CHECK_EQ(s, "OK"); 118 | curl_easy_cleanup(curl); 119 | } 120 | 121 | curl_global_cleanup(); 122 | ws.stop(); 123 | LT_END_AUTO_TEST(accept_default_ban_blocks) 124 | 125 | LT_BEGIN_AUTO_TEST(ban_system_suite, reject_default_allow_passes) 126 | webserver ws = create_webserver(PORT).default_policy(http_utils::REJECT); 127 | ws.start(false); 128 | 129 | ok_resource resource; 130 | LT_ASSERT_EQ(true, ws.register_resource("base", &resource)); 131 | 132 | curl_global_init(CURL_GLOBAL_ALL); 133 | 134 | { 135 | CURL *curl = curl_easy_init(); 136 | CURLcode res; 137 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 138 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 139 | res = curl_easy_perform(curl); 140 | LT_ASSERT_NEQ(res, 0); 141 | curl_easy_cleanup(curl); 142 | } 143 | 144 | { 145 | ws.allow_ip("127.0.0.1"); 146 | 147 | std::string s; 148 | CURL *curl = curl_easy_init(); 149 | CURLcode res; 150 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 151 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 152 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 153 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 154 | res = curl_easy_perform(curl); 155 | LT_ASSERT_EQ(res, 0); 156 | LT_CHECK_EQ(s, "OK"); 157 | curl_easy_cleanup(curl); 158 | } 159 | 160 | { 161 | ws.disallow_ip("127.0.0.1"); 162 | 163 | CURL *curl = curl_easy_init(); 164 | CURLcode res; 165 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 166 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 167 | res = curl_easy_perform(curl); 168 | LT_ASSERT_NEQ(res, 0); 169 | curl_easy_cleanup(curl); 170 | } 171 | 172 | curl_global_cleanup(); 173 | ws.stop(); 174 | LT_END_AUTO_TEST(reject_default_allow_passes) 175 | 176 | LT_BEGIN_AUTO_TEST_ENV() 177 | AUTORUN_TESTS() 178 | LT_END_AUTO_TEST_ENV() 179 | -------------------------------------------------------------------------------- /test/integ/deferred.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if defined(_WIN32) && !defined(__CYGWIN__) 22 | #define _WINDOWS 23 | #undef _WIN32_WINNT 24 | #define _WIN32_WINNT 0x600 25 | #include 26 | #include 27 | #else 28 | #include 29 | #include 30 | #include 31 | #endif 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include "./httpserver.hpp" 41 | #include "./littletest.hpp" 42 | 43 | using std::shared_ptr; 44 | using std::string; 45 | 46 | using httpserver::webserver; 47 | using httpserver::create_webserver; 48 | using httpserver::http_response; 49 | using httpserver::http_request; 50 | using httpserver::http_resource; 51 | using httpserver::deferred_response; 52 | 53 | size_t writefunc(void *ptr, size_t size, size_t nmemb, string *s) { 54 | s->append(reinterpret_cast(ptr), size*nmemb); 55 | return size*nmemb; 56 | } 57 | 58 | static int counter = 0; 59 | 60 | struct test_data { 61 | int value; 62 | }; 63 | 64 | ssize_t test_callback(shared_ptr closure_data, char* buf, size_t max) { 65 | std::ignore = closure_data; 66 | 67 | if (counter == 2) { 68 | return -1; 69 | } else { 70 | memset(buf, 0, max); 71 | snprintf(buf, max, "%s", "test"); 72 | counter++; 73 | return string(buf).size(); 74 | } 75 | } 76 | 77 | ssize_t test_callback_with_data(shared_ptr closure_data, char* buf, size_t max) { 78 | if (counter == 2) { 79 | return -1; 80 | } else { 81 | memset(buf, 0, max); 82 | snprintf(buf, max, "%s%s", "test", std::to_string(closure_data->value).c_str()); 83 | 84 | closure_data->value = 84; 85 | 86 | counter++; 87 | return std::string(buf).size(); 88 | } 89 | } 90 | 91 | class deferred_resource : public http_resource { 92 | public: 93 | shared_ptr render_GET(const http_request&) { 94 | return std::make_shared>(test_callback, nullptr, "cycle callback response"); 95 | } 96 | }; 97 | 98 | class deferred_resource_with_data : public http_resource { 99 | public: 100 | shared_ptr render_GET(const http_request&) { 101 | auto internal_info = std::make_shared(); 102 | internal_info->value = 42; 103 | return std::make_shared>(test_callback_with_data, internal_info, "cycle callback response"); 104 | } 105 | }; 106 | 107 | #ifdef HTTPSERVER_PORT 108 | #define PORT HTTPSERVER_PORT 109 | #else 110 | #define PORT 8080 111 | #endif // PORT 112 | 113 | #define STR2(p) #p 114 | #define STR(p) STR2(p) 115 | #define PORT_STRING STR(PORT) 116 | 117 | LT_BEGIN_SUITE(deferred_suite) 118 | std::unique_ptr ws; 119 | 120 | void set_up() { 121 | ws = std::make_unique(create_webserver(PORT)); 122 | ws->start(false); 123 | } 124 | 125 | void tear_down() { 126 | counter = 0; 127 | 128 | ws->stop(); 129 | } 130 | LT_END_SUITE(deferred_suite) 131 | 132 | LT_BEGIN_AUTO_TEST(deferred_suite, deferred_response_suite) 133 | deferred_resource resource; 134 | LT_ASSERT_EQ(true, ws->register_resource("base", &resource)); 135 | curl_global_init(CURL_GLOBAL_ALL); 136 | 137 | std::string s; 138 | CURL *curl = curl_easy_init(); 139 | CURLcode res; 140 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 141 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 142 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 143 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 144 | res = curl_easy_perform(curl); 145 | LT_ASSERT_EQ(res, 0); 146 | LT_CHECK_EQ(s, "testtest"); 147 | curl_easy_cleanup(curl); 148 | LT_END_AUTO_TEST(deferred_response_suite) 149 | 150 | LT_BEGIN_AUTO_TEST(deferred_suite, deferred_response_with_data) 151 | deferred_resource_with_data resource; 152 | LT_ASSERT_EQ(true, ws->register_resource("base", &resource)); 153 | curl_global_init(CURL_GLOBAL_ALL); 154 | 155 | std::string s; 156 | CURL *curl = curl_easy_init(); 157 | CURLcode res; 158 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 159 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 160 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 161 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 162 | res = curl_easy_perform(curl); 163 | LT_ASSERT_EQ(res, 0); 164 | LT_CHECK_EQ(s, "test42test84"); 165 | curl_easy_cleanup(curl); 166 | LT_END_AUTO_TEST(deferred_response_with_data) 167 | 168 | LT_BEGIN_AUTO_TEST_ENV() 169 | AUTORUN_TESTS() 170 | LT_END_AUTO_TEST_ENV() 171 | -------------------------------------------------------------------------------- /test/integ/nodelay.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "./httpserver.hpp" 27 | #include "./littletest.hpp" 28 | 29 | using std::shared_ptr; 30 | 31 | using httpserver::http_resource; 32 | using httpserver::http_response; 33 | using httpserver::string_response; 34 | using httpserver::http_request; 35 | using httpserver::http_resource; 36 | using httpserver::webserver; 37 | using httpserver::create_webserver; 38 | 39 | #ifdef HTTPSERVER_PORT 40 | #define PORT HTTPSERVER_PORT 41 | #else 42 | #define PORT 8080 43 | #endif // PORT 44 | 45 | #define STR2(p) #p 46 | #define STR(p) STR2(p) 47 | #define PORT_STRING STR(PORT) 48 | 49 | class ok_resource : public http_resource { 50 | public: 51 | shared_ptr render_GET(const http_request&) { 52 | return std::make_shared("OK", 200, "text/plain"); 53 | } 54 | }; 55 | 56 | LT_BEGIN_SUITE(threaded_suite) 57 | std::unique_ptr ws; 58 | 59 | void set_up() { 60 | ws = std::make_unique(create_webserver(PORT)); 61 | ws->start(false); 62 | } 63 | 64 | void tear_down() { 65 | ws->stop(); 66 | } 67 | LT_END_SUITE(threaded_suite) 68 | 69 | LT_BEGIN_AUTO_TEST(threaded_suite, base) 70 | ok_resource resource; 71 | LT_ASSERT_EQ(true, ws->register_resource("base", &resource)); 72 | curl_global_init(CURL_GLOBAL_ALL); 73 | std::string s; 74 | CURL* curl; 75 | CURLcode res; 76 | 77 | curl = curl_easy_init(); 78 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 79 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 80 | res = curl_easy_perform(curl); 81 | LT_ASSERT_EQ(res, 0); 82 | curl_easy_cleanup(curl); 83 | LT_END_AUTO_TEST(base) 84 | 85 | LT_BEGIN_AUTO_TEST_ENV() 86 | AUTORUN_TESTS() 87 | LT_END_AUTO_TEST_ENV() 88 | -------------------------------------------------------------------------------- /test/integ/threaded.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #if defined(_WIN32) && !defined(__CYGWIN__) 22 | #define _WINDOWS 23 | #endif 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "./httpserver.hpp" 31 | #include "./littletest.hpp" 32 | 33 | using std::shared_ptr; 34 | 35 | using httpserver::http_resource; 36 | using httpserver::http_request; 37 | using httpserver::http_response; 38 | using httpserver::string_response; 39 | using httpserver::webserver; 40 | using httpserver::create_webserver; 41 | 42 | #ifdef HTTPSERVER_PORT 43 | #define PORT HTTPSERVER_PORT 44 | #else 45 | #define PORT 8080 46 | #endif // PORT 47 | 48 | #define STR2(p) #p 49 | #define STR(p) STR2(p) 50 | #define PORT_STRING STR(PORT) 51 | 52 | class ok_resource : public http_resource { 53 | public: 54 | shared_ptr render_GET(const http_request&) { 55 | return std::make_shared("OK", 200, "text/plain"); 56 | } 57 | }; 58 | 59 | LT_BEGIN_SUITE(threaded_suite) 60 | 61 | #ifndef _WINDOWS 62 | std::unique_ptr ws; 63 | #endif 64 | 65 | void set_up() { 66 | #ifndef _WINDOWS 67 | ws = std::make_unique(create_webserver(PORT).start_method(httpserver::http::http_utils::INTERNAL_SELECT).max_threads(5)); 68 | ws->start(false); 69 | #endif 70 | } 71 | 72 | void tear_down() { 73 | #ifndef _WINDOWS 74 | ws->stop(); 75 | #endif 76 | } 77 | LT_END_SUITE(threaded_suite) 78 | 79 | LT_BEGIN_AUTO_TEST(threaded_suite, base) 80 | #ifndef _WINDOWS 81 | ok_resource resource; 82 | LT_ASSERT_EQ(true, ws->register_resource("base", &resource)); 83 | curl_global_init(CURL_GLOBAL_ALL); 84 | std::string s; 85 | CURL* curl; 86 | CURLcode res; 87 | 88 | curl = curl_easy_init(); 89 | curl_easy_setopt(curl, CURLOPT_URL, "localhost:" PORT_STRING "/base"); 90 | curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); 91 | res = curl_easy_perform(curl); 92 | LT_ASSERT_EQ(res, 0); 93 | curl_easy_cleanup(curl); 94 | #endif 95 | LT_END_AUTO_TEST(base) 96 | 97 | LT_BEGIN_AUTO_TEST_ENV() 98 | AUTORUN_TESTS() 99 | LT_END_AUTO_TEST_ENV() 100 | -------------------------------------------------------------------------------- /test/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf 3 | qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I 4 | niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+ 5 | faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx 6 | 7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ 7 | vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj 8 | lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R 9 | EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l 10 | /5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx 11 | u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/ 12 | dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo 13 | 32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc 14 | +JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd 15 | RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6 16 | OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob 17 | XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF 18 | hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae 19 | SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b 20 | AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH 21 | 6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3 22 | QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG 23 | 7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj 24 | P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9 25 | /Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC 26 | eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /test/libhttpserver.supp: -------------------------------------------------------------------------------- 1 | { 2 | gnutls_session_get_data 3 | Memcheck:Cond 4 | fun:gnutls_session_get_data 5 | } 6 | -------------------------------------------------------------------------------- /test/test_content: -------------------------------------------------------------------------------- 1 | test content of file 2 | -------------------------------------------------------------------------------- /test/test_content_2: -------------------------------------------------------------------------------- 1 | test content of second file 2 | -------------------------------------------------------------------------------- /test/test_content_empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etr/libhttpserver/1b5fe8fb1389f6f9707b7b89c988ef37213b76b6/test/test_content_empty -------------------------------------------------------------------------------- /test/test_root_ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB 3 | qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf 4 | Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw 5 | MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV 6 | BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw 7 | NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j 8 | LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG 9 | A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl 10 | IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG 11 | SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs 12 | W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta 13 | 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk 14 | 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 15 | Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J 16 | NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA 17 | MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP 18 | r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU 19 | DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz 20 | YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX 21 | xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 22 | /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ 23 | LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 24 | jVaMaA== 25 | -----END CERTIFICATE----- 26 | -------------------------------------------------------------------------------- /test/unit/http_resource_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2021 Alexander Dahl 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "./httpserver.hpp" 29 | #include "./littletest.hpp" 30 | 31 | using std::shared_ptr; 32 | using std::sort; 33 | using std::string; 34 | using std::vector; 35 | 36 | using httpserver::http_request; 37 | using httpserver::http_resource; 38 | using httpserver::http_response; 39 | using httpserver::string_response; 40 | 41 | class simple_resource : public http_resource { 42 | public: 43 | shared_ptr render_GET(const http_request&) { 44 | return std::make_shared("OK"); 45 | } 46 | }; 47 | 48 | LT_BEGIN_SUITE(http_resource_suite) 49 | void set_up() { 50 | } 51 | 52 | void tear_down() { 53 | } 54 | LT_END_SUITE(http_resource_suite) 55 | 56 | LT_BEGIN_AUTO_TEST(http_resource_suite, disallow_all_methods) 57 | simple_resource sr; 58 | sr.disallow_all(); 59 | auto allowed_methods = sr.get_allowed_methods(); 60 | LT_CHECK_EQ(allowed_methods.size(), 0); 61 | LT_END_AUTO_TEST(disallow_all_methods) 62 | 63 | LT_BEGIN_AUTO_TEST(http_resource_suite, allow_some_methods) 64 | simple_resource sr; 65 | sr.disallow_all(); 66 | sr.set_allowing(MHD_HTTP_METHOD_GET, true); 67 | sr.set_allowing(MHD_HTTP_METHOD_POST, true); 68 | auto allowed_methods = sr.get_allowed_methods(); 69 | LT_CHECK_EQ(allowed_methods.size(), 2); 70 | // elements in http_resource::method_state are sorted (std::map) 71 | vector some_methods{MHD_HTTP_METHOD_GET, MHD_HTTP_METHOD_POST}; 72 | sort(some_methods.begin(), some_methods.end()); 73 | LT_CHECK_COLLECTIONS_EQ(allowed_methods.cbegin(), allowed_methods.cend(), 74 | some_methods.cbegin()) 75 | LT_END_AUTO_TEST(allow_some_methods) 76 | 77 | LT_BEGIN_AUTO_TEST(http_resource_suite, allow_all_methods) 78 | simple_resource sr; 79 | sr.allow_all(); 80 | auto allowed_methods = sr.get_allowed_methods(); 81 | // elements in http_resource::method_state are sorted (std::map) 82 | vector all_methods{MHD_HTTP_METHOD_GET, MHD_HTTP_METHOD_POST, 83 | MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_HEAD, MHD_HTTP_METHOD_DELETE, 84 | MHD_HTTP_METHOD_TRACE, MHD_HTTP_METHOD_CONNECT, 85 | MHD_HTTP_METHOD_OPTIONS, MHD_HTTP_METHOD_PATCH}; 86 | sort(all_methods.begin(), all_methods.end()); 87 | LT_CHECK_COLLECTIONS_EQ(allowed_methods.cbegin(), allowed_methods.cend(), 88 | all_methods.cbegin()) 89 | LT_END_AUTO_TEST(allow_all_methods) 90 | 91 | LT_BEGIN_AUTO_TEST_ENV() 92 | AUTORUN_TESTS() 93 | LT_END_AUTO_TEST_ENV() 94 | -------------------------------------------------------------------------------- /test/unit/string_utilities_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libhttpserver 3 | Copyright (C) 2011-2019 Sebastiano Merlino 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | */ 20 | 21 | #include "httpserver/string_utilities.hpp" 22 | 23 | #include 24 | 25 | #include "./littletest.hpp" 26 | 27 | using std::string; 28 | using std::vector; 29 | 30 | LT_BEGIN_SUITE(string_utilities_suite) 31 | void set_up() { 32 | } 33 | 34 | void tear_down() { 35 | } 36 | LT_END_SUITE(string_utilities_suite) 37 | 38 | LT_BEGIN_AUTO_TEST(string_utilities_suite, to_upper_copy) 39 | LT_CHECK_EQ(httpserver::string_utilities::to_upper_copy("test message"), string("TEST MESSAGE")); 40 | LT_CHECK_EQ(httpserver::string_utilities::to_upper_copy("tEsT mEssAge 245&$"), string("TEST MESSAGE 245&$")); 41 | LT_END_AUTO_TEST(to_upper_copy) 42 | 43 | LT_BEGIN_AUTO_TEST(string_utilities_suite, to_lower_copy) 44 | LT_CHECK_EQ(httpserver::string_utilities::to_lower_copy("TEST MESSAGE"), string("test message")); 45 | LT_CHECK_EQ(httpserver::string_utilities::to_lower_copy("tEsT mEssAge 245&$"), string("test message 245&$")); 46 | LT_END_AUTO_TEST(to_lower_copy) 47 | 48 | LT_BEGIN_AUTO_TEST(string_utilities_suite, split_string) 49 | string value = "test this message here"; 50 | string expected_arr[] = { "test", "this", "message", "here" }; 51 | vector expected(expected_arr, expected_arr + sizeof(expected_arr) / sizeof(expected_arr[0])); 52 | vector actual = httpserver::string_utilities::string_split(value, ' ', false); 53 | 54 | LT_CHECK_COLLECTIONS_EQ(expected.begin(), expected.end(), actual.begin()); 55 | LT_END_AUTO_TEST(split_string) 56 | 57 | LT_BEGIN_AUTO_TEST(string_utilities_suite, split_string_multiple_spaces) 58 | string value = "test this message here"; 59 | string expected_arr[] = { "test", "", "this", "", "message", "", "here" }; 60 | vector expected(expected_arr, expected_arr + sizeof(expected_arr) / sizeof(expected_arr[0])); 61 | vector actual = httpserver::string_utilities::string_split(value, ' ', false); 62 | 63 | LT_CHECK_COLLECTIONS_EQ(expected.begin(), expected.end(), actual.begin()); 64 | LT_END_AUTO_TEST(split_string_multiple_spaces) 65 | 66 | LT_BEGIN_AUTO_TEST(string_utilities_suite, split_string_multiple_spaces_collapse) 67 | string value = "test this message here"; 68 | string expected_arr[] = { "test", "this", "message", "here" }; 69 | vector expected(expected_arr, expected_arr + sizeof(expected_arr) / sizeof(expected_arr[0])); 70 | vector actual = httpserver::string_utilities::string_split(value, ' ', true); 71 | 72 | LT_CHECK_COLLECTIONS_EQ(expected.begin(), expected.end(), actual.begin()); 73 | LT_END_AUTO_TEST(split_string_multiple_spaces_collapse) 74 | 75 | LT_BEGIN_AUTO_TEST(string_utilities_suite, split_string_end_space) 76 | string value = "test this message here "; 77 | string expected_arr[] = { "test", "this", "message", "here" }; 78 | vector expected(expected_arr, expected_arr + sizeof(expected_arr) / sizeof(expected_arr[0])); 79 | vector actual = httpserver::string_utilities::string_split(value, ' ', false); 80 | 81 | LT_CHECK_COLLECTIONS_EQ(expected.begin(), expected.end(), actual.begin()); 82 | LT_END_AUTO_TEST(split_string_end_space) 83 | 84 | LT_BEGIN_AUTO_TEST_ENV() 85 | AUTORUN_TESTS() 86 | LT_END_AUTO_TEST_ENV() 87 | --------------------------------------------------------------------------------