Can mod_rewrite distinguish between 'user' request and internal redirect?

Yet another reason why you should avoid adding rewriterules in .htaccess files. If you would do this in the main server context you would not have this problem. In a directory context or .htaccess file each rewrite causes an internal subrequest.

There is a parameter that contains the original request, It's "%{THE_REQUEST}

RewriteCond %{REQUEST_FILENAME}    !-f
RewriteRule (.*)                   public/$0.html?redir [L]

RewriteCond %{THE_REQUEST}        GET\ /public
RewriteRule .*                    - [R=404,L]

This should do it.