diff --git a/.github/workflows/minikube.yaml b/.github/workflows/minikube.yaml index 5713a83a0..5a19b8b5c 100644 --- a/.github/workflows/minikube.yaml +++ b/.github/workflows/minikube.yaml @@ -76,7 +76,6 @@ jobs: export JVM_BUILD_SERVICE_IMAGE=quay.io/$JBS_QUAY_ORG/$JBS_QUAY_IMAGE_CONTROLLER:$JBS_QUAY_IMAGE_TAG export JVM_BUILD_SERVICE_CACHE_IMAGE=quay.io/$JBS_QUAY_ORG/konflux-jbs-pnc-tenant/jvm-build-service/cache:$JBS_QUAY_IMAGE_TAG export JVM_BUILD_SERVICE_REQPROCESSOR_IMAGE=quay.io/$JBS_QUAY_ORG/konflux-jbs-pnc-tenant/jvm-build-service/build-request-processor:$JBS_QUAY_IMAGE_TAG - export JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE=quay.io/$JBS_QUAY_ORG/konflux-jbs-pnc-tenant/jvm-build-service/domain-proxy:$JBS_QUAY_IMAGE_TAG echo "Using worker namespace $JBS_WORKER_NAMESPACE DEV_IP $DEV_IP JVM_BUILD_SERVICE_IMAGE $JVM_BUILD_SERVICE_IMAGE" @@ -140,7 +139,6 @@ jobs: export JVM_BUILD_SERVICE_IMAGE=quay.io/$JBS_QUAY_ORG/$JBS_QUAY_IMAGE_CONTROLLER:$JBS_QUAY_IMAGE_TAG export JVM_BUILD_SERVICE_CACHE_IMAGE=quay.io/$JBS_QUAY_ORG/konflux-jbs-pnc-tenant/jvm-build-service/cache:$JBS_QUAY_IMAGE_TAG export JVM_BUILD_SERVICE_REQPROCESSOR_IMAGE=quay.io/$JBS_QUAY_ORG/konflux-jbs-pnc-tenant/jvm-build-service/build-request-processor:$JBS_QUAY_IMAGE_TAG - export JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE=quay.io/$JBS_QUAY_ORG/konflux-jbs-pnc-tenant/jvm-build-service/domain-proxy:$JBS_QUAY_IMAGE_TAG echo "Using worker namespace $JBS_WORKER_NAMESPACE DEV_IP $DEV_IP JVM_BUILD_SERVICE_IMAGE $JVM_BUILD_SERVICE_IMAGE" diff --git a/.gitignore b/.gitignore index 64dd4c603..3a3df3156 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,3 @@ deploy/**/ci-final/** # Ignore Gradle build output directory **/gradle/build/ - -# Ignore default domain proxy output directory -output/ diff --git a/.tekton/domain-proxy-pull-request.yaml b/.tekton/domain-proxy-pull-request.yaml deleted file mode 100644 index 0e6042fdd..000000000 --- a/.tekton/domain-proxy-pull-request.yaml +++ /dev/null @@ -1,454 +0,0 @@ -apiVersion: tekton.dev/v1 -kind: PipelineRun -metadata: - annotations: - build.appstudio.openshift.io/repo: https://github.com/redhat-appstudio/jvm-build-service?rev={{revision}} - build.appstudio.redhat.com/commit_sha: '{{revision}}' - build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' - build.appstudio.redhat.com/target_branch: '{{target_branch}}' - pipelinesascode.tekton.dev/max-keep-runs: "3" - pipelinesascode.tekton.dev/on-cel-expression: event == "pull_request" && target_branch - == "main" - creationTimestamp: null - labels: - appstudio.openshift.io/application: jvm-build-service - appstudio.openshift.io/component: domain-proxy - pipelines.appstudio.openshift.io/type: build - name: domain-proxy-on-pull-request - namespace: konflux-jbs-pnc-tenant -spec: - params: - - name: git-url - value: '{{source_url}}' - - name: revision - value: '{{revision}}' - - name: output-image - value: quay.io/redhat-user-workloads/konflux-jbs-pnc-tenant/jvm-build-service/domain-proxy:on-pr-{{revision}} - - name: image-expires-after - value: 5d - - name: dockerfile - value: /cmd/domainproxy/docker/Dockerfile.all-in-one - - name: path-context - value: . - pipelineSpec: - finally: - - name: show-sbom - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - taskRef: - params: - - name: name - value: show-sbom - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:945a7c9066d3e0a95d3fddb7e8a6992e4d632a2a75d8f3a9bd2ff2fef0ec9aa0 - - name: kind - value: task - resolver: bundles - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository.results.url)?rev=$(tasks.clone-repository.results.commit) - - name: image-url - value: $(params.output-image) - - name: build-task-status - value: $(tasks.build-container.status) - taskRef: - params: - - name: name - value: summary - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-summary:0.2@sha256:870d9a04d9784840a90b7bf6817cd0d0c4edfcda04b1ba1868cae625a3c3bfcc - - name: kind - value: task - resolver: bundles - workspaces: - - name: workspace - workspace: workspace - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: Path to the source code of an application's component from where - to build image. - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile inside the context specified by parameter - path-context - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Image tag expiration time, time values could be something like - 1h, 2d, 3w for hours, days, and weeks, respectively. - name: image-expires-after - - default: "false" - description: Build a source image. - name: build-source-image - type: string - - default: [] - description: Array of --build-arg values ("arg=value" strings) for buildah - name: build-args - type: array - - default: "" - description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file - name: build-args-file - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository.results.commit) - - description: "" - name: JAVA_COMMUNITY_DEPENDENCIES - value: $(tasks.build-container.results.JAVA_COMMUNITY_DEPENDENCIES) - tasks: - - name: init - params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - taskRef: - params: - - name: name - value: init - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:0523b51c28375a3f222da91690e22eff11888ebc98a0c73c468af44762265c69 - - name: kind - value: task - resolver: bundles - - name: clone-repository - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - params: - - name: name - value: git-clone - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone:0.1@sha256:d091a9e19567a4cbdc5acd57903c71ba71dc51d749a4ba7477e689608851e981 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository - taskRef: - params: - - name: name - value: prefetch-dependencies - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies:0.1@sha256:47d8d3320b4e29360108f18235598dd247bc316a4792063d970bffb00e61b71a - - name: kind - value: task - resolver: bundles - when: - - input: $(params.prefetch-input) - operator: notin - values: - - "" - workspaces: - - name: source - workspace: workspace - - name: git-basic-auth - workspace: git-auth - - name: netrc - workspace: netrc - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - - name: IMAGE_EXPIRES_AFTER - value: $(params.image-expires-after) - - name: COMMIT_SHA - value: $(tasks.clone-repository.results.commit) - - name: BUILD_ARGS - value: - - $(params.build-args[*]) - - name: BUILD_ARGS_FILE - value: $(params.build-args-file) - runAfter: - - prefetch-dependencies - taskRef: - params: - - name: name - value: buildah - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah:0.2@sha256:7779f9e48eda44aebae3597747f5d8c1cc3fbc3a98c2251ee20929d868b575f1 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: build-source-image - params: - - name: BINARY_IMAGE - value: $(params.output-image) - runAfter: - - build-container - taskRef: - params: - - name: name - value: source-build - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build:0.1@sha256:ddfa1fb418c1d9d55d7d70d39fe8f35ce05e96073bcd057bb6aaacd1f839cc51 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - - input: $(params.build-source-image) - operator: in - values: - - "true" - workspaces: - - name: workspace - workspace: workspace - - name: deprecated-base-image-check - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - runAfter: - - build-container - taskRef: - params: - - name: name - value: deprecated-image-check - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:5a1a165fa02270f0a947d8a2131ee9d8be0b8e9d34123828c2bef589e504ee84 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: clair-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: clair-scan - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:0a5421111e7092740398691d5bd7c125cc0896f29531d19414bb5724ae41692a - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: ecosystem-cert-preflight-checks - params: - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: ecosystem-cert-preflight-checks - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:df8a25a3431a70544172ed4844f9d0c6229d39130633960729f825a031a7dea9 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sast-snyk-check - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: sast-snyk-check - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check:0.3@sha256:9fa8acbd4331e5f7c7ba39c6283a219b084e8b2332996e0988a7907a4a75feb4 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: clamav-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: clamav-scan - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.1@sha256:b4f450f1447b166da671f1d5819ab5a1485083e5c27ab91f7d8b7a2ff994c8c2 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: apply-tags - params: - - name: IMAGE - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:87fd7fc0e937aad1a8db9b6e377d7e444f53394dafde512d68adbea6966a4702 - - name: kind - value: task - resolver: bundles - - name: push-dockerfile - params: - - name: IMAGE - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - runAfter: - - build-container - taskRef: - params: - - name: name - value: push-dockerfile - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile:0.1@sha256:48bb2ee92ea528b28c0814c9cc126021e499a081b69431987a774561e9ac8047 - - name: kind - value: task - resolver: bundles - workspaces: - - name: workspace - workspace: workspace - workspaces: - - name: workspace - - name: git-auth - optional: true - - name: netrc - optional: true - taskRunTemplate: {} - workspaces: - - name: workspace - volumeClaimTemplate: - metadata: - creationTimestamp: null - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - status: {} - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' -status: {} diff --git a/.tekton/domain-proxy-push.yaml b/.tekton/domain-proxy-push.yaml deleted file mode 100644 index b49a28960..000000000 --- a/.tekton/domain-proxy-push.yaml +++ /dev/null @@ -1,453 +0,0 @@ -apiVersion: tekton.dev/v1 -kind: PipelineRun -metadata: - annotations: - build.appstudio.openshift.io/repo: https://github.com/redhat-appstudio/jvm-build-service?rev={{revision}} - build.appstudio.redhat.com/commit_sha: '{{revision}}' - build.appstudio.redhat.com/target_branch: '{{target_branch}}' - pipelinesascode.tekton.dev/max-keep-runs: "3" - pipelinesascode.tekton.dev/on-cel-expression: event == "push" && target_branch - == "main" - creationTimestamp: null - labels: - appstudio.openshift.io/application: jvm-build-service - appstudio.openshift.io/component: domain-proxy - pipelines.appstudio.openshift.io/type: build - name: domain-proxy-on-push - namespace: konflux-jbs-pnc-tenant -spec: - params: - - name: git-url - value: '{{source_url}}' - - name: revision - value: '{{revision}}' - - name: output-image - value: quay.io/redhat-user-workloads/konflux-jbs-pnc-tenant/jvm-build-service/domain-proxy:{{revision}} - - name: dockerfile - value: /cmd/domainproxy/docker/Dockerfile.all-in-one - - name: path-context - value: . - pipelineSpec: - finally: - - name: show-sbom - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - taskRef: - params: - - name: name - value: show-sbom - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-show-sbom:0.1@sha256:9bfc6b99ef038800fe131d7b45ff3cd4da3a415dd536f7c657b3527b01c4a13b - - name: kind - value: task - resolver: bundles - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository.results.url)?rev=$(tasks.clone-repository.results.commit) - - name: image-url - value: $(params.output-image) - - name: build-task-status - value: $(tasks.build-container.status) - taskRef: - params: - - name: name - value: summary - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-summary:0.2@sha256:870d9a04d9784840a90b7bf6817cd0d0c4edfcda04b1ba1868cae625a3c3bfcc - - name: kind - value: task - resolver: bundles - workspaces: - - name: workspace - workspace: workspace - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: Path to the source code of an application's component from where - to build image. - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile inside the context specified by parameter - path-context - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Image tag expiration time, time values could be something like - 1h, 2d, 3w for hours, days, and weeks, respectively. - name: image-expires-after - - default: "false" - description: Build a source image. - name: build-source-image - type: string - - default: [] - description: Array of --build-arg values ("arg=value" strings) for buildah - name: build-args - type: array - - default: "" - description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file - name: build-args-file - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository.results.commit) - - description: "" - name: JAVA_COMMUNITY_DEPENDENCIES - value: $(tasks.build-container.results.JAVA_COMMUNITY_DEPENDENCIES) - tasks: - - name: init - params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - taskRef: - params: - - name: name - value: init - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-init:0.2@sha256:0523b51c28375a3f222da91690e22eff11888ebc98a0c73c468af44762265c69 - - name: kind - value: task - resolver: bundles - - name: clone-repository - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - params: - - name: name - value: git-clone - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone:0.1@sha256:d091a9e19567a4cbdc5acd57903c71ba71dc51d749a4ba7477e689608851e981 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository - taskRef: - params: - - name: name - value: prefetch-dependencies - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies:0.1@sha256:47d8d3320b4e29360108f18235598dd247bc316a4792063d970bffb00e61b71a - - name: kind - value: task - resolver: bundles - when: - - input: $(params.prefetch-input) - operator: notin - values: - - "" - workspaces: - - name: source - workspace: workspace - - name: git-basic-auth - workspace: git-auth - - name: netrc - workspace: netrc - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - - name: IMAGE_EXPIRES_AFTER - value: $(params.image-expires-after) - - name: COMMIT_SHA - value: $(tasks.clone-repository.results.commit) - - name: BUILD_ARGS - value: - - $(params.build-args[*]) - - name: BUILD_ARGS_FILE - value: $(params.build-args-file) - runAfter: - - prefetch-dependencies - taskRef: - params: - - name: name - value: buildah - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-buildah:0.2@sha256:7779f9e48eda44aebae3597747f5d8c1cc3fbc3a98c2251ee20929d868b575f1 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: build-source-image - params: - - name: BINARY_IMAGE - value: $(params.output-image) - runAfter: - - build-container - taskRef: - params: - - name: name - value: source-build - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build:0.1@sha256:ddfa1fb418c1d9d55d7d70d39fe8f35ce05e96073bcd057bb6aaacd1f839cc51 - - name: kind - value: task - resolver: bundles - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - - input: $(params.build-source-image) - operator: in - values: - - "true" - workspaces: - - name: workspace - workspace: workspace - - name: deprecated-base-image-check - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - runAfter: - - build-container - taskRef: - params: - - name: name - value: deprecated-image-check - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.4@sha256:5a1a165fa02270f0a947d8a2131ee9d8be0b8e9d34123828c2bef589e504ee84 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: clair-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: clair-scan - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.2@sha256:0a5421111e7092740398691d5bd7c125cc0896f29531d19414bb5724ae41692a - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: ecosystem-cert-preflight-checks - params: - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: ecosystem-cert-preflight-checks - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.1@sha256:df8a25a3431a70544172ed4844f9d0c6229d39130633960729f825a031a7dea9 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sast-snyk-check - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: sast-snyk-check - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check:0.3@sha256:9fa8acbd4331e5f7c7ba39c6283a219b084e8b2332996e0988a7907a4a75feb4 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: clamav-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - runAfter: - - build-container - taskRef: - params: - - name: name - value: clamav-scan - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.1@sha256:b4f450f1447b166da671f1d5819ab5a1485083e5c27ab91f7d8b7a2ff994c8c2 - - name: kind - value: task - resolver: bundles - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: apply-tags - params: - - name: IMAGE - value: $(tasks.build-container.results.IMAGE_URL) - - name: ADDITIONAL_TAGS - value: ["latest"] - runAfter: - - build-container - taskRef: - params: - - name: name - value: apply-tags - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.1@sha256:87fd7fc0e937aad1a8db9b6e377d7e444f53394dafde512d68adbea6966a4702 - - name: kind - value: task - resolver: bundles - - name: push-dockerfile - params: - - name: IMAGE - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - runAfter: - - build-container - taskRef: - params: - - name: name - value: push-dockerfile - - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile:0.1@sha256:48bb2ee92ea528b28c0814c9cc126021e499a081b69431987a774561e9ac8047 - - name: kind - value: task - resolver: bundles - workspaces: - - name: workspace - workspace: workspace - workspaces: - - name: workspace - - name: git-auth - optional: true - - name: netrc - optional: true - taskRunTemplate: {} - workspaces: - - name: workspace - volumeClaimTemplate: - metadata: - creationTimestamp: null - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - status: {} - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' -status: {} diff --git a/Makefile b/Makefile index 40bd5a19e..370b6877d 100644 --- a/Makefile +++ b/Makefile @@ -44,8 +44,6 @@ minikube-test: build: go build -o out/jvmbuildservice cmd/controller/main.go env GOOS=linux GOARCH=amd64 GOTOOLCHAIN=auto GOSUMDB=sum.golang.org go build -mod=vendor -o out/jvmbuildservice ./cmd/controller - go build -o out/domainproxyserver cmd/domainproxy/server/main.go - go build -o out/domainproxyclient cmd/domainproxy/client/main.go clean: rm -rf out @@ -62,15 +60,13 @@ generate: generate-crds verify-generate-deepcopy-client: generate-deepcopy-client hack/verify-codegen.sh -dev-image: build +dev-image: @if [ -z "$$QUAY_USERNAME" ]; then \ echo "ERROR: QUAY_USERNAME is not set"; \ exit 1; \ fi docker build . -t quay.io/$(QUAY_USERNAME)/hacbs-jvm-controller:"$${JBS_QUAY_IMAGE_TAG:-dev}" docker push quay.io/$(QUAY_USERNAME)/hacbs-jvm-controller:"$${JBS_QUAY_IMAGE_TAG:-dev}" - docker build . -f cmd/domainproxy/docker/Dockerfile.local -t quay.io/$(QUAY_USERNAME)/hacbs-jvm-domain-proxy:"$${JBS_QUAY_IMAGE_TAG:-dev}" - docker push quay.io/$(QUAY_USERNAME)/hacbs-jvm-domain-proxy:"$${JBS_QUAY_IMAGE_TAG:-dev}" dev: dev-image cd java-components && mvn clean install -Dlocal -DskipTests -Ddev diff --git a/cmd/domainproxy/client/main.go b/cmd/domainproxy/client/main.go deleted file mode 100644 index 17ef0e3ac..000000000 --- a/cmd/domainproxy/client/main.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/client" - "os" - "os/signal" - "syscall" -) - -func main() { - domainProxyClient := NewDomainProxyClient() - ready := make(chan bool) - domainProxyClient.Start(ready) - <-ready - signals := make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) - <-signals - domainProxyClient.Stop() -} diff --git a/cmd/domainproxy/docker/Dockerfile.all-in-one b/cmd/domainproxy/docker/Dockerfile.all-in-one deleted file mode 100644 index 604d90b2f..000000000 --- a/cmd/domainproxy/docker/Dockerfile.all-in-one +++ /dev/null @@ -1,14 +0,0 @@ -FROM registry.access.redhat.com/ubi9/go-toolset:1.22.5-1731639025@sha256:45170b6e45114849b5d2c0e55d730ffa4a709ddf5f58b9e810548097b085e78f as builder -USER 0 -WORKDIR /work -COPY ./ . - -RUN go build -o domainproxyserver cmd/domainproxy/server/main.go -RUN go build -o domainproxyclient cmd/domainproxy/client/main.go - -FROM quay.io/konflux-ci/buildah-task:latest@sha256:5cbd487022fb7ac476cbfdea25513b810f7e343ec48f89dc6a4e8c3c39fa37a2 -USER 0 -WORKDIR /work/ - -COPY --from=builder /work/domainproxyserver /app/domain-proxy-server -COPY --from=builder /work/domainproxyclient /app/domain-proxy-client diff --git a/cmd/domainproxy/docker/Dockerfile.local b/cmd/domainproxy/docker/Dockerfile.local deleted file mode 100644 index 09ba5af38..000000000 --- a/cmd/domainproxy/docker/Dockerfile.local +++ /dev/null @@ -1,5 +0,0 @@ -FROM quay.io/konflux-ci/buildah-task:latest@sha256:5cbd487022fb7ac476cbfdea25513b810f7e343ec48f89dc6a4e8c3c39fa37a2 -USER 0 -COPY out/domainproxyserver /app/domain-proxy-server -COPY out/domainproxyclient /app/domain-proxy-client - diff --git a/cmd/domainproxy/server/main.go b/cmd/domainproxy/server/main.go deleted file mode 100644 index 2656411b3..000000000 --- a/cmd/domainproxy/server/main.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/server" - "os" - "os/signal" - "syscall" -) - -func main() { - domainProxyServer := NewDomainProxyServer() - ready := make(chan bool) - domainProxyServer.Start(ready) - <-ready - signals := make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) - <-signals - domainProxyServer.Stop() -} diff --git a/deploy/openshift-ci.sh b/deploy/openshift-ci.sh index 5390692b7..b06f1af65 100755 --- a/deploy/openshift-ci.sh +++ b/deploy/openshift-ci.sh @@ -11,8 +11,6 @@ echo "jvm build service jvm cache image:" echo ${JVM_BUILD_SERVICE_CACHE_IMAGE} echo "jvm build service jvm reqprocessor image:" echo ${JVM_BUILD_SERVICE_REQPROCESSOR_IMAGE} -echo "jvm build service jvm domain proxy image:" -echo ${JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE} function waitFor() { endTime=$(( $(date +%s) + 600 )) @@ -52,4 +50,3 @@ oc set env deployment/hacbs-jvm-operator -n jvm-build-service \ JVM_BUILD_SERVICE_IMAGE=${JVM_BUILD_SERVICE_IMAGE} \ JVM_BUILD_SERVICE_CACHE_IMAGE=${JVM_BUILD_SERVICE_CACHE_IMAGE} \ JVM_BUILD_SERVICE_REQPROCESSOR_IMAGE=${JVM_BUILD_SERVICE_REQPROCESSOR_IMAGE} -JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE=${JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE} diff --git a/docs/development.adoc b/docs/development.adoc index 317085a87..d2df5c0ae 100644 --- a/docs/development.adoc +++ b/docs/development.adoc @@ -153,7 +153,6 @@ export QUAY_USERNAME= export JVM_BUILD_SERVICE_IMAGE= export JVM_BUILD_SERVICE_CACHE_IMAGE= export JVM_BUILD_SERVICE_REQPROCESSOR_IMAGE= -export JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE= ./deploy/openshift-ci.sh make openshift-e2e ---- diff --git a/go.mod b/go.mod index 1b64c7223..b5f0a78ef 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,7 @@ require ( sigs.k8s.io/yaml v1.4.0 ) -require ( - github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f - github.com/swist/go-k8s-portforward v0.2.1 -) +require github.com/swist/go-k8s-portforward v0.2.1 require ( contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect @@ -45,7 +42,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/creack/pty v1.1.21 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/elazarl/goproxy/ext v0.0.0-20240909085733-6741dbfc16a1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect diff --git a/go.sum b/go.sum index 7eb057cdd..3048111c9 100644 --- a/go.sum +++ b/go.sum @@ -95,10 +95,6 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs= -github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy/ext v0.0.0-20240909085733-6741dbfc16a1 h1:XgXwWTQglBILwCpfm8I9xUjPXKOi1EzRzuYzyczU5Z0= -github.com/elazarl/goproxy/ext v0.0.0-20240909085733-6741dbfc16a1/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= @@ -395,7 +391,6 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= diff --git a/pkg/domainproxy/client/client.go b/pkg/domainproxy/client/client.go deleted file mode 100644 index 2e4ae1fde..000000000 --- a/pkg/domainproxy/client/client.go +++ /dev/null @@ -1,110 +0,0 @@ -package client - -import ( - "fmt" - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/common" - "net" - "time" -) - -const ( - Localhost = "localhost" - HttpPortKey = "DOMAIN_PROXY_HTTP_PORT" - DefaultHttpPort = 8080 - HttpToDomainSocket = "HTTP <-> Domain Socket" -) - -var logger = NewLogger("Domain Proxy Client") -var common = NewCommon(logger) - -type DomainProxyClient struct { - sharedParams *SharedParams - httpPort int -} - -func NewDomainProxyClient() *DomainProxyClient { - return &DomainProxyClient{ - sharedParams: common.NewSharedParams(), - httpPort: getHttpPort(), - } -} - -func (dpc *DomainProxyClient) Start(ready chan<- bool) { - sharedParams := dpc.sharedParams - logger.Println("Starting domain proxy client...") - var err error - sharedParams.Listener, err = net.Listen(TCP, fmt.Sprintf("%s:%d", Localhost, dpc.httpPort)) - if err != nil { - logger.Fatalf("Failed to start HTTP server: %v", err) - } - go dpc.startClient(ready) -} - -func (dpc *DomainProxyClient) startClient(ready chan<- bool) { - sharedParams := dpc.sharedParams - logger.Printf("HTTP server listening on port %d", dpc.httpPort) - ready <- true - for { - select { - case <-sharedParams.RunningContext.Done(): - return - default: - if serverConnection, err := sharedParams.Listener.Accept(); err != nil { - select { - case <-sharedParams.RunningContext.Done(): - return - default: - logger.Printf("Failed to accept server connection: %v", err) - } - } else { - go dpc.handleConnectionRequest(serverConnection) - } - } - } -} - -func (dpc *DomainProxyClient) handleConnectionRequest(serverConnection net.Conn) { - sharedParams := dpc.sharedParams - if err := serverConnection.SetDeadline(time.Now().Add(sharedParams.IdleTimeout)); err != nil { - common.HandleSetDeadlineError(serverConnection, err) - return - } - connectionNo := sharedParams.HttpConnectionCounter.Add(1) - logger.Printf("Handling %s Connection %d", HttpToDomainSocket, connectionNo) - startTime := time.Now() - domainConnection, err := net.DialTimeout(UNIX, sharedParams.DomainSocket, sharedParams.ConnectionTimeout) - if err != nil { - logger.Printf("Failed to connect to domain socket: %v", err) - if err = serverConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - if err := domainConnection.SetDeadline(time.Now().Add(sharedParams.IdleTimeout)); err != nil { - common.HandleSetDeadlineError(domainConnection, err) - if err = serverConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - // Initiate transfer between server and domain - go func() { - common.BiDirectionalTransfer(sharedParams.RunningContext, serverConnection, domainConnection, sharedParams.ByteBufferSize, HttpToDomainSocket, connectionNo) - logger.Printf("%s Connection %d ended after %d ms", HttpToDomainSocket, connectionNo, time.Since(startTime).Milliseconds()) - }() -} - -func (dpc *DomainProxyClient) Stop() { - sharedParams := dpc.sharedParams - logger.Println("Shutting down domain proxy client...") - sharedParams.InitiateShutdown() - if sharedParams.Listener != nil { - if err := sharedParams.Listener.Close(); err != nil { - common.HandleListenerCloseError(err) - } - } -} - -func getHttpPort() int { - return common.GetIntEnvVariable(HttpPortKey, DefaultHttpPort) -} diff --git a/pkg/domainproxy/common/common.go b/pkg/domainproxy/common/common.go deleted file mode 100644 index 8f6a38024..000000000 --- a/pkg/domainproxy/common/common.go +++ /dev/null @@ -1,215 +0,0 @@ -package common - -import ( - "context" - "errors" - "io" - "log" - "net" - "os" - "strconv" - "strings" - "sync/atomic" - "time" -) - -const ( - ByteBufferSizeKey = "DOMAIN_PROXY_BYTE_BUFFER_SIZE" - DefaultByteBufferSize = 32768 - DomainSocketKey = "DOMAIN_PROXY_DOMAIN_SOCKET" - DefaultDomainSocket = "/tmp/domain-socket.sock" - ConnectionTimeoutKey = "DOMAIN_PROXY_CONNECTION_TIMEOUT" - DefaultConnectionTimeout = 10000 * time.Millisecond - IdleTimeoutKey = "DOMAIN_PROXY_IDLE_TIMEOUT" - DefaultIdleTimeout = 30000 * time.Millisecond - TCP = "tcp" - UNIX = "unix" -) - -type Common struct { - logger *log.Logger -} - -type SharedParams struct { - ByteBufferSize int - DomainSocket string - ConnectionTimeout time.Duration - IdleTimeout time.Duration - HttpConnectionCounter atomic.Uint64 - Listener net.Listener - RunningContext context.Context - InitiateShutdown context.CancelFunc -} - -func NewCommon(logger *log.Logger) *Common { - return &Common{ - logger: logger, - } -} - -func NewLogger(appName string) *log.Logger { - return log.New(os.Stdout, appName+" ", log.LstdFlags|log.Lshortfile) -} - -func (c *Common) NewSharedParams() *SharedParams { - runningContext, initiateShutdown := context.WithCancel(context.Background()) - return &SharedParams{ - ByteBufferSize: c.getByteBufferSize(), - DomainSocket: c.getDomainSocket(), - ConnectionTimeout: c.getConnectionTimeout(), - IdleTimeout: c.getIdleTimeout(), - RunningContext: runningContext, - InitiateShutdown: initiateShutdown, - } -} - -func (c *Common) BiDirectionalTransfer(runningContext context.Context, leftConnection, rightConnection net.Conn, byteBufferSize int, connectionType string, connectionNo uint64) { - defer c.CloseConnection(leftConnection, rightConnection, connectionType, connectionNo) - transferContext, terminateTransfer := context.WithCancel(runningContext) - go c.Transfer(transferContext, terminateTransfer, leftConnection, rightConnection, byteBufferSize, connectionType, connectionNo) - go c.Transfer(transferContext, terminateTransfer, rightConnection, leftConnection, byteBufferSize, connectionType, connectionNo) - <-transferContext.Done() -} - -func (c *Common) Transfer(transferContext context.Context, terminateTransfer context.CancelFunc, sourceConnection, targetConnection net.Conn, bufferSize int, connectionType string, connectionNo uint64) { - defer terminateTransfer() - buf := make([]byte, bufferSize) - for { - select { - case <-transferContext.Done(): - return - default: - if n, err := io.CopyBuffer(sourceConnection, targetConnection, buf); err != nil { - c.handleConnectionError(err, connectionType, connectionNo) - return - } else if n > 0 { - c.logger.Printf("%d bytes transferred for %s connection %d", n, connectionType, connectionNo) - } else { - // Nothing more to transfer - return - } - } - } -} - -func (c *Common) HandleSetDeadlineError(connection net.Conn, err error) { - c.logger.Printf("Failed to set deadline: %v", err) - if err = connection.Close(); err != nil { - c.HandleConnectionCloseError(err) - } -} - -func (c *Common) HandleConnectionCloseError(err error) { - c.logger.Printf("Failed to close connection: %v", err) -} - -func (c *Common) HandleListenerCloseError(err error) { - c.logger.Printf("Failed to close listener: %v", err) -} - -func (c *Common) handleConnectionError(err error, connectionType string, connectionNo uint64) { - var netErr net.Error - if !errors.Is(err, net.ErrClosed) { // We don't care if connection has been closed, because this is expected - if errors.As(err, &netErr) && netErr.Timeout() { - c.logger.Printf("%s connection %d timed out", connectionType, connectionNo) - } else if err != io.EOF { - c.logger.Printf("Failed to transfer data using %s connection %d: %v", connectionType, connectionNo, err) - } - } -} - -func (c *Common) CloseConnection(leftConnection, rightConnection net.Conn, connectionType string, connectionNo uint64) { - if err := leftConnection.Close(); err != nil { - c.HandleConnectionCloseError(err) - } - if err := rightConnection.Close(); err != nil { - c.HandleConnectionCloseError(err) - } - c.logger.Printf("%s connection %d closed", connectionType, connectionNo) -} - -func (c *Common) GetEnvVariable(key, defaultValue string) string { - value := os.Getenv(key) - if value == "" { - c.logger.Printf("Environment variable %s is not set, using default value: %s", key, defaultValue) - return defaultValue - } - return value -} - -func (c *Common) GetIntEnvVariable(key string, defaultValue int) int { - valueStr := os.Getenv(key) - if valueStr == "" { - c.logger.Printf("Environment variable %s is not set, using default value: %d", key, defaultValue) - return defaultValue - } - value, err := strconv.Atoi(valueStr) - if err != nil { - c.logger.Printf("Invalid environment variable %s: %v, using default value: %d", key, err, defaultValue) - return defaultValue - } - return value -} - -func (c *Common) GetCsvEnvVariable(key, defaultValue string) map[string]bool { - valuesStr := os.Getenv(key) - if valuesStr == "" { - c.logger.Printf("Environment variable %s is not set, using default value: %s", key, defaultValue) - return c.parseCsvToMap(defaultValue) - } - return c.parseCsvToMap(valuesStr) -} - -func (c *Common) GetMillisecondsEnvVariable(key string, defaultValue time.Duration) time.Duration { - valueStr := os.Getenv(key) - if valueStr == "" { - c.logger.Printf("Environment variable %s is not set, using default value: %d", key, defaultValue.Milliseconds()) - return defaultValue - } - value, err := strconv.Atoi(valueStr) - if err != nil { - c.logger.Printf("Invalid environment variable %s: %v, using default value: %d", key, err, defaultValue.Milliseconds()) - return defaultValue - } - return time.Duration(value) * time.Millisecond -} - -func (c *Common) parseCsvToMap(csvString string) map[string]bool { - valuesStr := strings.Split(csvString, ",") - values := make(map[string]bool) - for _, value := range valuesStr { - trimmedValue := strings.TrimSpace(value) - values[trimmedValue] = true - } - return values -} - -func (c *Common) GetBoolEnvVariable(key string, defaultValue bool) bool { - valueStr := os.Getenv(key) - if valueStr == "" { - c.logger.Printf("Environment variable %s is not set, using default value: %t", key, defaultValue) - return defaultValue - } - value, err := strconv.ParseBool(valueStr) - if err != nil { - c.logger.Printf("Invalid environment variable %s: %v, using default value: %t", key, err, defaultValue) - return defaultValue - } - return value -} - -func (c *Common) getByteBufferSize() int { - return c.GetIntEnvVariable(ByteBufferSizeKey, DefaultByteBufferSize) -} - -func (c *Common) getDomainSocket() string { - return c.GetEnvVariable(DomainSocketKey, DefaultDomainSocket) -} - -func (c *Common) getConnectionTimeout() time.Duration { - return c.GetMillisecondsEnvVariable(ConnectionTimeoutKey, DefaultConnectionTimeout) -} - -func (c *Common) getIdleTimeout() time.Duration { - return c.GetMillisecondsEnvVariable(IdleTimeoutKey, DefaultIdleTimeout) -} diff --git a/pkg/domainproxy/integration/domainproxy_test.go b/pkg/domainproxy/integration/domainproxy_test.go deleted file mode 100644 index d98ab6ab5..000000000 --- a/pkg/domainproxy/integration/domainproxy_test.go +++ /dev/null @@ -1,392 +0,0 @@ -package integration - -import ( - "crypto/md5" - "crypto/tls" - "encoding/hex" - "errors" - "fmt" - "github.com/elazarl/goproxy" - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/client" - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/common" - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/server" - "io" - "math/rand" - "net/http" - "net/http/httptest" - "net/url" - "os" - "strconv" - "strings" - "testing" -) - -const ( - DomainProxyPort = "8081" - InternalProxyPort = "8082" - DomainProxyUrl = "http://" + Localhost + ":" + DomainProxyPort - ContentType = "text/xml" - Md5Hash = "ea3ca57f8f99d1d210d1b438c9841440" - ContentLength = "403" - MockUrlPath = "/com/foo/bar/1.0/bar-1.0.pom" - NonExistentUrlPath = "/com/foo/bar/1.0/bar-2.0.pom" - NonWhitelistedUrl = "repo1.maven.org/maven2/org/apache/maven/plugins/maven-jar-plugin/3.4.1/maven-jar-plugin-3.4.1.jar" - NonExistentHost = "foo.bar" - User = "foo" - Password = "bar" -) - -func createClient(t *testing.T) *http.Client { - proxyUrl, err := url.Parse(DomainProxyUrl) - if err != nil { - t.Fatal(err) - } - transport := &http.Transport{ - Proxy: http.ProxyURL(proxyUrl), - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - return &http.Client{ - Transport: transport, - } -} - -func getMd5Hash(bytes []byte) string { - hash := md5.Sum(bytes) - return hex.EncodeToString(hash[:]) -} - -func getRandomDomainSocket() string { - return "/tmp/domain-socket-" + strconv.Itoa(rand.Int()) + ".sock" -} - -func mockHandler(t *testing.T) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodGet && r.URL.Path == MockUrlPath { - // Mock GET response - pom, err := os.ReadFile("testdata/bar-1.0.pom") - if err != nil { - t.Fatal(err) - } - w.Header().Set("Content-Type", ContentType) - w.WriteHeader(http.StatusOK) - if _, err := w.Write(pom); err != nil { - t.Fatal(err) - } - } else if r.Method == http.MethodHead && r.URL.Path == MockUrlPath { - // Mock HEAD response - w.Header().Set("Content-Type", ContentType) - w.Header().Set("Content-Length", ContentLength) - w.WriteHeader(http.StatusOK) - } else { - http.NotFound(w, r) - } - } -} - -func startDomainProxy() (*DomainProxyServer, *DomainProxyClient) { - domainProxyServer := NewDomainProxyServer() - serverReady := make(chan bool) - go domainProxyServer.Start(serverReady) - <-serverReady - clientReady := make(chan bool) - domainProxyClient := NewDomainProxyClient() - go domainProxyClient.Start(clientReady) - <-clientReady - return domainProxyServer, domainProxyClient -} - -func stopDomainProxy(domainProxyServer *DomainProxyServer, domainProxyClient *DomainProxyClient) { - domainProxyServer.Stop() - domainProxyClient.Stop() -} - -func startMockServers(t *testing.T) (*httptest.Server, *httptest.Server) { - mockHandler := mockHandler(t) - mockHttpServer := httptest.NewServer(mockHandler) - mockHttpsServer := httptest.NewUnstartedServer(mockHandler) - mockHttpsServer.StartTLS() - return mockHttpServer, mockHttpsServer -} - -func stopMockServers(mockHttpServer *httptest.Server, mockHttpsServer *httptest.Server) { - mockHttpServer.Close() - mockHttpsServer.Close() -} - -func startInternalProxyServer(t *testing.T, onRequestFunction func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response), onConnectFunction func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string)) *http.Server { - internalProxy := goproxy.NewProxyHttpServer() - internalProxy.Verbose = true - if onRequestFunction != nil { - internalProxy.OnRequest().DoFunc(onRequestFunction) - internalProxy.OnRequest().HandleConnectFunc(onConnectFunction) - } - internalProxyServer := &http.Server{ - Addr: Localhost + ":" + InternalProxyPort, - Handler: internalProxy, - } - go func() { - if err := internalProxyServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { - t.Error(err) - } - }() - return internalProxyServer -} - -func stopInternalProxyServer(t *testing.T, internalProxyServer *http.Server) { - err := internalProxyServer.Close() - if err != nil { - t.Fatal(err) - } -} - -func commonTestBehaviour(t *testing.T, qualifier string) { - // Set env variables - t.Setenv(DomainSocketKey, getRandomDomainSocket()) - t.Setenv(HttpPortKey, DomainProxyPort) - t.Setenv(TargetWhitelistKey, "127.0.0.1,foo.bar") - // Start services - domainProxyServer, domainProxyClient := startDomainProxy() - defer stopDomainProxy(domainProxyServer, domainProxyClient) - // Start mock HTTP and HTTPS servers - mockHttpServer, mockHttpsServer := startMockServers(t) - defer stopMockServers(mockHttpServer, mockHttpsServer) - mockHttpUrl := mockHttpServer.URL - mockHttpsUrl := mockHttpsServer.URL - // Create HTTP client - httpClient := createClient(t) - - t.Run(fmt.Sprintf("Test HTTP GET dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Get(mockHttpUrl + MockUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusOK { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusOK) - } - pom, err := io.ReadAll(response.Body) - if err != nil { - t.Fatal(err) - } - hash := getMd5Hash(pom) - if hash != Md5Hash { - t.Fatalf("Actual MD5 hash %s did not match expected MD5 hash %s", hash, Md5Hash) - } - }) - - t.Run(fmt.Sprintf("Test HTTPS GET dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Get(mockHttpsUrl + MockUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusOK { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusOK) - } - pom, err := io.ReadAll(response.Body) - if err != nil { - t.Fatal(err) - } - hash := getMd5Hash(pom) - if hash != Md5Hash { - t.Fatalf("Actual MD5 hash %s did not match expected MD5 hash %s", hash, Md5Hash) - } - }) - - t.Run(fmt.Sprintf("Test HTTP GET non-existent dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Get(mockHttpUrl + NonExistentUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusNotFound { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusNotFound) - } - }) - - t.Run(fmt.Sprintf("Test HTTPS GET non-existent dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Get(mockHttpsUrl + NonExistentUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusNotFound { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusNotFound) - } - }) - - t.Run(fmt.Sprintf("Test HTTP non-whitelisted host%s", qualifier), func(t *testing.T) { - response, err := httpClient.Get("http://" + NonWhitelistedUrl) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusForbidden { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusForbidden) - } - }) - - t.Run(fmt.Sprintf("Test HTTPS non-whitelisted host%s", qualifier), func(t *testing.T) { - _, err := httpClient.Get("https://" + NonWhitelistedUrl) - statusText := http.StatusText(http.StatusForbidden) - if !strings.Contains(err.Error(), statusText) { - t.Fatalf("Actual error %s did not contain expected HTTP status text %s", err.Error(), statusText) - } - }) - - t.Run(fmt.Sprintf("Test HTTP non-existent host%s", qualifier), func(t *testing.T) { - response, err := httpClient.Get("http://" + NonExistentHost) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusInternalServerError { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusInternalServerError) - } - }) - - t.Run(fmt.Sprintf("Test HTTPS non-existent host%s", qualifier), func(t *testing.T) { - _, err := httpClient.Get("https://" + NonExistentHost) - internalServerStatusText := http.StatusText(http.StatusInternalServerError) - badGatewayStatusText := http.StatusText(http.StatusBadGateway) - if !strings.Contains(err.Error(), internalServerStatusText) && !strings.Contains(err.Error(), badGatewayStatusText) { // Internal proxy may return 502 Bad Gateway - t.Fatalf("Actual error %s did not contain expected HTTP status text %s or %s", err.Error(), internalServerStatusText, badGatewayStatusText) - } - }) - - t.Run(fmt.Sprintf("Test HTTP HEAD dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Head(mockHttpUrl + MockUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - actualContentLength := response.Header.Get("Content-Length") - if actualContentLength != ContentLength { - t.Fatalf("Actual content length %s did not match expected content length %s", actualContentLength, ContentLength) - } - }) - - t.Run(fmt.Sprintf("Test HTTPS HEAD dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Head(mockHttpsUrl + MockUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - actualContentLength := response.Header.Get("Content-Length") - if actualContentLength != ContentLength { - t.Fatalf("Actual content length %s did not match expected content length %s", actualContentLength, ContentLength) - } - }) - - t.Run(fmt.Sprintf("Test HTTP HEAD non-existent dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Head(mockHttpUrl + NonExistentUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusNotFound { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusNotFound) - } - }) - - t.Run(fmt.Sprintf("Test HTTPS HEAD non-existent dependency%s", qualifier), func(t *testing.T) { - response, err := httpClient.Head(mockHttpsUrl + NonExistentUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusNotFound { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusNotFound) - } - }) -} - -func commonInternalProxyTestBehaviour(t *testing.T, qualifier string, onRequestFunction func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response), onConnectFunction func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string)) { - // Start internal proxy - internalProxyServer := startInternalProxyServer(t, onRequestFunction, onConnectFunction) - // Set env variables - t.Setenv(EnableInternalProxyKey, "true") - t.Setenv(InternalProxyHostKey, Localhost) - t.Setenv(InternalProxyPortKey, InternalProxyPort) - t.Setenv(InternalNonProxyHostsKey, "example.com") - // Run tests with internal proxy - commonTestBehaviour(t, qualifier) - // Stop internal proxy - stopInternalProxyServer(t, internalProxyServer) - // Set non-proxy hosts env variable - t.Setenv(InternalNonProxyHostsKey, "127.0.0.1,foo.bar") - // Run tests without internal proxy - commonTestBehaviour(t, qualifier+" and non-proxy host") -} - -func TestDomainProxy(t *testing.T) { - commonTestBehaviour(t, "") -} - -func TestDomainProxyWithInternalProxy(t *testing.T) { - commonInternalProxyTestBehaviour(t, " with internal proxy", nil, nil) -} - -func TestDomainProxyWithInternalProxyAndAuthentication(t *testing.T) { - // Set env variables - t.Setenv(InternalProxyUserKey, User) - t.Setenv(InternalProxyPasswordKey, Password) - basicAuth := "Basic " + GetBasicAuth(User, Password) - // Create internal proxy HTTP authentication handler - onRequestFunction := func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { - if req.Header.Get("Proxy-Authorization") != basicAuth { - return nil, goproxy.NewResponse(req, goproxy.ContentTypeText, http.StatusProxyAuthRequired, http.StatusText(http.StatusProxyAuthRequired)) - } - return req, nil - } - // Create internal proxy HTTPS authentication handler - onConnectionFunction := func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) { - req := ctx.Req - authHeader := req.Header.Get("Proxy-Authorization") - if authHeader != basicAuth { - ctx.Resp = goproxy.NewResponse(req, goproxy.ContentTypeText, http.StatusProxyAuthRequired, http.StatusText(http.StatusProxyAuthRequired)) - return goproxy.RejectConnect, host - } - return goproxy.OkConnect, host - } - // Run tests with internal proxy and authentication - commonInternalProxyTestBehaviour(t, " with internal proxy and authentication", onRequestFunction, onConnectionFunction) - - // Set invalid authentication env variables - t.Setenv(DomainSocketKey, getRandomDomainSocket()) - t.Setenv(InternalProxyUserKey, "123") - t.Setenv(InternalProxyPasswordKey, "456") - t.Setenv(InternalNonProxyHostsKey, "example.com") - // Start internal proxy - internalProxyServer := startInternalProxyServer(t, onRequestFunction, onConnectionFunction) - defer stopInternalProxyServer(t, internalProxyServer) - // Start services - domainProxyServer, domainProxyClient := startDomainProxy() - defer stopDomainProxy(domainProxyServer, domainProxyClient) - // Start mock HTTP and HTTPS servers - mockHttpServer, mockHttpsServer := startMockServers(t) - defer stopMockServers(mockHttpServer, mockHttpsServer) - mockHttpUrl := mockHttpServer.URL - mockHttpsUrl := mockHttpsServer.URL - // Create HTTP client - httpClient := createClient(t) - - t.Run("Test HTTP GET dependency with internal proxy and invalid authentication", func(t *testing.T) { - response, err := httpClient.Get(mockHttpUrl + MockUrlPath) - if err != nil { - t.Fatal(err) - } - defer response.Body.Close() - if response.StatusCode != http.StatusProxyAuthRequired { - t.Fatalf("Actual HTTP status %d did not match expected HTTP status %d", response.StatusCode, http.StatusProxyAuthRequired) - } - }) - - t.Run("Test HTTPS GET dependency with internal proxy and invalid authentication", func(t *testing.T) { - _, err := httpClient.Get(mockHttpsUrl + MockUrlPath) - statusText := http.StatusText(http.StatusProxyAuthRequired) - if !strings.Contains(err.Error(), statusText) { - t.Fatalf("Actual error %s did not contain expected HTTP status text %s", err.Error(), statusText) - } - }) -} diff --git a/pkg/domainproxy/integration/testdata/bar-1.0.pom b/pkg/domainproxy/integration/testdata/bar-1.0.pom deleted file mode 100644 index 45f65a9c9..000000000 --- a/pkg/domainproxy/integration/testdata/bar-1.0.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - com.foo - bar - 1.0 - diff --git a/pkg/domainproxy/server/server.go b/pkg/domainproxy/server/server.go deleted file mode 100644 index fa0e12db2..000000000 --- a/pkg/domainproxy/server/server.go +++ /dev/null @@ -1,420 +0,0 @@ -package server - -import ( - "bufio" - "encoding/base64" - "fmt" - . "github.com/redhat-appstudio/jvm-build-service/pkg/domainproxy/common" - "net" - "net/http" - "os" - "strconv" - "strings" - "sync/atomic" - "time" -) - -const ( - HttpPort = 80 - HttpsPort = 443 - TargetWhitelistKey = "DOMAIN_PROXY_TARGET_WHITELIST" - DefaultTargetWhitelist = "localhost,repo.maven.apache.org,repository.jboss.org,packages.confluent.io,jitpack.io,repo.gradle.org,plugins.gradle.org" - EnableInternalProxyKey = "DOMAIN_PROXY_ENABLE_INTERNAL_PROXY" - DefaultEnableInternalProxy = false - InternalProxyHostKey = "DOMAIN_PROXY_INTERNAL_PROXY_HOST" - DefaultInternalProxyHost = "indy-generic-proxy" - InternalProxyPortKey = "DOMAIN_PROXY_INTERNAL_PROXY_PORT" - DefaultInternalProxyPort = 80 - InternalProxyUserKey = "DOMAIN_PROXY_INTERNAL_PROXY_USER" - DefaultInternalProxyUser = "" - InternalProxyPasswordKey = "DOMAIN_PROXY_INTERNAL_PROXY_PASSWORD" - DefaultInternalProxyPassword = "" - InternalNonProxyHostsKey = "DOMAIN_PROXY_INTERNAL_NON_PROXY_HOSTS" - DefaultInternalNonProxyHosts = "localhost" - DomainSocketToHttp = "Domain Socket <-> HTTP" - DomainSocketToHttps = "Domain Socket <-> HTTPS" -) - -var logger = NewLogger("Domain Proxy Server") -var common = NewCommon(logger) - -type DomainProxyServer struct { - sharedParams *SharedParams - targetWhitelist map[string]bool - enableInternalProxy bool - internalProxyHost string - internalProxyPort int - internalProxyUser string - internalProxyPassword string - internalNonProxyHosts map[string]bool - httpsConnectionCounter atomic.Uint64 -} - -func NewDomainProxyServer() *DomainProxyServer { - return &DomainProxyServer{ - sharedParams: common.NewSharedParams(), - targetWhitelist: getTargetWhitelist(), - enableInternalProxy: getEnableInternalProxy(), - internalProxyHost: getInternalProxyHost(), - internalProxyPort: getInternalProxyPort(), - internalProxyUser: getInternalProxyUser(), - internalProxyPassword: getInternalProxyPassword(), - internalNonProxyHosts: getInternalNonProxyHosts(), - } -} - -func (dps *DomainProxyServer) Start(ready chan<- bool) { - sharedParams := dps.sharedParams - logger.Println("Starting domain proxy server...") - if _, err := os.Stat(sharedParams.DomainSocket); err == nil { - if err := os.Remove(sharedParams.DomainSocket); err != nil { - logger.Fatalf("Failed to delete existing domain socket: %v", err) - } - } - var err error - sharedParams.Listener, err = net.Listen(UNIX, sharedParams.DomainSocket) - if err != nil { - logger.Fatalf("Failed to start domain socket listener: %v", err) - } - go dps.startServer(ready) -} - -func (dps *DomainProxyServer) startServer(ready chan<- bool) { - sharedParams := dps.sharedParams - logger.Printf("Domain socket server listening on %s", sharedParams.DomainSocket) - ready <- true - for { - select { - case <-sharedParams.RunningContext.Done(): - return - default: - if domainConnection, err := sharedParams.Listener.Accept(); err != nil { - select { - case <-sharedParams.RunningContext.Done(): - return - default: - logger.Printf("Failed to accept domain socket connection: %v", err) - } - } else { - go dps.handleConnectionRequest(domainConnection) - } - } - } -} - -func (dps *DomainProxyServer) handleConnectionRequest(domainConnection net.Conn) { - sharedParams := dps.sharedParams - if err := domainConnection.SetDeadline(time.Now().Add(sharedParams.IdleTimeout)); err != nil { - common.HandleSetDeadlineError(domainConnection, err) - return - } - reader := bufio.NewReader(domainConnection) - request, err := http.ReadRequest(reader) - if err != nil { - logger.Printf("Failed to read request: %v", err) - if err = domainConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - writer := &responseWriter{connection: domainConnection} - if request.Method == http.MethodConnect { - dps.handleHttpsConnection(domainConnection, writer, request) - } else { - dps.handleHttpConnection(domainConnection, writer, request) - } -} - -func (dps *DomainProxyServer) handleHttpConnection(sourceConnection net.Conn, writer http.ResponseWriter, request *http.Request) { - sharedParams := dps.sharedParams - connectionNo := sharedParams.HttpConnectionCounter.Add(1) - targetHost, targetPort := getTargetHostAndPort(request.Host, HttpPort) - actualTargetHost, actualTargetPort := targetHost, targetPort - targetConnectionName := "target" - useInternalProxy := dps.useInternalProxy(targetHost) - // Redirect connection to internal proxy if enabled - if useInternalProxy { - targetHost, targetPort = dps.internalProxyHost, dps.internalProxyPort - logger.Printf("Handling %s Connection %d with internal proxy %s:%d and target %s:%d", DomainSocketToHttp, connectionNo, targetHost, targetPort, actualTargetHost, actualTargetPort) - targetConnectionName = "internal proxy" - } else { - logger.Printf("Handling %s Connection %d with target %s:%d", DomainSocketToHttp, connectionNo, actualTargetHost, actualTargetPort) - } - // Check if target is whitelisted - if !dps.isTargetWhitelisted(actualTargetHost, writer) { - if err := sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - startTime := time.Now() - request.Header.Del("Proxy-Connection") // Prevent keep-alive as it breaks internal proxy authentication - request.Header.Set("Connection", "close") // Prevent keep-alive as it breaks internal proxy authentication - // Update request with target details for internal proxy if enabled - if useInternalProxy { - request.Header.Set("Host", fmt.Sprintf("%s:%d", actualTargetHost, actualTargetPort)) - // Add authentication details if configured - if dps.internalProxyUser != "" && dps.internalProxyPassword != "" { - request.Header.Set("Proxy-Authorization", "Basic "+GetBasicAuth(dps.internalProxyUser, dps.internalProxyPassword)) - } - } - // Try to connect to target or internal proxy - targetConnection, err := net.DialTimeout(TCP, fmt.Sprintf("%s:%d", targetHost, targetPort), sharedParams.ConnectionTimeout) - if err != nil { - dps.handleErrorResponse(writer, err, fmt.Sprintf("Failed to connect to %s", targetConnectionName)) - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - if err = targetConnection.SetDeadline(time.Now().Add(sharedParams.IdleTimeout)); err != nil { - common.HandleSetDeadlineError(targetConnection, err) - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - // Send HTTP request to internal proxy if enabled - if useInternalProxy { - err = request.WriteProxy(targetConnection) - } else { - err = request.Write(targetConnection) - } - if err != nil { - dps.handleErrorResponse(writer, err, fmt.Sprintf("Failed to send request to %s", targetConnectionName)) - if err = targetConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - // Initiate transfer between source and target or internal proxy - go func() { - common.BiDirectionalTransfer(sharedParams.RunningContext, sourceConnection, targetConnection, sharedParams.ByteBufferSize, DomainSocketToHttp, connectionNo) - logger.Printf("%s Connection %d ended after %d ms", DomainSocketToHttp, connectionNo, time.Since(startTime).Milliseconds()) - }() -} - -func (dps *DomainProxyServer) handleHttpsConnection(sourceConnection net.Conn, writer http.ResponseWriter, request *http.Request) { - sharedParams := dps.sharedParams - connectionNo := dps.httpsConnectionCounter.Add(1) - targetHost, targetPort := getTargetHostAndPort(request.Host, HttpsPort) - actualTargetHost, actualTargetPort := targetHost, targetPort - targetConnectionName := "target" - useInternalProxy := dps.useInternalProxy(targetHost) - // Redirect connection to internal proxy if enabled - if useInternalProxy { - targetHost, targetPort = dps.internalProxyHost, dps.internalProxyPort - logger.Printf("Handling %s Connection %d with internal proxy %s:%d and target %s:%d", DomainSocketToHttps, connectionNo, targetHost, targetPort, actualTargetHost, actualTargetPort) - targetConnectionName = "internal proxy" - } else { - logger.Printf("Handling %s Connection %d with target %s:%d", DomainSocketToHttps, connectionNo, actualTargetHost, actualTargetPort) - } - // Check if target is whitelisted - if !dps.isTargetWhitelisted(actualTargetHost, writer) { - if err := sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - startTime := time.Now() - request.Header.Del("Proxy-Connection") // Prevent keep-alive as it breaks internal proxy authentication - request.Header.Set("Connection", "close") // Prevent keep-alive as it breaks internal proxy authentication - // Try to connect to target or internal proxy - targetConnection, err := net.DialTimeout(TCP, fmt.Sprintf("%s:%d", targetHost, targetPort), sharedParams.ConnectionTimeout) - if err != nil { - dps.handleErrorResponse(writer, err, fmt.Sprintf("Failed to connect to %s", targetConnectionName)) - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - if err = targetConnection.SetDeadline(time.Now().Add(sharedParams.IdleTimeout)); err != nil { - common.HandleSetDeadlineError(targetConnection, err) - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - // Create HTTPS connection to internal proxy if enabled - if useInternalProxy { - proxyConnectRequest := fmt.Sprintf("CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\nConnection: close\r\n", actualTargetHost, actualTargetPort, actualTargetHost, actualTargetPort) // Prevent keep-alive as it breaks internal proxy authentication - // Add authentication details if configured - if dps.internalProxyUser != "" && dps.internalProxyPassword != "" { - proxyConnectRequest += fmt.Sprintf("Proxy-Authorization: Basic %s\r\n", GetBasicAuth(dps.internalProxyUser, dps.internalProxyPassword)) - } - proxyConnectRequest += "\r\n" - if _, err = targetConnection.Write([]byte(proxyConnectRequest)); err != nil { - dps.handleErrorResponse(writer, err, "Failed to send connect request to internal proxy") - if err = targetConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - proxyReader := bufio.NewReader(targetConnection) - proxyResponse, err := http.ReadResponse(proxyReader, request) - if err != nil { - dps.handleErrorResponse(writer, err, "Failed to establish connection with internal proxy") - if err = targetConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } else if proxyResponse.StatusCode != http.StatusOK { - proxyResponse.Header.Set("Connection", "close") // Prevent keep-alive as it breaks internal proxy authentication - if err := proxyResponse.Write(sourceConnection); err != nil { - dps.handleErrorResponse(writer, err, "Failed to send internal proxy response to source") - } - if err = targetConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - } - // Notify source that HTTPS connection has been established to target or internal proxy - if _, err = writer.Write([]byte("HTTP/1.1 200 Connection Established\r\nConnection: close\r\n\r\n")); err != nil { // Prevent keep-alive as it breaks internal proxy authentication - dps.handleErrorResponse(writer, err, "Failed to send connect response to source") - if err = targetConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - if err = sourceConnection.Close(); err != nil { - common.HandleConnectionCloseError(err) - } - return - } - // Initiate transfer between source and target or internal proxy - go func() { - common.BiDirectionalTransfer(sharedParams.RunningContext, sourceConnection, targetConnection, sharedParams.ByteBufferSize, DomainSocketToHttps, connectionNo) - logger.Printf("%s Connection %d ended after %d ms", DomainSocketToHttps, connectionNo, time.Since(startTime).Milliseconds()) - }() -} - -func getTargetHostAndPort(host string, defaultPort int) (string, int) { - hostAndPort := strings.Split(host, ":") - targetHost := hostAndPort[0] - targetPort := defaultPort - if len(hostAndPort) > 1 { - if port, err := strconv.Atoi(hostAndPort[1]); err == nil { - targetPort = port - } - } - return targetHost, targetPort -} - -func (dps *DomainProxyServer) isTargetWhitelisted(targetHost string, writer http.ResponseWriter) bool { - if !dps.targetWhitelist[targetHost] { - message := fmt.Sprintf("Target host %s is not whitelisted", targetHost) - logger.Println(message) - http.Error(writer, message, http.StatusForbidden) - return false - } - return true -} - -func (dps *DomainProxyServer) useInternalProxy(targetHost string) bool { - if dps.enableInternalProxy { - if !dps.internalNonProxyHosts[targetHost] { - return true - } else { - logger.Printf("Target host %s is non-proxy host", targetHost) - } - } - return false -} - -func GetBasicAuth(user string, password string) string { - return base64.StdEncoding.EncodeToString([]byte(user + ":" + password)) -} - -func (dps *DomainProxyServer) handleErrorResponse(writer http.ResponseWriter, err error, message string) { - logger.Printf("%s: %v", message, err) - writer.Header().Set("Connection", "close") // Prevent keep-alive as it breaks internal proxy authentication - status := http.StatusInternalServerError - http.Error(writer, message+": "+err.Error(), status) -} - -func (dps *DomainProxyServer) Stop() { - sharedParams := dps.sharedParams - logger.Println("Shutting down domain proxy server...") - sharedParams.InitiateShutdown() - if sharedParams.Listener != nil { - if err := sharedParams.Listener.Close(); err != nil { - common.HandleListenerCloseError(err) - } - } - if _, err := os.Stat(sharedParams.DomainSocket); err == nil { - if err := os.Remove(sharedParams.DomainSocket); err != nil { - logger.Printf("Failed to delete domain socket: %v", err) - } - } -} - -type responseWriter struct { - connection net.Conn - header http.Header - statusCode int -} - -func (rw *responseWriter) Header() http.Header { - if rw.header == nil { - rw.header = make(http.Header) - } - return rw.header -} - -func (rw *responseWriter) Write(data []byte) (int, error) { - return rw.connection.Write(data) -} - -func (rw *responseWriter) WriteHeader(statusCode int) { - rw.statusCode = statusCode - headers := fmt.Sprintf("HTTP/1.1 %d %s\r\n", statusCode, http.StatusText(statusCode)) - headers += "Connection: close\r\n" // Prevent keep-alive as it breaks internal proxy authentication - for k, v := range rw.Header() { - for _, vv := range v { - headers += fmt.Sprintf("%s: %s\r\n", k, vv) - } - } - headers += "\r\n" - if _, err := rw.connection.Write([]byte(headers)); err != nil { - logger.Printf("Failed to write headers to connection: %v", err) - } -} - -func getTargetWhitelist() map[string]bool { - return common.GetCsvEnvVariable(TargetWhitelistKey, DefaultTargetWhitelist) -} - -func getEnableInternalProxy() bool { - return common.GetBoolEnvVariable(EnableInternalProxyKey, DefaultEnableInternalProxy) -} - -func getInternalProxyHost() string { - return common.GetEnvVariable(InternalProxyHostKey, DefaultInternalProxyHost) -} - -func getInternalProxyPort() int { - return common.GetIntEnvVariable(InternalProxyPortKey, DefaultInternalProxyPort) -} - -func getInternalProxyUser() string { - return common.GetEnvVariable(InternalProxyUserKey, DefaultInternalProxyUser) -} - -func getInternalProxyPassword() string { - return common.GetEnvVariable(InternalProxyPasswordKey, DefaultInternalProxyPassword) -} - -func getInternalNonProxyHosts() map[string]bool { - return common.GetCsvEnvVariable(InternalNonProxyHostsKey, DefaultInternalNonProxyHosts) -} diff --git a/pkg/reconciler/dependencybuild/buildrecipeyaml.go b/pkg/reconciler/dependencybuild/buildrecipeyaml.go index 8cec863c6..002a55a84 100644 --- a/pkg/reconciler/dependencybuild/buildrecipeyaml.go +++ b/pkg/reconciler/dependencybuild/buildrecipeyaml.go @@ -134,7 +134,7 @@ func createDeployPipelineSpec(jbsConfig *v1alpha1.JBSConfig, buildRequestProcess } */ -func createPipelineSpec(log logr.Logger, tool string, commitTime int64, jbsConfig *v1alpha1.JBSConfig, systemConfig *v1alpha1.SystemConfig, recipe *v1alpha1.BuildRecipe, db *v1alpha1.DependencyBuild, paramValues []tektonpipeline.Param, buildRequestProcessorImage string, domainProxyImage string, buildId string, existingImages map[string]string, orasOptions string) (*tektonpipeline.PipelineSpec, string, error) { +func createPipelineSpec(log logr.Logger, tool string, commitTime int64, jbsConfig *v1alpha1.JBSConfig, systemConfig *v1alpha1.SystemConfig, recipe *v1alpha1.BuildRecipe, db *v1alpha1.DependencyBuild, paramValues []tektonpipeline.Param, buildRequestProcessorImage string, buildId string, existingImages map[string]string, orasOptions string) (*tektonpipeline.PipelineSpec, string, error) { // Rather than tagging with hash of json build recipe, buildrequestprocessor image and db.Name as the former two // could change with new image versions just use db.Name (which is a hash of scm url/tag/path so should be stable) @@ -542,7 +542,7 @@ func createPipelineSpec(log logr.Logger, tool string, commitTime int64, jbsConfi Name: "BUILD_IMAGE", Value: tektonpipeline.ParamValue{ Type: tektonpipeline.ParamTypeString, - StringVal: domainProxyImage, + StringVal: DomainProxyImage, }, }, { diff --git a/pkg/reconciler/dependencybuild/dependencybuild.go b/pkg/reconciler/dependencybuild/dependencybuild.go index eae90f644..ce97587aa 100644 --- a/pkg/reconciler/dependencybuild/dependencybuild.go +++ b/pkg/reconciler/dependencybuild/dependencybuild.go @@ -73,6 +73,8 @@ const ( PipelineRunFinalizer = "jvmbuildservice.io/finalizer" DeploySuffix = "-deploy" + + DomainProxyImage = "quay.io/redhat-user-workloads/konflux-jbs-pnc-tenant/domain-proxy:latest" ) type ReconcileDependencyBuild struct { @@ -537,10 +539,6 @@ func (r *ReconcileDependencyBuild) handleStateBuilding(ctx context.Context, db * if err != nil { return reconcile.Result{}, err } - domainProxyImage, err := r.domainProxyImage(ctx) - if err != nil { - return reconcile.Result{}, err - } pr.Namespace = db.Namespace // we do not use generate name since // 1. it was used in creating the db and the db name has random ids @@ -596,7 +594,7 @@ func (r *ReconcileDependencyBuild) handleStateBuilding(ctx context.Context, db * Pipeline: &v12.Duration{Duration: time.Hour * v1alpha1.DefaultTimeout}, Tasks: &v12.Duration{Duration: time.Hour * v1alpha1.DefaultTimeout}, } - pr.Spec.PipelineSpec, diagnosticContainerfile, err = createPipelineSpec(log, attempt.Recipe.Tool, db.Status.CommitTime, jbsConfig, &systemConfig, attempt.Recipe, db, paramValues, buildRequestProcessorImage, domainProxyImage, attempt.BuildId, preBuildImages, orasOptions) + pr.Spec.PipelineSpec, diagnosticContainerfile, err = createPipelineSpec(log, attempt.Recipe.Tool, db.Status.CommitTime, jbsConfig, &systemConfig, attempt.Recipe, db, paramValues, buildRequestProcessorImage, attempt.BuildId, preBuildImages, orasOptions) if err != nil { return reconcile.Result{}, err } @@ -1324,11 +1322,6 @@ func (r *ReconcileDependencyBuild) buildRequestProcessorImage(ctx context.Contex return image, err } -func (r *ReconcileDependencyBuild) domainProxyImage(ctx context.Context) (string, error) { - image, err := util.GetImageName(ctx, r.client, "domain-proxy", "JVM_BUILD_SERVICE_DOMAIN_PROXY_IMAGE") - return image, err -} - func (r *ReconcileDependencyBuild) handleTektonResults(db *v1alpha1.DependencyBuild, pr *tektonpipeline.PipelineRun) bool { if pr.GetAnnotations() == nil { return false diff --git a/vendor/github.com/elazarl/goproxy/.gitignore b/vendor/github.com/elazarl/goproxy/.gitignore deleted file mode 100644 index 1005f6f1e..000000000 --- a/vendor/github.com/elazarl/goproxy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -*.swp diff --git a/vendor/github.com/elazarl/goproxy/LICENSE b/vendor/github.com/elazarl/goproxy/LICENSE deleted file mode 100644 index 2067e567c..000000000 --- a/vendor/github.com/elazarl/goproxy/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Elazar Leibovich. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Elazar Leibovich. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/elazarl/goproxy/README.md b/vendor/github.com/elazarl/goproxy/README.md deleted file mode 100644 index 2bb2367f6..000000000 --- a/vendor/github.com/elazarl/goproxy/README.md +++ /dev/null @@ -1,168 +0,0 @@ -# Introduction - -[![GoDoc](https://godoc.org/github.com/elazarl/goproxy?status.svg)](https://godoc.org/github.com/elazarl/goproxy) -[![Join the chat at https://gitter.im/elazarl/goproxy](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/elazarl/goproxy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -Package goproxy provides a customizable HTTP proxy library for Go (golang), - -It supports regular HTTP proxy, HTTPS through CONNECT, and "hijacking" HTTPS -connection using "Man in the Middle" style attack. - -The intent of the proxy is to be usable with reasonable amount of traffic, -yet customizable and programmable. - -The proxy itself is simply a `net/http` handler. - -In order to use goproxy, one should set their browser to use goproxy as an HTTP -proxy. Here is how you do that [in Chrome](https://support.google.com/chrome/answer/96815?hl=en) -and [in Firefox](http://www.wikihow.com/Enter-Proxy-Settings-in-Firefox). - -For example, the URL you should use as proxy when running `./bin/basic` is -`localhost:8080`, as this is the default binding for the basic proxy. - -## Mailing List - -New features will be discussed on the [mailing list](https://groups.google.com/forum/#!forum/goproxy-dev) -before their development. - -## Latest Stable Release - -Get the latest goproxy from `gopkg.in/elazarl/goproxy.v1`. - -# Why not Fiddler2? - -Fiddler is an excellent software with similar intent. However, Fiddler is not -as customizable as goproxy intends to be. The main difference is, Fiddler is not -intended to be used as a real proxy. - -A possible use case that suits goproxy but -not Fiddler, is gathering statistics on page load times for a certain website over a week. -With goproxy you could ask all your users to set their proxy to a dedicated machine running a -goproxy server. Fiddler is a GUI app not designed to be run like a server for multiple users. - -# A taste of goproxy - -To get a taste of `goproxy`, a basic HTTP/HTTPS transparent proxy - -```go -package main - -import ( - "github.com/elazarl/goproxy" - "log" - "net/http" -) - -func main() { - proxy := goproxy.NewProxyHttpServer() - proxy.Verbose = true - log.Fatal(http.ListenAndServe(":8080", proxy)) -} -``` - -This line will add `X-GoProxy: yxorPoG-X` header to all requests sent through the proxy - -```go -proxy.OnRequest().DoFunc( - func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) { - r.Header.Set("X-GoProxy","yxorPoG-X") - return r,nil - }) -``` - -`DoFunc` will process all incoming requests to the proxy. It will add a header to the request -and return it. The proxy will send the modified request. - -Note that we returned nil value as the response. Had we returned a response, goproxy would -have discarded the request and sent the new response to the client. - -In order to refuse connections to reddit at work time - -```go -proxy.OnRequest(goproxy.DstHostIs("www.reddit.com")).DoFunc( - func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) { - if h,_,_ := time.Now().Clock(); h >= 8 && h <= 17 { - return r,goproxy.NewResponse(r, - goproxy.ContentTypeText,http.StatusForbidden, - "Don't waste your time!") - } - return r,nil -}) -``` - -`DstHostIs` returns a `ReqCondition`, that is a function receiving a `Request` and returning a boolean. -We will only process requests that match the condition. `DstHostIs("www.reddit.com")` will return -a `ReqCondition` accepting only requests directed to "www.reddit.com". - -`DoFunc` will receive a function that will preprocess the request. We can change the request, or -return a response. If the time is between 8:00am and 17:00pm, we will reject the request, and -return a precanned text response saying "do not waste your time". - -See additional examples in the examples directory. - - -# Type of handlers for manipulating connect/req/resp behavior - -There are 3 kinds of useful handlers to manipulate the behavior, as follows: - -```go -// handler called after receiving HTTP CONNECT from the client, and before proxy establish connection -// with destination host -httpsHandlers []HttpsHandler - -// handler called before proxy send HTTP request to destination host -reqHandlers []ReqHandler - -// handler called after proxy receives HTTP Response from destination host, and before proxy forward -// the Response to the client. -respHandlers []RespHandler -``` - -Depending on what you want to manipulate, the ways to add handlers to each handler list are: - -```go -// Add handlers to httpsHandlers -proxy.OnRequest(Some ReqConditions).HandleConnect(YourHandlerFunc()) - -// Add handlers to reqHandlers -proxy.OnRequest(Some ReqConditions).Do(YourReqHandlerFunc()) - -// Add handlers to respHandlers -proxy.OnResponse(Some RespConditions).Do(YourRespHandlerFunc()) -``` - -For example: - -```go -// This rejects the HTTPS request to *.reddit.com during HTTP CONNECT phase -proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("reddit.*:443$"))).HandleConnect(goproxy.RejectConnect) - -// This will NOT reject the HTTPS request with URL ending with gif, due to the fact that proxy -// only got the URL.Hostname and URL.Port during the HTTP CONNECT phase if the scheme is HTTPS, which is -// quiet common these days. -proxy.OnRequest(goproxy.UrlMatches(regexp.MustCompile(`.*gif$`))).HandleConnect(goproxy.RejectConnect) - -// The correct way to manipulate the HTTP request using URL.Path as condition is: -proxy.OnRequest(goproxy.UrlMatches(regexp.MustCompile(`.*gif$`))).Do(YourReqHandlerFunc()) -``` - -# What's New - -1. Ability to `Hijack` CONNECT requests. See -[the eavesdropper example](https://github.com/elazarl/goproxy/blob/master/examples/goproxy-eavesdropper/main.go#L27) -2. Transparent proxy support for http/https including MITM certificate generation for TLS. See the [transparent example.](https://github.com/elazarl/goproxy/tree/master/examples/goproxy-transparent) - -# License - -I put the software temporarily under the Go-compatible BSD license. -If this prevents someone from using the software, do let me know and I'll consider changing it. - -At any rate, user feedback is very important for me, so I'll be delighted to know if you're using this package. - -# Beta Software - -I've received positive feedback from a few people who use goproxy in production settings. -I believe it is good enough for usage. - -I'll try to keep reasonable backwards compatibility. In case of a major API change, -I'll change the import path. diff --git a/vendor/github.com/elazarl/goproxy/actions.go b/vendor/github.com/elazarl/goproxy/actions.go deleted file mode 100644 index e1a3e7ff1..000000000 --- a/vendor/github.com/elazarl/goproxy/actions.go +++ /dev/null @@ -1,57 +0,0 @@ -package goproxy - -import "net/http" - -// ReqHandler will "tamper" with the request coming to the proxy server -// If Handle returns req,nil the proxy will send the returned request -// to the destination server. If it returns nil,resp the proxy will -// skip sending any requests, and will simply return the response `resp` -// to the client. -type ReqHandler interface { - Handle(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response) -} - -// A wrapper that would convert a function to a ReqHandler interface type -type FuncReqHandler func(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response) - -// FuncReqHandler.Handle(req,ctx) <=> FuncReqHandler(req,ctx) -func (f FuncReqHandler) Handle(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response) { - return f(req, ctx) -} - -// after the proxy have sent the request to the destination server, it will -// "filter" the response through the RespHandlers it has. -// The proxy server will send to the client the response returned by the RespHandler. -// In case of error, resp will be nil, and ctx.RoundTrip.Error will contain the error -type RespHandler interface { - Handle(resp *http.Response, ctx *ProxyCtx) *http.Response -} - -// A wrapper that would convert a function to a RespHandler interface type -type FuncRespHandler func(resp *http.Response, ctx *ProxyCtx) *http.Response - -// FuncRespHandler.Handle(req,ctx) <=> FuncRespHandler(req,ctx) -func (f FuncRespHandler) Handle(resp *http.Response, ctx *ProxyCtx) *http.Response { - return f(resp, ctx) -} - -// When a client send a CONNECT request to a host, the request is filtered through -// all the HttpsHandlers the proxy has, and if one returns true, the connection is -// sniffed using Man in the Middle attack. -// That is, the proxy will create a TLS connection with the client, another TLS -// connection with the destination the client wished to connect to, and would -// send back and forth all messages from the server to the client and vice versa. -// The request and responses sent in this Man In the Middle channel are filtered -// through the usual flow (request and response filtered through the ReqHandlers -// and RespHandlers) -type HttpsHandler interface { - HandleConnect(req string, ctx *ProxyCtx) (*ConnectAction, string) -} - -// A wrapper that would convert a function to a HttpsHandler interface type -type FuncHttpsHandler func(host string, ctx *ProxyCtx) (*ConnectAction, string) - -// FuncHttpsHandler should implement the RespHandler interface -func (f FuncHttpsHandler) HandleConnect(host string, ctx *ProxyCtx) (*ConnectAction, string) { - return f(host, ctx) -} diff --git a/vendor/github.com/elazarl/goproxy/all.bash b/vendor/github.com/elazarl/goproxy/all.bash deleted file mode 100644 index 6503e73dc..000000000 --- a/vendor/github.com/elazarl/goproxy/all.bash +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -go test || exit -for action in $@; do go $action; done - -mkdir -p bin -find regretable examples/* ext/* -maxdepth 0 -type d | while read d; do - (cd $d - go build -o ../../bin/$(basename $d) - find *_test.go -maxdepth 0 2>/dev/null|while read f;do - for action in $@; do go $action; done - go test - break - done) -done diff --git a/vendor/github.com/elazarl/goproxy/ca.pem b/vendor/github.com/elazarl/goproxy/ca.pem deleted file mode 100644 index 62653dae8..000000000 --- a/vendor/github.com/elazarl/goproxy/ca.pem +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF9DCCA9ygAwIBAgIJAODqYUwoVjJkMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD -VQQGEwJJTDEPMA0GA1UECAwGQ2VudGVyMQwwCgYDVQQHDANMb2QxEDAOBgNVBAoM -B0dvUHJveHkxEDAOBgNVBAsMB0dvUHJveHkxGjAYBgNVBAMMEWdvcHJveHkuZ2l0 -aHViLmlvMSAwHgYJKoZIhvcNAQkBFhFlbGF6YXJsQGdtYWlsLmNvbTAeFw0xNzA0 -MDUyMDAwMTBaFw0zNzAzMzEyMDAwMTBaMIGOMQswCQYDVQQGEwJJTDEPMA0GA1UE -CAwGQ2VudGVyMQwwCgYDVQQHDANMb2QxEDAOBgNVBAoMB0dvUHJveHkxEDAOBgNV -BAsMB0dvUHJveHkxGjAYBgNVBAMMEWdvcHJveHkuZ2l0aHViLmlvMSAwHgYJKoZI -hvcNAQkBFhFlbGF6YXJsQGdtYWlsLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAJ4Qy+H6hhoY1s0QRcvIhxrjSHaO/RbaFj3rwqcnpOgFq07gRdI9 -3c0TFKQJHpgv6feLRhEvX/YllFYu4J35lM9ZcYY4qlKFuStcX8Jm8fqpgtmAMBzP -sqtqDi8M9RQGKENzU9IFOnCV7SAeh45scMuI3wz8wrjBcH7zquHkvqUSYZz035t9 -V6WTrHyTEvT4w+lFOVN2bA/6DAIxrjBiF6DhoJqnha0SZtDfv77XpwGG3EhA/qoh -hiYrDruYK7zJdESQL44LwzMPupVigqalfv+YHfQjbhT951IVurW2NJgRyBE62dLr -lHYdtT9tCTCrd+KJNMJ+jp9hAjdIu1Br/kifU4F4+4ZLMR9Ueji0GkkPKsYdyMnq -j0p0PogyvP1l4qmboPImMYtaoFuYmMYlebgC9LN10bL91K4+jLt0I1YntEzrqgJo -WsJztYDw543NzSy5W+/cq4XRYgtq1b0RWwuUiswezmMoeyHZ8BQJe2xMjAOllASD -fqa8OK3WABHJpy4zUrnUBiMuPITzD/FuDx4C5IwwlC68gHAZblNqpBZCX0nFCtKj -YOcI2So5HbQ2OC8QF+zGVuduHUSok4hSy2BBfZ1pfvziqBeetWJwFvapGB44nIHh -WKNKvqOxLNIy7e+TGRiWOomrAWM18VSR9LZbBxpJK7PLSzWqYJYTRCZHAgMBAAGj -UzBRMB0GA1UdDgQWBBR4uDD9Y6x7iUoHO+32ioOcw1ICZTAfBgNVHSMEGDAWgBR4 -uDD9Y6x7iUoHO+32ioOcw1ICZTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4ICAQAaCEupzGGqcdh+L7BzhX7zyd7yzAKUoLxFrxaZY34Xyj3lcx1XoK6F -AqsH2JM25GixgadzhNt92JP7vzoWeHZtLfstrPS638Y1zZi6toy4E49viYjFk5J0 -C6ZcFC04VYWWx6z0HwJuAS08tZ37JuFXpJGfXJOjZCQyxse0Lg0tuKLMeXDCk2Y3 -Ba0noeuNyHRoWXXPyiUoeApkVCU5gIsyiJSWOjhJ5hpJG06rQNfNYexgKrrraEin -o0jmEMtJMx5TtD83hSnLCnFGBBq5lkE7jgXME1KsbIE3lJZzRX1mQwUK8CJDYxye -i6M/dzSvy0SsPvz8fTAlprXRtWWtJQmxgWENp3Dv+0Pmux/l+ilk7KA4sMXGhsfr -bvTOeWl1/uoFTPYiWR/ww7QEPLq23yDFY04Q7Un0qjIk8ExvaY8lCkXMgc8i7sGY -VfvOYb0zm67EfAQl3TW8Ky5fl5CcxpVCD360Bzi6hwjYixa3qEeBggOixFQBFWft -8wrkKTHpOQXjn4sDPtet8imm9UYEtzWrFX6T9MFYkBR0/yye0FIh9+YPiTA6WB86 -NCNwK5Yl6HuvF97CIH5CdgO+5C7KifUtqTOL8pQKbNwy0S3sNYvB+njGvRpR7pKV -BUnFpB/Atptqr4CUlTXrc5IPLAqAfmwk5IKcwy3EXUbruf9Dwz69YA== ------END CERTIFICATE----- diff --git a/vendor/github.com/elazarl/goproxy/certs.go b/vendor/github.com/elazarl/goproxy/certs.go deleted file mode 100644 index 4731971e7..000000000 --- a/vendor/github.com/elazarl/goproxy/certs.go +++ /dev/null @@ -1,111 +0,0 @@ -package goproxy - -import ( - "crypto/tls" - "crypto/x509" -) - -func init() { - if goproxyCaErr != nil { - panic("Error parsing builtin CA " + goproxyCaErr.Error()) - } - var err error - if GoproxyCa.Leaf, err = x509.ParseCertificate(GoproxyCa.Certificate[0]); err != nil { - panic("Error parsing builtin CA " + err.Error()) - } -} - -var tlsClientSkipVerify = &tls.Config{InsecureSkipVerify: true} - -var defaultTLSConfig = &tls.Config{ - InsecureSkipVerify: true, -} - -var CA_CERT = []byte(`-----BEGIN CERTIFICATE----- -MIIF9DCCA9ygAwIBAgIJAODqYUwoVjJkMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD -VQQGEwJJTDEPMA0GA1UECAwGQ2VudGVyMQwwCgYDVQQHDANMb2QxEDAOBgNVBAoM -B0dvUHJveHkxEDAOBgNVBAsMB0dvUHJveHkxGjAYBgNVBAMMEWdvcHJveHkuZ2l0 -aHViLmlvMSAwHgYJKoZIhvcNAQkBFhFlbGF6YXJsQGdtYWlsLmNvbTAeFw0xNzA0 -MDUyMDAwMTBaFw0zNzAzMzEyMDAwMTBaMIGOMQswCQYDVQQGEwJJTDEPMA0GA1UE -CAwGQ2VudGVyMQwwCgYDVQQHDANMb2QxEDAOBgNVBAoMB0dvUHJveHkxEDAOBgNV -BAsMB0dvUHJveHkxGjAYBgNVBAMMEWdvcHJveHkuZ2l0aHViLmlvMSAwHgYJKoZI -hvcNAQkBFhFlbGF6YXJsQGdtYWlsLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAJ4Qy+H6hhoY1s0QRcvIhxrjSHaO/RbaFj3rwqcnpOgFq07gRdI9 -3c0TFKQJHpgv6feLRhEvX/YllFYu4J35lM9ZcYY4qlKFuStcX8Jm8fqpgtmAMBzP -sqtqDi8M9RQGKENzU9IFOnCV7SAeh45scMuI3wz8wrjBcH7zquHkvqUSYZz035t9 -V6WTrHyTEvT4w+lFOVN2bA/6DAIxrjBiF6DhoJqnha0SZtDfv77XpwGG3EhA/qoh -hiYrDruYK7zJdESQL44LwzMPupVigqalfv+YHfQjbhT951IVurW2NJgRyBE62dLr -lHYdtT9tCTCrd+KJNMJ+jp9hAjdIu1Br/kifU4F4+4ZLMR9Ueji0GkkPKsYdyMnq -j0p0PogyvP1l4qmboPImMYtaoFuYmMYlebgC9LN10bL91K4+jLt0I1YntEzrqgJo -WsJztYDw543NzSy5W+/cq4XRYgtq1b0RWwuUiswezmMoeyHZ8BQJe2xMjAOllASD -fqa8OK3WABHJpy4zUrnUBiMuPITzD/FuDx4C5IwwlC68gHAZblNqpBZCX0nFCtKj -YOcI2So5HbQ2OC8QF+zGVuduHUSok4hSy2BBfZ1pfvziqBeetWJwFvapGB44nIHh -WKNKvqOxLNIy7e+TGRiWOomrAWM18VSR9LZbBxpJK7PLSzWqYJYTRCZHAgMBAAGj -UzBRMB0GA1UdDgQWBBR4uDD9Y6x7iUoHO+32ioOcw1ICZTAfBgNVHSMEGDAWgBR4 -uDD9Y6x7iUoHO+32ioOcw1ICZTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4ICAQAaCEupzGGqcdh+L7BzhX7zyd7yzAKUoLxFrxaZY34Xyj3lcx1XoK6F -AqsH2JM25GixgadzhNt92JP7vzoWeHZtLfstrPS638Y1zZi6toy4E49viYjFk5J0 -C6ZcFC04VYWWx6z0HwJuAS08tZ37JuFXpJGfXJOjZCQyxse0Lg0tuKLMeXDCk2Y3 -Ba0noeuNyHRoWXXPyiUoeApkVCU5gIsyiJSWOjhJ5hpJG06rQNfNYexgKrrraEin -o0jmEMtJMx5TtD83hSnLCnFGBBq5lkE7jgXME1KsbIE3lJZzRX1mQwUK8CJDYxye -i6M/dzSvy0SsPvz8fTAlprXRtWWtJQmxgWENp3Dv+0Pmux/l+ilk7KA4sMXGhsfr -bvTOeWl1/uoFTPYiWR/ww7QEPLq23yDFY04Q7Un0qjIk8ExvaY8lCkXMgc8i7sGY -VfvOYb0zm67EfAQl3TW8Ky5fl5CcxpVCD360Bzi6hwjYixa3qEeBggOixFQBFWft -8wrkKTHpOQXjn4sDPtet8imm9UYEtzWrFX6T9MFYkBR0/yye0FIh9+YPiTA6WB86 -NCNwK5Yl6HuvF97CIH5CdgO+5C7KifUtqTOL8pQKbNwy0S3sNYvB+njGvRpR7pKV -BUnFpB/Atptqr4CUlTXrc5IPLAqAfmwk5IKcwy3EXUbruf9Dwz69YA== ------END CERTIFICATE-----`) - -var CA_KEY = []byte(`-----BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY-----`) - -var GoproxyCa, goproxyCaErr = tls.X509KeyPair(CA_CERT, CA_KEY) diff --git a/vendor/github.com/elazarl/goproxy/chunked.go b/vendor/github.com/elazarl/goproxy/chunked.go deleted file mode 100644 index 83654f658..000000000 --- a/vendor/github.com/elazarl/goproxy/chunked.go +++ /dev/null @@ -1,59 +0,0 @@ -// Taken from $GOROOT/src/pkg/net/http/chunked -// needed to write https responses to client. -package goproxy - -import ( - "io" - "strconv" -) - -// newChunkedWriter returns a new chunkedWriter that translates writes into HTTP -// "chunked" format before writing them to w. Closing the returned chunkedWriter -// sends the final 0-length chunk that marks the end of the stream. -// -// newChunkedWriter is not needed by normal applications. The http -// package adds chunking automatically if handlers don't set a -// Content-Length header. Using newChunkedWriter inside a handler -// would result in double chunking or chunking with a Content-Length -// length, both of which are wrong. -func newChunkedWriter(w io.Writer) io.WriteCloser { - return &chunkedWriter{w} -} - -// Writing to chunkedWriter translates to writing in HTTP chunked Transfer -// Encoding wire format to the underlying Wire chunkedWriter. -type chunkedWriter struct { - Wire io.Writer -} - -// Write the contents of data as one chunk to Wire. -// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has -// a bug since it does not check for success of io.WriteString -func (cw *chunkedWriter) Write(data []byte) (n int, err error) { - - // Don't send 0-length data. It looks like EOF for chunked encoding. - if len(data) == 0 { - return 0, nil - } - - head := strconv.FormatInt(int64(len(data)), 16) + "\r\n" - - if _, err = io.WriteString(cw.Wire, head); err != nil { - return 0, err - } - if n, err = cw.Wire.Write(data); err != nil { - return - } - if n != len(data) { - err = io.ErrShortWrite - return - } - _, err = io.WriteString(cw.Wire, "\r\n") - - return -} - -func (cw *chunkedWriter) Close() error { - _, err := io.WriteString(cw.Wire, "0\r\n") - return err -} diff --git a/vendor/github.com/elazarl/goproxy/counterecryptor.go b/vendor/github.com/elazarl/goproxy/counterecryptor.go deleted file mode 100644 index 494e7a4fe..000000000 --- a/vendor/github.com/elazarl/goproxy/counterecryptor.go +++ /dev/null @@ -1,68 +0,0 @@ -package goproxy - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "errors" -) - -type CounterEncryptorRand struct { - cipher cipher.Block - counter []byte - rand []byte - ix int -} - -func NewCounterEncryptorRandFromKey(key interface{}, seed []byte) (r CounterEncryptorRand, err error) { - var keyBytes []byte - switch key := key.(type) { - case *rsa.PrivateKey: - keyBytes = x509.MarshalPKCS1PrivateKey(key) - default: - err = errors.New("only RSA keys supported") - return - } - h := sha256.New() - if r.cipher, err = aes.NewCipher(h.Sum(keyBytes)[:aes.BlockSize]); err != nil { - return - } - r.counter = make([]byte, r.cipher.BlockSize()) - if seed != nil { - copy(r.counter, h.Sum(seed)[:r.cipher.BlockSize()]) - } - r.rand = make([]byte, r.cipher.BlockSize()) - r.ix = len(r.rand) - return -} - -func (c *CounterEncryptorRand) Seed(b []byte) { - if len(b) != len(c.counter) { - panic("SetCounter: wrong counter size") - } - copy(c.counter, b) -} - -func (c *CounterEncryptorRand) refill() { - c.cipher.Encrypt(c.rand, c.counter) - for i := 0; i < len(c.counter); i++ { - if c.counter[i]++; c.counter[i] != 0 { - break - } - } - c.ix = 0 -} - -func (c *CounterEncryptorRand) Read(b []byte) (n int, err error) { - if c.ix == len(c.rand) { - c.refill() - } - if n = len(c.rand) - c.ix; n > len(b) { - n = len(b) - } - copy(b, c.rand[c.ix:c.ix+n]) - c.ix += n - return -} diff --git a/vendor/github.com/elazarl/goproxy/ctx.go b/vendor/github.com/elazarl/goproxy/ctx.go deleted file mode 100644 index 86162deb7..000000000 --- a/vendor/github.com/elazarl/goproxy/ctx.go +++ /dev/null @@ -1,93 +0,0 @@ -package goproxy - -import ( - "crypto/tls" - "net/http" - "regexp" -) - -// ProxyCtx is the Proxy context, contains useful information about every request. It is passed to -// every user function. Also used as a logger. -type ProxyCtx struct { - // Will contain the client request from the proxy - Req *http.Request - // Will contain the remote server's response (if available. nil if the request wasn't send yet) - Resp *http.Response - RoundTripper RoundTripper - // will contain the recent error that occurred while trying to send receive or parse traffic - Error error - // A handle for the user to keep data in the context, from the call of ReqHandler to the - // call of RespHandler - UserData interface{} - // Will connect a request to a response - Session int64 - certStore CertStorage - proxy *ProxyHttpServer -} - -type RoundTripper interface { - RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error) -} - -type CertStorage interface { - Fetch(hostname string, gen func() (*tls.Certificate, error)) (*tls.Certificate, error) -} - -type RoundTripperFunc func(req *http.Request, ctx *ProxyCtx) (*http.Response, error) - -func (f RoundTripperFunc) RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error) { - return f(req, ctx) -} - -func (ctx *ProxyCtx) RoundTrip(req *http.Request) (*http.Response, error) { - if ctx.RoundTripper != nil { - return ctx.RoundTripper.RoundTrip(req, ctx) - } - return ctx.proxy.Tr.RoundTrip(req) -} - -func (ctx *ProxyCtx) printf(msg string, argv ...interface{}) { - ctx.proxy.Logger.Printf("[%03d] "+msg+"\n", append([]interface{}{ctx.Session & 0xFF}, argv...)...) -} - -// Logf prints a message to the proxy's log. Should be used in a ProxyHttpServer's filter -// This message will be printed only if the Verbose field of the ProxyHttpServer is set to true -// -// proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ -// nr := atomic.AddInt32(&counter,1) -// ctx.Printf("So far %d requests",nr) -// return r, nil -// }) -func (ctx *ProxyCtx) Logf(msg string, argv ...interface{}) { - if ctx.proxy.Verbose { - ctx.printf("INFO: "+msg, argv...) - } -} - -// Warnf prints a message to the proxy's log. Should be used in a ProxyHttpServer's filter -// This message will always be printed. -// -// proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ -// f,err := os.OpenFile(cachedContent) -// if err != nil { -// ctx.Warnf("error open file %v: %v",cachedContent,err) -// return r, nil -// } -// return r, nil -// }) -func (ctx *ProxyCtx) Warnf(msg string, argv ...interface{}) { - ctx.printf("WARN: "+msg, argv...) -} - -var charsetFinder = regexp.MustCompile("charset=([^ ;]*)") - -// Will try to infer the character set of the request from the headers. -// Returns the empty string if we don't know which character set it used. -// Currently it will look for charset= in the Content-Type header of the request. -func (ctx *ProxyCtx) Charset() string { - charsets := charsetFinder.FindStringSubmatch(ctx.Resp.Header.Get("Content-Type")) - if charsets == nil { - return "" - } - return charsets[1] -} diff --git a/vendor/github.com/elazarl/goproxy/dispatcher.go b/vendor/github.com/elazarl/goproxy/dispatcher.go deleted file mode 100644 index 4e7c9cb9d..000000000 --- a/vendor/github.com/elazarl/goproxy/dispatcher.go +++ /dev/null @@ -1,325 +0,0 @@ -package goproxy - -import ( - "bytes" - "io/ioutil" - "net" - "net/http" - "regexp" - "strings" -) - -// ReqCondition.HandleReq will decide whether or not to use the ReqHandler on an HTTP request -// before sending it to the remote server -type ReqCondition interface { - RespCondition - HandleReq(req *http.Request, ctx *ProxyCtx) bool -} - -// RespCondition.HandleReq will decide whether or not to use the RespHandler on an HTTP response -// before sending it to the proxy client. Note that resp might be nil, in case there was an -// error sending the request. -type RespCondition interface { - HandleResp(resp *http.Response, ctx *ProxyCtx) bool -} - -// ReqConditionFunc.HandleReq(req,ctx) <=> ReqConditionFunc(req,ctx) -type ReqConditionFunc func(req *http.Request, ctx *ProxyCtx) bool - -// RespConditionFunc.HandleResp(resp,ctx) <=> RespConditionFunc(resp,ctx) -type RespConditionFunc func(resp *http.Response, ctx *ProxyCtx) bool - -func (c ReqConditionFunc) HandleReq(req *http.Request, ctx *ProxyCtx) bool { - return c(req, ctx) -} - -// ReqConditionFunc cannot test responses. It only satisfies RespCondition interface so that -// to be usable as RespCondition. -func (c ReqConditionFunc) HandleResp(resp *http.Response, ctx *ProxyCtx) bool { - return c(ctx.Req, ctx) -} - -func (c RespConditionFunc) HandleResp(resp *http.Response, ctx *ProxyCtx) bool { - return c(resp, ctx) -} - -// UrlHasPrefix returns a ReqCondition checking wether the destination URL the proxy client has requested -// has the given prefix, with or without the host. -// For example UrlHasPrefix("host/x") will match requests of the form 'GET host/x', and will match -// requests to url 'http://host/x' -func UrlHasPrefix(prefix string) ReqConditionFunc { - return func(req *http.Request, ctx *ProxyCtx) bool { - return strings.HasPrefix(req.URL.Path, prefix) || - strings.HasPrefix(req.URL.Host+req.URL.Path, prefix) || - strings.HasPrefix(req.URL.Scheme+req.URL.Host+req.URL.Path, prefix) - } -} - -// UrlIs returns a ReqCondition, testing whether or not the request URL is one of the given strings -// with or without the host prefix. -// UrlIs("google.com/","foo") will match requests 'GET /' to 'google.com', requests `'GET google.com/' to -// any host, and requests of the form 'GET foo'. -func UrlIs(urls ...string) ReqConditionFunc { - urlSet := make(map[string]bool) - for _, u := range urls { - urlSet[u] = true - } - return func(req *http.Request, ctx *ProxyCtx) bool { - _, pathOk := urlSet[req.URL.Path] - _, hostAndOk := urlSet[req.URL.Host+req.URL.Path] - return pathOk || hostAndOk - } -} - -// ReqHostMatches returns a ReqCondition, testing whether the host to which the request was directed to matches -// any of the given regular expressions. -func ReqHostMatches(regexps ...*regexp.Regexp) ReqConditionFunc { - return func(req *http.Request, ctx *ProxyCtx) bool { - for _, re := range regexps { - if re.MatchString(req.Host) { - return true - } - } - return false - } -} - -// ReqHostIs returns a ReqCondition, testing whether the host to which the request is directed to equal -// to one of the given strings -func ReqHostIs(hosts ...string) ReqConditionFunc { - hostSet := make(map[string]bool) - for _, h := range hosts { - hostSet[h] = true - } - return func(req *http.Request, ctx *ProxyCtx) bool { - _, ok := hostSet[req.URL.Host] - return ok - } -} - -var localHostIpv4 = regexp.MustCompile(`127\.0\.0\.\d+`) - -// IsLocalHost checks whether the destination host is explicitly local host -// (buggy, there can be IPv6 addresses it doesn't catch) -var IsLocalHost ReqConditionFunc = func(req *http.Request, ctx *ProxyCtx) bool { - return req.URL.Host == "::1" || - req.URL.Host == "0:0:0:0:0:0:0:1" || - localHostIpv4.MatchString(req.URL.Host) || - req.URL.Host == "localhost" -} - -// UrlMatches returns a ReqCondition testing whether the destination URL -// of the request matches the given regexp, with or without prefix -func UrlMatches(re *regexp.Regexp) ReqConditionFunc { - return func(req *http.Request, ctx *ProxyCtx) bool { - return re.MatchString(req.URL.Path) || - re.MatchString(req.URL.Host+req.URL.Path) - } -} - -// DstHostIs returns a ReqCondition testing wether the host in the request url is the given string -func DstHostIs(host string) ReqConditionFunc { - return func(req *http.Request, ctx *ProxyCtx) bool { - return req.URL.Host == host - } -} - -// SrcIpIs returns a ReqCondition testing whether the source IP of the request is one of the given strings -func SrcIpIs(ips ...string) ReqCondition { - return ReqConditionFunc(func(req *http.Request, ctx *ProxyCtx) bool { - for _, ip := range ips { - if strings.HasPrefix(req.RemoteAddr, ip+":") { - return true - } - } - return false - }) -} - -// Not returns a ReqCondition negating the given ReqCondition -func Not(r ReqCondition) ReqConditionFunc { - return func(req *http.Request, ctx *ProxyCtx) bool { - return !r.HandleReq(req, ctx) - } -} - -// ContentTypeIs returns a RespCondition testing whether the HTTP response has Content-Type header equal -// to one of the given strings. -func ContentTypeIs(typ string, types ...string) RespCondition { - types = append(types, typ) - return RespConditionFunc(func(resp *http.Response, ctx *ProxyCtx) bool { - if resp == nil { - return false - } - contentType := resp.Header.Get("Content-Type") - for _, typ := range types { - if contentType == typ || strings.HasPrefix(contentType, typ+";") { - return true - } - } - return false - }) -} - -// ProxyHttpServer.OnRequest Will return a temporary ReqProxyConds struct, aggregating the given condtions. -// You will use the ReqProxyConds struct to register a ReqHandler, that would filter -// the request, only if all the given ReqCondition matched. -// Typical usage: -// proxy.OnRequest(UrlIs("example.com/foo"),UrlMatches(regexp.MustParse(`.*\.exampl.\com\./.*`)).Do(...) -func (proxy *ProxyHttpServer) OnRequest(conds ...ReqCondition) *ReqProxyConds { - return &ReqProxyConds{proxy, conds} -} - -// ReqProxyConds aggregate ReqConditions for a ProxyHttpServer. Upon calling Do, it will register a ReqHandler that would -// handle the request if all conditions on the HTTP request are met. -type ReqProxyConds struct { - proxy *ProxyHttpServer - reqConds []ReqCondition -} - -// DoFunc is equivalent to proxy.OnRequest().Do(FuncReqHandler(f)) -func (pcond *ReqProxyConds) DoFunc(f func(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response)) { - pcond.Do(FuncReqHandler(f)) -} - -// ReqProxyConds.Do will register the ReqHandler on the proxy, -// the ReqHandler will handle the HTTP request if all the conditions -// aggregated in the ReqProxyConds are met. Typical usage: -// proxy.OnRequest().Do(handler) // will call handler.Handle(req,ctx) on every request to the proxy -// proxy.OnRequest(cond1,cond2).Do(handler) -// // given request to the proxy, will test if cond1.HandleReq(req,ctx) && cond2.HandleReq(req,ctx) are true -// // if they are, will call handler.Handle(req,ctx) -func (pcond *ReqProxyConds) Do(h ReqHandler) { - pcond.proxy.reqHandlers = append(pcond.proxy.reqHandlers, - FuncReqHandler(func(r *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response) { - for _, cond := range pcond.reqConds { - if !cond.HandleReq(r, ctx) { - return r, nil - } - } - return h.Handle(r, ctx) - })) -} - -// HandleConnect is used when proxy receives an HTTP CONNECT request, -// it'll then use the HttpsHandler to determine what should it -// do with this request. The handler returns a ConnectAction struct, the Action field in the ConnectAction -// struct returned will determine what to do with this request. ConnectAccept will simply accept the request -// forwarding all bytes from the client to the remote host, ConnectReject will close the connection with the -// client, and ConnectMitm, will assume the underlying connection is an HTTPS connection, and will use Man -// in the Middle attack to eavesdrop the connection. All regular handler will be active on this eavesdropped -// connection. -// The ConnectAction struct contains possible tlsConfig that will be used for eavesdropping. If nil, the proxy -// will use the default tls configuration. -// proxy.OnRequest().HandleConnect(goproxy.AlwaysReject) // rejects all CONNECT requests -func (pcond *ReqProxyConds) HandleConnect(h HttpsHandler) { - pcond.proxy.httpsHandlers = append(pcond.proxy.httpsHandlers, - FuncHttpsHandler(func(host string, ctx *ProxyCtx) (*ConnectAction, string) { - for _, cond := range pcond.reqConds { - if !cond.HandleReq(ctx.Req, ctx) { - return nil, "" - } - } - return h.HandleConnect(host, ctx) - })) -} - -// HandleConnectFunc is equivalent to HandleConnect, -// for example, accepting CONNECT request if they contain a password in header -// io.WriteString(h,password) -// passHash := h.Sum(nil) -// proxy.OnRequest().HandleConnectFunc(func(host string, ctx *ProxyCtx) (*ConnectAction, string) { -// c := sha1.New() -// io.WriteString(c,ctx.Req.Header.Get("X-GoProxy-Auth")) -// if c.Sum(nil) == passHash { -// return OkConnect, host -// } -// return RejectConnect, host -// }) -func (pcond *ReqProxyConds) HandleConnectFunc(f func(host string, ctx *ProxyCtx) (*ConnectAction, string)) { - pcond.HandleConnect(FuncHttpsHandler(f)) -} - -func (pcond *ReqProxyConds) HijackConnect(f func(req *http.Request, client net.Conn, ctx *ProxyCtx)) { - pcond.proxy.httpsHandlers = append(pcond.proxy.httpsHandlers, - FuncHttpsHandler(func(host string, ctx *ProxyCtx) (*ConnectAction, string) { - for _, cond := range pcond.reqConds { - if !cond.HandleReq(ctx.Req, ctx) { - return nil, "" - } - } - return &ConnectAction{Action: ConnectHijack, Hijack: f}, host - })) -} - -// ProxyConds is used to aggregate RespConditions for a ProxyHttpServer. -// Upon calling ProxyConds.Do, it will register a RespHandler that would -// handle the HTTP response from remote server if all conditions on the HTTP response are met. -type ProxyConds struct { - proxy *ProxyHttpServer - reqConds []ReqCondition - respCond []RespCondition -} - -// ProxyConds.DoFunc is equivalent to proxy.OnResponse().Do(FuncRespHandler(f)) -func (pcond *ProxyConds) DoFunc(f func(resp *http.Response, ctx *ProxyCtx) *http.Response) { - pcond.Do(FuncRespHandler(f)) -} - -// ProxyConds.Do will register the RespHandler on the proxy, h.Handle(resp,ctx) will be called on every -// request that matches the conditions aggregated in pcond. -func (pcond *ProxyConds) Do(h RespHandler) { - pcond.proxy.respHandlers = append(pcond.proxy.respHandlers, - FuncRespHandler(func(resp *http.Response, ctx *ProxyCtx) *http.Response { - for _, cond := range pcond.reqConds { - if !cond.HandleReq(ctx.Req, ctx) { - return resp - } - } - for _, cond := range pcond.respCond { - if !cond.HandleResp(resp, ctx) { - return resp - } - } - return h.Handle(resp, ctx) - })) -} - -// OnResponse is used when adding a response-filter to the HTTP proxy, usual pattern is -// proxy.OnResponse(cond1,cond2).Do(handler) // handler.Handle(resp,ctx) will be used -// // if cond1.HandleResp(resp) && cond2.HandleResp(resp) -func (proxy *ProxyHttpServer) OnResponse(conds ...RespCondition) *ProxyConds { - return &ProxyConds{proxy, make([]ReqCondition, 0), conds} -} - -// AlwaysMitm is a HttpsHandler that always eavesdrop https connections, for example to -// eavesdrop all https connections to www.google.com, we can use -// proxy.OnRequest(goproxy.ReqHostIs("www.google.com")).HandleConnect(goproxy.AlwaysMitm) -var AlwaysMitm FuncHttpsHandler = func(host string, ctx *ProxyCtx) (*ConnectAction, string) { - return MitmConnect, host -} - -// AlwaysReject is a HttpsHandler that drops any CONNECT request, for example, this code will disallow -// connections to hosts on any other port than 443 -// proxy.OnRequest(goproxy.Not(goproxy.ReqHostMatches(regexp.MustCompile(":443$"))). -// HandleConnect(goproxy.AlwaysReject) -var AlwaysReject FuncHttpsHandler = func(host string, ctx *ProxyCtx) (*ConnectAction, string) { - return RejectConnect, host -} - -// HandleBytes will return a RespHandler that read the entire body of the request -// to a byte array in memory, would run the user supplied f function on the byte arra, -// and will replace the body of the original response with the resulting byte array. -func HandleBytes(f func(b []byte, ctx *ProxyCtx) []byte) RespHandler { - return FuncRespHandler(func(resp *http.Response, ctx *ProxyCtx) *http.Response { - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - ctx.Warnf("Cannot read response %s", err) - return resp - } - resp.Body.Close() - - resp.Body = ioutil.NopCloser(bytes.NewBuffer(f(b, ctx))) - return resp - }) -} diff --git a/vendor/github.com/elazarl/goproxy/doc.go b/vendor/github.com/elazarl/goproxy/doc.go deleted file mode 100644 index 50aaa71f8..000000000 --- a/vendor/github.com/elazarl/goproxy/doc.go +++ /dev/null @@ -1,100 +0,0 @@ -/* -Package goproxy provides a customizable HTTP proxy, -supporting hijacking HTTPS connection. - -The intent of the proxy, is to be usable with reasonable amount of traffic -yet, customizable and programable. - -The proxy itself is simply an `net/http` handler. - -Typical usage is - - proxy := goproxy.NewProxyHttpServer() - proxy.OnRequest(..conditions..).Do(..requesthandler..) - proxy.OnRequest(..conditions..).DoFunc(..requesthandlerFunction..) - proxy.OnResponse(..conditions..).Do(..responesHandler..) - proxy.OnResponse(..conditions..).DoFunc(..responesHandlerFunction..) - http.ListenAndServe(":8080", proxy) - -Adding a header to each request - - proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ - r.Header.Set("X-GoProxy","1") - return r, nil - }) - -Note that the function is called before the proxy sends the request to the server - -For printing the content type of all incoming responses - - proxy.OnResponse().DoFunc(func(r *http.Response, ctx *goproxy.ProxyCtx)*http.Response{ - println(ctx.Req.Host,"->",r.Header.Get("Content-Type")) - return r - }) - -note that we used the ProxyCtx context variable here. It contains the request -and the response (Req and Resp, Resp is nil if unavailable) of this specific client -interaction with the proxy. - -To print the content type of all responses from a certain url, we'll add a -ReqCondition to the OnResponse function: - - proxy.OnResponse(goproxy.UrlIs("golang.org/pkg")).DoFunc(func(r *http.Response, ctx *goproxy.ProxyCtx)*http.Response{ - println(ctx.Req.Host,"->",r.Header.Get("Content-Type")) - return r - }) - -We can write the condition ourselves, conditions can be set on request and on response - - var random = ReqConditionFunc(func(r *http.Request) bool { - return rand.Intn(1) == 0 - }) - var hasGoProxyHeader = RespConditionFunc(func(resp *http.Response,req *http.Request)bool { - return resp.Header.Get("X-GoProxy") != "" - }) - -Caution! If you give a RespCondition to the OnRequest function, you'll get a run time panic! It doesn't -make sense to read the response, if you still haven't got it! - -Finally, we have convenience function to throw a quick response - - proxy.OnResponse(hasGoProxyHeader).DoFunc(func(r*http.Response,ctx *goproxy.ProxyCtx)*http.Response { - r.Body.Close() - return goproxy.ForbiddenTextResponse(ctx.Req,"Can't see response with X-GoProxy header!") - }) - -we close the body of the original repsonse, and return a new 403 response with a short message. - -Example use cases: - -1. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-avgsize - -To measure the average size of an Html served in your site. One can ask -all the QA team to access the website by a proxy, and the proxy will -measure the average size of all text/html responses from your host. - -2. [not yet implemented] - -All requests to your web servers should be directed through the proxy, -when the proxy will detect html pieces sent as a response to AJAX -request, it'll send a warning email. - -3. https://github.com/elazarl/goproxy/blob/master/examples/goproxy-httpdump/ - -Generate a real traffic to your website by real users using through -proxy. Record the traffic, and try it again for more real load testing. - -4. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-no-reddit-at-worktime - -Will allow browsing to reddit.com between 8:00am and 17:00pm - -5. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-jquery-version - -Will warn if multiple versions of jquery are used in the same domain. - -6. https://github.com/elazarl/goproxy/blob/master/examples/goproxy-upside-down-ternet/ - -Modifies image files in an HTTP response via goproxy's image extension found in ext/. - -*/ -package goproxy diff --git a/vendor/github.com/elazarl/goproxy/https.go b/vendor/github.com/elazarl/goproxy/https.go deleted file mode 100644 index 12de7511d..000000000 --- a/vendor/github.com/elazarl/goproxy/https.go +++ /dev/null @@ -1,435 +0,0 @@ -package goproxy - -import ( - "bufio" - "crypto/tls" - "errors" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - "regexp" - "strconv" - "strings" - "sync" - "sync/atomic" -) - -type ConnectActionLiteral int - -const ( - ConnectAccept = iota - ConnectReject - ConnectMitm - ConnectHijack - ConnectHTTPMitm - ConnectProxyAuthHijack -) - -var ( - OkConnect = &ConnectAction{Action: ConnectAccept, TLSConfig: TLSConfigFromCA(&GoproxyCa)} - MitmConnect = &ConnectAction{Action: ConnectMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)} - HTTPMitmConnect = &ConnectAction{Action: ConnectHTTPMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)} - RejectConnect = &ConnectAction{Action: ConnectReject, TLSConfig: TLSConfigFromCA(&GoproxyCa)} - httpsRegexp = regexp.MustCompile(`^https:\/\/`) -) - -type ConnectAction struct { - Action ConnectActionLiteral - Hijack func(req *http.Request, client net.Conn, ctx *ProxyCtx) - TLSConfig func(host string, ctx *ProxyCtx) (*tls.Config, error) -} - -func stripPort(s string) string { - ix := strings.IndexRune(s, ':') - if ix == -1 { - return s - } - return s[:ix] -} - -func (proxy *ProxyHttpServer) dial(network, addr string) (c net.Conn, err error) { - if proxy.Tr.Dial != nil { - return proxy.Tr.Dial(network, addr) - } - return net.Dial(network, addr) -} - -func (proxy *ProxyHttpServer) connectDial(network, addr string) (c net.Conn, err error) { - if proxy.ConnectDial == nil { - return proxy.dial(network, addr) - } - return proxy.ConnectDial(network, addr) -} - -func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request) { - ctx := &ProxyCtx{Req: r, Session: atomic.AddInt64(&proxy.sess, 1), proxy: proxy, certStore: proxy.CertStore} - - hij, ok := w.(http.Hijacker) - if !ok { - panic("httpserver does not support hijacking") - } - - proxyClient, _, e := hij.Hijack() - if e != nil { - panic("Cannot hijack connection " + e.Error()) - } - - ctx.Logf("Running %d CONNECT handlers", len(proxy.httpsHandlers)) - todo, host := OkConnect, r.URL.Host - for i, h := range proxy.httpsHandlers { - newtodo, newhost := h.HandleConnect(host, ctx) - - // If found a result, break the loop immediately - if newtodo != nil { - todo, host = newtodo, newhost - ctx.Logf("on %dth handler: %v %s", i, todo, host) - break - } - } - switch todo.Action { - case ConnectAccept: - if !hasPort.MatchString(host) { - host += ":80" - } - targetSiteCon, err := proxy.connectDial("tcp", host) - if err != nil { - httpError(proxyClient, ctx, err) - return - } - ctx.Logf("Accepting CONNECT to %s", host) - proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) - - targetTCP, targetOK := targetSiteCon.(*net.TCPConn) - proxyClientTCP, clientOK := proxyClient.(*net.TCPConn) - if targetOK && clientOK { - go copyAndClose(ctx, targetTCP, proxyClientTCP) - go copyAndClose(ctx, proxyClientTCP, targetTCP) - } else { - go func() { - var wg sync.WaitGroup - wg.Add(2) - go copyOrWarn(ctx, targetSiteCon, proxyClient, &wg) - go copyOrWarn(ctx, proxyClient, targetSiteCon, &wg) - wg.Wait() - proxyClient.Close() - targetSiteCon.Close() - - }() - } - - case ConnectHijack: - ctx.Logf("Hijacking CONNECT to %s", host) - proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) - todo.Hijack(r, proxyClient, ctx) - case ConnectHTTPMitm: - proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) - ctx.Logf("Assuming CONNECT is plain HTTP tunneling, mitm proxying it") - targetSiteCon, err := proxy.connectDial("tcp", host) - if err != nil { - ctx.Warnf("Error dialing to %s: %s", host, err.Error()) - return - } - for { - client := bufio.NewReader(proxyClient) - remote := bufio.NewReader(targetSiteCon) - req, err := http.ReadRequest(client) - if err != nil && err != io.EOF { - ctx.Warnf("cannot read request of MITM HTTP client: %+#v", err) - } - if err != nil { - return - } - req, resp := proxy.filterRequest(req, ctx) - if resp == nil { - if err := req.Write(targetSiteCon); err != nil { - httpError(proxyClient, ctx, err) - return - } - resp, err = http.ReadResponse(remote, req) - if err != nil { - httpError(proxyClient, ctx, err) - return - } - defer resp.Body.Close() - } - resp = proxy.filterResponse(resp, ctx) - if err := resp.Write(proxyClient); err != nil { - httpError(proxyClient, ctx, err) - return - } - } - case ConnectMitm: - proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) - ctx.Logf("Assuming CONNECT is TLS, mitm proxying it") - // this goes in a separate goroutine, so that the net/http server won't think we're - // still handling the request even after hijacking the connection. Those HTTP CONNECT - // request can take forever, and the server will be stuck when "closed". - // TODO: Allow Server.Close() mechanism to shut down this connection as nicely as possible - tlsConfig := defaultTLSConfig - if todo.TLSConfig != nil { - var err error - tlsConfig, err = todo.TLSConfig(host, ctx) - if err != nil { - httpError(proxyClient, ctx, err) - return - } - } - go func() { - //TODO: cache connections to the remote website - rawClientTls := tls.Server(proxyClient, tlsConfig) - if err := rawClientTls.Handshake(); err != nil { - ctx.Warnf("Cannot handshake client %v %v", r.Host, err) - return - } - defer rawClientTls.Close() - clientTlsReader := bufio.NewReader(rawClientTls) - for !isEof(clientTlsReader) { - req, err := http.ReadRequest(clientTlsReader) - var ctx = &ProxyCtx{Req: req, Session: atomic.AddInt64(&proxy.sess, 1), proxy: proxy, UserData: ctx.UserData} - if err != nil && err != io.EOF { - return - } - if err != nil { - ctx.Warnf("Cannot read TLS request from mitm'd client %v %v", r.Host, err) - return - } - req.RemoteAddr = r.RemoteAddr // since we're converting the request, need to carry over the original connecting IP as well - ctx.Logf("req %v", r.Host) - - if !httpsRegexp.MatchString(req.URL.String()) { - req.URL, err = url.Parse("https://" + r.Host + req.URL.String()) - } - - // Bug fix which goproxy fails to provide request - // information URL in the context when does HTTPS MITM - ctx.Req = req - - req, resp := proxy.filterRequest(req, ctx) - if resp == nil { - if err != nil { - ctx.Warnf("Illegal URL %s", "https://"+r.Host+req.URL.Path) - return - } - removeProxyHeaders(ctx, req) - resp, err = ctx.RoundTrip(req) - if err != nil { - ctx.Warnf("Cannot read TLS response from mitm'd server %v", err) - return - } - ctx.Logf("resp %v", resp.Status) - } - resp = proxy.filterResponse(resp, ctx) - defer resp.Body.Close() - - text := resp.Status - statusCode := strconv.Itoa(resp.StatusCode) + " " - if strings.HasPrefix(text, statusCode) { - text = text[len(statusCode):] - } - // always use 1.1 to support chunked encoding - if _, err := io.WriteString(rawClientTls, "HTTP/1.1"+" "+statusCode+text+"\r\n"); err != nil { - ctx.Warnf("Cannot write TLS response HTTP status from mitm'd client: %v", err) - return - } - // Since we don't know the length of resp, return chunked encoded response - // TODO: use a more reasonable scheme - resp.Header.Del("Content-Length") - resp.Header.Set("Transfer-Encoding", "chunked") - // Force connection close otherwise chrome will keep CONNECT tunnel open forever - resp.Header.Set("Connection", "close") - if err := resp.Header.Write(rawClientTls); err != nil { - ctx.Warnf("Cannot write TLS response header from mitm'd client: %v", err) - return - } - if _, err = io.WriteString(rawClientTls, "\r\n"); err != nil { - ctx.Warnf("Cannot write TLS response header end from mitm'd client: %v", err) - return - } - chunked := newChunkedWriter(rawClientTls) - if _, err := io.Copy(chunked, resp.Body); err != nil { - ctx.Warnf("Cannot write TLS response body from mitm'd client: %v", err) - return - } - if err := chunked.Close(); err != nil { - ctx.Warnf("Cannot write TLS chunked EOF from mitm'd client: %v", err) - return - } - if _, err = io.WriteString(rawClientTls, "\r\n"); err != nil { - ctx.Warnf("Cannot write TLS response chunked trailer from mitm'd client: %v", err) - return - } - } - ctx.Logf("Exiting on EOF") - }() - case ConnectProxyAuthHijack: - proxyClient.Write([]byte("HTTP/1.1 407 Proxy Authentication Required\r\n")) - todo.Hijack(r, proxyClient, ctx) - case ConnectReject: - if ctx.Resp != nil { - if err := ctx.Resp.Write(proxyClient); err != nil { - ctx.Warnf("Cannot write response that reject http CONNECT: %v", err) - } - } - proxyClient.Close() - } -} - -func httpError(w io.WriteCloser, ctx *ProxyCtx, err error) { - if _, err := io.WriteString(w, "HTTP/1.1 502 Bad Gateway\r\n\r\n"); err != nil { - ctx.Warnf("Error responding to client: %s", err) - } - if err := w.Close(); err != nil { - ctx.Warnf("Error closing client connection: %s", err) - } -} - -func copyOrWarn(ctx *ProxyCtx, dst io.Writer, src io.Reader, wg *sync.WaitGroup) { - if _, err := io.Copy(dst, src); err != nil { - ctx.Warnf("Error copying to client: %s", err) - } - wg.Done() -} - -func copyAndClose(ctx *ProxyCtx, dst, src *net.TCPConn) { - if _, err := io.Copy(dst, src); err != nil { - ctx.Warnf("Error copying to client: %s", err) - } - - dst.CloseWrite() - src.CloseRead() -} - -func dialerFromEnv(proxy *ProxyHttpServer) func(network, addr string) (net.Conn, error) { - https_proxy := os.Getenv("HTTPS_PROXY") - if https_proxy == "" { - https_proxy = os.Getenv("https_proxy") - } - if https_proxy == "" { - return nil - } - return proxy.NewConnectDialToProxy(https_proxy) -} - -func (proxy *ProxyHttpServer) NewConnectDialToProxy(https_proxy string) func(network, addr string) (net.Conn, error) { - return proxy.NewConnectDialToProxyWithHandler(https_proxy, nil) -} - -func (proxy *ProxyHttpServer) NewConnectDialToProxyWithHandler(https_proxy string, connectReqHandler func(req *http.Request)) func(network, addr string) (net.Conn, error) { - u, err := url.Parse(https_proxy) - if err != nil { - return nil - } - if u.Scheme == "" || u.Scheme == "http" { - if strings.IndexRune(u.Host, ':') == -1 { - u.Host += ":80" - } - return func(network, addr string) (net.Conn, error) { - connectReq := &http.Request{ - Method: "CONNECT", - URL: &url.URL{Opaque: addr}, - Host: addr, - Header: make(http.Header), - } - if connectReqHandler != nil { - connectReqHandler(connectReq) - } - c, err := proxy.dial(network, u.Host) - if err != nil { - return nil, err - } - connectReq.Write(c) - // Read response. - // Okay to use and discard buffered reader here, because - // TLS server will not speak until spoken to. - br := bufio.NewReader(c) - resp, err := http.ReadResponse(br, connectReq) - if err != nil { - c.Close() - return nil, err - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - resp, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - c.Close() - return nil, errors.New("proxy refused connection" + string(resp)) - } - return c, nil - } - } - if u.Scheme == "https" { - if strings.IndexRune(u.Host, ':') == -1 { - u.Host += ":443" - } - return func(network, addr string) (net.Conn, error) { - c, err := proxy.dial(network, u.Host) - if err != nil { - return nil, err - } - c = tls.Client(c, proxy.Tr.TLSClientConfig) - connectReq := &http.Request{ - Method: "CONNECT", - URL: &url.URL{Opaque: addr}, - Host: addr, - Header: make(http.Header), - } - if connectReqHandler != nil { - connectReqHandler(connectReq) - } - connectReq.Write(c) - // Read response. - // Okay to use and discard buffered reader here, because - // TLS server will not speak until spoken to. - br := bufio.NewReader(c) - resp, err := http.ReadResponse(br, connectReq) - if err != nil { - c.Close() - return nil, err - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 500)) - if err != nil { - return nil, err - } - c.Close() - return nil, errors.New("proxy refused connection" + string(body)) - } - return c, nil - } - } - return nil -} - -func TLSConfigFromCA(ca *tls.Certificate) func(host string, ctx *ProxyCtx) (*tls.Config, error) { - return func(host string, ctx *ProxyCtx) (*tls.Config, error) { - var err error - var cert *tls.Certificate - - hostname := stripPort(host) - config := *defaultTLSConfig - ctx.Logf("signing for %s", stripPort(host)) - - genCert := func() (*tls.Certificate, error) { - return signHost(*ca, []string{hostname}) - } - if ctx.certStore != nil { - cert, err = ctx.certStore.Fetch(hostname, genCert) - } else { - cert, err = genCert() - } - - if err != nil { - ctx.Warnf("Cannot sign host certificate with provided CA: %s", err) - return nil, err - } - - config.Certificates = append(config.Certificates, *cert) - return &config, nil - } -} diff --git a/vendor/github.com/elazarl/goproxy/key.pem b/vendor/github.com/elazarl/goproxy/key.pem deleted file mode 100644 index 2ea1dca4e..000000000 --- a/vendor/github.com/elazarl/goproxy/key.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/vendor/github.com/elazarl/goproxy/logger.go b/vendor/github.com/elazarl/goproxy/logger.go deleted file mode 100644 index 939cf69ed..000000000 --- a/vendor/github.com/elazarl/goproxy/logger.go +++ /dev/null @@ -1,5 +0,0 @@ -package goproxy - -type Logger interface { - Printf(format string, v ...interface{}) -} diff --git a/vendor/github.com/elazarl/goproxy/proxy.go b/vendor/github.com/elazarl/goproxy/proxy.go deleted file mode 100644 index 175851615..000000000 --- a/vendor/github.com/elazarl/goproxy/proxy.go +++ /dev/null @@ -1,167 +0,0 @@ -package goproxy - -import ( - "bufio" - "io" - "log" - "net" - "net/http" - "os" - "regexp" - "sync/atomic" -) - -// The basic proxy type. Implements http.Handler. -type ProxyHttpServer struct { - // session variable must be aligned in i386 - // see http://golang.org/src/pkg/sync/atomic/doc.go#L41 - sess int64 - // KeepDestinationHeaders indicates the proxy should retain any headers present in the http.Response before proxying - KeepDestinationHeaders bool - // setting Verbose to true will log information on each request sent to the proxy - Verbose bool - Logger Logger - NonproxyHandler http.Handler - reqHandlers []ReqHandler - respHandlers []RespHandler - httpsHandlers []HttpsHandler - Tr *http.Transport - // ConnectDial will be used to create TCP connections for CONNECT requests - // if nil Tr.Dial will be used - ConnectDial func(network string, addr string) (net.Conn, error) - CertStore CertStorage -} - -var hasPort = regexp.MustCompile(`:\d+$`) - -func copyHeaders(dst, src http.Header, keepDestHeaders bool) { - if !keepDestHeaders { - for k := range dst { - dst.Del(k) - } - } - for k, vs := range src { - for _, v := range vs { - dst.Add(k, v) - } - } -} - -func isEof(r *bufio.Reader) bool { - _, err := r.Peek(1) - if err == io.EOF { - return true - } - return false -} - -func (proxy *ProxyHttpServer) filterRequest(r *http.Request, ctx *ProxyCtx) (req *http.Request, resp *http.Response) { - req = r - for _, h := range proxy.reqHandlers { - req, resp = h.Handle(r, ctx) - // non-nil resp means the handler decided to skip sending the request - // and return canned response instead. - if resp != nil { - break - } - } - return -} -func (proxy *ProxyHttpServer) filterResponse(respOrig *http.Response, ctx *ProxyCtx) (resp *http.Response) { - resp = respOrig - for _, h := range proxy.respHandlers { - ctx.Resp = resp - resp = h.Handle(resp, ctx) - } - return -} - -func removeProxyHeaders(ctx *ProxyCtx, r *http.Request) { - r.RequestURI = "" // this must be reset when serving a request with the client - ctx.Logf("Sending request %v %v", r.Method, r.URL.String()) - // If no Accept-Encoding header exists, Transport will add the headers it can accept - // and would wrap the response body with the relevant reader. - r.Header.Del("Accept-Encoding") - // curl can add that, see - // https://jdebp.eu./FGA/web-proxy-connection-header.html - r.Header.Del("Proxy-Connection") - r.Header.Del("Proxy-Authenticate") - r.Header.Del("Proxy-Authorization") - // Connection, Authenticate and Authorization are single hop Header: - // http://www.w3.org/Protocols/rfc2616/rfc2616.txt - // 14.10 Connection - // The Connection general-header field allows the sender to specify - // options that are desired for that particular connection and MUST NOT - // be communicated by proxies over further connections. - r.Header.Del("Connection") -} - -// Standard net/http function. Shouldn't be used directly, http.Serve will use it. -func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { - //r.Header["X-Forwarded-For"] = w.RemoteAddr() - if r.Method == "CONNECT" { - proxy.handleHttps(w, r) - } else { - ctx := &ProxyCtx{Req: r, Session: atomic.AddInt64(&proxy.sess, 1), proxy: proxy} - - var err error - ctx.Logf("Got request %v %v %v %v", r.URL.Path, r.Host, r.Method, r.URL.String()) - if !r.URL.IsAbs() { - proxy.NonproxyHandler.ServeHTTP(w, r) - return - } - r, resp := proxy.filterRequest(r, ctx) - - if resp == nil { - removeProxyHeaders(ctx, r) - resp, err = ctx.RoundTrip(r) - if err != nil { - ctx.Error = err - resp = proxy.filterResponse(nil, ctx) - if resp == nil { - ctx.Logf("error read response %v %v:", r.URL.Host, err.Error()) - http.Error(w, err.Error(), 500) - return - } - } - ctx.Logf("Received response %v", resp.Status) - } - origBody := resp.Body - resp = proxy.filterResponse(resp, ctx) - defer origBody.Close() - ctx.Logf("Copying response to client %v [%d]", resp.Status, resp.StatusCode) - // http.ResponseWriter will take care of filling the correct response length - // Setting it now, might impose wrong value, contradicting the actual new - // body the user returned. - // We keep the original body to remove the header only if things changed. - // This will prevent problems with HEAD requests where there's no body, yet, - // the Content-Length header should be set. - if origBody != resp.Body { - resp.Header.Del("Content-Length") - } - copyHeaders(w.Header(), resp.Header, proxy.KeepDestinationHeaders) - w.WriteHeader(resp.StatusCode) - nr, err := io.Copy(w, resp.Body) - if err := resp.Body.Close(); err != nil { - ctx.Warnf("Can't close response body %v", err) - } - ctx.Logf("Copied %v bytes to client error=%v", nr, err) - } -} - -// NewProxyHttpServer creates and returns a proxy server, logging to stderr by default -func NewProxyHttpServer() *ProxyHttpServer { - proxy := ProxyHttpServer{ - Logger: log.New(os.Stderr, "", log.LstdFlags), - reqHandlers: []ReqHandler{}, - respHandlers: []RespHandler{}, - httpsHandlers: []HttpsHandler{}, - NonproxyHandler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - http.Error(w, "This is a proxy server. Does not respond to non-proxy requests.", 500) - }), - Tr: &http.Transport{TLSClientConfig: tlsClientSkipVerify, Proxy: http.ProxyFromEnvironment}, - } - proxy.ConnectDial = dialerFromEnv(&proxy) - - return &proxy -} diff --git a/vendor/github.com/elazarl/goproxy/responses.go b/vendor/github.com/elazarl/goproxy/responses.go deleted file mode 100644 index e1bf28fc2..000000000 --- a/vendor/github.com/elazarl/goproxy/responses.go +++ /dev/null @@ -1,39 +0,0 @@ -package goproxy - -import ( - "bytes" - "io/ioutil" - "net/http" -) - -// Will generate a valid http response to the given request the response will have -// the given contentType, and http status. -// Typical usage, refuse to process requests to local addresses: -// -// proxy.OnRequest(IsLocalHost()).DoFunc(func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request,*http.Response) { -// return nil,NewResponse(r,goproxy.ContentTypeHtml,http.StatusUnauthorized, -// `Can't use proxy for local addresses`) -// }) -func NewResponse(r *http.Request, contentType string, status int, body string) *http.Response { - resp := &http.Response{} - resp.Request = r - resp.TransferEncoding = r.TransferEncoding - resp.Header = make(http.Header) - resp.Header.Add("Content-Type", contentType) - resp.StatusCode = status - resp.Status = http.StatusText(status) - buf := bytes.NewBufferString(body) - resp.ContentLength = int64(buf.Len()) - resp.Body = ioutil.NopCloser(buf) - return resp -} - -const ( - ContentTypeText = "text/plain" - ContentTypeHtml = "text/html" -) - -// Alias for NewResponse(r,ContentTypeText,http.StatusAccepted,text) -func TextResponse(r *http.Request, text string) *http.Response { - return NewResponse(r, ContentTypeText, http.StatusAccepted, text) -} diff --git a/vendor/github.com/elazarl/goproxy/signer.go b/vendor/github.com/elazarl/goproxy/signer.go deleted file mode 100644 index 11a98de45..000000000 --- a/vendor/github.com/elazarl/goproxy/signer.go +++ /dev/null @@ -1,88 +0,0 @@ -package goproxy - -import ( - "crypto/rsa" - "crypto/sha1" - "crypto/tls" - "crypto/x509" - "crypto/x509/pkix" - "math/big" - "net" - "runtime" - "sort" - "time" -) - -func hashSorted(lst []string) []byte { - c := make([]string, len(lst)) - copy(c, lst) - sort.Strings(c) - h := sha1.New() - for _, s := range c { - h.Write([]byte(s + ",")) - } - return h.Sum(nil) -} - -func hashSortedBigInt(lst []string) *big.Int { - rv := new(big.Int) - rv.SetBytes(hashSorted(lst)) - return rv -} - -var goproxySignerVersion = ":goroxy1" - -func signHost(ca tls.Certificate, hosts []string) (cert *tls.Certificate, err error) { - var x509ca *x509.Certificate - - // Use the provided ca and not the global GoproxyCa for certificate generation. - if x509ca, err = x509.ParseCertificate(ca.Certificate[0]); err != nil { - return - } - start := time.Unix(0, 0) - end, err := time.Parse("2006-01-02", "2049-12-31") - if err != nil { - panic(err) - } - hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version())) - serial := new(big.Int) - serial.SetBytes(hash) - template := x509.Certificate{ - // TODO(elazar): instead of this ugly hack, just encode the certificate and hash the binary form. - SerialNumber: serial, - Issuer: x509ca.Subject, - Subject: pkix.Name{ - Organization: []string{"GoProxy untrusted MITM proxy Inc"}, - }, - NotBefore: start, - NotAfter: end, - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - } - for _, h := range hosts { - if ip := net.ParseIP(h); ip != nil { - template.IPAddresses = append(template.IPAddresses, ip) - } else { - template.DNSNames = append(template.DNSNames, h) - template.Subject.CommonName = h - } - } - var csprng CounterEncryptorRand - if csprng, err = NewCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil { - return - } - var certpriv *rsa.PrivateKey - if certpriv, err = rsa.GenerateKey(&csprng, 2048); err != nil { - return - } - var derBytes []byte - if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, &certpriv.PublicKey, ca.PrivateKey); err != nil { - return - } - return &tls.Certificate{ - Certificate: [][]byte{derBytes, ca.Certificate[0]}, - PrivateKey: certpriv, - }, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7291ede95..47f136184 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -33,11 +33,6 @@ github.com/cespare/xxhash/v2 # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f -## explicit -github.com/elazarl/goproxy -# github.com/elazarl/goproxy/ext v0.0.0-20240909085733-6741dbfc16a1 -## explicit # github.com/emicklei/go-restful/v3 v3.11.0 ## explicit; go 1.13 github.com/emicklei/go-restful/v3