Skip to content

Commit

Permalink
feature: Basic functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Periecle committed Sep 24, 2024
1 parent a156066 commit a219376
Show file tree
Hide file tree
Showing 6 changed files with 1,140 additions and 1 deletion.
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CI

on:
push:
branches:
- main
pull_request:

jobs:
build-and-test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- uses: actions/checkout@v3

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Build
run: cargo build --verbose

- name: Run Tests
run: cargo test --verbose

- name: Run Clippy
run: cargo clippy -- -D warnings

- name: Run Formatter Check
run: cargo fmt -- --check
79 changes: 79 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Release

on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"

permissions:
contents: write

jobs:
build-and-upload:
name: Build and upload
runs-on: ${{ matrix.os }}

strategy:
matrix:
# You can add more, for any target you'd like!
include:
- build: linux
os: ubuntu-latest
target: x86_64-unknown-linux-musl

- build: macos
os: macos-latest
target: x86_64-apple-darwin


- build: windows
os: windows-latest
target: x86_64-pc-windows-msvc

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Get the release version from the tag
shell: bash
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV

- name: Install Rust
# Or @nightly if you want
uses: dtolnay/rust-toolchain@stable
# Arguments to pass in
with:
# Make Rust compile to our target (defined in the matrix)
targets: ${{ matrix.target }}

- name: Build
uses: actions-rs/cargo@v1
with:
use-cross: true
command: build
args: --verbose --release --target ${{ matrix.target }}

- name: Build archive
shell: bash
run: |
# Replace with the name of your binary
binary_name="fff"
dirname="$binary_name-${{ env.VERSION }}-${{ matrix.target }}"
mkdir "$dirname"
if [ "${{ matrix.os }}" = "windows-latest" ]; then
mv "target/${{ matrix.target }}/release/$binary_name.exe" "$dirname"
else
mv "target/${{ matrix.target }}/release/$binary_name" "$dirname"
fi
if [ "${{ matrix.os }}" = "windows-latest" ]; then
7z a "$dirname.zip" "$dirname"
echo "ASSET=$dirname.zip" >> $GITHUB_ENV
else
tar -czf "$dirname.tar.gz" "$dirname"
echo "ASSET=$dirname.tar.gz" >> $GITHUB_ENV
fi
- name: Release
uses: softprops/action-gh-release@v1
with:
files: |
${{ env.ASSET }}
35 changes: 35 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
name = "fff"
version = "1.0.0"
authors = ["Roman Kvasnytskyi <[email protected]>"]
edition = "2021"

[dependencies]
clap = { version = "4.5.18", features = ["derive"] }
futures = "0.3.30"
regex = "1.10.6"
reqwest = { version = "0.12.7", features = ["rustls-tls"] }
tokio = { version = "1.40.0", features = ["full"] }
hex = "0.4.3"
once_cell = "1.19.0"
twoway = "0.2"
colored = "2.1.0"
xxhash-rust = { version = "0.8.12", features = ["xxh3"] }
bytes = "1.7.2"

[dev-dependencies]
assert_cmd = "2.0.16"
tempfile = "3.12.0"
predicates = "3.1.2"
httpmock = "0.6.8"
tokio = { version = "1.40.0", features = ["full"] } # For async tests

[[bin]]
name = "fff"
path = "src/main.rs"
bench = true

[profile.release]
lto = true
codegen-units = 1
panic = "abort"
141 changes: 140 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,141 @@
# fff
Rust reimplementation of tomnomnom fff

fff is a high-performance, asynchronous command-line tool written in Rust for making HTTP requests to URLs provided via standard input (stdin). It's designed to be fast, efficient, and highly configurable, making it ideal for tasks like web scraping, testing, and automation.


# Features
- Asynchronous I/O using Tokio for high concurrency.
- Customizable concurrency limits.
- Support for HTTP methods, headers, and request bodies.
- Proxy support.
- Response filtering based on status codes, content, and more.
- Colorized output for easy readability.
- Fast hashing using xxHash for saving responses uniquely.
- Ignore HTML or empty responses.
- Save responses matching specific criteria.

# Installation

## Pre-built Binaries
Download the latest release for your platform from the [Releases page](https://github.com/Periecle/fff/releases).

## Build from Source
To build fff from source, ensure you have Rust and Cargo installed.


```shell
# Clone the repository
git clone https://github.com/Periecle/fff.git
cd fff

# Build the project in release mode and install it in your Path
cargo install --path .
```

# Usage

## Basic Usage
Supply URLs via stdin, one per line:

```shell
cat urls.txt | fff [OPTIONS]
```

## Options

```shell
Usage: fff [OPTIONS]

Request URLs provided on stdin fairly frickin' fast
Options:
-b, --body <BODY> Request body
-d, --delay <DELAY> Delay between issuing requests (ms) [default: 100]
-H, --header <HEADER> Add a header to the request (can be specified multiple times)
--ignore-html Don't save HTML files; useful when looking for non-HTML files only
--ignore-empty Don't save empty files
-k, --keep-alive Use HTTP Keep-Alive
-m, --method <METHOD> HTTP method to use (default: GET, or POST if body is specified) [default: GET]
-M, --match <MATCH> Save responses that include <string> in the body
-o, --output <OUTPUT> Directory to save responses in (will be created) [default: out]
-s, --save-status <SAVE_STATUS>...
Save responses with given status code (can be specified multiple times)
-S, --save Save all responses
-x, --proxy <PROXY> Use the provided HTTP proxy
-h, --help Print help information
-V, --version Print version information
```
# Examples
## Basic Request
Make request to each URL, do not save any responses
```shell
cat urls.txt | fff
```
## Custom HTTP Method and Body
Make request to each URL using POST, with body and specific header.
```shell
echo "http://example.com/api" | fff -m POST -b '{"key":"value"}' -H "Content-Type: application/json"
```
## Using a Proxy
Make request to each URL via specified proxy server.
```shell
cat urls.txt | fff -x http://proxyserver:8080
```
## Saving Responses with Specific Status Codes
Make request to each URL and save requests with status codes 200 and 300 into default directory "roots"
```shell
cat urls.txt | fff -s 200 -s 301
```
## Ignoring HTML Responses
Can be useful if you want to fetch all non-html requests.
```shell
cat urls.txt | fff --ignore-html
```
## Matching Content in Responses
Matches only content that contains specified string.
```shell
cat urls.txt | fff -M "Welcome to"
```
## Setting Concurrency and Delay
For targets that have some rate-limits, or just sensitive to high amount of requests you can setup delay between requests in milliseconds.
```shell
cat urls.txt | fff -c 50 -d 500
```
# Original Work
This tool was originally written by [tomnomnom in Go](https://github.com/tomnomnom/fff).
Differences from the Original Go Tool
- Language: fff is written in Rust, leveraging Rust's safety and performance benefits.
- Asynchronous I/O: Utilizes Tokio for efficient asynchronous operations.
- Performance: Optimized for speed with features like ultrafast hashing using xxHash.
- Extensibility: Easier to extend and maintain due to Rust's powerful type system and package ecosystem.
- Enhanced Features: Additional options like ignoring HTML content, matching response bodies, and colorized output.
- Dependency Management: Uses Cargo for dependency management, simplifying the build process.
# Contributing
Contributions are welcome! Please open an issue or submit a pull request on GitHub.
# Fork the repository.
Create a new branch with your feature or bug fix.
Commit your changes with clear messages.
Push to your branch and open a pull request.
Ensure that all tests pass and adhere to the existing code style.
# License
This project is licensed under the MIT License.
Loading

0 comments on commit a219376

Please sign in to comment.