pax_global_header00006660000000000000000000000064147543236670014533gustar00rootroot0000000000000052 comment=6854bb0298eb6cc948c30179a37781a008b4f046 HTTPing-4.4.0/000077500000000000000000000000001475432366700130155ustar00rootroot00000000000000HTTPing-4.4.0/.editorconfig000066400000000000000000000003221475432366700154670ustar00rootroot00000000000000root = true [*] charset = utf-8 max_line_length = 80 end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true [{CMakeLists.txt,*.cmake}] indent_style = space indent_size = 2 tab_width = 2 HTTPing-4.4.0/.github/000077500000000000000000000000001475432366700143555ustar00rootroot00000000000000HTTPing-4.4.0/.github/FUNDING.yml000066400000000000000000000000671475432366700161750ustar00rootroot00000000000000github: [folkertvanheusden] patreon: folkertvanheusden HTTPing-4.4.0/.github/workflows/000077500000000000000000000000001475432366700164125ustar00rootroot00000000000000HTTPing-4.4.0/.github/workflows/codeql-analysis.yml000066400000000000000000000044371475432366700222350ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: push: branches: [ master ] pull_request: # The branches below must be a subset of the branches above branches: [ master ] schedule: - cron: '29 21 * * 1' jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://git.io/codeql-language-support steps: - name: Checkout repository uses: actions/checkout@v2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 HTTPing-4.4.0/.github/workflows/compile.yml000066400000000000000000000057671475432366700206040ustar00rootroot00000000000000name: native and cross on: [push, pull_request] jobs: build: runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: release: - "ubuntu:22.04" - "ubuntu:24.04" - "ubuntu:rolling" - "debian:stable-slim" - "debian:testing-slim" - "debian:unstable-slim" - "debian:experimental" steps: - uses: actions/checkout@v4 - name: Prepare ${{ matrix.release }} container env: release: ${{ matrix.release == 'debian:experimental' && '-t experimental' || '' }} run: | podman version podman run --name stable -di --userns=keep-id:uid=1000,gid=1000 -v "$PWD":/home -w /home ${{ matrix.release }} bash podman exec -i stable uname -a podman exec -i stable id podman exec -i -u root stable apt update podman exec -e DEBIAN_FRONTEND='noninteractive' -i -u root stable apt install -o APT::Install-Suggests=false -qy ${release} \ clang \ cmake \ pkg-config \ gcc \ gcc-aarch64-linux-gnu \ gcc-arm-linux-gnueabihf \ gcc-mips-linux-gnu \ libncurses-dev \ fftw-dev \ libfftw3-dev \ gettext \ libssl-dev - name: Configure & Build with gcc (minimal configuration) env: cc: gcc run: | podman exec -i --env CC=${cc} stable cmake -B build-${cc} -DUSE_TUI=OFF -DUSE_FFTW3=OFF -DUSE_SSL=OFF -DUSE_GETTEXT=OFF podman exec -i stable cmake --build build-${cc} - name: Configure & Build with gcc (SSL support) env: cc: gcc run: | podman exec -i --env CC=${cc} stable cmake -B build-${cc} -DUSE_TUI=OFF -DUSE_FFTW3=OFF -DUSE_SSL=ON -DUSE_GETTEXT=OFF podman exec -i stable cmake --build build-${cc} - name: Configure & Build with gcc (full TUI support) env: cc: gcc run: | podman exec -i --env CC=${cc} stable cmake -B build-${cc} -DUSE_TUI=ON -DUSE_FFTW3=ON -DUSE_SSL=OFF -DUSE_GETTEXT=OFF podman exec -i stable cmake --build build-${cc} - name: Configure & Build with gcc (full TUI support and SSL) env: cc: gcc run: | podman exec -i --env CC=${cc} stable cmake -B build-${cc} -DUSE_TUI=ON -DUSE_FFTW3=ON -DUSE_SSL=ON -DUSE_GETTEXT=OFF podman exec -i stable cmake --build build-${cc} - name: Configure & Build with gcc (full TUI support, SSL, and gettext) env: cc: gcc run: | podman exec -i --env CC=${cc} stable cmake -B build-${cc} -DUSE_TUI=ON -DUSE_FFTW3=ON -DUSE_SSL=ON -DUSE_GETTEXT=ON podman exec -i stable cmake --build build-${cc} - name: Configure & Build with clang (minimal configuration) env: cc: clang run: | podman exec -i --env CC=${cc} stable cmake -B build-${cc} -DUSE_TUI=OFF -DUSE_FFTW3=OFF -DUSE_SSL=OFF -DUSE_GETTEXT=OFF podman exec -i stable cmake --build build-${cc} HTTPing-4.4.0/.gitignore000066400000000000000000000000331475432366700150010ustar00rootroot00000000000000tags compile_commands.json HTTPing-4.4.0/CMakeLists.txt000066400000000000000000000042101475432366700155520ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.12) add_compile_options(-Wall -pedantic -Wextra) project(httping LANGUAGES C VERSION "4.4.0") # Create compile_commands.json file set(CMAKE_EXPORT_COMPILE_COMMANDS 1) if(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) # Git auto-ignore out-of-source build directory file(GENERATE OUTPUT .gitignore CONTENT "*") endif() option(USE_TUI "Enable text user interface" OFF) option(USE_FFTW3 "Enable FFTW3 backend (depedns on USE_TUI)" OFF) option(USE_SSL "Enable SSL support" OFF) option(USE_GETTEXT "Enable interantionalization" OFF) set(SOURCES colors.c cookies.c error.c fft.c gen.c help.c http.c io.c kalman.c main.c mssl.c nc.c res.c socks5.c tcp.c utils.c) add_executable(httping ${SOURCES}) target_link_libraries(httping m) if(USE_GETTEXT) find_package(Gettext REQUIRED) find_package(Intl REQUIRED) target_link_libraries(httping Intl::Intl) endif() set(CMAKE_BUILD_TYPE Debug) include(FindPkgConfig) if(USE_TUI) pkg_check_modules(NCURSES REQUIRED ncurses) target_link_libraries(httping ${NCURSES_LIBRARIES}) target_include_directories(httping PUBLIC ${NCURSES_INCLUDE_DIRS}) target_compile_options(httping PUBLIC ${NCURSES_CFLAGS_OTHER}) if(USE_FFTW3) pkg_check_modules(FFTW3 REQUIRED fftw3) target_link_libraries(httping ${FFTW3_LIBRARIES}) target_include_directories(httping PUBLIC ${FFTW3_INCLUDE_DIRS}) target_compile_options(httping PUBLIC ${FFTW3_CFLAGS_OTHER}) endif() endif() if(USE_SSL) find_package(OpenSSL REQUIRED) target_link_libraries(httping OpenSSL::SSL OpenSSL::Crypto) endif() include(GNUInstallDirs) if(USE_GETTEXT) add_subdirectory(po) endif() configure_file(config.h.in config.h) target_include_directories(httping PUBLIC "${PROJECT_BINARY_DIR}") install(TARGETS httping DESTINATION bin) install(FILES README.md LICENSE plot-json.py DESTINATION ${CMAKE_INSTALL_DOCDIR}) install(FILES httping.1 DESTINATION ${CMAKE_INSTALL_MANDIR}) # setup summary message(STATUS "CMake version: ${CMAKE_VERSION}") message(STATUS "Use SSL: ${USE_SSL}") message(STATUS "Use TUI: ${USE_TUI}") message(STATUS "Use FFTW3: ${USE_FFTW3}") message(STATUS "Use gettext: ${USE_GETTEXT}") HTTPing-4.4.0/LICENSE000066400000000000000000001033331475432366700140250ustar00rootroot00000000000000 GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . HTTPing-4.4.0/README.md000066400000000000000000000014171475432366700142770ustar00rootroot00000000000000httping ======= Ping with HTTP requests, see . Compiling: * `cmake -B build` * `cmake --build build` This configuration will build a binary with the minimal functionality. You can use the following options to add more features to httping: If you need the SSL support, use (requires `OpenSSL` library): * `cmake -DUSE_SSL=ON build` If you would like the TUI (text user interface) to be included (for -K), use (requires `ncurses` library): * `cmake -DUSE_TUI=ON build` Adding `-DUSE_FFTW3=ON` to the `-DUSE_TUI=ON` allows TUI to show performance graphics. This option requires `fftw3` library. If you want httping to use local translations, add `-DUSE_GETTEXT=ON` to the cmake commandline. The AGPL v3.0 license applies to this software. HTTPing-4.4.0/colors.c000066400000000000000000000020111475432366700144540ustar00rootroot00000000000000#include "colors.h" const char *c_error = ""; const char *c_normal = ""; const char *c_very_normal = ""; const char *c_red = ""; const char *c_blue = ""; const char *c_green = ""; const char *c_yellow = ""; const char *c_magenta = ""; const char *c_cyan = ""; const char *c_white = ""; const char *c_bright = ""; void set_colors(char nc) { if (nc) { c_red = COLOR_ESCAPE "1"; c_blue = COLOR_ESCAPE "2"; c_green = COLOR_ESCAPE "3"; c_yellow = COLOR_ESCAPE "4"; c_magenta = COLOR_ESCAPE "5"; c_cyan = COLOR_ESCAPE "6"; c_white = COLOR_ESCAPE "7"; c_bright = COLOR_ESCAPE "8"; c_normal = COLOR_ESCAPE "9"; c_very_normal = COLOR_ESCAPE "7" COLOR_ESCAPE "9"; c_error = COLOR_ESCAPE "1"; } else { c_red = "\033[31;40m"; c_blue = "\033[34;40m"; c_green = "\033[32;40m"; c_yellow = "\033[33;40m"; c_magenta = "\033[35;40m"; c_cyan = "\033[36;40m"; c_white = "\033[37;40m"; c_bright = "\033[1;40m"; c_normal = "\033[0;37;40m"; c_very_normal = "\033[0m"; c_error = "\033[1;4;40m"; } } HTTPing-4.4.0/colors.h000066400000000000000000000005631475432366700144730ustar00rootroot00000000000000extern const char *c_error; extern const char *c_normal; extern const char *c_very_normal; extern const char *c_red; extern const char *c_blue; extern const char *c_green; extern const char *c_yellow; extern const char *c_magenta; extern const char *c_cyan; extern const char *c_white; extern const char *c_bright; #define COLOR_ESCAPE "\001" void set_colors(char nc); HTTPing-4.4.0/config.h.in000066400000000000000000000006431475432366700150430ustar00rootroot00000000000000#pragma once #define NAME "@PROJECT_NAME@" #define VERSION "@PROJECT_VERSION@" #define LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@" #cmakedefine01 FFTW3_FOUND #define HAVE_FFTW3 FFTW3_FOUND #cmakedefine01 NCURSES_FOUND #define HAVE_NCURSES NCURSES_FOUND #cmakedefine01 OPENSSL_FOUND #define HAVE_OPENSSL OPENSSL_FOUND #cmakedefine01 INTL_FOUND #define HAVE_INTL INTL_FOUND #if !HAVE_OPENSSL #define NO_SSL #endif HTTPing-4.4.0/cookies.c000066400000000000000000000047071475432366700146250ustar00rootroot00000000000000#include #include #include #include "utils.h" void add_cookie(char ***cookies, int *n_cookies, char *in) { char *in_copy = strdup(in), *is = strchr(in_copy, '='); int index = 0, found_at = -1; if (is) *is = 0x00; for(index=0; index<*n_cookies; index++) { char *dummy = strdup((*cookies)[index]); is = strchr(dummy, '='); if (is) *is = 0x00; if (strcmp(in_copy, dummy) == 0) { found_at = index; free(dummy); break; } free(dummy); } if (found_at >= 0) { free((*cookies)[found_at]); (*cookies)[found_at] = strdup(in); } else { *cookies = (char **)realloc(*cookies, (*n_cookies + 1) * sizeof(char *)); (*cookies)[*n_cookies] = strdup(in); (*n_cookies)++; } free(in_copy); } void combine_cookie_lists(char ***destc, int *n_dest, char **src, int n_src) { int loop = 0; *destc = (char **)realloc(*destc, (*n_dest + n_src) * sizeof(char *)); for(loop=0; loop #include #include #include #include #include #include char last_error[4096] = { 0 }; extern char json_output; void error_exit(char *format, ...) { int e = errno; va_list ap; va_start(ap, format); (void)vfprintf(stderr, format, ap); va_end(ap); if (json_output) { printf("\n]\n"); } fprintf(stderr, gettext("\n\nerrno=%d which means %s (if applicable)\n"), e, strerror(e)); exit(1); } void set_error(const char *fmt, ...) { int buffer_size = sizeof last_error; va_list ap; if (last_error[0]) fprintf(stderr, "%s\n", last_error); va_start(ap, fmt); if (vsnprintf(last_error, sizeof last_error, fmt, ap) >= buffer_size) error_exit(gettext("Error message '%s' truncated"), last_error); va_end(ap); } void clear_error() { last_error[0] = 0x00; } char * get_error() { return last_error; } HTTPing-4.4.0/error.h000066400000000000000000000003261475432366700143200ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ void error_exit(const char *format, ...); void set_error(const char *str, ...); void clear_error(void); char * get_error(void); HTTPing-4.4.0/example_show_json.php000066400000000000000000000013151475432366700172520ustar00rootroot00000000000000
sequencedata
$value) { ?>
keyvalue
HTTPing-4.4.0/fft.c000066400000000000000000000025211475432366700137400ustar00rootroot00000000000000#include "config.h" #if HAVE_FFTW3 #include "gen.h" #include #include #include #include #include "error.h" double *pin = NULL; fftw_complex *pout = NULL; fftw_plan plan; int sample_rate = 44100; void fft_init(int sample_rate_in) { sample_rate = sample_rate_in; pin = (double *)malloc(sizeof(double) * sample_rate_in); if (!pin) error_exit(gettext("failed allocating memory for fft (1)")); pout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * sample_rate_in + 1); if (!pout) error_exit(gettext("failed allocating memory for fft (2)")); /* init fftw */ plan = fftw_plan_dft_r2c_1d(sample_rate_in, pin, pout, FFTW_ESTIMATE); if (!plan) error_exit(gettext("failed calculating plan for fft")); } void fft_free(void) { if (pin) { fftw_free(pout); free(pin); } fftw_destroy_plan(plan); } void fft_stop(void) { fftw_cleanup(); } void fft_do(double *in, double *output_mag, double *output_phase) { int loop = 0; memcpy(pin, in, sizeof(double) * sample_rate); /* calc fft */ fftw_execute(plan); for(loop=0; loop<(sample_rate / 2) + 1; loop++) { double real = pout[loop][0]; double img = pout[loop][1]; /* magnitude */ output_mag[loop] = sqrt(pow(real, 2.0) + pow(img, 2.0)); /* phase */ output_phase[loop] = (real == 0 && img == 0) ? 0 : atan2(real, img); } } #endif HTTPing-4.4.0/fft.h000066400000000000000000000002201475432366700137370ustar00rootroot00000000000000void fft_init(int sample_rate_in); void fft_free(void); void fft_do(double *in, double *output_mag, double *output_phase); void fft_stop(void); HTTPing-4.4.0/gen.c000066400000000000000000000050731475432366700137370ustar00rootroot00000000000000#include #include #include #include "gen.h" void init_statst(stats_t *data, char do_median) { memset(data, 0x00, sizeof(stats_t)); data -> min = MY_DOUBLE_INF; data -> max = -data -> min; data -> calc_median = do_median; } void uninit_statst(stats_t *data) { free(data -> median); } void update_statst(stats_t *data, double in) { data -> cur = in; data -> min = min(data -> min, in); data -> max = max(data -> max, in); data -> avg += in; data -> sd += in * in; data -> valid = 1; data -> cur_valid = 1; if (data -> calc_median) { if (data -> n >= data -> median_size) { data -> median_size = data -> median_size == 0 ? 128 : data -> median_size * 2; data -> median = (double *)realloc(data -> median, data -> median_size * sizeof(double)); } } if (data -> calc_median) data -> median[data -> n] = in; data -> n++; } void reset_statst_cur(stats_t *data) { data -> cur_valid = 0; } double calc_sd(stats_t *in) { double avg = 0.0; if (in -> n == 0 || !in -> valid) return 0; avg = in -> avg / (double)in -> n; return sqrt((in -> sd / (double)in -> n) - pow(avg, 2.0)); } static int cmpfunc(const void *a, const void *b) { if (*(const double *)a > *(const double *)b) return 1; if (*(const double *)a < *(const double *)b) return -1; return 0; } double calc_median(const stats_t *in) { int half = in -> n / 2; if (in -> calc_median == 0) return -1; qsort(in -> median, in -> n, sizeof(double), cmpfunc); if (in -> n & 1) return in->median[half + 1]; return (in->median[half + 0] + in->median[half + 1]) / 2.; } /* Base64 encoding start */ const char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void encode_tryptique(char source[3], char result[4]) /* Encode 3 char in B64, result give 4 Char */ { int tryptique, i; tryptique = source[0]; tryptique *= 256; tryptique += source[1]; tryptique *= 256; tryptique += source[2]; for (i=0; i<4; i++) { result[3-i] = alphabet[tryptique%64]; tryptique /= 64; } } int enc_b64(char *source, int source_lenght, char *target) { /* Divide string /3 and encode trio */ while (source_lenght >= 3) { encode_tryptique(source, target); source_lenght -= 3; source += 3; target += 4; } /* Add padding to the rest */ if (source_lenght > 0) { char pad[3]; memset(pad, 0, sizeof pad); memcpy(pad, source, source_lenght); encode_tryptique(pad, target); target[3] = '='; if (source_lenght == 1) target[2] = '='; target += 4; } target[0] = 0; return 1; } /* Base64 encoding END */ HTTPing-4.4.0/gen.h000066400000000000000000000021441475432366700137400ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #ifndef __GEN_H__ #define __GEN_H__ #define RC_OK 0 #define RC_SHORTREAD -1 #define RC_SHORTWRITE -1 #define RC_TIMEOUT -2 #define RC_CTRLC -3 #define RC_INVAL -4 #define RECV_BUFFER_SIZE (128 * 1024) #define SPAM_FILE "/tmp/httping.dat" #define MAX_SHOW_SUPPRESSION 3 #ifdef NO_SSL #define SSL void #define SSL_CTX void #define BIO void #endif #define PI (4 * atan(1.0)) #define MY_DOUBLE_INF 999999999999999.9 #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) #if INTL_FOUND #include #else #define gettext(x) (x) #endif typedef struct { double cur, min, avg, max, sd, med; int n; char valid, cur_valid; char calc_median; int median_size; double *median; } stats_t; int enc_b64(char *source, int source_lenght, char *target); void init_statst(stats_t *data, char do_median); void uninit_statst(stats_t *data); void update_statst(stats_t *data, double in); void reset_statst_cur(stats_t *data); double calc_sd(stats_t *in); double calc_median(const stats_t *in); #endif HTTPing-4.4.0/help.c000066400000000000000000000274531475432366700141240ustar00rootroot00000000000000#include "config.h" #include "gen.h" #include #include #include #include #include "gen.h" #include "main.h" #include "help.h" #include "utils.h" void new_version_alert(void) { char new_version = 0; FILE *fh = fopen(SPAM_FILE, "r"); if (!fh) new_version = 1; else { char buffer[4096], *dummy = 0x00; fgets(buffer, sizeof buffer, fh); fclose(fh); dummy = strchr(buffer, '\n'); if (dummy) *dummy = 0x00; if (strcmp(buffer, VERSION) != 0) new_version = 1; } if (new_version) { FILE *fh = fopen(SPAM_FILE, "w"); if (fh) { fprintf(fh, "%s\n", VERSION); fclose(fh); } printf("Welcome to the new HTTPing version " VERSION "!\n\n"); #if HAVE_NCURSES printf("Did you know that with -K you can start a fullscreen GUI version with nice graphs and lots more information? And that you can disable the moving graphs with -D?\n"); #if !HAVE_FFTW3 printf("And if you compile this program with libfftw3, that it can also show a fourier transform of the measured values?\n"); #endif #else printf("Did you know that if you compile this program with NCURSES, that it then includes a nice GUI with lots more information and graphs?\n"); #endif printf("\n\n"); } } void version(void) { fprintf(stderr, gettext("HTTPing v" VERSION ", (C) 2003-2023 folkert@vanheusden.com\n")); #ifndef NO_SSL fprintf(stderr, gettext(" * SSL support included (-l)\n")); #endif #if HAVE_NCURSES #if HAVE_FFTW3 fprintf(stderr, gettext(" * ncurses interface with FFT included (-K)\n")); #else fprintf(stderr, gettext(" * ncurses interface included (-K)\n")); #endif #endif fprintf(stderr, gettext(" * TFO (TCP fast open) support included (-F)\n")); fprintf(stderr, gettext("\n")); } void format_help(const char *short_str, const char *long_str, const char *descr) { int par_width = SWITCHES_COLUMN_WIDTH, max_wrap_width = par_width / 2, cur_par_width = 0; int descr_width = max_x - (par_width + 1); char *line = NULL, *p = (char *)descr; char first = 1; if (long_str && short_str) str_add(&line, "%-4s / %s", short_str, long_str); else if (long_str) str_add(&line, "%s", long_str); else str_add(&line, "%s", short_str); cur_par_width = fprintf(stderr, "%-*s ", par_width, line); free(line); if (par_width + 1 >= max_x || cur_par_width >= max_x) { fprintf(stderr, "%s\n", descr); return; } for(;strlen(p);) { char *n = NULL, *kn = NULL, *copy = NULL; int n_len = 0, len_after_ww = 0, len_before_ww = 0; int str_len = 0, cur_descr_width = first ? max_x - cur_par_width : descr_width; while(*p == ' ') p++; str_len = strlen(p); if (!str_len) break; len_before_ww = min(str_len, cur_descr_width); n = &p[len_before_ww]; kn = n; if (str_len > cur_descr_width) { while (*n != ' ' && n_len < max_wrap_width) { n--; n_len++; } if (n_len >= max_wrap_width) n = kn; } len_after_ww = (int)(n - p); if (len_after_ww <= 0) break; copy = (char *)malloc(len_after_ww + 1); memcpy(copy, p, len_after_ww); copy[len_after_ww] = 0x00; if (first) first = 0; else fprintf(stderr, "%*s ", par_width, ""); fprintf(stderr, "%s\n", copy); free(copy); p = n; } } void usage(const char *me) { char *dummy = NULL, has_color = 0; char host[256] = { 0 }; /* where to connect to */ fprintf(stderr, gettext(" *** where to connect to ***\n")); format_help("-g x", "--url", gettext("URL to ping (e.g. -g http://localhost/)")); format_help("-h x", "--hostname", gettext("hostname to ping (e.g. localhost) - use either -g or -h")); format_help("-p x", "--port", gettext("portnumber (e.g. 80) - use with -h")); format_help("-6", "--ipv6", gettext("use IPv6 when resolving/connecting")); #ifndef NO_SSL format_help("-l", "--use-ssl", gettext("connect using SSL. pinging an https URL automatically enables this setting")); #endif fprintf(stderr, gettext("\n")); /* proxy settings */ fprintf(stderr, gettext(" *** proxy settings ***\n")); format_help("-x x", "--proxy", gettext("x should be \"host:port\" which are the network settings of the http/https proxy server. ipv6 ip-address should be \"[ip:address]:port\"")); format_help("-E", NULL, gettext("fetch proxy settings from environment variables")); format_help(NULL, "--proxy-user x", gettext("username for authentication against proxy")); format_help(NULL, "--proxy-password x", gettext("password for authentication against proxy")); format_help(NULL, "--proxy-password-file x", gettext("read password for proxy authentication from file x")); format_help("-5", NULL, gettext("proxy is a socks5 server")); format_help(NULL, "--proxy-buster x", gettext("adds \"&x=[random value]\" to the request URL")); fprintf(stderr, gettext("\n")); /* timing settings */ fprintf(stderr, gettext(" *** timing settings ***\n")); format_help("-c x", "--count", gettext("how many times to ping")); format_help("-i x", "--interval", gettext("delay between each ping")); format_help("-t x", "--timeout", gettext("timeout (default: 30s)")); format_help(NULL, "--ai / --adaptive-interval", gettext("execute pings at multiples of interval relative to start, automatically enabled in ncurses output mode")); format_help("-f", "--flood", gettext("flood connect (no delays)")); fprintf(stderr, gettext("\n")); /* http settings */ fprintf(stderr, gettext(" *** HTTP settings ***\n")); format_help("-Z", "--no-cache", gettext("ask any proxies on the way not to cache the requests")); format_help(NULL, "--divert-connect", gettext("connect to a different host than in the URL given")); format_help(NULL, "--keep-cookies", gettext("return the cookies given by the HTTP server in the following request(s)")); format_help(NULL, "--no-host-header", gettext("do not add \"Host:\"-line to the request headers")); format_help("-Q", "--persistent-connections", gettext("use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. usually possible when 'Connection: Keep-Alive' is sent by server. adds a 'C' to the output if httping had to reconnect")); format_help("-I x", "--user-agent", gettext("use 'x' for the UserAgent header")); format_help("-R x", "--referer", gettext("use 'x' for the Referer header")); format_help(NULL, "--header", gettext("adds an extra request-header")); fprintf(stderr, gettext("\n")); /* network settings */ fprintf(stderr, gettext(" *** networking settings ***\n")); format_help(NULL, "--max-mtu", gettext("limit the MTU size")); format_help(NULL, "--no-tcp-nodelay", gettext("do not disable Naggle")); format_help(NULL, "--recv-buffer", gettext("receive buffer size")); format_help(NULL, "--tx-buffer", gettext("transmit buffer size")); format_help("-r", "--resolve-once", gettext("resolve hostname only once (useful when pinging roundrobin DNS: also takes the first DNS lookup out of the loop so that the first measurement is also correct)")); format_help("-W", NULL, gettext("do not abort the program if resolving failed: keep retrying")); format_help("-y x", "--bind-to", gettext("bind to an ip-address (and thus interface) with an optional port")); format_help("-F", "--tcp-fast-open", gettext("\"TCP fast open\" (TFO), reduces the latency of TCP connects")); #ifdef linux format_help(NULL, "--priority", gettext("set priority of packets")); #endif format_help(NULL, "--tos", gettext("set TOS (type of service)")); fprintf(stderr, gettext("\n")); /* http authentication */ fprintf(stderr, gettext(" *** HTTP authentication ***\n")); format_help("-A", "--basic-auth", gettext("activate (\"basic\") authentication")); format_help("-U x", "--username", gettext("username for authentication")); format_help("-P x", "--password", gettext("password for authentication")); format_help("-T x", NULL, gettext("read the password fom the file 'x' (replacement for -P)")); fprintf(stderr, gettext("\n")); /* output settings */ fprintf(stderr, gettext(" *** output settings ***\n")); format_help("-s", "--show-statuscodes", gettext("show statuscodes")); format_help(NULL, "--median", gettext("show median")); format_help("-S", "--split-time", gettext("split measured time in its individual components (resolve, connect, send, receive, disconnect)")); format_help(NULL, "--threshold-red", gettext("from what ping value to show the value in red (must be bigger than yellow), only in color mode (-Y)")); format_help(NULL, "--threshold-yellow", gettext("from what ping value to show the value in yellow")); format_help(NULL, "--threshold-show", gettext("from what ping value to show the results")); format_help(NULL, "--timestamp / --ts", gettext("put a timestamp before the measured values, use -v to include the date and -vv to show in microseconds")); format_help(NULL, "--aggregate x[,y[,z]]", gettext("show an aggregate each x[/y[/z[/etc]]] seconds")); #ifndef NO_SSL format_help("-k", "--insecure", gettext("allow insecure server connections")); format_help("-z", "--show-fingerprint", gettext("show fingerprint (SSL)")); format_help(NULL, "--ca-path", gettext("path to ca certificates (SSL)")); #endif format_help("-v", NULL, gettext("verbose mode")); fprintf(stderr, gettext("\n")); /* GET settings */ fprintf(stderr, gettext(" *** \"GET\" (instead of HTTP \"HEAD\") settings ***\n")); format_help("-G", "--get-request", gettext("do a GET request instead of HEAD (read the contents of the page as well)")); format_help("-b", "--show-transfer-speed", gettext("show transfer speed in KB/s (use with -G)")); format_help("-B", "--show-xfer-speed-compressed", gettext("like -b but use compression if available")); format_help("-L x", "--data-limit", gettext("limit the amount of data transferred (for -b) to 'x' (in bytes)")); format_help("-X", "--show-kb", gettext("show the number of KB transferred (for -b)")); fprintf(stderr, gettext("\n")); /* output mode settings */ fprintf(stderr, gettext(" *** output mode settings ***\n")); format_help("-q", "--quiet", gettext("quiet, only returncode")); format_help("-m", "--parseable-output", gettext("give machine parseable output (see also -o and -e)")); format_help("-M", NULL, gettext("json output, cannot be combined with -m")); format_help("-o rc,rc,...", "--ok-result-codes", gettext("what http results codes indicate 'ok' comma separated WITHOUT spaces inbetween default is 200, use with -e")); format_help("-e x", "--result-string", gettext("string to display when http result code doesn't match")); format_help("-n warn,crit", "--nagios-mode-1 / --nagios-mode-2", gettext("Nagios-mode: return 1 when avg. response time >= warn, 2 if >= crit, otherwhise return 0")); format_help("-N x", NULL, gettext("Nagios mode 2: return 0 when all fine, 'x' when anything failes")); format_help("-C cookie=value", "--cookie", gettext("add a cookie to the request")); format_help("-Y", "--colors", gettext("add colors")); format_help("-a", "--audible-ping", gettext("audible ping")); fprintf(stderr, gettext("\n")); /* GUI/ncurses mode */ #if HAVE_NCURSES fprintf(stderr, gettext(" *** GUI/ncurses mode settings ***\n")); format_help("-K", "--ncurses / --gui", gettext("ncurses/GUI mode")); #if HAVE_FFTW3 format_help(NULL, "--draw-phase", gettext("draw phase (fourier transform) in gui")); #endif format_help(NULL, "--slow-log", gettext("when the duration is x or more, show ping line in the slow log window (the middle window)")); format_help(NULL, "--graph-limit x", gettext("do not scale to values above x")); format_help("-D", "--no-graph", gettext("do not show graphs (in ncurses/GUI mode)")); fprintf(stderr, gettext("\n")); #endif format_help("-V", "--version", gettext("show the version")); fprintf(stderr, gettext("\n")); dummy = getenv("TERM"); if (dummy) { if (strstr(dummy, "ANSI") || strstr(dummy, "xterm") || strstr(dummy, "screen")) has_color = 1; } if (gethostname(host, sizeof host)) strcpy(host, "localhost"); fprintf(stderr, gettext("Example:\n")); fprintf(stderr, "\t%s %s%s -s -Z\n\n", me, host, has_color ? " -Y" : ""); new_version_alert(); } HTTPing-4.4.0/help.h000066400000000000000000000002061475432366700141140ustar00rootroot00000000000000#define SWITCHES_COLUMN_WIDTH 24 void new_version_alert(void); void version(void); void help_long(void); void usage(const char *me); HTTPing-4.4.0/http.c000066400000000000000000000041561475432366700141460ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include "config.h" #include #include #include #include #include #ifndef NO_SSL #include #include "mssl.h" #endif #include "gen.h" #include "http.h" #include "io.h" #include "utils.h" int get_HTTP_headers(int socket_h, SSL *ssl_h, char **headers, int *overflow, double timeout) { char *term = NULL; int len_in=0, len=4096; char *buffer = (char *)malloc(len + 1); int rc = RC_OK; *headers = NULL; memset(buffer, 0x00, len); for(;;) { int rrc = -1; int now_n = len - len_in; #ifndef NO_SSL if (ssl_h) rrc = SSL_read(ssl_h, &buffer[len_in], now_n); else #endif rrc = read_to(socket_h, &buffer[len_in], now_n, timeout); if (rrc == 0 || rrc == RC_SHORTREAD) /* socket closed before request was read? */ { rc = RC_SHORTREAD; break; } else if (rrc < 0) { free(buffer); return rrc; } len_in += rrc; assert(len_in >= 0); assert(len_in <= len); buffer[len_in] = 0x00; if (strstr(buffer, "\r\n\r\n") != NULL) break; if (len_in >= len) { len <<= 1; buffer = (char *)realloc(buffer, len + 1); } } *headers = buffer; term = strstr(buffer, "\r\n\r\n"); if (term) *overflow = len_in - (term - buffer + 4); else *overflow = 0; return rc; } int dumb_get_HTTP_headers(int socket_h, char **headers, double timeout) { int len_in=0, len=4096; char *buffer = (char *)malloc(len); int rc = RC_OK; *headers = NULL; for(;;) { int rrc = read_to(socket_h, &buffer[len_in], 1, timeout); if (rrc == 0 || rrc == RC_SHORTREAD) /* socket closed before request was read? */ { rc = RC_SHORTREAD; break; } else if (rrc == RC_TIMEOUT) /* timeout */ { free(buffer); return RC_TIMEOUT; } len_in += rrc; buffer[len_in] = 0x00; if (memcmp(&buffer[len_in - 4], "\r\n\r\n", 4) == 0) break; if (memcmp(&buffer[len_in - 2], "\n\n", 2) == 0) /* broken proxies */ break; if (len_in == (len - 1)) { len <<= 1; buffer = (char *)realloc(buffer, len); } } *headers = buffer; return rc; } HTTPing-4.4.0/http.h000066400000000000000000000003761475432366700141530ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ int get_HTTP_headers(int socket_h, SSL *ssl_h, char **headers, int *overflow, double timeout); int dumb_get_HTTP_headers(int socket_h, char **headers, double timeout); HTTPing-4.4.0/httping-nl.1000066400000000000000000000172611475432366700151720ustar00rootroot00000000000000.\" Copyright Folkert van Heusden, 2003-2016 .\" .\" This file may be copied under the conditions described .\" in the GNU GENERAL PUBLIC LICENSE, version 2 .\" that can be found on the website of the free software .\" foundation. .\" .TH HTTPING 1 2016-09 "httping" .SH NAME httping - meten van de latency en doorvoorsnelheid van een http server .SH SAMENVATTING .BI "httping [" opties "] .sp een aantal opties: .BI "[\-g URL] [\-h systeem naam] [\-p port nummer] [\-x proxy systeem naam:port] [\-c aantal] [\-i interval] [\-t duur limiet] [\-s] [\-K] [\-Y] .SH BESCHRIJVING The program Het programma .B httping meet de latency van een http server. Sinds versie 1.0.6 kan ook de dooorvoorsnelheid gemeten worden. .PP .SH OPTIES .TP .B "\-5" De geselecteerde server is een SOCKS5 server. .TP .B "\-6" Schakel IPv6 mode in. Standaard instelling is IPv4. .TP .B "\-a" Hoorbare ping .TP .B "\-b" Gebruik deze optie samen met \-G. HTTPing zal dan de doorvoorsnelheid (in kB/s) tonen. .TP .B "\-B" Gebruik deze optie samen met \-G. HTTPing zal dan de doorvoorsnelheid (in kB/s) tonen. HTTPing zal echter vragen aan de webserver of deze de data comprimeerd. .TP .B "\-c aantal" Hoevaak te pingen. .TP .B "\-D" Teken geen grafieken (in ncurses (\-K) mode). .TP .B "\-e str" Als de status-code anders is dan die ingesteld is met \-o, dan zal 'str' getoond worden. .TP .B "\-E" Haal de proxy instellingen uit omgevings variabelen. .TP .B "\-F" Probeer verbindingen met "TFO (TCP Fast open)" op te zetten. Dit werkt alleen met Linux kernel 3.7 of recenter. .TP .B "\-f" Ping zo snel als mogelijk achter elkaar. .TP .B "\-G" Doe een GET-verzoek in plaats van een HEAD-verzoek. Daarmee wordt ook de pagina-inhoud opgehaald. .TP .B "\-g URL" Kies welke URL gepinged moet worden. Bijvoorbeeld: http://www.microsoft.com/ .TP .B "\-h systeem naam" In plaats van een URL kan men ook alleen een systeem naam opgeven. .TP .B "\-I str" Welke "UserAgent" te sturen naar de webserver. .TP .B "\-i interval" Hoeveel seconden (of delen daarvan) te wachten tussen het verzenden van iedere ping. .TP .B "\-K" Gebruik de ncurses gebruikers interface. .TP .B "\-L x" In combinatie met \-G zet dit een limiet op hoeveel data er binnengehaald wordt. .TP .B "\-l" Maak een SSL verbinding. Dit vereist een https-URL. .TP .B "\-m" Geef output die makkelijker met een script te bewerken is. .TP .B "\-N x" Nagios-mode 1: geef 1 terug als de gemiddel reaktie snelheid >= "warn" en 2 als die snelheid >= "crit", anders geef 0 terug. Nagios mode 2: geef 0 terug als alles goed ging, anders 'x'. .TP .B "\-n warn,crit" Schakelt HTTPing naar Nagios-plugin mode 1. Geef afsluit code 1 als de gemiddelde response tijd groter is dan 'warn', geef 2 terug als die tijd groter is dan 'crit'. Anders 0. .TP .B "\-o x,x,..." Selecteer de HTTP status-codes die als 'ok' beschouwd worden. .TP .B "\-p portnumber" Gebruik dit on combinatie met h. Het zet het port-nummer om te pingen. .TP .B "\-Q" Gebruik een blijvende verbinding, dat wil zeggen hergebruiken dezelfde TCP-verbinding voor meerdere HTTP-verzoeken. Meestal mogelijk wanneer 'Connection: Keep-Alive' is verzonden door de server. Als het bestemmingssysteem de verbinding verbroken heeft, dan zal HTTPing een \"C\" toevoegen aan de uitvoer. .TP .B "\-q" Geef geen uitvoer, alleen een teruggave code. .TP .B "\-R str" Welke "Referer" te zenden naar de webserver. .TP .B "\-r" Eenmalig systeemnaam vertalen (dit is zinvol bij het pingen van een roterende DNS, bovendien haalt het de eerste vertaling uit de ping lus zodat de 1e ping niet een bovengemiddelde tijd duurt). .TP .B "\-S" Toon alle individuele componenten (verbinden, zenden, etc) van de gemeten tijden. .TP .B "\-s" Toon de HTTP statuscodes. .TP .B "\-T x" Lees de toegangscode voor website authenticatie uit bestand 'x'. .TP .B "\-t timeout" Hoelang te wachten op een reactie van de webserver. .TP .B "\-U" Gebruik authenticatie bij toegang tot de website. Combineer dit met \-P of \-T. .TP .B "\-v" Toon meer details. .TP .B "\-W" Stop HTTPing niet als het opzoeken van de server naam niet lukt. .TP .B "\-X" Gebruik deze in combinatie met \-G. Toon hoeveel data er ontvangen werd. .TP .B "\-x proxyhost[:port] Gebruik een proxy server om een verbinding op te zetten. .TP .B "\-Y" Gebruik kleuren. .TP .B "\-z" Toon de vingerafdruk van de X.509 certificaten bij het opzetten van een SSL verbinding. .TP .B "\-\-abbreviate" Kort waardes af wanneer ze groter zijn dan 1000/1000000/etc. .TP .B "\-\-adaptive-interval" or "\-\-ai" Zorg ervoor dat pings steeds met dezelfde interval uitgevoerd worden, relatief tot het start tijdstip. deze instelling wordt automatisch aangezet in "ncurses"\-mode. .TP .B "\-\-aggregates x[,y[,z[,etc.]]]" Toon cumulatief de waardes van x[/y[/etc]] seconden. .TP .B "\-\-divert\-connect x" Gebruik niet de systeemnaam uit de URL om naar te verbinden. Verbind naar 'x'. .TP .B "\-\-draw-phase" Toon fase diagram. .TP .B "\-\-graph\-limit x" Bij het bepalen van de grafiek-bandbreedte: negeer waardes hoger dan x. .TP .B "\-\-header x" Voeg een extra verzoek-regel toe. .TP .B "\-\-keep\-cookies" Als de HTTP server cookies geeft, zend die dan mee terug bij volgende pings. .TP .B "\-\-max\-mtu x" Welke MTU te gebruiken. Kan niet groter zijn dan de MTU van de netwerk adapter. .TP .B "\-\-no\-host\-header" Voeg niet een "Host:"\-regel toe aan het verzoek. .TP .B "\-\-no\-tcp\-nodelay" Zet het Naggle-algorithme niet uit. .TP .B "\-\-priority x" Geef packets een bepaalde prioriteit. .TP .B "\-\-tos x" Configureer de TOS. .TP .B "\-\-proxy\-user x" Gebruikersnaam voor proxy authenticatie. .TP .B "\-\-proxy\-password x" Toegangscode voor proxy authenticatie. .TP .B "\-\-proxy\-password-file x" Lees toegangscode voor proxy authenticatie uit bestand 'x'. .TP .B "\-\-recv-buffer x" Configureer de grootte van de ontvangst buffer. .TP .B "\-\-slow\-log x" Als een ping-tijd meer dan x is, toon het resultaat dan in het middelste venster. .TP .B "\-\-threshold\-red x" Toon metingen in rood als de gemeten waarde meer dan x is. .TP .B "\-\-threshold\-yellow x" Toon metingen in geel als de gemeten waarde meer dan x is. .TP .B "\-\-threshold\-show x" Toon metingen alleen als ze hoger dan x zijn. .TP .B "\-\-timestamp" or "\-\-ts" Voeg een een tijdstempel toe aan de uitvoer. Gebruik \-v om ook een datum te zien en \-vv om ook microseconden te zien. .TP .B "\-\-tx-buffer x" Configureer de grootte van de zend-buffer. .TP .B "\-V" Toon versie informatie. .SH UITVOER In de \-S mode zal iets als "tijd=0.08+24.09+23.17+15.64+0.02=62.98 ms" getoond worden. De eerste waarde is hoe lang het duurde om de systeem naam te vertalen, de 2e waarde hoe lang het duurde om te verbinden, de 3e waarde geeft aan hoe lang het duurde om het verzoek te verzenden en de 4e waarde is hoelang het duurde voordat de http-server een antwoord formuleerde en terugzond. de 5e waarde geeft aan hoelang het duurde om de socket te sluiten. .SH GRAFIEK De grafiek in ncurses mode gebruikt een aantal kleuren. Groen: de waarde is minder dan de ondergrens. Rood: de waarde is hoger dan de bovengrens. Blauw: de waarde is gelimiteerd door '\-\-graph\-limit'. Cyaan: er is geen meetwaarde. .SH TOETSEN Druk + om het programma af te breken. Er zal dan een samenvatting getoond worden. In ncurses mode: + ververst het scherm, H stopt (en hervat) de grafieken en ook q zal het programma stoppen. .SH VOORBEELDEN .TP .B "httping \-g http://localhost/" Ping de HTTP server op URL http://localhost/ .TP .B "httping \-h localhost \-p 1000" Ping de HTTP server op systeem 'localhost' en port nummer 1000. .TP .SH BUGS Geen. .SH "ZIE OOK" .BR http://www.vanheusden.com/httping/ .SH NOTITIES Deze man-page beschrijft .B httping versie 2.3: andere versies kunnen iets of wat verschillen. Stuur a.u.b. correcties, toevingen en foutraporten naar mail@vanheusden.com HTTPing-4.4.0/httping-ru.1000066400000000000000000000402431475432366700152030ustar00rootroot00000000000000.\" Copyright Folkert van Heusden, 2003-2016 .\" .\" This file may be copied under the conditions described .\" in the GNU GENERAL PUBLIC LICENSE, version 2 .\" that can be found on the website of the free software .\" foundation. .\" .TH HTTPING 1 2016-09 "httping" .SH ИМЯ httping - измеряет задержку и пропускную способность веб-сервера .SH СИНТАКСИС .BI "httping [" опции "] .sp опции: .BI "[\-g url] [\-h имя_хоста] [\-p номер_порта] [\-x прокси_хост:порт] [\-c число] [\-i интервал] [\-t тайм-аут] [\-s] [\-G] [\-b] [\-L предел_передачи] [\-X] [\-l] [\-z] [\-f] [\-m] [\-o ко,...] [\-e строка]" .BI "[\-I UserAgent строка] [\-R Referer строка] [\-r] [\-n warn,crit] [\-N режим] [\-q] [\-V]" .SH ОПИСАНИЕ Утилита .B httping позволяет измерять задержку веб-сервера. Начиная с версии 1.0.6 также есть возможность измерять пропускную способность. .PP .SH ОПЦИИ .TP .B "\-5" Выбранный прокси-сервер — это SOCKS5 сервер. .TP .B "\-6" Включить режим IPv6. По умолчанию IPv4. .TP .B "\-a" Слышимый пинг .TP .B "\-b" Используйте этот переключатель вместе с '-\G'. Когда эта опция используется, показывается пропускная способность (в КБ/с). .TP .B "\-B" Используйте этот переключатель вместе с '-\G'. Просит HTTP сервер сжимать возвращаемые данные: это позволит уменьшить важность пропускной способности вашего соединения, увеличивая важность вычислительной мощности HTTP сервера. .TP .B "\-c число" Сколько проб отправить перед тем как выйти. .TP .B "\-D" Не рисовать графики в режиме ncurses (-\K). .TP .B "\-e строка" Когда код ответа отличается от указанных в '\-o', отображать данную строку. .TP .B "\-E" Получить настройки прокси-сервера из переменных окружения ('http_proxy' и 'https_proxy'). .TP .B "\-F" Попытаться использовать TCP Fast Open подключаясь к серверу (для Linux ядра версии 3.7 и более) .TP .B "\-f" Флуд пинг: не сидеть сложа руки между каждым пингом, а пинговать быстро, насколько компьютер и сеть позволит вам. .TP .B "\-G" Делать GET запрос вместо HEAD запроса: это значит, что полная страница/файл будет передан. Обратите внимание, в данном случае вы больше не измеряете задержку! .TP .B "\-g URL" Устанавливает URL для проб. К примеру: http://localhost/ .TP .B "\-h имя_хоста" Вместо '\-g' вы можете также использовать '\-h' чтобы установить имя хоста, к примеру: \-h localhost .TP .B "\-I строка" UserAgent строка для отправки веб-серверу (по умолчанию 'HTTPing <версия>'). .TP .B "\-i interval" Сколько секунд между отправкой каждой пробы. .TP .B "\-K" Включить пользовательский интерфейс ncurses. .TP .B "\-L x" Используйте этот переключатель вместе с '\-G'. Ограничивает объем передаваемых данных значением 'х'. Обратите внимание, это влияет только на содержание страницы/файла, а не на заголовки. .TP .B "\-l" Подключаться с помощью SSL: чтобы это работало вы должны задать 'https' URL или номер порта 443. .TP .B "\-m" Показывать машиночитаемый вывод (смотрите также '\-o' и '\-e'). .TP .B "\-N x" Переключает HTTPing в режим 2 Nagios плагина: возвращает 0, когда все хорошо, "х", когда что-то не так. Т.е.: 1 => Nagios состояние warning, 2 => Nagios состояние critical. .TP .B "\-n warn,crit" Переключает HTTPing в режим 1 Nagios плагина: возвращает код выхода '1', когда среднее время отклика больше "warn", и возвращает код выхода '2', когда время на средний отклик больше "crit". Во всех остальных случаях возвращает код выхода '0'. .TP .B "\-o x,x,..." Устанавливает HTTP-коды, которые рассматриваются как ОК-состояния (только с '\-m'). .TP .B "\-p portnumber" \-p может быть использован вместе с \-h. \-p выбирает номер_порта для пробы. .TP .B "\-q" Без подробностей, возвращать только код выхода. .TP .B "\-R строка" Referer строка для отправки на веб-сервер. .TP .B "\-Q" Использовать постоянное соединение, т.е. переиспользовать то же самое TCP соединение для нескольких HTTP запросов. обычно возможно когда 'Connection: Keep-Alive' отправлено сервером. добавляет 'C' в вывод если httping был вынужден переподключиться .TP .B "\-r" Резолвить имя хоста только раз: это убирает резолвинг из цикла, так что латентность DNS не измеряется. Также полезно когда вы хотите измерить только 1 веб-сервер, а DNS возвращает новый IP-адрес на каждом резолве ('round robin'). .TP .B "\-S" Разделяет измеряемую задержку на время для подключения и на время обмена запросом с HTTP сервером. .TP .B "\-s" Когда транзакция успешна завершена, показывать HTTP код ответа (200, 404 и т.д.). .TP .B "\-T x" Читать пароль для аутентификации веб-сайта из файла 'х' (вместо ввода его в командной строке). .TP .B "\-t тайм-аут" Как долго ждать ответа с другой стороны. .TP .B "\-U" Включить аутентификацию для веб-сайта. Устанавливайте имя пользователя с помощью \-U, пароль с помощью \-P (или используйте \-T, чтобы прочитать пароль из файла). .TP .B "\-v" Увеличить уровень подробностей. Покажет в выводе стандартное отклонение и даты. .TP .B "\-W" Не прерывать программу если резолвинг не удался. .TP .B "\-X" Используйте этот переключатель вместе с '\-G'. Для каждого пинга показывать количество переданных данных (за исключением заголовков). .TP .B "\-x прокси_хост[:порт] Совершать пробу с помощью прокси сервера. Обратите внимание, вы также измеряете задержку работы с прокси сервером! .TP .B "\-Y" Включить цвета .TP .B "\-z" При подключении с помощью SSL, показывать фингерпринт X509 сертификата(ов) пиров. .TP .B "\-\-abbreviate" Сокращать значения больше, чем тысяча, миллион, миллиард, и т.д. .TP .B "\-\-adaptive-interval" или "\-\-ai" (Пытается) исполнять пинг на одном интервале. Например, если интервал установлен в 1.0 секунду и t[n] от пинга до пинга является 500s с длительностью 250 мс, то следующий пинг (t[n+1]) произойдет на 501 секунде, а не на 501.25 секунде. Конечно, когда длительность пинга > больше, чем интервал, пинг будет "пропущен" (не в буквальном смысле: последовательный номер продолжится) и t[n+1] будет на 502-й секунде вместо ожидаемой 501-й. Это полезно, например, в режиме вывода библиотеки, где FFT вычисляется по длительности пинга. .TP .B "\-\-aggregates x[,y[,z[,т.д.]]]" Показывать совокупный результат каждые x[,y[,z[,т.д.]]] секунд. .TP .B "\-\-divert\-connect x" Не обращать внимания на имя хоста в URL и вместо этого подключаться к 'х'. Данный ранее URL будет запрошен у 'х'. .TP .B "\-\-draw-phase" Рисовать не только величину преобразования Фурье, но также и фазу. .TP .B "\-\-graph\-limit x" Если измеренные значения больше, чем х, то ограничить их х. .TP .B "\-\-header x" Добавить дополнительный заголовок запроса 'х'. .TP .B "\-\-keep\-cookies" Когда сервер отправляет куки, оно будет отправлено назад в следующем запросе. .TP .B "\-\-max\-mtu x" Максимальное значение MTU для использования. Не может быть больше, чем MTU сетевого интерфейса. .TP .B "\-\-no\-host\-header" Не ставить "Host:" заголовок в заголовки запроса. .TP .B "\-\-no\-tcp\-nodelay" Не отключать "задержку TCP" (Naggle). .TP .B "\-\-priority x" Установить приоритет пакетов. .TP .B "\-\-tos x" Установить тип сервиса. .TP .B "\-\-proxy\-user x" Использовать имя пользователя 'х' для аутентификации на прокси-сервере (http/socks5) (опционально). .TP .B "\-\-proxy\-password x" Использовать пароль 'х' для аутентификации на прокси-сервере (http/socks5) (опционально). .TP .B "\-\-proxy\-password-file x" Читать пароль из файла 'х' для аутентификации на прокси-сервере (http/socks5) (опционально). .TP .B "\-\-recv-buffer x" Установить размер буфера приема (в байтах). .TP .B "\-\-slow\-log x" Когда длительность больше или равна x, показывать строку пинга в окне медленного журнала (среднее окно). .TP .B "\-\-threshold\-red x" Если измеренный пинг выше, чем х (и \-Y установлен), то показываемое значение будет покрашено в красный. Если вы также используете \-\-threshold\-yellow, то это значение должно быть больше. .TP .B "\-\-threshold\-yellow x" Если измеренный пинг выше, чем х (и \-Y установлен), то показываемое значение будет покрашено в желтый. .TP .B "\-\-threshold\-show x" Если измеренный пинг выше, чем х, то результат будет отображен (по умолчанию отображается всегда). Значение х в мс. .TP .B "\-\-timestamp" or "\-\-ts" Показывать таймстамп перед строками с результатами. Используйте опцию \-v, чтобы показывать также и дату. .TP .B "\-\-tx-buffer x" Установить размер буфера передачи (в байтах). .TP .B "\-V" Показать версию и выйти. .SH ВЫВОД В режиме разделения экрана (\-S) вы увидите что-то вроде "время=0.08+24.09+23.17+15.64+0.02=62.98 мс". Первое значение — это время, которое потребовалось, чтобы зарезолвить имя хоста (или 'Н/Д', если оно не резолвилось на этой итерации, например, в режиме "резолвить один раз" (\-r)), затем время, которое потребовалось для подключения (Или \-1 в, например, постоянных соединениях (\-Q, HTTP v1.1)), после этого время, которое потребовалось, чтобы произвести операцию записи, затем, то время, которое потребовалось для HTTP сервера, чтобы обработать запрос и отправить его обратно и, наконец, время, которое потребовалось, чтобы закрыть соединение. .SH ГРАФИК График в ncurses использует цвета для кодирования смысла. Зеленый: значение меньше, чем 1 блок. Красный: значение не укладывается в график. Синий: значение было ограничено опцией -\-\-graph\-limit. Бирюзовый: нет измерения для этого момента времени. .SH КЛАВИШИ Нажмите + , чтобы выйти из программы. Это отобразит краткую информацию о том, что было измерено. В графическом интерфейсе ncurses, нажмите клавишу + для принудительной перерисовки экрана. Нажмите 'H', чтобы остановить графики (и снова, чтобы продолжить). Нажмите 'q', чтобы остановить программу (или + ). .SH ПРИМЕРЫ .TP .B "httping \-g http://localhost/" Исполнить пинг к веб-серверу на хосте "localhost". .TP .B "httping \-h localhost \-p 1000" Исполнить пинг к веб-серверу на хосте "localhost" с номером порта 1000. .TP .B "httping \-l \-g https://localhost/" Исполнить пинг к веб-серверу на хосте "localhost" с помощью соединения SSL. .TP .B "httping \-g http://localhost/ -U username -P password" Исполнить пинг к веб-серверу на хосте "localhost", используя HTTP Basic Authentication.. .SH БАГИ Нету. В этой программе полностью отсутствуют баги. .SH "СМОТРИТЕ ТАКЖЕ" .BR http://www.vanheusden.com/httping/ .SH ЗАМЕТКИ Эта страница описывает .B httping , который содержится в пакете httping-2.3; другие версии могут немного отличаться. Пожалуйста, отправляйте исправления и дополнения на mail@vanheusden.com. Сообщить об ошибках в программе можно по адресу mail@vanheusden.com. HTTPing-4.4.0/httping.1000066400000000000000000000231711475432366700145600ustar00rootroot00000000000000.\" Copyright Folkert van Heusden, 2003-2023 .\" .\" This file may be copied under the conditions described .\" in the GNU GENERAL PUBLIC LICENSE, version 2 .\" that can be found on the website of the free software .\" foundation. .\" .TH HTTPING 1 2023-09 "httping" .SH NAME httping - measure the latency and throughput of a webserver .SH SYNOPSIS .BI "httping [" options "] .sp options: .BI "[\-g url] [\-h hostname] [\-p portnumber] [\-x proxyhost:port] [\-c count] [\-i interval] [\-t timeout] [\-s] [\-G] [\-b] [\-L xferlimit] [\-X] [\-l] [\-z] [\-f] [\-m] [\-o rc,...] [\-e string]" .BI "[\-I useragent string] [\-R referer string] [\-r] [\-n warn,crit] [\-N mode] [\-q] [\-V]" .SH DESCRIPTION The program .B httping lets you measure the latency of a webserver. Since version 1.0.6 also the throughput can be measured. .PP .SH OPTIONS .TP .B "\-5" The proxy server selected is a SOCKS5 server. .TP .B "\-6" Enable IPv6 mode. Default is IPv4. .TP .B "\-a" Audible ping .TP .B "\-b" Use this switch together with '\-G'. When this option is used, the transferspeed (in KB/s) is shown. .TP .B "\-B" Use this switch together with '\-G'. Ask the HTTP server to compress the returned data: this will reduce the influence of the bandwidth of your connection while increasing the influence of the processorpower of the HTTP server. .TP .B "\-c count" How many probes to send before exiting. .TP .B "\-D" Do not draw graphs in ncurses mode (\-K). .TP .B "\-e str" When the status-code differs from the ones selected with '\-o', the given string is displayed. .TP .B "\-E" Retrieve proxy settings from environment variables ('http_proxy' and 'https_proxy'). .TP .B "\-F" Attempt TCP Fast Open while trying to connect to a server (for Linux, version 3.7 onwards of the kernel) .TP .B "\-f" Flood ping: do not sit idle between each ping but ping as fast as the computer and network allow you to. .TP .B "\-G" Do a GET request instead of a HEAD request: this means that also the complete page/file must be transferred. Note that in this case you're no longer measuring the latency! .TP .B "\-g url" This selects the url to probe. E.g.: http://localhost/ .TP .B "\-h hostname" Instead of '\-g' one can also set a hostname to probe with \-h: \-h localhost .TP .B "\-I str" UserAgent-string to send to the webserver (instead of 'HTTPing '). .TP .B "\-i interval" How many seconds to sleep between every probe sent. .TP .B "\-K" Enable ncurses user interface. .TP .B "\-L x" Use this switch together with '\-G'. Limit the amount of data transferred to 'x'. Note that this only affects the content of the page/file and not the headerdata. .TP .B "\-l" Connect using SSL: for this to work you need to give a 'https'-url or a 443 portnumber. .TP .B "\-m" Show machine readable output (also check '\-o' and '\-e'). .TP .B "\-N x" Switches HTTPing to Nagios-plugin mode 2: return 0 when everything is fine, 'x' when anything fails. E.g.: 1 => Nagios warning state, 2 => Nagios critical state. .TP .B "\-n warn,crit" Switches HTTPing to Nagios-plugin mode 1: return exitcode '1' when the average response time is bigger then 'warn', return exitcode '2' when the the average response time is bigger then 'crit'. In all other cases return exitcode '0'. .TP .B "\-o x,x,..." This selects the HTTP status-codes which are regarded as an OK-state (only with '\-m'). .TP .B "\-p portnumber" \-p can be used together with \-h. \-p selects the portnumber to probe. .TP .B "\-q" Be quiet, only return an exit-code. .TP .B "\-R str" Referer-string to send to the webserver. .TP .B "\-Q" Use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. Usually possible when 'Connection: Keep-Alive' is sent by server. Adds a 'C' to the output if httping had to reconnect. .TP .B "\-r" Only resolve the hostname once: this takes the resolving out of the loop so that the latency of the DNS is not measured. Also useful when you want to measure only 1 webserver while the DNS returns a different ip-address for each resolve ('roundrobin'). .TP .B "\-S" Split measured latency in time to connect and time to exchange a request with the HTTP server. Split are returned in the following order: Resolve, Connect, Send, Receive, Disconnect. .TP .B "\-s" When a successfull transaction was done, show the HTTP statuscode (200, 404, etc.). .TP .B "\-T x" Read the password for website authentication from file 'x' (instead of entering it on the command line). .TP .B "\-t timeout" How long to wait for answer from the other side. .TP .B "\-U" Enable authentication against website. Set username with \-U, set password with \-P (or \-T to read the password from a file). .TP .B "\-v" Increase verbosity mode. To show standard deviation and dates in output. .TP .B "\-W" Do not abort program if resolving fails. .TP .B "\-X" Use this switch together with '\-G'. For each "ping" show the amount of data transferred (excluding the headers). .TP .B "\-x proxyhost[:port] Probe using a proxyserver. Note that you're also measuring the latency of the proxyserver! .TP .B "\-Y" Enable colors .TP .B "\-z" When connecting using SSL, display the fingerprint of the X509 certificate(s) of the peer. .TP .B "\-\-abbreviate" Abbreviate values bigger than thousand, million, billion, etc. .TP .B "\-\-adaptive-interval" or "\-\-ai" (Try to) ping on the same interval. E.g. if interval is set to 1.0 seconds and ping a ping t[n] occurs at 500s with duration 250ms, then the next ping (t[n+1]) will happen at 501 seconds and not at 501.25 seconds. Of course when the ping duration is > bigger than the interval, a ping will be "skipped" (not literally: the sequence number will continue) and t[n+1] will then be e.g. 502s instead of the expected 501s. This is useful for example in the ncurses output mode where an fft is calculated over the ping times. .TP .B "\-\-aggregates x[,y[,z[,etc.]]]" Show aggregates every x[/y[/z[/etc]]] seconds. .TP .B "\-\-divert\-connect x" Ignore the hostname in the URL and connect to 'x' instead. The given URL will be requested at 'x'. .TP .B "\-\-draw-phase" Not only draw the magnitude of the fourier transform, draw the phase as well. .TP .B "\-\-graph\-limit x" If values measured are bigger than x, then they're limitted to x. .TP .B "\-\-header x" Add an additional request-header 'x'. .TP .B "\-\-keep\-cookies" When the server sends a cookie, it will be returned in the next request. .TP .B "\-\-max\-mtu x" Maximum MTU to use. Cannot be larger than network interface MTU. .TP .B "\-\-median" Calculate median. .TP .B "\-\-no\-host\-header" Do not put a "Host:"\-header in the request header. .TP .B "\-\-no\-tcp\-nodelay" Do not disable "tcp delay" (Naggle). .TP .B "\-\-priority x" Set priority of packets. .TP .B "\-\-tos x" Set type of service. .TP .B "\-\-proxy\-user x" Use username 'x' to authenticate against proxy (http/socks5) server (optional). .TP .B "\-\-proxy\-password x" Use password 'x' to authenticate against proxy (http/socks5) server (optional). .TP .B "\-\-proxy\-password-file x" Read password from file 'x' to authenticate against proxy (http/socks5) server (optional). .TP .B "\-\-recv-buffer x" Set the size of the receive buffer (in bytes). .TP .B "\-\-slow\-log x" When the duration is x or more, show ping line in the slow log window (the middle window). .TP .B "\-\-threshold\-red x" If the measured threshold is higher than x (and \-Y is given), then the shown value is colored red. If you also use \-\-threshold\-yellow, then this value must be bigger. .TP .B "\-\-threshold\-yellow x" If the measured threshold is higher than x (and \-Y is given), then the shown value is colored yellow. .TP .B "\-\-threshold\-show x" If the measured threshold is higher than x, then the result is shown (default is show always). The value x is in ms. .TP .B "\-\-timestamp" or "\-\-ts" Put a timestamp before the result-lines. Use \-v to also show a date. .TP .B "\-\-tx-buffer x" Set the size of the transmit buffer (in bytes). .TP .B "\-V" Show the version and exit. .SH OUTPUT In split mode (\-S) something like "time=0.08+24.09+23.17+15.64+0.02=62.98 ms" is shown. The first value is the time it took to resolve the hostname (or 'n/a' if it did not resolve in this iteration, e.g. in "resolve once" (\-r) mode), then the time it took to connect (or \-1 for example in persistent connection (\-Q, HTTP v1.1), after that the time it took to put the request on the wire, then the time it took for the HTTP server to process the request and send it back and lastly the time it took to close the connection. .SH GRAPH The graph in the ncurses uses colors to encode a meaning. Green: value is less than 1 block. Red: the value did not fit in the graph. Blue: the value was limitted by \-\-graph\-limit. Cyan: no measurement for that point in time. .SH KEYS Press + to exit the program. It will display a summary of what was measured. In the ncurses gui, press + to forcibly redraw the screen. Press 'H' to halt the graphs (and again to continue). Press 'q' to stop the program ( + will work too). .SH EXAMPLES .TP .B "httping \-g http://localhost/" Ping the webserver on host 'localhost'. .TP .B "httping \-h localhost \-p 1000" Ping the webserver on host 'localhost' and portnumber 1000. .TP .B "httping \-l \-g https://localhost/" Ping the webserver on host 'localhost' using an SSL connection. .TP .B "httping \-g http://localhost/ -U username -P password" Ping the webserver on host 'localhost' using the Basic HTTP Authentication. .SH BUGS None. This program is totally bug-free. .SH "SEE ALSO" .BR http://www.vanheusden.com/httping/ .SH NOTES This page describes .B httping as found in the httping-2.3 package; other versions may differ slightly. Please mail corrections and additions to mail@vanheusden.com. Report bugs in the program to mail@vanheusden.com. HTTPing-4.4.0/io.c000066400000000000000000000064151475432366700135760ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include "gen.h" #include #include #include #include #include #include #include #include #include #include "gen.h" #include "error.h" ssize_t read_to(int fd, char *whereto, size_t len, double timeout) { for(;;) { ssize_t rc; struct timeval to; fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; rc = select(fd + 1, &rfds, NULL, NULL, &to); if (rc == 0) return RC_TIMEOUT; else if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("read_to::select failed: %s"), strerror(errno)); return RC_SHORTREAD; } return read(fd, whereto, len); } } ssize_t myread(int fd, char *whereto, size_t len, double timeout) { ssize_t cnt=0; while(len>0) { ssize_t rc; struct timeval to; fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; rc = select(fd + 1, &rfds, NULL, NULL, &to); if (rc == 0) return RC_TIMEOUT; else if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("myread::select failed: %s"), strerror(errno)); return RC_SHORTREAD; } if (FD_ISSET(fd, &rfds)) { rc = read(fd, whereto, len); if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("myread::read failed: %s"), strerror(errno)); return RC_SHORTREAD; } else if (rc == 0) break; else { whereto += rc; len -= rc; cnt += rc; } } } return cnt; } ssize_t mywrite(int fd, char *wherefrom, size_t len, double timeout) { ssize_t cnt=0; while(len>0) { ssize_t rc; struct timeval to; fd_set wfds; FD_ZERO(&wfds); FD_SET(fd, &wfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; rc = select(fd + 1, NULL, &wfds, NULL, &to); if (rc == 0) return RC_TIMEOUT; else if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("mywrite::select failed: %s"), strerror(errno)); return RC_SHORTWRITE; } rc = write(fd, wherefrom, len); if (rc == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) return RC_CTRLC; set_error(gettext("mywrite::write failed: %s"), strerror(errno)); return RC_SHORTWRITE; } else if (rc == 0) break; else { wherefrom += rc; len -= rc; cnt += rc; } } return cnt; } int set_fd_nonblocking(int fd) { /* set fd to non-blocking */ if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { fprintf(stderr, gettext("set_fd_nonblocking failed! (%s)\n"), strerror(errno)); return -1; } return 0; } int set_fd_blocking(int fd) { /* set fd to blocking */ if (fcntl(fd, F_SETFL, 0) == -1) { fprintf(stderr, gettext("set_fd_blocking failed! (%s)\n"), strerror(errno)); return -1; } return 0; } HTTPing-4.4.0/io.h000066400000000000000000000005461475432366700136020ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ ssize_t read_to(int fd, char *whereto, size_t len, double timeout); ssize_t myread(int fd, char *whereto, size_t len, double timeout); ssize_t mywrite(int fd, const char *wherefrom, size_t len, double timeout); int set_fd_nonblocking(int fd); int set_fd_blocking(int fd); HTTPing-4.4.0/kalman.c000066400000000000000000000036021475432366700144250ustar00rootroot00000000000000/* #define _TEST */ #include #ifdef _TEST #include #include #endif double x_est_last = 0.0, P_last = 0.0, Q = 0.0, R = 0.0, K = 0.0, P = 0.0, P_temp = 0.0, x_temp_est = 0.0, x_est = 0.0, z_measured = 0.0, z_real = 0.0, sum_error_kalman = 0.0, sum_error_measure = 0.0; char first = 1; void kalman_init(double ideal_value) { /* initial values for the kalman filter */ x_est_last = 0; P_last = 0; /* the noise in the system (FIXME?) */ Q = 0.022; R = 0.617; z_real = ideal_value; /* 0.5; the ideal value we wish to measure */ first = 1; } double kalman_do(double z_measured) { /* initialize with a measurement */ if (first) { first = 0; x_est_last = z_measured; } /* do a prediction */ x_temp_est = x_est_last; P_temp = P_last + Q; /* calculate the Kalman gain */ K = P_temp * (1.0/(P_temp + R)); /* measure */ /*z_measured = z_real + frand()*0.09; the real measurement plus noise*/ /* correct */ x_est = x_temp_est + K * (z_measured - x_temp_est); P = (1- K) * P_temp; /* we have our new system */ #ifdef _TEST printf("Ideal position: %6.3f \n",z_real); printf("Measured position: %6.3f [diff:%.3f]\n",z_measured,fabs(z_real-z_measured)); printf("Kalman position: %6.3f [diff:%.3f]\n",x_est,fabs(z_real - x_est)); #endif sum_error_kalman += fabs(z_real - x_est); sum_error_measure += fabs(z_real-z_measured); /* update our last's */ P_last = P; x_est_last = x_est; #ifdef _TEST printf("Total error if using raw measured: %f\n",sum_error_measure); printf("Total error if using kalman filter: %f\n",sum_error_kalman); printf("Reduction in error: %d%% \n",100-(int)((sum_error_kalman/sum_error_measure)*100)); #endif return x_est; } #ifdef _TEST int main(int argc, char *argv[]) { kalman_init(0.0); for(int loop=0; loop<25; loop++) { double v = drand48(); printf("%d] %f %f\n", loop + 1, v, kalman_do(v)); } return 0; } #endif HTTPing-4.4.0/kalman.h000066400000000000000000000002331475432366700144270ustar00rootroot00000000000000/* taken (and adapted) from http://www.dzone.com/snippets/simple-kalman-filter-c */ void kalman_init(double ideal_value); double kalman_do(double value); HTTPing-4.4.0/main.c000066400000000000000000001630231475432366700141120ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include "config.h" #include #define _GNU_SOURCE #define __USE_XOPEN #include #include #include #include #include "gen.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NO_SSL #include #include "mssl.h" #endif #include #include #if defined(sun) || defined(__sun) #include #endif #if HAVE_NCURSES #include #endif #include "gen.h" #include "help.h" #include "colors.h" #include "http.h" #include "io.h" #include "tcp.h" #include "res.h" #include "utils.h" #include "error.h" #include "socks5.h" #if HAVE_NCURSES #include "nc.h" #endif #include "cookies.h" volatile int stop = 0; int quiet = 0; char machine_readable = 0; char json_output = 0; char show_ts = 0; int max_x = 80, max_y = 24; char nagios_mode = 0; char ncurses_mode = 0; int fd = -1; volatile char got_sigquit = 0; void handler_quit(int s) { signal(SIGQUIT, handler_quit); got_sigquit = 1; } void determine_terminal_size(int *max_y, int *max_x) { struct winsize size; *max_x = *max_y = 0; if (!isatty(1)) { *max_y = 24; *max_x = 80; } #ifdef TIOCGWINSZ else if (ioctl(1, TIOCGWINSZ, &size) == 0) { *max_y = size.ws_row; *max_x = size.ws_col; } #endif if (!*max_x || !*max_y) { char *dummy = getenv("COLUMNS"); if (dummy) *max_x = atoi(dummy); else *max_x = 80; dummy = getenv("LINES"); if (dummy) *max_y = atoi(dummy); else *max_y = 24; } } void emit_statuslines(double run_time) { #if HAVE_NCURSES if (ncurses_mode) { time_t t = time(NULL); char *t_str = ctime(&t); char *dummy = strchr(t_str, '\n'); if (dummy) *dummy = 0x00; status_line(gettext("%s, run time: %.3fs, press ctrl + c to stop"), t_str, run_time); } #else (void)run_time; #endif } void emit_headers(char *in) { #if HAVE_NCURSES int len_in = -1; if (ncurses_mode && in != NULL && (len_in = strlen(in) - 4) > 0) { extern WINDOW *w_slow; werase(w_slow); int pos = 0, pos_out = 0; char *copy = (char *)malloc(len_in + 1), *dummy = NULL; for(pos=0; pos 1) printf(", \n"); printf("{ "); printf("\"status\" : \"%d\", ", ok); printf("\"seq\" : \"%d\", ", seq); printf("\"start_ts\" : \"%f\", ", start_ts); if (t_resolve!=NULL && t_resolve -> cur_valid) printf("\"resolve_ms\" : \"%e\", ", t_resolve -> cur); else printf("\"resolve_ms\" : \"%e\", ",-1.0); if (t_connect!=NULL && t_connect -> cur_valid) printf("\"connect_ms\" : \"%e\", ", t_connect -> cur); else printf("\"connect_ms\" : \"%e\", ",-1.0); if (t_request != NULL) printf("\"request_ms\" : \"%e\", ", t_request -> cur); if (t_total != NULL) printf("\"total_ms\" : \"%e\", ", t_total -> cur); printf("\"http_code\" : \"%d\", ", http_code); printf("\"msg\" : \"%s\", ", msg); printf("\"header_size\" : \"%d\", ", header_size); printf("\"data_size\" : \"%d\", ", data_size); printf("\"bps\" : \"%f\", ", Bps); printf("\"host\" : \"%s\", ", host); printf("\"ssl_fingerprint\" : \"%s\", ", ssl_fp ? ssl_fp : ""); printf("\"time_offset\" : \"%f\", ", toff_diff_ts); printf("\"tfo_success\" : \"%s\", ", tfo_success ? "true" : "false"); if (t_ssl != NULL && t_ssl -> cur_valid) printf("\"ssl_ms\" : \"%e\", ", t_ssl -> cur); printf("\"tfo_succes\" : \"%s\", ", tfo_success ? "true" : "false"); if (t_ssl !=NULL && t_ssl -> cur_valid) printf("\"ssl_ms\" : \"%e\", ", t_ssl -> cur); if (t_write != NULL) printf("\"write\" : \"%e\", ", t_write -> cur); if (t_close != NULL) printf("\"close\" : \"%e\", ", t_close -> cur); printf("\"cookies\" : \"%d\", ", n_cookies); if (stats_to != NULL && stats_to -> cur_valid) printf("\"to\" : \"%e\", ", stats_to -> cur); if (tcp_rtt_stats !=NULL && tcp_rtt_stats -> cur_valid) printf("\"tcp_rtt_stats\" : \"%e\", ", tcp_rtt_stats -> cur); printf("\"re_tx\" : \"%d\", ", re_tx); printf("\"pmtu\" : \"%d\", ", pmtu); printf("\"tos\" : \"%02x\" ", recv_tos); printf("}"); } char *get_ts_str(int verbose) { char buffer[4096] = { 0 }; struct tm *tvm = NULL; struct timeval tv; (void)gettimeofday(&tv, NULL); tvm = localtime(&tv.tv_sec); if (verbose == 1) sprintf(buffer, "%04d/%02d/%02d ", tvm -> tm_year + 1900, tvm -> tm_mon + 1, tvm -> tm_mday); else if (verbose >= 2) sprintf(buffer, "%.6f", get_ts()); if (verbose <= 1) sprintf(&buffer[strlen(buffer)], "%02d:%02d:%02d.%03d", tvm -> tm_hour, tvm -> tm_min, tvm -> tm_sec, (int)(tv.tv_usec / 1000)); return strdup(buffer); } void emit_error(int verbose, int seq, double start_ts) { char *ts = show_ts ? get_ts_str(verbose) : NULL; #if HAVE_NCURSES if (ncurses_mode) { slow_log("\n%s%s", ts ? ts : "", get_error()); update_terminal(); } else #endif if (!quiet && !machine_readable && !nagios_mode && !json_output) printf("%s%s%s%s\n", ts ? ts : "", c_error, get_error(), c_normal); if (json_output) emit_json(0, seq, start_ts, NULL, NULL, NULL, -1, get_error(), -1, -1, -1, "", "", -1, 0, NULL, NULL, NULL, 0, NULL, NULL, 0, 0, 0, NULL); clear_error(); free(ts); fflush(NULL); } void handler(int sig) { #if HAVE_NCURSES if (sig == SIGWINCH) win_resize = 1; else #endif { if (!json_output) fprintf(stderr, gettext("Got signal %d\n"), sig); stop = 1; } } char * read_file(const char *file) { char buffer[4096] = { 0 }, *lf = NULL; FILE *fh = fopen(file, "rb"); if (!fh) error_exit(gettext("Cannot open password-file %s"), file); if (!fgets(buffer, sizeof buffer, fh)) error_exit(gettext("Problem reading password from file %s"), file); fclose(fh); lf = strchr(buffer, '\n'); if (lf) *lf = 0x00; return strdup(buffer); } char * create_http_request_header(const char *get, char use_proxy_host, char get_instead_of_head, char persistent_connections, const char *hostname, const char *useragent, const char *referer, char ask_compression, char no_cache, const char *auth_usr, const char *auth_password, char **static_cookies, int n_static_cookies, char **dynamic_cookies, int n_dynamic_cookies, const char *proxy_buster, const char *proxy_user, const char *proxy_password, char **additional_headers, int n_additional_headers, char http2, char is_ssl) { int index; char *request = NULL; char pb[128] = { 0 }; if (proxy_buster) { if (strchr(get, '?')) pb[0] = '&'; else pb[0] = '?'; snprintf(pb + 1, sizeof pb - 1, "%s=%ld", proxy_buster, lrand48()); } if (use_proxy_host) str_add(&request, "%s %s%s HTTP/1.%c\r\n", get_instead_of_head?"GET":"HEAD", get, pb, persistent_connections || http2 ? '1':'0'); else { const char *dummy = get, *slash = NULL; if (strncasecmp(dummy, "http://", 7) == 0) dummy += 7; else if (strncasecmp(dummy, "https://", 7) == 0) dummy += 8; slash = strchr(dummy, '/'); if (slash) str_add(&request, "%s %s HTTP/1.%c\r\n", get_instead_of_head?"GET":"HEAD", slash, persistent_connections || http2?'1':'0'); else str_add(&request, "%s / HTTP/1.%c\r\n", get_instead_of_head?"GET":"HEAD", persistent_connections || http2 ? '1':'0'); } if (hostname) str_add(&request, "Host: %s\r\n", hostname); if (useragent) str_add(&request, "User-Agent: %s\r\n", useragent); else str_add(&request, "User-Agent: HTTPing v" VERSION "\r\n"); if (referer) str_add(&request, "Referer: %s\r\n", referer); if (ask_compression) str_add(&request, "Accept-Encoding: gzip,deflate\r\n"); if (http2) { str_add(&request, "Connection: Upgrade, HTTP2-Settings\r\n"); if (is_ssl) // https str_add(&request, "Upgrade: h2\r\n"); else str_add(&request, "Upgrade: h2c\r\n"); str_add(&request, "HTTP2-Settings: \r\n"); } if (no_cache) { str_add(&request, "Pragma: no-cache\r\n"); str_add(&request, "Cache-Control: no-cache\r\n"); } /* Basic Authentification */ if (auth_usr) { char auth_string[256] = { 0 }; char b64_auth_string[512] = { 0 }; sprintf(auth_string, "%s:%s", auth_usr, auth_password); enc_b64(auth_string, strlen(auth_string), b64_auth_string); str_add(&request, "Authorization: Basic %s\r\n", b64_auth_string); } /* proxy authentication */ if (proxy_user) { char ppa_string[256] = { 0 }; char b64_ppa_string[512] = { 0 }; sprintf(ppa_string, "%s:%s", proxy_user, proxy_password); enc_b64(ppa_string, strlen(ppa_string), b64_ppa_string); str_add(&request, "Proxy-Authorization: Basic %s\r\n", b64_ppa_string); } /* Cookie insertion */ for(index=0; index= sizeof in_use) error_exit(gettext("URL too big, HTTPing has a %d bytes limit"), sizeof in_use - 1); /* make url complete, if not already */ if (strncasecmp(in, "http://", 7) == 0 || strncasecmp(in, "https://", 8) == 0) /* complete url? */ { snprintf(in_use, sizeof in_use - 1, "%s", in); if (strchr(&in[8], '/') == NULL) in_use[strlen(in_use)] = '/'; } else if (strchr(in, '/')) /* hostname + location without 'http://'? */ sprintf(in_use, "http://%s", in); else if (use_ssl) sprintf(in_use, "https://%s/", in); else sprintf(in_use, "http://%s/", in); /* sanity check */ if (strncasecmp(in_use, "http://", 7) == 0 && use_ssl) error_exit(gettext("using \"http://\" with SSL enabled (-l)")); *complete_url = strdup(in_use); /* fetch hostname */ if (strncasecmp(in_use, "http://", 7) == 0) *hostname = strdup(&in_use[7]); else /* https */ *hostname = strdup(&in_use[8]); dummy = strchr(*hostname, '/'); if (dummy) *dummy = 0x00; /* fetch port number */ if (*portnr == 0) { if (use_ssl || strncasecmp(in, "https://", 8) == 0) *portnr = 443; else *portnr = 80; } if (!use_ipv6) { char *at = strchr(*hostname, '@'); char *colon = strchr(*hostname, ':'); char *colon2 = colon ? strchr(colon + 1, ':') : NULL; if (colon2) { *colon2 = 0x00; *portnr = atoi(colon2 + 1); if (at) { *colon = 0x00; *at = 0x00; *auth_user = strdup(*hostname); *auth_password = strdup(colon + 1); } } else if (colon) { if (colon < at) { *colon = 0x00; *at = 0x00; *auth_user = strdup(*hostname); *auth_password = strdup(colon + 1); } else if (at) { *at = 0x00; *auth_user = strdup(*hostname); } else { *colon = 0x00; *portnr = atoi(colon + 1); } } } /* fetch path */ dummy = strchr(&in_use[8], '/'); if (dummy) *path = strdup(dummy); else *path = strdup("/"); } typedef struct { int interval, last_ts; double value, sd, min, max; int n_values; } aggregate_t; void set_aggregate(char *in, int *n_aggregates, aggregate_t **aggregates) { char *dummy = in; *n_aggregates = 0; for(;dummy;) { (*n_aggregates)++; *aggregates = (aggregate_t *)realloc(*aggregates, *n_aggregates * sizeof(aggregate_t)); memset(&(*aggregates)[*n_aggregates - 1], 0x00, sizeof(aggregate_t)); (*aggregates)[*n_aggregates - 1].interval = atoi(dummy); (*aggregates)[*n_aggregates - 1].max = -MY_DOUBLE_INF; (*aggregates)[*n_aggregates - 1].min = MY_DOUBLE_INF; dummy = strchr(dummy, ','); if (dummy) dummy++; } } void do_aggregates(double cur_ms, int cur_ts, int n_aggregates, aggregate_t *aggregates, int verbose, char show_ts) { int index=0; /* update measurements */ for(index=0; index aggregates[index].max) aggregates[index].max = cur_ms; aggregates[index].sd += cur_ms * cur_ms; aggregates[index].n_values++; } /* emit */ for(index=0; index 0; index++) { aggregate_t *a = &aggregates[index]; if (cur_ts - a -> last_ts >= a -> interval) { char *line = NULL; double avg = a -> n_values ? a -> value / (double)a -> n_values : -1.0; char *ts = get_ts_str(verbose); str_add(&line, "%s", show_ts ? ts : ""); free(ts); str_add(&line, gettext("AGG[%d]: %d values, min/avg/max%s = %.1f/%.1f/%.1f"), a -> interval, a -> n_values, verbose ? gettext("/sd") : "", a -> min, avg, a -> max); if (verbose) { double sd = -1.0; if (a -> n_values) sd = sqrt((a -> sd / (double)a -> n_values) - pow(avg, 2.0)); str_add(&line, "/%.1f", sd); } str_add(&line, " ms"); #if HAVE_NCURSES if (ncurses_mode) slow_log("\n%s", line); else #endif printf("%s\n", line); free(line); aggregates[index].value = aggregates[index].sd = 0.0; aggregates[index].min = MY_DOUBLE_INF; aggregates[index].max = -MY_DOUBLE_INF; aggregates[index].n_values = 0; aggregates[index].last_ts = cur_ts; } } } void fetch_proxy_settings(char **proxy_user, char **proxy_password, char **proxy_host, int *proxy_port, char use_ssl, char use_ipv6) { char *str = getenv(use_ssl ? "https_proxy" : "http_proxy"); if (!str) { /* FIXME from wgetrc/curlrc? */ } if (str) { char *path = NULL, *url = NULL; interpret_url(str, &path, proxy_host, proxy_port, use_ipv6, use_ssl, &url, proxy_user, proxy_password); free(url); free(path); } } void parse_nagios_settings(const char *in, double *nagios_warn, double *nagios_crit) { char *dummy = strchr(in, ','); if (!dummy) error_exit(gettext("-n: missing parameter\n")); *nagios_warn = atof(in); *nagios_crit = atof(dummy + 1); } void parse_bind_to(const char *in, struct sockaddr_in *bind_to_4, struct sockaddr_in6 *bind_to_6, struct sockaddr_in **bind_to) { char *dummy = strchr(in, ':'); if (dummy) { *bind_to = (struct sockaddr_in *)bind_to_6; memset(bind_to_6, 0x00, sizeof *bind_to_6); bind_to_6 -> sin6_family = AF_INET6; if (inet_pton(AF_INET6, in, &bind_to_6 -> sin6_addr) != 1) error_exit(gettext("cannot convert ip address '%s' (for -y)\n"), in); } else { *bind_to = (struct sockaddr_in *)bind_to_4; memset(bind_to_4, 0x00, sizeof *bind_to_4); bind_to_4 -> sin_family = AF_INET; if (inet_pton(AF_INET, in, &bind_to_4 -> sin_addr) != 1) error_exit(gettext("cannot convert ip address '%s' (for -y)\n"), in); } } time_t parse_date_from_response_headers(const char *in) { char *date = NULL, *komma = NULL; if (in == NULL) return -1; date = strstr(in, "\nDate:"); komma = date ? strchr(date, ',') : NULL; if (date && komma) { struct tm tm; memset(&tm, 0x00, sizeof tm); /* 22 Feb 2015 09:13:56 */ if (strptime(komma + 1, "%d %b %Y %H:%M:%S %Z", &tm)) return mktime(&tm); } return -1; } int calc_page_age(const char *in, const time_t their_ts) { int age = -1; if (in != NULL && their_ts > 0) { char *date = strstr(in, "\nLast-Modified:"); char *komma = date ? strchr(date, ',') : NULL; if (date && komma) { struct tm tm; memset(&tm, 0x00, sizeof tm); /* 22 Feb 2015 09:13:56 */ if (strptime(komma + 1, "%d %b %Y %H:%M:%S %Z", &tm)) age = their_ts - mktime(&tm); } } return age; } const char *get_location(const char *host, int port, char use_ssl, char *reply) { if (reply) { char *copy = strdup(reply); char *head = strstr(copy, "\nLocation:"); char *lf = head ? strchr(head + 1, '\n') : NULL; if (head) { char *buffer = NULL; char *dest = head + 11; if (lf) *lf = 0x00; if (memcmp(dest, "http", 4) == 0) str_add(&buffer, "%s", dest); else str_add(&buffer, "http%s://%s:%d%s", use_ssl ? "s" : "", host, port, dest); free(copy); return buffer; } free(copy); } return NULL; } char check_compressed(const char *reply) { if (reply != NULL) { char *encoding = strstr(reply, "\nContent-Encoding:"); if (encoding) { char *dummy = strchr(encoding + 1, '\r'); if (dummy) *dummy = 0x00; dummy = strchr(encoding + 1, '\n'); if (dummy) *dummy = 0x00; if (strstr(encoding, "gzip") == 0 || strstr(encoding, "deflate") == 0) return 1; } } return 0; } int nagios_result(int ok, int nagios_mode, int nagios_exit_code, double avg_httping_time, double nagios_warn, double nagios_crit) { if (nagios_mode == 1) { if (ok == 0) { printf(gettext("CRITICAL - connecting failed: %s"), get_error()); return 2; } else if (avg_httping_time >= nagios_crit) { printf(gettext("CRITICAL - average httping-time is %.1f\n"), avg_httping_time); return 2; } else if (avg_httping_time >= nagios_warn) { printf(gettext("WARNING - average httping-time is %.1f\n"), avg_httping_time); return 1; } printf(gettext("OK - average httping-time is %.1f (%s)|ping=%f\n"), avg_httping_time, get_error(), avg_httping_time); return 0; } else if (nagios_mode == 2) { const char *err = get_error(); if (ok && err[0] == 0x00) { printf(gettext("OK - all fine, avg httping time is %.1f|ping=%f\n"), avg_httping_time, avg_httping_time); return 0; } printf(gettext("%s: - failed: %s"), nagios_exit_code == 1?"WARNING":(nagios_exit_code == 2?"CRITICAL":"ERROR"), err); return nagios_exit_code; } return -1; } void proxy_to_host_and_port(char *in, char **proxy_host, int *proxy_port) { if (in[0] == '[') { char *dummy = NULL; *proxy_host = strdup(in + 1); dummy = strchr(*proxy_host, ']'); if (dummy) { *dummy = 0x00; /* +2: ']:' */ *proxy_port = atoi(dummy + 2); } } else { char *dummy = strchr(in, ':'); *proxy_host = in; if (dummy) { *dummy=0x00; *proxy_port = atoi(dummy + 1); } } } void stats_close(int *fd, stats_t *t_close, char is_failure) { double t_start = get_ts(), t_end = -1;; if (is_failure) failure_close(*fd); else close(*fd); *fd = -1; t_end = get_ts(); update_statst(t_close, (t_end - t_start) * 1000.0); } void add_header(char ***additional_headers, int *n_additional_headers, const char *in) { *additional_headers = (char **)realloc(*additional_headers, (*n_additional_headers + 1) * sizeof(char **)); (*additional_headers)[*n_additional_headers] = strdup(in); (*n_additional_headers)++; } void free_headers(char **additional_headers, int n_additional_headers) { int index = 0; for(index=0; index 0) fprintf(stderr, gettext("internal error! (curncount)\n")); if (count == -1) dummy = curncount; printf(gettext("%s%d%s connects, %s%d%s ok, %s%3.2f%%%s failed, time %s%s%.0fms%s\n"), c_yellow, curncount, c_normal, c_green, ok, c_normal, c_red, (((double)err) / ((double)dummy)) * 100.0, c_normal, c_blue, c_bright, total_took * 1000.0, c_normal); if (ok > 0) { if (t_total->calc_median) printf(gettext("round-trip min/avg/median/max%s = %s%.1f%s/%s%.1f%s/%.1f/%s%.1f%s"), verbose ? gettext("/sd") : "", c_bright, t_total -> min, c_normal, c_bright, avg_httping_time, c_normal, calc_median(t_total), c_bright, t_total -> max, c_normal); else printf(gettext("round-trip min/avg/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s"), verbose ? gettext("/sd") : "", c_bright, t_total -> min, c_normal, c_bright, avg_httping_time, c_normal, c_bright, t_total -> max, c_normal); if (verbose) { double sd_final = t_total -> n ? sqrt((t_total -> sd / (double)t_total -> n) - pow(avg_httping_time, 2.0)) : -1.0; printf("/%.1f", sd_final); } printf(" ms\n"); if (bps) printf(gettext("Transfer speed: min/avg/max = %s%f%s/%s%f%s/%s%f%s KB\n"), c_bright, bps -> Bps_min / 1024, c_normal, c_bright, (bps -> Bps_avg / (double)ok) / 1024.0, c_normal, c_bright, bps -> Bps_max / 1024.0, c_normal); } } int main(int argc, char *argv[]) { double started_at = -1; char do_fetch_proxy_settings = 0; char *hostname = NULL; char *proxy_host = NULL, *proxy_user = NULL, *proxy_password = NULL; int proxy_port = 8080; int portnr = 0; char *get = NULL, *request = NULL; int req_len = 0; int c = 0; int count = -1, curncount = 0; double wait = 1.0; char wait_set = 0; int audible = 0; int ok = 0, err = 0; double timeout = 30.0; char show_statuscodes = 0; char use_ssl = 0; const char *ok_str = "200"; const char *err_str = "-1"; const char *useragent = NULL; const char *referer = NULL; const char *auth_password = NULL; const char *auth_usr = NULL; char **static_cookies = NULL, **dynamic_cookies = NULL; int n_static_cookies = 0, n_dynamic_cookies = 0; char resolve_once = 0; char have_resolved = 0; double nagios_warn=0.0, nagios_crit=0.0; int nagios_exit_code = 2; double avg_httping_time = -1.0; int get_instead_of_head = 0; char show_Bps = 0, ask_compression = 0; bps_t bps; int Bps_limit = -1; char show_bytes_xfer = 0, show_fp = 0; SSL *ssl_h = NULL; BIO *s_bio = NULL; struct sockaddr_in *bind_to = NULL; struct sockaddr_in bind_to_4; struct sockaddr_in6 bind_to_6; char split = 0, use_ipv6 = 0; char persistent_connections = 0, persistent_did_reconnect = 0; char no_cache = 0; char use_tfo = 0; char abort_on_resolve_failure = 1; double offset_yellow = -1, offset_red = -1; char colors = 0; int verbose = 0; double offset_show = -1.0; char add_host_header = 1; char *proxy_buster = NULL; char proxy_is_socks5 = 0; char *url = NULL, *complete_url = NULL; int n_aggregates = 0; aggregate_t *aggregates = NULL; char *au_dummy = NULL, *ap_dummy = NULL; stats_t t_connect, t_request, t_total, t_resolve, t_write, t_ssl, t_close, stats_to, tcp_rtt_stats, stats_header_size; char first_resolve = 1; double graph_limit = MY_DOUBLE_INF; char nc_graph = 1; char adaptive_interval = 0; double show_slow_log = MY_DOUBLE_INF; char use_tcp_nodelay = 1; int max_mtu = -1; int write_sleep = 500; /* in us (microseconds), determines resolution of transmit time determination */ char keep_cookies = 0; char abbreviate = 0; char *divert_connect = NULL; int recv_buffer_size = -1, tx_buffer_size = -1; int priority = -1, send_tos = -1; char **additional_headers = NULL; int n_additional_headers = 0; #ifndef NO_SSL SSL_CTX *client_ctx = NULL; #endif const char *ca_path = NULL; struct sockaddr_in6 addr; struct addrinfo *ai = NULL, *ai_use = NULL; struct addrinfo *ai_proxy = NULL, *ai_use_proxy = NULL; char http2 = 0; char use_median = 0; char ignore_ssl_errors = 0; static struct option long_options[] = { {"aggregate", 1, NULL, 9 }, {"url", 1, NULL, 'g' }, {"hostname", 1, NULL, 'h' }, {"port", 1, NULL, 'p' }, {"proxy", 1, NULL, 'x' }, {"count", 1, NULL, 'c' }, {"persistent-connections", 0, NULL, 'Q' }, {"interval", 1, NULL, 'i' }, {"timeout", 1, NULL, 't' }, {"ipv6", 0, NULL, '6' }, {"show-statuscodes", 0, NULL, 's' }, {"split-time", 0, NULL, 'S' }, {"get-request", 0, NULL, 'G' }, {"show-transfer-speed", 0, NULL, 'b' }, {"show-xfer-speed-compressed", 0, NULL, 'B' }, {"data-limit", 1, NULL, 'L' }, {"show-kb", 0, NULL, 'X' }, {"no-cache", 0, NULL, 'Z' }, #ifndef NO_SSL {"insecure", 0, NULL, 'k' }, {"use-ssl", 0, NULL, 'l' }, {"show-fingerprint", 0, NULL, 'z' }, #endif {"flood", 0, NULL, 'f' }, {"audible-ping", 0, NULL, 'a' }, {"parseable-output", 0, NULL, 'm' }, {"ok-result-codes", 1, NULL, 'o' }, {"result-string", 1, NULL, 'e' }, {"user-agent", 1, NULL, 'I' }, {"referer", 1, NULL, 'S' }, {"resolve-once",0, NULL, 'r' }, {"nagios-mode-1", 1, NULL, 'n' }, {"nagios-mode-2", 1, NULL, 'n' }, {"bind-to", 1, NULL, 'y' }, {"quiet", 0, NULL, 'q' }, {"username", 1, NULL, 'U' }, {"password", 1, NULL, 'P' }, {"cookie", 1, NULL, 'C' }, {"colors", 0, NULL, 'Y' }, {"offset-yellow", 1, NULL, 1 }, {"threshold-yellow", 1, NULL, 1 }, {"offset-red", 1, NULL, 2 }, {"threshold-red", 1, NULL, 2 }, {"offset-show", 1, NULL, 3 }, {"show-offset", 1, NULL, 3 }, {"threshold-show", 1, NULL, 3 }, {"show-threshold", 1, NULL, 3 }, {"timestamp", 0, NULL, 4 }, {"ts", 0, NULL, 4 }, {"no-host-header", 0, NULL, 5 }, {"proxy-buster", 1, NULL, 6 }, {"proxy-user", 1, NULL, 7 }, {"proxy-password", 1, NULL, 8 }, {"proxy-password-file", 1, NULL, 10 }, {"graph-limit", 1, NULL, 11 }, {"adaptive-interval", 0, NULL, 12 }, {"ai", 0, NULL, 12 }, {"slow-log", 0, NULL, 13 }, {"draw-phase", 0, NULL, 14 }, {"no-tcp-nodelay", 0, NULL, 15 }, {"max-mtu", 1, NULL, 16 }, {"keep-cookies", 0, NULL, 17 }, {"abbreviate", 0, NULL, 18 }, {"divert-connect", 1, NULL, 19 }, {"recv-buffer", 1, NULL, 20 }, {"tx-buffer", 1, NULL, 21 }, {"priority", 1, NULL, 23 }, {"tos", 1, NULL, 24 }, {"header", 1, NULL, 25 }, {"ca-path", 1, NULL, 26 }, {"median", 0, NULL, 27 }, #if HAVE_NCURSES {"ncurses", 0, NULL, 'K' }, {"gui", 0, NULL, 'K' }, #if HAVE_FFTW3 {"no-graph", 0, NULL, 'D' }, #endif #endif {"http2", 0, NULL, '2' }, {"version", 0, NULL, 'V' }, {"help", 0, NULL, 22 }, {NULL, 0, NULL, 0 } }; bps.Bps_min = 1 << 30; bps.Bps_max = -bps.Bps_min; bps.Bps_avg = 0; setlocale(LC_ALL, ""); bindtextdomain("httping", LOCALEDIR); textdomain("httping"); determine_terminal_size(&max_y, &max_x); signal(SIGPIPE, SIG_IGN); while((c = getopt_long(argc, argv, "2DKEA5MvYWT:ZQ6Sy:XL:bBg:h:p:c:i:Gx:t:o:e:falqsmV?I:R:rn:N:zP:U:C:Fk", long_options, NULL)) != -1) { switch(c) { case '2': http2 = 1; break; case 26: ca_path = optarg; break; case 27: use_median = 1; break; case 25: add_header(&additional_headers, &n_additional_headers, optarg); break; case 24: send_tos = atoi(optarg); break; case 23: #ifdef linux priority = atoi(optarg); #else error_exit("Setting the network priority is only supported on Linux.\n"); #endif break; case 21: tx_buffer_size = atoi(optarg); break; case 20: recv_buffer_size = atoi(optarg); break; case 19: divert_connect = optarg; break; case 18: abbreviate = 1; break; case 17: keep_cookies = 1; break; case 16: max_mtu = atoi(optarg); break; case 15: use_tcp_nodelay = 0; break; #if HAVE_NCURSES case 14: draw_phase = 1; break; #endif case 13: show_slow_log = atof(optarg); break; case 12: adaptive_interval = 1; break; case 11: graph_limit = atof(optarg); break; #if HAVE_NCURSES case 'K': ncurses_mode = 1; adaptive_interval = 1; if (!wait_set) wait = 0.5; break; #if HAVE_FFTW3 case 'D': nc_graph = 0; break; #endif #endif case 'E': do_fetch_proxy_settings = 1; break; case 'A': fprintf(stderr, gettext("\n *** -A is no longer required ***\n\n")); break; case 'M': json_output = 1; break; case 'v': verbose++; break; case 1: offset_yellow = atof(optarg); break; case 2: offset_red = atof(optarg); break; case 3: offset_show = atof(optarg); break; case 4: show_ts = 1; break; case 5: add_host_header = 0; break; case 6: proxy_buster = optarg; break; case '5': proxy_is_socks5 = 1; break; case 7: proxy_user = optarg; break; case 8: proxy_password = optarg; break; case 9: set_aggregate(optarg, &n_aggregates, &aggregates); break; case 10: proxy_password = read_file(optarg); break; case 'Y': colors = 1; break; case 'W': abort_on_resolve_failure = 0; break; case 'T': auth_password = read_file(optarg); break; case 'Z': no_cache = 1; break; case '6': use_ipv6 = 1; break; case 'S': split = 1; break; case 'Q': persistent_connections = 1; break; case 'y': parse_bind_to(optarg, &bind_to_4, &bind_to_6, &bind_to); break; case 'z': show_fp = 1; break; case 'X': show_bytes_xfer = 1; break; case 'L': Bps_limit = atoi(optarg); break; case 'B': show_Bps = 1; ask_compression = 1; break; case 'b': show_Bps = 1; break; case 'e': err_str = optarg; break; case 'o': ok_str = optarg; break; case 'x': proxy_to_host_and_port(optarg, &proxy_host, &proxy_port); break; case 'g': url = optarg; break; case 'r': resolve_once = 1; break; case 'h': free(url); url = NULL; str_add(&url, "http://%s/", optarg); break; case 'p': portnr = atoi(optarg); break; case 'c': count = atoi(optarg); break; case 'i': wait = atof(optarg); if (wait < 0.0) error_exit(gettext("-i cannot have a value smaller than zero")); wait_set = 1; break; case 't': timeout = atof(optarg); break; case 'I': useragent = optarg; break; case 'R': referer = optarg; break; case 'a': audible = 1; break; case 'f': wait = 0; wait_set = 1; adaptive_interval = 0; break; case 'G': get_instead_of_head = 1; break; #ifndef NO_SSL case 'l': use_ssl = 1; break; #endif case 'm': machine_readable = 1; break; case 'q': quiet = 1; break; case 's': show_statuscodes = 1; break; case 'k': ignore_ssl_errors = 1; break; case 'V': version(); return 0; case 'n': if (nagios_mode) error_exit(gettext("-n and -N are mutual exclusive\n")); else nagios_mode = 1; parse_nagios_settings(optarg, &nagios_warn, &nagios_crit); break; case 'N': if (nagios_mode) error_exit(gettext("-n and -N are mutual exclusive\n")); nagios_mode = 2; nagios_exit_code = atoi(optarg); break; case 'P': auth_password = optarg; break; case 'U': auth_usr = optarg; break; case 'C': add_cookie(&static_cookies, &n_static_cookies, optarg); break; case 'F': use_tfo = 1; break; case 22: version(); usage(argv[0]); return 0; case '?': default: fprintf(stderr, "\n"); version(); fprintf(stderr, gettext("\n\nPlease run:\n\t%s --help\nto see a list of options.\n\n"), argv[0]); return 1; } } init_statst(&t_resolve, use_median); init_statst(&t_connect, use_median); init_statst(&t_write, use_median); init_statst(&t_request, use_median); init_statst(&t_total, use_median); init_statst(&t_ssl, use_median); init_statst(&t_close, use_median); init_statst(&stats_to, use_median); #if defined(linux) || defined(__FreeBSD__) init_statst(&tcp_rtt_stats, use_median); #endif init_statst(&stats_header_size, use_median); if (do_fetch_proxy_settings) fetch_proxy_settings(&proxy_user, &proxy_password, &proxy_host, &proxy_port, use_ssl, use_ipv6); if (optind < argc) url = argv[optind]; if (!url) { fprintf(stderr, gettext("No URL/host to ping given\n\n")); return 1; } if (machine_readable + json_output + ncurses_mode > 1) error_exit(gettext("Cannot combine -m, -M and -K")); if ((machine_readable || json_output) && n_aggregates > 0) error_exit(gettext("Aggregates can only be used in non-machine/json-output mode")); clear_error(); if (!(get_instead_of_head || use_ssl) && show_Bps) error_exit(gettext("-b/-B can only be used when also using -G (GET instead of HEAD) or -l (use SSL)\n")); if (colors) set_colors(ncurses_mode); if (!machine_readable && !json_output) printf("%s%s", c_normal, c_white); interpret_url(url, &get, &hostname, &portnr, use_ipv6, use_ssl, &complete_url, &au_dummy, &ap_dummy); if (!auth_usr) auth_usr = au_dummy; if (!auth_password) auth_password = ap_dummy; #if HAVE_NCURSES if (ncurses_mode) { if (wait == 0.0) wait = 0.001; init_ncurses_ui(graph_limit, 1.0 / wait, colors); } #endif if (strncmp(complete_url, "https://", 8) == 0 && !use_ssl) { use_ssl = 1; #if HAVE_NCURSES if (ncurses_mode) { slow_log(gettext("\nAuto enabling SSL due to https-URL\n")); update_terminal(); } else #endif { fprintf(stderr, gettext("Auto enabling SSL due to https-URL\n")); } } if (use_tfo && use_ssl) error_exit(gettext("TCP Fast open and SSL not supported together\n")); if (verbose) { #if HAVE_NCURSES if (ncurses_mode) { slow_log(gettext("\nConnecting to host %s, port %d and requesting file %s"), hostname, portnr, get); if (proxy_host) slow_log(gettext("\nUsing proxyserver: %s:%d"), proxy_host, proxy_port); } else #endif { printf(gettext("Connecting to host %s, port %d and requesting file %s\n\n"), hostname, portnr, get); if (proxy_host) fprintf(stderr, gettext("Using proxyserver: %s:%d\n"), proxy_host, proxy_port); } } #ifndef NO_SSL if (use_ssl) { client_ctx = initialize_ctx(ask_compression, ca_path); if (!client_ctx) { set_error(gettext("problem creating SSL context")); goto error_exit; } } #endif if (!quiet && !machine_readable && !nagios_mode && !json_output) { #if HAVE_NCURSES if (ncurses_mode) slow_log("\nPING %s:%d (%s):", hostname, portnr, get); else #endif printf("PING %s%s:%s%d%s (%s):\n", c_green, hostname, c_bright, portnr, c_normal, get); } if (json_output) printf("[\n"); if (adaptive_interval && wait <= 0.0) error_exit(gettext("Interval must be > 0 when using adaptive interval")); signal(SIGINT, handler); signal(SIGTERM, handler); signal(SIGQUIT, handler_quit); timeout *= 1000.0; /* change to ms */ /* if (follow_30x) { get headers const char *get_location(const char *host, int port, char use_ssl, char *reply) set new host/port/path/etc } */ started_at = get_ts(); if (proxy_host) { #if HAVE_NCURSES if (ncurses_mode) { slow_log(gettext("\nResolving hostname %s"), proxy_host); update_terminal(); } #endif if (resolve_host(proxy_host, &ai_proxy, use_ipv6, proxy_port) == -1) error_exit(get_error()); ai_use_proxy = select_resolved_host(ai_proxy, use_ipv6); if (!ai_use_proxy) error_exit(gettext("No valid IPv4 or IPv6 address found for %s"), proxy_host); } else if (resolve_once) { char *res_host = divert_connect ? divert_connect : hostname; #if HAVE_NCURSES if (ncurses_mode) { slow_log(gettext("\nResolving hostname %s"), res_host); update_terminal(); } #endif if (resolve_host(res_host, &ai, use_ipv6, portnr) == -1) { err++; emit_error(verbose, -1, started_at); have_resolved = 0; if (abort_on_resolve_failure) error_exit(get_error()); } ai_use = select_resolved_host(ai, use_ipv6); if (!ai_use) { set_error(gettext("No valid IPv4 or IPv6 address found for %s"), res_host); if (abort_on_resolve_failure) error_exit(get_error()); /* do not emit the resolve-error here: as 'have_resolved' is set to 0 next, the program will try to resolve again anyway this prevents a double error-message while err is increased only once */ have_resolved = 0; } if (have_resolved) get_addr(ai_use, &addr); } if (persistent_connections) fd = -1; while((curncount < count || count == -1) && stop == 0) { double dstart = -1.0, dend = -1.0, dafter_connect = 0.0, dafter_resolve = 0.0, dafter_write_complete = 0.0; char *reply = NULL; double Bps = 0; char is_compressed = 0; long long int bytes_transferred = 0; time_t their_ts = 0; int age = -1; char *sc = NULL, *scdummy = NULL; char *fp = NULL; int re_tx = 0, pmtu = 0, recv_tos = 0; socklen_t recv_tos_len = sizeof recv_tos; dstart = get_ts(); for(;;) { char did_reconnect = 0; int rc = -1; int persistent_tries = 0; int len = 0, overflow = 0, headers_len = 0; char req_sent = 0; double dummy_ms = 0.0; double their_est_ts = -1.0, toff_diff_ts = -1.0; char tfo_success = 0; double ssl_handshake = 0.0; char cur_have_resolved = 0; #if defined(linux) || defined(__FreeBSD__) struct tcp_info info; socklen_t info_len = sizeof(struct tcp_info); #endif curncount++; persistent_loop: if ((!resolve_once || (resolve_once == 1 && have_resolved == 0)) && fd == -1 && proxy_host == NULL) { char *res_host = divert_connect ? divert_connect : hostname; memset(&addr, 0x00, sizeof addr); #if HAVE_NCURSES if (ncurses_mode && first_resolve) { slow_log(gettext("\nResolving hostname %s"), res_host); update_terminal(); first_resolve = 0; } #endif if (ai) { freeaddrinfo(ai); ai_use = ai = NULL; } if (resolve_host(res_host, &ai, use_ipv6, portnr) == -1) { err++; emit_error(verbose, curncount, dstart); if (abort_on_resolve_failure) error_exit(get_error()); break; } ai_use = select_resolved_host(ai, use_ipv6); if (!ai_use) { set_error(gettext("No valid IPv4 or IPv6 address found for %s"), res_host); emit_error(verbose, curncount, dstart); err++; if (abort_on_resolve_failure) error_exit(get_error()); break; } get_addr(ai_use, &addr); cur_have_resolved = have_resolved = 1; } if (cur_have_resolved) { dafter_resolve = get_ts(); dummy_ms = (dafter_resolve - dstart) * 1000.0; update_statst(&t_resolve, dummy_ms); } free(request); request = create_http_request_header(proxy_host ? complete_url : get, proxy_host ? 1 : 0, get_instead_of_head, persistent_connections, add_host_header ? hostname : NULL, useragent, referer, ask_compression, no_cache, auth_usr, auth_password, static_cookies, n_static_cookies, dynamic_cookies, keep_cookies ? n_dynamic_cookies : 0, proxy_buster, proxy_user, proxy_password, additional_headers, n_additional_headers, http2, use_ssl); req_len = strlen(request); if (req_len >= 4096) { char *line = NULL; static int notify_cnt = 0; notify_cnt++; if (notify_cnt == MAX_SHOW_SUPPRESSION + 1) str_add(&line, gettext("Will no longer inform about request headers too large.")); else if (notify_cnt <= MAX_SHOW_SUPPRESSION) str_add(&line, gettext("Request headers > 4KB! (%d bytes) This may give failures with some HTTP servers."), req_len); if (line) { #if HAVE_NCURSES if (ncurses_mode) slow_log("\n%s", line); else #endif printf("%s\n", line); } free(line); } if ((persistent_connections && fd < 0) || !persistent_connections) { int rc = -1; struct addrinfo *ai_dummy = proxy_host ? ai_use_proxy : ai_use; fd = create_socket((struct sockaddr *)bind_to, ai_dummy, recv_buffer_size, tx_buffer_size, max_mtu, use_tcp_nodelay, priority, send_tos); if (fd < 0) rc = fd; /* FIXME need to fix this, this is ugly */ else if (proxy_host) { if (proxy_is_socks5) rc = socks5connect(fd, ai_dummy, timeout, proxy_user, proxy_password, hostname, portnr, abort_on_resolve_failure); #ifndef NO_SSL else if (use_ssl) rc = connect_ssl_proxy(fd, ai_dummy, timeout, proxy_user, proxy_password, hostname, portnr, &use_tfo); #endif else rc = connect_to(fd, ai_dummy, timeout, &use_tfo, request, req_len, &req_sent); } else { rc = connect_to(fd, ai_dummy, timeout, &use_tfo, request, req_len, &req_sent); } if (rc < 0) { failure_close(fd); fd = rc; /* FIXME need to fix this */ } did_reconnect = 1; } if (fd == RC_CTRLC) /* ^C pressed */ break; if (fd < 0) { fd = -1; } if (fd >= 0) { /* set fd blocking */ if (set_fd_blocking(fd) == -1) /* FIXME redundant? already in connect_to etc? */ { stats_close(&fd, &t_close, 1); break; } #ifndef NO_SSL if (use_ssl && ssl_h == NULL) { int rc = connect_ssl(fd, client_ctx, &ssl_h, &s_bio, timeout, &ssl_handshake, hostname, ignore_ssl_errors); if (rc == 0) update_statst(&t_ssl, ssl_handshake); else { stats_close(&fd, &t_close, 1); fd = rc; if (persistent_connections && ++persistent_tries < 2) { persistent_did_reconnect = 1; goto persistent_loop; } } } #endif } dafter_connect = get_ts(); if (did_reconnect) { if (cur_have_resolved) dummy_ms = (dafter_connect - dafter_resolve) * 1000.0; else dummy_ms = (dafter_connect - dstart) * 1000.0; update_statst(&t_connect, dummy_ms - ssl_handshake); } if (fd < 0) { if (fd == RC_TIMEOUT) set_error(gettext("timeout connecting to host")); emit_error(verbose, curncount, dstart); err++; fd = -1; break; } #ifndef NO_SSL if (use_ssl) rc = WRITE_SSL(ssl_h, request, req_len, timeout); else #endif { if (!req_sent) rc = mywrite(fd, request, req_len, timeout); else rc = req_len; } /* wait for data transmit(!) to complete, e.g. until the transmitbuffers are empty and the data was sent to the next hop */ #ifdef linux for(;;) { int bytes_left = 0; int i_rc = ioctl(fd, TIOCOUTQ, &bytes_left); if (i_rc == -1 || bytes_left == 0 || stop) break; dafter_write_complete = get_ts(); if ((dafter_write_complete - dafter_connect) * 1000.0 >= timeout) break; /* this keeps it somewhat from becoming a busy loop * I know of no other way to wait for the kernel to * finish the transmission */ myusleep(write_sleep); } #endif dafter_write_complete = get_ts(); dummy_ms = (dafter_write_complete - dafter_connect) * 1000.0; update_statst(&t_write, dummy_ms); if (rc != req_len) { if (persistent_connections) { if (++persistent_tries < 2) { stats_close(&fd, &t_close, 0); persistent_did_reconnect = 1; goto persistent_loop; } } if (rc == -1) set_error(gettext("error sending request to host")); else if (rc == RC_TIMEOUT) set_error(gettext("timeout sending to host")); else if (rc == RC_INVAL) set_error(gettext("retrieved invalid data from host")); else if (rc == RC_CTRLC) {/* ^C */} else if (rc == 0) set_error(gettext("connection prematurely closed by peer")); emit_error(verbose, curncount, dstart); stats_close(&fd, &t_close, 1); err++; break; } #if defined(linux) || defined(__FreeBSD__) #if HAVE_NCURSES if (!use_ssl && ncurses_mode) { struct timeval tv; int t_rc = -1; fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = (long)(timeout / 1000.0) % 1000000; tv.tv_usec = (long)(timeout * 1000.0) % 1000000; t_rc = select(fd + 1, &rfds, NULL, NULL, &tv); #ifdef linux if (t_rc == 1 && \ FD_ISSET(fd, &rfds) && \ getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &info_len) == 0 && \ info.tcpi_unacked > 0) { static int in_transit_cnt = 0; in_transit_cnt++; if (in_transit_cnt == MAX_SHOW_SUPPRESSION + 1) slow_log(gettext("\nNo longer emitting message about \"still data in transit\"")); else if (in_transit_cnt <= MAX_SHOW_SUPPRESSION) slow_log(gettext("\nHTTP server started sending data with %d bytes still in transit"), info.tcpi_unacked); } #endif if (t_rc == 0) { stats_close(&fd, &t_close, 1); rc = RC_TIMEOUT; set_error(gettext("timeout sending to host")); emit_error(verbose, curncount, dstart); err++; break; } } #endif if (getsockopt(fd, IPPROTO_IP, IP_TOS, &recv_tos, &recv_tos_len) == -1) { set_error(gettext("failed to obtain TOS info")); recv_tos = -1; } #endif rc = get_HTTP_headers(fd, ssl_h, &reply, &overflow, timeout); #if HAVE_NCURSES if (ncurses_mode && !get_instead_of_head && overflow > 0) { static int more_data_cnt = 0; more_data_cnt++; if (more_data_cnt == MAX_SHOW_SUPPRESSION + 1) slow_log(gettext("\nNo longer emitting message about \"more data than response headers\"")); else if (more_data_cnt <= MAX_SHOW_SUPPRESSION) slow_log(gettext("\nHTTP server sent more data than just the response headers")); } #endif emit_headers(reply); if (reply) { free_cookies(dynamic_cookies, n_dynamic_cookies); dynamic_cookies = NULL; n_dynamic_cookies = 0; get_cookies(reply, &dynamic_cookies, &n_dynamic_cookies, &static_cookies, &n_static_cookies); } if ((show_statuscodes || machine_readable || json_output || ncurses_mode) && reply != NULL) { /* statuscode is in first line behind * 'HTTP/1.x' */ char *dummy = strchr(reply, ' '); if (dummy) { sc = strdup(dummy + 1); /* lines are normally terminated with a * CR/LF */ dummy = strchr(sc, '\r'); if (dummy) *dummy = 0x00; dummy = strchr(sc, '\n'); if (dummy) *dummy = 0x00; } } their_ts = parse_date_from_response_headers(reply); age = calc_page_age(reply, their_ts); is_compressed = check_compressed(reply); if (persistent_connections && show_bytes_xfer && reply != NULL) { char *length = strstr(reply, "\nContent-Length:"); if (!length) { set_error(gettext("'Content-Length'-header missing!")); emit_error(verbose, curncount, dstart); stats_close(&fd, &t_close, 1); break; } len = atoi(&length[17]); } if (http2 && get_instead_of_head) { printf("%s\n", reply); printf("%s\n", request); if (strncmp(reply, "HTTP/1.1 101", 12) != 0) printf("Server did not want to switch protocols\n"); else if (strcasestr(reply, "Connection: Upgrade") == NULL) printf("Server did not want to upgrade connection\n"); else if (strcasestr(reply, "Upgrade: h2c") == NULL) printf("Server did not want to upgrade connection to HTTP/2\n"); } headers_len = 0; if (reply) { headers_len = strlen(reply) + 4 - overflow; free(reply); reply = NULL; } update_statst(&stats_header_size, headers_len); if (rc < 0) { if (persistent_connections) { if (++persistent_tries < 2) { stats_close(&fd, &t_close, 0); persistent_did_reconnect = 1; goto persistent_loop; } } if (rc == RC_SHORTREAD) set_error(gettext("short read during receiving reply-headers from host")); else if (rc == RC_TIMEOUT) set_error(gettext("timeout while receiving reply-headers from host")); emit_error(verbose, curncount, dstart); stats_close(&fd, &t_close, 1); err++; break; } ok++; if (get_instead_of_head && show_Bps) { int buffer_size = RECV_BUFFER_SIZE; char *buffer = (char *)malloc(buffer_size); double dl_start = get_ts(), dl_end; double cur_limit = Bps_limit; if (persistent_connections) { if (cur_limit == -1 || len < cur_limit) cur_limit = len - overflow; } for(;;) { int n = cur_limit != -1 ? min(cur_limit - bytes_transferred, buffer_size) : buffer_size; int rc = read(fd, buffer, n); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) error_exit(gettext("read of response body dataa failed")); } else if (rc == 0) { break; } bytes_transferred += rc; if (cur_limit != -1 && bytes_transferred >= cur_limit) break; } free(buffer); dl_end = get_ts(); Bps = (double)bytes_transferred / max(dl_end - dl_start, 0.000001); bps.Bps_min = min(bps.Bps_min, Bps); bps.Bps_max = max(bps.Bps_max, Bps); bps.Bps_avg += Bps; } dend = get_ts(); #ifndef NO_SSL if (use_ssl) { if ((show_fp || json_output || ncurses_mode) && ssl_h != NULL) fp = get_fingerprint(ssl_h); if (!persistent_connections) { if (close_ssl_connection(ssl_h) == -1) { set_error(gettext("error shutting down ssl")); emit_error(verbose, curncount, dstart); } SSL_free(ssl_h); ssl_h = NULL; s_bio = NULL; } } #endif #if defined(linux) || defined(__FreeBSD__) if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &info_len) == 0) { #ifdef TCPI_OPT_SYN_DATA if (info.tcpi_options & TCPI_OPT_SYN_DATA) tfo_success = 1; #endif update_statst(&tcp_rtt_stats, (double)info.tcpi_rtt / 1000.0); #ifdef linux re_tx = info.tcpi_retransmits; pmtu = info.tcpi_pmtu; #endif } #endif if (!persistent_connections) stats_close(&fd, &t_close, 0); dummy_ms = (dend - dafter_write_complete) * 1000.0; update_statst(&t_request, dummy_ms); dummy_ms = (dend - dstart) * 1000.0; update_statst(&t_total, dummy_ms); their_est_ts = (dend + dafter_connect) / 2.0; /* estimate of when other end started replying */ toff_diff_ts = ((double)their_ts - their_est_ts) * 1000.0; update_statst(&stats_to, toff_diff_ts); if (json_output) { char current_host[4096] = { 0 }; if (proxy_host) snprintf(current_host, sizeof current_host, "%s", hostname); else if (getnameinfo((const struct sockaddr *)&addr, sizeof addr, current_host, sizeof current_host, NULL, 0, NI_NUMERICHOST) == -1) snprintf(current_host, sizeof current_host, gettext("getnameinfo() failed: %d (%s)"), errno, strerror(errno)); emit_json(1, curncount, dstart, &t_resolve, &t_connect, &t_request, atoi(sc ? sc : "-1"), sc ? sc : "?", headers_len, len, Bps, current_host, fp, toff_diff_ts, tfo_success, &t_ssl, &t_write, &t_close, n_dynamic_cookies, &stats_to, &tcp_rtt_stats, re_tx, pmtu, recv_tos, &t_total); } else if (machine_readable) { if (sc) { char *dummy = strchr(sc, ' '); if (dummy) *dummy = 0x00; if (strstr(ok_str, sc)) printf("%f", t_total.cur); else printf("%s", err_str); if (show_statuscodes) printf(" %s", sc); } else { printf("%s", err_str); } if(audible) putchar('\a'); printf("\n"); } else if (!quiet && !nagios_mode && t_total.cur >= offset_show) { char *tot_str = NULL; const char *i6_bs = "", *i6_be = ""; char *line = NULL; const char *ms_color = c_green; char current_host[4096] = { 0 }; char *operation = !persistent_connections ? gettext("connected to") : gettext("pinged host"); const char *sep = c_bright, *unsep = c_normal; if (show_ts || ncurses_mode) { char *ts = get_ts_str(verbose); if (ncurses_mode) str_add(&line, "[%s] ", ts); else str_add(&line, "%s ", ts); free(ts); } if (curncount & 1) { str_add(&line, "%s", c_bright); sep = c_normal; unsep = c_bright; } if (proxy_host) snprintf(current_host, sizeof current_host, "%s", hostname); else if (getnameinfo((const struct sockaddr *)&addr, sizeof addr, current_host, sizeof current_host, NULL, 0, NI_NUMERICHOST) == -1) snprintf(current_host, sizeof current_host, gettext("getnameinfo() failed: %d (%s)"), errno, strerror(errno)); if (addr.sin6_family == AF_INET6) { i6_bs = "["; i6_be = "]"; } if (offset_red > 0.0 && t_total.cur >= offset_red) ms_color = c_red; else if (offset_yellow > 0.0 && t_total.cur >= offset_yellow) ms_color = c_yellow; if (!ncurses_mode) str_add(&line, "%s%s ", c_white, operation); if (persistent_connections && show_bytes_xfer) str_add(&line, gettext("%s%s%s%s%s:%s%d%s (%d/%d bytes), seq=%s%d%s "), c_red, i6_bs, current_host, i6_be, c_white, c_yellow, portnr, c_white, headers_len, len, c_blue, curncount-1, c_white); else str_add(&line, gettext("%s%s%s%s%s:%s%d%s (%d bytes), seq=%s%d%s "), c_red, i6_bs, current_host, i6_be, c_white, c_yellow, portnr, c_white, headers_len, c_blue, curncount-1, c_white); tot_str = format_value(t_total.cur, 6, 2, abbreviate); if (split) { char *res_str = t_resolve.cur_valid ? format_value(t_resolve.cur, 6, 2, abbreviate) : strdup(gettext(" n/a")); char *con_str = t_connect.cur_valid ? format_value(t_connect.cur, 6, 2, abbreviate) : strdup(gettext(" n/a")); char *wri_str = format_value(t_write.cur, 6, 2, abbreviate); char *req_str = format_value(t_request.cur, 6, 2, abbreviate); char *clo_str = format_value(t_close.cur, 6, 2, abbreviate); str_add(&line, gettext("time=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s"), res_str, con_str, wri_str, req_str, clo_str, sep, unsep, ms_color, tot_str, c_white, c_cyan, sc?sc:"", c_white); free(clo_str); free(req_str); free(wri_str); free(con_str); free(res_str); } else { str_add(&line, gettext("time=%s%s%s ms %s%s%s"), ms_color, tot_str, c_white, c_cyan, sc?sc:"", c_white); } free(tot_str); if (persistent_did_reconnect) { str_add(&line, " %sC%s", c_magenta, c_white); persistent_did_reconnect = 0; } if (show_Bps) { str_add(&line, " %dKB/s", (int)Bps / 1024); if (show_bytes_xfer) str_add(&line, " %dKB", (int)(bytes_transferred / 1024)); if (ask_compression) { str_add(&line, " ("); if (!is_compressed) str_add(&line, gettext("not ")); str_add(&line, gettext("compressed)")); } } if (use_ssl && show_fp && fp != NULL) { str_add(&line, " %s", fp); } if (verbose > 0 && their_ts > 0) { /* if diff_ts > 0, then their clock is running too fast */ str_add(&line, gettext(" toff=%d"), (int)toff_diff_ts); } if (verbose > 0 && age > 0) str_add(&line, gettext(" age=%d"), age); str_add(&line, "%s", c_normal); if (audible) { #if HAVE_NCURSES my_beep(); #else putchar('\a'); #endif } if (tfo_success) str_add(&line, " F"); #if HAVE_NCURSES if (ncurses_mode) { if (dummy_ms >= show_slow_log) slow_log("\n%s", line); else fast_log("\n%s", line); } else #endif { printf("%s\n", line); } do_aggregates(t_total.cur, (int)(get_ts() - started_at), n_aggregates, aggregates, verbose, show_ts); free(line); } if (show_statuscodes && ok_str != NULL && sc != NULL) { scdummy = strchr(sc, ' '); if (scdummy) *scdummy = 0x00; if (strstr(ok_str, sc) == NULL) { ok--; err++; } } if (got_sigquit && !quiet && !machine_readable && !nagios_mode && !json_output) { got_sigquit = 0; stats_line(0, complete_url, count, curncount, err, ok, started_at, verbose, &t_total, avg_httping_time, show_Bps ? &bps : NULL); } break; } emit_statuslines(get_ts() - started_at); #if HAVE_NCURSES if (ncurses_mode) update_stats(&t_resolve, &t_connect, &t_request, &t_total, &t_ssl, curncount, err, sc, fp, use_tfo, nc_graph, &stats_to, &tcp_rtt_stats, re_tx, pmtu, recv_tos, &t_close, &t_write, n_dynamic_cookies, abbreviate, &stats_header_size); #endif free(sc); free(fp); #if HAVE_NCURSES if (ncurses_mode) update_terminal(); else #endif fflush(NULL); if (!stop && wait > 0) { double cur_sleep = wait; if (adaptive_interval) { double now = get_ts(); double interval_left = fmod(now - started_at, wait); if (interval_left <= 0.0) cur_sleep = wait; else cur_sleep = wait - interval_left; } myusleep((useconds_t)(cur_sleep * 1000000.0)); } reset_statst_cur(&t_resolve); reset_statst_cur(&t_connect); reset_statst_cur(&t_ssl); reset_statst_cur(&t_write); reset_statst_cur(&t_request); reset_statst_cur(&t_close); reset_statst_cur(&t_total); reset_statst_cur(&stats_to); #if defined(linux) || defined(__FreeBSD__) reset_statst_cur(&tcp_rtt_stats); #endif } #if HAVE_NCURSES if (ncurses_mode) end_ncurses(); #endif if (colors) set_colors(0); if (ok) avg_httping_time = t_total.avg / (double)t_total.n; else avg_httping_time = -1.0; if (!quiet && !machine_readable && !nagios_mode && !json_output) stats_line(1, complete_url, count, curncount, err, ok, started_at, verbose, &t_total, avg_httping_time, show_Bps ? &bps : NULL); error_exit: if (nagios_mode) return nagios_result(ok, nagios_mode, nagios_exit_code, avg_httping_time, nagios_warn, nagios_crit); if (!json_output && !machine_readable) printf("%s", c_very_normal); if (json_output) printf("\n]\n"); free_cookies(static_cookies, n_static_cookies); free_cookies(dynamic_cookies, n_dynamic_cookies); freeaddrinfo(ai); free(request); free(get); free(hostname); free(complete_url); free_headers(additional_headers, n_additional_headers); free(aggregates); #ifndef NO_SSL if (use_ssl) { SSL_CTX_free(client_ctx); shutdown_ssl(); } #endif fflush(NULL); uninit_statst(&t_resolve); uninit_statst(&t_connect); uninit_statst(&t_write); uninit_statst(&t_request); uninit_statst(&t_total); uninit_statst(&t_ssl); uninit_statst(&t_close); uninit_statst(&stats_to); #if defined(linux) || defined(__FreeBSD__) uninit_statst(&tcp_rtt_stats); #endif uninit_statst(&stats_header_size); if (ok) return 0; return 127; } HTTPing-4.4.0/main.h000066400000000000000000000002431475432366700141110ustar00rootroot00000000000000extern volatile int stop; extern volatile char got_sigquit; extern int max_x, max_y; void determine_terminal_size(int *max_y, int *max_x); void handler(int sig); HTTPing-4.4.0/mssl.c000066400000000000000000000220571475432366700141450ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include "config.h" #ifndef NO_SSL #include #include "gen.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "gen.h" #include "mssl.h" #include "tcp.h" #include "io.h" #include "http.h" #include "utils.h" #include "main.h" BIO *bio_err = NULL; void shutdown_ssl(void) { BIO_free(bio_err); ERR_free_strings(); CONF_modules_free(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); } int close_ssl_connection(SSL *const ssl_h) { int rc = SSL_shutdown(ssl_h); if (!rc) rc = SSL_shutdown(ssl_h); /* ignoring failures: the socket will be closed anyway later on so any openssl failures won't do any harm if (rc == -1) { fprintf(stderr, "SSL_shutdown failed: %s\n", strerror(errno)); return -1; } */ return 0; } int READ_SSL(SSL *const ssl_h, char *whereto, int len, const double timeout) { const int cnt = len; const int fd = SSL_get_rfd(ssl_h); double end = get_ts() + timeout; while(len > 0 && !got_sigquit) { int rc = -1; fd_set rfds, wfds; struct timeval tv; double now = get_ts(), left = end - now; if (left <= 0.0) { set_error(gettext("Time-out on SSL connection")); return -1; } FD_ZERO(&rfds); FD_SET(fd, &rfds); FD_ZERO(&wfds); /* yes, see openssl */ FD_SET(fd, &wfds); tv.tv_sec = left; tv.tv_usec = (left - tv.tv_sec) * 1000000; rc = select(fd + 1, &rfds, &wfds, NULL, &tv); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("READ_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) { set_error(gettext("Time-out on SSL connection (READ)")); return -1; } rc = SSL_read(ssl_h, whereto, len); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("READ_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) return 0; whereto += rc; len -= rc; } return cnt; } int WRITE_SSL(SSL *const ssl_h, const char *wherefrom, int len, const double timeout) { const int cnt = len; const int fd = SSL_get_wfd(ssl_h); double end = get_ts() + timeout; while(len > 0 && !got_sigquit) { int rc = -1; fd_set rfds, wfds; struct timeval tv; double now = get_ts(), left = end - now; if (left <= 0.0) { set_error(gettext("Time-out on SSL connection")); return -1; } FD_ZERO(&rfds); /* yes, that's correct */ FD_SET(fd, &rfds); FD_ZERO(&wfds); FD_SET(fd, &wfds); tv.tv_sec = left; tv.tv_usec = (left - tv.tv_sec) * 1000000; rc = select(fd + 1, &rfds, &wfds, NULL, &tv); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("WRITE_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) { set_error(gettext("Time-out on SSL connection (write)")); return -1; } rc = SSL_write(ssl_h, wherefrom, len); if (rc == -1) { if (errno != EINTR && errno != EAGAIN) set_error(gettext("WRITE_SSL: io-error: %s"), strerror(errno)); return -1; } if (rc == 0) return 0; wherefrom += rc; len -= rc; } return cnt; } int connect_ssl(const int fd, SSL_CTX *const client_ctx, SSL **const ssl_h, BIO **const s_bio, const double timeout, double *const ssl_handshake, char *const hostname, const char ignore_ssl_errors) { double dstart = get_ts(); double end = get_ts() + timeout; struct timeval tv; tv.tv_sec = (long)(timeout / 1000.0); tv.tv_usec = (long)(timeout * 1000.0) % 1000000; *ssl_handshake = -1.0; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) == -1) { set_error(gettext("problem setting receive timeout (%s)"), strerror(errno)); return -1; } if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) == -1) { set_error(gettext("problem setting transmit timeout (%s)"), strerror(errno)); return -1; } *ssl_h = SSL_new(client_ctx); SSL_set_tlsext_host_name(*ssl_h, hostname); X509_VERIFY_PARAM *param = SSL_get0_param(*ssl_h); X509_VERIFY_PARAM_set1_host(param, hostname, 0); *s_bio = BIO_new_socket(fd, BIO_NOCLOSE); SSL_set_bio(*ssl_h, *s_bio, *s_bio); if (set_fd_nonblocking(fd) == -1) return RC_INVAL; do { int rc = SSL_connect(*ssl_h); if (rc <= 0) { int err = SSL_get_error(*ssl_h, rc); if (err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { struct timeval tv; fd_set fds; double left = end - get_ts(); if (left <= 0) { set_error(gettext("Time-out during SSL handshake")); return -1; } tv.tv_sec = left; tv.tv_usec = (left - tv.tv_sec) * 1000000; FD_ZERO(&fds); FD_SET(fd, &fds); if (err == SSL_ERROR_WANT_READ) rc = select(fd + 1, &fds, NULL, NULL, &tv); else rc = select(fd + 1, NULL, &fds, NULL, &tv); } else { set_error(gettext("SSL handshake error: %s"), ERR_reason_error_string(ERR_get_error())); return -1; } } } while (!SSL_is_init_finished(*ssl_h) && !got_sigquit); X509 *cert = SSL_get_peer_certificate(*ssl_h); if (cert) X509_free(cert); else set_error(gettext("SSL no peer certificate")); long v = SSL_get_verify_result(*ssl_h); if (v != X509_V_OK && ignore_ssl_errors == 0) set_error(gettext("SSL certificate validation failed: %s"), X509_verify_cert_error_string(v)); if (got_sigquit) return -1; *ssl_handshake = get_ts() - dstart; if (set_fd_blocking(fd) == -1) return -1; return 0; } SSL_CTX * initialize_ctx(const char ask_compression, const char *ca_path) { const SSL_METHOD *meth = NULL; SSL_CTX *ctx = NULL; if (!bio_err) { SSL_library_init(); SSL_load_error_strings(); ERR_load_crypto_strings(); /* error write context */ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); } /* create context */ meth = SSLv23_method(); ctx = SSL_CTX_new(meth); if (ca_path == NULL) #if defined(__NetBSD__) ca_path = "/etc/openssl/certs"; #else ca_path = "/etc/ssl/certs"; #endif SSL_CTX_load_verify_locations(ctx, NULL, ca_path); #ifdef SSL_OP_NO_COMPRESSION if (!ask_compression) SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); #endif return ctx; } char * get_fingerprint(SSL *const ssl_h) { char *string = NULL; unsigned char fp_digest[EVP_MAX_MD_SIZE]; X509 *x509_data = SSL_get_peer_certificate(ssl_h); if (x509_data) { unsigned int fp_digest_size = sizeof fp_digest; memset(fp_digest, 0x00, fp_digest_size); if (X509_digest(x509_data, EVP_md5(), fp_digest, &fp_digest_size)) { string = (char *)malloc(MD5_DIGEST_LENGTH * 3 + 1); if (string) { int loop, pos =0; for(loop=0; loop #include #include #include void shutdown_ssl(void); int close_ssl_connection(SSL *const ssl_h); int READ_SSL(SSL *const ssl_h, char *whereto, int len, const double timeout); int WRITE_SSL(SSL *const ssl_h, const char *whereto, int len, const double timeout); int connect_ssl(const int fd, SSL_CTX *const client_ctx, SSL **const ssl_h, BIO **const s_bio, const double timeout, double *const ssl_handshake, char *const hostname, const char ignore_ssl_errors); SSL_CTX * initialize_ctx(const char ask_compression, const char *ca_path); char * get_fingerprint(SSL *const ssl_h); int connect_ssl_proxy(const int fd, struct addrinfo *const ai, const double timeout, const char *const proxy_user, const char *const proxy_password, const char *const hostname, const int portnr, char *const tfo); HTTPing-4.4.0/nc.c000066400000000000000000000445331475432366700135720ustar00rootroot00000000000000#include "config.h" #if HAVE_NCURSES #define _GNU_SOURCE #include #include "gen.h" #include #include #include #include #include #include #include #include #include #include "error.h" #include "colors.h" #include "gen.h" #include "main.h" #include "kalman.h" #if HAVE_FFTW3 #include "fft.h" #endif #include "utils.h" char win_resize = 0; WINDOW *w_stats = NULL, *w_line1 = NULL, *w_slow = NULL, *w_line2 = NULL, *w_fast = NULL; int stats_h = 10; int logs_n = 0, slow_n = 0, fast_n = 0; char **slow_history = NULL, **fast_history = NULL; int window_history_n = 0; char use_colors = 0; int fast_nr = 0; double graph_limit = MY_DOUBLE_INF; double hz = 1.0; double *history = NULL, *history_temp = NULL, *history_fft_magn = NULL, *history_fft_phase = NULL; char *history_set = NULL; int history_n = 0; char draw_phase = 0; char fancy_colors = 0; char pause_graphs = 0; typedef enum { C_WHITE = 0, C_GREEN, C_YELLOW, C_BLUE, C_MAGENTA, C_CYAN, C_RED } color_t; void update_terminal(void) { wnoutrefresh(w_stats); wnoutrefresh(w_slow); wnoutrefresh(w_fast); doupdate(); } void create_windows(void) { char *r_a = gettext("realloc issue"); int nr = 0; if (w_stats) { delwin(w_stats); delwin(w_line1); delwin(w_slow); delwin(w_line2); delwin(w_fast); } #if HAVE_FFTW3 fft_free(); fft_init(max_x); #endif if (max_x > history_n) { history = (double *)realloc(history, sizeof(double) * max_x); if (!history) error_exit(r_a); history_temp = (double *)realloc(history_temp, sizeof(double) * max_x); if (!history_temp) error_exit(r_a); /* halve of it is enough really */ history_fft_magn = (double *)realloc(history_fft_magn, sizeof(double) * max_x); if (!history_fft_magn) error_exit(r_a); history_fft_phase = (double *)realloc(history_fft_phase, sizeof(double) * max_x); if (!history_fft_phase) error_exit(r_a); history_set = (char *)realloc(history_set, sizeof(char) * max_x); if (!history_set) error_exit(r_a); memset(&history[history_n], 0x00, (max_x - history_n) * sizeof(double)); memset(&history_set[history_n], 0x00, (max_x - history_n) * sizeof(char)); history_n = max_x; } if ((int)max_y > window_history_n) { slow_history = (char **)realloc(slow_history, sizeof(char *) * max_y); if (!slow_history) error_exit(r_a); fast_history = (char **)realloc(fast_history, sizeof(char *) * max_y); if (!fast_history) error_exit(r_a); memset(&slow_history[window_history_n], 0x00, (max_y - window_history_n) * sizeof(char *)); memset(&fast_history[window_history_n], 0x00, (max_y - window_history_n) * sizeof(char *)); window_history_n = max_y; } w_stats = newwin(stats_h, max_x, 0, 0); scrollok(w_stats, false); w_line1 = newwin(1, max_x, stats_h, 0); scrollok(w_line1, false); wnoutrefresh(w_line1); logs_n = max_y - (stats_h + 1 + 1); fast_n = logs_n * 11 / 20; slow_n = logs_n - fast_n; w_slow = newwin(slow_n, max_x, (stats_h + 1), 0); scrollok(w_slow, true); w_line2 = newwin(1, max_x, (stats_h + 1) + slow_n, 0); scrollok(w_line2, false); wnoutrefresh(w_line2); w_fast = newwin(fast_n, max_x, (stats_h + 1) + slow_n + 1, 0); scrollok(w_fast, true); wattron(w_line1, A_REVERSE); wattron(w_line2, A_REVERSE); for(nr=0; nr= 0; index--) { if (slow_history[index]) myprint(w_slow, slow_history[index]); if (fast_history[index]) myprint(w_fast, fast_history[index]); } doupdate(); win_resize = 0; } void init_ncurses_ui(double graph_limit_in, double hz_in, char use_colors_in) { graph_limit = graph_limit_in; hz = hz_in; use_colors = use_colors_in; initscr(); start_color(); keypad(stdscr, TRUE); intrflush(stdscr, FALSE); noecho(); refresh(); nodelay(stdscr, FALSE); meta(stdscr, TRUE); /* enable 8-bit input */ idlok(stdscr, TRUE); /* may give a little clunky screenredraw */ idcok(stdscr, TRUE); /* may give a little clunky screenredraw */ leaveok(stdscr, FALSE); init_pair(C_WHITE, COLOR_WHITE, COLOR_BLACK); init_pair(C_CYAN, COLOR_CYAN, COLOR_BLACK); init_pair(C_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); init_pair(C_BLUE, COLOR_BLUE, COLOR_BLACK); init_pair(C_YELLOW, COLOR_YELLOW, COLOR_BLACK); init_pair(C_GREEN, COLOR_GREEN, COLOR_BLACK); init_pair(C_RED, COLOR_RED, COLOR_BLACK); fancy_colors = COLORS >= 256 && COLOR_PAIRS >= 256 && can_change_color(); kalman_init(0.0); recreate_terminal(); } void end_ncurses(void) { int index = 0; for(index=0; index= end_y; y--) mvwchgat(win, y, x, 1, A_REVERSE, C_YELLOW, dummy); if (limitter) mvwchgat(win, 0, x, 1, A_REVERSE, C_BLUE, dummy); else if (overflow) mvwchgat(win, 0, x, 1, A_REVERSE, C_RED, dummy); else if (height == 0) mvwchgat(win, win_h - 1, x, 1, A_REVERSE, C_GREEN, dummy); } void draw_rad_column(WINDOW *win, int x, double val) { void *dummy = NULL; int y = 0, end_y = 0, win_h = 0, win_w = 0; int center_y = 0; getmaxyx(win, win_h, win_w); (void)win_w; /* silence warnings */ center_y = win_h / 2; end_y = (int)((double)(win_h / 2) * ((val / PI) + 1.0)); if (end_y > center_y) { for(y=center_y; y 0 ? history[index - 1] : 0; if (val > graph_limit) val = graph_limit; history_temp[index] = val; } fft_do(history_temp, history_fft_magn, history_fft_phase); for(index=1; index mx_mag) { mx_mag = history_fft_magn[index]; highest = index; } } highest_freq = (hz / (double)max_x) * (double)highest; avg_freq_index /= total_val; avg_freq = (hz / (double)max_x) * avg_freq_index; wattron(w_line1, A_REVERSE); myprintloc(w_line1, 0, 38, gettext("highest: %6.2fHz, avg: %6.2fHz"), highest_freq, avg_freq); wattroff(w_line1, A_REVERSE); wnoutrefresh(w_line1); dummy = max_x / 2 + 1; if (draw_phase) { int y = 0; for(y=0; y ma) continue; avg2 += val; sd2 += val * val; n2++; } if (n2) { avg2 /= (double)n2; sd2 = sqrt((sd2 / (double)n2) - pow(avg2, 2.0)); mi = max(mi, avg2 - sd2); ma = min(ma, avg2 + sd2); diff = ma - mi; if (diff == 0.0) diff = 1.0; wattron(w_line1, A_REVERSE); myprintloc(w_line1, 0, 0, gettext("graph range: %7.2fms - %7.2fms "), mi, ma); wattroff(w_line1, A_REVERSE); wnoutrefresh(w_line1); /* fprintf(stderr, "%d| %f %f %f %f\n", h_stats.n, mi, avg, ma, sd); */ for(index=0; index 1.0) { height = 1.0; overflow = 1; } i_h = (int)(height * stats_h); /* fprintf(stderr, "%d %f %f %d %d\n", index, history[index], height, i_h, overflow); */ draw_column(w_stats, x, i_h, overflow, limitter); } } } void show_stats_t(int y, int x, char *header, stats_t *data, char abbreviate) { if (y & 1) wattron(w_stats, A_DIM); if (data -> valid) { char *cur_str = format_value(data -> cur, 6, 2, abbreviate); char *min_str = format_value(data -> min, 6, 2, abbreviate); char *avg_str = format_value(data -> avg / (double)data -> n, 6, 2, abbreviate); char *max_str = format_value(data -> max, 6, 2, abbreviate); char *sd_str = format_value(calc_sd(data), 6, 2, abbreviate); myprintloc(w_stats, y, x, "%s: %s %s %s %s %s", header, data -> cur_valid ? cur_str : gettext(" n/a"), min_str, avg_str, max_str, sd_str); free(sd_str); free(max_str); free(avg_str); free(min_str); free(cur_str); } else { myprintloc(w_stats, y, x, gettext("%s: n/a"), header); } if (y & 1) wattroff(w_stats, A_DIM); } void update_stats(stats_t *resolve, stats_t *connect, stats_t *request, stats_t *total, stats_t *ssl_setup, int n_ok, int n_fail, const char *last_connect_str, const char *fp, char use_tfo, char dg, stats_t *st_to, stats_t *tcp_rtt_stats, int re_tx, int pmtu, int tos, stats_t *close_st, stats_t *t_write, int n_cookies, char abbreviate, stats_t *stats_header_size) { double k = 0.0; char force_redraw = 0; struct pollfd p = { 0, POLLIN, 0 }; werase(w_stats); if (n_ok) { char buffer[4096] = { 0 }, *scc_str = NULL, *kalman_str = NULL; int buflen = 0; myprintloc(w_stats, 0, 0, " %6s %6s %6s %6s %6s", gettext("latest"), gettext("min"), gettext("avg"), gettext("max"), gettext("sd")); show_stats_t(1, 0, gettext("resolve"), resolve, abbreviate); show_stats_t(2, 0, gettext("connect"), connect, abbreviate); show_stats_t(3, 0, gettext("ssl "), ssl_setup, abbreviate); show_stats_t(4, 0, gettext("send "), t_write, abbreviate); show_stats_t(5, 0, gettext("request"), request, abbreviate); show_stats_t(6, 0, gettext("close "), close_st, abbreviate); show_stats_t(7, 0, gettext("total "), total, abbreviate); scc_str = format_value(get_cur_scc(), 5, 3, abbreviate); kalman_str = format_value(kalman_do(total -> cur), 5, 3, abbreviate); myprintloc(w_stats, 8, 0, gettext("ok: %3d, fail: %3d%s, scc: %s, kalman: %s"), n_ok, n_fail, use_tfo ? gettext(", with TFO") : "", scc_str, kalman_str); free(kalman_str); free(scc_str); if (max_x >= 44 * 2 + 1) { double trend = calc_trend(); char trend_dir = ' '; myprintloc(w_stats, 0, 45, " %6s %6s %6s %6s %6s", gettext("cur"), gettext("min"), gettext("avg"), gettext("max"), gettext("sd")); show_stats_t(1, 45, gettext("t offst"), st_to, abbreviate); #if defined(linux) || defined(__FreeBSD__) show_stats_t(2, 45, gettext("tcp rtt"), tcp_rtt_stats, abbreviate); #endif show_stats_t(3, 45, gettext("headers"), stats_header_size, abbreviate); if (trend < 0) trend_dir = '-'; else if (trend > 0) trend_dir = '+'; myprintloc(w_stats, 8, 48, gettext("# cookies: %d"), n_cookies); #ifdef linux myprintloc(w_stats, 9, 48, gettext("trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x"), trend_dir, fabs(trend), re_tx, pmtu, tos); #else myprintloc(w_stats, 9, 48, gettext("trend: %c%6.2f%%, TOS: %02x"), trend_dir, fabs(trend), tos); #endif } buflen = snprintf(buffer, sizeof buffer, gettext("HTTP rc: %s, SSL fp: %s"), last_connect_str, fp ? fp : gettext("n/a")); if (buflen <= max_x) myprintloc(w_stats, 9, 0, "%s", buffer); else { static char prev_sf[48] = { 0 }; myprintloc(w_stats, 9, 0, gettext("http result code: %s"), last_connect_str); if (fp && strcmp(prev_sf, fp)) { slow_log(gettext("\nSSL fingerprint: %s"), fp); memcpy(prev_sf, fp, 47); } } } memmove(&history[1], &history[0], (history_n - 1) * sizeof(double)); memmove(&history_set[1], &history_set[0], (history_n - 1) * sizeof(char)); history[0]= total -> cur; history_set[0] = 1; if (poll(&p, 1, 0) == 1 && p.revents == POLLIN) { int c = getch(); if (c == 12) /* ^L */ force_redraw = 1; if (c == 'H') pause_graphs = !pause_graphs; if (c == 'q') stop = 1; } if (dg && !pause_graphs) { draw_graph(k); #if HAVE_FFTW3 draw_fft(); #endif } wnoutrefresh(w_stats); if (win_resize || force_redraw) recreate_terminal(); } #endif HTTPing-4.4.0/nc.h000066400000000000000000000012661475432366700135730ustar00rootroot00000000000000#include extern char win_resize; extern char draw_phase; void init_ncurses_ui(double graph_limit_in, double hz_in, char use_colors); void end_ncurses(void); void fast_log(const char *fmt, ...); void slow_log(const char *fmt, ...); void my_beep(void); void update_terminal(void); void status_line(char *fmt, ...); void update_stats(stats_t *resolve, stats_t *connect, stats_t *request, stats_t *total, stats_t *ssl_setup, int n_ok, int n_fail, const char *last_connect_str, const char *fp, char use_tfo, char dg, stats_t *st_to, stats_t *tcp_rtt_stats, int re_tx, int pmtu, int tos, stats_t *close_st, stats_t *t_write, int n_cookies, char abbreviate, stats_t *stats_header_size); HTTPing-4.4.0/plot-json.py000077500000000000000000000034621475432366700153240ustar00rootroot00000000000000#!/usr/bin/env python3 import json import math import os import stat import sys fin = sys.argv[1] print(f"Loading from {fin}") fh = open(fin) json_data = json.load(fh) print(f"Number of rows: {len(json_data)}") fdata = fin + ".dat" print(f"Writing data to {fdata}") data_fh = open(fdata, "w") host = "?" total = 0 total_sd = 0 n = 0 avg = 0 sd = 0 minp = 999999999 maxp = -minp for row in json_data: if row["status"] == "1": val = float(row["total_s"]) data_fh.write("%f %f\n" % (float(row["start_ts"]), val)) host = row["host"] total += val total_sd += val * val n += 1 if val > maxp: maxp = val if val < minp: minp = val print(f"Rows ignored: {len(json_data) - n}") data_fh.close() if n > 0: avg = total / n sd = math.sqrt((total_sd / n) - math.pow(avg, 2.0)) print(f"Average ping time: {avg}s ({n} pings)") print(f"Standard deviation: {sd}s") print(f"Minimum ping value: {minp}s") print(f"Maximum ping value: {maxp}s") fscript = fin + ".sh" print(f"Writing script to {fscript}") fpng = fin + ".png" with open(fscript, "w") as script_fh: script_fh.write("#! /bin/sh\n\n") script_fh.write("gnuplot < " + fpng + "\n") script_fh.write("set term png size 800,600 tiny\n") script_fh.write("set autoscale\n") script_fh.write('set timefmt "%s"\n') script_fh.write("set xdata time\n") script_fh.write('set format x "%H:%M:%S"\n') script_fh.write('plot "' + fdata + '" using 1:2 with lines title "' + host + '"\n') script_fh.write("EOF\n") os.chmod( fscript, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH, ) print(f"Now invoke {fscript} to generate {fpng}") HTTPing-4.4.0/po/000077500000000000000000000000001475432366700134335ustar00rootroot00000000000000HTTPing-4.4.0/po/CMakeLists.txt000066400000000000000000000011721475432366700161740ustar00rootroot00000000000000set(catalogname httping) file(GLOB PO_FILES *.po) foreach(_poFile ${PO_FILES}) get_filename_component(_poFileName ${_poFile} NAME) string(REGEX REPLACE "^${catalogname}_?" "" _langCode ${_poFileName}) string(REGEX REPLACE "\\.po$" "" _langCode ${_langCode}) if( _langCode ) get_filename_component(_lang ${_poFile} NAME_WE) set(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) gettext_process_po_files(${_langCode} ALL PO_FILES ${_poFile}) install( FILES ${_gmoFile} DESTINATION ${CMAKE_INSTALL_LOCALEDIR}/${_langCode}/LC_MESSAGES/ RENAME ${catalogname}.mo ) endif() endforeach() HTTPing-4.4.0/po/nl.po000066400000000000000000000733221475432366700144130ustar00rootroot00000000000000# Dutch translations for HTTPing package. # Copyright (C) 2016 folkert van heusden # This file is distributed under the same license as the HTTPing package. # folkert van heusden , 2016. # Translated by Joris Zwart - http://joriszwart.nl/ # msgid "" msgstr "" "Project-Id-Version: HTTPing\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-04 15:29+0200\n" "PO-Revision-Date: 2015-05-04 18:41+0100\n" "Last-Translator: Joris Zwart \n" "Language-Team: Dutch\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Dutch\n" "X-Poedit-Country: NETHERLANDS\n" #: error.c:23 #, c-format msgid "" "\n" "\n" "errno=%d which means %s (if applicable)\n" msgstr "" "\n" "\n" "errno=%d en dat betekent: %s (indien van toepassing)\n" #: error.c:39 #, c-format msgid "Error message '%s' truncated" msgstr "De foutmelding '%s' past niet in de buffer." #: fft.c:21 msgid "failed allocating memory for fft (1)" msgstr "Geheugentoewijzingsprobleem voor 'fft (1)'." #: fft.c:25 msgid "failed allocating memory for fft (2)" msgstr "Geheugentoewijzingsprobleem voor 'fft (2)'." #: fft.c:30 msgid "failed calculating plan for fft" msgstr "Probleem bij het voorbereiden van de FFT berekening." #: help.c:77 #, c-format msgid "HTTPing v" msgstr "HTTPing versie " msgid "adds an extra request-header" msgstr "voeg een extra verzoek-regel toe" #: help.c:79 #, c-format msgid " * SSL support included (-l)\n" msgstr " * Ondersteuning voor SSL (-l)\n" #: help.c:84 #, c-format msgid " * ncurses interface with FFT included (-K)\n" msgstr " * ncurses gebruikersinterface met fourier transformatie berekening (-K)\n" #: help.c:86 #, c-format msgid " * ncurses interface included (-K)\n" msgstr " * ncurses gebruikersinterface (-K)\n" #: help.c:91 #, c-format msgid " * TFO (TCP fast open) support included (-F)\n" msgstr " * Ondersteuning voor 'TFO (TCP fast open)' (-F)\n" #: help.c:93 #: help.c:293 #, c-format msgid "\n" msgstr "\n" #: help.c:176 #, c-format msgid " *** where to connect to ***\n" msgstr " *** adresspecificaties ***\n" #: help.c:177 msgid "URL to ping (e.g. -g http://localhost/)" msgstr "URL om te pingen (bijvoorbeeld -g http://localhost/)" #: help.c:178 msgid "hostname to ping (e.g. localhost) - use either -g or -h" msgstr "Systeemnaam om te pingen (bijvoorbeeld localhost). -g en -h kunnen niet gecombineerd worden" #: help.c:179 msgid "portnumber (e.g. 80) - use with -h" msgstr "poortnummer (bijv. 80), voor gebruik in combinatie met -h" #: help.c:180 msgid "use IPv6 when resolving/connecting" msgstr "gebruik IPv6 bij het omzetten van een systeemnaam en bij het maken van een verbinding" #: help.c:182 msgid "connect using SSL. pinging an https URL automatically enables this setting" msgstr "gebruik SSL encryptie. Wanneer men een https-URL kiest, dan zal deze optie automatisch ingeschakeld worden." #: help.c:187 #, c-format msgid " *** proxy settings ***\n" msgstr " *** proxy instellingen ***\n" #: help.c:188 msgid "x should be \"host:port\" which are the network settings of the http/https proxy server. ipv6 ip-address should be \"[ip:address]:port\"" msgstr "x moet zijn \"host:port\", dat zijn de parameters van de http/https proxyserver. ipv6 ip-adressen moeten opgebouwd zijn als volgt: \"[ip:adres]:port\"" #: help.c:189 msgid "fetch proxy settings from environment variables" msgstr "haal de proxy-instellingen uit de omgevingsvariabelen" #: help.c:190 msgid "username for authentication against proxy" msgstr "gebruikersnaam voor proxy-authenticatie" #: help.c:191 msgid "password for authentication against proxy" msgstr "toegangscode voor proxy-authenticatie" #: help.c:192 msgid "read password for proxy authentication from file x" msgstr "lees toegangscode voor proxy-authenticatie uit bestand x" #: help.c:193 msgid "proxy is a socks5 server" msgstr "de proxy is een socks5 systeem" #: help.c:194 msgid "adds \"&x=[random value]\" to the request URL" msgstr "voeg een \"&x=[willekeurig getal]\" aan de geselecteerde URL" #: help.c:198 #, c-format msgid " *** timing settings ***\n" msgstr " *** tijdsinstellingen ***\n" #: help.c:199 msgid "how many times to ping" msgstr "hoe vaak te pingen" #: help.c:200 msgid "delay between each ping" msgstr "pauze tussen iedere ping" #: help.c:201 msgid "timeout (default: 30s)" msgstr "hoelang te wachten op een server die niet reageert (standaard waarde: 30 seconden)" #: help.c:202 msgid "execute pings at multiples of interval relative to start, automatically enabled in ncurses output mode" msgstr "zorg ervoor dat pings steeds met dezelfde interval uitgevoerd worden, relatief tot het start tijdstip. deze instelling wordt automatisch aangezet in \"ncurses\"-mode" #: help.c:203 msgid "flood connect (no delays)" msgstr "geen vertraging tussen iedere ping" #: help.c:207 #, c-format msgid " *** HTTP settings ***\n" msgstr " *** HTTP-instellingen ***\n" #: help.c:208 msgid "ask any proxies on the way not to cache the requests" msgstr "vraag aan de proxy-sysstemen in de route tussen het lokale systeem en het bestemmingssysteem om de verzoeken niet te cachen" #: help.c:209 msgid "connect to a different host than in the URL given" msgstr "verbind en zend de URL-verzoeken naar een ander systeem dan wat in de URL is opgegeven" #: help.c:210 msgid "return the cookies given by the HTTP server in the following request(s)" msgstr "als de HTTP-server cookies geeft, zend die dan mee terug bij volgende pings" #: help.c:211 msgid "do not add \"Host:\"-line to the request headers" msgstr "voeg geen \"Host:\"-regel in het verbindingsverzoek" #: help.c:212 msgid "use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. usually possible when 'Connection: Keep-Alive' is sent by server. adds a 'C' to the output if httping had to reconnect" msgstr "gebruik een blijvende verbinding, dat wil zeggen hergebruiken dezelfde TCP-verbinding voor meerdere HTTP-verzoeken. meestal mogelijk wanneer 'Connection: Keep-Alive' is verzonden door de server. als het bestemmingssysteem de verbinding verbroken heeft, dan zal HTTPing een \"C\" toevoegen aan de uitvoer" #: help.c:213 msgid "use 'x' for the UserAgent header" msgstr "gebruik 'x' in de UserAgent verzoekinstellingen" #: help.c:214 msgid "use 'x' for the Referer header" msgstr "gebruik 'x' in de Referer verzoekinstellingen" #: help.c:218 #, c-format msgid " *** networking settings ***\n" msgstr " *** netwerk instellingen ***\n" #: help.c:219 msgid "limit the MTU size" msgstr "beperkt de MTU omvang" #: help.c:220 msgid "do not disable Naggle" msgstr "zet het Naggle-algorithme niet uit" #: help.c:221 msgid "receive buffer size" msgstr "ontvangst buffer omvang" #: help.c:222 msgid "transmit buffer size" msgstr "verzend buffer omvang" #: help.c:223 msgid "resolve hostname only once (useful when pinging roundrobin DNS: also takes the first DNS lookup out of the loop so that the first measurement is also correct)" msgstr "eenmalig systeemnaam vertalen (dit is zinvol bij het pingen van een roterende DNS, bovendien haalt het de eerste vertaling uit de ping lus zodat de 1e ping niet een bovengemiddelde tijd duurt)" #: help.c:224 msgid "do not abort the program if resolving failed: keep retrying" msgstr "breek het programma niet af als de systeemnaamvertaling mislukt is" #: help.c:225 msgid "bind to an ip-address (and thus interface) with an optional port" msgstr "stuur verzoeken via een specifieke netwerk adapter, eventueel zelfs vanaf een specifieke port" #: help.c:227 msgid "\"TCP fast open\" (TFO), reduces the latency of TCP connects" msgstr "\"TCP fast open\" (TFO), dit verlaagt de latency van opvolgende TCP verbindingen" #: help.c:229 msgid "set priority of packets" msgstr "zet prioriteit van pakketten" #: help.c:230 msgid "set TOS (type of service)" msgstr "zet de TOS (diensttype)" #: help.c:234 #, c-format msgid " *** HTTP authentication ***\n" msgstr " *** HTTP authenticatie ***\n" #: help.c:235 msgid "activate (\"basic\") authentication" msgstr "activeer (\"basic\")-authenticatie" #: help.c:236 msgid "username for authentication" msgstr "gebruikersnaam voor authenticatie" #: help.c:237 msgid "password for authentication" msgstr "toegangscode voor authenticatie" #: help.c:238 msgid "read the password fom the file 'x' (replacement for -P)" msgstr "lees de toegangscode uit bestand 'x'" #: help.c:242 #, c-format msgid " *** output settings ***\n" msgstr " *** uitvoerinstellingen ***\n" #: help.c:243 msgid "show statuscodes" msgstr "toon statuscodes" #: help.c:244 msgid "split measured time in its individual components (resolve, connect, send, etc." msgstr "toon alle individuele componenten (verbinden, zenden, etc) van de gemeten tijden" #: help.c:245 msgid "from what ping value to show the value in red (must be bigger than yellow), only in color mode (-Y)" msgstr "toon de waardes in rood vanaf welke gemeten tijden" #: help.c:246 msgid "from what ping value to show the value in yellow" msgstr "toon de waardes in 't geel vanaf welke gemeten tijden" #: help.c:247 msgid "from what ping value to show the results" msgstr "filter alle metingen die beneden deze waarde vallen" #: help.c:248 msgid "put a timestamp before the measured values, use -v to include the date and -vv to show in microseconds" msgstr "toon een tijdstempel voor iedere gemeten waarde. gebruik -v om ook de datum te zien en -vv om ook microseconden te zien" #: help.c:249 msgid "show an aggregate each x[/y[/z[/etc]]] seconds" msgstr "toon cumulatief de waardes van x[/y[/etc]] seconden" #: help.c:251 msgid "show fingerprint (SSL)" msgstr "toon een vingerafdruk voor de SSL-verbinding" #: help.c:253 msgid "verbose mode" msgstr "toon meer details" #: help.c:257 #, c-format msgid " *** \"GET\" (instead of HTTP \"HEAD\") settings ***\n" msgstr " *** \"GET\" (in plaats van HTTP \"HEAD\") instellingen ***\n" #: help.c:258 msgid "do a GET request instead of HEAD (read the contents of the page as well)" msgstr "doe een GET verzoek in plaats van een HEAD verzoek en haal ook de inhoud van een pagina op" #: help.c:259 msgid "show transfer speed in KB/s (use with -G)" msgstr "toon de verzendsnelheid in KB/s (gebruik in combinatie met -G)" #: help.c:260 msgid "like -b but use compression if available" msgstr "zoals -b maar gebruik compressie als het HTTP systeem dit ondersteunt" #: help.c:261 msgid "limit the amount of data transferred (for -b) to 'x' (in bytes)" msgstr "limiteer de hoeveelheid verzonden data (ism -b) tot 'x' bytes" #: help.c:262 msgid "show the number of KB transferred (for -b)" msgstr "toon de totaal verzonden hoeveelheid data (in KB, ism -b)" #: help.c:266 #, c-format msgid " *** output mode settings ***\n" msgstr " *** uitvoer modeinstellingen ***\n" #: help.c:267 msgid "quiet, only returncode" msgstr "toon niets, geef alleen een resultaatwaarde terug" #: help.c:268 msgid "give machine parseable output (see also -o and -e)" msgstr "toon resultaat in computervriendelijkformaat (zie ook -o en -e)" #: help.c:269 msgid "json output, cannot be combined with -m" msgstr "json uitvoer, kan niet met -m gecombineerd worden" #: help.c:270 msgid "what http results codes indicate 'ok' comma separated WITHOUT spaces inbetween default is 200, use with -e" msgstr "welke HTTP statuscodes als 'ok' te beschouwen. dit moet een met komma gescheiden lijst (geen spaties) zijn. de standaard waarde is 200. gebruik deze instelling ism -e" #: help.c:271 msgid "string to display when http result code doesn't match" msgstr "wat te laten zien als de HTTP statuscodes niet overeenkomen" #: help.c:272 msgid "Nagios-mode: return 1 when avg. response time >= warn, 2 if >= crit, otherwhise return 0" msgstr "Nagios-mode 1: geef 1 terug als de gemiddelde reactiesnelheid >= \"warn\" en 2 als die snelheid >= \"crit\", anders geef 0 terug" #: help.c:273 msgid "Nagios mode 2: return 0 when all fine, 'x' when anything failes" msgstr "Nagios mode 2: geef 0 terug als alles goed ging, anders 'x'" #: help.c:274 msgid "add a cookie to the request" msgstr "voeg een cookie toe aan het HTTP-verzoek" #: help.c:275 msgid "add colors" msgstr "gebruik kleuren" #: help.c:276 msgid "audible ping" msgstr "hoorbare piep" #: help.c:281 #, c-format msgid " *** GUI/ncurses mode settings ***\n" msgstr " *** grafische interface/ncurses mode instellingen ***\n" #: help.c:282 msgid "ncurses/GUI mode" msgstr "ncurses/GUI mode" #: help.c:284 msgid "draw phase (fourier transform) in gui" msgstr "toon fasediagram" #: help.c:286 msgid "when the duration is x or more, show ping line in the slow log window (the middle window)" msgstr "als de tijdmetingen groter zijn dan x, toon dan het resultaat in het middelste venster" #: help.c:287 msgid "do not scale to values above x" msgstr "schaal niet naar waardes boven 'x'" #: help.c:288 msgid "do not show graphs (in ncurses/GUI mode)" msgstr "toon geen grafieken" #: help.c:292 msgid "show the version" msgstr "toon de versie van dit programma" #: help.c:305 #, c-format msgid "Voorbeeld:\n" msgstr "" #: io.c:43 #: io.c:78 #, c-format msgid "myread::select failed: %s" msgstr "leesfout: %s" #: io.c:94 #, c-format msgid "myread::read failed: %s" msgstr "leesfout: %s" #: io.c:138 #, c-format msgid "mywrite::select failed: %s" msgstr "selecteer fout: %s" #: io.c:152 #, c-format msgid "mywrite::write failed: %s" msgstr "schrijffout: %s" #: io.c:174 #, c-format msgid "set_fd_nonblocking failed! (%s)\n" msgstr "\"set_fd_nonblocking\" fout: %s\n" #: io.c:187 #, c-format msgid "set_fd_blocking failed! (%s)\n" msgstr "\"set_fd_blocking\" fout: %s\n" #: main.c:109 #: main.c:108 #, c-format msgid "%s, run time: %.3fs, press ctrl + c to stop" msgstr "%s, loop tijd: %.3fs, druk op ctrl + c om het programma te stoppen" #: main.c:244 #: main.c:243 #, c-format msgid "Got signal %d\n" msgstr "Signaal %d\n" #: main.c:255 #: main.c:254 #, c-format msgid "Cannot open password-file %s" msgstr "Kan het toegangscodebestand '%s' niet openen" #: main.c:258 #: main.c:257 #, c-format msgid "Problem reading password from file %s" msgstr "Probleem bij het lezen van de toegangscode uit bestand '%s'" #: main.c:365 #: main.c:364 #, c-format msgid "URL too big, HTTPing has a %d bytes limit" msgstr "URL is te groot, HTTPing heeft daar een limiet van %d bytes op" #: main.c:384 #: main.c:383 msgid "using \"http://\" with SSL enabled (-l)" msgstr "\"http://\" gebruikt met SSL ingeschakeld (-l)" #: main.c:519 #: main.c:518 #, c-format msgid "AGG[%d]: %d values, min/avg/max%s = %.1f/%.1f/%.1f" msgstr "CUM[%d]: %d waardes, min/gem/max%s = %.1f/%.1f/%.1f" #: main.c:519 #: main.c:2294 #: main.c:518 #: main.c:2289 msgid "/sd" msgstr "/sd" #: main.c:576 #: main.c:575 msgid "-n: missing parameter\n" msgstr "-n: ontbrekende parameter\n" #: main.c:594 #: main.c:603 #: main.c:593 #: main.c:602 #, c-format msgid "cannot convert ip address '%s' (for -y)\n" msgstr "kan het IP-adres '%s' niet vertalen (-y)\n" #: main.c:710 #: main.c:709 #, c-format msgid "CRITICAL - connecting failed: %s" msgstr "KRITIEK - verbinding mislukt: %s" #: main.c:715 #: main.c:714 #, c-format msgid "CRITICAL - average httping-time is %.1f\n" msgstr "KRITIEK - gemiddelde HTTPing tijd is %.1f\n" #: main.c:720 #: main.c:719 #, c-format msgid "WARNING - average httping-time is %.1f\n" msgstr "WAARSCHUWING - gemiddelde HTTPing tijd is %.1f\n" #: main.c:724 #: main.c:723 #, c-format msgid "OK - average httping-time is %.1f (%s)|ping=%f\n" msgstr "OK - gemiddelde HTTPing-tijd is %.1f (%s)|ping=%f\n" #: main.c:734 #: main.c:733 #, c-format msgid "OK - all fine, avg httping time is %.1f|ping=%f\n" msgstr "OK - gemiddelde HTTPing-tijd is %.1f|ping=%f\n" #: main.c:738 #: main.c:737 #, c-format msgid "%s: - failed: %s" msgstr "%s: - mislukt: %s" #: main.c:1025 #: main.c:1020 #, c-format msgid "" "\n" " *** -A is no longer required ***\n" "\n" msgstr "" "\n" " *** -A is niet langer nodig ***\n" "\n" #: main.c:1170 #: main.c:1165 msgid "-i cannot have a value smaller than zero" msgstr "-i waarde kan niet kleiner dan 0 zijn" #: main.c:1224 #: main.c:1232 #: main.c:1219 #: main.c:1227 msgid "-n and -N are mutual exclusive\n" msgstr "-n en -N zijn wederzijds uitsluitende\n" #: main.c:1253 #: main.c:1248 #, c-format msgid "Warning: TCP TFO is not supported. Disabling.\n" msgstr "Let op: TCP TFO is niet ondersteund.\n" #: main.c:1269 #: main.c:1264 #, c-format msgid "" "\n" "\n" "Please run:\n" "\t%s --help\n" "to see a list of options.\n" "\n" msgstr "" "\n" "\n" "Start:\n" "\t%s --help\n" "om een lijst van opties te zien.\n" "\n" #: main.c:1281 #, c-format msgid "" "No URL/host to ping given\n" "\n" msgstr "" "Geen URL of systeemnaam gespecificeerd om te pingen\n" "\n" #: main.c:1291 #: main.c:1286 msgid "Cannot combine -m, -M and -K" msgstr "-m, -M en -K kunnen niet gecombineerd worden" #: main.c:1294 #: main.c:1289 msgid "Aggregates can only be used in non-machine/json-output mode" msgstr "Cumulatieven kunnen niet in machine-uitvoer/json-uitvoer modi gebruikt worden" #: main.c:1299 #: main.c:1294 msgid "-b/-B can only be used when also using -G (GET instead of HEAD) or -l (use SSL)\n" msgstr "-b/-B kunnen alleen gebruikt worden ism -G or -l\n" #: main.c:1302 #: main.c:1297 msgid "TCP Fast open and SSL not supported together\n" msgstr "\"TCP Fast open\" en SSL kunnen niet gecombineerd worden\n" #: main.c:1332 #: main.c:1327 msgid "" "\n" "Auto enabling SSL due to https-URL" msgstr "" "\n" "SSL ingeschakeld vanwege https-URL" #: main.c:1338 #: main.c:1333 #, c-format msgid "Auto enabling SSL due to https-URL" msgstr "SSL ingeschakeld vanwege https-URL" #: main.c:1347 #: main.c:1342 #, c-format msgid "" "\n" "Connecting to host %s, port %d and requesting file %s" msgstr "" "\n" "Verbinden met %s:%d en opvragen van bestand %s" #: main.c:1350 #: main.c:1345 #, c-format msgid "" "\n" "Using proxyserver: %s:%d" msgstr "" "\n" "Proxy %s:%d wordt gebruikt" #: main.c:1355 #: main.c:1350 #, c-format msgid "" "Connecting to host %s, port %d and requesting file %s\n" "\n" msgstr "" "Verbinden met %s:%d en opvragen van bestand %s\n" "\n" #: main.c:1358 #: main.c:1353 #, c-format msgid "Using proxyserver: %s:%d\n" msgstr "Proxy: %s:%d\n" #: main.c:1369 #: main.c:1364 msgid "problem creating SSL context" msgstr "Probleem bij aanmaken SSL-context" #: main.c:1389 #: main.c:1384 msgid "Interval must be > 0 when using adaptive interval" msgstr "Interval moet groter dan 0 zijn bij adaptieve interval" #: main.c:1417 #: main.c:1435 #: main.c:1519 #: main.c:1412 #: main.c:1430 #: main.c:1514 #, c-format msgid "" "\n" "Resolving hostname %s" msgstr "" "\n" "Vertalen systeemnaam '%s'" #: main.c:1427 #: main.c:1452 #: main.c:1545 #: main.c:1422 #: main.c:1447 #: main.c:1540 #, c-format msgid "No valid IPv4 or IPv6 address found for %s" msgstr "Geen geldig IPv4 of IPv6 adres gevonden voor '%s'" #: main.c:1579 #: main.c:1574 msgid "Will no longer inform about request headers too large." msgstr "Zal niet langer meldingen tonen over te grote verzoeken." #: main.c:1581 #: main.c:1576 #, c-format msgid "Request headers > 4KB! (%d bytes) This may give failures with some HTTP servers." msgstr "Verzoek is groter dan 4KB! (%d bytes) Dit kan problemen opleveren met sommige HTTP-servers." #: main.c:1685 #: main.c:1680 msgid "timeout connecting to host" msgstr "systeem reageerde niet op tijd" #: main.c:1748 #: main.c:1743 msgid "error sending request to host" msgstr "probleem bij verzenden verzoek naar systeem" #: main.c:1750 #: main.c:1800 #: main.c:1745 #: main.c:1795 msgid "timeout sending to host" msgstr "systeem reageerde niet op tijd bij verzenden verzoek" #: main.c:1752 #: main.c:1747 msgid "retrieved invalid data from host" msgstr "ongeldige data ontvangen van systeem" #: main.c:1756 #: main.c:1751 msgid "connection prematurely closed by peer" msgstr "verbinding voortijdig gesloten door systeem" #: main.c:1790 #: main.c:1785 msgid "" "\n" "No longer emitting message about \"still data in transit\"" msgstr "" "\n" "Er zullen geen meldingen meer getoond worden over data die nog getransporteerd wordt." #: main.c:1792 #: main.c:1787 #, c-format msgid "" "\n" "HTTP server started sending data with %d bytes still in transit" msgstr "" "\n" "HTTP server begon al een reaktie te versturen terwijl er nog %d bytes onderweg waren" #: main.c:1813 #: main.c:1808 msgid "failed to obtain TOS info" msgstr "probleem bij ophalen TOS-informatie" #: main.c:1827 #: main.c:1822 msgid "" "\n" "No longer emitting message about \"more data than response headers\"" msgstr "" "\n" "De melding \"HTTP server verzond meer data dan alleen de antwoord metadata\" zal niet meer getoond worden." #: main.c:1829 #: main.c:1824 msgid "" "\n" "HTTP server sent more data than just the response headers" msgstr "" "\n" "HTTP server verzond meer data dan alleen de antwoord metadata" #: main.c:1878 #: main.c:1873 msgid "'Content-Length'-header missing!" msgstr "'Content-Length' metadata ontbreekt" #: main.c:1910 #: main.c:1905 msgid "short read during receiving reply-headers from host" msgstr "ontvangprobleem bij metadata van systeem" #: main.c:1912 #: main.c:1907 msgid "timeout while receiving reply-headers from host" msgstr "geen reactie bij ontvangen metadata van systeem" #: main.c:1945 #: main.c:1940 msgid "read of response body dataa failed" msgstr "lezen van reactiedata mislukt" #: main.c:1980 #: main.c:1975 msgid "error shutting down ssl" msgstr "probleem bij stoppen SSL-verbinding" #: main.c:2026 #: main.c:2087 #: main.c:2021 #: main.c:2082 #, c-format msgid "getnameinfo() failed: %d (%s)" msgstr "getnameinfo() faalde: %d (%s)" #: main.c:2061 #: main.c:2056 msgid "connected to" msgstr "verbinden met" #: main.c:2061 #: main.c:2056 msgid "pinged host" msgstr "gepingde systeem" #: main.c:2105 #: main.c:2100 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d/%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d/%d bytes), volgnr=%s%d%s " #: main.c:2107 #: main.c:2102 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d bytes), volgnr=%s%d%s " #: main.c:2113 #: main.c:2114 #: nc.c:721 #: main.c:2108 #: main.c:2109 msgid " n/a" msgstr " ---" #: main.c:2119 #: main.c:2114 #, c-format msgid "time=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s" msgstr "tijd=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s" #: main.c:2129 #: main.c:2124 #, c-format msgid "time=%s%s%s ms %s%s%s" msgstr "tijd=%s%s%s ms %s%s%s" #: main.c:2149 #: main.c:2144 msgid "not " msgstr "niet " #: main.c:2150 #: main.c:2145 msgid "compressed)" msgstr "gecomprimeerd)" #: main.c:2162 #: main.c:2157 #, c-format msgid " toff=%d" msgstr " tijdoffset=%d" #: main.c:2166 #: main.c:2161 #, c-format msgid " age=%d" msgstr " leeftijd=%d" #: main.c:2282 #: main.c:2277 #, c-format msgid "--- %s ping statistics ---\n" msgstr "--- %s ping statistieken ---\n" #: main.c:2285 #: main.c:2280 #, c-format msgid "internal error! (curncount)\n" msgstr "interne fout! (curncount)\n" #: main.c:2290 #: main.c:2285 #, c-format msgid "%s%d%s connects, %s%d%s ok, %s%3.2f%%%s failed, time %s%s%.0fms%s\n" msgstr "%s%d%s verbindingen, %s%d%s ok, %s%3.2f%%%s mislukt, tijd %s%s%.0fms%s\n" #: main.c:2294 #: main.c:2289 #, c-format msgid "round-trip min/avg/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" msgstr "retour min/gem/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" #: main.c:2305 #: main.c:2300 #, c-format msgid "Transfer speed: min/avg/max = %s%f%s/%s%f%s/%s%f%s KB\n" msgstr "Verzendsnelheid: min/gem/max = %s%f%s/%s%f%s/%s%f%s KB\n" #: mssl.c:79 #, c-format msgid "READ_SSL: io-error: %s" msgstr "SSL lezen, I/O fout: %s" #: mssl.c:110 #, c-format msgid "WRITE_SSL: io-error: %s" msgstr "SSL schrijven, I/O fout: %s" #: mssl.c:141 #, c-format msgid "problem setting receive timeout (%s)" msgstr "probleem bij instellen ontvangsttijdslimiet (%s)" #: mssl.c:147 #, c-format msgid "problem setting transmit timeout (%s)" msgstr "probleem bij instellen verzendtijdslimiet (%s)" #: mssl.c:159 #, c-format msgid "problem starting SSL connection: %d" msgstr "probleem bij starten SSL verbinding: %d" #: mssl.c:259 msgid "Problem sending request to proxy" msgstr "Probleem bij verzenden verzoek naar proxy" #: mssl.c:268 msgid "Problem retrieving proxy response" msgstr "Probleem in ontvangen proxyreactie" #: mssl.c:282 msgid "Invalid proxy response headers" msgstr "Ongeldige proxyreactie" #: mssl.c:289 #, c-format msgid "Proxy indicated error: %s" msgstr "Proxy gaf een fout aan: %s" #: nc.c:57 msgid "realloc issue" msgstr "geheugenfout" #: nc.c:542 #, c-format msgid "highest: %6.2fHz, avg: %6.2fHz" msgstr "hoogste: %6.2fHz, gem: %6.2fHz" #: nc.c:668 #, c-format msgid "graph range: %7.2fms - %7.2fms " msgstr "grafiekbandbreedte: %7.2fms - %7.2fms " #: nc.c:732 #, c-format msgid "%s: n/a" msgstr "%s: ---" #: nc.c:749 msgid "latest" msgstr "laatste" #: nc.c:749 #: nc.c:769 msgid "min" msgstr "min" #: nc.c:749 #: nc.c:769 msgid "avg" msgstr "gem" #: nc.c:749 #: nc.c:769 msgid "max" msgstr "max" #: nc.c:749 #: nc.c:769 msgid "sd" msgstr "sd" #: nc.c:750 msgid "resolve" msgstr "vertaal" #: nc.c:751 msgid "connect" msgstr "verbind" #: nc.c:752 msgid "ssl " msgstr "ssl " #: nc.c:753 msgid "send " msgstr "zend " #: nc.c:754 msgid "request" msgstr "verzoek" #: nc.c:755 msgid "close " msgstr "sluiten" #: nc.c:756 msgid "total " msgstr "totaal " #: nc.c:760 #, c-format msgid "ok: %3d, fail: %3d%s, scc: %s, kalman: %s" msgstr "ok: %2d, mislukt: %2d%s, scc: %s, Kalman: %s" #: nc.c:760 msgid ", with TFO" msgstr ", met TFO" #: nc.c:769 msgid "cur" msgstr "nu" #: nc.c:770 msgid "t offst" msgstr "t offst" #: nc.c:773 msgid "tcp rtt" msgstr "TCP RTT" #: nc.c:775 msgid "headers" msgstr "meta " #: nc.c:782 #, c-format msgid "# cookies: %d" msgstr "# cookies: %d" #: nc.c:784 #, c-format msgid "trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" msgstr "trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" #: nc.c:787 #, c-format msgid "HTTP rc: %s, SSL fp: %s" msgstr "HTTP rc: %s, SSL va: %s" #: nc.c:787 msgid "n/a" msgstr "---" #: nc.c:795 #, c-format msgid "http result code: %s" msgstr "HTTP statuscode: %s" #: nc.c:799 #, c-format msgid "" "\n" "SSL fingerprint: %s" msgstr "" "\n" "SSL vingerafdruk: %s" #: res.c:36 #, c-format msgid "Resolving %s %sfailed: %s" msgstr "Vertalen %s %smislukt: %s" #: res.c:36 msgid "(IPv6) " msgstr "(IPv6) " #: res.c:71 #, c-format msgid "Problem resolving %s (IPv4): %s" msgstr "Probleem vertalen %s (IPv4): %s" #: socks5.c:56 #, c-format msgid "socks5connect: reply with requested authentication method does not say version 5 (%02x)" msgstr "socks5connect: reactie geeft niet versie 5 aan (%02x)" #: socks5.c:70 #, c-format msgid "socks5connect: socks5 refuses our authentication methods: %02x" msgstr "socks5connect: socks5 systeem wijst onze authenticatie methode af: %02x" #: socks5.c:81 msgid "socks5connect: socks5 server requests username/password authentication" msgstr "socks5connect: systeem vraagt gebruikersnaamauthenticatie" #: socks5.c:90 msgid "socks5connect: failed transmitting username/password to socks5 server" msgstr "socks5connect: probleem bij verzenden gebrukersnaam/toegangscode naar systeem" #: socks5.c:96 msgid "socks5connect: failed receiving authentication reply" msgstr "socks5connect: authenticatie reactie ontvangen mislukt" #: socks5.c:102 msgid "socks5connect: password authentication failed" msgstr "socks5connect: authenticatie faalde" #: socks5.c:116 #, c-format msgid "Cannot resolve %s" msgstr "Kan %s niet vertalen" #: socks5.c:133 msgid "socks5connect: failed to transmit associate request" msgstr "socks5connect: \"associatie\"-verzoek verzenden mislukt" #: socks5.c:139 msgid "socks5connect: command reply receive failure" msgstr "socks5connect: commando-reactie ontvangen mislukt" #: socks5.c:146 #, c-format msgid "socks5connect: bind request replies with version other than 0x05 (%02x)" msgstr "socks5connect: verbindingsreactie geeft ander versienummer (%02x) dan 0x05 terug" #: socks5.c:152 #, c-format msgid "socks5connect: failed to connect (%02x)" msgstr "socks5connect: verbinden mislukt (%02x)" #: socks5.c:158 #, c-format msgid "socks5connect: only accepting bind-replies with IPv4 address (%02x)" msgstr "socks5connect: alleen \"bind\"-reakties voor IPv4 ondersteund (%02x)" #: tcp.c:31 #: tcp.c:42 #, c-format msgid "could not set TCP_NODELAY on socket (%s)" msgstr "kan TCP_NODELAY niet inschakelen op verbinding (%s)" #: tcp.c:57 #, c-format msgid "problem creating socket (%s)" msgstr "probleem bij maken socket (%s)" #: tcp.c:69 #, c-format msgid "error setting sockopt to interface (%s)" msgstr "sockopt zetten op adapter mislukt (%s)" #: tcp.c:75 #, c-format msgid "error binding to interface (%s)" msgstr "probleem bij binden aan adapter (%s)" #: tcp.c:84 #, c-format msgid "error setting MTU size (%s)" msgstr "probleem bij instellen MTU-grootte (%s)" #: tcp.c:101 #, c-format msgid "error setting transmit buffer size (%s)" msgstr "probleem bij instellen verzendbuffergrootte (%s)" #: tcp.c:110 #, c-format msgid "error setting receive buffer size (%s)" msgstr "probleem bij instellen ontvangstbuffergrootte (%s)" #: tcp.c:119 #, c-format msgid "error setting priority (%s)" msgstr "probleem bij instellen prioriteit (%s)" #: tcp.c:128 msgid "failed to set TOS info" msgstr "probleem bij instellen TOS-info" #: tcp.c:165 #, c-format msgid "TCP TFO Not Supported. Please check if \"/proc/sys/net/ipv4/tcp_fastopen\" is 1. Disabling TFO for now.\n" msgstr "TCP TFO is niet ondersteund. Controleer of \"/proc/sys/net/ipv4/tcp_fastopen\" de waarde 1 bevat.\n" #: tcp.c:195 #, c-format msgid "problem connecting to host: %s" msgstr "probleem bij verbinden met systeem: %s" #: tcp.c:208 msgid "connect time out" msgstr "verbindingstimeout" #: tcp.c:216 #, c-format msgid "select() failed: %s" msgstr "select() mislukt: %s" #: tcp.c:228 #, c-format msgid "getsockopt failed (%s)" msgstr "getsockopt mislukt (%s)" #: tcp.c:240 #, c-format msgid "could not connect (%s)" msgstr "kan niet verbinden (%s)" #: utils.c:25 msgid "gettimeofday failed" msgstr "gettimeofday mislukt" #~ #: main.c:1276 main.c:1271 #~ msgid "Cannot combine maximum MTU size setting with proxy connections or SSL" #~ msgstr "" HTTPing-4.4.0/po/ru.po000066400000000000000000001077431475432366700144350ustar00rootroot00000000000000# Russian translation for HTTPing package. # Copyright (C) 2016 folkert van heusden # This file is distributed under the same license as the HTTPing package. # folkert van heusden , 2016. # Translated by Way, No - http://noway421.github.io/ # msgid "" msgstr "" "Project-Id-Version: HTTPing\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-04 15:29+0200\n" "PO-Revision-Date: 2016-07-13 16:00+1100\n" "Last-Translator: Way, No \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" "X-Poedit-Language: Russian\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" #: error.c:23 #, c-format msgid "" "\n" "\n" "errno=%d which means %s (if applicable)\n" msgstr "" "\n" "\n" "errno=%d что значит: %s (если применимо)\n" #: error.c:39 #, c-format msgid "Error message '%s' truncated" msgstr "Сообщение об ошибке '%s' урезано." #: fft.c:21 msgid "failed allocating memory for fft (1)" msgstr "не удалось выделить память для fft (1)." #: fft.c:25 msgid "failed allocating memory for fft (2)" msgstr "не удалось выделить память для fft (2)." #: fft.c:30 msgid "failed calculating plan for fft" msgstr "не удалось вычислить план для fft." #: help.c:77 #, c-format msgid "HTTPing v" msgstr "HTTPing версия" msgid "adds an extra request-header" msgstr "добавляет дополнительный заголовок запроса" #: help.c:79 #, c-format msgid " * SSL support included (-l)\n" msgstr " * SSL поддержка включена (-l)\n" #: help.c:84 #, c-format msgid " * ncurses interface with FFT included (-K)\n" msgstr " * ncurses интерфейс с FFT включен (-K)\n" #: help.c:86 #, c-format msgid " * ncurses interface included (-K)\n" msgstr " * ncurses интерфейс включен (-K)\n" #: help.c:91 #, c-format msgid " * TFO (TCP fast open) support included (-F)\n" msgstr " * TFO (TCP fast open) поддержка включена' (-F)\n" #: help.c:93 #: help.c:293 #, c-format msgid "\n" msgstr "\n" #: help.c:176 #, c-format msgid " *** where to connect to ***\n" msgstr " *** куда подключаться ***\n" #: help.c:177 msgid "URL to ping (e.g. -g http://localhost/)" msgstr "URL для пинга (к примеру, -g http://localhost/)" #: help.c:178 msgid "hostname to ping (e.g. localhost) - use either -g or -h" msgstr "имя хоста для пинга (к примеру, localhost) - используйте -g или -h" #: help.c:179 msgid "portnumber (e.g. 80) - use with -h" msgstr "номер порта (к примеру, 80), используется с -h" #: help.c:180 msgid "use IPv6 when resolving/connecting" msgstr "использовать IPv6 для резолва/подключения" #: help.c:182 msgid "connect using SSL. pinging an https URL automatically enables this setting" msgstr "подключаться с SSL. при пинге https URL эта опция включается автоматически" #: help.c:187 #, c-format msgid " *** proxy settings ***\n" msgstr " *** настройки proxy ***\n" #: help.c:188 msgid "x should be \"host:port\" which are the network settings of the http/https proxy server. ipv6 ip-address should be \"[ip:address]:port\"" msgstr "x должен быть \"host:port\", т.е. сетевыми настройками http/https прокси сервера. ipv6 адрес должен быть в формате \"[ip:address]:port\"" #: help.c:189 msgid "fetch proxy settings from environment variables" msgstr "читать настройки прокси из переменных окружения" #: help.c:190 msgid "username for authentication against proxy" msgstr "имя пользователя для прокси аутентификации" #: help.c:191 msgid "password for authentication against proxy" msgstr "пароль для прокси аутентификации" #: help.c:192 msgid "read password for proxy authentication from file x" msgstr "читать пароль для прокси аутентификации из файла x" #: help.c:193 msgid "proxy is a socks5 server" msgstr "прокси является socks5 сервером" #: help.c:194 msgid "adds \"&x=[random value]\" to the request URL" msgstr "добавляет \"&x=[случайное значение]\" к URL запроса" #: help.c:198 #, c-format msgid " *** timing settings ***\n" msgstr " *** настройки времени ***\n" #: help.c:199 msgid "how many times to ping" msgstr "сколько раз исполнять пинг" #: help.c:200 msgid "delay between each ping" msgstr "задержка между каждым пингом" #: help.c:201 msgid "timeout (default: 30s)" msgstr "тайм-аут (по умолчанию: 30 секунд)" #: help.c:202 msgid "execute pings at multiples of interval relative to start, automatically enabled in ncurses output mode" msgstr "выполнять пинги пропорционально интервалам относительно начала, автоматически включено в ncurses режиме вывода" #: help.c:203 msgid "flood connect (no delays)" msgstr "подключение в режиме флуда (без задержек)" #: help.c:207 #, c-format msgid " *** HTTP settings ***\n" msgstr " *** HTTP настройки ***\n" #: help.c:208 msgid "ask any proxies on the way not to cache the requests" msgstr "просить все прокси по пути не кэшировать запросы" #: help.c:209 msgid "connect to a different host than in the URL given" msgstr "подключиться к другому хосту, отличному от данного в URL" #: help.c:210 msgid "return the cookies given by the HTTP server in the following request(s)" msgstr "возвращать куки выданные HTTP сервером в следующем запросе(ах)" #: help.c:211 msgid "do not add \"Host:\"-line to the request headers" msgstr "не добавлять \"Host:\" строку к заголовку запроса" #: help.c:212 msgid "use a persistent connection, i.e. reuse the same TCP connection for multiple HTTP requests. usually possible when 'Connection: Keep-Alive' is sent by server. adds a 'C' to the output if httping had to reconnect" msgstr "использовать постоянное соединение, т.е. переиспользовать то же самое TCP соединение для нескольких HTTP запросов. обычно возможно когда 'Connection: Keep-Alive' отправлено сервером. добавляет 'C' в вывод если httping был вынужден переподключиться" #: help.c:213 msgid "use 'x' for the UserAgent header" msgstr "использовать 'x' в качестве заголовка UserAgent" #: help.c:214 msgid "use 'x' for the Referer header" msgstr "использовать 'x' в качестве заголовка Referer" #: help.c:218 #, c-format msgid " *** networking settings ***\n" msgstr " *** настройки сети ***\n" #: help.c:219 msgid "limit the MTU size" msgstr "ограничивать размер MTU" #: help.c:220 msgid "do not disable Naggle" msgstr "не отключать алгоритм Naggle" #: help.c:221 msgid "receive buffer size" msgstr "размер буфера приема" #: help.c:222 msgid "transmit buffer size" msgstr "размер буфера передачи" #: help.c:223 msgid "resolve hostname only once (useful when pinging roundrobin DNS: also takes the first DNS lookup out of the loop so that the first measurement is also correct)" msgstr "резолвить имя хоста только один раз (полезно, когда пингуется round robin DNS: также берется первый DNS ответ из цикла таким образом, что первое измерение тоже корректно)" #: help.c:224 msgid "do not abort the program if resolving failed: keep retrying" msgstr "не выходить из программы если резолвинг не удался: продолжать попытки" #: help.c:225 msgid "bind to an ip-address (and thus interface) with an optional port" msgstr "биндиться на ip адрес (и, соответственно, интерфейс), опционально на порт" #: help.c:227 msgid "\"TCP fast open\" (TFO), reduces the latency of TCP connects" msgstr "\"TCP fast open\" (TFO), уменьшает задержку TCP подключений" #: help.c:229 msgid "set priority of packets" msgstr "устанавливать приоритет пакетов" #: help.c:230 msgid "set TOS (type of service)" msgstr "устанавливать TOS (тип сервиса)" #: help.c:234 #, c-format msgid " *** HTTP authentication ***\n" msgstr " *** HTTP аутентификация ***\n" #: help.c:235 msgid "activate (\"basic\") authentication" msgstr "активировать (\"basic\") аутентификацию" #: help.c:236 msgid "username for authentication" msgstr "имя пользователя для аутентификации" #: help.c:237 msgid "password for authentication" msgstr "пароль для аутентификации" #: help.c:238 msgid "read the password fom the file 'x' (replacement for -P)" msgstr "читать пароль из файла 'x' (замена -P)" #: help.c:242 #, c-format msgid " *** output settings ***\n" msgstr " *** настройки вывода ***\n" #: help.c:243 msgid "show statuscodes" msgstr "показывать коды ответа" #: help.c:244 msgid "split measured time in its individual components (resolve, connect, send, etc." msgstr "разделять замеренное время на индивидуальные составляющие (резолв, подключение, отправка и т.п.)" #: help.c:245 msgid "from what ping value to show the value in red (must be bigger than yellow), only in color mode (-Y)" msgstr "начиная от какого значения пинга показывать значение красным (должно быть больше, чем желтое), только в цветном режиме (-Y)" #: help.c:246 msgid "from what ping value to show the value in yellow" msgstr "начиная от какого значения пинга показывать значение желтым" #: help.c:247 msgid "from what ping value to show the results" msgstr "начиная от какого значения пинга показывать результаты" #: help.c:248 msgid "put a timestamp before the measured values, use -v to include the date and -vv to show in microseconds" msgstr "показывать таймстамп перед измеренными значениями, используйте -v, чтобы включить дату и -vv, чтобы показывать микросекунды" #: help.c:249 msgid "show an aggregate each x[/y[/z[/etc]]] seconds" msgstr "показывать совокупный результат каждые x[/y[/z[/т.д.]]] секунд" #: help.c:251 msgid "show fingerprint (SSL)" msgstr "показывать фингерпринт (SSL)" #: help.c:253 msgid "verbose mode" msgstr "показывать подробности (verbose)" #: help.c:257 #, c-format msgid " *** \"GET\" (instead of HTTP \"HEAD\") settings ***\n" msgstr " *** \"GET\" (вместо HTTP \"HEAD\") настройки ***\n" #: help.c:258 msgid "do a GET request instead of HEAD (read the contents of the page as well)" msgstr "делать GET запрос вместо HEAD запроса (читать содержимое страницы в том числе)" #: help.c:259 msgid "show transfer speed in KB/s (use with -G)" msgstr "показывать скорость передачи в КБ/с (используется с -G)" #: help.c:260 msgid "like -b but use compression if available" msgstr "как и -b но использовать сжатие если доступно" #: help.c:261 msgid "limit the amount of data transferred (for -b) to 'x' (in bytes)" msgstr "ограничить количество переданных данных (для -b) до 'x' байт" #: help.c:262 msgid "show the number of KB transferred (for -b)" msgstr "показывать количество переданных данных в КБ (для -b)" #: help.c:266 #, c-format msgid " *** output mode settings ***\n" msgstr " *** настройки режима вывода ***\n" #: help.c:267 msgid "quiet, only returncode" msgstr "тихий режим, возвращать только код возврата" #: help.c:268 msgid "give machine parseable output (see also -o and -e)" msgstr "выдавать машиночитаемый вывод (смотрите также -o и -e)" #: help.c:269 msgid "json output, cannot be combined with -m" msgstr "json вывод, не может быть использовано вместе с -m" #: help.c:270 msgid "what http results codes indicate 'ok' comma separated WITHOUT spaces inbetween default is 200, use with -e" msgstr "какие HTTP коды ответа считать за 'ok'. разделять запятыми БЕЗ пробелов, по умолчанию 200, использовать вместе с -e" #: help.c:271 msgid "string to display when http result code doesn't match" msgstr "строка для показа когда код ответа HTTP не совпадает" #: help.c:272 msgid "Nagios-mode: return 1 when avg. response time >= warn, 2 if >= crit, otherwhise return 0" msgstr "Nagios-mode 1: возвращать 1 когда сред. времени ответа >= \"warn\", 2 когда оно >= \"crit\", в остальных случаях возвращать 0" #: help.c:273 msgid "Nagios mode 2: return 0 when all fine, 'x' when anything failes" msgstr "Nagios mode 2: возвращать 0 когда все в порядке, 'x' когда что-то идет не так" #: help.c:274 msgid "add a cookie to the request" msgstr "добавлять куки к запросу" #: help.c:275 msgid "add colors" msgstr "добавлять цвета" #: help.c:276 msgid "audible ping" msgstr "слышимый пинг" #: help.c:281 #, c-format msgid " *** GUI/ncurses mode settings ***\n" msgstr " *** Настройки режима GUI/ncurses ***\n" #: help.c:282 msgid "ncurses/GUI mode" msgstr "ncurses/GUI режим" #: help.c:284 msgid "draw phase (fourier transform) in gui" msgstr "рисовать фазу (преобразование Фурье) в GUI" #: help.c:286 msgid "when the duration is x or more, show ping line in the slow log window (the middle window)" msgstr "когда длительность больше или равна x, показывать строку пинга в окне медленного журнала (среднее окно)" #: help.c:287 msgid "do not scale to values above x" msgstr "не масштабировать значения больше 'x'" #: help.c:288 msgid "do not show graphs (in ncurses/GUI mode)" msgstr "не показывать графики (в ncurses/GUI режиме)" #: help.c:292 msgid "show the version" msgstr "показывать версию" #: help.c:305 #, c-format msgid "Voorbeeld:\n" msgstr "Пример:\n" #: io.c:43 #: io.c:78 #, c-format msgid "myread::select failed: %s" msgstr "myread::select потерпел неудачу: %s" #: io.c:94 #, c-format msgid "myread::read failed: %s" msgstr "myread::read потерпел неудачу: %s" #: io.c:138 #, c-format msgid "mywrite::select failed: %s" msgstr "mywrite::select потерпел неудачу: %s" #: io.c:152 #, c-format msgid "mywrite::write failed: %s" msgstr "mywrite::write потерпел неудачу: %s" #: io.c:174 #, c-format msgid "set_fd_nonblocking failed! (%s)\n" msgstr "set_fd_nonblocking потерпел неудачу! (%s)\n" #: io.c:187 #, c-format msgid "set_fd_blocking failed! (%s)\n" msgstr "set_fd_blocking потерпел неудачу! (%s)\n" #: main.c:109 #: main.c:108 #, c-format msgid "%s, run time: %.3fs, press ctrl + c to stop" msgstr "%s, время работы: %.3fs, нажмите ctrl + c, чтобы остановить" #: main.c:244 #: main.c:243 #, c-format msgid "Got signal %d\n" msgstr "Есть сигнал %d\n" #: main.c:255 #: main.c:254 #, c-format msgid "Cannot open password-file %s" msgstr "Не получается открыть файл пароля %s" #: main.c:258 #: main.c:257 #, c-format msgid "Problem reading password from file %s" msgstr "Проблема чтения пароля из файла %s" #: main.c:365 #: main.c:364 #, c-format msgid "URL too big, HTTPing has a %d bytes limit" msgstr "URL слишком длинный, HTTPing имеет лимит %d байт" #: main.c:384 #: main.c:383 msgid "using \"http://\" with SSL enabled (-l)" msgstr "Используем \"http://\" с включенным SSL (-l)" #: main.c:519 #: main.c:518 #, c-format msgid "AGG[%d]: %d values, min/avg/max%s = %.1f/%.1f/%.1f" msgstr "СВКПН[%d]: %d значений, мин/сред/макс%s = %.1f/%.1f/%.1f" #: main.c:519 #: main.c:2294 #: main.c:518 #: main.c:2289 msgid "/sd" msgstr "/sd" #: main.c:576 #: main.c:575 msgid "-n: missing parameter\n" msgstr "-n: отсутствующий параметр\n" #: main.c:594 #: main.c:603 #: main.c:593 #: main.c:602 #, c-format msgid "cannot convert ip address '%s' (for -y)\n" msgstr "не получается конвертировать IP адрес '%s' (для -y)\n" #: main.c:710 #: main.c:709 #, c-format msgid "CRITICAL - connecting failed: %s" msgstr "КРИТИЧНО - подключение не удалось: %s" #: main.c:715 #: main.c:714 #, c-format msgid "CRITICAL - average httping-time is %.1f\n" msgstr "КРИТИЧНО - среднее httping-время %.1f\n" #: main.c:720 #: main.c:719 #, c-format msgid "WARNING - average httping-time is %.1f\n" msgstr "ПРЕДУПРЕЖДЕНИЕ - среднее httping-время %.1f\n" #: main.c:724 #: main.c:723 #, c-format msgid "OK - average httping-time is %.1f (%s)|ping=%f\n" msgstr "OK - среднее httping-время %.1f (%s)|ping=%f\n" #: main.c:734 #: main.c:733 #, c-format msgid "OK - all fine, avg httping time is %.1f|ping=%f\n" msgstr "OK - все в порядке, сред httping время %.1f|ping=%f\n" #: main.c:738 #: main.c:737 #, c-format msgid "%s: - failed: %s" msgstr "%s: - не удалось: %s" #: main.c:1025 #: main.c:1020 #, c-format msgid "" "\n" " *** -A is no longer required ***\n" "\n" msgstr "" "\n" " *** -A больше не требуется ***\n" "\n" #: main.c:1170 #: main.c:1165 msgid "-i cannot have a value smaller than zero" msgstr "-i не может иметь значение меньше нуля" #: main.c:1224 #: main.c:1232 #: main.c:1219 #: main.c:1227 msgid "-n and -N are mutual exclusive\n" msgstr "-n и -N являются взаимоисключающими\n" #: main.c:1253 #: main.c:1248 #, c-format msgid "Warning: TCP TFO is not supported. Disabling.\n" msgstr "Предупреждение: TCP TFO не поддерживается. Отключаем.\n" #: main.c:1269 #: main.c:1264 #, c-format msgid "" "\n" "\n" "Please run:\n" "\t%s --help\n" "to see a list of options.\n" "\n" msgstr "" "\n" "\n" "Пожалуйста выполните:\n" "\t%s --help\n" "чтобы посмотреть список опций.\n" "\n" #: main.c:1281 #, c-format msgid "" "No URL/host to ping given\n" "\n" msgstr "" "Никакого URL/хоста для пинга не дано\n" "\n" #: main.c:1291 #: main.c:1286 msgid "Cannot combine -m, -M and -K" msgstr "Нельзя совместить -m, -M и -K" #: main.c:1294 #: main.c:1289 msgid "Aggregates can only be used in non-machine/json-output mode" msgstr "Вывод совокупностей может быть только использован в немашиночитаемом/json-вывод режиме" #: main.c:1299 #: main.c:1294 msgid "-b/-B can only be used when also using -G (GET instead of HEAD) or -l (use SSL)\n" msgstr "-b/-B может быть использован только при использовании -G (GET вместо HEAD) или -l (использовать SSL)\n" #: main.c:1302 #: main.c:1297 msgid "TCP Fast open and SSL not supported together\n" msgstr "TCP Fast open и SSL не поддерживаются вместе\n" #: main.c:1332 #: main.c:1327 msgid "" "\n" "Auto enabling SSL due to https-URL" msgstr "" "\n" "Автоматически включаем SSL ввиду https URL" #: main.c:1338 #: main.c:1333 #, c-format msgid "Auto enabling SSL due to https-URL" msgstr "Автоматически включаем SSL ввиду https-URL" #: main.c:1347 #: main.c:1342 #, c-format msgid "" "\n" "Connecting to host %s, port %d and requesting file %s" msgstr "" "\n" "Подключаемся к хосту %s, порт %d и запрашиваем файл %s" #: main.c:1350 #: main.c:1345 #, c-format msgid "" "\n" "Using proxyserver: %s:%d" msgstr "" "\n" "Используем прокси сервер: %s:%d" #: main.c:1355 #: main.c:1350 #, c-format msgid "" "Connecting to host %s, port %d and requesting file %s\n" "\n" msgstr "" "Подключаемся к хосту %s, порт %d и запрашиваем файл %s\n" "\n" #: main.c:1358 #: main.c:1353 #, c-format msgid "Using proxyserver: %s:%d\n" msgstr "Используем прокси сервер: %s:%d\n" #: main.c:1369 #: main.c:1364 msgid "problem creating SSL context" msgstr "Проблема при создании SSL контекста" #: main.c:1389 #: main.c:1384 msgid "Interval must be > 0 when using adaptive interval" msgstr "Интервал должен быть больше нуля при использовании адаптивного интервала" #: main.c:1417 #: main.c:1435 #: main.c:1519 #: main.c:1412 #: main.c:1430 #: main.c:1514 #, c-format msgid "" "\n" "Resolving hostname %s" msgstr "" "\n" "Резолвим имя хоста %s" #: main.c:1427 #: main.c:1452 #: main.c:1545 #: main.c:1422 #: main.c:1447 #: main.c:1540 #, c-format msgid "No valid IPv4 or IPv6 address found for %s" msgstr "Валидный IPv4 или IPv6 адрес не найден для %s" #: main.c:1579 #: main.c:1574 msgid "Will no longer inform about request headers too large." msgstr "Больше не сообщать о слишком больших заголовках запроса." #: main.c:1581 #: main.c:1576 #, c-format msgid "Request headers > 4KB! (%d bytes) This may give failures with some HTTP servers." msgstr "Заголовок запроса > 4КБ! (%d байт) Это может привести к ошибке на некоторых HTTP серверах." #: main.c:1685 #: main.c:1680 msgid "timeout connecting to host" msgstr "тайм-аут при подключении к хосту" #: main.c:1748 #: main.c:1743 msgid "error sending request to host" msgstr "ошибка при отправке запроса к хосту" #: main.c:1750 #: main.c:1800 #: main.c:1745 #: main.c:1795 msgid "timeout sending to host" msgstr "тайм-аут при отправке к хосту" #: main.c:1752 #: main.c:1747 msgid "retrieved invalid data from host" msgstr "получены неправильные данные от хоста" #: main.c:1756 #: main.c:1751 msgid "connection prematurely closed by peer" msgstr "подключение преждевременно закрыто пиром" #: main.c:1790 #: main.c:1785 msgid "" "\n" "No longer emitting message about \"still data in transit\"" msgstr "" "\n" "Больше не выводить сообщение о \"данных еще в пути\"" #: main.c:1792 #: main.c:1787 #, c-format msgid "" "\n" "HTTP server started sending data with %d bytes still in transit" msgstr "" "\n" "HTTP начал отправлять данные в то время как %d байт еще в пути" #: main.c:1813 #: main.c:1808 msgid "failed to obtain TOS info" msgstr "ошибка при получении TOS информации" #: main.c:1827 #: main.c:1822 msgid "" "\n" "No longer emitting message about \"more data than response headers\"" msgstr "" "\n" "Больше не выводить сообщение о \"больше данных сверх заголовков ответа\"" #: main.c:1829 #: main.c:1824 msgid "" "\n" "HTTP server sent more data than just the response headers" msgstr "" "\n" "HTTP сервер отправил больше данных сверх заголовков ответа" #: main.c:1878 #: main.c:1873 msgid "'Content-Length'-header missing!" msgstr "'Content-Length' заголовок отсутствует!" #: main.c:1910 #: main.c:1905 msgid "short read during receiving reply-headers from host" msgstr "короткое чтение во время получения заголовков ответа от хоста" #: main.c:1912 #: main.c:1907 msgid "timeout while receiving reply-headers from host" msgstr "тайм-аут при получении заголовков ответа от хоста" #: main.c:1945 #: main.c:1940 msgid "read of response body dataa failed" msgstr "неудача при чтении тела ответа" #: main.c:1980 #: main.c:1975 msgid "error shutting down ssl" msgstr "ошибка при завершении SSL" #: main.c:2026 #: main.c:2087 #: main.c:2021 #: main.c:2082 #, c-format msgid "getnameinfo() failed: %d (%s)" msgstr "getnameinfo() не удался: %d (%s)" #: main.c:2061 #: main.c:2056 msgid "connected to" msgstr "подключено к" #: main.c:2061 #: main.c:2056 msgid "pinged host" msgstr "пингуемый хост" #: main.c:2105 #: main.c:2100 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d/%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d/%d байт), поряд.н.=%s%d%s " #: main.c:2107 #: main.c:2102 #, c-format msgid "%s%s%s%s%s:%s%d%s (%d bytes), seq=%s%d%s " msgstr "%s%s%s%s%s:%s%d%s (%d bytes), поряд.н.=%s%d%s " #: main.c:2113 #: main.c:2114 #: nc.c:721 #: main.c:2108 #: main.c:2109 msgid " n/a" msgstr " н/д" #: main.c:2119 #: main.c:2114 #, c-format msgid "time=%s+%s+%s+%s+%s%s=%s%s%s%s ms %s%s%s" msgstr "время=%s+%s+%s+%s+%s%s=%s%s%s%s мс %s%s%s" #: main.c:2129 #: main.c:2124 #, c-format msgid "time=%s%s%s ms %s%s%s" msgstr "время=%s%s%s мс %s%s%s" #: main.c:2149 #: main.c:2144 msgid "not " msgstr "не " #: main.c:2150 #: main.c:2145 msgid "compressed)" msgstr "сжатый)" #: main.c:2162 #: main.c:2157 #, c-format msgid " toff=%d" msgstr " t сдвиг=%d" #: main.c:2166 #: main.c:2161 #, c-format msgid " age=%d" msgstr " возраст=%d" #: main.c:2282 #: main.c:2277 #, c-format msgid "--- %s ping statistics ---\n" msgstr "--- %s статистика пинга ---\n" #: main.c:2285 #: main.c:2280 #, c-format msgid "internal error! (curncount)\n" msgstr "внутренняя ошибка! (curncount)\n" #: main.c:2290 #: main.c:2285 #, c-format msgid "%s%d%s connects, %s%d%s ok, %s%3.2f%%%s failed, time %s%s%.0fms%s\n" msgstr "%s%d%s подключений, %s%d%s ok, %s%3.2f%%%s неудавшихся, время %s%s%.0fмс%s\n" #: main.c:2294 #: main.c:2289 #, c-format msgid "round-trip min/avg/max%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" msgstr "туда-сюда мин/сред/макс%s = %s%.1f%s/%s%.1f%s/%s%.1f%s" #: main.c:2305 #: main.c:2300 #, c-format msgid "Transfer speed: min/avg/max = %s%f%s/%s%f%s/%s%f%s KB\n" msgstr "Скорость передачи: мин/сред/макс = %s%f%s/%s%f%s/%s%f%s КБ\n" #: mssl.c:79 #, c-format msgid "READ_SSL: io-error: %s" msgstr "SSL чтение, I/O ошибка: %s" #: mssl.c:110 #, c-format msgid "WRITE_SSL: io-error: %s" msgstr "SSL запись, I/O ошибка: %s" #: mssl.c:141 #, c-format msgid "problem setting receive timeout (%s)" msgstr "проблема при установке тайм-аута приема (%s)" #: mssl.c:147 #, c-format msgid "problem setting transmit timeout (%s)" msgstr "проблема при установке тайм-аута передачи (%s)" #: mssl.c:159 #, c-format msgid "problem starting SSL connection: %d" msgstr "проблема при старте SSL соединения: %d" #: mssl.c:259 msgid "Problem sending request to proxy" msgstr "Проблема при отправке запроса к прокси" #: mssl.c:268 msgid "Problem retrieving proxy response" msgstr "Проблема при получении ответа от прокси" #: mssl.c:282 msgid "Invalid proxy response headers" msgstr "Неверные заголовки ответа от прокси" #: mssl.c:289 #, c-format msgid "Proxy indicated error: %s" msgstr "Proxy сообщила об ошибке: %s" #: nc.c:57 msgid "realloc issue" msgstr "realloc проблема" #: nc.c:542 #, c-format msgid "highest: %6.2fHz, avg: %6.2fHz" msgstr "наибольшее: %6.2fHz, сред: %6.2fHz" #: nc.c:668 #, c-format msgid "graph range: %7.2fms - %7.2fms " msgstr "диапазон графика: %7.2fмс - %7.2fмс " #: nc.c:732 #, c-format msgid "%s: n/a" msgstr "%s: н/д" #: nc.c:749 msgid "latest" msgstr "последний" #: nc.c:749 #: nc.c:769 msgid "min" msgstr "мин" #: nc.c:749 #: nc.c:769 msgid "avg" msgstr "сред" #: nc.c:749 #: nc.c:769 msgid "max" msgstr "макс" #: nc.c:749 #: nc.c:769 msgid "sd" msgstr "sd" #: nc.c:750 msgid "resolve" msgstr "резолвить" #: nc.c:751 msgid "connect" msgstr "подключаться" #: nc.c:752 msgid "ssl " msgstr "ssl " #: nc.c:753 msgid "send " msgstr "отправлять " #: nc.c:754 msgid "request" msgstr "запрос" #: nc.c:755 msgid "close " msgstr "закрыть" #: nc.c:756 msgid "total " msgstr "всего " #: nc.c:760 #, c-format msgid "ok: %3d, fail: %3d%s, scc: %s, kalman: %s" msgstr "ОК: %2d, неудача: %2d%s, scc: %s, Kalman: %s" #: nc.c:760 msgid ", with TFO" msgstr ", с TFO" #: nc.c:769 msgid "cur" msgstr "тек." #: nc.c:770 msgid "t offst" msgstr "t сдвиг" #: nc.c:773 msgid "tcp rtt" msgstr "TCP RTT" #: nc.c:775 msgid "headers" msgstr "заголовки" #: nc.c:782 #, c-format msgid "# cookies: %d" msgstr "# куки: %d" #: nc.c:784 #, c-format msgid "trend: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" msgstr "тренд: %c%6.2f%%, re-tx: %2d, pmtu: %5d, TOS: %02x" #: nc.c:787 #, c-format msgid "HTTP rc: %s, SSL fp: %s" msgstr "HTTP rc: %s, SSL fp: %s" #: nc.c:787 msgid "n/a" msgstr "Н/Д" #: nc.c:795 #, c-format msgid "http result code: %s" msgstr "HTTP код ответа: %s" #: nc.c:799 #, c-format msgid "" "\n" "SSL fingerprint: %s" msgstr "" "\n" "SSL фингерпринт: %s" #: res.c:36 #, c-format msgid "Resolving %s %sfailed: %s" msgstr "Резолв %s %sне удался: %s" #: res.c:36 msgid "(IPv6) " msgstr "(IPv6) " #: res.c:71 #, c-format msgid "Problem resolving %s (IPv4): %s" msgstr "Проблема при резолве %s (IPv4): %s" #: socks5.c:56 #, c-format msgid "socks5connect: reply with requested authentication method does not say version 5 (%02x)" msgstr "socks5connect: ответ с запрошенным аутентификационным методом не выдает версию 5 (%02x)" #: socks5.c:70 #, c-format msgid "socks5connect: socks5 refuses our authentication methods: %02x" msgstr "socks5connect: socks5 отказывается от наших аутентификационных методов: %02x" #: socks5.c:81 msgid "socks5connect: socks5 server requests username/password authentication" msgstr "socks5connect: socks5 сервер запрашивает аутентификацию основанную на имени пользователя/пароле" #: socks5.c:90 msgid "socks5connect: failed transmitting username/password to socks5 server" msgstr "socks5connect: не удалось передать имя пользователя/пароль socks5 серверу" #: socks5.c:96 msgid "socks5connect: failed receiving authentication reply" msgstr "socks5connect: не удалось получить ответ аутентификации" #: socks5.c:102 msgid "socks5connect: password authentication failed" msgstr "socks5connect: аутентификация по паролю не удалась" #: socks5.c:116 #, c-format msgid "Cannot resolve %s" msgstr "Не получается резолв %s" #: socks5.c:133 msgid "socks5connect: failed to transmit associate request" msgstr "socks5connect: не удалось передать associate запрос" #: socks5.c:139 msgid "socks5connect: command reply receive failure" msgstr "socks5connect: ошибка при получение command ответа" #: socks5.c:146 #, c-format msgid "socks5connect: bind request replies with version other than 0x05 (%02x)" msgstr "socks5connect: bind запрос отвечает с версией отличной от 0x05 (%02x)" #: socks5.c:152 #, c-format msgid "socks5connect: failed to connect (%02x)" msgstr "socks5connect: не удалось подключиться (%02x)" #: socks5.c:158 #, c-format msgid "socks5connect: only accepting bind-replies with IPv4 address (%02x)" msgstr "socks5connect: только принимаем bind ответы с IPv4 адресом (%02x)" #: tcp.c:31 #: tcp.c:42 #, c-format msgid "could not set TCP_NODELAY on socket (%s)" msgstr "не удалось установить TCP_NODELAY на сокет (%s)" #: tcp.c:57 #, c-format msgid "problem creating socket (%s)" msgstr "проблема при создании сокета (%s)" #: tcp.c:69 #, c-format msgid "error setting sockopt to interface (%s)" msgstr "проблема при установке sockopt на интерфейс (%s)" #: tcp.c:75 #, c-format msgid "error binding to interface (%s)" msgstr "проблема при биндинге к интерфейсу (%s)" #: tcp.c:84 #, c-format msgid "error setting MTU size (%s)" msgstr "ошибка при установке размера MTU (%s)" #: tcp.c:101 #, c-format msgid "error setting transmit buffer size (%s)" msgstr "ошибка при установке размера буфера передачи (%s)" #: tcp.c:110 #, c-format msgid "error setting receive buffer size (%s)" msgstr "ошибка при установке размера буфера приема (%s)" #: tcp.c:119 #, c-format msgid "error setting priority (%s)" msgstr "ошибка при установке приоритета (%s)" #: tcp.c:128 msgid "failed to set TOS info" msgstr "не удалось установить TOS информацию" #: tcp.c:165 #, c-format msgid "TCP TFO Not Supported. Please check if \"/proc/sys/net/ipv4/tcp_fastopen\" is 1. Disabling TFO for now.\n" msgstr "TCP TFO не поддерживается. Пожалуйста проверьте равняется ли \"/proc/sys/net/ipv4/tcp_fastopen\" единице. Пока что, отключаем TFO. \n" #: tcp.c:195 #, c-format msgid "problem connecting to host: %s" msgstr "проблема при подключении к хосту: %s" #: tcp.c:208 msgid "connect time out" msgstr "тайм-аут при подключении" #: tcp.c:216 #, c-format msgid "select() failed: %s" msgstr "select() не удался: %s" #: tcp.c:228 #, c-format msgid "getsockopt failed (%s)" msgstr "getsockopt не удался (%s)" #: tcp.c:240 #, c-format msgid "could not connect (%s)" msgstr "не смог подключиться (%s)" #: utils.c:25 msgid "gettimeofday failed" msgstr "gettimeofday не удался" #~ #: main.c:1276 main.c:1271 #~ msgid "Cannot combine maximum MTU size setting with proxy connections or SSL" #~ msgstr "Нельзя совмещать настройку максимального размера MTU с прокси соединениями или SSL" HTTPing-4.4.0/res.c000066400000000000000000000033701475432366700137550ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include "gen.h" #include #include #include #include #include #include "gen.h" #include "res.h" #include "error.h" int resolve_host(const char *host, struct addrinfo **ai, char use_ipv6, int portnr) { int rc = -1; char servname[10]; struct addrinfo myaddr; memset(&myaddr, 0, sizeof myaddr); /* myaddr.ai_flags = AI_PASSIVE; */ myaddr.ai_socktype = SOCK_STREAM; myaddr.ai_protocol = IPPROTO_TCP; myaddr.ai_family = use_ipv6 ? AF_INET6 : AF_INET; snprintf(servname, sizeof servname, "%d", portnr); rc = getaddrinfo(host, servname, &myaddr, ai); if (rc != 0) set_error(gettext("Resolving %s %sfailed: %s"), host, use_ipv6 ? gettext("(IPv6) ") : "", gai_strerror(rc)); return rc; } struct addrinfo * select_resolved_host(struct addrinfo *ai, char use_ipv6) { struct addrinfo *p = ai; while(p) { if (p -> ai_family == AF_INET6 && use_ipv6) return p; if (p -> ai_family == AF_INET) return p; p = p -> ai_next; } return NULL; } void get_addr(struct addrinfo *ai_use, struct sockaddr_in6 *addr) { memcpy(addr, ai_use->ai_addr, ai_use->ai_addrlen); } #define incopy(a) *((struct in_addr *)a) int resolve_host_ipv4(const char *host, struct sockaddr_in *addr) { struct hostent *hostdnsentries = gethostbyname(host); if (hostdnsentries == NULL) { set_error(gettext("Problem resolving %s (IPv4): %s"), host, hstrerror(h_errno)); return -1; } /* create address structure */ addr -> sin_family = hostdnsentries -> h_addrtype; addr -> sin_addr = incopy(hostdnsentries -> h_addr_list[0]); return 0; } HTTPing-4.4.0/res.h000066400000000000000000000006561475432366700137660ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #define incopy(a) *((struct in_addr *)a) int resolve_host(const char *host, struct addrinfo **ai, char use_ipv6, int portnr); struct addrinfo * select_resolved_host(struct addrinfo *ai, char use_ipv6); void get_addr(struct addrinfo *ai_use, struct sockaddr_in6 *addr); int resolve_host_ipv4(const char *host, struct sockaddr_in *addr); HTTPing-4.4.0/socks5.c000066400000000000000000000103521475432366700143710ustar00rootroot00000000000000#include "gen.h" #include #include #include #include #include #include #include #include #include #include #include "error.h" #include "gen.h" #include "io.h" #include "res.h" #include "tcp.h" int socks5connect(int fd, struct addrinfo *ai, double timeout, const char *socks5_username, const char *socks5_password, const char *host, int port, char abort_on_resolve_failure) { struct sockaddr_in sai; uint32_t addr = 0; unsigned char io_buffer[256] = { 0 }; int io_len = 0, rc = -1; if ((rc = connect_to(fd, ai, timeout, NULL, NULL, 0, NULL)) == -1) return rc; /* inform socks server about the auth. methods we support */ if (socks5_username != NULL) { io_buffer[0] = 0x05; /* version */ io_buffer[1] = 2; /* 2 authentication methods */ io_buffer[2] = 0x00; /* method 1: no authentication */ io_buffer[3] = 0x02; /* method 2: username/password */ io_len = 4; } else { io_buffer[0] = 0x05; /* version */ io_buffer[1] = 1; /* 2 authentication methods */ io_buffer[2] = 0x00; /* method 1: no authentication */ io_len = 3; } if ((rc = mywrite(fd, (char *)io_buffer, io_len, timeout)) < 0) return rc; /* wait for reply telling selected authentication method */ if ((rc = myread(fd, (char *)io_buffer, 2, timeout)) < 0) return rc; if (io_buffer[0] != 0x05) { set_error(gettext("socks5connect: reply with requested authentication method does not say version 5 (%02x)"), io_buffer[0]); return RC_INVAL; } if (io_buffer[1] == 0x00) { /* printf("socks5connect: \"no authentication at all\" selected by server\n"); */ } else if (io_buffer[1] == 0x02) { /* printf("socks5connect: selected username/password authentication\n"); */ } else { set_error(gettext("socks5connect: socks5 refuses our authentication methods: %02x"), io_buffer[1]); return RC_INVAL; } /* in case the socks5 server asks us to authenticate, do so */ if (io_buffer[1] == 0x02) { int io_len = 0; if (socks5_username == NULL || socks5_password == NULL) { set_error(gettext("socks5connect: socks5 server requests username/password authentication")); return RC_INVAL; } io_buffer[0] = 0x01; /* version */ io_len = snprintf((char *)&io_buffer[1], sizeof io_buffer - 1, "%c%s%c%s", (int)strlen(socks5_username), socks5_username, (int)strlen(socks5_password), socks5_password); if ((rc = mywrite(fd, (char *)io_buffer, io_len + 1, timeout)) < 0) { set_error(gettext("socks5connect: failed transmitting username/password to socks5 server")); return rc; } if ((rc = myread(fd, (char *)io_buffer, 2, timeout)) < 0) { set_error(gettext("socks5connect: failed receiving authentication reply")); return rc; } if (io_buffer[1] != 0x00) { set_error(gettext("socks5connect: password authentication failed")); return RC_INVAL; } } /* ask socks5 server to associate with server */ io_buffer[0] = 0x05; /* version */ io_buffer[1] = 0x01; /* connect to */ io_buffer[2] = 0x00; /* reserved */ io_buffer[3] = 0x01; /* ipv4 */ if (resolve_host_ipv4(host, &sai) == -1) { if (abort_on_resolve_failure) error_exit(gettext("Cannot resolve %s"), host); return RC_INVAL; } addr = ntohl(sai.sin_addr.s_addr); io_buffer[4] = (addr >> 24) & 255; io_buffer[5] = (addr >> 16) & 255; io_buffer[6] = (addr >> 8) & 255; io_buffer[7] = (addr ) & 255; io_buffer[8] = (port >> 8) & 255; io_buffer[9] = (port ) & 255; if ((rc = mywrite(fd, (char *)io_buffer, 10, timeout)) < 0) { set_error(gettext("socks5connect: failed to transmit associate request")); return rc; } if ((rc = myread(fd, (char *)io_buffer, 10, timeout)) < 0) { set_error(gettext("socks5connect: command reply receive failure")); return rc; } /* verify reply */ if (io_buffer[0] != 0x05) { set_error(gettext("socks5connect: bind request replies with version other than 0x05 (%02x)"), io_buffer[0]); return RC_INVAL; } if (io_buffer[1] != 0x00) { set_error(gettext("socks5connect: failed to connect (%02x)"), io_buffer[1]); return RC_INVAL; } if (io_buffer[3] != 0x01) { set_error(gettext("socks5connect: only accepting bind-replies with IPv4 address (%02x)"), io_buffer[3]); return RC_INVAL; } return RC_OK; } HTTPing-4.4.0/socks5.h000066400000000000000000000002651475432366700144000ustar00rootroot00000000000000int socks5connect(int fd, struct addrinfo *ai, double timeout, const char *socks5_username, const char *socks5_password, const char *host, int port, char abort_on_resolve_failure); HTTPing-4.4.0/tcp.c000066400000000000000000000131221475432366700137460ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #include #include #include #include #include #include #include "gen.h" #include #include #include #include #include #include "error.h" #include "gen.h" #include "io.h" #include "main.h" #include "tcp.h" void failure_close(int fd) { struct linger sl; sl.l_onoff = 1; sl.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &sl, sizeof sl) == -1) set_error(gettext("could not set TCP_NODELAY on socket (%s)"), strerror(errno)); close(fd); } int set_no_delay(int fd) { int flag = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) == -1) { set_error(gettext("could not set TCP_NODELAY on socket (%s)"), strerror(errno)); return -1; } return 0; } int create_socket(struct sockaddr *bind_to, struct addrinfo *ai, int recv_buffer_size, int tx_buffer_size, int max_mtu, char use_no_delay, int priority, int tos) { int fd = -1; /* create socket */ fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd == -1) { set_error(gettext("problem creating socket (%s)"), strerror(errno)); return RC_INVAL; } /* go through a specific interface? */ if (bind_to) { int set = 1; /* set reuse flags */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof set) == -1) { set_error(gettext("error setting sockopt to interface (%s)"), strerror(errno)); close(fd); return RC_INVAL; } if (bind(fd, bind_to, sizeof *bind_to) == -1) { set_error(gettext("error binding to interface (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } if (max_mtu >= 0) { if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &max_mtu, sizeof max_mtu) == -1) { set_error(gettext("error setting MTU size (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } if (use_no_delay) { int rc = -1; if ((rc = set_no_delay(fd)) != 0) return rc; } if (tx_buffer_size > 0) { if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&tx_buffer_size, sizeof tx_buffer_size) == -1) { set_error(gettext("error setting transmit buffer size (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } if (recv_buffer_size > 0) { if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&recv_buffer_size, sizeof recv_buffer_size) == -1) { set_error(gettext("error setting receive buffer size (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } #ifdef linux if (priority >= 0) { if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (char *)&priority, sizeof priority) == -1) { set_error(gettext("error setting priority (%s)"), strerror(errno)); close(fd); return RC_INVAL; } } #endif if (tos >= 0) { if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof tos) == -1) { set_error(gettext("failed to set TOS info")); close(fd); return RC_INVAL; } } return fd; } int connect_to(int fd, struct addrinfo *ai, double timeout, char *tfo, char *msg, int msg_len, char *msg_accepted) { int rc = -1; struct timeval to; fd_set wfds; /* make fd nonblocking */ if (set_fd_nonblocking(fd) == -1) return RC_INVAL; /* wait for connection */ FD_ZERO(&wfds); FD_SET(fd, &wfds); to.tv_sec = (long)(timeout / 1000.0); to.tv_usec = (long)(timeout * 1000.0) % 1000000; /* connect to peer */ if (tfo && *tfo) { #if defined(__FreeBSD__) int enable = 1; setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &enable, sizeof(enable)); rc = sendto(fd, msg, msg_len, 0, ai->ai_addr, ai->ai_addrlen); #else rc = sendto(fd, msg, msg_len, MSG_FASTOPEN, ai -> ai_addr, ai -> ai_addrlen); #endif if (rc == msg_len) *msg_accepted = 1; if (errno == 0) return RC_OK; if (errno == ENOTSUP) { printf(gettext("TCP TFO Not Supported. Please check if \"/proc/sys/net/ipv4/tcp_fastopen\" is 1. Disabling TFO for now.\n")); *tfo = 0; goto old_connect; } } else { int rc = -1; old_connect: rc = connect(fd, ai -> ai_addr, ai -> ai_addrlen); if (rc == 0) { /* connection made, return */ return RC_OK; } if (rc == -1) { /* problem connecting */ if (errno != EINPROGRESS) { set_error(gettext("problem connecting to host: %s"), strerror(errno)); return RC_INVAL; } } } if (stop) return RC_CTRLC; /* wait for connection */ rc = select(fd + 1, NULL, &wfds, NULL, &to); if (rc == 0) { set_error(gettext("connect time out")); return RC_TIMEOUT; /* timeout */ } else if (rc == -1) { if (errno == EINTR) return RC_CTRLC;/* ^C pressed */ set_error(gettext("select() failed: %s"), strerror(errno)); return RC_INVAL; /* error */ } else { int optval=0; socklen_t optvallen = sizeof optval; /* see if the connect succeeded or failed */ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optvallen) == -1) { set_error(gettext("getsockopt failed (%s)"), strerror(errno)); return RC_INVAL; } /* no error? */ if (optval == 0) return RC_OK; /* don't ask */ errno = optval; } set_error(gettext("could not connect (%s)"), strerror(errno)); return RC_INVAL; } HTTPing-4.4.0/tcp.h000066400000000000000000000006111475432366700137520ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ int create_socket(struct sockaddr *bind_to, struct addrinfo *ai, int recv_buffer_size, int tx_buffer_size, int max_mtu, char use_no_delay, int priority, int tos); int connect_to(int fd, struct addrinfo *ai, double timeout, char *tfo, char *msg, int msg_len, char *msg_accepted); void failure_close(int fd); HTTPing-4.4.0/utils.c000066400000000000000000000042051475432366700143220ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include "gen.h" #include "error.h" #include "utils.h" double get_ts(void) { struct timeval ts; struct timezone tz; if (gettimeofday(&ts, &tz) == -1) error_exit(gettext("gettimeofday failed")); return (double)ts.tv_sec + ((double)ts.tv_usec)/1000000.0 + (double)(tz.tz_minuteswest * 60); } void split_string(const char *in, const char *split, char ***list, int *list_n) { char *copy = strdup(in), *pc = copy; int split_len = strlen(split); for(;;) { char *term = strstr(pc, split); if (term) *term = 0x00; *list = (char **)realloc(*list, (*list_n + 1) * sizeof(char *)); (*list)[*list_n] = strdup(pc); (*list_n)++; if (!term) break; pc = term + split_len; } free(copy); } void free_splitted_string(char **list, int n) { int index=0; for(index=0; index= GIGA) { div = GIGA; mul = "G"; } else if (a >= MEGA) { div = MEGA; mul = "M"; } else if (a >= KILO) { div = KILO; mul = "k"; } if (mul[0]) digits_sig--; (void)asprintf(&out, "%*.*f%s", digits_sig, digits_nsig, value / div, mul); return out; } void myusleep(useconds_t v) { int s = v / 1000000; if (s) sleep(s); v %= 1000000; if (v) usleep(v); } HTTPing-4.4.0/utils.h000066400000000000000000000010541475432366700143260ustar00rootroot00000000000000/* Released under AGPL v3 with exception for the OpenSSL library. See license.txt */ double get_ts(void); void split_string(const char *in, const char *split, char ***list, int *list_n); void free_splitted_string(char **list, int n); void str_add(char **to, const char *what, ...); #define GIGA 1000000000.0 #define MEGA 1000000.0 #define KILO 1000.0 char * format_value(double value, int digits_sig, int digits_nsig, char abbreviate); #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) void myusleep(useconds_t v);