[
https://issues.apache.org/jira/browse/NIFI-15692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18067770#comment-18067770
]
Ivan Majsinger edited comment on NIFI-15692 at 3/23/26 5:38 PM:
----------------------------------------------------------------
=== RECOMMENDED RESPONSE TO DAVID ===
Hi David,
Thank you for reviewing this. After working with the network team, we
identified the actual root cause.
**This is NOT a reverse proxy configuration issue - it's an invalid HTTP
header.**
The `getRawFile()` method sends `Accept: *` which is **invalid per RFC 7231
(HTTP/1.1 Semantics)**. The correct header is `Accept: */*`.
When GitLab is behind a WAF (Web Application Firewall) that validates HTTP
headers - a security best practice in enterprise environments - the WAF
correctly rejects this malformed header with 403 Forbidden.
**Why other NiFi operations work:**
- `createContent()`, `deleteFile()`, `getFile()` → send correct `Accept: */*` ✓
- Only `getRawFile()` → sends invalid `Accept: *` ✗
This is why verification passes but flow registration fails.
**Why the fix won't be "easily lost":**
The fix improves compatibility with:
- Enterprise environments with WAF
- Security-hardened GitLab deployments
- Any environment with HTTP header validation (increasingly common)
This is not a niche edge case - it affects any production environment with
proper security controls.
**Why the fix is correct:**
Using `getFile()` + Base64 decode:
1. Sends correct `Accept: */*` header (RFC 7231 compliant)
2. Uses standard GitLab API endpoint
3. Returns identical content
4. No performance impact
5. Works with both security-hardened and standard environments
**Reproducible test case:**
You can verify this with any HTTP header validator:
```bash
# Invalid header (what NiFi currently sends):
curl -H "Accept: *" https://any-gitlab/api/v4/.../raw
# Blocked by WAF with strict HTTP validation
# Valid header (what the fix sends):
curl -H "Accept: */*" https://any-gitlab/api/v4/.../raw
# Works everywhere
```
**Alternative:**
If you prefer, the issue could be fixed in gitlab4j-api library itself.
However, that would:
1. Take longer to reach NiFi users
2. Require NiFi to upgrade the dependency
3. Leave current NiFi versions broken in security-hardened environments
The proposed fix is simple, safe, and provides immediate value.
**Would you like me to provide a pull request with the fix?**
Best regards,
Ivan
---
P.S. The error message "Apache Server at ... Port 80" is misleading - it's the
WAF's error response template, not an indication of a redirect. The WAF blocks
the request before it reaches GitLab.
was (Author: JIRAUSER312697):
Hi David,
Thank you for reviewing this. After working with the network team, we
identified the actual root cause.
{*}{{*}}This is NOT a reverse proxy configuration issue - it's an invalid HTTP
header *
The `getRawFile()` method sends `Accept: {*}` which is **invalid per RFC 7231
(HTTP/1.1 Semantics){*}{*}. The correct header is `Accept: */ *{*} `.
When GitLab is behind a WAF (Web Application Firewall) that validates HTTP
headers - a security best practice in enterprise environments - the WAF
correctly rejects this malformed header with 403 Forbidden.
{*}{{*}}Why other NiFi operations work:{
- `createContent()`, `deleteFile()`, `getFile()` → send correct `Accept: */ *`
✓
- Only `getRawFile()` → sends invalid `Accept: *` ✗
This is why verification passes but flow registration fails.
{*}{{*}}Why the fix won't be "easily lost":{{*}}{*}
The fix improves compatibility with:
- Enterprise environments with WAF
- Security-hardened GitLab deployments
- Any environment with HTTP header validation (increasingly common)
This is not a niche edge case - it affects any production environment with
proper security controls.
{*}{{*}}Why the fix is correct:{{*}}{*}
Using `getFile()` + Base64 decode:
1. Sends correct `Accept: {*}/{*}` header (RFC 7231 compliant)
2. Uses standard GitLab API endpoint
3. Returns identical content
4. No performance impact
5. Works with both security-hardened and standard environments
{*}{{*}}Reproducible test case:{{*}}{*}
You can verify this with any HTTP header validator:
```bash
# Invalid header (what NiFi currently sends):
curl -H "Accept: *" [https://any-gitlab/api/v4/.../raw]
# Blocked by WAF with strict HTTP validation
# Valid header (what the fix sends):
curl -H "Accept: {*}/{*}" [https://any-gitlab/api/v4/.../raw]
# Works everywhere
```
{*}{{*}}Alternative:{{*}}{*}
If you prefer, the issue could be fixed in gitlab4j-api library itself.
However, that would:
1. Take longer to reach NiFi users
2. Require NiFi to upgrade the dependency
3. Leave current NiFi versions broken in security-hardened environments
The proposed fix is simple, safe, and provides immediate value.
Best regards,
Ivan
—
P.S. The error message "Apache Server at ... Port 80" is misleading - it's the
WAF's error response template, not an indication of a redirect. The WAF blocks
the request before it reaches GitLab.
> GitLabRepositoryClient.deleteContent() fails with 403 when GitLab is behind
> reverse proxy due to getRawFile() usage
> -------------------------------------------------------------------------------------------------------------------
>
> Key: NIFI-15692
> URL: https://issues.apache.org/jira/browse/NIFI-15692
> Project: Apache NiFi
> Issue Type: Bug
> Components: Extensions
> Affects Versions: 2.7.2
> Reporter: Ivan Majsinger
> Assignee: Pierre Villard
> Priority: Major
> Time Spent: 50m
> Remaining Estimate: 0h
>
> h3. Problem
> GitLabFlowRegistryClient fails to register flow snapshots when GitLab is
> behind an Apache reverse proxy. The verification passes all checks, but
> "Start Version Control" fails with 403 Forbidden.
> h3. Root Cause
> The \{{deleteContent()}} method in \{{GitLabRepositoryClient.java}} uses
> \{{getRawFile()}} which hits the
> \{{/api/v4/projects/.../repository/files/.../raw}} endpoint. This endpoint is
> handled differently by some reverse proxies, causing a redirect to HTTP port
> 80 where authentication fails.
> {code:java}
> // Current implementation (line ~266)
> public InputStream deleteContent(...) {
> return execute(() -> {
> final InputStream content =
> gitLab.getRepositoryFileApi().getRawFile(...); // FAILS HERE
> gitLab.getRepositoryFileApi().deleteFile(...);
> return content;
> });
> }
> {code}
> h3. Error
> {code}
> org.gitlab4j.api.GitLabApiException:
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
> <html><head><title>403 Forbidden</title></head><body>
> <h1>Forbidden</h1>
> <p>You don't have permission to access this resource.</p>
> <address>Apache Server at [hostname] Port 80</address>
> </body></html>
> at
> org.gitlab4j.api.RepositoryFileApi.getRawFile(RepositoryFileApi.java:422)
> at org.apache.nifi.gitlab.GitLabRepositoryClient.lambda$deleteContent$8
> {code}
> h3. Proposed Fix
> Use \{{getFile()}} instead of \{{getRawFile()}}. The \{{getFile()}} method
> uses the standard \{{/api/v4/projects/.../repository/files/...}} endpoint
> (without \{{/raw}}) which returns Base64-encoded content and works correctly
> behind reverse proxies.
> {code:java}
> // Proposed fix
> public InputStream deleteContent(...) {
> return execute(() -> {
> RepositoryFile file =
> gitLab.getRepositoryFileApi().getFile(projectPath, resolvedPath, branch);
> byte[] content = Base64.getDecoder().decode(file.getContent());
> gitLab.getRepositoryFileApi().deleteFile(...);
> return new ByteArrayInputStream(content);
> });
> }
> {code}
> h3. Related
> - gitlab4j-api issue: https://github.com/gmessner/gitlab4j-api/issues/282
> h3. Environment
> - NiFi 2.7.0
> - GitLab behind Apache reverse proxy
--
This message was sent by Atlassian Jira
(v8.20.10#820010)