001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.tag;
020
021import java.nio.charset.Charset;
022
023import javax.servlet.http.HttpServletResponse;
024
025import lucee.commons.io.CharsetUtil;
026import lucee.runtime.PageContextImpl;
027import lucee.runtime.exp.PageException;
028import lucee.runtime.exp.TemplateException;
029import lucee.runtime.ext.tag.TagImpl;
030
031/**
032* Generates custom HTTP response headers to return to the client.
033*
034*
035*
036**/
037public final class Header extends TagImpl {
038
039        /** A value for the HTTP header. This attribute is used in conjunction with the name attribute. */
040        private String value="";
041
042        /** Text that explains the status code. This attribute is used in conjunction with the 
043        **      statusCode attribute. */
044        private String statustext;
045
046        /** A name for the header. */
047        private String name;
048
049        /** A number that sets the HTTP status code. */
050        private int statuscode;
051        
052        private boolean hasStatucCode;
053
054    private Charset charset;
055    
056        @Override
057        public void release()   {
058                super.release();
059                value="";
060                statustext=null;
061                name=null;
062                statuscode=0;
063                hasStatucCode=false;
064        charset=null;
065        }
066
067
068        /** set the value value
069        *  A value for the HTTP header. This attribute is used in conjunction with the name attribute.
070        * @param value value to set
071        **/
072        public void setValue(String value)      {
073                this.value=value;
074        }
075
076        /** set the value statustext
077        *  Text that explains the status code. This attribute is used in conjunction with the 
078        *       statusCode attribute.
079        * @param statustext value to set
080        **/
081        public void setStatustext(String statustext)    {
082                this.statustext=statustext;
083        }
084
085        /** set the value name
086        *  A name for the header.
087        * @param name value to set
088        **/
089        public void setName(String name)        {
090                this.name=name;
091        }
092
093        /** set the value statuscode
094        *  A number that sets the HTTP status code.
095        * @param statuscode value to set
096        **/
097        public void setStatuscode(double statuscode)    {
098                this.statuscode=(int) statuscode;
099                hasStatucCode=true;
100        }
101    
102    /**
103     * @param charset The charset to set.
104     */
105    public void setCharset(String charset) {
106        this.charset = CharsetUtil.toCharset(charset);
107    }
108
109
110        @Override
111        public int doStartTag() throws PageException    {
112                
113                HttpServletResponse rsp = pageContext. getHttpServletResponse();
114                if(rsp.isCommitted())
115                        throw new TemplateException("can't assign value to header, header is alredy committed");
116                
117                // set name value
118                if(name != null) {
119            if(charset==null && name.equalsIgnoreCase("content-disposition")) {
120                    charset=((PageContextImpl)pageContext).getWebCharset();
121            }
122            if(charset!=null) {
123                name = new String(name.getBytes(charset), CharsetUtil.ISO88591);
124                value = new String(value.getBytes(charset), CharsetUtil.ISO88591);
125            }
126            else {
127                name = new String(name.getBytes(), CharsetUtil.ISO88591);
128                value = new String(value.getBytes(), CharsetUtil.ISO88591);
129            }
130            
131                        if(name.toLowerCase().equals("content-type") && value.length()>0) {
132                rsp.setContentType(value);
133            }
134                        else {
135                rsp.addHeader(name, value);
136            }
137                }
138                // set status
139                if(hasStatucCode) {
140                if(statustext != null) {
141                        //try {
142                                ///rsp.sendError(statuscode, statustext);
143                                rsp.setStatus(statuscode,statustext);
144                        /*} 
145                catch (IOException e) {
146                                throw new TemplateException("can't assign value to header, header is alredy committed",e.getMessage());
147                        } */
148            }
149                else {
150                rsp.setStatus(statuscode);
151            }
152                }
153                return SKIP_BODY;
154        }
155
156        @Override
157        public int doEndTag()   {
158                return EVAL_PAGE;
159        }
160}