Struts2 File Upload doesn't work on Internet-Explorer - file-upload

I am having issue with Struts 2 file upload for Word file(.docx, .doc) in Internet Explorer. It works fine in Chrome and Firefox, but I am not sure what I am missing for IE.
I am using IE9.
I appreciate your advice.
<action name="saveOrUpdateUser" method="saveOrUpdate"
class="com.adaptivsol.action.UsersAction">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">104857600</param>
<param name="allowedTypes">
text/plain,
application/word,
application/msword,
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/vnd.openxmlformats-officedocument.wordprocessingml.document
</param>
<param name="allowedExtensions">doc,docx,txt</param>
</interceptor-ref>
<result name="success">./pages/login/register.jsp</result>
<result name="input">./pages/login/register.jsp</result>
<result name="error">./pages/login/register.jsp</result>
</action>

Your parameters are wrong, the fileUpload. prefix is missing in two of them, they need to be:
<param name="fileUpload.allowedTypes">
text/plain,
application/word,
application/msword,
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/vnd.openxmlformats-officedocument.wordprocessingml.document
</param>
<param name="fileUpload.allowedExtensions">doc,docx,txt</param>
By the way, set devMode to true in struts.xml, and post here the logs where the file upload stop working. We need to see an error, a warning, a message, something to understand what's wrong.
Also in your JSP add actionerrors, actionmessages and fielderrors printing capabilities, and report here the message you get.

Related

Upload CSV Files doesn't work fine with Struts2

I have problem when I'm uploading a csv file by web page jsp.
I can upload many files with my Struts2 application.
I'm using Struts 2.5.20 and I can upload all Mime types in "allowedTypes" except "text/csv".
<action name="uploadDocuments" class="UploadDocumentsAction" method="uploadDocuments">
<interceptor-ref name="fileUpload">
<param name="maximumSize">5242880</param>
<param name="allowedTypes">image/jpeg,
image/jpeg2000,
image/png,
image/gif,
image/bmp,
image/tiff,
image/apng,
text/plain,
text/csv,
application/pdf,
application/msword,
application/vnd.openxmlformats-officedocument.wordprocessingml.document</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">stream</param>
</result>
</action>
With Jquery Ajax I invoke action and if "success" show "File Upload Success", otherwise alert "check the extensions of the allowed file types..."
When I try to upload a Csv file I have alert message.
I don't understand because only csv File doesn't work, all other files in "allowedTypes" work fine.
I put breakonpoint in my Action, If I try csv file doesn't pass in Java code, when I select other format files it passes.
Thanks

Why does this web api need a local web api call to log?

I have two almost identical web api services programmed in C# and installed on the same Windows 2008 Server on IIS 6.1. When I do web api calls to them, they both work just fine. I am using log4net for logging purposes. One of them, however, does not always log. They both have the same exact log4net configuration, which is:
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\LOGS\SomeFolder\" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<preserveLogFileNameExtension value="true" />
<rollingStyle value="Date" />
<datePattern value="'WebApi.One.'yyyy-MM-dd'.log'" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level [%thread][%date{dd-MM-yy HH:mm:ss,fff}] %logger - %message%newline" />
</layout>
</appender>
</log4net>
The only difference in the configuration is the datePattern which has a slightly different name so that they do not log to the same exact file.
For the web api where logging works as expected a new log file is created each day as soon as a web api call comes in. For the web api where logging does not seem to work the new log file is not created. However, if I make a web api call from a browser on the same server as it is installed on, then logging starts. After the logging has started for that day it continues fine (even with web api calls coming from other machines). But the next day no new file is created.
I am unable to see what the difference is. Surely there must be something I am not thinking of that makes these two web apis behave differently when it comes to logging. Remember, both of the services work fine, it is just the logging that is not working for one of them.
Any suggestions?
Edit 1:
After adding diagnostics as suggested by Peter I can see that the access to the path is denied:
log4net:ERROR Could not create Appender [RollingLogFileAppender] of type [log4net.Appender.RollingFileAppender]. Reported error follows.
System.UnauthorizedAccessException: Access to the path 'C__LOGS_WebApi.One_' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(Boolean initiallyOwned, String name, Boolean& createdNew, SECURITY_ATTRIBUTES secAttrs)
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity)
at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name)
at log4net.Appender.RollingFileAppender.ActivateOptions()
at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)
log4net:ERROR Appender named [RollingLogFileAppender] not found.
I don't know why though.
Edit 2:
I checked solutions in these StackOverflow answers:
What am I doing wrong with thie log4net implementation?
log4net: Error on loading custom appender
But still no progress.
This looked very similar, but I could see no solution there (although maybe there is one).
Edit 3:
Folder permissions:
According to the exception message, the process does not have enough rights to write to the location of the log file.
In my experience with dealing with IIS, changing the security permissions on the folder where the log file is stored so that the application/process has the rights to modify the log file(s) usually works.
To confirm/troubleshoot start by giving everyone full control on the folder and testing that the file can be modified.
If that works then you can confirm it is a permission issue.
I usually give IIS_IUSRS the following permission on the Log folder where I store my logs and archive.
Read
Write
Modify
To limit possible attack vectors I try to give the process as few permission as needed to perform its function. Adding and removing permissions and then testing that it still functions as desired.
It looks like a security issue, to debug this you should enable debugging for log4net:
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
And
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
in your configuration.
This way you are able to see why the creation of the file fails.
log4net faq

