{"id":1404,"date":"2016-09-07T10:52:47","date_gmt":"2016-09-07T14:52:47","guid":{"rendered":"http:\/\/blog.jonesling.us\/?p=1404"},"modified":"2016-09-07T12:46:18","modified_gmt":"2016-09-07T16:46:18","slug":"nifi-http-service","status":"publish","type":"post","link":"https:\/\/blog.jonesling.us\/?p=1404","title":{"rendered":"NiFi HTTP Service"},"content":{"rendered":"<p>I&#8217;m attempting to set up an HTTP server in NiFi to accept uploads and process them on-demand.\u00a0 This gets tricky because I want to submit the files using an existing web application that will not be served from NiFi, which leads to trouble with XSS (Cross-Site Scripting) and setting up CORS (Cross Origin Resource Sharing [<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Access_control_CORS\" target=\"_blank\">1<\/a>]).<\/p>\n<p>The trouble starts with just trying to <code>PUT<\/code> or <code>POST<\/code> a simple file.\u00a0 The error in Firefox reads:<\/p>\n<pre>Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource (Reason: CORS header 'Access-Control-Allow-Origin' missing).<\/pre>\n<p>You can serve up the Javascript that actually performs the upload from NiFi and side-step XSS, but you may still run into trouble with CORS.\u00a0 You&#8217;ll have trouble even if NiFi and your other web server live on the same host (using different ports, of course), as they&#8217;re considered different hosts for the purposes of XSS prevention.<\/p>\n<figure id=\"attachment_1405\" aria-describedby=\"caption-attachment-1405\" style=\"width: 300px\" class=\"wp-caption alignright\"><a href=\"http:\/\/blog.jonesling.us\/wp-content\/uploads\/2016\/09\/HandleHttpResponse.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1405\" src=\"\/\/blog.jonesling.us\/wp-content\/uploads\/2016\/09\/HandleHttpResponse-300x170.png\" alt=\"handlehttpresponse screen shot\" width=\"300\" height=\"170\" srcset=\"https:\/\/blog.jonesling.us\/wp-content\/uploads\/2016\/09\/HandleHttpResponse-300x170.png 300w, https:\/\/blog.jonesling.us\/wp-content\/uploads\/2016\/09\/HandleHttpResponse-768x435.png 768w, https:\/\/blog.jonesling.us\/wp-content\/uploads\/2016\/09\/HandleHttpResponse.png 804w\" sizes=\"auto, (max-width: 300px) 85vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1405\" class=\"wp-caption-text\">HandleHttpResponse processor config<\/figcaption><\/figure>\n<p>To make this work, you&#8217;ll need to enable specific headers in the HandleHttpResponse processor.\u00a0 Neither the need to set some headers, nor the headers that need to be set, are documented by NiFi at this time (so far as I can tell).<\/p>\n<ol>\n<li>Open the configuration of the HandleHttpResponse processor<\/li>\n<li>Add the following headers and values as properties and values, but see below for notes regarding the values\n<pre><code>Access-Control-Allow-Origin: *\n\nAccess-Control-Allow-Methods: PUT, POST, GET, OPTIONS\n\nAccess-Control-Allow-Headers: Accept, Accept-Encoding, Accept-Language, Connection, Content-Length, Content-Type, DNT, Host, Referer, User-Agent, Origin, X-Forwarded-For<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>You may want to review the value for <code>Access-Control-Allow-Origin<\/code>, as the wildcard may allow access to unexpected hosts.\u00a0 If your server is public-facing (why would you do that with NiFi?) then you certainly don&#8217;t want a wildcard here.\u00a0 The wildcard makes configuration much simpler if NiFi is strictly interior-facing, though.<\/p>\n<p>The specific values to set for <code>Access-Control-Allow-Methods<\/code> depend on what you&#8217;re doing.\u00a0 You&#8217;ll probably need <code>OPTIONS<\/code> for most cases.\u00a0 I&#8217;m serving up static files so I need <code>GET<\/code>, and I&#8217;m receiving uploads that may or may not be chunked, so I need <code>POST<\/code> and <code>PUT<\/code>.<\/p>\n<p>The actual headers needed for <code>Access-Control-Allow-Headers<\/code> is a bit variable.\u00a0 A wildcard is not an acceptable value here, so you&#8217;ll have to list every header you need separately\u00a0\u2014 and there are a bunch of possible headers.\u00a0 See [<a href=\"http:\/\/stackoverflow.com\/questions\/13146892\/cors-access-control-allow-headers-wildcard-being-ignored\" target=\"_blank\">3<\/a>] for an explanation and a fairly comprehensive list of possible headers.\u00a0 Our list contains a small subset that covers our basic test cases; your mileage may vary.<\/p>\n<p>You may also want to set up a <code>RouteOnAttribute<\/code> processor to ignore <code>OPTIONS<\/code> requests (<code>${http.method:equals('OPTIONS')}<\/code>), otherwise you might see a bunch of zero-byte files in your flow.<\/p>\n<p><strong>References:<\/strong><\/p>\n<p>[1] <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Access_control_CORS\" target=\"_blank\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Access_control_CORS<\/a><\/p>\n<p>[2] <a href=\"http:\/\/stackoverflow.com\/questions\/24371734\/firefox-cors-request-giving-cross-origin-request-blocked-despite-headers\" target=\"_blank\">http:\/\/stackoverflow.com\/questions\/24371734\/firefox-cors-request-giving-cross-origin-request-blocked-despite-headers<\/a><\/p>\n<p>[3] <a href=\"http:\/\/stackoverflow.com\/questions\/13146892\/cors-access-control-allow-headers-wildcard-being-ignored\" target=\"_blank\">http:\/\/stackoverflow.com\/questions\/13146892\/cors-access-control-allow-headers-wildcard-being-ignored<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m attempting to set up an HTTP server in NiFi to accept uploads and process them on-demand.\u00a0 This gets tricky because I want to submit the files using an existing web application that will not be served from NiFi, which leads to trouble with XSS (Cross-Site Scripting) and setting up CORS (Cross Origin Resource Sharing &hellip; <a href=\"https:\/\/blog.jonesling.us\/?p=1404\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;NiFi HTTP Service&#8221;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","wprm-recipe-roundup-name":"","wprm-recipe-roundup-description":"","advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[9],"tags":[295,294,296,151,277,298,300,83,267,299,297],"class_list":["post-1404","post","type-post","status-publish","format-standard","hentry","category-linux","tag-cors","tag-cross-origin-resource-sharing","tag-cross-site-scripting","tag-dad-needs-to-stop-bringing-work-home","tag-errors","tag-handlehttpresponse","tag-http","tag-linux","tag-nifi","tag-routeonattribute","tag-xss"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4o3FW-mE","jetpack-related-posts":[],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts\/1404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1404"}],"version-history":[{"count":9,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts\/1404\/revisions"}],"predecessor-version":[{"id":1414,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=\/wp\/v2\/posts\/1404\/revisions\/1414"}],"wp:attachment":[{"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jonesling.us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}