View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.server;
20  
21  import java.util.Set;
22  
23  import org.eclipse.jetty.http.HttpField;
24  import org.eclipse.jetty.http.HttpFields;
25  import org.eclipse.jetty.http.HttpHeader;
26  import org.eclipse.jetty.http.HttpMethod;
27  import org.eclipse.jetty.http.HttpURI;
28  import org.eclipse.jetty.http.MetaData;
29  import org.eclipse.jetty.util.URIUtil;
30  import org.eclipse.jetty.util.log.Log;
31  import org.eclipse.jetty.util.log.Logger;
32  
33  
34  /* ------------------------------------------------------------ */
35  /** 
36   */
37  public class PushBuilderImpl implements PushBuilder
38  {    
39      private static final Logger LOG = Log.getLogger(PushBuilderImpl.class);
40  
41      private final static HttpField JettyPush = new HttpField("x-http2-push","PushBuilder");
42      
43      private final Request _request;
44      private final HttpFields _fields;
45      private String _method;
46      private String _queryString;
47      private String _sessionId;
48      private boolean _conditional;
49      private String _path;
50      private String _etag;
51      private String _lastModified;
52      
53      public PushBuilderImpl(Request request, HttpFields fields, String method, String queryString, String sessionId, boolean conditional)
54      {
55          super();
56          _request = request;
57          _fields = fields;
58          _method = method;
59          _queryString = queryString;
60          _sessionId = sessionId;
61          _conditional = conditional;
62          _fields.add(JettyPush);
63          if (LOG.isDebugEnabled())
64              LOG.debug("PushBuilder({} {}?{} s={} c={})",_method,_request.getRequestURI(),_queryString,_sessionId,_conditional);
65      }
66  
67      /* ------------------------------------------------------------ */
68      /**
69       * @see org.eclipse.jetty.server.PushBuilder#getMethod()
70       */
71      @Override
72      public String getMethod()
73      {
74          return _method;
75      }
76      
77      /* ------------------------------------------------------------ */
78      /**
79       * @see org.eclipse.jetty.server.PushBuilder#method(java.lang.String)
80       */
81      @Override
82      public PushBuilder method(String method)
83      {
84          _method = method;
85          return this;
86      }
87      
88      /* ------------------------------------------------------------ */
89      /**
90       * @see org.eclipse.jetty.server.PushBuilder#getQueryString()
91       */
92      @Override
93      public String getQueryString()
94      {
95          return _queryString;
96      }
97      
98      /* ------------------------------------------------------------ */
99      /**
100      * @see org.eclipse.jetty.server.PushBuilder#queryString(java.lang.String)
101      */
102     @Override
103     public PushBuilder queryString(String queryString)
104     {
105         _queryString = queryString;
106         return this;
107     }
108     
109     /* ------------------------------------------------------------ */
110     /**
111      * @see org.eclipse.jetty.server.PushBuilder#getSessionId()
112      */
113     @Override
114     public String getSessionId()
115     {
116         return _sessionId;
117     }
118     
119     /* ------------------------------------------------------------ */
120     /**
121      * @see org.eclipse.jetty.server.PushBuilder#sessionId(java.lang.String)
122      */
123     @Override
124     public PushBuilder sessionId(String sessionId)
125     {
126         _sessionId = sessionId;
127         return this;
128     }
129     
130     /* ------------------------------------------------------------ */
131     /**
132      * @see org.eclipse.jetty.server.PushBuilder#isConditional()
133      */
134     @Override
135     public boolean isConditional()
136     {
137         return _conditional;
138     }
139     
140     /* ------------------------------------------------------------ */
141     /**
142      * @see org.eclipse.jetty.server.PushBuilder#conditional(boolean)
143      */
144     @Override
145     public PushBuilder conditional(boolean conditional)
146     {
147         _conditional = conditional;
148         return this;
149     }
150     
151     /* ------------------------------------------------------------ */
152     /**
153      * @see org.eclipse.jetty.server.PushBuilder#getHeaderNames()
154      */
155     @Override
156     public Set<String> getHeaderNames()
157     {
158         return _fields.getFieldNamesCollection();
159     }
160     
161     /* ------------------------------------------------------------ */
162     /**
163      * @see org.eclipse.jetty.server.PushBuilder#getHeader(java.lang.String)
164      */
165     @Override
166     public String getHeader(String name)
167     {
168         return _fields.get(name);
169     }
170     
171     /* ------------------------------------------------------------ */
172     /**
173      * @see org.eclipse.jetty.server.PushBuilder#setHeader(java.lang.String, java.lang.String)
174      */
175     @Override
176     public PushBuilder setHeader(String name,String value)
177     {
178         _fields.put(name,value);
179         return this;
180     }
181     
182     /* ------------------------------------------------------------ */
183     /**
184      * @see org.eclipse.jetty.server.PushBuilder#addHeader(java.lang.String, java.lang.String)
185      */
186     @Override
187     public PushBuilder addHeader(String name,String value)
188     {
189         _fields.add(name,value);
190         return this;
191     }
192 
193     
194     /* ------------------------------------------------------------ */
195     /**
196      * @see org.eclipse.jetty.server.PushBuilder#getPath()
197      */
198     @Override
199     public String getPath()
200     {
201         return _path;
202     }
203 
204     /* ------------------------------------------------------------ */
205     /**
206      * @see org.eclipse.jetty.server.PushBuilder#path(java.lang.String)
207      */
208     @Override
209     public PushBuilder path(String path)
210     {
211         _path = path;
212         return this;
213     }
214 
215     /* ------------------------------------------------------------ */
216     /**
217      * @see org.eclipse.jetty.server.PushBuilder#getEtag()
218      */
219     @Override
220     public String getEtag()
221     {
222         return _etag;
223     }
224 
225     /* ------------------------------------------------------------ */
226     /**
227      * @see org.eclipse.jetty.server.PushBuilder#etag(java.lang.String)
228      */
229     @Override
230     public PushBuilder etag(String etag)
231     {
232         _etag = etag;
233         return this;
234     }
235 
236     /* ------------------------------------------------------------ */
237     /**
238      * @see org.eclipse.jetty.server.PushBuilder#getLastModified()
239      */
240     @Override
241     public String getLastModified()
242     {
243         return _lastModified;
244     }
245 
246     /* ------------------------------------------------------------ */
247     /**
248      * @see org.eclipse.jetty.server.PushBuilder#lastModified(java.lang.String)
249      */
250     @Override
251     public PushBuilder lastModified(String lastModified)
252     {
253         _lastModified = lastModified;
254         return this;
255     }
256 
257     /* ------------------------------------------------------------ */
258     /* ------------------------------------------------------------ */
259     /**
260      * @see org.eclipse.jetty.server.PushBuilder#push()
261      */
262     @Override
263     public void push()
264     {
265         if (HttpMethod.POST.is(_method) || HttpMethod.PUT.is(_method))
266             throw new IllegalStateException("Bad Method "+_method);
267         
268         if (_path==null || _path.length()==0)
269             throw new IllegalStateException("Bad Path "+_path);
270         
271         String path=_path;
272         String query=_queryString;
273         int q=path.indexOf('?');
274         if (q>=0)
275         {
276             query=(query!=null && query.length()>0)?(_path.substring(q+1)+'&'+query):_path.substring(q+1);
277             path=_path.substring(0,q);
278         }
279         
280         if (!path.startsWith("/"))
281             path=URIUtil.addPaths(_request.getContextPath(),path);
282         
283         String param=null;
284         if (_sessionId!=null)
285         {
286             if (_request.isRequestedSessionIdFromURL())
287                 param="jsessionid="+_sessionId;
288             // TODO else 
289             //      _fields.add("Cookie","JSESSIONID="+_sessionId);
290         }
291         
292         if (_conditional)
293         {
294             if (_etag!=null)
295                 _fields.add(HttpHeader.IF_NONE_MATCH,_etag);
296             else if (_lastModified!=null)
297                 _fields.add(HttpHeader.IF_MODIFIED_SINCE,_lastModified);
298         }
299         
300         HttpURI uri = HttpURI.createHttpURI(_request.getScheme(),_request.getServerName(),_request.getServerPort(),_path,param,query,null);
301         MetaData.Request push = new MetaData.Request(_method,uri,_request.getHttpVersion(),_fields);
302         
303         if (LOG.isDebugEnabled())
304             LOG.debug("Push {} {} inm={} ims={}",_method,uri,_fields.get(HttpHeader.IF_NONE_MATCH),_fields.get(HttpHeader.IF_MODIFIED_SINCE));
305         
306         _request.getHttpChannel().getHttpTransport().push(push);
307         _path=null;
308         _etag=null;
309         _lastModified=null;
310     }
311 }