How to ignore Liferay user removed from LDAP errors?

I have a Liferay 6.1 instance that is connected to LDAP. New users get imported nicely, but when I remove a user from the LDAP directory, Liferay starts throwing exceptions when it tries to sync users from LDAP.
These seem to be safe to ignore, but they produce several megabytes of log and it makes log parsing highly annoying. Also I think it might affect performance. If a deleted user logs in, they see nothing.
16:13:54,422 ERROR [liferay/scheduler_dispatch-790][PortalLDAPImporterImpl:995] LDAP user not found with fullUserDN cn=foobar,ou=people,o=foo,dc=bar,dc=baz
javax.naming.NameNotFoundException: [LDAP: error code 32 - No Such Object]; remaining name 'cn=foobar,ou=people,o=foo,dc=bar,dc=baz'
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3057)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2978)
... etc
How could I convince Liferay that this is really OK? Or is there something else I should do?
Until missing users in LDAP are supported by Liferay you can turn off the logging for this particular message. Just create the file ROOT.war/WEB-INF/classes/META-INF/portal-log4j-ext.xml with the following content:
<?xml version="1.0">
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Copy all appenders from
ROOT.war/WEB-INF/lib/portal-impl.jar/META-INF/portal-log4j.xml
and add the following filter: -->
<appender ...>
...
<filter class="org.apache.log4j.filter.StringMatchFilter">
<param name="StringToMatch" value="LDAP user not found with fullUserDN" />
<param name="AcceptOnMatch" value="false" />
</filter>
</appender>
<!-- Keep the root definition from portal-log4j.xml
to trigger the parsing of the appenders: -->
<root>
<priority value="INFO" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>
You can find more about logging in the Liferay Wiki.

IIS 7 removes Content-Disposition filename for Content-Type application/pdf

I have the following code that returns a PDF file in my web application:
string path = "help.pdf";
byte[] data = File.ReadAllBytes(path);
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Length", data.Length.ToString());
Response.AddHeader("Content-Type", "application/pdf");
Response.AddHeader("Content-Disposition", "attachment; filename=help.pdf");
Response.OutputStream.Write(data, 0, data.Length);
Response.End();
When I call the handler of this code in any browser (Chrome, IE or Firefox), I get a "Save as..." dialog with the name of the page (index.aspx) rather than the name provided in the code (help.pdf).
I also checked the following:
Tested on my local machine. It works there as expected.
Deactivated compression in IIS: no change
Deactivated SSL in IIS: no change
Checked MIME types in IIS: application/pdf is configured
Replaced Content-Type application/pdf with application/octet-stream: problem is gone (but we are using third party export tools that I can't modify in this way, so this is not a solution)
I checked the HTTP response header with all browsers. It looks like this:
Cache-Control:private
Content-Disposition:attachment
Content-Length:89407
Content-Type:application/pdf
Date:Thu, 07 May 2015 08:43:12 GMT
Server:Microsoft-IIS/7.5
X-Powered-By:ASP.NET
X-UA-Compatible:IE=edge,chrome=1
As you can see the filename parameter is removed from the Content-Disposition field. So the behaviour of the browsers is correct. The web server (IIS) seems to tinker around with the header.
I found somebody with the same problem here. But the problem was never solved. Any ideas?
The problem was that because of an IIS 7.5 issue someone added the following lines to the web.config file of the application:
<outboundRules>
<rule name="Force pdfs to download" preCondition="only match pdfs">
<match serverVariable="RESPONSE_Content_Disposition" pattern="(.*)" />
<action type="Rewrite" value="attachment" />
</rule>
<preConditions>
<preCondition name="only match pdfs">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^application/pdf" />
</preCondition>
</preConditions>
</outboundRules>

Struts Pass Login Screen Form Data To Next Page Action

Basically I have your standard login page for a struts application.
You enter password and Username and post back to the server, whilst moving onto the main application page.
I have java code within the main page that requires the login data from the last page to populate the table on screen. I have tried ActionRedirect but it keeps bring back nullpointerexception:
ActionRedirect redirect =
new ActionRedirect(mapping.findForward(SUCCESS));
redirect.addParameter("userName",loginForm.getUserName());
return redirect;
here is the struts config:
<action input="/login.jsp" name="LoginForm" path="/Login" scope="request" type="com.myapp.struts.LoginAction" validate="false">
<result name="success" type="redirect-action">
<param name="location">/timesheet.jsp</param>
<param name="parse">false</param>
</result>
<forward name="failure" path="/login.jsp" />
</action>
and the error comes back as:
WARNING: Unable to find 'timesheet.jsp' forward.
and yes I have tried to add another forward relating to 'SUCCESS' but again it fails.
Struts config was missing forward, had put the result section within the forward param and thats why its wasnt working