/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.uportal.org/license.html
 */
package org.jasig.cas.authentication.principal;

import java.net.URLEncoder;
import java.util.Map;

/**
 * Encapsulates a Response to send back for a particular service.
 * 
 * @author Scott Battaglia
 * @author Arnaud Lesueur
 * @version $Revision: 1.1 $ $Date: 2005/08/19 18:27:17 $
 * @since 3.1
 */
public final class Response {

    public static enum ResponseType {
        POST, REDIRECT
    }

    private final ResponseType responseType;

    private final String url;

    private final Map<String, String> attributes;

    protected Response(ResponseType responseType, final String url, final Map<String, String> attributes) {
        this.responseType = responseType;
        this.url = url;
        this.attributes = attributes;
    }

    public static Response getPostResponse(final String url, final Map<String, String> attributes) {
        return new Response(ResponseType.POST, url, attributes);
    }

    public static Response getRedirectResponse(final String url, final Map<String, String> parameters) {
        final StringBuilder builder = new StringBuilder(parameters.size() * 40 + 100);
        boolean isFirst = true;
        final String[] fragmentSplit = url.split("#");
        
        builder.append(fragmentSplit[0]);
        
        for (final Map.Entry<String, String> entry : parameters.entrySet()) {
            if (entry.getValue() != null) {
                if (isFirst) {
                    builder.append(url.contains("?") ? "&" : "?");
                    isFirst = false;
                } else {
                    builder.append("&");   
                }
                builder.append(entry.getKey());
                builder.append("=");

                try {
                    builder.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
                } catch (final Exception e) {
                    builder.append(entry.getValue());
                }
            }
        }

        if (fragmentSplit.length > 1) {
            builder.append("#");
            builder.append(fragmentSplit[1]);
        }

        return new Response(ResponseType.REDIRECT, builder.toString(), parameters);
    }

    public Map<String, String> getAttributes() {
        return this.attributes;
    }

    public ResponseType getResponseType() {
        return this.responseType;
    }

    public String getUrl() {
        return this.url;
    }
}

@@ -277,16 +277,82 @@
 il.Map;%0D
+%0Aimport java.util.regex.Matcher;%0D%0Aimport java.util.regex.Pattern;%0D
 %0A%0D%0A/**%0D%0A
@@ -587,16 +587,152 @@
 ponse %7B%0D
+%0A    /** Pattern to detect unprintable characters. */%0D%0A    private static final Pattern NON_PRINTABLE = Pattern.compile(%22%5C%5CP%7BPrint%7D+%22);%0D
 %0A%0D%0A    p
@@ -1600,19 +1600,32 @@
 Split = 
+sanitizeUrl(
 url
+)
 .split(%22
@@ -2825,24 +2825,24 @@
 getUrl() %7B%0D%0A
-
         retu
@@ -2862,11 +2862,343 @@
 %0A    %7D%0D%0A
+    %0D%0A    private static String sanitizeUrl(final String url) %7B%0D%0A        final Matcher m = NON_PRINTABLE.matcher(url);%0D%0A        final StringBuffer sb = new StringBuffer(url.length());%0D%0A        while (m.find()) %7B%0D%0A            m.appendReplacement(sb, %22 %22);%0D%0A        %7D%0D%0A        m.appendTail(sb);%0D%0A        return sb.toString();%0D%0A    %7D%0D%0A
 %7D%0D%0A

Add URL sanitization to protect against CRLF attacks.