diff options
author | Maximilian Hils <git@maximilianhils.com> | 2020-04-08 20:21:12 +0200 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2020-04-08 20:21:12 +0200 |
commit | 9d5305301a8e073cbb64bb6574e66bb34373935a (patch) | |
tree | 7f30b0412a9974751846c757d44889694d00dc7b | |
parent | 40925181e9d64c727f75e89acf0205bb4b87bb3a (diff) | |
parent | 4d6886a0f4ebbf6bc66b74fa548ff724ba2ad660 (diff) | |
download | mitmproxy-9d5305301a8e073cbb64bb6574e66bb34373935a.tar.gz mitmproxy-9d5305301a8e073cbb64bb6574e66bb34373935a.tar.bz2 mitmproxy-9d5305301a8e073cbb64bb6574e66bb34373935a.zip |
Merge remote-tracking branch 'origin/master' into fix-ci
162 files changed, 6317 insertions, 1935 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c856523b..648292c8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,10 +2,6 @@ name: CI on: [push, pull_request] -# We currently use Python 3.7 for most things: -# - zstandard currently doesn't have 3.8 wheels, -# - we need to upgrade cryptography from version 2.4, which also doesn't have wheels - env: # Codecov CODECOV_TOKEN: "0409bdfd-57a4-477d-a8af-f6172ef431d3" @@ -57,9 +53,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v1 with: - python-version: '3.7' + python-version: '3.8' - run: pip install tox - - run: tox -e py37 + - run: tox -e py38 # codecov's GitHub action only supports Linux. https://github.com/codecov/codecov-action/issues/7 # codecov's Python uploader has no github actions support yet. https://github.com/codecov/codecov-python/pull/214 - name: Extract branch name # https://stackoverflow.com/a/58035262/934719 @@ -90,7 +86,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v1 with: - python-version: '3.7' + python-version: '3.8' - run: pip install tox - run: tox -e cibuild -- build - uses: actions/upload-artifact@master @@ -155,10 +151,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v1 with: - python-version: '3.7' + python-version: '3.8' - run: pip install tox - run: | - wget https://github.com/gohugoio/hugo/releases/download/v0.59.1/hugo_0.59.1_Linux-64bit.deb + wget https://github.com/gohugoio/hugo/releases/download/v0.65.3/hugo_extended_0.65.3_Linux-64bit.deb sudo dpkg -i hugo*.deb - run: tox -e docs @@ -200,7 +196,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v1 with: - python-version: '3.7' + python-version: '3.8' # artifacts must be downloaded individually, see https://github.com/actions/download-artifact/issues/6 - uses: actions/download-artifact@master with: @@ -17,6 +17,7 @@ dist/ mitmproxy/contrib/kaitaistruct/*.ksy .pytest_cache __pycache__ +.hypothesis/ # UI @@ -124,12 +124,10 @@ The following tools are required to build the mitmproxy docs: - Hugo_ - modd_ -- yarn_ .. code-block:: bash cd docs - yarn modd @@ -191,7 +189,6 @@ with the following command: .. _tox: https://tox.readthedocs.io/ .. _Hugo: https://gohugo.io/ .. _modd: https://github.com/cortesi/modd -.. _yarn: https://yarnpkg.com/en/ .. _PEP8: https://www.python.org/dev/peps/pep-0008 .. _`Google Style Guide`: https://google.github.io/styleguide/pyguide.html .. _StackOverflow: https://stackoverflow.com/questions/tagged/mitmproxy diff --git a/docs/.gitignore b/docs/.gitignore index 64b6fff6..1fb99949 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -2,3 +2,4 @@ generated/ src/public node_modules public +src/resources/_gen/ diff --git a/docs/README.md b/docs/README.md index a9ee1113..5c99fb39 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,7 +5,7 @@ This directory houses the mitmproxy documentation available at <https://docs.mit ## Quick Start 1. Install [hugo](https://gohugo.io/). - 2. Windows users: Depending on your git settings, you may need to manually create a symlink from + 2. Windows users: Depending on your git settings, you may need to manually create a symlink from /docs/src/examples to /examples. 3. Make sure the mitmproxy Python package is installed. 4. Run `./build-current` to generate the documentation source files in `./src/generated`. @@ -17,7 +17,6 @@ Now you can run `hugo server -D` in ./src. This is required to modify CSS files. - 1. Install node, yarn, and [modd](https://github.com/cortesi/modd). - 2. Run `yarn` in this directory to get node-sass. + 1. Install hugo extended version. You can now run `modd` in this directory instead of running hugo directly. diff --git a/docs/modd.conf b/docs/modd.conf index ddadc11a..c4e0ffd7 100644 --- a/docs/modd.conf +++ b/docs/modd.conf @@ -1,8 +1,3 @@ { daemon: cd src; hugo server -D } - -style/** { - # This is quite fast, so it can stay a prep rather than a daemon - prep: ./node_modules/.bin/node-sass -o ./src/themes/mitmproxydocs/static/css ./style/style.scss --error-bell -} diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index a950c88d..00000000 --- a/docs/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "bulma": "^0.6.1", - "node-sass": "^4.7.2" - } -} diff --git a/docs/style/badge.scss b/docs/src/assets/badge.scss index 8082f6c7..8082f6c7 100644 --- a/docs/style/badge.scss +++ b/docs/src/assets/badge.scss diff --git a/docs/src/assets/bulma/base/_all.sass b/docs/src/assets/bulma/base/_all.sass new file mode 100644 index 00000000..e913d6ba --- /dev/null +++ b/docs/src/assets/bulma/base/_all.sass @@ -0,0 +1,5 @@ +@charset "utf-8" + +@import "minireset.sass" +@import "generic.sass" +@import "helpers.sass" diff --git a/docs/src/assets/bulma/base/generic.sass b/docs/src/assets/bulma/base/generic.sass new file mode 100644 index 00000000..31eedfe9 --- /dev/null +++ b/docs/src/assets/bulma/base/generic.sass @@ -0,0 +1,142 @@ +$body-background-color: $scheme-main !default +$body-size: 16px !default +$body-min-width: 300px !default +$body-rendering: optimizeLegibility !default +$body-family: $family-primary !default +$body-overflow-x: hidden !default +$body-overflow-y: scroll !default + +$body-color: $text !default +$body-font-size: 1em !default +$body-weight: $weight-normal !default +$body-line-height: 1.5 !default + +$code-family: $family-code !default +$code-padding: 0.25em 0.5em 0.25em !default +$code-weight: normal !default +$code-size: 0.875em !default + +$small-font-size: 0.875em !default + +$hr-background-color: $background !default +$hr-height: 2px !default +$hr-margin: 1.5rem 0 !default + +$strong-color: $text-strong !default +$strong-weight: $weight-bold !default + +$pre-font-size: 0.875em !default +$pre-padding: 1.25rem 1.5rem !default +$pre-code-font-size: 1em !default + +html + background-color: $body-background-color + font-size: $body-size + -moz-osx-font-smoothing: grayscale + -webkit-font-smoothing: antialiased + min-width: $body-min-width + overflow-x: $body-overflow-x + overflow-y: $body-overflow-y + text-rendering: $body-rendering + text-size-adjust: 100% + +article, +aside, +figure, +footer, +header, +hgroup, +section + display: block + +body, +button, +input, +select, +textarea + font-family: $body-family + +code, +pre + -moz-osx-font-smoothing: auto + -webkit-font-smoothing: auto + font-family: $code-family + +body + color: $body-color + font-size: $body-font-size + font-weight: $body-weight + line-height: $body-line-height + +// Inline + +a + color: $link + cursor: pointer + text-decoration: none + strong + color: currentColor + &:hover + color: $link-hover + +code + background-color: $code-background + color: $code + font-size: $code-size + font-weight: $code-weight + padding: $code-padding + +hr + background-color: $hr-background-color + border: none + display: block + height: $hr-height + margin: $hr-margin + +img + height: auto + max-width: 100% + +input[type="checkbox"], +input[type="radio"] + vertical-align: baseline + +small + font-size: $small-font-size + +span + font-style: inherit + font-weight: inherit + +strong + color: $strong-color + font-weight: $strong-weight + +// Block + +fieldset + border: none + +pre + +overflow-touch + background-color: $pre-background + color: $pre + font-size: $pre-font-size + overflow-x: auto + padding: $pre-padding + white-space: pre + word-wrap: normal + code + background-color: transparent + color: currentColor + font-size: $pre-code-font-size + padding: 0 + +table + td, + th + vertical-align: top + &:not([align]) + text-align: left + th + color: $text-strong diff --git a/docs/src/assets/bulma/base/helpers.sass b/docs/src/assets/bulma/base/helpers.sass new file mode 100644 index 00000000..bbb489dd --- /dev/null +++ b/docs/src/assets/bulma/base/helpers.sass @@ -0,0 +1,281 @@ +// Float + +.is-clearfix + +clearfix + +.is-pulled-left + float: left !important + +.is-pulled-right + float: right !important + +// Overflow + +.is-clipped + overflow: hidden !important + +// Overlay + +.is-overlay + @extend %overlay + +// Typography + +=typography-size($target:'') + @each $size in $sizes + $i: index($sizes, $size) + .is-size-#{$i}#{if($target == '', '', '-' + $target)} + font-size: $size !important + ++typography-size() + ++mobile + +typography-size('mobile') + ++tablet + +typography-size('tablet') + ++touch + +typography-size('touch') + ++desktop + +typography-size('desktop') + ++widescreen + +typography-size('widescreen') + ++fullhd + +typography-size('fullhd') + +$alignments: ('centered': 'center', 'justified': 'justify', 'left': 'left', 'right': 'right') + +@each $alignment, $text-align in $alignments + .has-text-#{$alignment} + text-align: #{$text-align} !important + +@each $alignment, $text-align in $alignments + +mobile + .has-text-#{$alignment}-mobile + text-align: #{$text-align} !important + +tablet + .has-text-#{$alignment}-tablet + text-align: #{$text-align} !important + +tablet-only + .has-text-#{$alignment}-tablet-only + text-align: #{$text-align} !important + +touch + .has-text-#{$alignment}-touch + text-align: #{$text-align} !important + +desktop + .has-text-#{$alignment}-desktop + text-align: #{$text-align} !important + +desktop-only + .has-text-#{$alignment}-desktop-only + text-align: #{$text-align} !important + +widescreen + .has-text-#{$alignment}-widescreen + text-align: #{$text-align} !important + +widescreen-only + .has-text-#{$alignment}-widescreen-only + text-align: #{$text-align} !important + +fullhd + .has-text-#{$alignment}-fullhd + text-align: #{$text-align} !important + +.is-capitalized + text-transform: capitalize !important + +.is-lowercase + text-transform: lowercase !important + +.is-uppercase + text-transform: uppercase !important + +.is-italic + font-style: italic !important + +@each $name, $pair in $colors + $color: nth($pair, 1) + .has-text-#{$name} + color: $color !important + a.has-text-#{$name} + &:hover, + &:focus + color: darken($color, 10%) !important + .has-background-#{$name} + background-color: $color !important + +@each $name, $shade in $shades + .has-text-#{$name} + color: $shade !important + .has-background-#{$name} + background-color: $shade !important + +.has-text-weight-light + font-weight: $weight-light !important +.has-text-weight-normal + font-weight: $weight-normal !important +.has-text-weight-medium + font-weight: $weight-medium !important +.has-text-weight-semibold + font-weight: $weight-semibold !important +.has-text-weight-bold + font-weight: $weight-bold !important + +.is-family-primary + font-family: $family-primary !important + +.is-family-secondary + font-family: $family-secondary !important + +.is-family-sans-serif + font-family: $family-sans-serif !important + +.is-family-monospace + font-family: $family-monospace !important + +.is-family-code + font-family: $family-code !important + +// Visibility + +$displays: 'block' 'flex' 'inline' 'inline-block' 'inline-flex' + +@each $display in $displays + .is-#{$display} + display: #{$display} !important + +mobile + .is-#{$display}-mobile + display: #{$display} !important + +tablet + .is-#{$display}-tablet + display: #{$display} !important + +tablet-only + .is-#{$display}-tablet-only + display: #{$display} !important + +touch + .is-#{$display}-touch + display: #{$display} !important + +desktop + .is-#{$display}-desktop + display: #{$display} !important + +desktop-only + .is-#{$display}-desktop-only + display: #{$display} !important + +widescreen + .is-#{$display}-widescreen + display: #{$display} !important + +widescreen-only + .is-#{$display}-widescreen-only + display: #{$display} !important + +fullhd + .is-#{$display}-fullhd + display: #{$display} !important + +.is-hidden + display: none !important + +.is-sr-only + border: none !important + clip: rect(0, 0, 0, 0) !important + height: 0.01em !important + overflow: hidden !important + padding: 0 !important + position: absolute !important + white-space: nowrap !important + width: 0.01em !important + ++mobile + .is-hidden-mobile + display: none !important + ++tablet + .is-hidden-tablet + display: none !important + ++tablet-only + .is-hidden-tablet-only + display: none !important + ++touch + .is-hidden-touch + display: none !important + ++desktop + .is-hidden-desktop + display: none !important + ++desktop-only + .is-hidden-desktop-only + display: none !important + ++widescreen + .is-hidden-widescreen + display: none !important + ++widescreen-only + .is-hidden-widescreen-only + display: none !important + ++fullhd + .is-hidden-fullhd + display: none !important + +.is-invisible + visibility: hidden !important + ++mobile + .is-invisible-mobile + visibility: hidden !important + ++tablet + .is-invisible-tablet + visibility: hidden !important + ++tablet-only + .is-invisible-tablet-only + visibility: hidden !important + ++touch + .is-invisible-touch + visibility: hidden !important + ++desktop + .is-invisible-desktop + visibility: hidden !important + ++desktop-only + .is-invisible-desktop-only + visibility: hidden !important + ++widescreen + .is-invisible-widescreen + visibility: hidden !important + ++widescreen-only + .is-invisible-widescreen-only + visibility: hidden !important + ++fullhd + .is-invisible-fullhd + visibility: hidden !important + +// Other + +.is-marginless + margin: 0 !important + +.is-paddingless + padding: 0 !important + +.is-radiusless + border-radius: 0 !important + +.is-shadowless + box-shadow: none !important + +.is-unselectable + @extend %unselectable + +.is-relative + position: relative !important diff --git a/docs/src/assets/bulma/base/minireset.sass b/docs/src/assets/bulma/base/minireset.sass new file mode 100644 index 00000000..c5657ebd --- /dev/null +++ b/docs/src/assets/bulma/base/minireset.sass @@ -0,0 +1,79 @@ +/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */ +// Blocks +html, +body, +p, +ol, +ul, +li, +dl, +dt, +dd, +blockquote, +figure, +fieldset, +legend, +textarea, +pre, +iframe, +hr, +h1, +h2, +h3, +h4, +h5, +h6 + margin: 0 + padding: 0 + +// Headings +h1, +h2, +h3, +h4, +h5, +h6 + font-size: 100% + font-weight: normal + +// List +ul + list-style: none + +// Form +button, +input, +select, +textarea + margin: 0 + +// Box sizing +html + box-sizing: border-box + +* + &, + &::before, + &::after + box-sizing: inherit + +// Media +img, +video + height: auto + max-width: 100% + +// Iframe +iframe + border: 0 + +// Table +table + border-collapse: collapse + border-spacing: 0 + +td, +th + padding: 0 + &:not([align]) + text-align: left diff --git a/docs/src/assets/bulma/components/_all.sass b/docs/src/assets/bulma/components/_all.sass new file mode 100644 index 00000000..88fd45c5 --- /dev/null +++ b/docs/src/assets/bulma/components/_all.sass @@ -0,0 +1,15 @@ +@charset "utf-8" + +@import "breadcrumb.sass" +@import "card.sass" +@import "dropdown.sass" +@import "level.sass" +@import "list.sass" +@import "media.sass" +@import "menu.sass" +@import "message.sass" +@import "modal.sass" +@import "navbar.sass" +@import "pagination.sass" +@import "panel.sass" +@import "tabs.sass" diff --git a/docs/src/assets/bulma/components/breadcrumb.sass b/docs/src/assets/bulma/components/breadcrumb.sass new file mode 100644 index 00000000..3d7f4eb3 --- /dev/null +++ b/docs/src/assets/bulma/components/breadcrumb.sass @@ -0,0 +1,75 @@ +$breadcrumb-item-color: $link !default +$breadcrumb-item-hover-color: $link-hover !default +$breadcrumb-item-active-color: $text-strong !default + +$breadcrumb-item-padding-vertical: 0 !default +$breadcrumb-item-padding-horizontal: 0.75em !default + +$breadcrumb-item-separator-color: $border-hover !default + +.breadcrumb + @extend %block + @extend %unselectable + font-size: $size-normal + white-space: nowrap + a + align-items: center + color: $breadcrumb-item-color + display: flex + justify-content: center + padding: $breadcrumb-item-padding-vertical $breadcrumb-item-padding-horizontal + &:hover + color: $breadcrumb-item-hover-color + li + align-items: center + display: flex + &:first-child a + padding-left: 0 + &.is-active + a + color: $breadcrumb-item-active-color + cursor: default + pointer-events: none + & + li::before + color: $breadcrumb-item-separator-color + content: "\0002f" + ul, + ol + align-items: flex-start + display: flex + flex-wrap: wrap + justify-content: flex-start + .icon + &:first-child + margin-right: 0.5em + &:last-child + margin-left: 0.5em + // Alignment + &.is-centered + ol, + ul + justify-content: center + &.is-right + ol, + ul + justify-content: flex-end + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + // Styles + &.has-arrow-separator + li + li::before + content: "\02192" + &.has-bullet-separator + li + li::before + content: "\02022" + &.has-dot-separator + li + li::before + content: "\000b7" + &.has-succeeds-separator + li + li::before + content: "\0227B" diff --git a/docs/src/assets/bulma/components/card.sass b/docs/src/assets/bulma/components/card.sass new file mode 100644 index 00000000..3cdf0008 --- /dev/null +++ b/docs/src/assets/bulma/components/card.sass @@ -0,0 +1,79 @@ +$card-color: $text !default +$card-background-color: $scheme-main !default +$card-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default + +$card-header-background-color: transparent !default +$card-header-color: $text-strong !default +$card-header-padding: 0.75rem 1rem !default +$card-header-shadow: 0 0.125em 0.25em rgba($scheme-invert, 0.1) !default +$card-header-weight: $weight-bold !default + +$card-content-background-color: transparent !default +$card-content-padding: 1.5rem !default + +$card-footer-background-color: transparent !default +$card-footer-border-top: 1px solid $border-light !default +$card-footer-padding: 0.75rem !default + +$card-media-margin: $block-spacing !default + +.card + background-color: $card-background-color + box-shadow: $card-shadow + color: $card-color + max-width: 100% + position: relative + +.card-header + background-color: $card-header-background-color + align-items: stretch + box-shadow: $card-header-shadow + display: flex + +.card-header-title + align-items: center + color: $card-header-color + display: flex + flex-grow: 1 + font-weight: $card-header-weight + padding: $card-header-padding + &.is-centered + justify-content: center + +.card-header-icon + align-items: center + cursor: pointer + display: flex + justify-content: center + padding: $card-header-padding + +.card-image + display: block + position: relative + +.card-content + background-color: $card-content-background-color + padding: $card-content-padding + +.card-footer + background-color: $card-footer-background-color + border-top: $card-footer-border-top + align-items: stretch + display: flex + +.card-footer-item + align-items: center + display: flex + flex-basis: 0 + flex-grow: 1 + flex-shrink: 0 + justify-content: center + padding: $card-footer-padding + &:not(:last-child) + border-right: $card-footer-border-top + +// Combinations + +.card + .media:not(:last-child) + margin-bottom: $card-media-margin diff --git a/docs/src/assets/bulma/components/dropdown.sass b/docs/src/assets/bulma/components/dropdown.sass new file mode 100644 index 00000000..d62a6d88 --- /dev/null +++ b/docs/src/assets/bulma/components/dropdown.sass @@ -0,0 +1,81 @@ +$dropdown-menu-min-width: 12rem !default + +$dropdown-content-background-color: $scheme-main !default +$dropdown-content-arrow: $link !default +$dropdown-content-offset: 4px !default +$dropdown-content-padding-bottom: 0.5rem !default +$dropdown-content-padding-top: 0.5rem !default +$dropdown-content-radius: $radius !default +$dropdown-content-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default +$dropdown-content-z: 20 !default + +$dropdown-item-color: $text !default +$dropdown-item-hover-color: $scheme-invert !default +$dropdown-item-hover-background-color: $background !default +$dropdown-item-active-color: $link-invert !default +$dropdown-item-active-background-color: $link !default + +$dropdown-divider-background-color: $border-light !default + +.dropdown + display: inline-flex + position: relative + vertical-align: top + &.is-active, + &.is-hoverable:hover + .dropdown-menu + display: block + &.is-right + .dropdown-menu + left: auto + right: 0 + &.is-up + .dropdown-menu + bottom: 100% + padding-bottom: $dropdown-content-offset + padding-top: initial + top: auto + +.dropdown-menu + display: none + left: 0 + min-width: $dropdown-menu-min-width + padding-top: $dropdown-content-offset + position: absolute + top: 100% + z-index: $dropdown-content-z + +.dropdown-content + background-color: $dropdown-content-background-color + border-radius: $dropdown-content-radius + box-shadow: $dropdown-content-shadow + padding-bottom: $dropdown-content-padding-bottom + padding-top: $dropdown-content-padding-top + +.dropdown-item + color: $dropdown-item-color + display: block + font-size: 0.875rem + line-height: 1.5 + padding: 0.375rem 1rem + position: relative + +a.dropdown-item, +button.dropdown-item + padding-right: 3rem + text-align: left + white-space: nowrap + width: 100% + &:hover + background-color: $dropdown-item-hover-background-color + color: $dropdown-item-hover-color + &.is-active + background-color: $dropdown-item-active-background-color + color: $dropdown-item-active-color + +.dropdown-divider + background-color: $dropdown-divider-background-color + border: none + display: block + height: 1px + margin: 0.5rem 0 diff --git a/docs/src/assets/bulma/components/level.sass b/docs/src/assets/bulma/components/level.sass new file mode 100644 index 00000000..608f291e --- /dev/null +++ b/docs/src/assets/bulma/components/level.sass @@ -0,0 +1,77 @@ +$level-item-spacing: ($block-spacing / 2) !default + +.level + @extend %block + align-items: center + justify-content: space-between + code + border-radius: $radius + img + display: inline-block + vertical-align: top + // Modifiers + &.is-mobile + display: flex + .level-left, + .level-right + display: flex + .level-left + .level-right + margin-top: 0 + .level-item + &:not(:last-child) + margin-bottom: 0 + margin-right: $level-item-spacing + &:not(.is-narrow) + flex-grow: 1 + // Responsiveness + +tablet + display: flex + & > .level-item + &:not(.is-narrow) + flex-grow: 1 + +.level-item + align-items: center + display: flex + flex-basis: auto + flex-grow: 0 + flex-shrink: 0 + justify-content: center + .title, + .subtitle + margin-bottom: 0 + // Responsiveness + +mobile + &:not(:last-child) + margin-bottom: $level-item-spacing + +.level-left, +.level-right + flex-basis: auto + flex-grow: 0 + flex-shrink: 0 + .level-item + // Modifiers + &.is-flexible + flex-grow: 1 + // Responsiveness + +tablet + &:not(:last-child) + margin-right: $level-item-spacing + +.level-left + align-items: center + justify-content: flex-start + // Responsiveness + +mobile + & + .level-right + margin-top: 1.5rem + +tablet + display: flex + +.level-right + align-items: center + justify-content: flex-end + // Responsiveness + +tablet + display: flex diff --git a/docs/src/assets/bulma/components/list.sass b/docs/src/assets/bulma/components/list.sass new file mode 100644 index 00000000..bc99428a --- /dev/null +++ b/docs/src/assets/bulma/components/list.sass @@ -0,0 +1,39 @@ +$list-background-color: $scheme-main !default +$list-shadow: 0 2px 3px rgba($scheme-invert, 0.1), 0 0 0 1px rgba($scheme-invert, 0.1) !default +$list-radius: $radius !default + +$list-item-border: 1px solid $border !default +$list-item-color: $text !default +$list-item-active-background-color: $link !default +$list-item-active-color: $link-invert !default +$list-item-hover-background-color: $background !default + +.list + @extend %block + background-color: $list-background-color + border-radius: $list-radius + box-shadow: $list-shadow + // &.is-hoverable > .list-item:hover:not(.is-active) + // background-color: $list-item-hover-background-color + // cursor: pointer + +.list-item + display: block + padding: 0.5em 1em + &:not(a) + color: $list-item-color + &:first-child + border-top-left-radius: $list-radius + border-top-right-radius: $list-radius + &:last-child + border-bottom-left-radius: $list-radius + border-bottom-right-radius: $list-radius + &:not(:last-child) + border-bottom: $list-item-border + &.is-active + background-color: $list-item-active-background-color + color: $list-item-active-color + +a.list-item + background-color: $list-item-hover-background-color + cursor: pointer diff --git a/docs/src/assets/bulma/components/media.sass b/docs/src/assets/bulma/components/media.sass new file mode 100644 index 00000000..a9ad114a --- /dev/null +++ b/docs/src/assets/bulma/components/media.sass @@ -0,0 +1,50 @@ +$media-border-color: bulmaRgba($border, 0.5) !default + +.media + align-items: flex-start + display: flex + text-align: left + .content:not(:last-child) + margin-bottom: 0.75rem + .media + border-top: 1px solid $media-border-color + display: flex + padding-top: 0.75rem + .content:not(:last-child), + .control:not(:last-child) + margin-bottom: 0.5rem + .media + padding-top: 0.5rem + & + .media + margin-top: 0.5rem + & + .media + border-top: 1px solid $media-border-color + margin-top: 1rem + padding-top: 1rem + // Sizes + &.is-large + & + .media + margin-top: 1.5rem + padding-top: 1.5rem + +.media-left, +.media-right + flex-basis: auto + flex-grow: 0 + flex-shrink: 0 + +.media-left + margin-right: 1rem + +.media-right + margin-left: 1rem + +.media-content + flex-basis: auto + flex-grow: 1 + flex-shrink: 1 + text-align: left + ++mobile + .media-content + overflow-x: auto diff --git a/docs/src/assets/bulma/components/menu.sass b/docs/src/assets/bulma/components/menu.sass new file mode 100644 index 00000000..3de7e18d --- /dev/null +++ b/docs/src/assets/bulma/components/menu.sass @@ -0,0 +1,57 @@ +$menu-item-color: $text !default +$menu-item-radius: $radius-small !default +$menu-item-hover-color: $text-strong !default +$menu-item-hover-background-color: $background !default +$menu-item-active-color: $link-invert !default +$menu-item-active-background-color: $link !default + +$menu-list-border-left: 1px solid $border !default +$menu-list-line-height: 1.25 !default +$menu-list-link-padding: 0.5em 0.75em !default +$menu-nested-list-margin: 0.75em !default +$menu-nested-list-padding-left: 0.75em !default + +$menu-label-color: $text-light !default +$menu-label-font-size: 0.75em !default +$menu-label-letter-spacing: 0.1em !default +$menu-label-spacing: 1em !default + +.menu + font-size: $size-normal + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + +.menu-list + line-height: $menu-list-line-height + a + border-radius: $menu-item-radius + color: $menu-item-color + display: block + padding: $menu-list-link-padding + &:hover + background-color: $menu-item-hover-background-color + color: $menu-item-hover-color + // Modifiers + &.is-active + background-color: $menu-item-active-background-color + color: $menu-item-active-color + li + ul + border-left: $menu-list-border-left + margin: $menu-nested-list-margin + padding-left: $menu-nested-list-padding-left + +.menu-label + color: $menu-label-color + font-size: $menu-label-font-size + letter-spacing: $menu-label-letter-spacing + text-transform: uppercase + &:not(:first-child) + margin-top: $menu-label-spacing + &:not(:last-child) + margin-bottom: $menu-label-spacing diff --git a/docs/src/assets/bulma/components/message.sass b/docs/src/assets/bulma/components/message.sass new file mode 100644 index 00000000..89e4cc9a --- /dev/null +++ b/docs/src/assets/bulma/components/message.sass @@ -0,0 +1,99 @@ +$message-background-color: $background !default +$message-radius: $radius !default + +$message-header-background-color: $text !default +$message-header-color: $text-invert !default +$message-header-weight: $weight-bold !default +$message-header-padding: 0.75em 1em !default +$message-header-radius: $radius !default + +$message-body-border-color: $border !default +$message-body-border-width: 0 0 0 4px !default +$message-body-color: $text !default +$message-body-padding: 1.25em 1.5em !default +$message-body-radius: $radius !default + +$message-body-pre-background-color: $scheme-main !default +$message-body-pre-code-background-color: transparent !default + +$message-header-body-border-width: 0 !default +$message-colors: $colors !default + +.message + @extend %block + background-color: $message-background-color + border-radius: $message-radius + font-size: $size-normal + strong + color: currentColor + a:not(.button):not(.tag):not(.dropdown-item) + color: currentColor + text-decoration: underline + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + // Colors + @each $name, $components in $message-colors + $color: nth($components, 1) + $color-invert: nth($components, 2) + $color-light: null + $color-dark: null + + @if length($components) >= 3 + $color-light: nth($components, 3) + @if length($components) >= 4 + $color-dark: nth($components, 4) + @else + $color-luminance: colorLuminance($color) + $darken-percentage: $color-luminance * 70% + $desaturate-percentage: $color-luminance * 30% + $color-dark: desaturate(darken($color, $darken-percentage), $desaturate-percentage) + @else + $color-lightning: max((100% - lightness($color)) - 2%, 0%) + $color-light: lighten($color, $color-lightning) + + &.is-#{$name} + background-color: $color-light + .message-header + background-color: $color + color: $color-invert + .message-body + border-color: $color + color: $color-dark + +.message-header + align-items: center + background-color: $message-header-background-color + border-radius: $message-header-radius $message-header-radius 0 0 + color: $message-header-color + display: flex + font-weight: $message-header-weight + justify-content: space-between + line-height: 1.25 + padding: $message-header-padding + position: relative + .delete + flex-grow: 0 + flex-shrink: 0 + margin-left: 0.75em + & + .message-body + border-width: $message-header-body-border-width + border-top-left-radius: 0 + border-top-right-radius: 0 + +.message-body + border-color: $message-body-border-color + border-radius: $message-body-radius + border-style: solid + border-width: $message-body-border-width + color: $message-body-color + padding: $message-body-padding + code, + pre + background-color: $message-body-pre-background-color + pre code + background-color: $message-body-pre-code-background-color diff --git a/docs/src/assets/bulma/components/modal.sass b/docs/src/assets/bulma/components/modal.sass new file mode 100644 index 00000000..377dfa78 --- /dev/null +++ b/docs/src/assets/bulma/components/modal.sass @@ -0,0 +1,113 @@ +$modal-z: 40 !default + +$modal-background-background-color: bulmaRgba($scheme-invert, 0.86) !default + +$modal-content-width: 640px !default +$modal-content-margin-mobile: 20px !default +$modal-content-spacing-mobile: 160px !default +$modal-content-spacing-tablet: 40px !default + +$modal-close-dimensions: 40px !default +$modal-close-right: 20px !default +$modal-close-top: 20px !default + +$modal-card-spacing: 40px !default + +$modal-card-head-background-color: $background !default +$modal-card-head-border-bottom: 1px solid $border !default +$modal-card-head-padding: 20px !default +$modal-card-head-radius: $radius-large !default + +$modal-card-title-color: $text-strong !default +$modal-card-title-line-height: 1 !default +$modal-card-title-size: $size-4 !default + +$modal-card-foot-radius: $radius-large !default +$modal-card-foot-border-top: 1px solid $border !default + +$modal-card-body-background-color: $scheme-main !default +$modal-card-body-padding: 20px !default + +.modal + @extend %overlay + align-items: center + display: none + flex-direction: column + justify-content: center + overflow: hidden + position: fixed + z-index: $modal-z + // Modifiers + &.is-active + display: flex + +.modal-background + @extend %overlay + background-color: $modal-background-background-color + +.modal-content, +.modal-card + margin: 0 $modal-content-margin-mobile + max-height: calc(100vh - #{$modal-content-spacing-mobile}) + overflow: auto + position: relative + width: 100% + // Responsiveness + +tablet + margin: 0 auto + max-height: calc(100vh - #{$modal-content-spacing-tablet}) + width: $modal-content-width + +.modal-close + @extend %delete + background: none + height: $modal-close-dimensions + position: fixed + right: $modal-close-right + top: $modal-close-top + width: $modal-close-dimensions + +.modal-card + display: flex + flex-direction: column + max-height: calc(100vh - #{$modal-card-spacing}) + overflow: hidden + -ms-overflow-y: visible + +.modal-card-head, +.modal-card-foot + align-items: center + background-color: $modal-card-head-background-color + display: flex + flex-shrink: 0 + justify-content: flex-start + padding: $modal-card-head-padding + position: relative + +.modal-card-head + border-bottom: $modal-card-head-border-bottom + border-top-left-radius: $modal-card-head-radius + border-top-right-radius: $modal-card-head-radius + +.modal-card-title + color: $modal-card-title-color + flex-grow: 1 + flex-shrink: 0 + font-size: $modal-card-title-size + line-height: $modal-card-title-line-height + +.modal-card-foot + border-bottom-left-radius: $modal-card-foot-radius + border-bottom-right-radius: $modal-card-foot-radius + border-top: $modal-card-foot-border-top + .button + &:not(:last-child) + margin-right: 0.5em + +.modal-card-body + +overflow-touch + background-color: $modal-card-body-background-color + flex-grow: 1 + flex-shrink: 1 + overflow: auto + padding: $modal-card-body-padding diff --git a/docs/src/assets/bulma/components/navbar.sass b/docs/src/assets/bulma/components/navbar.sass new file mode 100644 index 00000000..664558f7 --- /dev/null +++ b/docs/src/assets/bulma/components/navbar.sass @@ -0,0 +1,443 @@ +$navbar-background-color: $scheme-main !default +$navbar-box-shadow-size: 0 2px 0 0 !default +$navbar-box-shadow-color: $background !default +$navbar-height: 3.25rem !default +$navbar-padding-vertical: 1rem !default +$navbar-padding-horizontal: 2rem !default +$navbar-z: 30 !default +$navbar-fixed-z: 30 !default + +$navbar-item-color: $text !default +$navbar-item-hover-color: $link !default +$navbar-item-hover-background-color: $scheme-main-bis !default +$navbar-item-active-color: $scheme-invert !default +$navbar-item-active-background-color: transparent !default +$navbar-item-img-max-height: 1.75rem !default + +$navbar-burger-color: $navbar-item-color !default + +$navbar-tab-hover-background-color: transparent !default +$navbar-tab-hover-border-bottom-color: $link !default +$navbar-tab-active-color: $link !default +$navbar-tab-active-background-color: transparent !default +$navbar-tab-active-border-bottom-color: $link !default +$navbar-tab-active-border-bottom-style: solid !default +$navbar-tab-active-border-bottom-width: 3px !default + +$navbar-dropdown-background-color: $scheme-main !default +$navbar-dropdown-border-top: 2px solid $border !default +$navbar-dropdown-offset: -4px !default +$navbar-dropdown-arrow: $link !default +$navbar-dropdown-radius: $radius-large !default +$navbar-dropdown-z: 20 !default + +$navbar-dropdown-boxed-radius: $radius-large !default +$navbar-dropdown-boxed-shadow: 0 8px 8px rgba($scheme-invert, 0.1), 0 0 0 1px rgba($scheme-invert, 0.1) !default + +$navbar-dropdown-item-hover-color: $scheme-invert !default +$navbar-dropdown-item-hover-background-color: $background !default +$navbar-dropdown-item-active-color: $link !default +$navbar-dropdown-item-active-background-color: $background !default + +$navbar-divider-background-color: $background !default +$navbar-divider-height: 2px !default + +$navbar-bottom-box-shadow-size: 0 -2px 0 0 !default + +$navbar-breakpoint: $desktop !default + +=navbar-fixed + left: 0 + position: fixed + right: 0 + z-index: $navbar-fixed-z + +.navbar + background-color: $navbar-background-color + min-height: $navbar-height + position: relative + z-index: $navbar-z + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + .navbar-brand + & > .navbar-item, + .navbar-link + color: $color-invert + & > a.navbar-item, + .navbar-link + &:focus, + &:hover, + &.is-active + background-color: darken($color, 5%) + color: $color-invert + .navbar-link + &::after + border-color: $color-invert + .navbar-burger + color: $color-invert + +from($navbar-breakpoint) + .navbar-start, + .navbar-end + & > .navbar-item, + .navbar-link + color: $color-invert + & > a.navbar-item, + .navbar-link + &:focus, + &:hover, + &.is-active + background-color: darken($color, 5%) + color: $color-invert + .navbar-link + &::after + border-color: $color-invert + .navbar-item.has-dropdown:focus .navbar-link, + .navbar-item.has-dropdown:hover .navbar-link, + .navbar-item.has-dropdown.is-active .navbar-link + background-color: darken($color, 5%) + color: $color-invert + .navbar-dropdown + a.navbar-item + &.is-active + background-color: $color + color: $color-invert + & > .container + align-items: stretch + display: flex + min-height: $navbar-height + width: 100% + &.has-shadow + box-shadow: $navbar-box-shadow-size $navbar-box-shadow-color + &.is-fixed-bottom, + &.is-fixed-top + +navbar-fixed + &.is-fixed-bottom + bottom: 0 + &.has-shadow + box-shadow: $navbar-bottom-box-shadow-size $navbar-box-shadow-color + &.is-fixed-top + top: 0 + +html, +body + &.has-navbar-fixed-top + padding-top: $navbar-height + &.has-navbar-fixed-bottom + padding-bottom: $navbar-height + +.navbar-brand, +.navbar-tabs + align-items: stretch + display: flex + flex-shrink: 0 + min-height: $navbar-height + +.navbar-brand + a.navbar-item + &:focus, + &:hover + background-color: transparent + +.navbar-tabs + +overflow-touch + max-width: 100vw + overflow-x: auto + overflow-y: hidden + +.navbar-burger + color: $navbar-burger-color + +hamburger($navbar-height) + margin-left: auto + +.navbar-menu + display: none + +.navbar-item, +.navbar-link + color: $navbar-item-color + display: block + line-height: 1.5 + padding: 0.5rem 0.75rem + position: relative + .icon + &:only-child + margin-left: -0.25rem + margin-right: -0.25rem + +a.navbar-item, +.navbar-link + cursor: pointer + &:focus, + &:focus-within, + &:hover, + &.is-active + background-color: $navbar-item-hover-background-color + color: $navbar-item-hover-color + +.navbar-item + display: block + flex-grow: 0 + flex-shrink: 0 + img + max-height: $navbar-item-img-max-height + &.has-dropdown + padding: 0 + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.is-tab + border-bottom: 1px solid transparent + min-height: $navbar-height + padding-bottom: calc(0.5rem - 1px) + &:focus, + &:hover + background-color: $navbar-tab-hover-background-color + border-bottom-color: $navbar-tab-hover-border-bottom-color + &.is-active + background-color: $navbar-tab-active-background-color + border-bottom-color: $navbar-tab-active-border-bottom-color + border-bottom-style: $navbar-tab-active-border-bottom-style + border-bottom-width: $navbar-tab-active-border-bottom-width + color: $navbar-tab-active-color + padding-bottom: calc(0.5rem - #{$navbar-tab-active-border-bottom-width}) + +.navbar-content + flex-grow: 1 + flex-shrink: 1 + +.navbar-link:not(.is-arrowless) + padding-right: 2.5em + &::after + @extend %arrow + border-color: $navbar-dropdown-arrow + margin-top: -0.375em + right: 1.125em + +.navbar-dropdown + font-size: 0.875rem + padding-bottom: 0.5rem + padding-top: 0.5rem + .navbar-item + padding-left: 1.5rem + padding-right: 1.5rem + +.navbar-divider + background-color: $navbar-divider-background-color + border: none + display: none + height: $navbar-divider-height + margin: 0.5rem 0 + ++until($navbar-breakpoint) + .navbar > .container + display: block + .navbar-brand, + .navbar-tabs + .navbar-item + align-items: center + display: flex + .navbar-link + &::after + display: none + .navbar-menu + background-color: $navbar-background-color + box-shadow: 0 8px 16px rgba($scheme-invert, 0.1) + padding: 0.5rem 0 + &.is-active + display: block + // Fixed navbar + .navbar + &.is-fixed-bottom-touch, + &.is-fixed-top-touch + +navbar-fixed + &.is-fixed-bottom-touch + bottom: 0 + &.has-shadow + box-shadow: 0 -2px 3px rgba($scheme-invert, 0.1) + &.is-fixed-top-touch + top: 0 + &.is-fixed-top, + &.is-fixed-top-touch + .navbar-menu + +overflow-touch + max-height: calc(100vh - #{$navbar-height}) + overflow: auto + html, + body + &.has-navbar-fixed-top-touch + padding-top: $navbar-height + &.has-navbar-fixed-bottom-touch + padding-bottom: $navbar-height + ++from($navbar-breakpoint) + .navbar, + .navbar-menu, + .navbar-start, + .navbar-end + align-items: stretch + display: flex + .navbar + min-height: $navbar-height + &.is-spaced + padding: $navbar-padding-vertical $navbar-padding-horizontal + .navbar-start, + .navbar-end + align-items: center + a.navbar-item, + .navbar-link + border-radius: $radius + &.is-transparent + a.navbar-item, + .navbar-link + &:focus, + &:hover, + &.is-active + background-color: transparent !important + .navbar-item.has-dropdown + &.is-active, + &.is-hoverable:focus, + &.is-hoverable:focus-within, + &.is-hoverable:hover + .navbar-link + background-color: transparent !important + .navbar-dropdown + a.navbar-item + &:focus, + &:hover + background-color: $navbar-dropdown-item-hover-background-color + color: $navbar-dropdown-item-hover-color + &.is-active + background-color: $navbar-dropdown-item-active-background-color + color: $navbar-dropdown-item-active-color + .navbar-burger + display: none + .navbar-item, + .navbar-link + align-items: center + display: flex + .navbar-item + display: flex + &.has-dropdown + align-items: stretch + &.has-dropdown-up + .navbar-link::after + transform: rotate(135deg) translate(0.25em, -0.25em) + .navbar-dropdown + border-bottom: $navbar-dropdown-border-top + border-radius: $navbar-dropdown-radius $navbar-dropdown-radius 0 0 + border-top: none + bottom: 100% + box-shadow: 0 -8px 8px rgba($scheme-invert, 0.1) + top: auto + &.is-active, + &.is-hoverable:focus, + &.is-hoverable:focus-within, + &.is-hoverable:hover + .navbar-dropdown + display: block + .navbar.is-spaced &, + &.is-boxed + opacity: 1 + pointer-events: auto + transform: translateY(0) + .navbar-menu + flex-grow: 1 + flex-shrink: 0 + .navbar-start + justify-content: flex-start + margin-right: auto + .navbar-end + justify-content: flex-end + margin-left: auto + .navbar-dropdown + background-color: $navbar-dropdown-background-color + border-bottom-left-radius: $navbar-dropdown-radius + border-bottom-right-radius: $navbar-dropdown-radius + border-top: $navbar-dropdown-border-top + box-shadow: 0 8px 8px rgba($scheme-invert, 0.1) + display: none + font-size: 0.875rem + left: 0 + min-width: 100% + position: absolute + top: 100% + z-index: $navbar-dropdown-z + .navbar-item + padding: 0.375rem 1rem + white-space: nowrap + a.navbar-item + padding-right: 3rem + &:focus, + &:hover + background-color: $navbar-dropdown-item-hover-background-color + color: $navbar-dropdown-item-hover-color + &.is-active + background-color: $navbar-dropdown-item-active-background-color + color: $navbar-dropdown-item-active-color + .navbar.is-spaced &, + &.is-boxed + border-radius: $navbar-dropdown-boxed-radius + border-top: none + box-shadow: $navbar-dropdown-boxed-shadow + display: block + opacity: 0 + pointer-events: none + top: calc(100% + (#{$navbar-dropdown-offset})) + transform: translateY(-5px) + transition-duration: $speed + transition-property: opacity, transform + &.is-right + left: auto + right: 0 + .navbar-divider + display: block + .navbar > .container, + .container > .navbar + .navbar-brand + margin-left: -.75rem + .navbar-menu + margin-right: -.75rem + // Fixed navbar + .navbar + &.is-fixed-bottom-desktop, + &.is-fixed-top-desktop + +navbar-fixed + &.is-fixed-bottom-desktop + bottom: 0 + &.has-shadow + box-shadow: 0 -2px 3px rgba($scheme-invert, 0.1) + &.is-fixed-top-desktop + top: 0 + html, + body + &.has-navbar-fixed-top-desktop + padding-top: $navbar-height + &.has-navbar-fixed-bottom-desktop + padding-bottom: $navbar-height + &.has-spaced-navbar-fixed-top + padding-top: $navbar-height + ($navbar-padding-vertical * 2) + &.has-spaced-navbar-fixed-bottom + padding-bottom: $navbar-height + ($navbar-padding-vertical * 2) + // Hover/Active states + a.navbar-item, + .navbar-link + &.is-active + color: $navbar-item-active-color + &.is-active:not(:focus):not(:hover) + background-color: $navbar-item-active-background-color + .navbar-item.has-dropdown + &:focus, + &:hover, + &.is-active + .navbar-link + background-color: $navbar-item-hover-background-color + +// Combination + +.hero + &.is-fullheight-with-navbar + min-height: calc(100vh - #{$navbar-height}) diff --git a/docs/src/assets/bulma/components/pagination.sass b/docs/src/assets/bulma/components/pagination.sass new file mode 100644 index 00000000..822c2e81 --- /dev/null +++ b/docs/src/assets/bulma/components/pagination.sass @@ -0,0 +1,150 @@ +$pagination-color: $text-strong !default +$pagination-border-color: $border !default +$pagination-margin: -0.25rem !default +$pagination-min-width: $control-height !default + +$pagination-item-font-size: 1em !default +$pagination-item-margin: 0.25rem !default +$pagination-item-padding-left: 0.5em !default +$pagination-item-padding-right: 0.5em !default + +$pagination-hover-color: $link-hover !default +$pagination-hover-border-color: $link-hover-border !default + +$pagination-focus-color: $link-focus !default +$pagination-focus-border-color: $link-focus-border !default + +$pagination-active-color: $link-active !default +$pagination-active-border-color: $link-active-border !default + +$pagination-disabled-color: $text-light !default +$pagination-disabled-background-color: $border !default +$pagination-disabled-border-color: $border !default + +$pagination-current-color: $link-invert !default +$pagination-current-background-color: $link !default +$pagination-current-border-color: $link !default + +$pagination-ellipsis-color: $grey-light !default + +$pagination-shadow-inset: inset 0 1px 2px rgba($scheme-invert, 0.2) + +.pagination + @extend %block + font-size: $size-normal + margin: $pagination-margin + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + &.is-rounded + .pagination-previous, + .pagination-next + padding-left: 1em + padding-right: 1em + border-radius: $radius-rounded + .pagination-link + border-radius: $radius-rounded + +.pagination, +.pagination-list + align-items: center + display: flex + justify-content: center + text-align: center + +.pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis + @extend %control + @extend %unselectable + font-size: $pagination-item-font-size + justify-content: center + margin: $pagination-item-margin + padding-left: $pagination-item-padding-left + padding-right: $pagination-item-padding-right + text-align: center + +.pagination-previous, +.pagination-next, +.pagination-link + border-color: $pagination-border-color + color: $pagination-color + min-width: $pagination-min-width + &:hover + border-color: $pagination-hover-border-color + color: $pagination-hover-color + &:focus + border-color: $pagination-focus-border-color + &:active + box-shadow: $pagination-shadow-inset + &[disabled] + background-color: $pagination-disabled-background-color + border-color: $pagination-disabled-border-color + box-shadow: none + color: $pagination-disabled-color + opacity: 0.5 + +.pagination-previous, +.pagination-next + padding-left: 0.75em + padding-right: 0.75em + white-space: nowrap + +.pagination-link + &.is-current + background-color: $pagination-current-background-color + border-color: $pagination-current-border-color + color: $pagination-current-color + +.pagination-ellipsis + color: $pagination-ellipsis-color + pointer-events: none + +.pagination-list + flex-wrap: wrap + ++mobile + .pagination + flex-wrap: wrap + .pagination-previous, + .pagination-next + flex-grow: 1 + flex-shrink: 1 + .pagination-list + li + flex-grow: 1 + flex-shrink: 1 + ++tablet + .pagination-list + flex-grow: 1 + flex-shrink: 1 + justify-content: flex-start + order: 1 + .pagination-previous + order: 2 + .pagination-next + order: 3 + .pagination + justify-content: space-between + &.is-centered + .pagination-previous + order: 1 + .pagination-list + justify-content: center + order: 2 + .pagination-next + order: 3 + &.is-right + .pagination-previous + order: 1 + .pagination-next + order: 2 + .pagination-list + justify-content: flex-end + order: 3 diff --git a/docs/src/assets/bulma/components/panel.sass b/docs/src/assets/bulma/components/panel.sass new file mode 100644 index 00000000..c7b14877 --- /dev/null +++ b/docs/src/assets/bulma/components/panel.sass @@ -0,0 +1,119 @@ +$panel-margin: $block-spacing !default +$panel-item-border: 1px solid $border-light !default +$panel-radius: $radius-large !default +$panel-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default + +$panel-heading-background-color: $border-light !default +$panel-heading-color: $text-strong !default +$panel-heading-line-height: 1.25 !default +$panel-heading-padding: 0.75em 1em !default +$panel-heading-radius: $radius !default +$panel-heading-size: 1.25em !default +$panel-heading-weight: $weight-bold !default + +$panel-tabs-font-size: 0.875em !default +$panel-tab-border-bottom: 1px solid $border !default +$panel-tab-active-border-bottom-color: $link-active-border !default +$panel-tab-active-color: $link-active !default + +$panel-list-item-color: $text !default +$panel-list-item-hover-color: $link !default + +$panel-block-color: $text-strong !default +$panel-block-hover-background-color: $background !default +$panel-block-active-border-left-color: $link !default +$panel-block-active-color: $link-active !default +$panel-block-active-icon-color: $link !default + +$panel-icon-color: $text-light !default +$panel-colors: $colors !default + +.panel + border-radius: $panel-radius + box-shadow: $panel-shadow + font-size: $size-normal + &:not(:last-child) + margin-bottom: $panel-margin + // Colors + @each $name, $components in $panel-colors + $color: nth($components, 1) + $color-invert: nth($components, 2) + &.is-#{$name} + .panel-heading + background-color: $color + color: $color-invert + .panel-tabs a.is-active + border-bottom-color: $color + .panel-block.is-active .panel-icon + color: $color + +.panel-tabs, +.panel-block + &:not(:last-child) + border-bottom: $panel-item-border + +.panel-heading + background-color: $panel-heading-background-color + border-radius: $panel-radius $panel-radius 0 0 + color: $panel-heading-color + font-size: $panel-heading-size + font-weight: $panel-heading-weight + line-height: $panel-heading-line-height + padding: $panel-heading-padding + +.panel-tabs + align-items: flex-end + display: flex + font-size: $panel-tabs-font-size + justify-content: center + a + border-bottom: $panel-tab-border-bottom + margin-bottom: -1px + padding: 0.5em + // Modifiers + &.is-active + border-bottom-color: $panel-tab-active-border-bottom-color + color: $panel-tab-active-color + +.panel-list + a + color: $panel-list-item-color + &:hover + color: $panel-list-item-hover-color + +.panel-block + align-items: center + color: $panel-block-color + display: flex + justify-content: flex-start + padding: 0.5em 0.75em + input[type="checkbox"] + margin-right: 0.75em + & > .control + flex-grow: 1 + flex-shrink: 1 + width: 100% + &.is-wrapped + flex-wrap: wrap + &.is-active + border-left-color: $panel-block-active-border-left-color + color: $panel-block-active-color + .panel-icon + color: $panel-block-active-icon-color + &:last-child + border-bottom-left-radius: $panel-radius + border-bottom-right-radius: $panel-radius + +a.panel-block, +label.panel-block + cursor: pointer + &:hover + background-color: $panel-block-hover-background-color + +.panel-icon + +fa(14px, 1em) + color: $panel-icon-color + margin-right: 0.75em + .fa + font-size: inherit + line-height: inherit diff --git a/docs/src/assets/bulma/components/tabs.sass b/docs/src/assets/bulma/components/tabs.sass new file mode 100644 index 00000000..8c28c257 --- /dev/null +++ b/docs/src/assets/bulma/components/tabs.sass @@ -0,0 +1,151 @@ +$tabs-border-bottom-color: $border !default +$tabs-border-bottom-style: solid !default +$tabs-border-bottom-width: 1px !default +$tabs-link-color: $text !default +$tabs-link-hover-border-bottom-color: $text-strong !default +$tabs-link-hover-color: $text-strong !default +$tabs-link-active-border-bottom-color: $link !default +$tabs-link-active-color: $link !default +$tabs-link-padding: 0.5em 1em !default + +$tabs-boxed-link-radius: $radius !default +$tabs-boxed-link-hover-background-color: $background !default +$tabs-boxed-link-hover-border-bottom-color: $border !default + +$tabs-boxed-link-active-background-color: $scheme-main !default +$tabs-boxed-link-active-border-color: $border !default +$tabs-boxed-link-active-border-bottom-color: transparent !default + +$tabs-toggle-link-border-color: $border !default +$tabs-toggle-link-border-style: solid !default +$tabs-toggle-link-border-width: 1px !default +$tabs-toggle-link-hover-background-color: $background !default +$tabs-toggle-link-hover-border-color: $border-hover !default +$tabs-toggle-link-radius: $radius !default +$tabs-toggle-link-active-background-color: $link !default +$tabs-toggle-link-active-border-color: $link !default +$tabs-toggle-link-active-color: $link-invert !default + +.tabs + @extend %block + +overflow-touch + @extend %unselectable + align-items: stretch + display: flex + font-size: $size-normal + justify-content: space-between + overflow: hidden + overflow-x: auto + white-space: nowrap + a + align-items: center + border-bottom-color: $tabs-border-bottom-color + border-bottom-style: $tabs-border-bottom-style + border-bottom-width: $tabs-border-bottom-width + color: $tabs-link-color + display: flex + justify-content: center + margin-bottom: -#{$tabs-border-bottom-width} + padding: $tabs-link-padding + vertical-align: top + &:hover + border-bottom-color: $tabs-link-hover-border-bottom-color + color: $tabs-link-hover-color + li + display: block + &.is-active + a + border-bottom-color: $tabs-link-active-border-bottom-color + color: $tabs-link-active-color + ul + align-items: center + border-bottom-color: $tabs-border-bottom-color + border-bottom-style: $tabs-border-bottom-style + border-bottom-width: $tabs-border-bottom-width + display: flex + flex-grow: 1 + flex-shrink: 0 + justify-content: flex-start + &.is-left + padding-right: 0.75em + &.is-center + flex: none + justify-content: center + padding-left: 0.75em + padding-right: 0.75em + &.is-right + justify-content: flex-end + padding-left: 0.75em + .icon + &:first-child + margin-right: 0.5em + &:last-child + margin-left: 0.5em + // Alignment + &.is-centered + ul + justify-content: center + &.is-right + ul + justify-content: flex-end + // Styles + &.is-boxed + a + border: 1px solid transparent + border-radius: $tabs-boxed-link-radius $tabs-boxed-link-radius 0 0 + &:hover + background-color: $tabs-boxed-link-hover-background-color + border-bottom-color: $tabs-boxed-link-hover-border-bottom-color + li + &.is-active + a + background-color: $tabs-boxed-link-active-background-color + border-color: $tabs-boxed-link-active-border-color + border-bottom-color: $tabs-boxed-link-active-border-bottom-color !important + &.is-fullwidth + li + flex-grow: 1 + flex-shrink: 0 + &.is-toggle + a + border-color: $tabs-toggle-link-border-color + border-style: $tabs-toggle-link-border-style + border-width: $tabs-toggle-link-border-width + margin-bottom: 0 + position: relative + &:hover + background-color: $tabs-toggle-link-hover-background-color + border-color: $tabs-toggle-link-hover-border-color + z-index: 2 + li + & + li + margin-left: -#{$tabs-toggle-link-border-width} + &:first-child a + border-radius: $tabs-toggle-link-radius 0 0 $tabs-toggle-link-radius + &:last-child a + border-radius: 0 $tabs-toggle-link-radius $tabs-toggle-link-radius 0 + &.is-active + a + background-color: $tabs-toggle-link-active-background-color + border-color: $tabs-toggle-link-active-border-color + color: $tabs-toggle-link-active-color + z-index: 1 + ul + border-bottom: none + &.is-toggle-rounded + li + &:first-child a + border-bottom-left-radius: $radius-rounded + border-top-left-radius: $radius-rounded + padding-left: 1.25em + &:last-child a + border-bottom-right-radius: $radius-rounded + border-top-right-radius: $radius-rounded + padding-right: 1.25em + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large diff --git a/docs/src/assets/bulma/elements/_all.sass b/docs/src/assets/bulma/elements/_all.sass new file mode 100644 index 00000000..7490c00d --- /dev/null +++ b/docs/src/assets/bulma/elements/_all.sass @@ -0,0 +1,15 @@ +@charset "utf-8" + +@import "box.sass" +@import "button.sass" +@import "container.sass" +@import "content.sass" +@import "icon.sass" +@import "image.sass" +@import "notification.sass" +@import "progress.sass" +@import "table.sass" +@import "tag.sass" +@import "title.sass" + +@import "other.sass" diff --git a/docs/src/assets/bulma/elements/box.sass b/docs/src/assets/bulma/elements/box.sass new file mode 100644 index 00000000..2fd18d49 --- /dev/null +++ b/docs/src/assets/bulma/elements/box.sass @@ -0,0 +1,24 @@ +$box-color: $text !default +$box-background-color: $scheme-main !default +$box-radius: $radius-large !default +$box-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default +$box-padding: 1.25rem !default + +$box-link-hover-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0 0 1px $link !default +$box-link-active-shadow: inset 0 1px 2px rgba($scheme-invert, 0.2), 0 0 0 1px $link !default + +.box + @extend %block + background-color: $box-background-color + border-radius: $box-radius + box-shadow: $box-shadow + color: $box-color + display: block + padding: $box-padding + +a.box + &:hover, + &:focus + box-shadow: $box-link-hover-shadow + &:active + box-shadow: $box-link-active-shadow diff --git a/docs/src/assets/bulma/elements/button.sass b/docs/src/assets/bulma/elements/button.sass new file mode 100644 index 00000000..df5417c8 --- /dev/null +++ b/docs/src/assets/bulma/elements/button.sass @@ -0,0 +1,323 @@ +$button-color: $text-strong !default +$button-background-color: $scheme-main !default +$button-family: false !default + +$button-border-color: $border !default +$button-border-width: $control-border-width !default + +$button-padding-vertical: calc(0.5em - #{$button-border-width}) !default +$button-padding-horizontal: 1em !default + +$button-hover-color: $link-hover !default +$button-hover-border-color: $link-hover-border !default + +$button-focus-color: $link-focus !default +$button-focus-border-color: $link-focus-border !default +$button-focus-box-shadow-size: 0 0 0 0.125em !default +$button-focus-box-shadow-color: bulmaRgba($link, 0.25) !default + +$button-active-color: $link-active !default +$button-active-border-color: $link-active-border !default + +$button-text-color: $text !default +$button-text-decoration: underline !default +$button-text-hover-background-color: $background !default +$button-text-hover-color: $text-strong !default + +$button-disabled-background-color: $scheme-main !default +$button-disabled-border-color: $border !default +$button-disabled-shadow: none !default +$button-disabled-opacity: 0.5 !default + +$button-static-color: $text-light !default +$button-static-background-color: $scheme-main-ter !default +$button-static-border-color: $border !default + +// The button sizes use mixins so they can be used at different breakpoints +=button-small + border-radius: $radius-small + font-size: $size-small +=button-normal + font-size: $size-normal +=button-medium + font-size: $size-medium +=button-large + font-size: $size-large + +.button + @extend %control + @extend %unselectable + background-color: $button-background-color + border-color: $button-border-color + border-width: $button-border-width + color: $button-color + cursor: pointer + @if $button-family + font-family: $button-family + justify-content: center + padding-bottom: $button-padding-vertical + padding-left: $button-padding-horizontal + padding-right: $button-padding-horizontal + padding-top: $button-padding-vertical + text-align: center + white-space: nowrap + strong + color: inherit + .icon + &, + &.is-small, + &.is-medium, + &.is-large + height: 1.5em + width: 1.5em + &:first-child:not(:last-child) + margin-left: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + margin-right: $button-padding-horizontal / 4 + &:last-child:not(:first-child) + margin-left: $button-padding-horizontal / 4 + margin-right: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + &:first-child:last-child + margin-left: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + margin-right: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + // States + &:hover, + &.is-hovered + border-color: $button-hover-border-color + color: $button-hover-color + &:focus, + &.is-focused + border-color: $button-focus-border-color + color: $button-focus-color + &:not(:active) + box-shadow: $button-focus-box-shadow-size $button-focus-box-shadow-color + &:active, + &.is-active + border-color: $button-active-border-color + color: $button-active-color + // Colors + &.is-text + background-color: transparent + border-color: transparent + color: $button-text-color + text-decoration: $button-text-decoration + &:hover, + &.is-hovered, + &:focus, + &.is-focused + background-color: $button-text-hover-background-color + color: $button-text-hover-color + &:active, + &.is-active + background-color: darken($button-text-hover-background-color, 5%) + color: $button-text-hover-color + &[disabled], + fieldset[disabled] & + background-color: transparent + border-color: transparent + box-shadow: none + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + border-color: transparent + color: $color-invert + &:hover, + &.is-hovered + background-color: darken($color, 2.5%) + border-color: transparent + color: $color-invert + &:focus, + &.is-focused + border-color: transparent + color: $color-invert + &:not(:active) + box-shadow: $button-focus-box-shadow-size rgba($color, 0.25) + &:active, + &.is-active + background-color: darken($color, 5%) + border-color: transparent + color: $color-invert + &[disabled], + fieldset[disabled] & + background-color: $color + border-color: transparent + box-shadow: none + &.is-inverted + background-color: $color-invert + color: $color + &:hover, + &.is-hovered + background-color: darken($color-invert, 5%) + &[disabled], + fieldset[disabled] & + background-color: $color-invert + border-color: transparent + box-shadow: none + color: $color + &.is-loading + &::after + border-color: transparent transparent $color-invert $color-invert !important + &.is-outlined + background-color: transparent + border-color: $color + color: $color + &:hover, + &.is-hovered, + &:focus, + &.is-focused + background-color: $color + border-color: $color + color: $color-invert + &.is-loading + &::after + border-color: transparent transparent $color $color !important + &:hover, + &.is-hovered, + &:focus, + &.is-focused + &::after + border-color: transparent transparent $color-invert $color-invert !important + &[disabled], + fieldset[disabled] & + background-color: transparent + border-color: $color + box-shadow: none + color: $color + &.is-inverted.is-outlined + background-color: transparent + border-color: $color-invert + color: $color-invert + &:hover, + &.is-hovered, + &:focus, + &.is-focused + background-color: $color-invert + color: $color + &.is-loading + &:hover, + &.is-hovered, + &:focus, + &.is-focused + &::after + border-color: transparent transparent $color $color !important + &[disabled], + fieldset[disabled] & + background-color: transparent + border-color: $color-invert + box-shadow: none + color: $color-invert + // If light and dark colors are provided + @if length($pair) >= 4 + $color-light: nth($pair, 3) + $color-dark: nth($pair, 4) + &.is-light + background-color: $color-light + color: $color-dark + &:hover, + &.is-hovered + background-color: darken($color-light, 2.5%) + border-color: transparent + color: $color-dark + &:active, + &.is-active + background-color: darken($color-light, 5%) + border-color: transparent + color: $color-dark + // Sizes + &.is-small + +button-small + &.is-normal + +button-normal + &.is-medium + +button-medium + &.is-large + +button-large + // Modifiers + &[disabled], + fieldset[disabled] & + background-color: $button-disabled-background-color + border-color: $button-disabled-border-color + box-shadow: $button-disabled-shadow + opacity: $button-disabled-opacity + &.is-fullwidth + display: flex + width: 100% + &.is-loading + color: transparent !important + pointer-events: none + &::after + @extend %loader + +center(1em) + position: absolute !important + &.is-static + background-color: $button-static-background-color + border-color: $button-static-border-color + color: $button-static-color + box-shadow: none + pointer-events: none + &.is-rounded + border-radius: $radius-rounded + padding-left: calc(#{$button-padding-horizontal} + 0.25em) + padding-right: calc(#{$button-padding-horizontal} + 0.25em) + +.buttons + align-items: center + display: flex + flex-wrap: wrap + justify-content: flex-start + .button + margin-bottom: 0.5rem + &:not(:last-child):not(.is-fullwidth) + margin-right: 0.5rem + &:last-child + margin-bottom: -0.5rem + &:not(:last-child) + margin-bottom: 1rem + // Sizes + &.are-small + .button:not(.is-normal):not(.is-medium):not(.is-large) + +button-small + &.are-medium + .button:not(.is-small):not(.is-normal):not(.is-large) + +button-medium + &.are-large + .button:not(.is-small):not(.is-normal):not(.is-medium) + +button-large + &.has-addons + .button + &:not(:first-child) + border-bottom-left-radius: 0 + border-top-left-radius: 0 + &:not(:last-child) + border-bottom-right-radius: 0 + border-top-right-radius: 0 + margin-right: -1px + &:last-child + margin-right: 0 + &:hover, + &.is-hovered + z-index: 2 + &:focus, + &.is-focused, + &:active, + &.is-active, + &.is-selected + z-index: 3 + &:hover + z-index: 4 + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.is-centered + justify-content: center + &:not(.has-addons) + .button:not(.is-fullwidth) + margin-left: 0.25rem + margin-right: 0.25rem + &.is-right + justify-content: flex-end + &:not(.has-addons) + .button:not(.is-fullwidth) + margin-left: 0.25rem + margin-right: 0.25rem diff --git a/docs/src/assets/bulma/elements/container.sass b/docs/src/assets/bulma/elements/container.sass new file mode 100644 index 00000000..d88eb94a --- /dev/null +++ b/docs/src/assets/bulma/elements/container.sass @@ -0,0 +1,24 @@ +$container-offset: (2 * $gap) !default + +.container + flex-grow: 1 + margin: 0 auto + position: relative + width: auto + &.is-fluid + max-width: none + padding-left: $gap + padding-right: $gap + width: 100% + +desktop + max-width: $desktop - $container-offset + +until-widescreen + &.is-widescreen + max-width: $widescreen - $container-offset + +until-fullhd + &.is-fullhd + max-width: $fullhd - $container-offset + +widescreen + max-width: $widescreen - $container-offset + +fullhd + max-width: $fullhd - $container-offset diff --git a/docs/src/assets/bulma/elements/content.sass b/docs/src/assets/bulma/elements/content.sass new file mode 100644 index 00000000..001419ab --- /dev/null +++ b/docs/src/assets/bulma/elements/content.sass @@ -0,0 +1,155 @@ +$content-heading-color: $text-strong !default +$content-heading-weight: $weight-semibold !default +$content-heading-line-height: 1.125 !default + +$content-blockquote-background-color: $background !default +$content-blockquote-border-left: 5px solid $border !default +$content-blockquote-padding: 1.25em 1.5em !default + +$content-pre-padding: 1.25em 1.5em !default + +$content-table-cell-border: 1px solid $border !default +$content-table-cell-border-width: 0 0 1px !default +$content-table-cell-padding: 0.5em 0.75em !default +$content-table-cell-heading-color: $text-strong !default +$content-table-head-cell-border-width: 0 0 2px !default +$content-table-head-cell-color: $text-strong !default +$content-table-foot-cell-border-width: 2px 0 0 !default +$content-table-foot-cell-color: $text-strong !default + +.content + @extend %block + // Inline + li + li + margin-top: 0.25em + // Block + p, + dl, + ol, + ul, + blockquote, + pre, + table + &:not(:last-child) + margin-bottom: 1em + h1, + h2, + h3, + h4, + h5, + h6 + color: $content-heading-color + font-weight: $content-heading-weight + line-height: $content-heading-line-height + h1 + font-size: 2em + margin-bottom: 0.5em + &:not(:first-child) + margin-top: 1em + h2 + font-size: 1.75em + margin-bottom: 0.5714em + &:not(:first-child) + margin-top: 1.1428em + h3 + font-size: 1.5em + margin-bottom: 0.6666em + &:not(:first-child) + margin-top: 1.3333em + h4 + font-size: 1.25em + margin-bottom: 0.8em + h5 + font-size: 1.125em + margin-bottom: 0.8888em + h6 + font-size: 1em + margin-bottom: 1em + blockquote + background-color: $content-blockquote-background-color + border-left: $content-blockquote-border-left + padding: $content-blockquote-padding + ol + list-style-position: outside + margin-left: 2em + margin-top: 1em + &:not([type]) + list-style-type: decimal + &.is-lower-alpha + list-style-type: lower-alpha + &.is-lower-roman + list-style-type: lower-roman + &.is-upper-alpha + list-style-type: upper-alpha + &.is-upper-roman + list-style-type: upper-roman + ul + list-style: disc outside + margin-left: 2em + margin-top: 1em + ul + list-style-type: circle + margin-top: 0.5em + ul + list-style-type: square + dd + margin-left: 2em + figure + margin-left: 2em + margin-right: 2em + text-align: center + &:not(:first-child) + margin-top: 2em + &:not(:last-child) + margin-bottom: 2em + img + display: inline-block + figcaption + font-style: italic + pre + +overflow-touch + overflow-x: auto + padding: $content-pre-padding + white-space: pre + word-wrap: normal + sup, + sub + font-size: 75% + table + width: 100% + td, + th + border: $content-table-cell-border + border-width: $content-table-cell-border-width + padding: $content-table-cell-padding + vertical-align: top + th + color: $content-table-cell-heading-color + &:not([align]) + text-align: left + thead + td, + th + border-width: $content-table-head-cell-border-width + color: $content-table-head-cell-color + tfoot + td, + th + border-width: $content-table-foot-cell-border-width + color: $content-table-foot-cell-color + tbody + tr + &:last-child + td, + th + border-bottom-width: 0 + .tabs + li + li + margin-top: 0 + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large diff --git a/docs/src/assets/bulma/elements/form.sass b/docs/src/assets/bulma/elements/form.sass new file mode 100644 index 00000000..3122dc4c --- /dev/null +++ b/docs/src/assets/bulma/elements/form.sass @@ -0,0 +1 @@ +@warn "The form.sass file is DEPRECATED. It has moved into its own /form folder. Please import sass/form/_all instead." diff --git a/docs/src/assets/bulma/elements/icon.sass b/docs/src/assets/bulma/elements/icon.sass new file mode 100644 index 00000000..988546c7 --- /dev/null +++ b/docs/src/assets/bulma/elements/icon.sass @@ -0,0 +1,21 @@ +$icon-dimensions: 1.5rem !default +$icon-dimensions-small: 1rem !default +$icon-dimensions-medium: 2rem !default +$icon-dimensions-large: 3rem !default + +.icon + align-items: center + display: inline-flex + justify-content: center + height: $icon-dimensions + width: $icon-dimensions + // Sizes + &.is-small + height: $icon-dimensions-small + width: $icon-dimensions-small + &.is-medium + height: $icon-dimensions-medium + width: $icon-dimensions-medium + &.is-large + height: $icon-dimensions-large + width: $icon-dimensions-large diff --git a/docs/src/assets/bulma/elements/image.sass b/docs/src/assets/bulma/elements/image.sass new file mode 100644 index 00000000..7547abcf --- /dev/null +++ b/docs/src/assets/bulma/elements/image.sass @@ -0,0 +1,71 @@ +$dimensions: 16 24 32 48 64 96 128 !default + +.image + display: block + position: relative + img + display: block + height: auto + width: 100% + &.is-rounded + border-radius: $radius-rounded + &.is-fullwidth + width: 100% + // Ratio + &.is-square, + &.is-1by1, + &.is-5by4, + &.is-4by3, + &.is-3by2, + &.is-5by3, + &.is-16by9, + &.is-2by1, + &.is-3by1, + &.is-4by5, + &.is-3by4, + &.is-2by3, + &.is-3by5, + &.is-9by16, + &.is-1by2, + &.is-1by3 + img, + .has-ratio + @extend %overlay + height: 100% + width: 100% + &.is-square, + &.is-1by1 + padding-top: 100% + &.is-5by4 + padding-top: 80% + &.is-4by3 + padding-top: 75% + &.is-3by2 + padding-top: 66.6666% + &.is-5by3 + padding-top: 60% + &.is-16by9 + padding-top: 56.25% + &.is-2by1 + padding-top: 50% + &.is-3by1 + padding-top: 33.3333% + &.is-4by5 + padding-top: 125% + &.is-3by4 + padding-top: 133.3333% + &.is-2by3 + padding-top: 150% + &.is-3by5 + padding-top: 166.6666% + &.is-9by16 + padding-top: 177.7777% + &.is-1by2 + padding-top: 200% + &.is-1by3 + padding-top: 300% + // Sizes + @each $dimension in $dimensions + &.is-#{$dimension}x#{$dimension} + height: $dimension * 1px + width: $dimension * 1px diff --git a/docs/src/assets/bulma/elements/notification.sass b/docs/src/assets/bulma/elements/notification.sass new file mode 100644 index 00000000..32a0ee13 --- /dev/null +++ b/docs/src/assets/bulma/elements/notification.sass @@ -0,0 +1,43 @@ +$notification-background-color: $background !default +$notification-code-background-color: $scheme-main !default +$notification-radius: $radius !default +$notification-padding: 1.25rem 2.5rem 1.25rem 1.5rem !default + +.notification + @extend %block + background-color: $notification-background-color + border-radius: $notification-radius + padding: $notification-padding + position: relative + a:not(.button):not(.dropdown-item) + color: currentColor + text-decoration: underline + strong + color: currentColor + code, + pre + background: $notification-code-background-color + pre code + background: transparent + & > .delete + position: absolute + right: 0.5rem + top: 0.5rem + .title, + .subtitle, + .content + color: currentColor + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + // If light and dark colors are provided + @if length($pair) >= 4 + $color-light: nth($pair, 3) + $color-dark: nth($pair, 4) + &.is-light + background-color: $color-light + color: $color-dark diff --git a/docs/src/assets/bulma/elements/other.sass b/docs/src/assets/bulma/elements/other.sass new file mode 100644 index 00000000..5725617c --- /dev/null +++ b/docs/src/assets/bulma/elements/other.sass @@ -0,0 +1,39 @@ +.block + @extend %block + +.delete + @extend %delete + +.heading + display: block + font-size: 11px + letter-spacing: 1px + margin-bottom: 5px + text-transform: uppercase + +.highlight + @extend %block + font-weight: $weight-normal + max-width: 100% + overflow: hidden + padding: 0 + pre + overflow: auto + max-width: 100% + +.loader + @extend %loader + +.number + align-items: center + background-color: $background + border-radius: $radius-rounded + display: inline-flex + font-size: $size-medium + height: 2em + justify-content: center + margin-right: 1.5rem + min-width: 2.5em + padding: 0.25rem 0.5rem + text-align: center + vertical-align: top diff --git a/docs/src/assets/bulma/elements/progress.sass b/docs/src/assets/bulma/elements/progress.sass new file mode 100644 index 00000000..bb43bb60 --- /dev/null +++ b/docs/src/assets/bulma/elements/progress.sass @@ -0,0 +1,67 @@ +$progress-bar-background-color: $border-light !default +$progress-value-background-color: $text !default +$progress-border-radius: $radius-rounded !default + +$progress-indeterminate-duration: 1.5s !default + +.progress + @extend %block + -moz-appearance: none + -webkit-appearance: none + border: none + border-radius: $progress-border-radius + display: block + height: $size-normal + overflow: hidden + padding: 0 + width: 100% + &::-webkit-progress-bar + background-color: $progress-bar-background-color + &::-webkit-progress-value + background-color: $progress-value-background-color + &::-moz-progress-bar + background-color: $progress-value-background-color + &::-ms-fill + background-color: $progress-value-background-color + border: none + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + &::-webkit-progress-value + background-color: $color + &::-moz-progress-bar + background-color: $color + &::-ms-fill + background-color: $color + &:indeterminate + background-image: linear-gradient(to right, $color 30%, $progress-bar-background-color 30%) + + &:indeterminate + animation-duration: $progress-indeterminate-duration + animation-iteration-count: infinite + animation-name: moveIndeterminate + animation-timing-function: linear + background-color: $progress-bar-background-color + background-image: linear-gradient(to right, $text 30%, $progress-bar-background-color 30%) + background-position: top left + background-repeat: no-repeat + background-size: 150% 150% + &::-webkit-progress-bar + background-color: transparent + &::-moz-progress-bar + background-color: transparent + + // Sizes + &.is-small + height: $size-small + &.is-medium + height: $size-medium + &.is-large + height: $size-large + +@keyframes moveIndeterminate + from + background-position: 200% 0 + to + background-position: -200% 0 diff --git a/docs/src/assets/bulma/elements/table.sass b/docs/src/assets/bulma/elements/table.sass new file mode 100644 index 00000000..2e6036ad --- /dev/null +++ b/docs/src/assets/bulma/elements/table.sass @@ -0,0 +1,127 @@ +$table-color: $text-strong !default +$table-background-color: $scheme-main !default + +$table-cell-border: 1px solid $border !default +$table-cell-border-width: 0 0 1px !default +$table-cell-padding: 0.5em 0.75em !default +$table-cell-heading-color: $text-strong !default + +$table-head-cell-border-width: 0 0 2px !default +$table-head-cell-color: $text-strong !default +$table-foot-cell-border-width: 2px 0 0 !default +$table-foot-cell-color: $text-strong !default + +$table-head-background-color: transparent !default +$table-body-background-color: transparent !default +$table-foot-background-color: transparent !default + +$table-row-hover-background-color: $scheme-main-bis !default + +$table-row-active-background-color: $primary !default +$table-row-active-color: $primary-invert !default + +$table-striped-row-even-background-color: $scheme-main-bis !default +$table-striped-row-even-hover-background-color: $scheme-main-ter !default + +.table + @extend %block + background-color: $table-background-color + color: $table-color + td, + th + border: $table-cell-border + border-width: $table-cell-border-width + padding: $table-cell-padding + vertical-align: top + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + border-color: $color + color: $color-invert + // Modifiers + &.is-narrow + white-space: nowrap + width: 1% + &.is-selected + background-color: $table-row-active-background-color + color: $table-row-active-color + a, + strong + color: currentColor + th + color: $table-cell-heading-color + &:not([align]) + text-align: left + tr + &.is-selected + background-color: $table-row-active-background-color + color: $table-row-active-color + a, + strong + color: currentColor + td, + th + border-color: $table-row-active-color + color: currentColor + thead + background-color: $table-head-background-color + td, + th + border-width: $table-head-cell-border-width + color: $table-head-cell-color + tfoot + background-color: $table-foot-background-color + td, + th + border-width: $table-foot-cell-border-width + color: $table-foot-cell-color + tbody + background-color: $table-body-background-color + tr + &:last-child + td, + th + border-bottom-width: 0 + // Modifiers + &.is-bordered + td, + th + border-width: 1px + tr + &:last-child + td, + th + border-bottom-width: 1px + &.is-fullwidth + width: 100% + &.is-hoverable + tbody + tr:not(.is-selected) + &:hover + background-color: $table-row-hover-background-color + &.is-striped + tbody + tr:not(.is-selected) + &:hover + background-color: $table-row-hover-background-color + &:nth-child(even) + background-color: $table-striped-row-even-hover-background-color + &.is-narrow + td, + th + padding: 0.25em 0.5em + &.is-striped + tbody + tr:not(.is-selected) + &:nth-child(even) + background-color: $table-striped-row-even-background-color + +.table-container + @extend %block + +overflow-touch + overflow: auto + overflow-y: hidden + max-width: 100% diff --git a/docs/src/assets/bulma/elements/tag.sass b/docs/src/assets/bulma/elements/tag.sass new file mode 100644 index 00000000..e0fb89ef --- /dev/null +++ b/docs/src/assets/bulma/elements/tag.sass @@ -0,0 +1,128 @@ +$tag-background-color: $background !default +$tag-color: $text !default +$tag-radius: $radius !default +$tag-delete-margin: 1px !default + +.tags + align-items: center + display: flex + flex-wrap: wrap + justify-content: flex-start + .tag + margin-bottom: 0.5rem + &:not(:last-child) + margin-right: 0.5rem + &:last-child + margin-bottom: -0.5rem + &:not(:last-child) + margin-bottom: 1rem + // Sizes + &.are-medium + .tag:not(.is-normal):not(.is-large) + font-size: $size-normal + &.are-large + .tag:not(.is-normal):not(.is-medium) + font-size: $size-medium + &.is-centered + justify-content: center + .tag + margin-right: 0.25rem + margin-left: 0.25rem + &.is-right + justify-content: flex-end + .tag + &:not(:first-child) + margin-left: 0.5rem + &:not(:last-child) + margin-right: 0 + &.has-addons + .tag + margin-right: 0 + &:not(:first-child) + margin-left: 0 + border-bottom-left-radius: 0 + border-top-left-radius: 0 + &:not(:last-child) + border-bottom-right-radius: 0 + border-top-right-radius: 0 + +.tag:not(body) + align-items: center + background-color: $tag-background-color + border-radius: $tag-radius + color: $tag-color + display: inline-flex + font-size: $size-small + height: 2em + justify-content: center + line-height: 1.5 + padding-left: 0.75em + padding-right: 0.75em + white-space: nowrap + .delete + margin-left: 0.25rem + margin-right: -0.375rem + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + // If a light and dark colors are provided + @if length($pair) > 3 + $color-light: nth($pair, 3) + $color-dark: nth($pair, 4) + &.is-light + background-color: $color-light + color: $color-dark + // Sizes + &.is-normal + font-size: $size-small + &.is-medium + font-size: $size-normal + &.is-large + font-size: $size-medium + .icon + &:first-child:not(:last-child) + margin-left: -0.375em + margin-right: 0.1875em + &:last-child:not(:first-child) + margin-left: 0.1875em + margin-right: -0.375em + &:first-child:last-child + margin-left: -0.375em + margin-right: -0.375em + // Modifiers + &.is-delete + margin-left: $tag-delete-margin + padding: 0 + position: relative + width: 2em + &::before, + &::after + background-color: currentColor + content: "" + display: block + left: 50% + position: absolute + top: 50% + transform: translateX(-50%) translateY(-50%) rotate(45deg) + transform-origin: center center + &::before + height: 1px + width: 50% + &::after + height: 50% + width: 1px + &:hover, + &:focus + background-color: darken($tag-background-color, 5%) + &:active + background-color: darken($tag-background-color, 10%) + &.is-rounded + border-radius: $radius-rounded + +a.tag + &:hover + text-decoration: underline diff --git a/docs/src/assets/bulma/elements/title.sass b/docs/src/assets/bulma/elements/title.sass new file mode 100644 index 00000000..fa9947dd --- /dev/null +++ b/docs/src/assets/bulma/elements/title.sass @@ -0,0 +1,70 @@ +$title-color: $text-strong !default +$title-family: false !default +$title-size: $size-3 !default +$title-weight: $weight-semibold !default +$title-line-height: 1.125 !default +$title-strong-color: inherit !default +$title-strong-weight: inherit !default +$title-sub-size: 0.75em !default +$title-sup-size: 0.75em !default + +$subtitle-color: $text !default +$subtitle-family: false !default +$subtitle-size: $size-5 !default +$subtitle-weight: $weight-normal !default +$subtitle-line-height: 1.25 !default +$subtitle-strong-color: $text-strong !default +$subtitle-strong-weight: $weight-semibold !default +$subtitle-negative-margin: -1.25rem !default + +.title, +.subtitle + @extend %block + word-break: break-word + em, + span + font-weight: inherit + sub + font-size: $title-sub-size + sup + font-size: $title-sup-size + .tag + vertical-align: middle + +.title + color: $title-color + @if $title-family + font-family: $title-family + font-size: $title-size + font-weight: $title-weight + line-height: $title-line-height + strong + color: $title-strong-color + font-weight: $title-strong-weight + & + .highlight + margin-top: -0.75rem + &:not(.is-spaced) + .subtitle + margin-top: $subtitle-negative-margin + // Sizes + @each $size in $sizes + $i: index($sizes, $size) + &.is-#{$i} + font-size: $size + +.subtitle + color: $subtitle-color + @if $subtitle-family + font-family: $subtitle-family + font-size: $subtitle-size + font-weight: $subtitle-weight + line-height: $subtitle-line-height + strong + color: $subtitle-strong-color + font-weight: $subtitle-strong-weight + &:not(.is-spaced) + .title + margin-top: $subtitle-negative-margin + // Sizes + @each $size in $sizes + $i: index($sizes, $size) + &.is-#{$i} + font-size: $size diff --git a/docs/src/assets/bulma/form/_all.sass b/docs/src/assets/bulma/form/_all.sass new file mode 100644 index 00000000..d9a2b955 --- /dev/null +++ b/docs/src/assets/bulma/form/_all.sass @@ -0,0 +1,8 @@ +@charset "utf-8" + +@import "shared.sass" +@import "input-textarea.sass" +@import "checkbox-radio.sass" +@import "select.sass" +@import "file.sass" +@import "tools.sass" diff --git a/docs/src/assets/bulma/form/checkbox-radio.sass b/docs/src/assets/bulma/form/checkbox-radio.sass new file mode 100644 index 00000000..d9f3ff0c --- /dev/null +++ b/docs/src/assets/bulma/form/checkbox-radio.sass @@ -0,0 +1,21 @@ +%checkbox-radio + cursor: pointer + display: inline-block + line-height: 1.25 + position: relative + input + cursor: pointer + &:hover + color: $input-hover-color + &[disabled], + fieldset[disabled] & + color: $input-disabled-color + cursor: not-allowed + +.checkbox + @extend %checkbox-radio + +.radio + @extend %checkbox-radio + & + .radio + margin-left: 0.5em diff --git a/docs/src/assets/bulma/form/file.sass b/docs/src/assets/bulma/form/file.sass new file mode 100644 index 00000000..41cc0215 --- /dev/null +++ b/docs/src/assets/bulma/form/file.sass @@ -0,0 +1,180 @@ +$file-border-color: $border !default +$file-radius: $radius !default + +$file-cta-background-color: $scheme-main-ter !default +$file-cta-color: $text !default +$file-cta-hover-color: $text-strong !default +$file-cta-active-color: $text-strong !default + +$file-name-border-color: $border !default +$file-name-border-style: solid !default +$file-name-border-width: 1px 1px 1px 0 !default +$file-name-max-width: 16em !default + +.file + @extend %unselectable + align-items: stretch + display: flex + justify-content: flex-start + position: relative + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + .file-cta + background-color: $color + border-color: transparent + color: $color-invert + &:hover, + &.is-hovered + .file-cta + background-color: darken($color, 2.5%) + border-color: transparent + color: $color-invert + &:focus, + &.is-focused + .file-cta + border-color: transparent + box-shadow: 0 0 0.5em rgba($color, 0.25) + color: $color-invert + &:active, + &.is-active + .file-cta + background-color: darken($color, 5%) + border-color: transparent + color: $color-invert + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + .file-icon + .fa + font-size: 21px + &.is-large + font-size: $size-large + .file-icon + .fa + font-size: 28px + // Modifiers + &.has-name + .file-cta + border-bottom-right-radius: 0 + border-top-right-radius: 0 + .file-name + border-bottom-left-radius: 0 + border-top-left-radius: 0 + &.is-empty + .file-cta + border-radius: $file-radius + .file-name + display: none + &.is-boxed + .file-label + flex-direction: column + .file-cta + flex-direction: column + height: auto + padding: 1em 3em + .file-name + border-width: 0 1px 1px + .file-icon + height: 1.5em + width: 1.5em + .fa + font-size: 21px + &.is-small + .file-icon .fa + font-size: 14px + &.is-medium + .file-icon .fa + font-size: 28px + &.is-large + .file-icon .fa + font-size: 35px + &.has-name + .file-cta + border-radius: $file-radius $file-radius 0 0 + .file-name + border-radius: 0 0 $file-radius $file-radius + border-width: 0 1px 1px + &.is-centered + justify-content: center + &.is-fullwidth + .file-label + width: 100% + .file-name + flex-grow: 1 + max-width: none + &.is-right + justify-content: flex-end + .file-cta + border-radius: 0 $file-radius $file-radius 0 + .file-name + border-radius: $file-radius 0 0 $file-radius + border-width: 1px 0 1px 1px + order: -1 + +.file-label + align-items: stretch + display: flex + cursor: pointer + justify-content: flex-start + overflow: hidden + position: relative + &:hover + .file-cta + background-color: darken($file-cta-background-color, 2.5%) + color: $file-cta-hover-color + .file-name + border-color: darken($file-name-border-color, 2.5%) + &:active + .file-cta + background-color: darken($file-cta-background-color, 5%) + color: $file-cta-active-color + .file-name + border-color: darken($file-name-border-color, 5%) + +.file-input + height: 100% + left: 0 + opacity: 0 + outline: none + position: absolute + top: 0 + width: 100% + +.file-cta, +.file-name + @extend %control + border-color: $file-border-color + border-radius: $file-radius + font-size: 1em + padding-left: 1em + padding-right: 1em + white-space: nowrap + +.file-cta + background-color: $file-cta-background-color + color: $file-cta-color + +.file-name + border-color: $file-name-border-color + border-style: $file-name-border-style + border-width: $file-name-border-width + display: block + max-width: $file-name-max-width + overflow: hidden + text-align: left + text-overflow: ellipsis + +.file-icon + align-items: center + display: flex + height: 1em + justify-content: center + margin-right: 0.5em + width: 1em + .fa + font-size: 14px diff --git a/docs/src/assets/bulma/form/input-textarea.sass b/docs/src/assets/bulma/form/input-textarea.sass new file mode 100644 index 00000000..7636cdae --- /dev/null +++ b/docs/src/assets/bulma/form/input-textarea.sass @@ -0,0 +1,64 @@ +$textarea-padding: $control-padding-horizontal !default +$textarea-max-height: 40em !default +$textarea-min-height: 8em !default + +%input-textarea + @extend %input + box-shadow: $input-shadow + max-width: 100% + width: 100% + &[readonly] + box-shadow: none + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + border-color: $color + &:focus, + &.is-focused, + &:active, + &.is-active + box-shadow: $input-focus-box-shadow-size rgba($color, 0.25) + // Sizes + &.is-small + +control-small + &.is-medium + +control-medium + &.is-large + +control-large + // Modifiers + &.is-fullwidth + display: block + width: 100% + &.is-inline + display: inline + width: auto + +.input + @extend %input-textarea + &.is-rounded + border-radius: $radius-rounded + padding-left: calc(#{$control-padding-horizontal} + 0.375em) + padding-right: calc(#{$control-padding-horizontal} + 0.375em) + &.is-static + background-color: transparent + border-color: transparent + box-shadow: none + padding-left: 0 + padding-right: 0 + +.textarea + @extend %input-textarea + display: block + max-width: 100% + min-width: 100% + padding: $textarea-padding + resize: vertical + &:not([rows]) + max-height: $textarea-max-height + min-height: $textarea-min-height + &[rows] + height: initial + // Modifiers + &.has-fixed-size + resize: none diff --git a/docs/src/assets/bulma/form/select.sass b/docs/src/assets/bulma/form/select.sass new file mode 100644 index 00000000..909b9d52 --- /dev/null +++ b/docs/src/assets/bulma/form/select.sass @@ -0,0 +1,85 @@ +.select + display: inline-block + max-width: 100% + position: relative + vertical-align: top + &:not(.is-multiple) + height: $input-height + &:not(.is-multiple):not(.is-loading) + &::after + @extend %arrow + border-color: $input-arrow + right: 1.125em + z-index: 4 + &.is-rounded + select + border-radius: $radius-rounded + padding-left: 1em + select + @extend %input + cursor: pointer + display: block + font-size: 1em + max-width: 100% + outline: none + &::-ms-expand + display: none + &[disabled]:hover, + fieldset[disabled] &:hover + border-color: $input-disabled-border-color + &:not([multiple]) + padding-right: 2.5em + &[multiple] + height: auto + padding: 0 + option + padding: 0.5em 1em + // States + &:not(.is-multiple):not(.is-loading):hover + &::after + border-color: $input-hover-color + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + &:not(:hover)::after + border-color: $color + select + border-color: $color + &:hover, + &.is-hovered + border-color: darken($color, 5%) + &:focus, + &.is-focused, + &:active, + &.is-active + box-shadow: $input-focus-box-shadow-size rgba($color, 0.25) + // Sizes + &.is-small + +control-small + &.is-medium + +control-medium + &.is-large + +control-large + // Modifiers + &.is-disabled + &::after + border-color: $input-disabled-color + &.is-fullwidth + width: 100% + select + width: 100% + &.is-loading + &::after + @extend %loader + margin-top: 0 + position: absolute + right: 0.625em + top: 0.625em + transform: none + &.is-small:after + font-size: $size-small + &.is-medium:after + font-size: $size-medium + &.is-large:after + font-size: $size-large diff --git a/docs/src/assets/bulma/form/shared.sass b/docs/src/assets/bulma/form/shared.sass new file mode 100644 index 00000000..3005587e --- /dev/null +++ b/docs/src/assets/bulma/form/shared.sass @@ -0,0 +1,55 @@ +$input-color: inherit !default +$input-background-color: $scheme-main !default +$input-border-color: $border !default +$input-height: $control-height !default +$input-shadow: inset 0 0.0625em 0.125em rgba($scheme-invert, 0.05) !default +$input-placeholder-color: bulmaRgba($input-color, 0.3) !default + +$input-hover-color: $text-strong !default +$input-hover-border-color: $border-hover !default + +$input-focus-color: $text-strong !default +$input-focus-border-color: $link !default +$input-focus-box-shadow-size: 0 0 0 0.125em !default +$input-focus-box-shadow-color: bulmaRgba($link, 0.25) !default + +$input-disabled-color: $text-light !default +$input-disabled-background-color: $background !default +$input-disabled-border-color: $background !default +$input-disabled-placeholder-color: bulmaRgba($input-disabled-color, 0.3) !default + +$input-arrow: $link !default + +$input-icon-color: $border !default +$input-icon-active-color: $text !default + +$input-radius: $radius !default + +=input + @extend %control + background-color: $input-background-color + border-color: $input-border-color + border-radius: $input-radius + color: $input-color + +placeholder + color: $input-placeholder-color + &:hover, + &.is-hovered + border-color: $input-hover-border-color + &:focus, + &.is-focused, + &:active, + &.is-active + border-color: $input-focus-border-color + box-shadow: $input-focus-box-shadow-size $input-focus-box-shadow-color + &[disabled], + fieldset[disabled] & + background-color: $input-disabled-background-color + border-color: $input-disabled-border-color + box-shadow: none + color: $input-disabled-color + +placeholder + color: $input-disabled-placeholder-color + +%input + +input diff --git a/docs/src/assets/bulma/form/tools.sass b/docs/src/assets/bulma/form/tools.sass new file mode 100644 index 00000000..ff2f8e20 --- /dev/null +++ b/docs/src/assets/bulma/form/tools.sass @@ -0,0 +1,205 @@ +$label-color: $text-strong !default +$label-weight: $weight-bold !default + +$help-size: $size-small !default + +.label + color: $label-color + display: block + font-size: $size-normal + font-weight: $label-weight + &:not(:last-child) + margin-bottom: 0.5em + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + +.help + display: block + font-size: $help-size + margin-top: 0.25rem + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + color: $color + +// Containers + +.field + &:not(:last-child) + margin-bottom: 0.75rem + // Modifiers + &.has-addons + display: flex + justify-content: flex-start + .control + &:not(:last-child) + margin-right: -1px + &:not(:first-child):not(:last-child) + .button, + .input, + .select select + border-radius: 0 + &:first-child:not(:only-child) + .button, + .input, + .select select + border-bottom-right-radius: 0 + border-top-right-radius: 0 + &:last-child:not(:only-child) + .button, + .input, + .select select + border-bottom-left-radius: 0 + border-top-left-radius: 0 + .button, + .input, + .select select + &:not([disabled]) + &:hover, + &.is-hovered + z-index: 2 + &:focus, + &.is-focused, + &:active, + &.is-active + z-index: 3 + &:hover + z-index: 4 + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.has-addons-centered + justify-content: center + &.has-addons-right + justify-content: flex-end + &.has-addons-fullwidth + .control + flex-grow: 1 + flex-shrink: 0 + &.is-grouped + display: flex + justify-content: flex-start + & > .control + flex-shrink: 0 + &:not(:last-child) + margin-bottom: 0 + margin-right: 0.75rem + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.is-grouped-centered + justify-content: center + &.is-grouped-right + justify-content: flex-end + &.is-grouped-multiline + flex-wrap: wrap + & > .control + &:last-child, + &:not(:last-child) + margin-bottom: 0.75rem + &:last-child + margin-bottom: -0.75rem + &:not(:last-child) + margin-bottom: 0 + &.is-horizontal + +tablet + display: flex + +.field-label + .label + font-size: inherit + +mobile + margin-bottom: 0.5rem + +tablet + flex-basis: 0 + flex-grow: 1 + flex-shrink: 0 + margin-right: 1.5rem + text-align: right + &.is-small + font-size: $size-small + padding-top: 0.375em + &.is-normal + padding-top: 0.375em + &.is-medium + font-size: $size-medium + padding-top: 0.375em + &.is-large + font-size: $size-large + padding-top: 0.375em + +.field-body + .field .field + margin-bottom: 0 + +tablet + display: flex + flex-basis: 0 + flex-grow: 5 + flex-shrink: 1 + .field + margin-bottom: 0 + & > .field + flex-shrink: 1 + &:not(.is-narrow) + flex-grow: 1 + &:not(:last-child) + margin-right: 0.75rem + +.control + box-sizing: border-box + clear: both + font-size: $size-normal + position: relative + text-align: left + // Modifiers + &.has-icons-left, + &.has-icons-right + .input, + .select + &:focus + & ~ .icon + color: $input-icon-active-color + &.is-small ~ .icon + font-size: $size-small + &.is-medium ~ .icon + font-size: $size-medium + &.is-large ~ .icon + font-size: $size-large + .icon + color: $input-icon-color + height: $input-height + pointer-events: none + position: absolute + top: 0 + width: $input-height + z-index: 4 + &.has-icons-left + .input, + .select select + padding-left: $input-height + .icon.is-left + left: 0 + &.has-icons-right + .input, + .select select + padding-right: $input-height + .icon.is-right + right: 0 + &.is-loading + &::after + @extend %loader + position: absolute !important + right: 0.625em + top: 0.625em + z-index: 4 + &.is-small:after + font-size: $size-small + &.is-medium:after + font-size: $size-medium + &.is-large:after + font-size: $size-large diff --git a/docs/src/assets/bulma/grid/_all.sass b/docs/src/assets/bulma/grid/_all.sass new file mode 100644 index 00000000..e53070f6 --- /dev/null +++ b/docs/src/assets/bulma/grid/_all.sass @@ -0,0 +1,4 @@ +@charset "utf-8" + +@import "columns.sass" +@import "tiles.sass" diff --git a/docs/src/assets/bulma/grid/columns.sass b/docs/src/assets/bulma/grid/columns.sass new file mode 100644 index 00000000..34a83533 --- /dev/null +++ b/docs/src/assets/bulma/grid/columns.sass @@ -0,0 +1,504 @@ +$column-gap: 0.75rem !default + +.column + display: block + flex-basis: 0 + flex-grow: 1 + flex-shrink: 1 + padding: $column-gap + .columns.is-mobile > &.is-narrow + flex: none + .columns.is-mobile > &.is-full + flex: none + width: 100% + .columns.is-mobile > &.is-three-quarters + flex: none + width: 75% + .columns.is-mobile > &.is-two-thirds + flex: none + width: 66.6666% + .columns.is-mobile > &.is-half + flex: none + width: 50% + .columns.is-mobile > &.is-one-third + flex: none + width: 33.3333% + .columns.is-mobile > &.is-one-quarter + flex: none + width: 25% + .columns.is-mobile > &.is-one-fifth + flex: none + width: 20% + .columns.is-mobile > &.is-two-fifths + flex: none + width: 40% + .columns.is-mobile > &.is-three-fifths + flex: none + width: 60% + .columns.is-mobile > &.is-four-fifths + flex: none + width: 80% + .columns.is-mobile > &.is-offset-three-quarters + margin-left: 75% + .columns.is-mobile > &.is-offset-two-thirds + margin-left: 66.6666% + .columns.is-mobile > &.is-offset-half + margin-left: 50% + .columns.is-mobile > &.is-offset-one-third + margin-left: 33.3333% + .columns.is-mobile > &.is-offset-one-quarter + margin-left: 25% + .columns.is-mobile > &.is-offset-one-fifth + margin-left: 20% + .columns.is-mobile > &.is-offset-two-fifths + margin-left: 40% + .columns.is-mobile > &.is-offset-three-fifths + margin-left: 60% + .columns.is-mobile > &.is-offset-four-fifths + margin-left: 80% + @for $i from 0 through 12 + .columns.is-mobile > &.is-#{$i} + flex: none + width: percentage($i / 12) + .columns.is-mobile > &.is-offset-#{$i} + margin-left: percentage($i / 12) + +mobile + &.is-narrow-mobile + flex: none + &.is-full-mobile + flex: none + width: 100% + &.is-three-quarters-mobile + flex: none + width: 75% + &.is-two-thirds-mobile + flex: none + width: 66.6666% + &.is-half-mobile + flex: none + width: 50% + &.is-one-third-mobile + flex: none + width: 33.3333% + &.is-one-quarter-mobile + flex: none + width: 25% + &.is-one-fifth-mobile + flex: none + width: 20% + &.is-two-fifths-mobile + flex: none + width: 40% + &.is-three-fifths-mobile + flex: none + width: 60% + &.is-four-fifths-mobile + flex: none + width: 80% + &.is-offset-three-quarters-mobile + margin-left: 75% + &.is-offset-two-thirds-mobile + margin-left: 66.6666% + &.is-offset-half-mobile + margin-left: 50% + &.is-offset-one-third-mobile + margin-left: 33.3333% + &.is-offset-one-quarter-mobile + margin-left: 25% + &.is-offset-one-fifth-mobile + margin-left: 20% + &.is-offset-two-fifths-mobile + margin-left: 40% + &.is-offset-three-fifths-mobile + margin-left: 60% + &.is-offset-four-fifths-mobile + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-mobile + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-mobile + margin-left: percentage($i / 12) + +tablet + &.is-narrow, + &.is-narrow-tablet + flex: none + &.is-full, + &.is-full-tablet + flex: none + width: 100% + &.is-three-quarters, + &.is-three-quarters-tablet + flex: none + width: 75% + &.is-two-thirds, + &.is-two-thirds-tablet + flex: none + width: 66.6666% + &.is-half, + &.is-half-tablet + flex: none + width: 50% + &.is-one-third, + &.is-one-third-tablet + flex: none + width: 33.3333% + &.is-one-quarter, + &.is-one-quarter-tablet + flex: none + width: 25% + &.is-one-fifth, + &.is-one-fifth-tablet + flex: none + width: 20% + &.is-two-fifths, + &.is-two-fifths-tablet + flex: none + width: 40% + &.is-three-fifths, + &.is-three-fifths-tablet + flex: none + width: 60% + &.is-four-fifths, + &.is-four-fifths-tablet + flex: none + width: 80% + &.is-offset-three-quarters, + &.is-offset-three-quarters-tablet + margin-left: 75% + &.is-offset-two-thirds, + &.is-offset-two-thirds-tablet + margin-left: 66.6666% + &.is-offset-half, + &.is-offset-half-tablet + margin-left: 50% + &.is-offset-one-third, + &.is-offset-one-third-tablet + margin-left: 33.3333% + &.is-offset-one-quarter, + &.is-offset-one-quarter-tablet + margin-left: 25% + &.is-offset-one-fifth, + &.is-offset-one-fifth-tablet + margin-left: 20% + &.is-offset-two-fifths, + &.is-offset-two-fifths-tablet + margin-left: 40% + &.is-offset-three-fifths, + &.is-offset-three-fifths-tablet + margin-left: 60% + &.is-offset-four-fifths, + &.is-offset-four-fifths-tablet + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}, + &.is-#{$i}-tablet + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}, + &.is-offset-#{$i}-tablet + margin-left: percentage($i / 12) + +touch + &.is-narrow-touch + flex: none + &.is-full-touch + flex: none + width: 100% + &.is-three-quarters-touch + flex: none + width: 75% + &.is-two-thirds-touch + flex: none + width: 66.6666% + &.is-half-touch + flex: none + width: 50% + &.is-one-third-touch + flex: none + width: 33.3333% + &.is-one-quarter-touch + flex: none + width: 25% + &.is-one-fifth-touch + flex: none + width: 20% + &.is-two-fifths-touch + flex: none + width: 40% + &.is-three-fifths-touch + flex: none + width: 60% + &.is-four-fifths-touch + flex: none + width: 80% + &.is-offset-three-quarters-touch + margin-left: 75% + &.is-offset-two-thirds-touch + margin-left: 66.6666% + &.is-offset-half-touch + margin-left: 50% + &.is-offset-one-third-touch + margin-left: 33.3333% + &.is-offset-one-quarter-touch + margin-left: 25% + &.is-offset-one-fifth-touch + margin-left: 20% + &.is-offset-two-fifths-touch + margin-left: 40% + &.is-offset-three-fifths-touch + margin-left: 60% + &.is-offset-four-fifths-touch + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-touch + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-touch + margin-left: percentage($i / 12) + +desktop + &.is-narrow-desktop + flex: none + &.is-full-desktop + flex: none + width: 100% + &.is-three-quarters-desktop + flex: none + width: 75% + &.is-two-thirds-desktop + flex: none + width: 66.6666% + &.is-half-desktop + flex: none + width: 50% + &.is-one-third-desktop + flex: none + width: 33.3333% + &.is-one-quarter-desktop + flex: none + width: 25% + &.is-one-fifth-desktop + flex: none + width: 20% + &.is-two-fifths-desktop + flex: none + width: 40% + &.is-three-fifths-desktop + flex: none + width: 60% + &.is-four-fifths-desktop + flex: none + width: 80% + &.is-offset-three-quarters-desktop + margin-left: 75% + &.is-offset-two-thirds-desktop + margin-left: 66.6666% + &.is-offset-half-desktop + margin-left: 50% + &.is-offset-one-third-desktop + margin-left: 33.3333% + &.is-offset-one-quarter-desktop + margin-left: 25% + &.is-offset-one-fifth-desktop + margin-left: 20% + &.is-offset-two-fifths-desktop + margin-left: 40% + &.is-offset-three-fifths-desktop + margin-left: 60% + &.is-offset-four-fifths-desktop + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-desktop + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-desktop + margin-left: percentage($i / 12) + +widescreen + &.is-narrow-widescreen + flex: none + &.is-full-widescreen + flex: none + width: 100% + &.is-three-quarters-widescreen + flex: none + width: 75% + &.is-two-thirds-widescreen + flex: none + width: 66.6666% + &.is-half-widescreen + flex: none + width: 50% + &.is-one-third-widescreen + flex: none + width: 33.3333% + &.is-one-quarter-widescreen + flex: none + width: 25% + &.is-one-fifth-widescreen + flex: none + width: 20% + &.is-two-fifths-widescreen + flex: none + width: 40% + &.is-three-fifths-widescreen + flex: none + width: 60% + &.is-four-fifths-widescreen + flex: none + width: 80% + &.is-offset-three-quarters-widescreen + margin-left: 75% + &.is-offset-two-thirds-widescreen + margin-left: 66.6666% + &.is-offset-half-widescreen + margin-left: 50% + &.is-offset-one-third-widescreen + margin-left: 33.3333% + &.is-offset-one-quarter-widescreen + margin-left: 25% + &.is-offset-one-fifth-widescreen + margin-left: 20% + &.is-offset-two-fifths-widescreen + margin-left: 40% + &.is-offset-three-fifths-widescreen + margin-left: 60% + &.is-offset-four-fifths-widescreen + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-widescreen + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-widescreen + margin-left: percentage($i / 12) + +fullhd + &.is-narrow-fullhd + flex: none + &.is-full-fullhd + flex: none + width: 100% + &.is-three-quarters-fullhd + flex: none + width: 75% + &.is-two-thirds-fullhd + flex: none + width: 66.6666% + &.is-half-fullhd + flex: none + width: 50% + &.is-one-third-fullhd + flex: none + width: 33.3333% + &.is-one-quarter-fullhd + flex: none + width: 25% + &.is-one-fifth-fullhd + flex: none + width: 20% + &.is-two-fifths-fullhd + flex: none + width: 40% + &.is-three-fifths-fullhd + flex: none + width: 60% + &.is-four-fifths-fullhd + flex: none + width: 80% + &.is-offset-three-quarters-fullhd + margin-left: 75% + &.is-offset-two-thirds-fullhd + margin-left: 66.6666% + &.is-offset-half-fullhd + margin-left: 50% + &.is-offset-one-third-fullhd + margin-left: 33.3333% + &.is-offset-one-quarter-fullhd + margin-left: 25% + &.is-offset-one-fifth-fullhd + margin-left: 20% + &.is-offset-two-fifths-fullhd + margin-left: 40% + &.is-offset-three-fifths-fullhd + margin-left: 60% + &.is-offset-four-fifths-fullhd + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-fullhd + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-fullhd + margin-left: percentage($i / 12) + +.columns + margin-left: (-$column-gap) + margin-right: (-$column-gap) + margin-top: (-$column-gap) + &:last-child + margin-bottom: (-$column-gap) + &:not(:last-child) + margin-bottom: calc(1.5rem - #{$column-gap}) + // Modifiers + &.is-centered + justify-content: center + &.is-gapless + margin-left: 0 + margin-right: 0 + margin-top: 0 + & > .column + margin: 0 + padding: 0 !important + &:not(:last-child) + margin-bottom: 1.5rem + &:last-child + margin-bottom: 0 + &.is-mobile + display: flex + &.is-multiline + flex-wrap: wrap + &.is-vcentered + align-items: center + // Responsiveness + +tablet + &:not(.is-desktop) + display: flex + +desktop + // Modifiers + &.is-desktop + display: flex + +@if $variable-columns + .columns.is-variable + --columnGap: 0.75rem + margin-left: calc(-1 * var(--columnGap)) + margin-right: calc(-1 * var(--columnGap)) + .column + padding-left: var(--columnGap) + padding-right: var(--columnGap) + @for $i from 0 through 8 + &.is-#{$i} + --columnGap: #{$i * 0.25rem} + +mobile + &.is-#{$i}-mobile + --columnGap: #{$i * 0.25rem} + +tablet + &.is-#{$i}-tablet + --columnGap: #{$i * 0.25rem} + +tablet-only + &.is-#{$i}-tablet-only + --columnGap: #{$i * 0.25rem} + +touch + &.is-#{$i}-touch + --columnGap: #{$i * 0.25rem} + +desktop + &.is-#{$i}-desktop + --columnGap: #{$i * 0.25rem} + +desktop-only + &.is-#{$i}-desktop-only + --columnGap: #{$i * 0.25rem} + +widescreen + &.is-#{$i}-widescreen + --columnGap: #{$i * 0.25rem} + +widescreen-only + &.is-#{$i}-widescreen-only + --columnGap: #{$i * 0.25rem} + +fullhd + &.is-#{$i}-fullhd + --columnGap: #{$i * 0.25rem} diff --git a/docs/src/assets/bulma/grid/tiles.sass b/docs/src/assets/bulma/grid/tiles.sass new file mode 100644 index 00000000..15648c29 --- /dev/null +++ b/docs/src/assets/bulma/grid/tiles.sass @@ -0,0 +1,34 @@ +$tile-spacing: 0.75rem !default + +.tile + align-items: stretch + display: block + flex-basis: 0 + flex-grow: 1 + flex-shrink: 1 + min-height: min-content + // Modifiers + &.is-ancestor + margin-left: $tile-spacing * -1 + margin-right: $tile-spacing * -1 + margin-top: $tile-spacing * -1 + &:last-child + margin-bottom: $tile-spacing * -1 + &:not(:last-child) + margin-bottom: $tile-spacing + &.is-child + margin: 0 !important + &.is-parent + padding: $tile-spacing + &.is-vertical + flex-direction: column + & > .tile.is-child:not(:last-child) + margin-bottom: 1.5rem !important + // Responsiveness + +tablet + &:not(.is-child) + display: flex + @for $i from 1 through 12 + &.is-#{$i} + flex: none + width: ($i / 12) * 100% diff --git a/docs/src/assets/bulma/layout/_all.sass b/docs/src/assets/bulma/layout/_all.sass new file mode 100644 index 00000000..143ada35 --- /dev/null +++ b/docs/src/assets/bulma/layout/_all.sass @@ -0,0 +1,5 @@ +@charset "utf-8" + +@import "hero.sass" +@import "section.sass" +@import "footer.sass" diff --git a/docs/src/assets/bulma/layout/footer.sass b/docs/src/assets/bulma/layout/footer.sass new file mode 100644 index 00000000..8faa11ed --- /dev/null +++ b/docs/src/assets/bulma/layout/footer.sass @@ -0,0 +1,9 @@ +$footer-background-color: $scheme-main-bis !default +$footer-color: false !default +$footer-padding: 3rem 1.5rem 6rem !default + +.footer + background-color: $footer-background-color + padding: $footer-padding + @if $footer-color + color: $footer-color diff --git a/docs/src/assets/bulma/layout/hero.sass b/docs/src/assets/bulma/layout/hero.sass new file mode 100644 index 00000000..ae8ed086 --- /dev/null +++ b/docs/src/assets/bulma/layout/hero.sass @@ -0,0 +1,144 @@ +$hero-body-padding: 3rem 1.5rem !default +$hero-body-padding-small: 1.5rem !default +$hero-body-padding-medium: 9rem 1.5rem !default +$hero-body-padding-large: 18rem 1.5rem !default + +// Main container +.hero + align-items: stretch + display: flex + flex-direction: column + justify-content: space-between + .navbar + background: none + .tabs + ul + border-bottom: none + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), + strong + color: inherit + .title + color: $color-invert + .subtitle + color: bulmaRgba($color-invert, 0.9) + a:not(.button), + strong + color: $color-invert + .navbar-menu + +touch + background-color: $color + .navbar-item, + .navbar-link + color: bulmaRgba($color-invert, 0.7) + a.navbar-item, + .navbar-link + &:hover, + &.is-active + background-color: darken($color, 5%) + color: $color-invert + .tabs + a + color: $color-invert + opacity: 0.9 + &:hover + opacity: 1 + li + &.is-active a + opacity: 1 + &.is-boxed, + &.is-toggle + a + color: $color-invert + &:hover + background-color: bulmaRgba($scheme-invert, 0.1) + li.is-active a + &, + &:hover + background-color: $color-invert + border-color: $color-invert + color: $color + // Modifiers + &.is-bold + $gradient-top-left: darken(saturate(adjust-hue($color, -10deg), 10%), 10%) + $gradient-bottom-right: lighten(saturate(adjust-hue($color, 10deg), 5%), 5%) + background-image: linear-gradient(141deg, $gradient-top-left 0%, $color 71%, $gradient-bottom-right 100%) + +mobile + .navbar-menu + background-image: linear-gradient(141deg, $gradient-top-left 0%, $color 71%, $gradient-bottom-right 100%) + // Sizes + &.is-small + .hero-body + padding: $hero-body-padding-small + &.is-medium + +tablet + .hero-body + padding: $hero-body-padding-medium + &.is-large + +tablet + .hero-body + padding: $hero-body-padding-large + &.is-halfheight, + &.is-fullheight, + &.is-fullheight-with-navbar + .hero-body + align-items: center + display: flex + & > .container + flex-grow: 1 + flex-shrink: 1 + &.is-halfheight + min-height: 50vh + &.is-fullheight + min-height: 100vh + +// Components + +.hero-video + @extend %overlay + overflow: hidden + video + left: 50% + min-height: 100% + min-width: 100% + position: absolute + top: 50% + transform: translate3d(-50%, -50%, 0) + // Modifiers + &.is-transparent + opacity: 0.3 + // Responsiveness + +mobile + display: none + +.hero-buttons + margin-top: 1.5rem + // Responsiveness + +mobile + .button + display: flex + &:not(:last-child) + margin-bottom: 0.75rem + +tablet + display: flex + justify-content: center + .button:not(:last-child) + margin-right: 1.5rem + +// Containers + +.hero-head, +.hero-foot + flex-grow: 0 + flex-shrink: 0 + +.hero-body + flex-grow: 1 + flex-shrink: 0 + padding: $hero-body-padding diff --git a/docs/src/assets/bulma/layout/section.sass b/docs/src/assets/bulma/layout/section.sass new file mode 100644 index 00000000..6f2d3523 --- /dev/null +++ b/docs/src/assets/bulma/layout/section.sass @@ -0,0 +1,13 @@ +$section-padding: 3rem 1.5rem !default +$section-padding-medium: 9rem 1.5rem !default +$section-padding-large: 18rem 1.5rem !default + +.section + padding: $section-padding + // Responsiveness + +desktop + // Sizes + &.is-medium + padding: $section-padding-medium + &.is-large + padding: $section-padding-large diff --git a/docs/src/assets/bulma/utilities/_all.sass b/docs/src/assets/bulma/utilities/_all.sass new file mode 100644 index 00000000..bf4ecfe3 --- /dev/null +++ b/docs/src/assets/bulma/utilities/_all.sass @@ -0,0 +1,8 @@ +@charset "utf-8" + +@import "initial-variables.sass" +@import "functions.sass" +@import "derived-variables.sass" +@import "animations.sass" +@import "mixins.sass" +@import "controls.sass" diff --git a/docs/src/assets/bulma/utilities/animations.sass b/docs/src/assets/bulma/utilities/animations.sass new file mode 100644 index 00000000..a14525d7 --- /dev/null +++ b/docs/src/assets/bulma/utilities/animations.sass @@ -0,0 +1,5 @@ +@keyframes spinAround + from + transform: rotate(0deg) + to + transform: rotate(359deg) diff --git a/docs/src/assets/bulma/utilities/controls.sass b/docs/src/assets/bulma/utilities/controls.sass new file mode 100644 index 00000000..cc7672a1 --- /dev/null +++ b/docs/src/assets/bulma/utilities/controls.sass @@ -0,0 +1,50 @@ +$control-radius: $radius !default +$control-radius-small: $radius-small !default + +$control-border-width: 1px !default + +$control-height: 2.5em !default +$control-line-height: 1.5 !default + +$control-padding-vertical: calc(0.5em - #{$control-border-width}) !default +$control-padding-horizontal: calc(0.75em - #{$control-border-width}) !default + +=control + -moz-appearance: none + -webkit-appearance: none + align-items: center + border: $control-border-width solid transparent + border-radius: $control-radius + box-shadow: none + display: inline-flex + font-size: $size-normal + height: $control-height + justify-content: flex-start + line-height: $control-line-height + padding-bottom: $control-padding-vertical + padding-left: $control-padding-horizontal + padding-right: $control-padding-horizontal + padding-top: $control-padding-vertical + position: relative + vertical-align: top + // States + &:focus, + &.is-focused, + &:active, + &.is-active + outline: none + &[disabled], + fieldset[disabled] & + cursor: not-allowed + +%control + +control + +// The controls sizes use mixins so they can be used at different breakpoints +=control-small + border-radius: $control-radius-small + font-size: $size-small +=control-medium + font-size: $size-medium +=control-large + font-size: $size-large diff --git a/docs/src/assets/bulma/utilities/derived-variables.sass b/docs/src/assets/bulma/utilities/derived-variables.sass new file mode 100644 index 00000000..18a7f461 --- /dev/null +++ b/docs/src/assets/bulma/utilities/derived-variables.sass @@ -0,0 +1,106 @@ +$primary: $turquoise !default + +$info: $cyan !default +$success: $green !default +$warning: $yellow !default +$danger: $red !default + +$light: $white-ter !default +$dark: $grey-darker !default + +// Invert colors + +$orange-invert: findColorInvert($orange) !default +$yellow-invert: findColorInvert($yellow) !default +$green-invert: findColorInvert($green) !default +$turquoise-invert: findColorInvert($turquoise) !default +$cyan-invert: findColorInvert($cyan) !default +$blue-invert: findColorInvert($blue) !default +$purple-invert: findColorInvert($purple) !default +$red-invert: findColorInvert($red) !default + +$primary-invert: findColorInvert($primary) !default +$primary-light: findLightColor($primary) !default +$primary-dark: findDarkColor($primary) !default +$info-invert: findColorInvert($info) !default +$info-light: findLightColor($info) !default +$info-dark: findDarkColor($info) !default +$success-invert: findColorInvert($success) !default +$success-light: findLightColor($success) !default +$success-dark: findDarkColor($success) !default +$warning-invert: findColorInvert($warning) !default +$warning-light: findLightColor($warning) !default +$warning-dark: findDarkColor($warning) !default +$danger-invert: findColorInvert($danger) !default +$danger-light: findLightColor($danger) !default +$danger-dark: findDarkColor($danger) !default +$light-invert: findColorInvert($light) !default +$dark-invert: findColorInvert($dark) !default + +// General colors + +$scheme-main: $white !default +$scheme-main-bis: $white-bis !default +$scheme-main-ter: $white-ter !default +$scheme-invert: $black !default +$scheme-invert-bis: $black-bis !default +$scheme-invert-ter: $black-ter !default + +$background: $white-ter !default + +$border: $grey-lighter !default +$border-hover: $grey-light !default +$border-light: $grey-lightest !default +$border-light-hover: $grey-light !default + +// Text colors + +$text: $grey-dark !default +$text-invert: findColorInvert($text) !default +$text-light: $grey !default +$text-strong: $grey-darker !default + +// Code colors + +$code: $red !default +$code-background: $background !default + +$pre: $text !default +$pre-background: $background !default + +// Link colors + +$link: $blue !default +$link-invert: findColorInvert($link) !default +$link-light: findLightColor($link) !default +$link-dark: findDarkColor($link) !default +$link-visited: $purple !default + +$link-hover: $grey-darker !default +$link-hover-border: $grey-light !default + +$link-focus: $grey-darker !default +$link-focus-border: $blue !default + +$link-active: $grey-darker !default +$link-active-border: $grey-dark !default + +// Typography + +$family-primary: $family-sans-serif !default +$family-secondary: $family-sans-serif !default +$family-code: $family-monospace !default + +$size-small: $size-7 !default +$size-normal: $size-6 !default +$size-medium: $size-5 !default +$size-large: $size-4 !default + +// Lists and maps +$custom-colors: null !default +$custom-shades: null !default + +$colors: mergeColorMaps(("white": ($white, $black), "black": ($black, $white), "light": ($light, $light-invert), "dark": ($dark, $dark-invert), "primary": ($primary, $primary-invert, $primary-light, $primary-dark), "link": ($link, $link-invert, $link-light, $link-dark), "info": ($info, $info-invert, $info-light, $info-dark), "success": ($success, $success-invert, $success-light, $success-dark), "warning": ($warning, $warning-invert, $warning-light, $warning-dark), "danger": ($danger, $danger-invert, $danger-light, $danger-dark)), $custom-colors) !default +$shades: mergeColorMaps(("black-bis": $black-bis, "black-ter": $black-ter, "grey-darker": $grey-darker, "grey-dark": $grey-dark, "grey": $grey, "grey-light": $grey-light, "grey-lighter": $grey-lighter, "white-ter": $white-ter, "white-bis": $white-bis), $custom-shades) !default + +$sizes: $size-1 $size-2 $size-3 $size-4 $size-5 $size-6 $size-7 !default diff --git a/docs/src/assets/bulma/utilities/functions.sass b/docs/src/assets/bulma/utilities/functions.sass new file mode 100644 index 00000000..54225e21 --- /dev/null +++ b/docs/src/assets/bulma/utilities/functions.sass @@ -0,0 +1,103 @@ +@function mergeColorMaps($bulma-colors, $custom-colors) + // We return at least Bulma's hard-coded colors + $merged-colors: $bulma-colors + + // We want a map as input + @if type-of($custom-colors) == 'map' + @each $name, $components in $custom-colors + // The color name should be a string + // and the components either a single color + // or a colors list with at least one element + @if type-of($name) == 'string' and (type-of($components) == 'list' or type-of($components) == 'color') and length($components) >= 1 + $color-base: null + $color-invert: null + $color-light: null + $color-dark: null + $value: null + + // The param can either be a single color + // or a list of 2 colors + @if type-of($components) == 'color' + $color-base: $components + $color-invert: findColorInvert($color-base) + $color-light: findLightColor($color-base) + $color-dark: findDarkColor($color-base) + @else if type-of($components) == 'list' + $color-base: nth($components, 1) + // If Invert, Light and Dark are provided + @if length($components) > 3 + $color-invert: nth($components, 2) + $color-light: nth($components, 3) + $color-dark: nth($components, 4) + // If only Invert and Light are provided + @else if length($components) > 2 + $color-invert: nth($components, 2) + $color-light: nth($components, 3) + $color-dark: findDarkColor($color-base) + // If only Invert is provided + @else + $color-invert: nth($components, 2) + $color-light: findLightColor($color-base) + $color-dark: findDarkColor($color-base) + + $value: ($color-base, $color-invert, $color-light, $color-dark) + + // We only want to merge the map if the color base is an actual color + @if type-of($color-base) == 'color' + // We merge this colors elements as map with Bulma's colors map + // (we can override them this way, no multiple definition for the same name) + // $merged-colors: map_merge($merged-colors, ($name: ($color-base, $color-invert, $color-light, $color-dark))) + $merged-colors: map_merge($merged-colors, ($name: $value)) + + @return $merged-colors + +@function powerNumber($number, $exp) + $value: 1 + @if $exp > 0 + @for $i from 1 through $exp + $value: $value * $number + @else if $exp < 0 + @for $i from 1 through -$exp + $value: $value / $number + @return $value + +@function colorLuminance($color) + $color-rgb: ('red': red($color),'green': green($color),'blue': blue($color)) + @each $name, $value in $color-rgb + $adjusted: 0 + $value: $value / 255 + @if $value < 0.03928 + $value: $value / 12.92 + @else + $value: ($value + .055) / 1.055 + $value: powerNumber($value, 2) + $color-rgb: map-merge($color-rgb, ($name: $value)) + @return (map-get($color-rgb, 'red') * .2126) + (map-get($color-rgb, 'green') * .7152) + (map-get($color-rgb, 'blue') * .0722) + +@function findColorInvert($color) + @if (colorLuminance($color) > 0.55) + @return rgba(#000, 0.7) + @else + @return #fff + +@function findLightColor($color) + @if type-of($color) == 'color' + $l: 96% + @if lightness($color) > 96% + $l: lightness($color) + @return change-color($color, $lightness: $l) + @return $background + +@function findDarkColor($color) + @if type-of($color) == 'color' + $base-l: 29% + $luminance: colorLuminance($color) + $luminance-delta: (0.53 - $luminance) + $target-l: round($base-l + ($luminance-delta * 53)) + @return change-color($color, $lightness: max($base-l, $target-l)) + @return $text-strong + +@function bulmaRgba($color, $alpha) + @if type-of($color) == 'color' + @return rgba($color, $alpha) + @return $color diff --git a/docs/src/assets/bulma/utilities/initial-variables.sass b/docs/src/assets/bulma/utilities/initial-variables.sass new file mode 100644 index 00000000..03bbc128 --- /dev/null +++ b/docs/src/assets/bulma/utilities/initial-variables.sass @@ -0,0 +1,77 @@ +// Colors + +$black: hsl(0, 0%, 4%) !default +$black-bis: hsl(0, 0%, 7%) !default +$black-ter: hsl(0, 0%, 14%) !default + +$grey-darker: hsl(0, 0%, 21%) !default +$grey-dark: hsl(0, 0%, 29%) !default +$grey: hsl(0, 0%, 48%) !default +$grey-light: hsl(0, 0%, 71%) !default +$grey-lighter: hsl(0, 0%, 86%) !default +$grey-lightest: hsl(0, 0%, 93%) !default + +$white-ter: hsl(0, 0%, 96%) !default +$white-bis: hsl(0, 0%, 98%) !default +$white: hsl(0, 0%, 100%) !default + +$orange: hsl(14, 100%, 53%) !default +$yellow: hsl(48, 100%, 67%) !default +$green: hsl(141, 53%, 53%) !default +$turquoise: hsl(171, 100%, 41%) !default +$cyan: hsl(204, 71%, 53%) !default +$blue: hsl(217, 71%, 53%) !default +$purple: hsl(271, 100%, 71%) !default +$red: hsl(348, 86%, 61%) !default + +// Typography + +$family-sans-serif: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !default +$family-monospace: monospace !default +$render-mode: optimizeLegibility !default + +$size-1: 3rem !default +$size-2: 2.5rem !default +$size-3: 2rem !default +$size-4: 1.5rem !default +$size-5: 1.25rem !default +$size-6: 1rem !default +$size-7: 0.75rem !default + +$weight-light: 300 !default +$weight-normal: 400 !default +$weight-medium: 500 !default +$weight-semibold: 600 !default +$weight-bold: 700 !default + +// Spacing + +$block-spacing: 1.5rem !default + +// Responsiveness + +// The container horizontal gap, which acts as the offset for breakpoints +$gap: 32px !default +// 960, 1152, and 1344 have been chosen because they are divisible by both 12 and 16 +$tablet: 769px !default +// 960px container + 4rem +$desktop: 960px + (2 * $gap) !default +// 1152px container + 4rem +$widescreen: 1152px + (2 * $gap) !default +$widescreen-enabled: true !default +// 1344px container + 4rem +$fullhd: 1344px + (2 * $gap) !default +$fullhd-enabled: true !default + +// Miscellaneous + +$easing: ease-out !default +$radius-small: 2px !default +$radius: 4px !default +$radius-large: 6px !default +$radius-rounded: 290486px !default +$speed: 86ms !default + +// Flags + +$variable-columns: true !default diff --git a/docs/src/assets/bulma/utilities/mixins.sass b/docs/src/assets/bulma/utilities/mixins.sass new file mode 100644 index 00000000..27d74673 --- /dev/null +++ b/docs/src/assets/bulma/utilities/mixins.sass @@ -0,0 +1,261 @@ +@import "initial-variables" + +=clearfix + &::after + clear: both + content: " " + display: table + +=center($width, $height: 0) + position: absolute + @if $height != 0 + left: calc(50% - (#{$width} / 2)) + top: calc(50% - (#{$height} / 2)) + @else + left: calc(50% - (#{$width} / 2)) + top: calc(50% - (#{$width} / 2)) + +=fa($size, $dimensions) + display: inline-block + font-size: $size + height: $dimensions + line-height: $dimensions + text-align: center + vertical-align: top + width: $dimensions + +=hamburger($dimensions) + cursor: pointer + display: block + height: $dimensions + position: relative + width: $dimensions + span + background-color: currentColor + display: block + height: 1px + left: calc(50% - 8px) + position: absolute + transform-origin: center + transition-duration: $speed + transition-property: background-color, opacity, transform + transition-timing-function: $easing + width: 16px + &:nth-child(1) + top: calc(50% - 6px) + &:nth-child(2) + top: calc(50% - 1px) + &:nth-child(3) + top: calc(50% + 4px) + &:hover + background-color: bulmaRgba(black, 0.05) + // Modifers + &.is-active + span + &:nth-child(1) + transform: translateY(5px) rotate(45deg) + &:nth-child(2) + opacity: 0 + &:nth-child(3) + transform: translateY(-5px) rotate(-45deg) + +=overflow-touch + -webkit-overflow-scrolling: touch + +=placeholder + $placeholders: ':-moz' ':-webkit-input' '-moz' '-ms-input' + @each $placeholder in $placeholders + &:#{$placeholder}-placeholder + @content + +// Responsiveness + +=from($device) + @media screen and (min-width: $device) + @content + +=until($device) + @media screen and (max-width: $device - 1px) + @content + +=mobile + @media screen and (max-width: $tablet - 1px) + @content + +=tablet + @media screen and (min-width: $tablet), print + @content + +=tablet-only + @media screen and (min-width: $tablet) and (max-width: $desktop - 1px) + @content + +=touch + @media screen and (max-width: $desktop - 1px) + @content + +=desktop + @media screen and (min-width: $desktop) + @content + +=desktop-only + @if $widescreen-enabled + @media screen and (min-width: $desktop) and (max-width: $widescreen - 1px) + @content + +=until-widescreen + @if $widescreen-enabled + @media screen and (max-width: $widescreen - 1px) + @content + +=widescreen + @if $widescreen-enabled + @media screen and (min-width: $widescreen) + @content + +=widescreen-only + @if $widescreen-enabled and $fullhd-enabled + @media screen and (min-width: $widescreen) and (max-width: $fullhd - 1px) + @content + +=until-fullhd + @if $fullhd-enabled + @media screen and (max-width: $fullhd - 1px) + @content + +=fullhd + @if $fullhd-enabled + @media screen and (min-width: $fullhd) + @content + +// Placeholders + +=unselectable + -webkit-touch-callout: none + -webkit-user-select: none + -moz-user-select: none + -ms-user-select: none + user-select: none + +%unselectable + +unselectable + +=arrow($color: transparent) + border: 3px solid $color + border-radius: 2px + border-right: 0 + border-top: 0 + content: " " + display: block + height: 0.625em + margin-top: -0.4375em + pointer-events: none + position: absolute + top: 50% + transform: rotate(-45deg) + transform-origin: center + width: 0.625em + +%arrow + +arrow + +=block($spacing: $block-spacing) + &:not(:last-child) + margin-bottom: $spacing + +%block + +block + +=delete + @extend %unselectable + -moz-appearance: none + -webkit-appearance: none + background-color: bulmaRgba($scheme-invert, 0.2) + border: none + border-radius: $radius-rounded + cursor: pointer + pointer-events: auto + display: inline-block + flex-grow: 0 + flex-shrink: 0 + font-size: 0 + height: 20px + max-height: 20px + max-width: 20px + min-height: 20px + min-width: 20px + outline: none + position: relative + vertical-align: top + width: 20px + &::before, + &::after + background-color: $scheme-main + content: "" + display: block + left: 50% + position: absolute + top: 50% + transform: translateX(-50%) translateY(-50%) rotate(45deg) + transform-origin: center center + &::before + height: 2px + width: 50% + &::after + height: 50% + width: 2px + &:hover, + &:focus + background-color: bulmaRgba($scheme-invert, 0.3) + &:active + background-color: bulmaRgba($scheme-invert, 0.4) + // Sizes + &.is-small + height: 16px + max-height: 16px + max-width: 16px + min-height: 16px + min-width: 16px + width: 16px + &.is-medium + height: 24px + max-height: 24px + max-width: 24px + min-height: 24px + min-width: 24px + width: 24px + &.is-large + height: 32px + max-height: 32px + max-width: 32px + min-height: 32px + min-width: 32px + width: 32px + +%delete + +delete + +=loader + animation: spinAround 500ms infinite linear + border: 2px solid $grey-lighter + border-radius: $radius-rounded + border-right-color: transparent + border-top-color: transparent + content: "" + display: block + height: 1em + position: relative + width: 1em + +%loader + +loader + +=overlay($offset: 0) + bottom: $offset + left: $offset + position: absolute + right: $offset + top: $offset + +%overlay + +overlay diff --git a/docs/style/fa/_animated.scss b/docs/src/assets/fa/_animated.scss index 7c7c0e17..7c7c0e17 100644 --- a/docs/style/fa/_animated.scss +++ b/docs/src/assets/fa/_animated.scss diff --git a/docs/style/fa/_bordered-pulled.scss b/docs/src/assets/fa/_bordered-pulled.scss index c8c4274c..c8c4274c 100644 --- a/docs/style/fa/_bordered-pulled.scss +++ b/docs/src/assets/fa/_bordered-pulled.scss diff --git a/docs/style/fa/_core.scss b/docs/src/assets/fa/_core.scss index 7fd37f85..7fd37f85 100644 --- a/docs/style/fa/_core.scss +++ b/docs/src/assets/fa/_core.scss diff --git a/docs/style/fa/_fixed-width.scss b/docs/src/assets/fa/_fixed-width.scss index 5b33eb49..5b33eb49 100644 --- a/docs/style/fa/_fixed-width.scss +++ b/docs/src/assets/fa/_fixed-width.scss diff --git a/docs/style/fa/_icons.scss b/docs/src/assets/fa/_icons.scss index bfd2b469..bfd2b469 100644 --- a/docs/style/fa/_icons.scss +++ b/docs/src/assets/fa/_icons.scss diff --git a/docs/style/fa/_larger.scss b/docs/src/assets/fa/_larger.scss index 27c2ad5f..27c2ad5f 100644 --- a/docs/style/fa/_larger.scss +++ b/docs/src/assets/fa/_larger.scss diff --git a/docs/style/fa/_list.scss b/docs/src/assets/fa/_list.scss index 8ebf3333..8ebf3333 100644 --- a/docs/style/fa/_list.scss +++ b/docs/src/assets/fa/_list.scss diff --git a/docs/style/fa/_mixins.scss b/docs/src/assets/fa/_mixins.scss index 06e549b6..06e549b6 100644 --- a/docs/style/fa/_mixins.scss +++ b/docs/src/assets/fa/_mixins.scss diff --git a/docs/style/fa/_rotated-flipped.scss b/docs/src/assets/fa/_rotated-flipped.scss index 995bc4cc..995bc4cc 100644 --- a/docs/style/fa/_rotated-flipped.scss +++ b/docs/src/assets/fa/_rotated-flipped.scss diff --git a/docs/style/fa/_screen-reader.scss b/docs/src/assets/fa/_screen-reader.scss index 5d0ab262..5d0ab262 100644 --- a/docs/style/fa/_screen-reader.scss +++ b/docs/src/assets/fa/_screen-reader.scss diff --git a/docs/style/fa/_stacked.scss b/docs/src/assets/fa/_stacked.scss index 6c09d84c..6c09d84c 100644 --- a/docs/style/fa/_stacked.scss +++ b/docs/src/assets/fa/_stacked.scss diff --git a/docs/style/fa/_variables.scss b/docs/src/assets/fa/_variables.scss index d2c4d474..d2c4d474 100644 --- a/docs/style/fa/_variables.scss +++ b/docs/src/assets/fa/_variables.scss diff --git a/docs/style/fa/fa-brands.scss b/docs/src/assets/fa/fa-brands.scss index ab89c020..ab89c020 100644 --- a/docs/style/fa/fa-brands.scss +++ b/docs/src/assets/fa/fa-brands.scss diff --git a/docs/style/fa/fa-regular.scss b/docs/src/assets/fa/fa-regular.scss index 4f288292..4f288292 100644 --- a/docs/style/fa/fa-regular.scss +++ b/docs/src/assets/fa/fa-regular.scss diff --git a/docs/style/fa/fa-solid.scss b/docs/src/assets/fa/fa-solid.scss index bb0df52a..bb0df52a 100644 --- a/docs/style/fa/fa-solid.scss +++ b/docs/src/assets/fa/fa-solid.scss diff --git a/docs/style/fa/fontawesome.scss b/docs/src/assets/fa/fontawesome.scss index 04eb879a..04eb879a 100644 --- a/docs/style/fa/fontawesome.scss +++ b/docs/src/assets/fa/fontawesome.scss diff --git a/docs/style/style.scss b/docs/src/assets/style.scss index 908950d7..26c22071 100644 --- a/docs/style/style.scss +++ b/docs/src/assets/style.scss @@ -4,12 +4,15 @@ $primary: #C93312; $warning-invert: #FFFFFF; $family-sans-serif: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif, 'Font Awesome 5 Free', 'Font Awesome 5 Brands' !default; -@import "../node_modules/bulma/sass/utilities/_all"; -@import "../node_modules/bulma/sass/base/_all"; -@import "../node_modules/bulma/sass/grid/_all"; -@import "../node_modules/bulma/sass/elements/_all"; -@import "../node_modules/bulma/sass/components/_all"; -@import "../node_modules/bulma/sass/layout/_all"; + +/*!* +bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */ +@import "./bulma/utilities/_all"; +@import "./bulma/base/_all"; +@import "./bulma/grid/_all"; +@import "./bulma/elements/_all"; +@import "./bulma/components/_all"; +@import "./bulma/layout/_all"; html, body { height: 100%; diff --git a/docs/style/syntax.css b/docs/src/assets/syntax.css index 33ce367c..33ce367c 100644 --- a/docs/style/syntax.css +++ b/docs/src/assets/syntax.css diff --git a/docs/src/content/addons-events.md b/docs/src/content/addons-events.md index 489ea342..ddf0a99f 100644 --- a/docs/src/content/addons-events.md +++ b/docs/src/content/addons-events.md @@ -21,4 +21,18 @@ header with a count of the number of responses seen: Below is an addon class that implements stubs for all events. We've added annotations to illustrate the argument types for the various events. -{{< example src="examples/addons/events.py" lang="py" >}}
\ No newline at end of file +### Generic Events + +{{< example src="examples/addons/events.py" lang="py" >}} + +### HTTP Events + +{{< example src="examples/addons/events-http-specific.py" lang="py" >}} + +### WebSocket Events + +{{< example src="examples/addons/events-websocket-specific.py" lang="py" >}} + +### TCP Events + +{{< example src="examples/addons/events-tcp-specific.py" lang="py" >}} diff --git a/docs/src/content/addons-scripting.md b/docs/src/content/addons-scripting.md index 6a18eaf4..c90a9037 100644 --- a/docs/src/content/addons-scripting.md +++ b/docs/src/content/addons-scripting.md @@ -5,7 +5,7 @@ menu: weight: 5 --- -# Scripting +# Scripting HTTP/1.1 and HTTP/2.0 Sometimes, we would like to write a quick script without going through the trouble of creating a class. The addons mechanism has a shorthand that allows a @@ -13,7 +13,6 @@ module as a whole to be treated as an addon object. This lets us place event handler functions in the module scope. For instance, here is a complete script that adds a header to every request. - {{< example src="examples/addons/scripting-headers.py" lang="py" >}} @@ -22,11 +21,31 @@ an arbitrary response instead: {{< example src="examples/simple/send_reply_from_proxy.py" lang="py" >}} +All events around the HTTP protocol [can be found here]({{< relref "addons-events#http-events">}}). -You can look at the [http][] module, or the [Request][], and -[Response][] classes for other attributes that you can use when +For HTTP-related objects, please look at the [http][] module, or the +[Request][], and [Response][] classes for other attributes that you can use when scripting. -[http]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/http.py -[Request]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/net/http/request.py -[Response]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/net/http/response.py +# Scripting WebSocket + +The WebSocket protocol initially looks like a regular HTTP request, before the client and server agree to upgrade the connection to WebSocket. All scripting events for initial HTTP handshake, and also the dedicated WebSocket events [can be found here]({{< relref "addons-events#websocket-events">}}). + +{{< example src="examples/simple/websocket_messages.py" lang="py" >}} + +For WebSocket-related objects please look at the [websocket][] module to find +all attributes that you can use when scripting. + +[websocket]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/websocket.py + + +# Scripting TCP + +All events around the TCP protocol [can be found here]({{< relref "addons-events#tcp-events">}}). + +{{< example src="examples/complex/tcp_message.py" lang="py" >}} + +For WebSocket-related objects please look at the [tcp][] module to find +all attributes that you can use when scripting. + +[tcp]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/tcp.py diff --git a/docs/src/content/concepts-certificates.md b/docs/src/content/concepts-certificates.md index 4e2ae47a..4e9aa652 100644 --- a/docs/src/content/concepts-certificates.md +++ b/docs/src/content/concepts-certificates.md @@ -48,7 +48,7 @@ documentation for some common platforms. The mitmproxy CA cert is located in - [Windows (automated)](https://technet.microsoft.com/en-us/library/cc732443.aspx) {{< highlight bash >}} -certutil.exe -importpfx Root mitmproxy-ca-cert.p12 +certutil -addstore root mitmproxy-ca-cert.cer {{< / highlight >}} - [Mac OS X](https://support.apple.com/kb/PH20129) diff --git a/docs/src/content/concepts-commands.md b/docs/src/content/concepts-commands.md index 72f17252..46d76209 100644 --- a/docs/src/content/concepts-commands.md +++ b/docs/src/content/concepts-commands.md @@ -60,13 +60,3 @@ just replay flows for a specific domain: {{< highlight none >}} :replay.client "~d google.com" {{< /highlight >}} - - - - - - - - - - diff --git a/docs/src/content/concepts-filters.md b/docs/src/content/concepts-filters.md index f0b9a4b2..b9c89456 100644 --- a/docs/src/content/concepts-filters.md +++ b/docs/src/content/concepts-filters.md @@ -49,3 +49,8 @@ Requests whose body contains the string "test": Anything but requests with a text/html content type: !(~q & ~t "text/html") + +Replace entire GET string in a request (quotes required to make it work): + + ":~q ~m GET:.*:/replacement.html" + diff --git a/docs/src/content/concepts-protocols.md b/docs/src/content/concepts-protocols.md index c79274bf..dc9d84fb 100644 --- a/docs/src/content/concepts-protocols.md +++ b/docs/src/content/concepts-protocols.md @@ -73,6 +73,8 @@ If an endpoint sends a PING to mitmproxy, a PONG will be sent back immediately PING (without a payload) is sent to the other endpoint. Unsolicited PONG's are not forwarded. All PING's and PONG's are logged (with payload if present). +Please note that message interception, modification or replay are not possible yet. + ## Raw TCP / TCP Proxy / Fallback In case mitmproxy does not handle a specific protocol, you can exempt @@ -83,7 +85,7 @@ but differs in two important aspects: * The raw TCP messages are printed to the event log. * SSL connections will be intercepted. -Please note that message interception or modification are not possible yet. If +Please note that message interception, modification or replay are not possible yet. If you are not interested in the raw TCP messages, you should use the ignore domains feature. diff --git a/docs/src/content/tools-mitmdump.md b/docs/src/content/tools-mitmdump.md index fb6a6c0c..624246d4 100644 --- a/docs/src/content/tools-mitmdump.md +++ b/docs/src/content/tools-mitmdump.md @@ -35,16 +35,16 @@ and write to outfile. ### Client replay {{< highlight bash >}} -mitmdump -nc outfile +mitmdump -nC outfile {{< / highlight >}} Start mitmdump without binding to the proxy port (`-n`), then replay all -requests from outfile (`-c filename`). Flags combine in the obvious way, +requests from outfile (`-C filename`). Flags combine in the obvious way, so you can replay requests from one file, and write the resulting flows to another: {{< highlight bash >}} -mitmdump -nc srcfile -w dstfile +mitmdump -nC srcfile -w dstfile {{< / highlight >}} See the [client-side replay]({{< relref "overview-features#client-side-replay" @@ -53,7 +53,7 @@ See the [client-side replay]({{< relref "overview-features#client-side-replay" ### Running a script {{< highlight bash >}} -mitmdump -s examples/add_header.py +mitmdump -s examples/simple/add_header.py {{< / highlight >}} This runs the **add_header.py** example script, which simply adds a new @@ -62,7 +62,7 @@ header to all responses. ### Scripted data transformation {{< highlight bash >}} -mitmdump -ns examples/add_header.py -r srcfile -w dstfile +mitmdump -ns examples/simple/add_header.py -r srcfile -w dstfile {{< / highlight >}} This command loads flows from **srcfile**, transforms it according to diff --git a/docs/src/content/tute-clientreplay.md b/docs/src/content/tute-clientreplay.md index 1bf69031..048fd0a5 100644 --- a/docs/src/content/tute-clientreplay.md +++ b/docs/src/content/tute-clientreplay.md @@ -31,9 +31,8 @@ mitmdump -w wireless-login ## 2. Point your browser at the mitmdump instance. -I use a tiny Firefox addon called [Toggle -Proxy](https://addons.mozilla.org/en-us/firefox/addon/toggle-proxy-51740/) to -switch quickly to and from mitmproxy. I'm assuming you've already [configured +There is a Firefox addon called [FoxyProxy](https://addons.mozilla.org/fi/firefox/addon/foxyproxy-standard/) that +lets you switch quickly to and from mitmproxy. I'm assuming you've already [configured your browser with mitmproxy's SSL certificate authority]({{< relref "concepts-certificates" >}}). @@ -43,7 +42,7 @@ And that's it\! You now have a serialised version of the login process in the file wireless-login, and you can replay it at any time like this: {{< highlight bash >}} -mitmdump -c wireless-login +mitmdump -C wireless-login {{< / highlight >}} ## Embellishments diff --git a/docs/src/themes/mitmproxydocs/layouts/partials/header.html b/docs/src/themes/mitmproxydocs/layouts/partials/header.html index 559115f0..925631d6 100644 --- a/docs/src/themes/mitmproxydocs/layouts/partials/header.html +++ b/docs/src/themes/mitmproxydocs/layouts/partials/header.html @@ -13,10 +13,13 @@ {{ with .Site.Params.author }} <meta name="author" content="{{ . }}"> {{ end }} - <link rel="stylesheet" href="/css/style.css"> + + {{ $style := resources.Get "style.scss" | toCSS | minify }} + <link rel="stylesheet" href="{{ $style.Permalink }}"> + {{ if .RSSLink -}} <link href="{{ .RSSLink }}" rel="feed" type="application/rss+xml" title="{{ .Site.Title }}"> {{- end }} - {{ .Hugo.Generator }} + {{ hugo.Generator }} </head> <body> diff --git a/docs/yarn.lock b/docs/yarn.lock deleted file mode 100644 index 5f5b2ee6..00000000 --- a/docs/yarn.lock +++ /dev/null @@ -1,1203 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - -ajv@^5.1.0: - version "5.5.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - -are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -async-foreach@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.2.1, aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - -brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -bulma@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.6.1.tgz#5f21a77c0c06f7d80051c06628c23516081bd649" - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - -caseless@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@^2.9.0: - version "2.12.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -cross-spawn@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - dependencies: - array-find-index "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -extend@~3.0.0, extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fstream@^1.0.0, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gaze@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" - dependencies: - globule "^1.0.0" - -generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - dependencies: - is-property "^1.0.0" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globule@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" - dependencies: - glob "~7.1.1" - lodash "~4.17.4" - minimatch "~3.0.2" - -graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" - dependencies: - chalk "^1.1.1" - commander "^2.9.0" - is-my-json-valid "^2.12.4" - pinkie-promise "^2.0.0" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - -hosted-git-info@^2.1.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -in-publish@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@~2.0.0, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-my-json-valid@^2.12.4: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" - -is-property@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -js-base64@^2.1.8: - version "2.4.0" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -jsonpointer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - -lodash.clonedeep@^4.3.2: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - -lodash.mergewith@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" - -lodash@^4.0.0, lodash@~4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - -meow@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.1.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -nan@^2.3.2: - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" - -node-gyp@^3.3.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - minimatch "^3.0.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3 || 4" - osenv "0" - request "2" - rimraf "2" - semver "~5.3.0" - tar "^2.0.0" - which "1" - -node-sass@^4.7.2: - version "4.7.2" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e" - dependencies: - async-foreach "^0.1.3" - chalk "^1.1.1" - cross-spawn "^3.0.0" - gaze "^1.0.0" - get-stdin "^4.0.1" - glob "^7.0.3" - in-publish "^2.0.0" - lodash.assign "^4.2.0" - lodash.clonedeep "^4.3.2" - lodash.mergewith "^4.6.0" - meow "^3.7.0" - mkdirp "^0.5.1" - nan "^2.3.2" - node-gyp "^3.3.1" - npmlog "^4.0.0" - request "~2.79.0" - sass-graph "^2.2.4" - stdout-stream "^1.4.0" - "true-case-path" "^1.0.2" - -"nopt@2 || 3": - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -oauth-sign@~0.8.1, oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.3.0: - version "6.3.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" - -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -readable-stream@^2.0.1, readable-stream@^2.0.6: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@2: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -request@~2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - uuid "^3.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -rimraf@2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -sass-graph@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" - dependencies: - glob "^7.0.0" - lodash "^4.0.0" - scss-tokenizer "^0.2.3" - yargs "^7.0.0" - -scss-tokenizer@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" - dependencies: - js-base64 "^2.1.8" - source-map "^0.4.2" - -"semver@2 || 3 || 4 || 5": - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - -source-map@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -stdout-stream@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" - dependencies: - readable-stream "^2.0.1" - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -stringstream@~0.0.4, stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -tar@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -tough-cookie@~2.3.0, tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - -"true-case-path@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" - dependencies: - glob "^6.0.4" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tunnel-agent@~0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -uuid@^3.0.0, uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - -which@1, which@^1.2.9: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - dependencies: - string-width "^1.0.2" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -xtend@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - dependencies: - camelcase "^3.0.0" - -yargs@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" diff --git a/examples/addons/events-http-specific.py b/examples/addons/events-http-specific.py new file mode 100644 index 00000000..37d9f91a --- /dev/null +++ b/examples/addons/events-http-specific.py @@ -0,0 +1,42 @@ +import mitmproxy.http + + +class Events: + # HTTP lifecycle + def http_connect(self, flow: mitmproxy.http.HTTPFlow): + """ + An HTTP CONNECT request was received. Setting a non 2xx response on + the flow will return the response to the client abort the + connection. CONNECT requests and responses do not generate the usual + HTTP handler events. CONNECT requests are only valid in regular and + upstream proxy modes. + """ + + def requestheaders(self, flow: mitmproxy.http.HTTPFlow): + """ + HTTP request headers were successfully read. At this point, the body + is empty. + """ + + def request(self, flow: mitmproxy.http.HTTPFlow): + """ + The full HTTP request has been read. + """ + + def responseheaders(self, flow: mitmproxy.http.HTTPFlow): + """ + HTTP response headers were successfully read. At this point, the body + is empty. + """ + + def response(self, flow: mitmproxy.http.HTTPFlow): + """ + The full HTTP response has been read. + """ + + def error(self, flow: mitmproxy.http.HTTPFlow): + """ + An HTTP error has occurred, e.g. invalid server responses, or + interrupted connections. This is distinct from a valid server HTTP + error response, which is simply a response with an HTTP error code. + """ diff --git a/examples/addons/events-tcp-specific.py b/examples/addons/events-tcp-specific.py new file mode 100644 index 00000000..d150d0f9 --- /dev/null +++ b/examples/addons/events-tcp-specific.py @@ -0,0 +1,25 @@ +import mitmproxy.tcp + + +class Events: + # TCP lifecycle + def tcp_start(self, flow: mitmproxy.tcp.TCPFlow): + """ + A TCP connection has started. + """ + + def tcp_message(self, flow: mitmproxy.tcp.TCPFlow): + """ + A TCP connection has received a message. The most recent message + will be flow.messages[-1]. The message is user-modifiable. + """ + + def tcp_error(self, flow: mitmproxy.tcp.TCPFlow): + """ + A TCP error has occurred. + """ + + def tcp_end(self, flow: mitmproxy.tcp.TCPFlow): + """ + A TCP connection has ended. + """ diff --git a/examples/addons/events-websocket-specific.py b/examples/addons/events-websocket-specific.py new file mode 100644 index 00000000..60069fdb --- /dev/null +++ b/examples/addons/events-websocket-specific.py @@ -0,0 +1,36 @@ +import mitmproxy.http +import mitmproxy.websocket + + +class Events: + # Websocket lifecycle + def websocket_handshake(self, flow: mitmproxy.http.HTTPFlow): + """ + Called when a client wants to establish a WebSocket connection. The + WebSocket-specific headers can be manipulated to alter the + handshake. The flow object is guaranteed to have a non-None request + attribute. + """ + + def websocket_start(self, flow: mitmproxy.websocket.WebSocketFlow): + """ + A websocket connection has commenced. + """ + + def websocket_message(self, flow: mitmproxy.websocket.WebSocketFlow): + """ + Called when a WebSocket message is received from the client or + server. The most recent message will be flow.messages[-1]. The + message is user-modifiable. Currently there are two types of + messages, corresponding to the BINARY and TEXT frame types. + """ + + def websocket_error(self, flow: mitmproxy.websocket.WebSocketFlow): + """ + A websocket connection has had an error. + """ + + def websocket_end(self, flow: mitmproxy.websocket.WebSocketFlow): + """ + A websocket connection has ended. + """ diff --git a/examples/addons/events.py b/examples/addons/events.py index f83c8f11..958e7d39 100644 --- a/examples/addons/events.py +++ b/examples/addons/events.py @@ -10,99 +10,6 @@ import mitmproxy.proxy.protocol class Events: - # HTTP lifecycle - def http_connect(self, flow: mitmproxy.http.HTTPFlow): - """ - An HTTP CONNECT request was received. Setting a non 2xx response on - the flow will return the response to the client abort the - connection. CONNECT requests and responses do not generate the usual - HTTP handler events. CONNECT requests are only valid in regular and - upstream proxy modes. - """ - - def requestheaders(self, flow: mitmproxy.http.HTTPFlow): - """ - HTTP request headers were successfully read. At this point, the body - is empty. - """ - - def request(self, flow: mitmproxy.http.HTTPFlow): - """ - The full HTTP request has been read. - """ - - def responseheaders(self, flow: mitmproxy.http.HTTPFlow): - """ - HTTP response headers were successfully read. At this point, the body - is empty. - """ - - def response(self, flow: mitmproxy.http.HTTPFlow): - """ - The full HTTP response has been read. - """ - - def error(self, flow: mitmproxy.http.HTTPFlow): - """ - An HTTP error has occurred, e.g. invalid server responses, or - interrupted connections. This is distinct from a valid server HTTP - error response, which is simply a response with an HTTP error code. - """ - - # TCP lifecycle - def tcp_start(self, flow: mitmproxy.tcp.TCPFlow): - """ - A TCP connection has started. - """ - - def tcp_message(self, flow: mitmproxy.tcp.TCPFlow): - """ - A TCP connection has received a message. The most recent message - will be flow.messages[-1]. The message is user-modifiable. - """ - - def tcp_error(self, flow: mitmproxy.tcp.TCPFlow): - """ - A TCP error has occurred. - """ - - def tcp_end(self, flow: mitmproxy.tcp.TCPFlow): - """ - A TCP connection has ended. - """ - - # Websocket lifecycle - def websocket_handshake(self, flow: mitmproxy.http.HTTPFlow): - """ - Called when a client wants to establish a WebSocket connection. The - WebSocket-specific headers can be manipulated to alter the - handshake. The flow object is guaranteed to have a non-None request - attribute. - """ - - def websocket_start(self, flow: mitmproxy.websocket.WebSocketFlow): - """ - A websocket connection has commenced. - """ - - def websocket_message(self, flow: mitmproxy.websocket.WebSocketFlow): - """ - Called when a WebSocket message is received from the client or - server. The most recent message will be flow.messages[-1]. The - message is user-modifiable. Currently there are two types of - messages, corresponding to the BINARY and TEXT frame types. - """ - - def websocket_error(self, flow: mitmproxy.websocket.WebSocketFlow): - """ - A websocket connection has had an error. - """ - - def websocket_end(self, flow: mitmproxy.websocket.WebSocketFlow): - """ - A websocket connection has ended. - """ - # Network lifecycle def clientconnect(self, layer: mitmproxy.proxy.protocol.Layer): """ diff --git a/examples/complex/README.md b/examples/complex/README.md index c53503e4..923aadf1 100644 --- a/examples/complex/README.md +++ b/examples/complex/README.md @@ -2,6 +2,7 @@ | Filename | Description | |:-------------------------|:----------------------------------------------------------------------------------------------| +| block_dns_over_https.py | Use mitmproxy to block DNS over HTTPS (DoH) queries | | change_upstream_proxy.py | Dynamically change the upstream proxy. | | dns_spoofing.py | Use mitmproxy in a DNS spoofing scenario. | | dup_and_replay.py | Duplicates each request, changes it, and then replays the modified request. | diff --git a/examples/complex/block_dns_over_https.py b/examples/complex/block_dns_over_https.py new file mode 100644 index 00000000..479f0baa --- /dev/null +++ b/examples/complex/block_dns_over_https.py @@ -0,0 +1,177 @@ +""" +This module is for blocking DNS over HTTPS requests. + +It loads a blocklist of IPs and hostnames that are known to serve DNS over HTTPS requests. +It also uses headers, query params, and paths to detect DoH (and block it) +""" +from typing import List + +from mitmproxy import ctx + +# known DoH providers' hostnames and IP addresses to block +default_blocklist: dict = { + "hostnames": [ + "dns.adguard.com", "dns-family.adguard.com", "dns.google", "cloudflare-dns.com", + "mozilla.cloudflare-dns.com", "security.cloudflare-dns.com", "family.cloudflare-dns.com", + "dns.quad9.net", "dns9.quad9.net", "dns10.quad9.net", "dns11.quad9.net", "doh.opendns.com", + "doh.familyshield.opendns.com", "doh.cleanbrowsing.org", "doh.xfinity.com", "dohdot.coxlab.net", + "odvr.nic.cz", "doh.dnslify.com", "dns.nextdns.io", "dns.dnsoverhttps.net", "doh.crypto.sx", + "doh.powerdns.org", "doh-fi.blahdns.com", "doh-jp.blahdns.com", "doh-de.blahdns.com", + "doh.ffmuc.net", "dns.dns-over-https.com", "doh.securedns.eu", "dns.rubyfish.cn", + "dns.containerpi.com", "dns.containerpi.com", "dns.containerpi.com", "doh-2.seby.io", + "doh.seby.io", "commons.host", "doh.dnswarden.com", "doh.dnswarden.com", "doh.dnswarden.com", + "dns-nyc.aaflalo.me", "dns.aaflalo.me", "doh.applied-privacy.net", "doh.captnemo.in", + "doh.tiar.app", "doh.tiarap.org", "doh.dns.sb", "rdns.faelix.net", "doh.li", "doh.armadillodns.net", + "jp.tiar.app", "jp.tiarap.org", "doh.42l.fr", "dns.hostux.net", "dns.hostux.net", "dns.aa.net.uk", + "adblock.mydns.network", "ibksturm.synology.me", "jcdns.fun", "ibuki.cgnat.net", "dns.twnic.tw", + "example.doh.blockerdns.com", "dns.digitale-gesellschaft.ch", "doh.libredns.gr", + "doh.centraleu.pi-dns.com", "doh.northeu.pi-dns.com", "doh.westus.pi-dns.com", + "doh.eastus.pi-dns.com", "dns.flatuslifir.is", "private.canadianshield.cira.ca", + "protected.canadianshield.cira.ca", "family.canadianshield.cira.ca", "dns.google.com", + "dns.google.com" + ], + "ips": [ + "176.103.130.131", "176.103.130.130", "2a00:5a60::ad1:ff", "2a00:5a60::ad2:ff", "176.103.130.134", "176.103.130.132", + "2a00:5a60::bad2:ff", "2a00:5a60::bad1:ff", "8.8.4.4", "8.8.8.8", "2001:4860:4860::8888", "2001:4860:4860::8844", + "104.16.248.249", "104.16.249.249", "2606:4700::6810:f8f9", "2606:4700::6810:f9f9", "104.16.248.249", "104.16.249.249", + "2606:4700::6810:f9f9", "2606:4700::6810:f8f9", "104.18.2.55", "104.18.3.55", "2606:4700::6812:337", "2606:4700::6812:237", + "104.18.27.128", "104.18.26.128", "2606:4700::6812:1a80", "2606:4700::6812:1b80", "9.9.9.9", "149.112.112.112", "2620:fe::9", + "2620:fe::fe", "9.9.9.9", "149.112.112.9", "2620:fe::fe:9", "2620:fe::9", "9.9.9.10", "149.112.112.10", "2620:fe::10", + "2620:fe::fe:10", "9.9.9.11", "149.112.112.11", "2620:fe::fe:11", "2620:fe::11", "146.112.41.2", "2620:119:fc::2", + "146.112.41.3", "2620:119:fc::3", "185.228.168.168", "185.228.168.10", "96.113.151.148", "2001:558:fe21:6b:96:113:151:149", + "174.68.248.77", "185.43.135.1", "2001:148f:fffe::1", "185.235.81.1", "2a0d:4d00:81::1", "45.90.28.0", "2a07:a8c0::", + "104.236.178.232", "2604:a880:1:20::51:f001", "104.28.1.106", "104.28.0.106", "2606:4700:3036::681c:6a", + "2606:4700:3034::681c:16a", "136.144.215.158", "2a01:7c8:d002:1ef:5054:ff:fe40:3703", "95.216.212.177", + "2a01:4f9:c010:43ce::1", "45.32.55.94", "2001:19f0:7001:3259:5400:2ff:fe71:bc9", "159.69.198.101", "2a01:4f8:1c1c:6b4b::1", + "195.30.94.28", "2001:608:a01::3", "104.24.122.53", "104.24.123.53", "2606:4700:3033::6818:7b35", "2606:4700:3035::6818:7a35", + "146.185.167.43", "2a03:b0c0:0:1010::e9a:3001", "115.159.131.230", "45.77.180.10", "2001:19f0:7001:5554:5400:2ff:fe57:3077", + "45.77.180.10", "2001:19f0:7001:5554:5400:2ff:fe57:3077", "45.77.180.10", "2001:19f0:7001:5554:5400:2ff:fe57:3077", + "139.99.222.72", "45.76.113.31", "104.182.57.196", "168.235.81.167", "2604:180:f3::42", "176.56.236.175", "2a00:d880:5:bf0::7c93", + "94.130.106.88", "2a03:4000:38:53c::2", "139.59.48.222", "174.138.29.175", "2400:6180:0:d0::5f73:4001", "104.18.45.204", + "104.18.44.204", "2606:4700:3033::6812:2dcc", "2606:4700:3033::6812:2ccc", "104.31.91.138", "104.31.90.138", + "2606:4700:3035::681f:5a8a", "2606:4700:3036::681f:5b8a", "185.134.196.54", "46.227.200.55", "46.227.200.54", "185.134.197.54", + "2a01:9e00::54", "2a01:9e01::54", "2a01:9e00::55", "2a01:9e01::55", "46.101.66.244", "172.104.93.80", + "2400:8902::f03c:91ff:feda:c514", "104.18.44.204", "104.18.45.204", "2606:4700:3033::6812:2ccc", "2606:4700:3033::6812:2dcc", + "185.216.27.142", "185.26.126.37", "2001:4b98:dc2:43:216:3eff:fe86:1d28", "185.26.126.37", "2001:4b98:dc2:43:216:3eff:fe86:1d28", + "217.169.20.22", "217.169.20.23", "2001:8b0::2022", "2001:8b0::2023", "172.65.3.223", "2606:4700:60:0:a71e:6467:cef8:2a56", + "83.77.85.7", "2a02:1205:34d5:5070:b26e:bfff:fe1d:e19b", "178.62.214.105", "35.198.2.76", "210.17.9.228", + "2001:c50:ffff:1:101:101:101:101", "35.231.247.227", "185.95.218.43", "185.95.218.42", "2a05:fc84::43", "2a05:fc84::42", + "116.203.115.192", "116.202.176.26", "2a01:4f8:c2c:52bf::1", "88.198.91.187", "2a01:4f8:1c0c:8233::1", "95.216.181.228", + "2a01:4f9:c01f:4::abcd", "45.67.219.208", "2a04:bdc7:100:70::abcd", "185.213.26.187", "2a0d:5600:33:3::abcd", "46.239.223.80", + "2001:678:888:69:c45d:2738:c3f2:1878", "149.112.121.10", "149.112.122.10", "2620:10a:80bb::10", "2620:10a:80bc::10", + "149.112.121.20", "149.112.122.20", "2620:10a:80bb::20", "2620:10a:80bc::20", "149.112.121.30", "149.112.122.30", + "2620:10a:80bc::30", "2620:10a:80bb::30" + ] +} + +# additional hostnames to block +additional_doh_names: List[str] = [ + 'dns.google.com' +] + +# additional IPs to block +additional_doh_ips: List[str] = [ + +] + +doh_hostnames, doh_ips = default_blocklist['hostnames'], default_blocklist['ips'] + +# convert to sets for faster lookups +doh_hostnames = set(doh_hostnames) +doh_ips = set(doh_ips) + + +def _has_dns_message_content_type(flow): + """ + Check if HTTP request has a DNS-looking 'Content-Type' header + + :param flow: mitmproxy flow + :return: True if 'Content-Type' header is DNS-looking, False otherwise + """ + doh_content_types = ['application/dns-message'] + if 'Content-Type' in flow.request.headers: + if flow.request.headers['Content-Type'] in doh_content_types: + return True + return False + + +def _request_has_dns_query_string(flow): + """ + Check if the query string of a request contains the parameter 'dns' + + :param flow: mitmproxy flow + :return: True is 'dns' is a parameter in the query string, False otherwise + """ + return 'dns' in flow.request.query + + +def _request_is_dns_json(flow): + """ + Check if the request looks like DoH with JSON. + + The only known implementations of DoH with JSON are Cloudflare and Google. + + For more info, see: + - https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/ + - https://developers.google.com/speed/public-dns/docs/doh/json + + :param flow: mitmproxy flow + :return: True is request looks like DNS JSON, False otherwise + """ + # Header 'Accept: application/dns-json' is required in Cloudflare's DoH JSON API + # or they return a 400 HTTP response code + if 'Accept' in flow.request.headers: + if flow.request.headers['Accept'] == 'application/dns-json': + return True + # Google's DoH JSON API is https://dns.google/resolve + path = flow.request.path.split('?')[0] + if flow.request.host == 'dns.google' and path == '/resolve': + return True + return False + + +def _request_has_doh_looking_path(flow): + """ + Check if the path looks like it's DoH. + Most common one is '/dns-query', likely because that's what's in the RFC + + :param flow: mitmproxy flow + :return: True if path looks like it's DoH, otherwise False + """ + doh_paths = [ + '/dns-query', # used in example in RFC 8484 (see https://tools.ietf.org/html/rfc8484#section-4.1.1) + ] + path = flow.request.path.split('?')[0] + return path in doh_paths + + +def _requested_hostname_is_in_doh_blacklist(flow): + """ + Check if server hostname is in our DoH provider blacklist. + + The current blacklist is taken from https://github.com/curl/curl/wiki/DNS-over-HTTPS. + + :param flow: mitmproxy flow + :return: True if server's hostname is in DoH blacklist, otherwise False + """ + hostname = flow.request.host + ip = flow.server_conn.address + return hostname in doh_hostnames or hostname in doh_ips or ip in doh_ips + + +doh_request_detection_checks = [ + _has_dns_message_content_type, + _request_has_dns_query_string, + _request_is_dns_json, + _requested_hostname_is_in_doh_blacklist, + _request_has_doh_looking_path +] + + +def request(flow): + for check in doh_request_detection_checks: + is_doh = check(flow) + if is_doh: + ctx.log.warn("[DoH Detection] DNS over HTTPS request detected via method \"%s\"" % check.__name__) + flow.kill() + break diff --git a/examples/complex/nonblocking.py b/examples/complex/nonblocking.py index 72c9c0ab..dd74aec0 100644 --- a/examples/complex/nonblocking.py +++ b/examples/complex/nonblocking.py @@ -1,12 +1,11 @@ import time from mitmproxy.script import concurrent -from mitmproxy import ctx @concurrent # Remove this and see what happens def request(flow): - # You don't want to use mitmproxy.ctx from a different thread - ctx.log.info("handle request: %s%s" % (flow.request.host, flow.request.path)) + # This is ugly in mitmproxy's UI, but you don't want to use mitmproxy.ctx.log from a different thread. + print("handle request: %s%s" % (flow.request.host, flow.request.path)) time.sleep(5) - ctx.log.info("start request: %s%s" % (flow.request.host, flow.request.path)) + print("start request: %s%s" % (flow.request.host, flow.request.path)) diff --git a/examples/complex/websocket_inject_message.py b/examples/complex/websocket_inject_message.py index e9c3ea0c..38be5555 100644 --- a/examples/complex/websocket_inject_message.py +++ b/examples/complex/websocket_inject_message.py @@ -13,7 +13,7 @@ class InjectWebSocketMessage: i = 0 while not flow.ended and not flow.error: await asyncio.sleep(5) - flow.inject_message(flow.client_conn, 'This is the #{} an injected message!'.format(i)) + flow.inject_message(flow.client_conn, 'This is the #{} injected message!'.format(i)) i += 1 def websocket_start(self, flow): diff --git a/examples/simple/websocket_messages.py b/examples/simple/websocket_messages.py index 719e7b10..071ea21f 100644 --- a/examples/simple/websocket_messages.py +++ b/examples/simple/websocket_messages.py @@ -6,8 +6,15 @@ def websocket_message(flow): # get the latest message message = flow.messages[-1] - # simply print the content of the message - ctx.log.info(message.content) + # was the message sent from the client or server? + if message.from_client: + ctx.log.info("Client sent a message: {}".format(message.content)) + else: + ctx.log.info("Server sent a message: {}".format(message.content)) # manipulate the message content message.content = re.sub(r'^Hello', 'HAPPY', message.content) + + if 'FOOBAR' in message.content: + # kill the message and not send it to the other endpoint + message.kill() diff --git a/examples/simple/wsgi_flask_app.py b/examples/simple/wsgi_flask_app.py index 4be38000..bbde6913 100644 --- a/examples/simple/wsgi_flask_app.py +++ b/examples/simple/wsgi_flask_app.py @@ -14,12 +14,12 @@ def hello_world() -> str: return 'Hello World!' -def load(l): +addons = [ # Host app at the magic domain "proxapp.local" on port 80. Requests to this # domain and port combination will now be routed to the WSGI app instance. - return wsgiapp.WSGIApp(app, "proxapp.local", 80) - + wsgiapp.WSGIApp(app, "proxapp.local", 80) # SSL works too, but the magic domain needs to be resolvable from the mitmproxy machine due to mitmproxy's design. # mitmproxy will connect to said domain and use serve its certificate (unless --no-upstream-cert is set) # but won't send any data. # mitmproxy.ctx.master.apps.add(app, "example.com", 443) +] diff --git a/mitmproxy/__init__.py b/mitmproxy/__init__.py index e69de29b..e930cf1e 100644 --- a/mitmproxy/__init__.py +++ b/mitmproxy/__init__.py @@ -0,0 +1,8 @@ +import asyncio +import sys + +if sys.platform == 'win32': + # workaround for + # https://github.com/tornadoweb/tornado/issues/2751 + # https://www.tornadoweb.org/en/stable/index.html#installation + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) diff --git a/mitmproxy/addons/browser.py b/mitmproxy/addons/browser.py index e74b50db..5735698b 100644 --- a/mitmproxy/addons/browser.py +++ b/mitmproxy/addons/browser.py @@ -73,4 +73,4 @@ class Browser: self.browser.kill() self.tdir.cleanup() self.browser = None - self.tdir = None + self.tdir = None
\ No newline at end of file diff --git a/mitmproxy/addons/onboardingapp/templates/index.html b/mitmproxy/addons/onboardingapp/templates/index.html index aa471668..aee6858c 100644 --- a/mitmproxy/addons/onboardingapp/templates/index.html +++ b/mitmproxy/addons/onboardingapp/templates/index.html @@ -135,20 +135,20 @@ function changeTo(device) { <h2 class="text-center"> Click to install your mitmproxy certificate </h2> <div id="certbank" class="row"> <div class="col-md-3"> - <a target="_blank" onclick="changeTo('apple')" href="/cert/pem"><i class="fa fa-apple fa-5x"></i></a> - <p>Apple</p> + <a target="_blank" onclick="changeTo('apple')" href="/cert/pem"><i class="fa fa-apple fa-5x"></i> + <p>Apple</p></a> </div> <div class="col-md-3"> - <a target="_blank" onclick="changeTo('windows')" href="/cert/p12"><i class="fa fa-windows fa-5x"></i></a> - <p>Windows</p> + <a target="_blank" onclick="changeTo('windows')" href="/cert/p12"><i class="fa fa-windows fa-5x"></i> + <p>Windows</p></a> </div> <div class="col-md-3"> - <a target="_blank" onclick="changeTo('android')" href="/cert/pem"><i class="fa fa-android fa-5x"></i></a> - <p>Android</p> + <a target="_blank" onclick="changeTo('android')" href="/cert/pem"><i class="fa fa-android fa-5x"></i> + <p>Android</p></a> </div> <div class="col-md-3"> - <a target="_blank" onclick="changeTo('asterisk')" href="/cert/pem"><i class="fa fa-asterisk fa-5x"></i></a> - <p>Other</p> + <a target="_blank" onclick="changeTo('asterisk')" href="/cert/pem"><i class="fa fa-asterisk fa-5x"></i> + <p>Other</p></a> </div> </div> diff --git a/mitmproxy/addons/script.py b/mitmproxy/addons/script.py index 3b2568c9..b3cb0999 100644 --- a/mitmproxy/addons/script.py +++ b/mitmproxy/addons/script.py @@ -105,11 +105,14 @@ class Script: # We're already running, so we have to explicitly register and # configure the addon ctx.master.addons.invoke_addon(self.ns, "running") - ctx.master.addons.invoke_addon( - self.ns, - "configure", - ctx.options.keys() - ) + try: + ctx.master.addons.invoke_addon( + self.ns, + "configure", + ctx.options.keys() + ) + except exceptions.OptionsError as e: + script_error_handler(self.fullpath, e, msg=str(e)) async def watcher(self): last_mtime = 0 diff --git a/mitmproxy/certs.py b/mitmproxy/certs.py index d574c027..a37d29bc 100644 --- a/mitmproxy/certs.py +++ b/mitmproxy/certs.py @@ -15,8 +15,8 @@ import OpenSSL from mitmproxy.coretypes import serializable # Default expiry must not be too long: https://github.com/mitmproxy/mitmproxy/issues/815 -DEFAULT_EXP = 94608000 # = 24 * 60 * 60 * 365 * 3 -DEFAULT_EXP_DUMMY_CERT = 63072000 # = 2 years +DEFAULT_EXP = 94608000 # = 60 * 60 * 24 * 365 * 3 = 3 years +DEFAULT_EXP_DUMMY_CERT = 31536000 # = 60 * 60 * 24 * 365 = 1 year # Generated with "openssl dhparam". It's too slow to generate this on startup. DEFAULT_DHPARAM = b""" diff --git a/mitmproxy/command.py b/mitmproxy/command.py index 48f9051e..49cb959e 100644 --- a/mitmproxy/command.py +++ b/mitmproxy/command.py @@ -103,7 +103,7 @@ class Command: except TypeError: expected = f'Expected: {str(self.signature.parameters)}' received = f'Received: {str(args)}' - raise exceptions.CommandError(f"Command argument mismatch: \n\t{expected}\n\t{received}") + raise exceptions.CommandError(f"Command argument mismatch: \n {expected}\n {received}") for name, value in bound_arguments.arguments.items(): convert_to = self.signature.parameters[name].annotation @@ -149,9 +149,10 @@ class CommandManager: if not i.startswith("__"): o = getattr(addon, i) try: - is_command = hasattr(o, "command_name") + # hasattr is not enough, see https://github.com/mitmproxy/mitmproxy/issues/3794 + is_command = isinstance(getattr(o, "command_name", None), str) except Exception: - pass # hasattr may raise if o implements __getattr__. + pass # getattr may raise if o implements __getattr__. else: if is_command: try: @@ -241,7 +242,7 @@ class CommandManager: raise exceptions.CommandError("Unknown command: %s" % command_name) return self.commands[command_name].func(*args) - def _call_strings(self, command_name: str, args: typing.Sequence[str]) -> typing.Any: + def call_strings(self, command_name: str, args: typing.Sequence[str]) -> typing.Any: """ Call a command using a list of string arguments. May raise CommandError. """ @@ -262,7 +263,7 @@ class CommandManager: for part in parts if part.type != mitmproxy.types.Space ] - return self._call_strings(command_name, args) + return self.call_strings(command_name, args) def dump(self, out=sys.stdout) -> None: cmds = list(self.commands.values()) @@ -284,7 +285,7 @@ def parsearg(manager: CommandManager, spec: str, argtype: type) -> typing.Any: try: return t.parse(manager, argtype, spec) except exceptions.TypeError as e: - raise exceptions.CommandError from e + raise exceptions.CommandError(str(e)) from e def command(name: typing.Optional[str] = None): diff --git a/mitmproxy/net/check.py b/mitmproxy/net/check.py index a19ad6fe..ffb5e163 100644 --- a/mitmproxy/net/check.py +++ b/mitmproxy/net/check.py @@ -2,7 +2,8 @@ import ipaddress import re # Allow underscore in host name -_label_valid = re.compile(br"(?!-)[A-Z\d\-_]{1,63}(?<!-)$", re.IGNORECASE) +# Note: This could be a DNS label, a hostname, a FQDN, or an IP +_label_valid = re.compile(br"[A-Z\d\-_]{1,63}$", re.IGNORECASE) def is_valid_host(host: bytes) -> bool: diff --git a/mitmproxy/net/http/headers.py b/mitmproxy/net/http/headers.py index 8a58cbbc..baed7e06 100644 --- a/mitmproxy/net/http/headers.py +++ b/mitmproxy/net/http/headers.py @@ -162,8 +162,12 @@ class Headers(multidict.MultiDict): pattern = re.compile(pattern, flags) replacements = 0 flag_count = count > 0 + count_reached = False fields = [] for name, value in self.fields: + if count_reached: + fields.append((name, value)) + continue line, n = pattern.subn(repl, name + b": " + value, count=count) try: name, value = line.split(b": ", 1) @@ -173,10 +177,12 @@ class Headers(multidict.MultiDict): pass else: replacements += n + fields.append((name, value)) if flag_count: count -= n if count == 0: - break + count_reached = True + continue fields.append((name, value)) self.fields = tuple(fields) return replacements diff --git a/mitmproxy/net/http/http1/assemble.py b/mitmproxy/net/http/http1/assemble.py index 8b7246f7..d30a74a1 100644 --- a/mitmproxy/net/http/http1/assemble.py +++ b/mitmproxy/net/http/http1/assemble.py @@ -1,4 +1,3 @@ -import mitmproxy.net.http.url from mitmproxy import exceptions @@ -78,15 +77,7 @@ def _assemble_request_headers(request_data): Args: request_data (mitmproxy.net.http.request.RequestData) """ - headers = request_data.headers - if "host" not in headers and request_data.scheme and request_data.host and request_data.port: - headers = headers.copy() - headers["host"] = mitmproxy.net.http.url.hostport( - request_data.scheme, - request_data.host, - request_data.port - ) - return bytes(headers) + return bytes(request_data.headers) def _assemble_response_line(response_data): diff --git a/mitmproxy/net/http/http1/read.py b/mitmproxy/net/http/http1/read.py index 294e8358..0fc03f1b 100644 --- a/mitmproxy/net/http/http1/read.py +++ b/mitmproxy/net/http/http1/read.py @@ -2,6 +2,8 @@ import time import sys import re +import typing + from mitmproxy.net.http import request from mitmproxy.net.http import response from mitmproxy.net.http import headers @@ -171,8 +173,15 @@ def connection_close(http_version, headers): return http_version != "HTTP/1.1" and http_version != b"HTTP/1.1" -def expected_http_body_size(request, response=None): +def expected_http_body_size( + request: request.Request, + response: typing.Optional[response.Response] = None, + expect_continue_as_0: bool = True +): """ + Args: + - expect_continue_as_0: If true, incorrectly predict a body size of 0 for requests which are waiting + for a 100 Continue response. Returns: The expected body length: - a positive integer, if the size is known in advance @@ -186,24 +195,17 @@ def expected_http_body_size(request, response=None): # http://tools.ietf.org/html/rfc7230#section-3.3 if not response: headers = request.headers - response_code = None - is_request = True - else: - headers = response.headers - response_code = response.status_code - is_request = False - - if is_request: - if headers.get("expect", "").lower() == "100-continue": + if expect_continue_as_0 and headers.get("expect", "").lower() == "100-continue": return 0 else: + headers = response.headers if request.method.upper() == "HEAD": return 0 - if 100 <= response_code <= 199: + if 100 <= response.status_code <= 199: return 0 - if response_code == 200 and request.method.upper() == "CONNECT": + if response.status_code == 200 and request.method.upper() == "CONNECT": return 0 - if response_code in (204, 304): + if response.status_code in (204, 304): return 0 if "chunked" in headers.get("transfer-encoding", "").lower(): @@ -218,9 +220,9 @@ def expected_http_body_size(request, response=None): if size < 0: raise ValueError() return size - except ValueError: - raise exceptions.HttpSyntaxException("Unparseable Content Length") - if is_request: + except ValueError as e: + raise exceptions.HttpSyntaxException("Unparseable Content Length") from e + if not response: return 0 return -1 diff --git a/mitmproxy/net/server_spec.py b/mitmproxy/net/server_spec.py index efbf1012..c877e6e1 100644 --- a/mitmproxy/net/server_spec.py +++ b/mitmproxy/net/server_spec.py @@ -1,13 +1,17 @@ """ Parse scheme, host and port from a string. """ -import collections import re +import typing from typing import Tuple from mitmproxy.net import check -ServerSpec = collections.namedtuple("ServerSpec", ["scheme", "address"]) + +class ServerSpec(typing.NamedTuple): + scheme: str + address: typing.Tuple[str, int] + server_spec_re = re.compile( r""" diff --git a/mitmproxy/net/tls.py b/mitmproxy/net/tls.py index d68a008f..d8e943d3 100644 --- a/mitmproxy/net/tls.py +++ b/mitmproxy/net/tls.py @@ -7,14 +7,13 @@ import os import struct import threading import typing -from ssl import match_hostname, CertificateError import certifi from OpenSSL import SSL from kaitaistruct import KaitaiStream -import mitmproxy.options # noqa -from mitmproxy import exceptions, certs +import mitmproxy.options +from mitmproxy import certs, exceptions from mitmproxy.contrib.kaitaistruct import tls_client_hello from mitmproxy.net import check @@ -88,7 +87,18 @@ class MasterSecretLogger: __name__ = "MasterSecretLogger" def __call__(self, connection, where, ret): - if where == SSL.SSL_CB_HANDSHAKE_DONE and ret == 1: + done_now = ( + where == SSL.SSL_CB_HANDSHAKE_DONE and ret == 1 + ) + # this is a horrendous workaround for https://github.com/mitmproxy/mitmproxy/pull/3692#issuecomment-608454530: + # OpenSSL 1.1.1f decided to not make connection.master_key() fail in the SSL_CB_HANDSHAKE_DONE callback. + # To support various OpenSSL versions and still log master secrets, we now mark connections where this has + # happened and then try again on the next event. This is ugly and shouldn't be done, but eventually we + # replace this with context.set_keylog_callback anyways. + done_previously_but_not_logged_yet = ( + hasattr(connection, "_still_needs_masterkey") + ) + if done_now or done_previously_but_not_logged_yet: with self.lock: if not self.f: d = os.path.dirname(self.filename) @@ -96,10 +106,16 @@ class MasterSecretLogger: os.makedirs(d) self.f = open(self.filename, "ab") self.f.write(b"\r\n") - client_random = binascii.hexlify(connection.client_random()) - masterkey = binascii.hexlify(connection.master_key()) - self.f.write(b"CLIENT_RANDOM %s %s\r\n" % (client_random, masterkey)) - self.f.flush() + try: + client_random = binascii.hexlify(connection.client_random()) + masterkey = binascii.hexlify(connection.master_key()) + except (AssertionError, SSL.Error): # careful: exception type changes between pyOpenSSL versions + connection._still_needs_masterkey = True + else: + self.f.write(b"CLIENT_RANDOM %s %s\r\n" % (client_random, masterkey)) + self.f.flush() + if hasattr(connection, "_still_needs_masterkey"): + delattr(connection, "_still_needs_masterkey") def close(self): with self.lock: @@ -237,33 +253,11 @@ def create_client_context( depth: int, is_cert_verified: bool ) -> bool: - if is_cert_verified and depth == 0: - # Verify hostname of leaf certificate. - cert = certs.Cert(x509) - try: - crt: typing.Dict[str, typing.Any] = dict( - subjectAltName=[("DNS", x.decode("ascii", "strict")) for x in cert.altnames] - ) - if cert.cn: - crt["subject"] = [[["commonName", cert.cn.decode("ascii", "strict")]]] - if sni: - # SNI hostnames allow support of IDN by using ASCII-Compatible Encoding - # Conversion algorithm is in RFC 3490 which is implemented by idna codec - # https://docs.python.org/3/library/codecs.html#text-encodings - # https://tools.ietf.org/html/rfc6066#section-3 - # https://tools.ietf.org/html/rfc4985#section-3 - hostname = sni.encode("idna").decode("ascii") - else: - hostname = "no-hostname" - match_hostname(crt, hostname) - except (ValueError, CertificateError) as e: - conn.cert_error = exceptions.InvalidCertificateException( - "Certificate verification error for {}: {}".format( - sni or repr(address), - str(e) - ) - ) - is_cert_verified = False + if is_cert_verified and depth == 0 and not sni: + conn.cert_error = exceptions.InvalidCertificateException( + f"Certificate verification error for {address}: Cannot validate hostname, SNI missing." + ) + is_cert_verified = False elif is_cert_verified: pass else: @@ -285,6 +279,20 @@ def create_client_context( **sslctx_kwargs, ) + if sni: + # Manually enable hostname verification on the context object. + # https://wiki.openssl.org/index.php/Hostname_validation + param = SSL._lib.SSL_CTX_get0_param(context._context) + # Matching on the CN is disabled in both Chrome and Firefox, so we disable it, too. + # https://www.chromestatus.com/feature/4981025180483584 + SSL._lib.X509_VERIFY_PARAM_set_hostflags( + param, + SSL._lib.X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS | SSL._lib.X509_CHECK_FLAG_NEVER_CHECK_SUBJECT + ) + SSL._openssl_assert( + SSL._lib.X509_VERIFY_PARAM_set1_host(param, sni.encode("idna"), 0) == 1 + ) + # Client Certs if cert: try: diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py index f42aa645..ac85f83a 100644 --- a/mitmproxy/optmanager.py +++ b/mitmproxy/optmanager.py @@ -320,8 +320,7 @@ class OptManager: update = {} for optname, optval in self.deferred.items(): if optname in self._options: - if isinstance(optval, str): - optval = self.parse_setval(self._options[optname], optval) + optval = self.parse_setval(self._options[optname], optval) update[optname] = optval self.update(**update) for k in update.keys(): diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py index e98faabf..982afb75 100644 --- a/mitmproxy/proxy/config.py +++ b/mitmproxy/proxy/config.py @@ -23,7 +23,7 @@ class HostMatcher: if self.handle in ["ignore", "tcp"]: return any(rex.search(host) for rex in self.regexes) else: # self.handle == "allow" - return any(not rex.search(host) for rex in self.regexes) + return not any(rex.search(host) for rex in self.regexes) def __bool__(self): return bool(self.patterns) diff --git a/mitmproxy/proxy/protocol/base.py b/mitmproxy/proxy/protocol/base.py index 2063f901..3bf03521 100644 --- a/mitmproxy/proxy/protocol/base.py +++ b/mitmproxy/proxy/protocol/base.py @@ -160,10 +160,10 @@ class ServerConnectionMixin: """ if not self.server_conn.address: raise exceptions.ProtocolException("Cannot connect to server, no server address given.") - self.log("serverconnect", "debug", [repr(self.server_conn.address)]) - self.channel.ask("serverconnect", self.server_conn) try: self.server_conn.connect() + self.log("serverconnect", "debug", [repr(self.server_conn.address)]) + self.channel.ask("serverconnect", self.server_conn) except exceptions.TcpException as e: raise exceptions.ProtocolException( "Server connection to {} failed: {}".format( diff --git a/mitmproxy/proxy/protocol/http.py b/mitmproxy/proxy/protocol/http.py index 4c20617b..37e1669e 100644 --- a/mitmproxy/proxy/protocol/http.py +++ b/mitmproxy/proxy/protocol/http.py @@ -1,3 +1,5 @@ +import textwrap + import h2.exceptions import time import enum @@ -142,13 +144,13 @@ def validate_request_form(mode, request): allowed_request_forms = MODE_REQUEST_FORMS[mode] if request.first_line_format not in allowed_request_forms: if mode == HTTPMode.transparent: - err_message = ( + err_message = textwrap.dedent(( """ Mitmproxy received an {} request even though it is not running in regular mode. This usually indicates a misconfiguration, please see the mitmproxy mode documentation for details. """ - ).format("HTTP CONNECT" if request.first_line_format == "authority" else "absolute-form") + )).strip().format("HTTP CONNECT" if request.first_line_format == "authority" else "absolute-form") else: err_message = "Invalid HTTP request form (expected: %s, got: %s)" % ( " or ".join(allowed_request_forms), request.first_line_format diff --git a/mitmproxy/proxy/protocol/http2.py b/mitmproxy/proxy/protocol/http2.py index a5870e6c..f5e7b1c6 100644 --- a/mitmproxy/proxy/protocol/http2.py +++ b/mitmproxy/proxy/protocol/http2.py @@ -87,6 +87,18 @@ class Http2Layer(base.Layer): # mypy type hints client_conn: connections.ClientConnection = None + class H2ConnLogger: + def __init__(self, name, log): + self.name = name + self.log = log + + def debug(self, fmtstr, *args): + msg = "H2Conn {}: {}".format(self.name, fmtstr % args) + self.log(msg, "debug") + + def trace(self, fmtstr, *args): + pass + def __init__(self, ctx, mode: str) -> None: super().__init__(ctx) self.mode = mode @@ -98,7 +110,8 @@ class Http2Layer(base.Layer): client_side=False, header_encoding=False, validate_outbound_headers=False, - validate_inbound_headers=False) + validate_inbound_headers=False, + logger=self.H2ConnLogger("client", self.log)) self.connections[self.client_conn] = SafeH2Connection(self.client_conn, config=config) def _initiate_server_conn(self): @@ -107,7 +120,8 @@ class Http2Layer(base.Layer): client_side=True, header_encoding=False, validate_outbound_headers=False, - validate_inbound_headers=False) + validate_inbound_headers=False, + logger=self.H2ConnLogger("server", self.log)) self.connections[self.server_conn] = SafeH2Connection(self.server_conn, config=config) self.connections[self.server_conn].initiate_connection() self.server_conn.send(self.connections[self.server_conn].data_to_send()) @@ -195,10 +209,12 @@ class Http2Layer(base.Layer): else: self.streams[eid].data_queue.put(event.data) self.streams[eid].queued_data_length += len(event.data) - self.connections[source_conn].safe_acknowledge_received_data( - event.flow_controlled_length, - event.stream_id - ) + + # always acknowledge receved data with a WINDOW_UPDATE frame + self.connections[source_conn].safe_acknowledge_received_data( + event.flow_controlled_length, + event.stream_id + ) return True def _handle_stream_ended(self, eid): @@ -209,13 +225,12 @@ class Http2Layer(base.Layer): def _handle_stream_reset(self, eid, event, is_server, other_conn): if eid in self.streams: self.streams[eid].kill() - if event.error_code == h2.errors.ErrorCodes.CANCEL: - if is_server: - other_stream_id = self.streams[eid].client_stream_id - else: - other_stream_id = self.streams[eid].server_stream_id - if other_stream_id is not None: - self.connections[other_conn].safe_reset_stream(other_stream_id, event.error_code) + if is_server: + other_stream_id = self.streams[eid].client_stream_id + else: + other_stream_id = self.streams[eid].server_stream_id + if other_stream_id is not None: + self.connections[other_conn].safe_reset_stream(other_stream_id, event.error_code) return True def _handle_remote_settings_changed(self, event, other_conn): @@ -461,7 +476,7 @@ class Http2SingleStreamLayer(httpbase._HttpTransmissionLayer, basethread.BaseThr if self.zombie is not None or connection_closed: if pre_command is not None: pre_command() - raise exceptions.Http2ZombieException("Connection already dead") + raise exceptions.Http2ZombieException("Connection or stream already dead: {}, {}".format(self.zombie, connection_closed)) @detect_zombie_stream def read_request_headers(self, flow): @@ -643,7 +658,8 @@ class Http2SingleStreamLayer(httpbase._HttpTransmissionLayer, basethread.BaseThr try: layer() except exceptions.Http2ZombieException: # pragma: no cover - pass + # zombies can be safely terminated - no need to kill them twice + return except exceptions.ProtocolException as e: # pragma: no cover self.log(repr(e), "info") except exceptions.SetServerNotAllowedException as e: # pragma: no cover diff --git a/mitmproxy/proxy/protocol/rawtcp.py b/mitmproxy/proxy/protocol/rawtcp.py index 0ec50594..00bba04c 100644 --- a/mitmproxy/proxy/protocol/rawtcp.py +++ b/mitmproxy/proxy/protocol/rawtcp.py @@ -29,13 +29,20 @@ class RawTCPLayer(base.Layer): server = self.server_conn.connection conns = [client, server] + # https://github.com/openssl/openssl/issues/6234 + for conn in conns: + if isinstance(conn, SSL.Connection) and hasattr(SSL._lib, "SSL_clear_mode"): + SSL._lib.SSL_clear_mode(conn._ssl, SSL._lib.SSL_MODE_AUTO_RETRY) + try: while not self.channel.should_exit.is_set(): r = mitmproxy.net.tcp.ssl_read_select(conns, 10) for conn in r: dst = server if conn == client else client - - size = conn.recv_into(buf, self.chunk_size) + try: + size = conn.recv_into(buf, self.chunk_size) + except (SSL.WantReadError, SSL.WantWriteError): + continue if not size: conns.remove(conn) # Shutdown connection to the other peer diff --git a/mitmproxy/tools/_main.py b/mitmproxy/tools/_main.py index b98bbe90..c1dd6179 100644 --- a/mitmproxy/tools/_main.py +++ b/mitmproxy/tools/_main.py @@ -113,12 +113,12 @@ def run( opts.update(**extra(args)) loop = asyncio.get_event_loop() - for signame in ('SIGINT', 'SIGTERM'): - try: - loop.add_signal_handler(getattr(signal, signame), getattr(master, "prompt_for_exit", master.shutdown)) - except NotImplementedError: - # Not supported on Windows - pass + try: + loop.add_signal_handler(signal.SIGINT, getattr(master, "prompt_for_exit", master.shutdown)) + loop.add_signal_handler(signal.SIGTERM, master.shutdown) + except NotImplementedError: + # Not supported on Windows + pass # Make sure that we catch KeyboardInterrupts on Windows. # https://stackoverflow.com/a/36925722/934719 diff --git a/mitmproxy/tools/cmdline.py b/mitmproxy/tools/cmdline.py index e9ff973f..9c8eae8a 100644 --- a/mitmproxy/tools/cmdline.py +++ b/mitmproxy/tools/cmdline.py @@ -127,7 +127,7 @@ def mitmweb(opts): group = parser.add_argument_group("Mitmweb") opts.make_parser(group, "web_open_browser") opts.make_parser(group, "web_port", metavar="PORT") - opts.make_parser(group, "web_iface", metavar="INTERFACE") + opts.make_parser(group, "web_host", metavar="HOST") common_options(parser, opts) group = parser.add_argument_group( diff --git a/mitmproxy/tools/console/commandexecutor.py b/mitmproxy/tools/console/commandexecutor.py index c738e349..1c6d5aa6 100644 --- a/mitmproxy/tools/console/commandexecutor.py +++ b/mitmproxy/tools/console/commandexecutor.py @@ -2,6 +2,7 @@ import typing from mitmproxy import exceptions from mitmproxy import flow +from mitmproxy import ctx from mitmproxy.tools.console import overlay from mitmproxy.tools.console import signals @@ -15,8 +16,8 @@ class CommandExecutor: if cmd.strip(): try: ret = self.master.commands.execute(cmd) - except exceptions.CommandError as v: - signals.status_message.send(message=str(v)) + except exceptions.CommandError as e: + ctx.log.error(str(e)) else: if ret: if type(ret) == typing.Sequence[flow.Flow]: diff --git a/mitmproxy/tools/console/common.py b/mitmproxy/tools/console/common.py index 325c5740..3dce8363 100644 --- a/mitmproxy/tools/console/common.py +++ b/mitmproxy/tools/console/common.py @@ -543,7 +543,7 @@ def format_flow(f, focus, extended=False, hostheader=False, cols=False, layout=' duration = None if f.response.timestamp_end and f.request.timestamp_start: - duration = f.response.timestamp_end - f.request.timestamp_start + duration = max([f.response.timestamp_end - f.request.timestamp_start, 0]) d.update(dict( resp_code=f.response.status_code, diff --git a/mitmproxy/tools/console/consoleaddons.py b/mitmproxy/tools/console/consoleaddons.py index 7fcd9b48..905653e7 100644 --- a/mitmproxy/tools/console/consoleaddons.py +++ b/mitmproxy/tools/console/consoleaddons.py @@ -160,7 +160,7 @@ class ConsoleAddon: fv = self.master.window.current("options") if not fv: raise exceptions.CommandError("Not viewing options.") - self.master.commands.execute("options.reset.one %s" % fv.current_name()) + self.master.commands.call_strings("options.reset.one", [fv.current_name()]) @command.command("console.nav.start") def nav_start(self) -> None: @@ -248,12 +248,11 @@ class ConsoleAddon: def callback(opt): # We're now outside of the call context... - repl = cmd + " " + " ".join(args) - repl = repl.replace("{choice}", opt) + repl = [arg.replace("{choice}", opt) for arg in args] try: - self.master.commands.execute(repl) + self.master.commands.call_strings(cmd, repl) except exceptions.CommandError as e: - signals.status_message.send(message=str(e)) + ctx.log.error(str(e)) self.master.overlay( overlay.Chooser(self.master, prompt, choices, "", callback) @@ -276,12 +275,11 @@ class ConsoleAddon: def callback(opt): # We're now outside of the call context... - repl = " ".join(command_lexer.quote(x) for x in args) - repl = repl.replace("{choice}", opt) + repl = [arg.replace("{choice}", opt) for arg in args] try: - self.master.commands.execute(subcmd + " " + repl) + self.master.commands.call_strings(subcmd, repl) except exceptions.CommandError as e: - signals.status_message.send(message=str(e)) + ctx.log.error(str(e)) self.master.overlay( overlay.Chooser(self.master, prompt, choices, "", callback) @@ -454,8 +452,9 @@ class ConsoleAddon: url = edited_url.rstrip(b"\n") flow.request.url = url.decode() elif flow_part in ["method", "status_code", "reason"]: - self.master.commands.execute( - "console.command flow.set @focus %s " % flow_part + self.master.commands.call_strings( + "console.command", + ["flow.set", "@focus", flow_part] ) def _grideditor(self): @@ -539,10 +538,12 @@ class ConsoleAddon: raise exceptions.CommandError("Invalid flowview mode.") try: - cmd = 'view.settings.setval @focus flowview_mode_%s %s' % (idx, mode) - self.master.commands.execute(cmd) + self.master.commands.call_strings( + "view.settings.setval", + ["@focus", "flowview_mode_%s" % (idx,), mode] + ) except exceptions.CommandError as e: - signals.status_message.send(message=str(e)) + ctx.log.error(str(e)) @command.command("console.flowview.mode.options") def flowview_mode_options(self) -> typing.Sequence[str]: @@ -561,8 +562,10 @@ class ConsoleAddon: raise exceptions.CommandError("Not viewing a flow.") idx = fv.body.tab_offset - cmd = 'view.settings.getval @focus flowview_mode_%s %s' % (idx, self.master.options.console_default_contentview) - return self.master.commands.execute(cmd) + return self.master.commands.call_strings( + "view.settings.getval", + ["@focus", "flowview_mode_%s" % (idx,), self.master.options.console_default_contentview] + ) @command.command("console.key.contexts") def key_contexts(self) -> typing.Sequence[str]: diff --git a/mitmproxy/tools/console/keymap.py b/mitmproxy/tools/console/keymap.py index 01ec9a0a..a42225cf 100644 --- a/mitmproxy/tools/console/keymap.py +++ b/mitmproxy/tools/console/keymap.py @@ -202,7 +202,7 @@ class KeymapConfig: user_ctxs = v.get("ctx", ["global"]) try: km._check_contexts(user_ctxs) - km.remove(v["key"], Contexts) + km.remove(v["key"], user_ctxs) km.add( key = v["key"], command = v["cmd"], diff --git a/mitmproxy/tools/web/master.py b/mitmproxy/tools/web/master.py index e2c60d94..d127bdec 100644 --- a/mitmproxy/tools/web/master.py +++ b/mitmproxy/tools/web/master.py @@ -1,5 +1,3 @@ -import webbrowser - import tornado.httpserver import tornado.ioloop from tornado.platform.asyncio import AsyncIOMainLoop @@ -107,43 +105,9 @@ class WebMaster(master.Master): AsyncIOMainLoop().install() iol = tornado.ioloop.IOLoop.instance() http_server = tornado.httpserver.HTTPServer(self.app) - http_server.listen(self.options.web_port, self.options.web_iface) - web_url = "http://{}:{}/".format(self.options.web_iface, self.options.web_port) + http_server.listen(self.options.web_port, self.options.web_host) + web_url = "http://{}:{}/".format(self.options.web_host, self.options.web_port) self.log.info( "Web server listening at {}".format(web_url), ) - # FIXME: This should be in an addon hooked to the "running" event, not in master - if self.options.web_open_browser: - success = open_browser(web_url) - if not success: - self.log.info( - "No web browser found. Please open a browser and point it to {}".format(web_url), - ) self.run_loop(iol.start) - - -def open_browser(url: str) -> bool: - """ - Open a URL in a browser window. - In contrast to webbrowser.open, we limit the list of suitable browsers. - This gracefully degrades to a no-op on headless servers, where webbrowser.open - would otherwise open lynx. - - Returns: - True, if a browser has been opened - False, if no suitable browser has been found. - """ - browsers = ( - "windows-default", "macosx", - "google-chrome", "chrome", "chromium", "chromium-browser", - "firefox", "opera", "safari", - ) - for browser in browsers: - try: - b = webbrowser.get(browser) - except webbrowser.Error: - pass - else: - b.open(url) - return True - return False diff --git a/mitmproxy/tools/web/static/app.js b/mitmproxy/tools/web/static/app.js index e429a344..d5888309 100644 --- a/mitmproxy/tools/web/static/app.js +++ b/mitmproxy/tools/web/static/app.js @@ -20,7 +20,7 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function ContentViewOptions(e){var t=e.flow,o=e.message,n=e.uploadContent,r=e.readonly,a=e.contentViewDescription;return _react2.default.createElement("div",{className:"view-options"},r?_react2.default.createElement(_ViewSelector2.default,{message:o}):_react2.default.createElement("span",null,_react2.default.createElement("b",null,"View:")," edit"),"Â ",_react2.default.createElement(_DownloadContentButton2.default,{flow:t,message:o}),"Â ",!r&&_react2.default.createElement(_UploadContentButton2.default,{uploadContent:n}),"Â ",r&&_react2.default.createElement("span",null,a))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_ViewSelector=require("./ViewSelector"),_ViewSelector2=_interopRequireDefault(_ViewSelector),_UploadContentButton=require("./UploadContentButton"),_UploadContentButton2=_interopRequireDefault(_UploadContentButton),_DownloadContentButton=require("./DownloadContentButton"),_DownloadContentButton2=_interopRequireDefault(_DownloadContentButton);ContentViewOptions.propTypes={flow:_propTypes2.default.object.isRequired,message:_propTypes2.default.object.isRequired},exports.default=(0,_reactRedux.connect)(function(e){return{contentViewDescription:e.ui.flow.viewDescription,readonly:!e.ui.flow.modifiedFlow}})(ContentViewOptions); },{"./DownloadContentButton":9,"./UploadContentButton":12,"./ViewSelector":13,"prop-types":"prop-types","react":"react","react-redux":"react-redux"}],8:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function ViewImage(e){var t=e.flow,r=e.message;return _react2.default.createElement("div",{className:"flowview-image"},_react2.default.createElement("img",{src:_utils.MessageUtils.getContentURL(t,r),alt:"preview",className:"img-thumbnail"}))}function Edit(e){var t=e.content,r=e.onChange;return _react2.default.createElement(_CodeEditor2.default,{content:t,onChange:r})}Object.defineProperty(exports,"__esModule",{value:!0}),exports.ViewImage=exports.ViewServer=exports.Edit=exports.PureViewServer=void 0;var _slicedToArray=function(){function e(e,t){var r=[],n=!0,o=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(n=(a=s.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){o=!0,i=e}finally{try{!n&&s.return&&s.return()}finally{if(o)throw i}}return r}return function(t,r){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),_createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_flow=require("../../ducks/ui/flow"),_ContentLoader=require("./ContentLoader"),_ContentLoader2=_interopRequireDefault(_ContentLoader),_utils=require("../../flow/utils"),_CodeEditor=require("./CodeEditor"),_CodeEditor2=_interopRequireDefault(_CodeEditor),isImage=/^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i;ViewImage.matches=function(e){return isImage.test(_utils.MessageUtils.getContentType(e))},ViewImage.propTypes={flow:_propTypes2.default.object.isRequired,message:_propTypes2.default.object.isRequired},Edit.propTypes={content:_propTypes2.default.string.isRequired},exports.Edit=Edit=(0,_ContentLoader2.default)(Edit);var PureViewServer=exports.PureViewServer=function(e){function t(){return _classCallCheck(this,t),_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return _inherits(t,_react.Component),_createClass(t,[{key:"componentWillMount",value:function(){this.setContentView(this.props)}},{key:"componentWillReceiveProps",value:function(e){e.content!=this.props.content&&this.setContentView(e)}},{key:"setContentView",value:function(e){try{this.data=JSON.parse(e.content)}catch(e){this.data={lines:[],description:e.message}}e.setContentViewDescription(e.contentView!=this.data.description?this.data.description:""),e.setContent(this.data.lines)}},{key:"render",value:function(){var e=this.props,t=(e.content,e.contentView,e.message),r=e.maxLines,n=this.props.showFullContent?this.data.lines:this.data.lines.slice(0,r);return _react2.default.createElement("div",null,ViewImage.matches(t)&&_react2.default.createElement(ViewImage,this.props),_react2.default.createElement("pre",null,n.map(function(e,t){return _react2.default.createElement("div",{key:"line"+t},e.map(function(e,t){var r=_slicedToArray(e,2),n=r[0],o=r[1];return _react2.default.createElement("span",{key:"tuple"+t,className:n},o)}))})))}}]),t}();PureViewServer.propTypes={showFullContent:_propTypes2.default.bool.isRequired,maxLines:_propTypes2.default.number.isRequired,setContentViewDescription:_propTypes2.default.func.isRequired,setContent:_propTypes2.default.func.isRequired};var ViewServer=(0,_reactRedux.connect)(function(e){return{showFullContent:e.ui.flow.showFullContent,maxLines:e.ui.flow.maxContentLines}},{setContentViewDescription:_flow.setContentViewDescription,setContent:_flow.setContent})((0,_ContentLoader2.default)(PureViewServer));exports.Edit=Edit,exports.ViewServer=ViewServer,exports.ViewImage=ViewImage; +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function ViewImage(e){var t=e.flow,r=e.message;return _react2.default.createElement("div",{className:"flowview-image"},_react2.default.createElement("img",{src:_utils.MessageUtils.getContentURL(t,r),alt:"preview",className:"img-thumbnail"}))}function Edit(e){var t=e.content,r=e.onChange;return _react2.default.createElement(_CodeEditor2.default,{content:t,onChange:r})}Object.defineProperty(exports,"__esModule",{value:!0}),exports.ViewImage=exports.ViewServer=exports.Edit=exports.PureViewServer=void 0;var _slicedToArray=function(){function e(e,t){var r=[],n=!0,o=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(n=(a=s.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){o=!0,i=e}finally{try{!n&&s.return&&s.return()}finally{if(o)throw i}}return r}return function(t,r){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),_createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_flow=require("../../ducks/ui/flow"),_ContentLoader=require("./ContentLoader"),_ContentLoader2=_interopRequireDefault(_ContentLoader),_utils=require("../../flow/utils"),_CodeEditor=require("./CodeEditor"),_CodeEditor2=_interopRequireDefault(_CodeEditor),isImage=/^image\/(png|jpe?g|gif|webp|vnc.microsoft.icon|x-icon)$/i;ViewImage.matches=function(e){return isImage.test(_utils.MessageUtils.getContentType(e))},ViewImage.propTypes={flow:_propTypes2.default.object.isRequired,message:_propTypes2.default.object.isRequired},Edit.propTypes={content:_propTypes2.default.string.isRequired},exports.Edit=Edit=(0,_ContentLoader2.default)(Edit);var PureViewServer=exports.PureViewServer=function(e){function t(){return _classCallCheck(this,t),_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return _inherits(t,_react.Component),_createClass(t,[{key:"componentWillMount",value:function(){this.setContentView(this.props)}},{key:"componentWillReceiveProps",value:function(e){e.content!=this.props.content&&this.setContentView(e)}},{key:"setContentView",value:function(e){try{this.data=JSON.parse(e.content)}catch(e){this.data={lines:[],description:e.message}}e.setContentViewDescription(e.contentView!=this.data.description?this.data.description:""),e.setContent(this.data.lines)}},{key:"render",value:function(){var e=this.props,t=(e.content,e.contentView,e.message),r=e.maxLines,n=this.props.showFullContent?this.data.lines:this.data.lines.slice(0,r);return _react2.default.createElement("div",null,ViewImage.matches(t)&&_react2.default.createElement(ViewImage,this.props),_react2.default.createElement("pre",null,n.map(function(e,t){return _react2.default.createElement("div",{key:"line"+t},e.map(function(e,t){var r=_slicedToArray(e,2),n=r[0],o=r[1];return _react2.default.createElement("span",{key:"tuple"+t,className:n},o)}))})))}}]),t}();PureViewServer.propTypes={showFullContent:_propTypes2.default.bool.isRequired,maxLines:_propTypes2.default.number.isRequired,setContentViewDescription:_propTypes2.default.func.isRequired,setContent:_propTypes2.default.func.isRequired};var ViewServer=(0,_reactRedux.connect)(function(e){return{showFullContent:e.ui.flow.showFullContent,maxLines:e.ui.flow.maxContentLines}},{setContentViewDescription:_flow.setContentViewDescription,setContent:_flow.setContent})((0,_ContentLoader2.default)(PureViewServer));exports.Edit=Edit,exports.ViewServer=ViewServer,exports.ViewImage=ViewImage; },{"../../ducks/ui/flow":60,"../../flow/utils":68,"./CodeEditor":5,"./ContentLoader":6,"prop-types":"prop-types","react":"react","react-redux":"react-redux"}],9:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function DownloadContentButton(e){var t=e.flow,o=e.message;return _react2.default.createElement("a",{className:"btn btn-default btn-xs",href:_utils.MessageUtils.getContentURL(t,o),title:"Download the content of the flow."},_react2.default.createElement("i",{className:"fa fa-download"}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=DownloadContentButton;var _react=require("react"),_react2=_interopRequireDefault(_react),_utils=require("../../flow/utils"),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes);DownloadContentButton.propTypes={flow:_propTypes2.default.object.isRequired,message:_propTypes2.default.object.isRequired}; @@ -101,7 +101,7 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function MenuToggle(e){var t=e.value,n=e.onChange,r=e.children;return React.createElement("div",{className:"menu-entry"},React.createElement("label",null,React.createElement("input",{type:"checkbox",checked:t,onChange:n}),r))}function SettingsToggle(e){var t=e.setting,n=e.children,r=e.settings,g=e.updateSettings;return React.createElement(MenuToggle,{value:r[t]||!1,onChange:function(){return g(_defineProperty({},t,!r[t]))}},n)}function EventlogToggle(e){var t=e.toggleVisibility,n=e.eventLogVisible;return React.createElement(MenuToggle,{value:n,onChange:t},"Display Event Log")}Object.defineProperty(exports,"__esModule",{value:!0}),exports.MenuToggle=MenuToggle,exports.SettingsToggle=SettingsToggle,exports.EventlogToggle=EventlogToggle;var _propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_settings=require("../../ducks/settings"),_eventLog=require("../../ducks/eventLog");MenuToggle.propTypes={value:_propTypes2.default.bool.isRequired,onChange:_propTypes2.default.func.isRequired,children:_propTypes2.default.node.isRequired},SettingsToggle.propTypes={setting:_propTypes2.default.string.isRequired,children:_propTypes2.default.node.isRequired},exports.SettingsToggle=SettingsToggle=(0,_reactRedux.connect)(function(e){return{settings:e.settings}},{updateSettings:_settings.update})(SettingsToggle),exports.EventlogToggle=EventlogToggle=(0,_reactRedux.connect)(function(e){return{eventLogVisible:e.eventLog.visible}},{toggleVisibility:_eventLog.toggleVisibility})(EventlogToggle); },{"../../ducks/eventLog":55,"../../ducks/settings":59,"prop-types":"prop-types","react-redux":"react-redux"}],35:[function(require,module,exports){ -"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a]);return t.default=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function OptionMenu(e){var t=e.openOptions;return _react2.default.createElement("div",null,_react2.default.createElement(_HideInStatic2.default,null,_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_Button2.default,{title:"Open Options",icon:"fa-cogs text-primary",onClick:t},"Edit Options ",_react2.default.createElement("sup",null,"alpha"))),_react2.default.createElement("div",{className:"menu-legend"},"Options Editor")),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"anticache"},"Strip cache headers ",_react2.default.createElement(_DocsLink2.default,{resource:"features/anticache.html"})),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"showhost"},"Use host header for display"),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"ssl_insecure"},"Verify server certificates")),_react2.default.createElement("div",{className:"menu-legend"},"Quick Options"))),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.EventlogToggle,null)),_react2.default.createElement("div",{className:"menu-legend"},"View Options")))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_MenuToggle=require("./MenuToggle"),_Button=require("../common/Button"),_Button2=_interopRequireDefault(_Button),_DocsLink=require("../common/DocsLink"),_DocsLink2=_interopRequireDefault(_DocsLink),_HideInStatic=require("../common/HideInStatic"),_HideInStatic2=_interopRequireDefault(_HideInStatic),_modal=require("../../ducks/ui/modal"),modalActions=_interopRequireWildcard(_modal);OptionMenu.title="Options",exports.default=(0,_reactRedux.connect)(null,{openOptions:function(){return modalActions.setActiveModal("OptionModal")}})(OptionMenu); +"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a]);return t.default=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function OptionMenu(e){var t=e.openOptions;return _react2.default.createElement("div",null,_react2.default.createElement(_HideInStatic2.default,null,_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_Button2.default,{title:"Open Options",icon:"fa-cogs text-primary",onClick:t},"Edit Options ",_react2.default.createElement("sup",null,"alpha"))),_react2.default.createElement("div",{className:"menu-legend"},"Options Editor")),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"anticache"},"Strip cache headers ",_react2.default.createElement(_DocsLink2.default,{resource:"features/anticache.html"})),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"showhost"},"Use host header for display"),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"ssl_insecure"},"Don't verify server certificates")),_react2.default.createElement("div",{className:"menu-legend"},"Quick Options"))),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.EventlogToggle,null)),_react2.default.createElement("div",{className:"menu-legend"},"View Options")))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_MenuToggle=require("./MenuToggle"),_Button=require("../common/Button"),_Button2=_interopRequireDefault(_Button),_DocsLink=require("../common/DocsLink"),_DocsLink2=_interopRequireDefault(_DocsLink),_HideInStatic=require("../common/HideInStatic"),_HideInStatic2=_interopRequireDefault(_HideInStatic),_modal=require("../../ducks/ui/modal"),modalActions=_interopRequireWildcard(_modal);OptionMenu.title="Options",exports.default=(0,_reactRedux.connect)(null,{openOptions:function(){return modalActions.setActiveModal("OptionModal")}})(OptionMenu); },{"../../ducks/ui/modal":64,"../common/Button":45,"../common/DocsLink":46,"../common/HideInStatic":49,"./MenuToggle":34,"react":"react","react-redux":"react-redux"}],36:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function MainView(e){var t=e.hasSelection;return _react2.default.createElement("div",{className:"main-view"},_react2.default.createElement(_FlowTable2.default,null),t&&_react2.default.createElement(_Splitter2.default,{key:"splitter"}),t&&_react2.default.createElement(_FlowView2.default,{key:"flowDetails"}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_Splitter=require("./common/Splitter"),_Splitter2=_interopRequireDefault(_Splitter),_FlowTable=require("./FlowTable"),_FlowTable2=_interopRequireDefault(_FlowTable),_FlowView=require("./FlowView"),_FlowView2=_interopRequireDefault(_FlowView);MainView.propTypes={hasSelection:_propTypes2.default.bool.isRequired},exports.default=(0,_reactRedux.connect)(function(e){return{hasSelection:!!e.flows.byId[e.flows.selected[0]]}},{})(MainView); diff --git a/mitmproxy/tools/web/webaddons.py b/mitmproxy/tools/web/webaddons.py index 6b52188c..bd85651a 100644 --- a/mitmproxy/tools/web/webaddons.py +++ b/mitmproxy/tools/web/webaddons.py @@ -1,3 +1,8 @@ +import webbrowser + +from mitmproxy import ctx + + class WebAddon: def load(self, loader): loader.add_option( @@ -13,6 +18,42 @@ class WebAddon: "Web UI port." ) loader.add_option( - "web_iface", str, "127.0.0.1", - "Web UI interface." + "web_host", str, "127.0.0.1", + "Web UI host." ) + + def running(self): + if hasattr(ctx.options, "web_open_browser") and ctx.options.web_open_browser: + web_url = "http://{}:{}/".format(ctx.options.web_host, ctx.options.web_port) + success = open_browser(web_url) + if not success: + ctx.log.info( + "No web browser found. Please open a browser and point it to {}".format(web_url), + ) + + +def open_browser(url: str) -> bool: + """ + Open a URL in a browser window. + In contrast to webbrowser.open, we limit the list of suitable browsers. + This gracefully degrades to a no-op on headless servers, where webbrowser.open + would otherwise open lynx. + + Returns: + True, if a browser has been opened + False, if no suitable browser has been found. + """ + browsers = ( + "windows-default", "macosx", + "google-chrome", "chrome", "chromium", "chromium-browser", + "firefox", "opera", "safari", + ) + for browser in browsers: + try: + b = webbrowser.get(browser) + except webbrowser.Error: + pass + else: + b.open(url) + return True + return False diff --git a/mitmproxy/types.py b/mitmproxy/types.py index ac992217..0d4ffd69 100644 --- a/mitmproxy/types.py +++ b/mitmproxy/types.py @@ -134,7 +134,7 @@ class _IntType(_BaseType): try: return int(s) except ValueError as e: - raise exceptions.TypeError from e + raise exceptions.TypeError(str(e)) from e def is_valid(self, manager: "CommandManager", typ: typing.Any, val: typing.Any) -> bool: return isinstance(val, int) @@ -328,7 +328,7 @@ class _FlowType(_BaseFlowType): try: flows = manager.execute("view.flows.resolve %s" % (s)) except exceptions.CommandError as e: - raise exceptions.TypeError from e + raise exceptions.TypeError(str(e)) from e if len(flows) != 1: raise exceptions.TypeError( "Command requires one flow, specification matched %s." % len(flows) @@ -347,7 +347,7 @@ class _FlowsType(_BaseFlowType): try: return manager.execute("view.flows.resolve %s" % (s)) except exceptions.CommandError as e: - raise exceptions.TypeError from e + raise exceptions.TypeError(str(e)) from e def is_valid(self, manager: "CommandManager", typ: typing.Any, val: typing.Any) -> bool: try: diff --git a/pathod/language/actions.py b/pathod/language/actions.py index 3e48f40d..916cd0aa 100644 --- a/pathod/language/actions.py +++ b/pathod/language/actions.py @@ -6,7 +6,7 @@ import pyparsing as pp from . import base -@total_ordering +@total_ordering # type: ignore class _Action(base.Token): """ diff --git a/release/README.md b/release/README.md index 1b8614ea..8632d644 100644 --- a/release/README.md +++ b/release/README.md @@ -3,6 +3,7 @@ These steps assume you are on the correct branch and have a git remote called `origin` that points to the `mitmproxy/mitmproxy` repo. If necessary, create a major version branch starting off the release tag (e.g. `git checkout -b v4.x v4.0.0`) first. - Update CHANGELOG. +- Verify that the compiled mitmweb assets are up-to-date. - Verify that all CI tests pass. - Verify that `mitmproxy/version.py` is correct. Remove `.dev` suffix if it exists. - Tag the release and push to Github. diff --git a/release/cibuild.py b/release/cibuild.py index b2bad9a0..d070a4b9 100755 --- a/release/cibuild.py +++ b/release/cibuild.py @@ -454,10 +454,10 @@ def build_wininstaller(be: BuildEnviron): # pragma: no cover return click.echo("Building wininstaller package...") - IB_VERSION = "19.10.0" + IB_VERSION = "20.3.0" IB_DIR = pathlib.Path(be.release_dir) / "installbuilder" IB_SETUP = IB_DIR / "setup" / f"{IB_VERSION}-installer.exe" - IB_CLI = fr"C:\Program Files (x86)\BitRock InstallBuilder Enterprise {IB_VERSION}\bin\builder-cli.exe" + IB_CLI = fr"C:\Program Files (x86)\VMware InstallBuilder Enterprise {IB_VERSION}\bin\builder-cli.exe" IB_LICENSE = IB_DIR / "license.xml" if not os.path.isfile(IB_CLI): @@ -470,11 +470,11 @@ def build_wininstaller(be: BuildEnviron): # pragma: no cover click.secho(f"Downloading... {round(100 * done / total)}%") urllib.request.urlretrieve( - f"https://clients.bitrock.com/installbuilder/installbuilder-enterprise-{IB_VERSION}-windows-installer.exe", + f"https://installbuilder.com/installbuilder-enterprise-{IB_VERSION}-windows-installer.exe", IB_SETUP.with_suffix(".tmp"), reporthook=report ) - shutil.move(IB_SETUP.with_suffix(".tmp"), IB_SETUP) + shutil.move(str(IB_SETUP.with_suffix(".tmp")), str(IB_SETUP)) click.echo("Install InstallBuilder...") subprocess.run([str(IB_SETUP), "--mode", "unattended", "--unattendedmodeui", "none"], check=True) diff --git a/release/docker/README.md b/release/docker/README.md index b676d3ae..2fa93949 100644 --- a/release/docker/README.md +++ b/release/docker/README.md @@ -23,7 +23,7 @@ $ docker run --rm -it -p 8080:8080 mitmproxy/mitmproxy mitmdump For `mitmweb`, you also need to expose port 8081: ```sh # this makes :8081 accessible to the local machine only -$ docker run --rm -it -p 8080:8080 -p 127.0.0.1:8081:8081 mitmproxy/mitmproxy mitmweb --web-iface 0.0.0.0 +$ docker run --rm -it -p 8080:8080 -p 127.0.0.1:8081:8081 mitmproxy/mitmproxy mitmweb --web-host 0.0.0.0 ``` You can also pass options directly via the CLI: diff --git a/release/hooks/hook-pkg_resources.py b/release/hooks/hook-pkg_resources.py new file mode 100644 index 00000000..8bd787f2 --- /dev/null +++ b/release/hooks/hook-pkg_resources.py @@ -0,0 +1,7 @@ +# flake8: noqa + +# temporary fix for https://github.com/pypa/setuptools/issues/1963 +# can be removed when we upgrade to PyInstaller 3.7. +hiddenimports = collect_submodules('pkg_resources._vendor') +hiddenimports.append('pkg_resources.py2_warn') +excludedimports = ['__main__'] @@ -66,25 +66,25 @@ setup( "Brotli>=1.0,<1.1", "certifi>=2019.9.11", # no semver here - this should always be on the last release! "click>=7.0,<8", - "cryptography>=2.1.4,<2.5", + "cryptography>=2.9,<3.0", "flask>=1.1.1,<1.2", - "h2>=3.0.1,<4", + "h2>=3.2.0,<4", "hyperframe>=5.1.0,<6", "kaitaistruct>=0.7,<0.9", - "ldap3>=2.6.1,<2.7", + "ldap3>=2.6.1,<2.8", "passlib>=1.6.5, <1.8", - "protobuf>=3.6.0, <3.11", + "protobuf>=3.6.0, <3.12", "pyasn1>=0.3.1,<0.5", - "pyOpenSSL==19.0.0", + "pyOpenSSL>=19.1.0,<19.2", "pyparsing>=2.4.2,<2.5", - "pyperclip>=1.6.0,<1.8", + "pyperclip>=1.6.0,<1.9", "ruamel.yaml>=0.16,<0.17", "sortedcontainers>=2.1.0,<2.2", "tornado>=4.3,<7", "urwid>=2.1.0,<2.2", - "wsproto>=0.14.0,<0.15.0", + "wsproto>=0.14,<0.16", "publicsuffix2>=2.20190812,<3", - "zstandard>=0.11.0,<0.13.0", + "zstandard>=0.11,<0.14", ], extras_require={ ':sys_platform == "win32"': [ diff --git a/test/mitmproxy/addons/test_script.py b/test/mitmproxy/addons/test_script.py index 05472d9a..61e19174 100644 --- a/test/mitmproxy/addons/test_script.py +++ b/test/mitmproxy/addons/test_script.py @@ -137,6 +137,17 @@ class TestScript: assert await tctx.master.await_log("error.py") @pytest.mark.asyncio + async def test_optionexceptions(self, tdata): + with taddons.context() as tctx: + sc = script.Script( + tdata.path("mitmproxy/data/addonscripts/configure.py"), + True, + ) + tctx.master.addons.add(sc) + tctx.configure(sc) + assert await tctx.master.await_log("Options Error") + + @pytest.mark.asyncio async def test_addon(self, tdata): with taddons.context() as tctx: sc = script.Script( diff --git a/test/mitmproxy/data/addonscripts/configure.py b/test/mitmproxy/data/addonscripts/configure.py new file mode 100644 index 00000000..6f6ac06a --- /dev/null +++ b/test/mitmproxy/data/addonscripts/configure.py @@ -0,0 +1,21 @@ +import typing + +from mitmproxy import exceptions + + +class OptionAddon: + def load(self, loader): + loader.add_option( + name = "optionaddon", + typespec = typing.Optional[int], + default = None, + help = "Option Addon", + ) + + def configure(self, updates): + raise exceptions.OptionsError("Options Error") + +addons = [ + OptionAddon() +] + diff --git a/test/mitmproxy/data/servercert/9da13359.0 b/test/mitmproxy/data/servercert/9da13359.0 index 5868a304..88ed4145 100644 --- a/test/mitmproxy/data/servercert/9da13359.0 +++ b/test/mitmproxy/data/servercert/9da13359.0 @@ -1,21 +1,21 @@ ------BEGIN CERTIFICATE----- -MIIDXTCCAkWgAwIBAgIJALzkvKyFAwWYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTgwOTA3MDgyMjUxWhcNMzgwOTAyMDgyMjUxWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAkvT4Y1ML8Gg4x5aFVygIW022tJsEyfuW4HsEvIarAGpFtUNkw0dOoAxv -Gv71I0KAWOXxtc9DUjtq7ZXJcG+dBiheTYJ40lrYhHvUt7J37nrUF5v5trQzoE9I -6WGtzTV8C8RI6F+M6GtwxgwRBgqkuXiK5ExPXAjGMMJZWtiEXHxGTNB6F4zy884m -VjVtQi8jy+c5g21Awp3z5HrQLM210zwvgi7Rygk6/UM0AnmST4o32SqFSd+0MFUJ -f3pH3xczfKmhU/TBoVEWRB1YzwixsJrzDOB8wOGnNKCsl45hYUJZZ8epVkyrvFZQ -iMkwIqqBJbkU6H7fZBl68TJ8ascUCQIDAQABo1AwTjAdBgNVHQ4EFgQUkurgHlw1 -xMP2wrsrGPTk0ofxCyowHwYDVR0jBBgwFoAUkurgHlw1xMP2wrsrGPTk0ofxCyow -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcdExVlSvH6aVExNiQO3k -cMamj+78woDn9x563vwzaGP24KvOXk1B/IJp5kqu3ZsXS0I0Mz6xwXHAXeuxaj06 -cKgEpHKKgClLblXo2zWqo/3V1UFFpOVP/NhI3r21b+fPrS46rP0mw75haQCph8/8 -buQr0OeAYbElliY/ji+cJiCJB8A/D13fUMV/NUUfPW/UE6497jOmz+6PtZNAoOFx -evrmDcbCzbJxacyLJX04rsrt6DO09jb/+5lFm5Aqr6ySKasrmheIGEisl4o9Zbuy -5PvYgbOEmFgPATIiWGpBO/rqwDdsmgyYFl+YfFoW0akXUVhDb2e5iRDx6Rs0fmN/ -NA== ------END CERTIFICATE----- +-----BEGIN CERTIFICATE-----
+MIIDazCCAlOgAwIBAgIUTE2oFYATbkkytGOt0+CIAOPpaeEwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjMwMDA1MDlaFw0zOTEx
+MTgwMDA1MDlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDZ7fqv4iC6738OvOC/ONFmhOVmMNe2SrGtk+7KIv/M
+d7MJJKpIygwc99EfL3m6WFjvSQ8CABO9GnLIeoB6RzX5X904dPQzIekMkE27J4D5
+wzYWAmYsu9md//9rjadaA01zHvxtpc30AsToOrRa2Rv7Lwotvcop2bBCXXZMdgvD
+BpCuCOl3cQ346LZBmED41q77P7SgnI98gCPuyyMVAFTZE4NnFUloVERTcMMo5Vwv
+tXFT41B6FOqtyhZFY89W1SeNKlm+n8zu+/aUF5c9usxwvQzj79pzBFYS9xMZzbxl
+BmU91GbLFNU32O+wp0jX6c1MfluGvRjcHQpK+gHRRJdZAgMBAAGjUzBRMB0GA1Ud
+DgQWBBSTmtfFP/zQDiCbte3AG3vchjSekjAfBgNVHSMEGDAWgBSTmtfFP/zQDiCb
+te3AG3vchjSekjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB6
+CnGmyJKVdD41Qs8QbyZ5VvrAkSq7DkL4CAIDy0pClOYjx51R16g4/dXPd8nuDjVB
+GbRuO/ZHlKeO+RAVbV4s74KeBmQ4uyuZMvuiJGCDtTgu+fbgp1l41vj21bkDnz/X
+0aVrwC4clh6O1/AFCY7cYygp22QJ0zGpIb9d0ly6QDMEocHJKasuQ8/0GPvv6wkY
+hwNub2ScsVFHPrFzzufZblBk3Ks0YZw+IsCMTY7QtGb1TZhGeX9xAydqNMnmIxNj
+XOE2FKx4ISQNFwf/U1LEAruO7PjbbsWx5FHr4oYV9TCLoERZFofwcGGM9o/cPc4P
+CH8fGvFYoU30PG+xX0Pc
+-----END CERTIFICATE-----
diff --git a/test/mitmproxy/data/servercert/self-signed.pem b/test/mitmproxy/data/servercert/self-signed.pem index d35284bd..55145c52 100644 --- a/test/mitmproxy/data/servercert/self-signed.pem +++ b/test/mitmproxy/data/servercert/self-signed.pem @@ -1,46 +1,49 @@ -----BEGIN CERTIFICATE-----
-MIIDEzCCAfugAwIBAgIJAKzH8k6aKTP6MA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNV
-BAMMFWV4YW1wbGUubWl0bXByb3h5Lm9yZzAeFw0xODA5MDcwODIyNTNaFw0zODA5
-MDIwODIyNTNaMCAxHjAcBgNVBAMMFWV4YW1wbGUubWl0bXByb3h5Lm9yZzCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOjJMp2o5eLQEmYJqMZzLBi61h9
-fsCVMvS8hgrH1Cg5q/RaLBLrZ8nILKmFZBapMUEFkUwQLB864tdTMaX7p+jNv3sM
-5LWEIYkTIbu6qV7QerKdubS1hpdFtQGRM1Q+C7H86FzF02DSKzNSmQc4fNed/lQM
-qo/jOm1xx4TZFR4j58BrmmoOfNP44IyrwXsPyXbMsukKixVEB3vQ2oyGDAyG6dYi
-VvM8PVL5yhX3BJ0D1Ky6hgGHJeirm0Cd8qqdSC/SWNdu1bGzg/xyUX5XFaHlIi7Y
-5YhD7ZDLvC76MeCWkfo4DaSB0CWmtG4l1TtHM2JqP8qf2l2LsABKs0q/a+UCAwEA
-AaNQME4wHQYDVR0OBBYEFIc9YAXgnGRhPTEcN/j+k/dxMdKqMB8GA1UdIwQYMBaA
-FIc9YAXgnGRhPTEcN/j+k/dxMdKqMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
-BQADggEBAD9qKci3Pr4/2WGx+sv8gOpKchC9eF2dXc5hA3xbDw7T6oRLUBAY8Pty
-JF7DHMovT+w7FPRYT8rSc190fbSwVRHAnEaqAzaxteImCp/qYgdBHOz39eG4c93W
-YrYvA1VdUDPcUnisEVWguDsKJGFg+G6pw+8Wkf/hCrJJkriTFogGvzg6ptdQatvE
-dpSkionfbuZKz+7lny6sCBGoMRIFBd22MHJsSQOyTb06Lwc5dpdF9c5vysPRzShJ
-5kkgIjGpTmWp+Ud8BAMQH8EDhJMkJ7iw1+07UQ9MUmXCp9Xgim6x1ri2/yoz9HeO
-83VCkD9YWufrzOrsXpo04rMYtoKo+lw=
+MIIDjTCCAnWgAwIBAgIUb0mIVHKB+bu2PGObggokU3Re7xMwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjMwMDA1MDlaFw0zOTEx
+MTgwMDA1MDlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDF6eqyZD2z83buUF4T+6AY0Zoe925a2AHOhGtHJMLo
+9AD7FF1Xi1iksEvxbOI6mreHtvYKzUpfNsA3DkFdSO91HMSkdvWcDcExpW62sNK9
+gQQrpcCx7DogOrFiGSIHI1LIy1y6YEJma3G71SgGbw7g1QF64dTX9+BzVQJsloT2
+H3ZxTi8Fb6APJq6d/Tp67GTM8U82vM+FjLKzfH7RMSEPvSyvWSibw3AZP6owFaxz
+DJtXpR7evOZbiZxqXmGOBl5OQPu9GdDA3Fyi9Drp7xa234loqd1a8PYyL8qWV/2G
+HM3IJOzG8Y5PUJhL8CkDbx4LJ9LfzeSuBnQPUf2ZNalZAgMBAAGjdTBzMB0GA1Ud
+DgQWBBQbkS0mAGPD4XjOv9GKzGMyR9ix3TAfBgNVHSMEGDAWgBQbkS0mAGPD4XjO
+v9GKzGMyR9ix3TAPBgNVHRMBAf8EBTADAQH/MCAGA1UdEQQZMBeCFWV4YW1wbGUu
+bWl0bXByb3h5Lm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAqZ64xpu3qrTlCc555OoP
+GgobUFP3qv07d0/r48cOyYdAdlEHhvmDPlqWTB9e4ZYtWZMlocY9DpCywzKTa7F7
+Ad8BwS0a/No3wVdl1UEkIGYxuD//jbd77Mrpf5URvQco85o/bicn+H0GAOchYt1P
+jP1VShqsRv6WiTs5kn1/JwVoafddl1jBlMDmCqDv4loAZJYHzie0CqdjjSeorFfE
+8FG8OLwmEnmIW6VnanRH8coH9MBbZ+dRtCavS+Q8s0R77dJM1sCp5/4yKcr5D/PD
++dQN9f+iugLxDdBQjiRyadWX9/l4n/h8ezabZ4cNsiWbRXrp5VS0nGNmAK3XvPAu
+ow==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIIEpgIBAAKCAQEAw6Mkynajl4tASZgmoxnMsGLrWH1+wJUy9LyGCsfUKDmr9Fos
-EutnycgsqYVkFqkxQQWRTBAsHzri11Mxpfun6M2/ewzktYQhiRMhu7qpXtB6sp25
-tLWGl0W1AZEzVD4LsfzoXMXTYNIrM1KZBzh8153+VAyqj+M6bXHHhNkVHiPnwGua
-ag580/jgjKvBew/Jdsyy6QqLFUQHe9DajIYMDIbp1iJW8zw9UvnKFfcEnQPUrLqG
-AYcl6KubQJ3yqp1IL9JY127VsbOD/HJRflcVoeUiLtjliEPtkMu8Lvox4JaR+jgN
-pIHQJaa0biXVO0czYmo/yp/aXYuwAEqzSr9r5QIDAQABAoIBAQC1RpgymlffdgJt
-rvQuMRu/XQlhh3dJj3YV3BIAL0VguH+i/WLVbRdQm5D2y0kAzml7LGODrYCUt4W1
-q7rXaCYfy3Xf2QSbRQGl9/pL7xw9ZMQseYW38nPx+39LInYDWzKPDB9qx0uj7Vpm
-ReTSEf9r81PUIaBxj0V2X/VWHag5scBjXoflQLxyV6i1UvTuWyhYvX1Bbaj02MqV
-tGNMrjbj25Wx2za53VDonzNA6RMZzkWGMfzmkkGM6kjGzLEsveys+bYCt7Fs7slR
-4oby0bIUmN7iqLhqlEhS4weWW4iHlq17X7CZeQAE1XeVZBz1N4G8FLjND2eyqb2N
-RAcQqp3BAoGBAOiU3WTu/kSccteDRxR1gVRPqEgfoLDwyAb7ORVUWX4Ii/z/soMw
-xZ2MlYPLnp3Fyu/hKhJPC1LzkD4CGHCTJJ1NnUudtDxl2Zh1FZYGmv1hi1TID/cm
-G0+3XhlJgztS41+AzxTNMulV1yieT2HIRIoRpdSx1UIA72l42YqjrwUNAoGBANdV
-/Ib+3hAfFtSMMI1qZQXvlKEoDRbUOCYuBVkTK8oQJQH6MLDokHZ8sXBAqi9383b1
-XmhQBJZ//yMy0AqFa2QBlkK0Gizzhh7BLSjIT2LREf66B2cWzhgdhbSp6Nuk+3DK
-NfibxsFAPpW05HqtfxhbjrLfoE8VvTuMGQ8AaXw5AoGBAISo7IL2wrdV2TdN3Mwx
-ndv+N4kz6Q8jt6QrxUqCOy1lKJvdKPAlcIJFvr5W9RkeyXr7nmilB1uAK4UC4vfL
-JfZHX/HSeQx+N5f7KJ3TFLJz4eow1tJsvOVCPP0FbkH3LFO7/+HojSKEYN39NmAa
-v+VU3Zas/GvSZrxtPwASDvE9AoGBAJOBbluW6MzITx5H7dZhRFR9miWOxvCVbOUS
-b01mKX/f8UnadVIp7RONNQr88NdVZqxdRk9USOBDS6Vz4DjkzfySbbjBoJCcPIqC
-r4mZNXAuYRJJolqGr6SrTHTGUyFqcWcAzVnAc7TbakOoxz4V7NLlnOmA8FJcROUu
-gdfZ42hZAoGBANyL2IQ+L92iYVvqsz1zPBlvemevx8zP6GmlzvTcVexyDTIiLg6W
-BVil5zRDPJdDiFfBK18Qg1mJoE4SjLTg+yGww9ef37Zb9kZypy6pM6AbRWILZ1Gv
-7UsWUzk6rgcQpDdpJCUEt+AD3LQJTxxuoIhZePvC2GLkzsjZA7ZyB5+S
+MIIEpAIBAAKCAQEAxenqsmQ9s/N27lBeE/ugGNGaHvduWtgBzoRrRyTC6PQA+xRd
+V4tYpLBL8WziOpq3h7b2Cs1KXzbANw5BXUjvdRzEpHb1nA3BMaVutrDSvYEEK6XA
+sew6IDqxYhkiByNSyMtcumBCZmtxu9UoBm8O4NUBeuHU1/fgc1UCbJaE9h92cU4v
+BW+gDyaunf06euxkzPFPNrzPhYyys3x+0TEhD70sr1kom8NwGT+qMBWscwybV6Ue
+3rzmW4mcal5hjgZeTkD7vRnQwNxcovQ66e8Wtt+JaKndWvD2Mi/Kllf9hhzNyCTs
+xvGOT1CYS/ApA28eCyfS383krgZ0D1H9mTWpWQIDAQABAoIBAGl4H8+TZeJ5E18q
+ywfhJ08ym+x2tYOJ62SP4s+WApy8M62aC6g0pTeWj9IH0YOjobycPwBAqKqW9dYh
+Lao1zQ5fF1gB4R+ZoOQBIkAPeS7uCzfrbAYlOlCklpUNibm+FEbXQQI9fAUyqviL
+Pno3QvmD6fb/VDsHaMBthA40JIU4C3yUUcSooKKUC3XKmbRDg5/stKbVdi6co5AQ
+OMNFj4smts3rXtk5tKMBep4AgKKdClf4IuhpWEqZDxN6e+hZA7g1VOmOIE+hKEEO
+ODBkjHNgHIFbsr8GTlZ+GSkHBxMNVdHxntJTU5a2jPiTNTTnhqu2hcVdkyDwLb9x
+TGUCdyUCgYEA/ZPwI2KaT4Lj8b+6DCV4v3nZF8nLCtt1LiXxJWexdnr+3q/ZfNjN
+5sKVl9rIynz2zoJDVr1MI8yjO6OmV7GBW2wgJsSFwg0vnV/bs75KqPZWZXqy/mrp
+HnXd82XUweyyOpmBg4cCjmcnMTrdvCHvfgx7JafnUDqeXNwriWeC5Y8CgYEAx83d
+qHgAT2rlnCQYRmCOGb5fuyQ+pSM4p8h1AjueLrTNiWcqX57ct9eVWjymD+AgevFZ
+hZH9m6TI4nCb/5ukcvjQb4g1kyY3l7rZiiJ3kf/c22kVsVUagJGeiW6Ypnox4r1o
+oFXEwAw1qSGIqOIjYVB2DqvjUl3+UjWCl9SOnpcCgYEA0TSdWUQ/VTwCvW9VmjHM
+FgT8I5Ebj+CRI7qv4hFTqxE8dxKTl1nzPd/ptTgOkmhY4vU7gzN3vs1VGp4gXZcX
+xwpE2Fcol3lzgB4Wz4s+Y3mgu+ZoCFjB7ZyGugmYZ0nVnV0KKi5X4I6gGhCb4VwK
+D29SpjWJNHq4LpqC3MDmkGcCgYAxnKOKXmmtTpy+3ZONfhIqwEOjA0fu10UNHFA5
+grYvYMOcd5pk7dxeZdB2/JI7ZOqLvHv/F5YCXLNozo9ds7bsuW2AFDFBXX72VPYJ
+P6+y9/ZOINS7GKeg/wd/lo+e3r6eT2u4TDOzgBSe722wiZ5BXqpB0Fp8rEwm+5R2
+wNe89wKBgQC59SOa4EW3gfjLRaH6hEPcMEzjr0Dt5ilBgntYbI+DsCePwEX28hAK
+fd7A6XoCqjnwLpAmh0cmNRsYjtPCzg6TXUdrhfnR/3r7DHzvsxaC06BfkPZJ0+Fu
+rP3el/oKSPaDsZKjW6RA5oqlIF82o45MNl2oCG82LgVtu25e3HbJSA==
-----END RSA PRIVATE KEY-----
diff --git a/test/mitmproxy/data/servercert/trusted-leaf.pem b/test/mitmproxy/data/servercert/trusted-leaf.pem index a2c25312..29bd38f7 100644 --- a/test/mitmproxy/data/servercert/trusted-leaf.pem +++ b/test/mitmproxy/data/servercert/trusted-leaf.pem @@ -1,45 +1,48 @@ -----BEGIN CERTIFICATE-----
-MIIC4TCCAckCCQCj6D9oVylb9zANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
-VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMB4XDTE4MDkwNzA4MjI1MloXDTM4MDkwMjA4MjI1MlowIDEeMBwG
-A1UEAwwVZXhhbXBsZS5taXRtcHJveHkub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAqKzVdsRKgthv6V/dk3Tncy4ymbACs383nGutjulExvroNOCw
-b0y0e7unNGbtXxFQqSvA7eGaT1yRNfoMbXGSS+sn8A3gB6/s2A0Sw7KeSDdoaqEq
-F/LzRBed1YkxSyy0GXuTd7HXNIoFn/eF1tqxgViWdfyFD85qY4yJ+luofdm7IcPM
-ENPzV4nKzDh2PdJpQrEokWz2jM0zefC3IYnFHXY5bA3MnhE03/P0VxeEYkBdmEAt
-O1U2Bkw9SKCLy9zF13ks6/dDZ9LjMtRKI83gQS5z3S3bA45YxFuyeLWgVsJ2NYTa
-j9/8c4xwOjg9TpkCvcmZiPUYGddPHWoKqAAhBwIDAQABMA0GCSqGSIb3DQEBCwUA
-A4IBAQAf8cjxunN4Y7NUD2Z/SNOJ/s0uWJtTPV6m4FxSwwD0wfbsyirPchmattLc
-BabrQkeMMm8gMOrORfanXQwvLZvX0aDf96EgLSfHv8Iqeol5Byrgkn7UORXl20Jt
-8UNRURUZYtWxn08P8dlhxQUncPF/UxCesC8x0cihqv+YTB3TX1sni9mOqPCYY8yH
-E8kCW4zTJ0J9OQUHq9qdYQM/PGVm99+DWBItUeZAva8Rqj1FN3f9j1eWB+EjfYu7
-ztsTInpNWP4tIh6vIFtuaGr077cJawTe6YVyNxVqquI9+2fpSPkt7tCTIhbQ4AmM
-DeHzn+KjfKN8ooWqmcfmUZWaADe0
+MIIDajCCAlKgAwIBAgIJAKPoP2hXKVv4MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTkxMTIzMDAwNTA5WhcNMzkxMTE4MDAwNTA5WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA4BZUGKkf52583Kps2SinCzRtGFaGIqtP1YfjaN1H21c08hEERRWf0GqW
+PIbZz0NRyqOVM0O+4A9cxKrdqDpALBNXdgB62Ven1NNE31ZjsbFgwbORPTiOQo+6
+Xsu+2KHQdqAGOXSqOdNSoZV/HqAKa41iweg6lUf3yrO/hpfnlXTFbuM/oYFARrr9
+YWY7qH5BEvcZBf4Sg3cWGjdbzYg8S6hnFBBkHPDMbS3xra7H8uru8aG9L70aiq0C
+3WsGf1/Qctz3cccB6BdnbiXji0QlP0miT+b52hEzDvNjdXvoObgbOZsUUcLrbz8q
+LqaQPj6TA2PYpKcxEdJLDcbN++tglQIDAQABo10wWzAfBgNVHSMEGDAWgBSTmtfF
+P/zQDiCbte3AG3vchjSekjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDAgBgNVHREE
+GTAXghVleGFtcGxlLm1pdG1wcm94eS5vcmcwDQYJKoZIhvcNAQELBQADggEBAMoK
+8+KTYF10dbQ8Hl3Fq4Iux7eutAPuKUXUz9dnCfDRhZukdl+gahRoNvkyMBdXOvvx
+R9Z2+Guo8NOYKgT1mJtS/c8IxTkjZj9doujJOVD2wTowSfoaT9z+/EJa+6Fp9+xd
+YVsO3E/2Vxai8PCNx8JTXr2axcnBDvpHPRXF21hOI8N94SPAcmLTZsdsTELjrGGa
+/BA0y+pCEwW6cY9mMHVAAvRoMoqfocBVI7nrYBaQfFoKuwxscxO679eEv+lbSjul
+z/VNdWfqrDhFFSzwRSVchapQ9q1EeTzv++wZRwI5bT0Ib6DFTJB3J5+9RihlFYfU
+GI17CI0D//DsFic7QJ0=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAqKzVdsRKgthv6V/dk3Tncy4ymbACs383nGutjulExvroNOCw
-b0y0e7unNGbtXxFQqSvA7eGaT1yRNfoMbXGSS+sn8A3gB6/s2A0Sw7KeSDdoaqEq
-F/LzRBed1YkxSyy0GXuTd7HXNIoFn/eF1tqxgViWdfyFD85qY4yJ+luofdm7IcPM
-ENPzV4nKzDh2PdJpQrEokWz2jM0zefC3IYnFHXY5bA3MnhE03/P0VxeEYkBdmEAt
-O1U2Bkw9SKCLy9zF13ks6/dDZ9LjMtRKI83gQS5z3S3bA45YxFuyeLWgVsJ2NYTa
-j9/8c4xwOjg9TpkCvcmZiPUYGddPHWoKqAAhBwIDAQABAoIBABsUC/zSDEgvKOAl
-RLP8a3+hJfxoNjbMsIfK/YTYy/LJqud6PrjPbpYCjRgrgeXmKLXP0VwfAJ/G84Tf
-zIjxV5Qaf0HZaGKzimkwyBdkoGZlhry/fLt1hDolNHBoYuJ3nb4NiaIIiczkb3y7
-xt+0IhTqvNTaIh5ke83ZbPklJ8p0HAzw1q6+iRFZiZKH1iVRwJyIyK654wpNQ93W
-SqUKa3uAbqw+Bx9fzyEunANFwoBcZka9oSR9bTlhGB8HPHZFVYKgZvE4n9WOclKW
-E75pGG6vFYZkxBdqcjFNlPKKZRisDuey28teiHXThh1MvYxRdaMq4oxOE1J+n17k
-F2gQolECgYEA01j1FlExu45+U36n3tCCyS50dTtf0Qpi71c1s5DZyT+AAB2ZSGXm
-VBtKgVRNg/iWfHn5b/zHF30OtgIzcsrU66cWMwIXPUQigXh8Cteve7VMs03hce1w
-wsFwLoyvdWEam32YAymqRgN3H6JQim82IJJ3YlWrgEytBnvLkADCihkCgYEAzE/g
-8aoxDZJUwbvaZjLwuydmvc+aAwanVgqvtkca4x99oPhNQna6O0jXXAtJXMA3SHp5
-QYMDKh98BqCXyfXd+1Semc9pgAPz7l4j09WG7Zdap3xinTOkUsmTAz/2T967HIsP
-6qP7RUiwjmbUk8ZGcKsNjoxzPA4JURYimKB5qB8CgYBTjlnnJtaYpi8/Z1WK+7iZ
-PSqBpqWtCYQvx7TNdzkDHX3Hjewp+U9kdR2xn9i9kiw8riR1p+Q2XxTP1HLusU4Y
-lIhsRilV6XgS48V2q+sO55CZWvMEjbEE7mEhpjFAINHaI39T0Mcmwvv3n75j3K/z
-lLRqRiB1qtrFM3A5UHOZEQKBgBPQm2xUqTU7v+SaJ3BJ+HbuN1SpUbKBbrE1kB0J
-gF4Oq8x0yGltwloFkn1mytKoAbSRzDjCUAhBzXGHGbGImuLJLiiUqRK1T28Kyka9
-KrzYNP6RXa8JVyKAUjW6elT8sQDvq7eB99icWCM3bd53GFXNAR+WF4b3hYfLscdD
-qQjZAoGAB3ah068Qscb2Ef3+eufa+EvOfMDrNNvlEoZXRlhviTg3NEwjyqbxaCIy
-6Xg+rWvgJm9UE2RBOcCNeghkEabmL1+8DvmDiV1lt9oJtqULBirvalp2H3+9yiTk
-j5dnVcRF6cYvNFmwTr2WZFBGgq96d/Zmbx3o3MIqSBc8I6pLNzo=
+MIIEowIBAAKCAQEA4BZUGKkf52583Kps2SinCzRtGFaGIqtP1YfjaN1H21c08hEE
+RRWf0GqWPIbZz0NRyqOVM0O+4A9cxKrdqDpALBNXdgB62Ven1NNE31ZjsbFgwbOR
+PTiOQo+6Xsu+2KHQdqAGOXSqOdNSoZV/HqAKa41iweg6lUf3yrO/hpfnlXTFbuM/
+oYFARrr9YWY7qH5BEvcZBf4Sg3cWGjdbzYg8S6hnFBBkHPDMbS3xra7H8uru8aG9
+L70aiq0C3WsGf1/Qctz3cccB6BdnbiXji0QlP0miT+b52hEzDvNjdXvoObgbOZsU
+UcLrbz8qLqaQPj6TA2PYpKcxEdJLDcbN++tglQIDAQABAoIBAG5V8DB4TdI5T9ej
+Ppcqch2NQc5DBCbb7SI5l5qRogj5BoPOJykQ/bC0WqcQyvxHrGU3aIZma/yM8+OO
+Mjfb/q71ExJyKAsOIwAiyn2hXtMmgHq/vNrFFx7lACIe9ihafHd8UbRGom54g+41
+2vKsYJUWd7L8cqQAXJz9JmfSMeAfRBVVLyOpENSVT8gM/LgPokmZbg0wRJTA5oa3
+10f4Ax1HqXO3cQgKKnrvIU72gB7MQ9Y2G+P2eAmiAlzGr41N5sv7uFz0JrFHhqtC
+qc7QrGVVNtxanu0s/LWgfQ+LrKldTysX16j/j6J0tg7Pfuq9cMFPklU98dv2LF5J
+jMB8eQECgYEA84+Yy/IGVjUPVb3HjmCmWUoxt4Aqop/12/4+1cBNS6h58iLJpcWc
+FVh8m3UbuE7shimEg0fZ1rPPkqepKlDw8/sKXDni/khBASOAh2v1RhvOxNGjxDfn
+ZvcK+BG99kU8ZWQHpKmn8OGfYswL2Fvo67L9XFg/wDnk1QpJx7E1GVUCgYEA64gg
+G6qnsah1NKSW64BPVKi/Gby83l4oa1amjHqq/Unq6iuGB4/QhK4BzW0aOGI7RMTE
+SPh5NF5ZhfT3LWD/EnaMm6QxMTSsL9TDIg36WTVZTkbODFOJczg19EdTs1pa6OXW
+0NM6psLu6Nf/QmHJzyYxSZ83uqPOM305xgooKkECgYEAnA0XMySglr9sUd1EbJ7U
+NkVpUU8XAhdHKWrey4lofN83MsLDPCk+dha5z8jat94pgVQ8iPiSRBP1HNu7cVdm
+6ouf+bNFEvMsYxRiF2I+RmsuscA4E1JWOwxxxLtpYM6/gZ7znrbs2VNWEbD2retF
+cy69UltgjUMKsMzktMN/Z/kCgYAbzV285lAVMIVlSWhnNCYpICIur5C7zvGGehv+
+yRwV+fu42JphmiBLCR89WHuX3ECSxYdF9c6Y1+pJXbkvqhtx2nyOgrsry8PngX3n
+Ly82CI4aJ1F7MwEukJwN0b2XljrU8wyAae6qcKgy5AxFkbV4tlFrF1hEt8FHYqjH
+L7u+AQKBgBnN2vjOVagtlZjJadg5ueR7uKnfk7/TGMtZjNf89C1UZH3TqWnnj6p6
+rLLe4tnA3EebFtGeVWlmnw5k166HRBEd7KuebOCq3hkNlf71aHwhDJ0bIdDwo1g+
+FTpG2vqkqpuEb+2FzDjZT5EdPnj8tUGthREDXpXqsdjFb6+2Enjx
-----END RSA PRIVATE KEY-----
diff --git a/test/mitmproxy/data/servercert/trusted-root.pem b/test/mitmproxy/data/servercert/trusted-root.pem index a53cb893..2248d9f3 100644 --- a/test/mitmproxy/data/servercert/trusted-root.pem +++ b/test/mitmproxy/data/servercert/trusted-root.pem @@ -1,48 +1,48 @@ -----BEGIN CERTIFICATE-----
-MIIDXTCCAkWgAwIBAgIJALzkvKyFAwWYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
-BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
-aWRnaXRzIFB0eSBMdGQwHhcNMTgwOTA3MDgyMjUxWhcNMzgwOTAyMDgyMjUxWjBF
-MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
-ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAkvT4Y1ML8Gg4x5aFVygIW022tJsEyfuW4HsEvIarAGpFtUNkw0dOoAxv
-Gv71I0KAWOXxtc9DUjtq7ZXJcG+dBiheTYJ40lrYhHvUt7J37nrUF5v5trQzoE9I
-6WGtzTV8C8RI6F+M6GtwxgwRBgqkuXiK5ExPXAjGMMJZWtiEXHxGTNB6F4zy884m
-VjVtQi8jy+c5g21Awp3z5HrQLM210zwvgi7Rygk6/UM0AnmST4o32SqFSd+0MFUJ
-f3pH3xczfKmhU/TBoVEWRB1YzwixsJrzDOB8wOGnNKCsl45hYUJZZ8epVkyrvFZQ
-iMkwIqqBJbkU6H7fZBl68TJ8ascUCQIDAQABo1AwTjAdBgNVHQ4EFgQUkurgHlw1
-xMP2wrsrGPTk0ofxCyowHwYDVR0jBBgwFoAUkurgHlw1xMP2wrsrGPTk0ofxCyow
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcdExVlSvH6aVExNiQO3k
-cMamj+78woDn9x563vwzaGP24KvOXk1B/IJp5kqu3ZsXS0I0Mz6xwXHAXeuxaj06
-cKgEpHKKgClLblXo2zWqo/3V1UFFpOVP/NhI3r21b+fPrS46rP0mw75haQCph8/8
-buQr0OeAYbElliY/ji+cJiCJB8A/D13fUMV/NUUfPW/UE6497jOmz+6PtZNAoOFx
-evrmDcbCzbJxacyLJX04rsrt6DO09jb/+5lFm5Aqr6ySKasrmheIGEisl4o9Zbuy
-5PvYgbOEmFgPATIiWGpBO/rqwDdsmgyYFl+YfFoW0akXUVhDb2e5iRDx6Rs0fmN/
-NA==
+MIIDazCCAlOgAwIBAgIUTE2oFYATbkkytGOt0+CIAOPpaeEwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjMwMDA1MDlaFw0zOTEx
+MTgwMDA1MDlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDZ7fqv4iC6738OvOC/ONFmhOVmMNe2SrGtk+7KIv/M
+d7MJJKpIygwc99EfL3m6WFjvSQ8CABO9GnLIeoB6RzX5X904dPQzIekMkE27J4D5
+wzYWAmYsu9md//9rjadaA01zHvxtpc30AsToOrRa2Rv7Lwotvcop2bBCXXZMdgvD
+BpCuCOl3cQ346LZBmED41q77P7SgnI98gCPuyyMVAFTZE4NnFUloVERTcMMo5Vwv
+tXFT41B6FOqtyhZFY89W1SeNKlm+n8zu+/aUF5c9usxwvQzj79pzBFYS9xMZzbxl
+BmU91GbLFNU32O+wp0jX6c1MfluGvRjcHQpK+gHRRJdZAgMBAAGjUzBRMB0GA1Ud
+DgQWBBSTmtfFP/zQDiCbte3AG3vchjSekjAfBgNVHSMEGDAWgBSTmtfFP/zQDiCb
+te3AG3vchjSekjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB6
+CnGmyJKVdD41Qs8QbyZ5VvrAkSq7DkL4CAIDy0pClOYjx51R16g4/dXPd8nuDjVB
+GbRuO/ZHlKeO+RAVbV4s74KeBmQ4uyuZMvuiJGCDtTgu+fbgp1l41vj21bkDnz/X
+0aVrwC4clh6O1/AFCY7cYygp22QJ0zGpIb9d0ly6QDMEocHJKasuQ8/0GPvv6wkY
+hwNub2ScsVFHPrFzzufZblBk3Ks0YZw+IsCMTY7QtGb1TZhGeX9xAydqNMnmIxNj
+XOE2FKx4ISQNFwf/U1LEAruO7PjbbsWx5FHr4oYV9TCLoERZFofwcGGM9o/cPc4P
+CH8fGvFYoU30PG+xX0Pc
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAkvT4Y1ML8Gg4x5aFVygIW022tJsEyfuW4HsEvIarAGpFtUNk
-w0dOoAxvGv71I0KAWOXxtc9DUjtq7ZXJcG+dBiheTYJ40lrYhHvUt7J37nrUF5v5
-trQzoE9I6WGtzTV8C8RI6F+M6GtwxgwRBgqkuXiK5ExPXAjGMMJZWtiEXHxGTNB6
-F4zy884mVjVtQi8jy+c5g21Awp3z5HrQLM210zwvgi7Rygk6/UM0AnmST4o32SqF
-Sd+0MFUJf3pH3xczfKmhU/TBoVEWRB1YzwixsJrzDOB8wOGnNKCsl45hYUJZZ8ep
-VkyrvFZQiMkwIqqBJbkU6H7fZBl68TJ8ascUCQIDAQABAoIBAC/1mopvs9nFaaJZ
-UTLccb26YwIWBT4VyWuBOk58dJoyFIXPdLb2MoaxCCF7S20yasiYYoW/Gm1fzsmy
-tIbpJgm4au5Iwj2EQF0cPJOmvtUpaMY7tQcXUDHlLhpcMmhiKBV+/Xw4krfXOHqp
-vXSHTLLq0Akpjkyu4F9RTfAD8U5tEbpPsCGcsSJEHxPgqDexITDwB/yuhvrKKUwY
-t8WQBWO5M8D6Z1HGTFovIa86eX4hUKKbNB8sE7yi1wGxbOloIOQESOcqiisP5GGN
-d6r5k9jBwZXlyh7GR+GNILF+n6ctdOFr6MQQEKvDzjh/IVYADen19909Ed7Wn0gR
-C0Ec2gECgYEAwruIv33GWxGFvQmAUtPaHyhkFOiIpTrmZGeaJe7uLvAF86wK9v35
-wN2fH69JczO1iEWuqDLZ4nEorx6UvjSFBGYTXT1dAnULJ1KHvkk6JjbXq1srTY42
-U2h33XfJiNgrXlj6v7tMhKD/nBsfyw8v4aHxxUkJl2HomPSv7C7EvhECgYEAwTFp
-sUwDXVeputWwBvDUXHgGaVks28QHXvYH7Q0WsbFjb6lZVH/FxLXvGs7aaZk8WuHQ
-JJcXmEkTs1QDMMWoOlZw9WJv5Zlopq31oYHp8dt2EuO/PQcYmXYEG7JIHJhx8mfL
-f3Y4ix/hnvnITTg7bRNpcxwGEqyg16kalP8PXnkCgYEAgml5cVTYLFEV0b21NMMw
-RsGUFPSN3qoNdZx0fYb/+GtCcSf8x+DbDDDfyiZn+EDfB/4ys+4qQR4rcuv2DVO6
-6XE68qyPx39/EryQr/z2dnUwBlAuNehRtZY3ABii3YR3tt28P/89hW0VAgSgTCtF
-k8QS2F7Lj5hAX38u+etwUyECgYBWjf7eckHnpgjjLi3JTki2jQfCVzOj2nW689ul
-NwH95o24T1U4aG6ArUpM5nQwb3j89sK8Qf1OOx9abr9nMIcoa+X76nhbk5mxY6rz
-CzN3Km4CFItvmihJSPiaOAva0+npQtuHZb37hvMcuKgnAJSPT+0kp1+JKlJ9jMPe
-EVAfcQKBgQCDxRNXxn4ILyH3kx8lrch7kD5fp/7KifDjAFFJ0DK2e2xsxLUToh2I
-PdMuzCUv4LL8kRsQ/+mUJY4YlOV9OKVAZbI/gPw9NnzBUBugz+wy0OG/nyS5k7G5
-MIzZm8yx3RieTNhwmw25NDLyGApHGQYsQ7DM/daA/wwdjFsyncxHSg==
+MIIEpAIBAAKCAQEA2e36r+Iguu9/DrzgvzjRZoTlZjDXtkqxrZPuyiL/zHezCSSq
+SMoMHPfRHy95ulhY70kPAgATvRpyyHqAekc1+V/dOHT0MyHpDJBNuyeA+cM2FgJm
+LLvZnf//a42nWgNNcx78baXN9ALE6Dq0Wtkb+y8KLb3KKdmwQl12THYLwwaQrgjp
+d3EN+Oi2QZhA+Nau+z+0oJyPfIAj7ssjFQBU2RODZxVJaFREU3DDKOVcL7VxU+NQ
+ehTqrcoWRWPPVtUnjSpZvp/M7vv2lBeXPbrMcL0M4+/acwRWEvcTGc28ZQZlPdRm
+yxTVN9jvsKdI1+nNTH5bhr0Y3B0KSvoB0USXWQIDAQABAoIBAQCWWYbgHSPzlBOW
+eVyc0Hg3QGx7aisIStP2Kt9NeYP87oAISNFqUmq0+Yu+9iQHGbiRrVe7S45SopKa
+GVnWApcMKsUWlCl9tWFxF4VpH0HuDm2cFZ+kMR1b0ifHbf0NLsYaLEB+7Sr/s4Fh
+rk6LdsnFK5jcIdn9sX/W6WAaND69Ft45sMXuAKPeqwySm7t77nlIEp4lJy/F/rvS
+UUV77UVL/5GqC1HOP1kXXEJDxHtNrDPh0fF49Qo/6JPRmLIOia0yKUS5+8lKHh6V
+J7nWTucyvviKoYvdJHpi9w2+DTI7mT33Go1Ss4QgHihzcURTtfjsn7yOelS6z8XM
+YOxURwoZAoGBAPZpod0Zpjm9trf547reFPLfAJUiKDj1wYXnlpSFAzOf7pSXDrfW
+L5dc3c5x2DiBXUlBu03ZWo7wVOKv7d9ByTrvXEqT1/KTqmHoI6Mzy0rn9wU0FmL4
+ASPcpPMnNStOSmRfe9HITDVvgLYo2wQEu1MXf5rGs5HjTRpEGVdWRkRPAoGBAOJo
+pQ9uRtaLlCF3KXoRr8HCBKI64IWDki7pbbLTglOBbmptQLfE2GPc/FPBsQwR3KBX
+m18A2pc7CRUKzsDavb7SyXTqtP3NF/AguTjGXIv/45QD6A96SStaYR0ZXSA3/uhZ
+rAaSSXxaI3mDTc32pXoXJDp7K+CPc5w00I8u1/fXAoGAe1UPoPyPiGL+K0M1yngR
+gCZBwmMgQrIutHjfk2Kn4ZTw8wpQYY8grt/aXNP6Zv3I1TvDJgneG6EKu5NWueHR
+eGAJj4JEGbPzGaH5BFyOKeXEa6RQeCStXWe4X8OGBzDeZzKrZKqeCjjO8V2tkWtU
+3xfp1GwTwLdGBhmDnYUfEl0CgYEA1vzVF6T4gQtDGtADQ5V91je8nKvZvQ4lhoRD
+lVZAX7j8tvSNSrMRYypZM9Mtoi9n1524vGqcJpR5WFDN6NUM7iFMCMhCGupgO7Vn
+DCFXidzvJgLbna7Zwd/tbWtDQa/KTqmvrwHD49/X5a+n9tapZRiKXznMfUzaU87W
+589sZjsCgYBQvtZpNQRqTDNOSuIJGsloMNp1HG2Keoj/nBQ9idkw29rUqhae7ZAa
+Csk91ix+AMR8nzQSkpHWOk2+RjdVAQ7m87bnQM6mmAJTcipikDfFxNqOWt7JkM2h
+Ydk36LHBIBVLOeqMXrhCHvai3h6efUz7wjGhNxRJ2OGrzWFfLgVsqA==
-----END RSA PRIVATE KEY-----
diff --git a/test/mitmproxy/net/data/verificationcerts/9da13359.0 b/test/mitmproxy/net/data/verificationcerts/9da13359.0 index 5868a304..88ed4145 100644 --- a/test/mitmproxy/net/data/verificationcerts/9da13359.0 +++ b/test/mitmproxy/net/data/verificationcerts/9da13359.0 @@ -1,21 +1,21 @@ ------BEGIN CERTIFICATE----- -MIIDXTCCAkWgAwIBAgIJALzkvKyFAwWYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTgwOTA3MDgyMjUxWhcNMzgwOTAyMDgyMjUxWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAkvT4Y1ML8Gg4x5aFVygIW022tJsEyfuW4HsEvIarAGpFtUNkw0dOoAxv -Gv71I0KAWOXxtc9DUjtq7ZXJcG+dBiheTYJ40lrYhHvUt7J37nrUF5v5trQzoE9I -6WGtzTV8C8RI6F+M6GtwxgwRBgqkuXiK5ExPXAjGMMJZWtiEXHxGTNB6F4zy884m -VjVtQi8jy+c5g21Awp3z5HrQLM210zwvgi7Rygk6/UM0AnmST4o32SqFSd+0MFUJ -f3pH3xczfKmhU/TBoVEWRB1YzwixsJrzDOB8wOGnNKCsl45hYUJZZ8epVkyrvFZQ -iMkwIqqBJbkU6H7fZBl68TJ8ascUCQIDAQABo1AwTjAdBgNVHQ4EFgQUkurgHlw1 -xMP2wrsrGPTk0ofxCyowHwYDVR0jBBgwFoAUkurgHlw1xMP2wrsrGPTk0ofxCyow -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcdExVlSvH6aVExNiQO3k -cMamj+78woDn9x563vwzaGP24KvOXk1B/IJp5kqu3ZsXS0I0Mz6xwXHAXeuxaj06 -cKgEpHKKgClLblXo2zWqo/3V1UFFpOVP/NhI3r21b+fPrS46rP0mw75haQCph8/8 -buQr0OeAYbElliY/ji+cJiCJB8A/D13fUMV/NUUfPW/UE6497jOmz+6PtZNAoOFx -evrmDcbCzbJxacyLJX04rsrt6DO09jb/+5lFm5Aqr6ySKasrmheIGEisl4o9Zbuy -5PvYgbOEmFgPATIiWGpBO/rqwDdsmgyYFl+YfFoW0akXUVhDb2e5iRDx6Rs0fmN/ -NA== ------END CERTIFICATE----- +-----BEGIN CERTIFICATE-----
+MIIDazCCAlOgAwIBAgIUTE2oFYATbkkytGOt0+CIAOPpaeEwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjMwMDA1MDlaFw0zOTEx
+MTgwMDA1MDlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDZ7fqv4iC6738OvOC/ONFmhOVmMNe2SrGtk+7KIv/M
+d7MJJKpIygwc99EfL3m6WFjvSQ8CABO9GnLIeoB6RzX5X904dPQzIekMkE27J4D5
+wzYWAmYsu9md//9rjadaA01zHvxtpc30AsToOrRa2Rv7Lwotvcop2bBCXXZMdgvD
+BpCuCOl3cQ346LZBmED41q77P7SgnI98gCPuyyMVAFTZE4NnFUloVERTcMMo5Vwv
+tXFT41B6FOqtyhZFY89W1SeNKlm+n8zu+/aUF5c9usxwvQzj79pzBFYS9xMZzbxl
+BmU91GbLFNU32O+wp0jX6c1MfluGvRjcHQpK+gHRRJdZAgMBAAGjUzBRMB0GA1Ud
+DgQWBBSTmtfFP/zQDiCbte3AG3vchjSekjAfBgNVHSMEGDAWgBSTmtfFP/zQDiCb
+te3AG3vchjSekjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB6
+CnGmyJKVdD41Qs8QbyZ5VvrAkSq7DkL4CAIDy0pClOYjx51R16g4/dXPd8nuDjVB
+GbRuO/ZHlKeO+RAVbV4s74KeBmQ4uyuZMvuiJGCDtTgu+fbgp1l41vj21bkDnz/X
+0aVrwC4clh6O1/AFCY7cYygp22QJ0zGpIb9d0ly6QDMEocHJKasuQ8/0GPvv6wkY
+hwNub2ScsVFHPrFzzufZblBk3Ks0YZw+IsCMTY7QtGb1TZhGeX9xAydqNMnmIxNj
+XOE2FKx4ISQNFwf/U1LEAruO7PjbbsWx5FHr4oYV9TCLoERZFofwcGGM9o/cPc4P
+CH8fGvFYoU30PG+xX0Pc
+-----END CERTIFICATE-----
diff --git a/test/mitmproxy/net/data/verificationcerts/generate.py b/test/mitmproxy/net/data/verificationcerts/generate.py index 8439c9e6..1e09138d 100644 --- a/test/mitmproxy/net/data/verificationcerts/generate.py +++ b/test/mitmproxy/net/data/verificationcerts/generate.py @@ -5,10 +5,10 @@ import subprocess import shlex import os import shutil - +import textwrap ROOT_CA = "trusted-root" -SUBJECT = "/CN=example.mitmproxy.org/" +SUBJECT = "example.mitmproxy.org" def do(args): @@ -18,29 +18,39 @@ def do(args): return output -def genrsa(cert): - do("openssl genrsa -out {cert}.key 2048".format(cert=cert)) +def genrsa(cert: str): + do(f"openssl genrsa -out {cert}.key 2048") -def sign(cert): - do("openssl x509 -req -in {cert}.csr " - "-CA {root_ca}.crt " - "-CAkey {root_ca}.key " - "-CAcreateserial " - "-days 7300 " - "-out {cert}.crt".format(root_ca=ROOT_CA, cert=cert) +def sign(cert: str, subject: str): + with open(f"openssl-{cert}.conf", "w") as f: + f.write(textwrap.dedent(f""" + authorityKeyIdentifier=keyid,issuer + basicConstraints=CA:FALSE + keyUsage = digitalSignature, keyEncipherment + subjectAltName = {subject} + """)) + do(f"openssl x509 -req -in {cert}.csr " + f"-CA {ROOT_CA}.crt " + f"-CAkey {ROOT_CA}.key " + f"-CAcreateserial " + f"-days 7300 " + f"-sha256 " + f"-extfile \"openssl-{cert}.conf\" " + f"-out {cert}.crt" ) + os.remove(f"openssl-{cert}.conf") -def mkcert(cert, args): +def mkcert(cert, subject): genrsa(cert) - do("openssl req -new -nodes -batch " - "-key {cert}.key " - "{args} " - "-out {cert}.csr".format(cert=cert, args=args) + do(f"openssl req -new -nodes -batch " + f"-key {cert}.key " + f"-addext \"subjectAltName = {subject}\" " + f"-out {cert}.csr" ) - sign(cert) - os.remove("{cert}.csr".format(cert=cert)) + sign(cert, subject) + os.remove(f"{cert}.csr") # create trusted root CA @@ -54,13 +64,13 @@ h = do("openssl x509 -hash -noout -in trusted-root.crt").decode("ascii").strip() shutil.copyfile("trusted-root.crt", "{}.0".format(h)) # create trusted leaf cert. -mkcert("trusted-leaf", "-subj {}".format(SUBJECT)) +mkcert("trusted-leaf", f'DNS:{SUBJECT}') # create self-signed cert genrsa("self-signed") do("openssl req -x509 -new -nodes -batch " "-key self-signed.key " - "-subj {} " + f'-addext "subjectAltName = DNS:{SUBJECT}" ' "-days 7300 " - "-out self-signed.crt".format(SUBJECT) - ) + "-out self-signed.crt" + )
\ No newline at end of file diff --git a/test/mitmproxy/net/data/verificationcerts/self-signed.crt b/test/mitmproxy/net/data/verificationcerts/self-signed.crt index 6e234b8b..a02d9f32 100644 --- a/test/mitmproxy/net/data/verificationcerts/self-signed.crt +++ b/test/mitmproxy/net/data/verificationcerts/self-signed.crt @@ -1,19 +1,22 @@ ------BEGIN CERTIFICATE----- -MIIDEzCCAfugAwIBAgIJAKzH8k6aKTP6MA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNV -BAMMFWV4YW1wbGUubWl0bXByb3h5Lm9yZzAeFw0xODA5MDcwODIyNTNaFw0zODA5 -MDIwODIyNTNaMCAxHjAcBgNVBAMMFWV4YW1wbGUubWl0bXByb3h5Lm9yZzCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOjJMp2o5eLQEmYJqMZzLBi61h9 -fsCVMvS8hgrH1Cg5q/RaLBLrZ8nILKmFZBapMUEFkUwQLB864tdTMaX7p+jNv3sM -5LWEIYkTIbu6qV7QerKdubS1hpdFtQGRM1Q+C7H86FzF02DSKzNSmQc4fNed/lQM -qo/jOm1xx4TZFR4j58BrmmoOfNP44IyrwXsPyXbMsukKixVEB3vQ2oyGDAyG6dYi -VvM8PVL5yhX3BJ0D1Ky6hgGHJeirm0Cd8qqdSC/SWNdu1bGzg/xyUX5XFaHlIi7Y -5YhD7ZDLvC76MeCWkfo4DaSB0CWmtG4l1TtHM2JqP8qf2l2LsABKs0q/a+UCAwEA -AaNQME4wHQYDVR0OBBYEFIc9YAXgnGRhPTEcN/j+k/dxMdKqMB8GA1UdIwQYMBaA -FIc9YAXgnGRhPTEcN/j+k/dxMdKqMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAD9qKci3Pr4/2WGx+sv8gOpKchC9eF2dXc5hA3xbDw7T6oRLUBAY8Pty -JF7DHMovT+w7FPRYT8rSc190fbSwVRHAnEaqAzaxteImCp/qYgdBHOz39eG4c93W -YrYvA1VdUDPcUnisEVWguDsKJGFg+G6pw+8Wkf/hCrJJkriTFogGvzg6ptdQatvE -dpSkionfbuZKz+7lny6sCBGoMRIFBd22MHJsSQOyTb06Lwc5dpdF9c5vysPRzShJ -5kkgIjGpTmWp+Ud8BAMQH8EDhJMkJ7iw1+07UQ9MUmXCp9Xgim6x1ri2/yoz9HeO -83VCkD9YWufrzOrsXpo04rMYtoKo+lw= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIUb0mIVHKB+bu2PGObggokU3Re7xMwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjMwMDA1MDlaFw0zOTEx
+MTgwMDA1MDlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDF6eqyZD2z83buUF4T+6AY0Zoe925a2AHOhGtHJMLo
+9AD7FF1Xi1iksEvxbOI6mreHtvYKzUpfNsA3DkFdSO91HMSkdvWcDcExpW62sNK9
+gQQrpcCx7DogOrFiGSIHI1LIy1y6YEJma3G71SgGbw7g1QF64dTX9+BzVQJsloT2
+H3ZxTi8Fb6APJq6d/Tp67GTM8U82vM+FjLKzfH7RMSEPvSyvWSibw3AZP6owFaxz
+DJtXpR7evOZbiZxqXmGOBl5OQPu9GdDA3Fyi9Drp7xa234loqd1a8PYyL8qWV/2G
+HM3IJOzG8Y5PUJhL8CkDbx4LJ9LfzeSuBnQPUf2ZNalZAgMBAAGjdTBzMB0GA1Ud
+DgQWBBQbkS0mAGPD4XjOv9GKzGMyR9ix3TAfBgNVHSMEGDAWgBQbkS0mAGPD4XjO
+v9GKzGMyR9ix3TAPBgNVHRMBAf8EBTADAQH/MCAGA1UdEQQZMBeCFWV4YW1wbGUu
+bWl0bXByb3h5Lm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAqZ64xpu3qrTlCc555OoP
+GgobUFP3qv07d0/r48cOyYdAdlEHhvmDPlqWTB9e4ZYtWZMlocY9DpCywzKTa7F7
+Ad8BwS0a/No3wVdl1UEkIGYxuD//jbd77Mrpf5URvQco85o/bicn+H0GAOchYt1P
+jP1VShqsRv6WiTs5kn1/JwVoafddl1jBlMDmCqDv4loAZJYHzie0CqdjjSeorFfE
+8FG8OLwmEnmIW6VnanRH8coH9MBbZ+dRtCavS+Q8s0R77dJM1sCp5/4yKcr5D/PD
++dQN9f+iugLxDdBQjiRyadWX9/l4n/h8ezabZ4cNsiWbRXrp5VS0nGNmAK3XvPAu
+ow==
+-----END CERTIFICATE-----
diff --git a/test/mitmproxy/net/data/verificationcerts/self-signed.key b/test/mitmproxy/net/data/verificationcerts/self-signed.key index 3546c3fb..b6da998f 100644 --- a/test/mitmproxy/net/data/verificationcerts/self-signed.key +++ b/test/mitmproxy/net/data/verificationcerts/self-signed.key @@ -1,27 +1,27 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpgIBAAKCAQEAw6Mkynajl4tASZgmoxnMsGLrWH1+wJUy9LyGCsfUKDmr9Fos -EutnycgsqYVkFqkxQQWRTBAsHzri11Mxpfun6M2/ewzktYQhiRMhu7qpXtB6sp25 -tLWGl0W1AZEzVD4LsfzoXMXTYNIrM1KZBzh8153+VAyqj+M6bXHHhNkVHiPnwGua -ag580/jgjKvBew/Jdsyy6QqLFUQHe9DajIYMDIbp1iJW8zw9UvnKFfcEnQPUrLqG -AYcl6KubQJ3yqp1IL9JY127VsbOD/HJRflcVoeUiLtjliEPtkMu8Lvox4JaR+jgN -pIHQJaa0biXVO0czYmo/yp/aXYuwAEqzSr9r5QIDAQABAoIBAQC1RpgymlffdgJt -rvQuMRu/XQlhh3dJj3YV3BIAL0VguH+i/WLVbRdQm5D2y0kAzml7LGODrYCUt4W1 -q7rXaCYfy3Xf2QSbRQGl9/pL7xw9ZMQseYW38nPx+39LInYDWzKPDB9qx0uj7Vpm -ReTSEf9r81PUIaBxj0V2X/VWHag5scBjXoflQLxyV6i1UvTuWyhYvX1Bbaj02MqV -tGNMrjbj25Wx2za53VDonzNA6RMZzkWGMfzmkkGM6kjGzLEsveys+bYCt7Fs7slR -4oby0bIUmN7iqLhqlEhS4weWW4iHlq17X7CZeQAE1XeVZBz1N4G8FLjND2eyqb2N -RAcQqp3BAoGBAOiU3WTu/kSccteDRxR1gVRPqEgfoLDwyAb7ORVUWX4Ii/z/soMw -xZ2MlYPLnp3Fyu/hKhJPC1LzkD4CGHCTJJ1NnUudtDxl2Zh1FZYGmv1hi1TID/cm -G0+3XhlJgztS41+AzxTNMulV1yieT2HIRIoRpdSx1UIA72l42YqjrwUNAoGBANdV -/Ib+3hAfFtSMMI1qZQXvlKEoDRbUOCYuBVkTK8oQJQH6MLDokHZ8sXBAqi9383b1 -XmhQBJZ//yMy0AqFa2QBlkK0Gizzhh7BLSjIT2LREf66B2cWzhgdhbSp6Nuk+3DK -NfibxsFAPpW05HqtfxhbjrLfoE8VvTuMGQ8AaXw5AoGBAISo7IL2wrdV2TdN3Mwx -ndv+N4kz6Q8jt6QrxUqCOy1lKJvdKPAlcIJFvr5W9RkeyXr7nmilB1uAK4UC4vfL -JfZHX/HSeQx+N5f7KJ3TFLJz4eow1tJsvOVCPP0FbkH3LFO7/+HojSKEYN39NmAa -v+VU3Zas/GvSZrxtPwASDvE9AoGBAJOBbluW6MzITx5H7dZhRFR9miWOxvCVbOUS -b01mKX/f8UnadVIp7RONNQr88NdVZqxdRk9USOBDS6Vz4DjkzfySbbjBoJCcPIqC -r4mZNXAuYRJJolqGr6SrTHTGUyFqcWcAzVnAc7TbakOoxz4V7NLlnOmA8FJcROUu -gdfZ42hZAoGBANyL2IQ+L92iYVvqsz1zPBlvemevx8zP6GmlzvTcVexyDTIiLg6W -BVil5zRDPJdDiFfBK18Qg1mJoE4SjLTg+yGww9ef37Zb9kZypy6pM6AbRWILZ1Gv -7UsWUzk6rgcQpDdpJCUEt+AD3LQJTxxuoIhZePvC2GLkzsjZA7ZyB5+S ------END RSA PRIVATE KEY----- +-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAxenqsmQ9s/N27lBeE/ugGNGaHvduWtgBzoRrRyTC6PQA+xRd
+V4tYpLBL8WziOpq3h7b2Cs1KXzbANw5BXUjvdRzEpHb1nA3BMaVutrDSvYEEK6XA
+sew6IDqxYhkiByNSyMtcumBCZmtxu9UoBm8O4NUBeuHU1/fgc1UCbJaE9h92cU4v
+BW+gDyaunf06euxkzPFPNrzPhYyys3x+0TEhD70sr1kom8NwGT+qMBWscwybV6Ue
+3rzmW4mcal5hjgZeTkD7vRnQwNxcovQ66e8Wtt+JaKndWvD2Mi/Kllf9hhzNyCTs
+xvGOT1CYS/ApA28eCyfS383krgZ0D1H9mTWpWQIDAQABAoIBAGl4H8+TZeJ5E18q
+ywfhJ08ym+x2tYOJ62SP4s+WApy8M62aC6g0pTeWj9IH0YOjobycPwBAqKqW9dYh
+Lao1zQ5fF1gB4R+ZoOQBIkAPeS7uCzfrbAYlOlCklpUNibm+FEbXQQI9fAUyqviL
+Pno3QvmD6fb/VDsHaMBthA40JIU4C3yUUcSooKKUC3XKmbRDg5/stKbVdi6co5AQ
+OMNFj4smts3rXtk5tKMBep4AgKKdClf4IuhpWEqZDxN6e+hZA7g1VOmOIE+hKEEO
+ODBkjHNgHIFbsr8GTlZ+GSkHBxMNVdHxntJTU5a2jPiTNTTnhqu2hcVdkyDwLb9x
+TGUCdyUCgYEA/ZPwI2KaT4Lj8b+6DCV4v3nZF8nLCtt1LiXxJWexdnr+3q/ZfNjN
+5sKVl9rIynz2zoJDVr1MI8yjO6OmV7GBW2wgJsSFwg0vnV/bs75KqPZWZXqy/mrp
+HnXd82XUweyyOpmBg4cCjmcnMTrdvCHvfgx7JafnUDqeXNwriWeC5Y8CgYEAx83d
+qHgAT2rlnCQYRmCOGb5fuyQ+pSM4p8h1AjueLrTNiWcqX57ct9eVWjymD+AgevFZ
+hZH9m6TI4nCb/5ukcvjQb4g1kyY3l7rZiiJ3kf/c22kVsVUagJGeiW6Ypnox4r1o
+oFXEwAw1qSGIqOIjYVB2DqvjUl3+UjWCl9SOnpcCgYEA0TSdWUQ/VTwCvW9VmjHM
+FgT8I5Ebj+CRI7qv4hFTqxE8dxKTl1nzPd/ptTgOkmhY4vU7gzN3vs1VGp4gXZcX
+xwpE2Fcol3lzgB4Wz4s+Y3mgu+ZoCFjB7ZyGugmYZ0nVnV0KKi5X4I6gGhCb4VwK
+D29SpjWJNHq4LpqC3MDmkGcCgYAxnKOKXmmtTpy+3ZONfhIqwEOjA0fu10UNHFA5
+grYvYMOcd5pk7dxeZdB2/JI7ZOqLvHv/F5YCXLNozo9ds7bsuW2AFDFBXX72VPYJ
+P6+y9/ZOINS7GKeg/wd/lo+e3r6eT2u4TDOzgBSe722wiZ5BXqpB0Fp8rEwm+5R2
+wNe89wKBgQC59SOa4EW3gfjLRaH6hEPcMEzjr0Dt5ilBgntYbI+DsCePwEX28hAK
+fd7A6XoCqjnwLpAmh0cmNRsYjtPCzg6TXUdrhfnR/3r7DHzvsxaC06BfkPZJ0+Fu
+rP3el/oKSPaDsZKjW6RA5oqlIF82o45MNl2oCG82LgVtu25e3HbJSA==
+-----END RSA PRIVATE KEY-----
diff --git a/test/mitmproxy/net/data/verificationcerts/trusted-leaf.crt b/test/mitmproxy/net/data/verificationcerts/trusted-leaf.crt index 3ccae708..d71cbd07 100644 --- a/test/mitmproxy/net/data/verificationcerts/trusted-leaf.crt +++ b/test/mitmproxy/net/data/verificationcerts/trusted-leaf.crt @@ -1,18 +1,21 @@ ------BEGIN CERTIFICATE----- -MIIC4TCCAckCCQCj6D9oVylb9zANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMB4XDTE4MDkwNzA4MjI1MloXDTM4MDkwMjA4MjI1MlowIDEeMBwG -A1UEAwwVZXhhbXBsZS5taXRtcHJveHkub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAqKzVdsRKgthv6V/dk3Tncy4ymbACs383nGutjulExvroNOCw -b0y0e7unNGbtXxFQqSvA7eGaT1yRNfoMbXGSS+sn8A3gB6/s2A0Sw7KeSDdoaqEq -F/LzRBed1YkxSyy0GXuTd7HXNIoFn/eF1tqxgViWdfyFD85qY4yJ+luofdm7IcPM -ENPzV4nKzDh2PdJpQrEokWz2jM0zefC3IYnFHXY5bA3MnhE03/P0VxeEYkBdmEAt -O1U2Bkw9SKCLy9zF13ks6/dDZ9LjMtRKI83gQS5z3S3bA45YxFuyeLWgVsJ2NYTa -j9/8c4xwOjg9TpkCvcmZiPUYGddPHWoKqAAhBwIDAQABMA0GCSqGSIb3DQEBCwUA -A4IBAQAf8cjxunN4Y7NUD2Z/SNOJ/s0uWJtTPV6m4FxSwwD0wfbsyirPchmattLc -BabrQkeMMm8gMOrORfanXQwvLZvX0aDf96EgLSfHv8Iqeol5Byrgkn7UORXl20Jt -8UNRURUZYtWxn08P8dlhxQUncPF/UxCesC8x0cihqv+YTB3TX1sni9mOqPCYY8yH -E8kCW4zTJ0J9OQUHq9qdYQM/PGVm99+DWBItUeZAva8Rqj1FN3f9j1eWB+EjfYu7 -ztsTInpNWP4tIh6vIFtuaGr077cJawTe6YVyNxVqquI9+2fpSPkt7tCTIhbQ4AmM -DeHzn+KjfKN8ooWqmcfmUZWaADe0 ------END CERTIFICATE----- +-----BEGIN CERTIFICATE-----
+MIIDajCCAlKgAwIBAgIJAKPoP2hXKVv4MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTkxMTIzMDAwNTA5WhcNMzkxMTE4MDAwNTA5WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA4BZUGKkf52583Kps2SinCzRtGFaGIqtP1YfjaN1H21c08hEERRWf0GqW
+PIbZz0NRyqOVM0O+4A9cxKrdqDpALBNXdgB62Ven1NNE31ZjsbFgwbORPTiOQo+6
+Xsu+2KHQdqAGOXSqOdNSoZV/HqAKa41iweg6lUf3yrO/hpfnlXTFbuM/oYFARrr9
+YWY7qH5BEvcZBf4Sg3cWGjdbzYg8S6hnFBBkHPDMbS3xra7H8uru8aG9L70aiq0C
+3WsGf1/Qctz3cccB6BdnbiXji0QlP0miT+b52hEzDvNjdXvoObgbOZsUUcLrbz8q
+LqaQPj6TA2PYpKcxEdJLDcbN++tglQIDAQABo10wWzAfBgNVHSMEGDAWgBSTmtfF
+P/zQDiCbte3AG3vchjSekjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDAgBgNVHREE
+GTAXghVleGFtcGxlLm1pdG1wcm94eS5vcmcwDQYJKoZIhvcNAQELBQADggEBAMoK
+8+KTYF10dbQ8Hl3Fq4Iux7eutAPuKUXUz9dnCfDRhZukdl+gahRoNvkyMBdXOvvx
+R9Z2+Guo8NOYKgT1mJtS/c8IxTkjZj9doujJOVD2wTowSfoaT9z+/EJa+6Fp9+xd
+YVsO3E/2Vxai8PCNx8JTXr2axcnBDvpHPRXF21hOI8N94SPAcmLTZsdsTELjrGGa
+/BA0y+pCEwW6cY9mMHVAAvRoMoqfocBVI7nrYBaQfFoKuwxscxO679eEv+lbSjul
+z/VNdWfqrDhFFSzwRSVchapQ9q1EeTzv++wZRwI5bT0Ib6DFTJB3J5+9RihlFYfU
+GI17CI0D//DsFic7QJ0=
+-----END CERTIFICATE-----
diff --git a/test/mitmproxy/net/data/verificationcerts/trusted-leaf.key b/test/mitmproxy/net/data/verificationcerts/trusted-leaf.key index 7db3186e..e62ee61f 100644 --- a/test/mitmproxy/net/data/verificationcerts/trusted-leaf.key +++ b/test/mitmproxy/net/data/verificationcerts/trusted-leaf.key @@ -1,27 +1,27 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAqKzVdsRKgthv6V/dk3Tncy4ymbACs383nGutjulExvroNOCw -b0y0e7unNGbtXxFQqSvA7eGaT1yRNfoMbXGSS+sn8A3gB6/s2A0Sw7KeSDdoaqEq -F/LzRBed1YkxSyy0GXuTd7HXNIoFn/eF1tqxgViWdfyFD85qY4yJ+luofdm7IcPM -ENPzV4nKzDh2PdJpQrEokWz2jM0zefC3IYnFHXY5bA3MnhE03/P0VxeEYkBdmEAt -O1U2Bkw9SKCLy9zF13ks6/dDZ9LjMtRKI83gQS5z3S3bA45YxFuyeLWgVsJ2NYTa -j9/8c4xwOjg9TpkCvcmZiPUYGddPHWoKqAAhBwIDAQABAoIBABsUC/zSDEgvKOAl -RLP8a3+hJfxoNjbMsIfK/YTYy/LJqud6PrjPbpYCjRgrgeXmKLXP0VwfAJ/G84Tf -zIjxV5Qaf0HZaGKzimkwyBdkoGZlhry/fLt1hDolNHBoYuJ3nb4NiaIIiczkb3y7 -xt+0IhTqvNTaIh5ke83ZbPklJ8p0HAzw1q6+iRFZiZKH1iVRwJyIyK654wpNQ93W -SqUKa3uAbqw+Bx9fzyEunANFwoBcZka9oSR9bTlhGB8HPHZFVYKgZvE4n9WOclKW -E75pGG6vFYZkxBdqcjFNlPKKZRisDuey28teiHXThh1MvYxRdaMq4oxOE1J+n17k -F2gQolECgYEA01j1FlExu45+U36n3tCCyS50dTtf0Qpi71c1s5DZyT+AAB2ZSGXm -VBtKgVRNg/iWfHn5b/zHF30OtgIzcsrU66cWMwIXPUQigXh8Cteve7VMs03hce1w -wsFwLoyvdWEam32YAymqRgN3H6JQim82IJJ3YlWrgEytBnvLkADCihkCgYEAzE/g -8aoxDZJUwbvaZjLwuydmvc+aAwanVgqvtkca4x99oPhNQna6O0jXXAtJXMA3SHp5 -QYMDKh98BqCXyfXd+1Semc9pgAPz7l4j09WG7Zdap3xinTOkUsmTAz/2T967HIsP -6qP7RUiwjmbUk8ZGcKsNjoxzPA4JURYimKB5qB8CgYBTjlnnJtaYpi8/Z1WK+7iZ -PSqBpqWtCYQvx7TNdzkDHX3Hjewp+U9kdR2xn9i9kiw8riR1p+Q2XxTP1HLusU4Y -lIhsRilV6XgS48V2q+sO55CZWvMEjbEE7mEhpjFAINHaI39T0Mcmwvv3n75j3K/z -lLRqRiB1qtrFM3A5UHOZEQKBgBPQm2xUqTU7v+SaJ3BJ+HbuN1SpUbKBbrE1kB0J -gF4Oq8x0yGltwloFkn1mytKoAbSRzDjCUAhBzXGHGbGImuLJLiiUqRK1T28Kyka9 -KrzYNP6RXa8JVyKAUjW6elT8sQDvq7eB99icWCM3bd53GFXNAR+WF4b3hYfLscdD -qQjZAoGAB3ah068Qscb2Ef3+eufa+EvOfMDrNNvlEoZXRlhviTg3NEwjyqbxaCIy -6Xg+rWvgJm9UE2RBOcCNeghkEabmL1+8DvmDiV1lt9oJtqULBirvalp2H3+9yiTk -j5dnVcRF6cYvNFmwTr2WZFBGgq96d/Zmbx3o3MIqSBc8I6pLNzo= ------END RSA PRIVATE KEY----- +-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA4BZUGKkf52583Kps2SinCzRtGFaGIqtP1YfjaN1H21c08hEE
+RRWf0GqWPIbZz0NRyqOVM0O+4A9cxKrdqDpALBNXdgB62Ven1NNE31ZjsbFgwbOR
+PTiOQo+6Xsu+2KHQdqAGOXSqOdNSoZV/HqAKa41iweg6lUf3yrO/hpfnlXTFbuM/
+oYFARrr9YWY7qH5BEvcZBf4Sg3cWGjdbzYg8S6hnFBBkHPDMbS3xra7H8uru8aG9
+L70aiq0C3WsGf1/Qctz3cccB6BdnbiXji0QlP0miT+b52hEzDvNjdXvoObgbOZsU
+UcLrbz8qLqaQPj6TA2PYpKcxEdJLDcbN++tglQIDAQABAoIBAG5V8DB4TdI5T9ej
+Ppcqch2NQc5DBCbb7SI5l5qRogj5BoPOJykQ/bC0WqcQyvxHrGU3aIZma/yM8+OO
+Mjfb/q71ExJyKAsOIwAiyn2hXtMmgHq/vNrFFx7lACIe9ihafHd8UbRGom54g+41
+2vKsYJUWd7L8cqQAXJz9JmfSMeAfRBVVLyOpENSVT8gM/LgPokmZbg0wRJTA5oa3
+10f4Ax1HqXO3cQgKKnrvIU72gB7MQ9Y2G+P2eAmiAlzGr41N5sv7uFz0JrFHhqtC
+qc7QrGVVNtxanu0s/LWgfQ+LrKldTysX16j/j6J0tg7Pfuq9cMFPklU98dv2LF5J
+jMB8eQECgYEA84+Yy/IGVjUPVb3HjmCmWUoxt4Aqop/12/4+1cBNS6h58iLJpcWc
+FVh8m3UbuE7shimEg0fZ1rPPkqepKlDw8/sKXDni/khBASOAh2v1RhvOxNGjxDfn
+ZvcK+BG99kU8ZWQHpKmn8OGfYswL2Fvo67L9XFg/wDnk1QpJx7E1GVUCgYEA64gg
+G6qnsah1NKSW64BPVKi/Gby83l4oa1amjHqq/Unq6iuGB4/QhK4BzW0aOGI7RMTE
+SPh5NF5ZhfT3LWD/EnaMm6QxMTSsL9TDIg36WTVZTkbODFOJczg19EdTs1pa6OXW
+0NM6psLu6Nf/QmHJzyYxSZ83uqPOM305xgooKkECgYEAnA0XMySglr9sUd1EbJ7U
+NkVpUU8XAhdHKWrey4lofN83MsLDPCk+dha5z8jat94pgVQ8iPiSRBP1HNu7cVdm
+6ouf+bNFEvMsYxRiF2I+RmsuscA4E1JWOwxxxLtpYM6/gZ7znrbs2VNWEbD2retF
+cy69UltgjUMKsMzktMN/Z/kCgYAbzV285lAVMIVlSWhnNCYpICIur5C7zvGGehv+
+yRwV+fu42JphmiBLCR89WHuX3ECSxYdF9c6Y1+pJXbkvqhtx2nyOgrsry8PngX3n
+Ly82CI4aJ1F7MwEukJwN0b2XljrU8wyAae6qcKgy5AxFkbV4tlFrF1hEt8FHYqjH
+L7u+AQKBgBnN2vjOVagtlZjJadg5ueR7uKnfk7/TGMtZjNf89C1UZH3TqWnnj6p6
+rLLe4tnA3EebFtGeVWlmnw5k166HRBEd7KuebOCq3hkNlf71aHwhDJ0bIdDwo1g+
+FTpG2vqkqpuEb+2FzDjZT5EdPnj8tUGthREDXpXqsdjFb6+2Enjx
+-----END RSA PRIVATE KEY-----
diff --git a/test/mitmproxy/net/data/verificationcerts/trusted-root.crt b/test/mitmproxy/net/data/verificationcerts/trusted-root.crt index 5868a304..88ed4145 100644 --- a/test/mitmproxy/net/data/verificationcerts/trusted-root.crt +++ b/test/mitmproxy/net/data/verificationcerts/trusted-root.crt @@ -1,21 +1,21 @@ ------BEGIN CERTIFICATE----- -MIIDXTCCAkWgAwIBAgIJALzkvKyFAwWYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTgwOTA3MDgyMjUxWhcNMzgwOTAyMDgyMjUxWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAkvT4Y1ML8Gg4x5aFVygIW022tJsEyfuW4HsEvIarAGpFtUNkw0dOoAxv -Gv71I0KAWOXxtc9DUjtq7ZXJcG+dBiheTYJ40lrYhHvUt7J37nrUF5v5trQzoE9I -6WGtzTV8C8RI6F+M6GtwxgwRBgqkuXiK5ExPXAjGMMJZWtiEXHxGTNB6F4zy884m -VjVtQi8jy+c5g21Awp3z5HrQLM210zwvgi7Rygk6/UM0AnmST4o32SqFSd+0MFUJ -f3pH3xczfKmhU/TBoVEWRB1YzwixsJrzDOB8wOGnNKCsl45hYUJZZ8epVkyrvFZQ -iMkwIqqBJbkU6H7fZBl68TJ8ascUCQIDAQABo1AwTjAdBgNVHQ4EFgQUkurgHlw1 -xMP2wrsrGPTk0ofxCyowHwYDVR0jBBgwFoAUkurgHlw1xMP2wrsrGPTk0ofxCyow -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcdExVlSvH6aVExNiQO3k -cMamj+78woDn9x563vwzaGP24KvOXk1B/IJp5kqu3ZsXS0I0Mz6xwXHAXeuxaj06 -cKgEpHKKgClLblXo2zWqo/3V1UFFpOVP/NhI3r21b+fPrS46rP0mw75haQCph8/8 -buQr0OeAYbElliY/ji+cJiCJB8A/D13fUMV/NUUfPW/UE6497jOmz+6PtZNAoOFx -evrmDcbCzbJxacyLJX04rsrt6DO09jb/+5lFm5Aqr6ySKasrmheIGEisl4o9Zbuy -5PvYgbOEmFgPATIiWGpBO/rqwDdsmgyYFl+YfFoW0akXUVhDb2e5iRDx6Rs0fmN/ -NA== ------END CERTIFICATE----- +-----BEGIN CERTIFICATE-----
+MIIDazCCAlOgAwIBAgIUTE2oFYATbkkytGOt0+CIAOPpaeEwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjMwMDA1MDlaFw0zOTEx
+MTgwMDA1MDlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDZ7fqv4iC6738OvOC/ONFmhOVmMNe2SrGtk+7KIv/M
+d7MJJKpIygwc99EfL3m6WFjvSQ8CABO9GnLIeoB6RzX5X904dPQzIekMkE27J4D5
+wzYWAmYsu9md//9rjadaA01zHvxtpc30AsToOrRa2Rv7Lwotvcop2bBCXXZMdgvD
+BpCuCOl3cQ346LZBmED41q77P7SgnI98gCPuyyMVAFTZE4NnFUloVERTcMMo5Vwv
+tXFT41B6FOqtyhZFY89W1SeNKlm+n8zu+/aUF5c9usxwvQzj79pzBFYS9xMZzbxl
+BmU91GbLFNU32O+wp0jX6c1MfluGvRjcHQpK+gHRRJdZAgMBAAGjUzBRMB0GA1Ud
+DgQWBBSTmtfFP/zQDiCbte3AG3vchjSekjAfBgNVHSMEGDAWgBSTmtfFP/zQDiCb
+te3AG3vchjSekjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB6
+CnGmyJKVdD41Qs8QbyZ5VvrAkSq7DkL4CAIDy0pClOYjx51R16g4/dXPd8nuDjVB
+GbRuO/ZHlKeO+RAVbV4s74KeBmQ4uyuZMvuiJGCDtTgu+fbgp1l41vj21bkDnz/X
+0aVrwC4clh6O1/AFCY7cYygp22QJ0zGpIb9d0ly6QDMEocHJKasuQ8/0GPvv6wkY
+hwNub2ScsVFHPrFzzufZblBk3Ks0YZw+IsCMTY7QtGb1TZhGeX9xAydqNMnmIxNj
+XOE2FKx4ISQNFwf/U1LEAruO7PjbbsWx5FHr4oYV9TCLoERZFofwcGGM9o/cPc4P
+CH8fGvFYoU30PG+xX0Pc
+-----END CERTIFICATE-----
diff --git a/test/mitmproxy/net/data/verificationcerts/trusted-root.key b/test/mitmproxy/net/data/verificationcerts/trusted-root.key index c690751f..11a4d5a6 100644 --- a/test/mitmproxy/net/data/verificationcerts/trusted-root.key +++ b/test/mitmproxy/net/data/verificationcerts/trusted-root.key @@ -1,27 +1,27 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAkvT4Y1ML8Gg4x5aFVygIW022tJsEyfuW4HsEvIarAGpFtUNk -w0dOoAxvGv71I0KAWOXxtc9DUjtq7ZXJcG+dBiheTYJ40lrYhHvUt7J37nrUF5v5 -trQzoE9I6WGtzTV8C8RI6F+M6GtwxgwRBgqkuXiK5ExPXAjGMMJZWtiEXHxGTNB6 -F4zy884mVjVtQi8jy+c5g21Awp3z5HrQLM210zwvgi7Rygk6/UM0AnmST4o32SqF -Sd+0MFUJf3pH3xczfKmhU/TBoVEWRB1YzwixsJrzDOB8wOGnNKCsl45hYUJZZ8ep -VkyrvFZQiMkwIqqBJbkU6H7fZBl68TJ8ascUCQIDAQABAoIBAC/1mopvs9nFaaJZ -UTLccb26YwIWBT4VyWuBOk58dJoyFIXPdLb2MoaxCCF7S20yasiYYoW/Gm1fzsmy -tIbpJgm4au5Iwj2EQF0cPJOmvtUpaMY7tQcXUDHlLhpcMmhiKBV+/Xw4krfXOHqp -vXSHTLLq0Akpjkyu4F9RTfAD8U5tEbpPsCGcsSJEHxPgqDexITDwB/yuhvrKKUwY -t8WQBWO5M8D6Z1HGTFovIa86eX4hUKKbNB8sE7yi1wGxbOloIOQESOcqiisP5GGN -d6r5k9jBwZXlyh7GR+GNILF+n6ctdOFr6MQQEKvDzjh/IVYADen19909Ed7Wn0gR -C0Ec2gECgYEAwruIv33GWxGFvQmAUtPaHyhkFOiIpTrmZGeaJe7uLvAF86wK9v35 -wN2fH69JczO1iEWuqDLZ4nEorx6UvjSFBGYTXT1dAnULJ1KHvkk6JjbXq1srTY42 -U2h33XfJiNgrXlj6v7tMhKD/nBsfyw8v4aHxxUkJl2HomPSv7C7EvhECgYEAwTFp -sUwDXVeputWwBvDUXHgGaVks28QHXvYH7Q0WsbFjb6lZVH/FxLXvGs7aaZk8WuHQ -JJcXmEkTs1QDMMWoOlZw9WJv5Zlopq31oYHp8dt2EuO/PQcYmXYEG7JIHJhx8mfL -f3Y4ix/hnvnITTg7bRNpcxwGEqyg16kalP8PXnkCgYEAgml5cVTYLFEV0b21NMMw -RsGUFPSN3qoNdZx0fYb/+GtCcSf8x+DbDDDfyiZn+EDfB/4ys+4qQR4rcuv2DVO6 -6XE68qyPx39/EryQr/z2dnUwBlAuNehRtZY3ABii3YR3tt28P/89hW0VAgSgTCtF -k8QS2F7Lj5hAX38u+etwUyECgYBWjf7eckHnpgjjLi3JTki2jQfCVzOj2nW689ul -NwH95o24T1U4aG6ArUpM5nQwb3j89sK8Qf1OOx9abr9nMIcoa+X76nhbk5mxY6rz -CzN3Km4CFItvmihJSPiaOAva0+npQtuHZb37hvMcuKgnAJSPT+0kp1+JKlJ9jMPe -EVAfcQKBgQCDxRNXxn4ILyH3kx8lrch7kD5fp/7KifDjAFFJ0DK2e2xsxLUToh2I -PdMuzCUv4LL8kRsQ/+mUJY4YlOV9OKVAZbI/gPw9NnzBUBugz+wy0OG/nyS5k7G5 -MIzZm8yx3RieTNhwmw25NDLyGApHGQYsQ7DM/daA/wwdjFsyncxHSg== ------END RSA PRIVATE KEY----- +-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA2e36r+Iguu9/DrzgvzjRZoTlZjDXtkqxrZPuyiL/zHezCSSq
+SMoMHPfRHy95ulhY70kPAgATvRpyyHqAekc1+V/dOHT0MyHpDJBNuyeA+cM2FgJm
+LLvZnf//a42nWgNNcx78baXN9ALE6Dq0Wtkb+y8KLb3KKdmwQl12THYLwwaQrgjp
+d3EN+Oi2QZhA+Nau+z+0oJyPfIAj7ssjFQBU2RODZxVJaFREU3DDKOVcL7VxU+NQ
+ehTqrcoWRWPPVtUnjSpZvp/M7vv2lBeXPbrMcL0M4+/acwRWEvcTGc28ZQZlPdRm
+yxTVN9jvsKdI1+nNTH5bhr0Y3B0KSvoB0USXWQIDAQABAoIBAQCWWYbgHSPzlBOW
+eVyc0Hg3QGx7aisIStP2Kt9NeYP87oAISNFqUmq0+Yu+9iQHGbiRrVe7S45SopKa
+GVnWApcMKsUWlCl9tWFxF4VpH0HuDm2cFZ+kMR1b0ifHbf0NLsYaLEB+7Sr/s4Fh
+rk6LdsnFK5jcIdn9sX/W6WAaND69Ft45sMXuAKPeqwySm7t77nlIEp4lJy/F/rvS
+UUV77UVL/5GqC1HOP1kXXEJDxHtNrDPh0fF49Qo/6JPRmLIOia0yKUS5+8lKHh6V
+J7nWTucyvviKoYvdJHpi9w2+DTI7mT33Go1Ss4QgHihzcURTtfjsn7yOelS6z8XM
+YOxURwoZAoGBAPZpod0Zpjm9trf547reFPLfAJUiKDj1wYXnlpSFAzOf7pSXDrfW
+L5dc3c5x2DiBXUlBu03ZWo7wVOKv7d9ByTrvXEqT1/KTqmHoI6Mzy0rn9wU0FmL4
+ASPcpPMnNStOSmRfe9HITDVvgLYo2wQEu1MXf5rGs5HjTRpEGVdWRkRPAoGBAOJo
+pQ9uRtaLlCF3KXoRr8HCBKI64IWDki7pbbLTglOBbmptQLfE2GPc/FPBsQwR3KBX
+m18A2pc7CRUKzsDavb7SyXTqtP3NF/AguTjGXIv/45QD6A96SStaYR0ZXSA3/uhZ
+rAaSSXxaI3mDTc32pXoXJDp7K+CPc5w00I8u1/fXAoGAe1UPoPyPiGL+K0M1yngR
+gCZBwmMgQrIutHjfk2Kn4ZTw8wpQYY8grt/aXNP6Zv3I1TvDJgneG6EKu5NWueHR
+eGAJj4JEGbPzGaH5BFyOKeXEa6RQeCStXWe4X8OGBzDeZzKrZKqeCjjO8V2tkWtU
+3xfp1GwTwLdGBhmDnYUfEl0CgYEA1vzVF6T4gQtDGtADQ5V91je8nKvZvQ4lhoRD
+lVZAX7j8tvSNSrMRYypZM9Mtoi9n1524vGqcJpR5WFDN6NUM7iFMCMhCGupgO7Vn
+DCFXidzvJgLbna7Zwd/tbWtDQa/KTqmvrwHD49/X5a+n9tapZRiKXznMfUzaU87W
+589sZjsCgYBQvtZpNQRqTDNOSuIJGsloMNp1HG2Keoj/nBQ9idkw29rUqhae7ZAa
+Csk91ix+AMR8nzQSkpHWOk2+RjdVAQ7m87bnQM6mmAJTcipikDfFxNqOWt7JkM2h
+Ydk36LHBIBVLOeqMXrhCHvai3h6efUz7wjGhNxRJ2OGrzWFfLgVsqA==
+-----END RSA PRIVATE KEY-----
diff --git a/test/mitmproxy/net/data/verificationcerts/trusted-root.srl b/test/mitmproxy/net/data/verificationcerts/trusted-root.srl index cf60e2a5..ee465f9d 100644 --- a/test/mitmproxy/net/data/verificationcerts/trusted-root.srl +++ b/test/mitmproxy/net/data/verificationcerts/trusted-root.srl @@ -1 +1 @@ -A3E83F6857295BF7 +A3E83F6857295BF8
diff --git a/test/mitmproxy/net/http/http1/test_assemble.py b/test/mitmproxy/net/http/http1/test_assemble.py index ab177885..4b4ab414 100644 --- a/test/mitmproxy/net/http/http1/test_assemble.py +++ b/test/mitmproxy/net/http/http1/test_assemble.py @@ -15,7 +15,6 @@ def test_assemble_request(): b"GET /path HTTP/1.1\r\n" b"header: qvalue\r\n" b"content-length: 7\r\n" - b"host: address:22\r\n" b"\r\n" b"content" ) @@ -84,17 +83,6 @@ def test_assemble_request_headers(): assert b"Transfer-Encoding" in c -def test_assemble_request_headers_host_header(): - r = treq() - r.headers = Headers() - c = _assemble_request_headers(r.data) - assert b"host" in c - - r.host = None - c = _assemble_request_headers(r.data) - assert b"host" not in c - - def test_assemble_response_headers(): # https://github.com/mitmproxy/mitmproxy/issues/186 r = tresp(content=b"") diff --git a/test/mitmproxy/net/http/http1/test_read.py b/test/mitmproxy/net/http/http1/test_read.py index 4084c360..127f75ba 100644 --- a/test/mitmproxy/net/http/http1/test_read.py +++ b/test/mitmproxy/net/http/http1/test_read.py @@ -163,6 +163,11 @@ def test_expected_http_body_size(): assert expected_http_body_size( treq(headers=Headers(expect="100-continue", content_length="42")) ) == 0 + # Expect: 100-continue + assert expected_http_body_size( + treq(headers=Headers(expect="100-continue", content_length="42")), + expect_continue_as_0=False + ) == 42 # http://tools.ietf.org/html/rfc7230#section-3.3 assert expected_http_body_size( diff --git a/test/mitmproxy/net/http/test_headers.py b/test/mitmproxy/net/http/test_headers.py index 8fc8b027..5f208dcb 100644 --- a/test/mitmproxy/net/http/test_headers.py +++ b/test/mitmproxy/net/http/test_headers.py @@ -88,6 +88,8 @@ class TestHeaders: headers = Headers(Host="foobarfoo.com", Accept="foo/bar") replacements = headers.replace("foo", "bar", count=1) assert replacements == 1 + assert headers["Host"] == "barbarfoo.com" + assert headers["Accept"] == "foo/bar" def test_parse_content_type(): diff --git a/test/mitmproxy/net/test_check.py b/test/mitmproxy/net/test_check.py index 0ffd6b2e..649e71da 100644 --- a/test/mitmproxy/net/test_check.py +++ b/test/mitmproxy/net/test_check.py @@ -12,3 +12,61 @@ def test_is_valid_host(): # Allow underscore assert check.is_valid_host(b"one_two") assert check.is_valid_host(b"::1") + + # IP Address Validations + assert check.is_valid_host(b'127.0.0.1') + assert check.is_valid_host(b'2001:0db8:85a3:0000:0000:8a2e:0370:7334') + assert check.is_valid_host(b'2001:db8:85a3:0:0:8a2e:370:7334') + assert check.is_valid_host(b'2001:db8:85a3::8a2e:370:7334') + assert not check.is_valid_host(b'2001:db8::85a3::7334') + assert check.is_valid_host(b'2001-db8-85a3-8d3-1319-8a2e-370-7348.ipv6-literal.net') + + # TLD must be between 2 and 63 chars + assert check.is_valid_host(b'example.tl') + assert check.is_valid_host(b'example.tld') + assert check.is_valid_host(b'example.' + b"x" * 63) + assert not check.is_valid_host(b'example.' + b"x" * 64) + + # misc characters test + assert not check.is_valid_host(b'ex@mple') + assert not check.is_valid_host(b'ex@mple.com') + assert not check.is_valid_host(b'example..com') + assert not check.is_valid_host(b'.example.com') + assert not check.is_valid_host(b'@.example.com') + assert not check.is_valid_host(b'!.example.com') + + # Every label must be between 1 and 63 chars + assert not check.is_valid_host(b'.tld') + assert check.is_valid_host(b'x' * 1 + b'.tld') + assert check.is_valid_host(b'x' * 30 + b'.tld') + assert not check.is_valid_host(b'x' * 64 + b'.tld') + assert check.is_valid_host(b'x' * 1 + b'.example.tld') + assert check.is_valid_host(b'x' * 30 + b'.example.tld') + assert not check.is_valid_host(b'x' * 64 + b'.example.tld') + + # Misc Underscore Test Cases + assert check.is_valid_host(b'_example') + assert check.is_valid_host(b'_example_') + assert check.is_valid_host(b'example_') + assert check.is_valid_host(b'_a.example.tld') + assert check.is_valid_host(b'a_.example.tld') + assert check.is_valid_host(b'_a_.example.tld') + + # Misc Dash/Hyphen/Minus Test Cases + assert check.is_valid_host(b'-example') + assert check.is_valid_host(b'-example_') + assert check.is_valid_host(b'example-') + assert check.is_valid_host(b'-a.example.tld') + assert check.is_valid_host(b'a-.example.tld') + assert check.is_valid_host(b'-a-.example.tld') + + # Misc Combo Test Cases + assert check.is_valid_host(b'api-.example.com') + assert check.is_valid_host(b'__a.example-site.com') + assert check.is_valid_host(b'_-a.example-site.com') + assert check.is_valid_host(b'_a_.example-site.com') + assert check.is_valid_host(b'-a-.example-site.com') + assert check.is_valid_host(b'api-.a.example.com') + assert check.is_valid_host(b'api-._a.example.com') + assert check.is_valid_host(b'api-.a_.example.com') + assert check.is_valid_host(b'api-.ab.example.com')
\ No newline at end of file diff --git a/test/mitmproxy/net/test_tcp.py b/test/mitmproxy/net/test_tcp.py index 22a306dc..ba9b7ebc 100644 --- a/test/mitmproxy/net/test_tcp.py +++ b/test/mitmproxy/net/test_tcp.py @@ -37,7 +37,7 @@ class ClientCipherListHandler(tcp.BaseHandler): sni = None def handle(self): - self.wfile.write(str(self.connection.get_cipher_list()).encode()) + self.wfile.write(f"{self.connection.get_cipher_list()}\n".encode()) self.wfile.flush() @@ -219,7 +219,7 @@ class TestInvalidTrustFile(tservers.ServerTestBase): c.convert_to_tls( sni="example.mitmproxy.org", verify=SSL.VERIFY_PEER, - ca_pemfile=tdata.path("mitmproxy/net/data/verificationcerts/generate.py") + ca_pemfile=cdata.path("data/verificationcerts/generate.py") ) @@ -265,7 +265,7 @@ class TestSSLUpstreamCertVerificationWBadServerCert(tservers.ServerTestBase): c.convert_to_tls( sni="example.mitmproxy.org", verify=SSL.VERIFY_PEER, - ca_pemfile=tdata.path("mitmproxy/net/data/verificationcerts/trusted-root.crt") + ca_pemfile=cdata.path("data/verificationcerts/trusted-root.crt") ) assert c.ssl_verification_error @@ -289,7 +289,7 @@ class TestSSLUpstreamCertVerificationWBadHostname(tservers.ServerTestBase): with pytest.raises(exceptions.TlsException): c.convert_to_tls( verify=SSL.VERIFY_PEER, - ca_pemfile=tdata.path("mitmproxy/net/data/verificationcerts/trusted-root.crt") + ca_pemfile=cdata.path("data/verificationcerts/trusted-root.crt") ) def test_mode_none_should_pass_without_sni(self, tdata): @@ -297,10 +297,10 @@ class TestSSLUpstreamCertVerificationWBadHostname(tservers.ServerTestBase): with c.connect(): c.convert_to_tls( verify=SSL.VERIFY_NONE, - ca_path=tdata.path("mitmproxy/net/data/verificationcerts/") + ca_path=cdata.path("data/verificationcerts/") ) - assert "'no-hostname' doesn't match" in str(c.ssl_verification_error) + assert "Cannot validate hostname, SNI missing." in str(c.ssl_verification_error) def test_should_fail(self, tdata): c = tcp.TCPClient(("127.0.0.1", self.port)) @@ -309,7 +309,7 @@ class TestSSLUpstreamCertVerificationWBadHostname(tservers.ServerTestBase): c.convert_to_tls( sni="mitmproxy.org", verify=SSL.VERIFY_PEER, - ca_pemfile=tdata.path("mitmproxy/net/data/verificationcerts/trusted-root.crt") + ca_pemfile=cdata.path("data/verificationcerts/trusted-root.crt") ) assert c.ssl_verification_error @@ -328,7 +328,7 @@ class TestSSLUpstreamCertVerificationWValidCertChain(tservers.ServerTestBase): c.convert_to_tls( sni="example.mitmproxy.org", verify=SSL.VERIFY_PEER, - ca_pemfile=tdata.path("mitmproxy/net/data/verificationcerts/trusted-root.crt") + ca_pemfile=cdata.path("data/verificationcerts/trusted-root.crt") ) assert c.ssl_verification_error is None @@ -344,7 +344,7 @@ class TestSSLUpstreamCertVerificationWValidCertChain(tservers.ServerTestBase): c.convert_to_tls( sni="example.mitmproxy.org", verify=SSL.VERIFY_PEER, - ca_path=tdata.path("mitmproxy/net/data/verificationcerts/") + ca_path=cdata.path("data/verificationcerts/") ) assert c.ssl_verification_error is None @@ -376,14 +376,14 @@ class TestSSLClientCert(tservers.ServerTestBase): c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): c.convert_to_tls( - cert=tdata.path("mitmproxy/net/data/clientcert/client.pem")) + cert=cdata.path("data/clientcert/client.pem")) assert c.rfile.readline().strip() == b"1" def test_clientcert_err(self, tdata): c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): with pytest.raises(exceptions.TlsException): - c.convert_to_tls(cert=tdata.path("mitmproxy/net/data/clientcert/make")) + c.convert_to_tls(cert=cdata.path("data/clientcert/make")) class TestSNI(tservers.ServerTestBase): @@ -421,16 +421,18 @@ class TestServerCipherList(tservers.ServerTestBase): cipher_list='AES256-GCM-SHA384' ) + @pytest.mark.xfail def test_echo(self): + # Not working for OpenSSL 1.1.1, see + # https://github.com/pyca/pyopenssl/blob/fc802df5c10f0d1cd9749c94887d652fa26db6fb/src/OpenSSL/SSL.py#L1192-L1196 c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): c.convert_to_tls(sni="foo.com") - expected = b"['AES256-GCM-SHA384']" - assert c.rfile.read(len(expected) + 2) == expected + expected = b"['TLS_AES_256_GCM_SHA384']" + assert c.rfile.readline() == expected class TestServerCurrentCipher(tservers.ServerTestBase): - class handler(tcp.BaseHandler): sni = None @@ -442,7 +444,10 @@ class TestServerCurrentCipher(tservers.ServerTestBase): cipher_list='AES256-GCM-SHA384' ) + @pytest.mark.xfail def test_echo(self): + # Not working for OpenSSL 1.1.1, see + # https://github.com/pyca/pyopenssl/blob/fc802df5c10f0d1cd9749c94887d652fa26db6fb/src/OpenSSL/SSL.py#L1192-L1196 c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): c.convert_to_tls(sni="foo.com") @@ -608,7 +613,7 @@ class TestDHParams(tservers.ServerTestBase): def test_dhparams(self): c = tcp.TCPClient(("127.0.0.1", self.port)) with c.connect(): - c.convert_to_tls() + c.convert_to_tls(method=SSL.TLSv1_2_METHOD) ret = c.get_current_cipher() assert ret[0] == "DHE-RSA-AES256-SHA" diff --git a/test/mitmproxy/net/test_tls.py b/test/mitmproxy/net/test_tls.py index c4e76bc6..e78564c7 100644 --- a/test/mitmproxy/net/test_tls.py +++ b/test/mitmproxy/net/test_tls.py @@ -43,7 +43,7 @@ class TestMasterSecretLogger(tservers.ServerTestBase): tls.log_master_secret.close() with open(logfile, "rb") as f: - assert f.read().count(b"CLIENT_RANDOM") == 2 + assert f.read().count(b"CLIENT_RANDOM") >= 2 tls.log_master_secret = _logfun diff --git a/test/mitmproxy/proxy/protocol/test_http2.py b/test/mitmproxy/proxy/protocol/test_http2.py index b5f21413..0afa6305 100644 --- a/test/mitmproxy/proxy/protocol/test_http2.py +++ b/test/mitmproxy/proxy/protocol/test_http2.py @@ -496,6 +496,71 @@ class TestStreamResetFromServer(_Http2Test): assert self.master.state.flows[0].response is None +class TestAllStreamResetsFromServer(_Http2Test): + + current_error_name = None + current_error_code = None + + @classmethod + def handle_server_event(cls, event, h2_conn, rfile, wfile): + if isinstance(event, h2.events.ConnectionTerminated): + return False + elif isinstance(event, h2.events.RequestReceived): + h2_conn.reset_stream(event.stream_id, int(cls.current_error_code)) + wfile.write(h2_conn.data_to_send()) + wfile.flush() + return True + + def test_all_stream_reset_error_codes(self): + for error_name, error_code in h2.errors.ErrorCodes.__members__.items(): + self.__class__.current_error_name = error_name + self.__class__.current_error_code = error_code + try: + self.run_test_for_stream_reset() + except: + print('Exception occurred during test for error code {} ({})'.format( + error_name, error_code + )) + raise + + def run_test_for_stream_reset(self): + h2_conn = self.setup_connection() + + self._send_request( + self.client.wfile, + h2_conn, + headers=[ + (':authority', "127.0.0.1:{}".format(self.server.server.address[1])), + (':method', 'GET'), + (':scheme', 'https'), + (':path', '/'), + ], + ) + + self.client.rfile.o.settimeout(1) + + done = False + while not done: + try: + raw = b''.join(http2.read_raw_frame(self.client.rfile)) + events = h2_conn.receive_data(raw) + except exceptions.HttpException: + print(traceback.format_exc()) + assert False + + self.client.wfile.write(h2_conn.data_to_send()) + self.client.wfile.flush() + + for event in events: + if isinstance(event, h2.events.StreamReset): + assert event.error_code == int(self.current_error_code) + done = True + + h2_conn.close_connection() + self.client.wfile.write(h2_conn.data_to_send()) + self.client.wfile.flush() + + class TestBodySizeLimit(_Http2Test): @classmethod diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index a432f9e3..7158935a 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -512,9 +512,15 @@ class TAttr: raise IOError +class TAttr2: + def __getattr__(self, item): + return TAttr2() + + class TCmds(TAttr): def __init__(self): self.TAttr = TAttr() + self.TAttr2 = TAttr2() @command.command("empty") def empty(self) -> None: @@ -524,7 +530,8 @@ class TCmds(TAttr): @pytest.mark.asyncio async def test_collect_commands(): """ - This tests for the error thrown by hasattr() + This tests for errors thrown by getattr() or __getattr__ implementations + that return an object for .command_name. """ with taddons.context() as tctx: c = command.CommandManager(tctx.master) diff --git a/test/mitmproxy/test_connections.py b/test/mitmproxy/test_connections.py index 7c371c1e..ae296631 100644 --- a/test/mitmproxy/test_connections.py +++ b/test/mitmproxy/test_connections.py @@ -199,6 +199,9 @@ class TestClientConnectionTLS: s = socket.create_connection(address) s = ctx.wrap_socket(s, server_hostname=sni) s.send(b'foobar') + # we need to wait for the test to finish successfully before calling .close() on Windows. + # The workaround here is to signal completion by sending data the other way around. + s.recv(3) s.close() threading.Thread(target=client_run).start() @@ -216,6 +219,7 @@ class TestClientConnectionTLS: assert c.sni == sni assert c.tls_established assert c.rfile.read(6) == b'foobar' + c.wfile.send(b"foo") c.finish() sock.close() diff --git a/test/mitmproxy/tools/console/test_keymap.py b/test/mitmproxy/tools/console/test_keymap.py index 0d6f9e88..f2c97ded 100644 --- a/test/mitmproxy/tools/console/test_keymap.py +++ b/test/mitmproxy/tools/console/test_keymap.py @@ -117,6 +117,21 @@ def test_load_path(tmpdir): kmc.load_path(km, dst) assert(km.get("chooser", "key1")) + with open(dst, 'w') as f: + f.write( + """ + - key: key2 + ctx: [flowlist] + cmd: foo + - key: key2 + ctx: [flowview] + cmd: bar + """ + ) + kmc.load_path(km, dst) + assert(km.get("flowlist", "key2")) + assert(km.get("flowview", "key2")) + km.add("key123", "str", ["flowlist", "flowview"]) with open(dst, 'w') as f: f.write( @@ -127,10 +142,9 @@ def test_load_path(tmpdir): """ ) kmc.load_path(km, dst) - for b in km.bindings: - if b.key == "key123": - assert b.contexts == ["options"] - break + assert(km.get("flowlist", "key123")) + assert(km.get("flowview", "key123")) + assert(km.get("options", "key123")) def test_parse(): @@ -52,7 +52,7 @@ passenv = CI_* GITHUB_* AWS_* TWINE_* DOCKER_* deps = -rrequirements.txt pyinstaller==3.5 - twine==2.0.0 + twine==3.1.1 awscli commands = mitmdump --version diff --git a/web/README.md b/web/README.md index c43d09f0..ae558bd6 100644 --- a/web/README.md +++ b/web/README.md @@ -1,6 +1,8 @@ # Quick Start +**Be sure to follow the Development Setup instructions found in the README.md, +and activate your virtualenv environment before proceeding.** - Run `yarn` to install dependencies -- Run `gulp` to start live-compilation. +- Run `yarn run gulp` to start live-compilation. - Run `mitmweb` and open http://localhost:8081/ diff --git a/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap b/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap index 83d9355c..106f1732 100644 --- a/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap +++ b/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap @@ -76,7 +76,7 @@ exports[`OptionMenu Component should render correctly 1`] = ` onChange={[Function]} type="checkbox" /> - Verify server certificates + Don't verify server certificates </label> </div> </div> diff --git a/web/src/js/components/Header/OptionMenu.jsx b/web/src/js/components/Header/OptionMenu.jsx index 765129ed..4eb319ec 100644 --- a/web/src/js/components/Header/OptionMenu.jsx +++ b/web/src/js/components/Header/OptionMenu.jsx @@ -31,7 +31,7 @@ function OptionMenu({ openOptions }) { Use host header for display </SettingsToggle> <SettingsToggle setting="ssl_insecure"> - Verify server certificates + Don't verify server certificates </SettingsToggle> </div> <div className="menu-legend">Quick Options</div> |