xref: /unit/src/java/nginx/unit/Request.java (revision 1011:0c41674ec79c)
1 package nginx.unit;
2 
3 import java.io.BufferedReader;
4 import java.io.InputStreamReader;
5 import java.io.IOException;
6 import java.io.UnsupportedEncodingException;
7 
8 import java.lang.IllegalArgumentException;
9 import java.lang.IllegalStateException;
10 import java.lang.Object;
11 import java.lang.String;
12 import java.lang.StringBuffer;
13 
14 import java.net.URI;
15 import java.net.URISyntaxException;
16 
17 import java.text.ParseException;
18 import java.text.SimpleDateFormat;
19 
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Date;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.Set;
30 
31 import java.security.Principal;
32 
33 import javax.servlet.AsyncContext;
34 import javax.servlet.DispatcherType;
35 import javax.servlet.RequestDispatcher;
36 import javax.servlet.ServletContext;
37 import javax.servlet.ServletException;
38 import javax.servlet.ServletInputStream;
39 import javax.servlet.ServletRequest;
40 import javax.servlet.ServletRequestAttributeEvent;
41 import javax.servlet.ServletRequestAttributeListener;
42 import javax.servlet.ServletResponse;
43 import javax.servlet.SessionTrackingMode;
44 import javax.servlet.SessionCookieConfig;
45 import javax.servlet.http.Cookie;
46 import javax.servlet.http.HttpSession;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.servlet.http.HttpServletResponse;
49 import javax.servlet.http.HttpUpgradeHandler;
50 import javax.servlet.http.Part;
51 
52 import org.eclipse.jetty.util.MultiMap;
53 import org.eclipse.jetty.util.UrlEncoded;
54 import org.eclipse.jetty.util.StringUtil;
55 
56 import org.eclipse.jetty.server.CookieCutter;
57 import org.eclipse.jetty.http.MimeTypes;
58 
59 public class Request implements HttpServletRequest, DynamicPathRequest
60 {
61     private final Context context;
62     private final long req_info_ptr;
63     private final long req_ptr;
64 
65     protected String authType = null;
66 
67     protected boolean cookiesParsed = false;
68 
69     protected CookieCutter cookies = null;
70 
71     private final Map<String, Object> attributes = new HashMap<>();
72 
73     private MultiMap<String> parameters = null;
74 
75     private final String context_path;
76     private String filter_path = null;
77     private String servlet_path = null;
78     private String path_info = null;
79     private String request_uri = null;
80     private String query_string = null;
81     private boolean query_string_valid = false;
82 
83     private DispatcherType dispatcher_type = DispatcherType.REQUEST;
84 
85     private String characterEncoding = null;
86 
87     /**
88      * The only date format permitted when generating HTTP headers.
89      */
90     public static final String RFC1123_DATE =
91             "EEE, dd MMM yyyy HH:mm:ss zzz";
92 
93     private static final SimpleDateFormat formats[] = {
94         new SimpleDateFormat(RFC1123_DATE, Locale.US),
95         new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
96         new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
97     };
98 
99     private InputStream inputStream = null;
100     private BufferedReader reader = null;
101 
102     private boolean request_session_id_parsed = false;
103     private String request_session_id = null;
104     private boolean request_session_id_from_cookie = false;
105     private boolean request_session_id_from_url = false;
106     private Session session = null;
107 
108     private final ServletRequestAttributeListener attr_listener;
109 
110     public static final String BARE = "nginx.unit.request.bare";
111 
112     public Request(Context ctx, long req_info, long req) {
113         context = ctx;
114         req_info_ptr = req_info;
115         req_ptr = req;
116 
117         attr_listener = context.getRequestAttributeListener();
118         context_path = context.getContextPath();
119     }
120 
121     @Override
122     public boolean authenticate(HttpServletResponse response)
123         throws IOException, ServletException
124     {
125         log("authenticate");
126 
127         if (response.isCommitted()) {
128             throw new IllegalStateException();
129         }
130 
131         return false;
132     }
133 
134     @Override
135     public String getAuthType()
136     {
137         log("getAuthType");
138 
139         return authType;
140     }
141 
142     @Override
143     public String getContextPath()
144     {
145         trace("getContextPath: " + context_path);
146 
147         return context_path;
148     }
149 
150     @Override
151     public Cookie[] getCookies()
152     {
153         trace("getCookies");
154 
155         if (!cookiesParsed) {
156             parseCookies();
157         }
158 
159         //Javadoc for Request.getCookies() stipulates null for no cookies
160         if (cookies == null || cookies.getCookies().length == 0) {
161             return null;
162         }
163 
164         return cookies.getCookies();
165     }
166 
167     protected void parseCookies()
168     {
169         cookiesParsed = true;
170 
171         cookies = new CookieCutter();
172 
173         Enumeration<String> cookie_headers = getHeaders("Cookie");
174 
175         while (cookie_headers.hasMoreElements()) {
176             cookies.addCookieField(cookie_headers.nextElement());
177         }
178     }
179 
180     @Override
181     public long getDateHeader(String name)
182     {
183         trace("getDateHeader: " + name);
184 
185         String value = getHeader(name);
186         if (value == null) {
187             return -1L;
188         }
189 
190         long res = parseDate(value);
191         if (res == -1L) {
192             throw new IllegalArgumentException(value);
193         }
194 
195         return res;
196     }
197 
198     protected long parseDate(String value)
199     {
200         Date date = null;
201         for (int i = 0; (date == null) && (i < formats.length); i++) {
202             try {
203                 date = formats[i].parse(value);
204             } catch (ParseException e) {
205                 // Ignore
206             }
207         }
208         if (date == null) {
209             return -1L;
210         }
211         return date.getTime();
212     }
213 
214     @Override
215     public String getHeader(String name)
216     {
217         String res = getHeader(req_ptr, name, name.length());
218 
219         trace("getHeader: " + name + " = '" + res + "'");
220 
221         return res;
222     }
223 
224     private static native String getHeader(long req_ptr, String name, int name_len);
225 
226 
227     @Override
228     public Enumeration<String> getHeaderNames()
229     {
230         trace("getHeaderNames");
231 
232         return getHeaderNames(req_ptr);
233     }
234 
235     private static native Enumeration<String> getHeaderNames(long req_ptr);
236 
237 
238     @Override
239     public Enumeration<String> getHeaders(String name)
240     {
241         trace("getHeaders: " + name);
242 
243         return getHeaders(req_ptr, name, name.length());
244     }
245 
246     private static native Enumeration<String> getHeaders(long req_ptr, String name, int name_len);
247 
248 
249     @Override
250     public int getIntHeader(String name)
251     {
252         trace("getIntHeader: " + name);
253 
254         return getIntHeader(req_ptr, name, name.length());
255     }
256 
257     private static native int getIntHeader(long req_ptr, String name, int name_len);
258 
259 
260     @Override
261     public String getMethod()
262     {
263         trace("getMethod");
264 
265         return getMethod(req_ptr);
266     }
267 
268     private static native String getMethod(long req_ptr);
269 
270 
271     @Override
272     public Part getPart(String name) throws IOException, ServletException
273     {
274         log("getPart: " + name);
275 
276         return null;
277     }
278 
279     @Override
280     public Collection<Part> getParts() throws IOException, ServletException
281     {
282         log("getParts");
283 
284         return Collections.emptyList();
285     }
286 
287     @Override
288     public String getPathInfo()
289     {
290         trace("getPathInfo: " + path_info);
291 
292         return path_info;
293     }
294 
295     @Override
296     public String getPathTranslated()
297     {
298         trace("getPathTranslated");
299 
300         if (path_info == null) {
301             return null;
302         }
303 
304         return context.getRealPath(path_info);
305     }
306 
307     @Override
308     public String getQueryString()
309     {
310         if (!query_string_valid) {
311             query_string = getQueryString(req_ptr);
312             query_string_valid = true;
313         }
314 
315         trace("getQueryString: " + query_string);
316 
317         return query_string;
318     }
319 
320     private static native String getQueryString(long req_ptr);
321 
322     @Override
323     public void setQueryString(String query)
324     {
325         trace("setQueryString: " + query);
326 
327         query_string = query;
328         query_string_valid = true;
329     }
330 
331     @Override
332     public String getRemoteUser()
333     {
334         log("getRemoteUser");
335 
336         /* TODO */
337         return null;
338     }
339 
340     @Override
341     public String getRequestedSessionId()
342     {
343         trace("getRequestedSessionId");
344 
345         if (!request_session_id_parsed) {
346             parseRequestSessionId();
347         }
348 
349         return request_session_id;
350     }
351 
352     private void parseRequestSessionId()
353     {
354         request_session_id_parsed = true;
355 
356         Cookie[] cookies = getCookies();
357         if (cookies == null) {
358             return;
359         }
360 
361         if (context.getEffectiveSessionTrackingModes().contains(
362             SessionTrackingMode.COOKIE))
363         {
364             final String name = context.getSessionCookieConfig().getName();
365 
366             for (Cookie c : cookies) {
367                 if (c.getName().equals(name)) {
368                     request_session_id = c.getValue();
369                     request_session_id_from_cookie = true;
370 
371                     return;
372                 }
373             }
374         }
375     }
376 
377     @Override
378     public String getRequestURI()
379     {
380         if (request_uri == null) {
381             request_uri = getRequestURI(req_ptr);
382         }
383 
384         trace("getRequestURI: " + request_uri);
385 
386         return request_uri;
387     }
388 
389     private static native String getRequestURI(long req_ptr);
390 
391 
392     @Override
393     public void setRequestURI(String uri)
394     {
395         trace("setRequestURI: " + uri);
396 
397         request_uri = uri;
398     }
399 
400 
401     @Override
402     public StringBuffer getRequestURL()
403     {
404         String host = getHeader("Host");
405         String uri = getRequestURI();
406         StringBuffer res = new StringBuffer("http://" + host + uri);
407 
408         trace("getRequestURL: " + res);
409 
410         return res;
411     }
412 
413     @Override
414     public String getServletPath()
415     {
416         trace("getServletPath: " + servlet_path);
417 
418         return servlet_path;
419     }
420 
421     @Override
422     public void setServletPath(String servlet_path, String path_info)
423     {
424         trace("setServletPath: " + servlet_path);
425 
426         this.filter_path = servlet_path;
427         this.servlet_path = servlet_path;
428         this.path_info = path_info;
429     }
430 
431     @Override
432     public void setServletPath(String filter_path, String servlet_path, String path_info)
433     {
434         trace("setServletPath: " + filter_path + ", " + servlet_path);
435 
436         this.filter_path = filter_path;
437         this.servlet_path = servlet_path;
438         this.path_info = path_info;
439     }
440 
441     @Override
442     public String getFilterPath()
443     {
444         return filter_path;
445     }
446 
447     @Override
448     public HttpSession getSession()
449     {
450         return getSession(true);
451     }
452 
453     @Override
454     public HttpSession getSession(boolean create)
455     {
456         if (session != null) {
457             if (context.isSessionIdValid(session.getId())) {
458                 trace("getSession(" + create + "): " + session.getId());
459 
460                 return session;
461             }
462 
463             session = null;
464         }
465 
466         if (!request_session_id_parsed) {
467             parseRequestSessionId();
468 
469             session = context.getSession(request_session_id);
470         }
471 
472         if (session != null || !create) {
473             trace("getSession(" + create + "): " + (session != null ? session.getId() : "null"));
474 
475             return session;
476         }
477 
478         session = context.createSession();
479 
480         if (context.getEffectiveSessionTrackingModes().contains(
481             SessionTrackingMode.COOKIE))
482         {
483             setSessionIdCookie();
484         }
485 
486         trace("getSession(" + create + "): " + session.getId());
487 
488         return session;
489     }
490 
491     private void setSessionIdCookie()
492     {
493         SessionCookieConfig config = context.getSessionCookieConfig();
494 
495         Cookie c = new Cookie(config.getName(), session.getId());
496 
497         c.setComment(config.getComment());
498         if (!StringUtil.isBlank(config.getDomain())) {
499             c.setDomain(config.getDomain());
500         }
501 
502         c.setHttpOnly(config.isHttpOnly());
503         if (!StringUtil.isBlank(config.getPath())) {
504             c.setPath(config.getPath());
505         }
506 
507         c.setMaxAge(config.getMaxAge());
508 
509         getResponse(req_info_ptr).addSessionIdCookie(c);
510     }
511 
512     @Override
513     public Principal getUserPrincipal()
514     {
515         log("getUserPrincipal");
516 
517         return null;
518     }
519 
520     @Override
521     public boolean isRequestedSessionIdFromCookie()
522     {
523         trace("isRequestedSessionIdFromCookie");
524 
525         if (!request_session_id_parsed) {
526             parseRequestSessionId();
527         }
528 
529         return request_session_id_from_cookie;
530     }
531 
532     @Override
533     @Deprecated
534     public boolean isRequestedSessionIdFromUrl()
535     {
536         trace("isRequestedSessionIdFromUrl");
537 
538         if (!request_session_id_parsed) {
539             parseRequestSessionId();
540         }
541 
542         return request_session_id_from_url;
543     }
544 
545     @Override
546     public boolean isRequestedSessionIdFromURL()
547     {
548         trace("isRequestedSessionIdFromURL");
549 
550         if (!request_session_id_parsed) {
551             parseRequestSessionId();
552         }
553 
554         return request_session_id_from_url;
555     }
556 
557     @Override
558     public boolean isRequestedSessionIdValid()
559     {
560         trace("isRequestedSessionIdValid");
561 
562         if (!request_session_id_parsed) {
563             parseRequestSessionId();
564         }
565 
566         return context.isSessionIdValid(request_session_id);
567     }
568 
569     @Override
570     public boolean isUserInRole(String role)
571     {
572         log("isUserInRole: " + role);
573 
574         return false;
575     }
576 
577     @Override
578     public void login(String username, String password) throws ServletException
579     {
580         log("login: " + username + "," + password);
581     }
582 
583     @Override
584     public void logout() throws ServletException
585     {
586         log("logout");
587     }
588 
589 
590     @Override
591     public AsyncContext getAsyncContext()
592     {
593         log("getAsyncContext");
594 
595         return null;
596     }
597 
598     @Override
599     public Object getAttribute(String name)
600     {
601         if (BARE.equals(name)) {
602             return this;
603         }
604 
605         Object o = attributes.get(name);
606 
607         trace("getAttribute: " + name + " = " + o);
608 
609         return o;
610     }
611 
612     @Override
613     public Enumeration<String> getAttributeNames()
614     {
615         trace("getAttributeNames");
616 
617         Set<String> names = attributes.keySet();
618         return Collections.enumeration(names);
619     }
620 
621     @Override
622     public String getCharacterEncoding()
623     {
624         trace("getCharacterEncoding");
625 
626         if (characterEncoding != null) {
627             return characterEncoding;
628         }
629 
630         getContentType();
631 
632         return characterEncoding;
633     }
634 
635     @Override
636     public int getContentLength()
637     {
638         trace("getContentLength");
639 
640         return (int) getContentLength(req_ptr);
641     }
642 
643     private static native long getContentLength(long req_ptr);
644 
645     @Override
646     public long getContentLengthLong()
647     {
648         trace("getContentLengthLong");
649 
650         return getContentLength(req_ptr);
651     }
652 
653     @Override
654     public String getContentType()
655     {
656         trace("getContentType");
657 
658         String content_type = getContentType(req_ptr);
659 
660         if (characterEncoding == null && content_type != null) {
661             MimeTypes.Type mime = MimeTypes.CACHE.get(content_type);
662             String charset = (mime == null || mime.getCharset() == null) ? MimeTypes.getCharsetFromContentType(content_type) : mime.getCharset().toString();
663             if (charset != null) {
664                 characterEncoding = charset;
665             }
666         }
667 
668         return content_type;
669     }
670 
671     private static native String getContentType(long req_ptr);
672 
673 
674     @Override
675     public DispatcherType getDispatcherType()
676     {
677         trace("getDispatcherType: " + dispatcher_type);
678 
679         return dispatcher_type;
680     }
681 
682     @Override
683     public void setDispatcherType(DispatcherType type)
684     {
685         trace("setDispatcherType: " + type);
686 
687         dispatcher_type = type;
688     }
689 
690     @Override
691     public ServletInputStream getInputStream() throws IOException
692     {
693         trace("getInputStream");
694 
695         if (reader != null) {
696             throw new IllegalStateException("getInputStream: getReader() already used");
697         }
698 
699         if (inputStream == null) {
700             inputStream = new InputStream(req_info_ptr);
701         }
702 
703         return inputStream;
704     }
705 
706     @Override
707     public String getLocalAddr()
708     {
709         trace("getLocalAddr");
710 
711         return getLocalAddr(req_ptr);
712     }
713 
714     private static native String getLocalAddr(long req_ptr);
715 
716 
717     @Override
718     public Locale getLocale()
719     {
720         log("getLocale");
721 
722         return Locale.getDefault();
723     }
724 
725     @Override
726     public Enumeration<Locale> getLocales()
727     {
728         log("getLocales");
729 
730         return Collections.emptyEnumeration();
731     }
732 
733     @Override
734     public String getLocalName()
735     {
736         trace("getLocalName");
737 
738         return getLocalName(req_ptr);
739     }
740 
741     private static native String getLocalName(long req_ptr);
742 
743 
744     @Override
745     public int getLocalPort()
746     {
747         trace("getLocalPort");
748 
749         return getLocalPort(req_ptr);
750     }
751 
752     private static native int getLocalPort(long req_ptr);
753 
754 
755     public MultiMap<String> getParameters()
756     {
757         if (parameters != null) {
758             return parameters;
759         }
760 
761         parameters = new MultiMap<>();
762 
763         String query = getQueryString();
764 
765         if (query != null) {
766             UrlEncoded.decodeUtf8To(query, parameters);
767         }
768 
769         if (getContentLength() > 0 &&
770             getMethod().equals("POST") &&
771             getContentType().startsWith("application/x-www-form-urlencoded"))
772         {
773             try {
774                 UrlEncoded.decodeUtf8To(new InputStream(req_info_ptr),
775                     parameters, getContentLength(), -1);
776             } catch (IOException e) {
777                 log("Unhandled IOException: " + e);
778             }
779         }
780 
781         return parameters;
782     }
783 
784     public void setParameters(MultiMap<String> p)
785     {
786         parameters = p;
787     }
788 
789     @Override
790     public String getParameter(String name)
791     {
792         trace("getParameter: " + name);
793 
794         return getParameters().getValue(name, 0);
795     }
796 
797     @Override
798     public Map<String,String[]> getParameterMap()
799     {
800         trace("getParameterMap");
801 
802         return Collections.unmodifiableMap(getParameters().toStringArrayMap());
803     }
804 
805     @Override
806     public Enumeration<String> getParameterNames()
807     {
808         trace("getParameterNames");
809 
810         return Collections.enumeration(getParameters().keySet());
811     }
812 
813     @Override
814     public String[] getParameterValues(String name)
815     {
816         trace("getParameterValues: " + name);
817 
818         List<String> vals = getParameters().getValues(name);
819         if (vals == null)
820             return null;
821         return vals.toArray(new String[vals.size()]);
822     }
823 
824     @Override
825     public String getProtocol()
826     {
827         trace("getProtocol");
828 
829         return getProtocol(req_ptr);
830     }
831 
832     private static native String getProtocol(long req_ptr);
833 
834     @Override
835     public BufferedReader getReader() throws IOException
836     {
837         trace("getReader");
838 
839         if (inputStream != null) {
840             throw new IllegalStateException("getReader: getInputStream() already used");
841         }
842 
843         if (reader == null) {
844             reader = new BufferedReader(new InputStreamReader(new InputStream(req_info_ptr)));
845         }
846 
847         return reader;
848     }
849 
850     @Override
851     @Deprecated
852     public String getRealPath(String path)
853     {
854         trace("getRealPath: " + path);
855 
856         return context.getRealPath(path);
857     }
858 
859     @Override
860     public String getRemoteAddr()
861     {
862         String res = getRemoteAddr(req_ptr);
863 
864         trace("getRemoteAddr: " + res);
865 
866         return res;
867     }
868 
869     private static native String getRemoteAddr(long req_ptr);
870 
871 
872     @Override
873     public String getRemoteHost()
874     {
875         String res = getRemoteHost(req_ptr);
876 
877         trace("getRemoteHost: " + res);
878 
879         return res;
880     }
881 
882     private static native String getRemoteHost(long req_ptr);
883 
884 
885     @Override
886     public int getRemotePort()
887     {
888         int res = getRemotePort(req_ptr);
889 
890         trace("getRemotePort: " + res);
891 
892         return res;
893     }
894 
895     private static native int getRemotePort(long req_ptr);
896 
897 
898     @Override
899     public RequestDispatcher getRequestDispatcher(String path)
900     {
901         trace("getRequestDispatcher: " + path);
902 
903         if (path.startsWith("/")) {
904             return context.getRequestDispatcher(path);
905         }
906 
907         try {
908             URI uri = new URI(getRequestURI());
909             uri = uri.resolve(path);
910 
911             return context.getRequestDispatcher(uri);
912         } catch (URISyntaxException e) {
913             log("getRequestDispatcher: failed to create dispatcher: " + e);
914         }
915 
916         return null;
917     }
918 
919 
920     @Override
921     public String getScheme()
922     {
923         log("getScheme");
924 
925         return getScheme(req_ptr);
926     }
927 
928     private static native String getScheme(long req_ptr);
929 
930 
931     @Override
932     public String getServerName()
933     {
934         String res = getServerName(req_ptr);
935 
936         trace("getServerName: " + res);
937 
938         return res;
939     }
940 
941     private static native String getServerName(long req_ptr);
942 
943 
944     @Override
945     public int getServerPort()
946     {
947         int res = getServerPort(req_ptr);
948 
949         trace("getServerPort: " + res);
950 
951         return res;
952     }
953 
954     private static native int getServerPort(long req_ptr);
955 
956     @Override
957     public ServletContext getServletContext()
958     {
959         trace("getServletContext");
960 
961         return context;
962     }
963 
964     @Override
965     public boolean isAsyncStarted()
966     {
967         log("isAsyncStarted");
968 
969         return false;
970     }
971 
972     @Override
973     public boolean isAsyncSupported()
974     {
975         log("isAsyncSupported");
976 
977         return false;
978     }
979 
980     @Override
981     public boolean isSecure()
982     {
983         trace("isSecure");
984 
985         return isSecure(req_ptr);
986     }
987 
988     private static native boolean isSecure(long req_ptr);
989 
990     @Override
991     public void removeAttribute(String name)
992     {
993         trace("removeAttribute: " + name);
994 
995         Object prev = attributes.remove(name);
996 
997         if (attr_listener == null || prev == null) {
998             return;
999         }
1000 
1001         attr_listener.attributeRemoved(
1002             new ServletRequestAttributeEvent(context, this, name, prev));
1003     }
1004 
1005     @Override
1006     public void setAttribute(String name, Object o)
1007     {
1008         trace("setAttribute: " + name + ", " + o);
1009 
1010         Object prev;
1011 
1012         if (o != null) {
1013             prev = attributes.put(name, o);
1014         } else {
1015             prev = attributes.remove(name);
1016         }
1017 
1018         if (attr_listener == null) {
1019             return;
1020         }
1021 
1022         if (prev == null) {
1023             if (o == null) {
1024                 return;
1025             }
1026 
1027             attr_listener.attributeAdded(new ServletRequestAttributeEvent(
1028                 context, this, name, o));
1029         } else {
1030             if (o != null) {
1031                 attr_listener.attributeReplaced(
1032                     new ServletRequestAttributeEvent(context, this, name, prev));
1033             } else {
1034                 attr_listener.attributeRemoved(
1035                     new ServletRequestAttributeEvent(context, this, name, prev));
1036             }
1037         }
1038     }
1039 
1040     public void setAttribute_(String name, Object o)
1041     {
1042         trace("setAttribute_: " + name + ", " + o);
1043 
1044         if (o != null) {
1045             attributes.put(name, o);
1046         } else {
1047             attributes.remove(name);
1048         }
1049     }
1050 
1051     @Override
1052     public void setCharacterEncoding(String env) throws UnsupportedEncodingException
1053     {
1054         trace("setCharacterEncoding: " + env);
1055 
1056         characterEncoding = env;
1057     }
1058 
1059     @Override
1060     public AsyncContext startAsync() throws IllegalStateException
1061     {
1062         log("startAsync");
1063 
1064         return null;
1065     }
1066 
1067     @Override
1068     public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException
1069     {
1070         log("startAsync(Req, resp)");
1071 
1072         return null;
1073     }
1074 
1075     @Override
1076     public <T extends HttpUpgradeHandler> T upgrade(
1077             Class<T> httpUpgradeHandlerClass) throws java.io.IOException, ServletException
1078     {
1079         log("upgrade: " + httpUpgradeHandlerClass.getName());
1080 
1081         return null;
1082     }
1083 
1084     @Override
1085     public String changeSessionId()
1086     {
1087         trace("changeSessionId");
1088 
1089         getSession(false);
1090 
1091         if (session == null) {
1092             return null;
1093         }
1094 
1095         context.changeSessionId(session);
1096 
1097         if (context.getEffectiveSessionTrackingModes().contains(
1098             SessionTrackingMode.COOKIE))
1099         {
1100             setSessionIdCookie();
1101         }
1102 
1103         return session.getId();
1104     }
1105 
1106     private void log(String msg)
1107     {
1108         msg = "Request." + msg;
1109         log(req_info_ptr, msg, msg.length());
1110     }
1111 
1112     public static native void log(long req_info_ptr, String msg, int msg_len);
1113 
1114 
1115     private void trace(String msg)
1116     {
1117         msg = "Request." + msg;
1118         trace(req_info_ptr, msg, msg.length());
1119     }
1120 
1121     public static native void trace(long req_info_ptr, String msg, int msg_len);
1122 
1123     private static native Response getResponse(long req_info_ptr);
1124 }
1125 
1126