You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I didn't want any search engines to crawl the blog on a different domain, in case they find it. So I added the noindex meta tag, and then stripped it from the proxied response.
This still gave me the same error when trying it locally. The curl request would hang, and then give me the error:
curl: (18) transfer closed with 34 bytes remaining to read
So I went back to #41 and tried adding the #finish method as well. That didn't work - when I called to_s on the body, this already closes the HTTP session.
At this point I double-checked to make sure my code was causing the issue. I just returned the original instance of Rack::HttpStreamingResponse, and this worked fine (the curl request completed normally.)
But this had the same issue. When I returned the original string, everything worked. When I removed the meta tag, the curl request hung, and it also didn't work in the browser.
Then I finally realized that it was because I was sending the original Content-Length header! I was removing bytes from the response, and curl was still waiting for me to send them.
I tried deleting the Content-Length header to see if Rack would recreate it, but it just sent "Content-Length: 0".
So I finally got it working by calling: headers['Content-Length'] = replaced_body.length.to_s
Then I also realized that I was doing this for HEAD requests with curl -I, which set the Content-Length to 0 (because body was an empty string), so that also needed to be fixed. I was able to find the request method by calling body.instance_variable_get('@request').method, and then checking that it equals GET. (Then this actually returns the wrong Content-Length, because it doesn't know about the removed bytes. I don't know if this really matters, since browsers will only be making GET requests.)
Here's the working code:
classBlogProxyMatcherAndTransformerdefself.match(path)ifpath.match?(/^\/blog\//)returnBlogProxyMatcherAndTransformer.newendfalseenddefurl(path)blog_path=path.sub(/^\/blog\//,'/')[ENV['BLOG_ROOT_URL'],blog_path].join('')enddeftransform(response,request_uri)Rails.logger.info"[rack-reverse-proxy]: #{request_uri}"status,headers,body=responseheaders['Cache-Control']='public, max-age=31464028'headers['Expires']=1.year.from_now.httpdatemethod=body.instance_variable_get('@request').method# Ignore HEAD requests and anything that's not HTMLunlessmethod == 'GET' && headers['Content-Type']&.include?('text/html')returnresponseendreplaced_body=body.to_s.gsub(/<meta name="?robots"? content="?noindex"?>/,'')# IMPORTANT: Also update the content length!headers['Content-Length']=replaced_body.length.to_s[status,headers,[replaced_body]]endendreverse_proxyBlogProxyMatcherAndTransformer
The text was updated successfully, but these errors were encountered:
Just posting this here in case someone runs into the same issue. This is kind of related to #36.
TL:DR; If you're going to change the body, make sure you update the
Content-Length
header!I found #51 and 2a0174f, so I followed the example in the test and set up my own matcher/transformer class like this:
I didn't want any search engines to crawl the blog on a different domain, in case they find it. So I added the
noindex
meta tag, and then stripped it from the proxied response.I found the StringIO example in this comment and thought I'd try that (but I wasn't calling
target_response.send(:session).finish
.)I tried this out, but was getting errors on staging:
Also:
Then I saw that I could just use a plain array (in #36), so I tried that.
This still gave me the same error when trying it locally. The
curl
request would hang, and then give me the error:So I went back to #41 and tried adding the
#finish
method as well. That didn't work - when I calledto_s
on the body, this already closes the HTTP session.I started looking at rack-proxy. Realized why
#to_s
was closing the HTTP session.At this point I double-checked to make sure my code was causing the issue. I just returned the original instance of
Rack::HttpStreamingResponse
, and this worked fine (the curl request completed normally.)I tried a new
StreamWrapper
class:But this had the same issue. When I returned the original string, everything worked. When I removed the
meta
tag, thecurl
request hung, and it also didn't work in the browser.Then I finally realized that it was because I was sending the original
Content-Length
header! I was removing bytes from the response, and curl was still waiting for me to send them.I tried deleting the
Content-Length
header to see if Rack would recreate it, but it just sent "Content-Length: 0".So I finally got it working by calling:
headers['Content-Length'] = replaced_body.length.to_s
Then I also realized that I was doing this for
HEAD
requests withcurl -I
, which set theContent-Length
to 0 (because body was an empty string), so that also needed to be fixed. I was able to find the request method by callingbody.instance_variable_get('@request').method
, and then checking that it equalsGET
. (Then this actually returns the wrongContent-Length
, because it doesn't know about the removed bytes. I don't know if this really matters, since browsers will only be makingGET
requests.)Here's the working code:
The text was updated successfully, but these errors were encountered: