Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service Stack Session Lost After File Upload

We've created a small website using Service Stack, but are having a problem with user uploads. We find that when a user uploads a file using a POST that their session is closed.

The size of the file doesn't seem to matter, nor does the delay in responding to the upload POST.

I've confirmed that the browser is still sending the same Session ID (ss-id) cookie before and after the upload.

Here's how we're handling AAA:

public override void Configure(Container container)
{
    //Config examples
    //this.Plugins.Add(new PostmanFeature());
    //this.Plugins.Add(new CorsFeature());            
    ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601; 

    Plugins.Add(new AuthFeature(() => new AuthUserSession(),
        new IAuthProvider[] {
            new FeedPartnerAuthProvider(), //Custom MSSQL based auth
        }
    ));

    //Global response filter to extend session automatically
    this.GlobalResponseFilters.Add((req, res, requestDto) =>
    {
        var userSession = req.GetSession();
        req.SaveSession(userSession, slidingExpiryTimeSpan);
    });

    this.Plugins.Add(new RazorFormat());
}

Here's what the upload code looks like:

//Upload Test Models
[Route("/upload", "POST")]
public class PostUpload : IReturn<PostUploadResponse>
{
    public String Title { get; set; }
}
public class PostUploadResponse
{
    public String Title { get; set; }
    public Boolean Success { get; set; }
}

//Upload Test Service
[Authenticate]
public object Post(PostUpload request)
{
    string uploadPath = "~/uploads";
    Directory.CreateDirectory(uploadPath.MapAbsolutePath());

    var customerFile = Request.Files.SingleOrDefault(uploadedFile =>
        uploadedFile.ContentLength > 0 &&
        uploadedFile.ContentLength <= 500 * 1000 * 1024);

    if (customerFile == null)
        throw new ArgumentException("Error: Uploaded file must be less than 500MB");

    //determine the extension of the file
    String inputFileExtension = "";
    var regexResult = Regex.Match(customerFile.FileName, "^.*\\.(.{3})$");
    if (regexResult.Success)
        inputFileExtension = regexResult.Groups[1].Value;

    if (inputFileExtension.Length == 0)
        throw new Exception("Error determining extension of input filename.");

    //build a temporary location on the disk for this file
    String outputFilename = "{0}/{1}.{2}".FormatWith(uploadPath, Guid.NewGuid(), inputFileExtension).MapAbsolutePath();
    if (File.Exists(outputFilename))
        throw new Exception("Unable to create temporary file during upload.");

    //Get some information from the session
    String ownerId = "Partner_" + this.GetSession().UserAuthId;

    //Write the temp file to the disk and begin creating the profile.                        
    try
    {
        //Move the file to a working directory.
        using (var outFile = File.OpenWrite(outputFilename))
        {
            customerFile.WriteTo(outFile);
        }

    }
    catch (Exception ex)
    {
        throw new Exception("Error creating profile with uploaded file. ", ex);
    }
    finally
    {
        //Clean up temp file no matter what
        try { File.Delete(outputFilename); }
        catch (Exception delException) { }
    }

    return new PostUploadResponse
    {
        Title = request.Title,
        Success = true
    };
}

The file uploads successfully, and the response is correctly passed back to the browser, but subsequent calls to any service receive a 302 Redirect to /login even though the correct ss-id and sp-pid are transmitted as part of the request.

What is causing my user session to end whenever I upload a file?

Many thanks!

-Z

like image 631
zorlack Avatar asked Feb 11 '26 10:02

zorlack


1 Answers

Well, I solved this one:

What was happening here was that the user uploaded files were ending up in /bin/uploads instead of /uploads. Whenever the contents of /bin change the App Domain restarted which invalidated the session.

The bug in this instance is my use of .MapAbsolutePath() instead of .MapServerPath()

like image 110
zorlack Avatar answered Feb 14 '26 00:02

zorlack



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!