1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.client;
20
21 import java.util.List;
22
23 import org.eclipse.jetty.client.api.Request;
24 import org.eclipse.jetty.client.api.Response;
25 import org.eclipse.jetty.client.api.Result;
26 import org.eclipse.jetty.client.util.BufferingResponseListener;
27 import org.eclipse.jetty.http.HttpHeader;
28 import org.eclipse.jetty.http.HttpHeaderValue;
29
30 public class ContinueProtocolHandler implements ProtocolHandler
31 {
32 private static final String ATTRIBUTE = ContinueProtocolHandler.class.getName() + ".100continue";
33
34 private final HttpClient client;
35 private final ResponseNotifier notifier;
36
37 public ContinueProtocolHandler(HttpClient client)
38 {
39 this.client = client;
40 this.notifier = new ResponseNotifier(client);
41 }
42
43 @Override
44 public boolean accept(Request request, Response response)
45 {
46 boolean expect100 = request.getHeaders().contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString());
47 HttpConversation conversation = client.getConversation(request.getConversationID(), false);
48 boolean handled100 = conversation != null && conversation.getAttribute(ATTRIBUTE) != null;
49 return expect100 && !handled100;
50 }
51
52 @Override
53 public Response.Listener getResponseListener()
54 {
55
56 return new ContinueListener();
57 }
58
59 protected class ContinueListener extends BufferingResponseListener
60 {
61 @Override
62 public void onSuccess(Response response)
63 {
64
65
66
67 HttpConversation conversation = client.getConversation(response.getConversationID(), false);
68
69 conversation.setAttribute(ATTRIBUTE, Boolean.TRUE);
70
71
72 conversation.updateResponseListeners(null);
73
74 HttpExchange exchange = conversation.getExchanges().peekLast();
75 assert exchange.getResponse() == response;
76 switch (response.getStatus())
77 {
78 case 100:
79 {
80
81 exchange.resetResponse(true);
82 exchange.proceed(true);
83 break;
84 }
85 default:
86 {
87
88
89
90 List<Response.ResponseListener> listeners = exchange.getResponseListeners();
91 HttpContentResponse contentResponse = new HttpContentResponse(response, getContent(), getEncoding());
92 notifier.forwardSuccess(listeners, contentResponse);
93 exchange.proceed(false);
94 break;
95 }
96 }
97 }
98
99 @Override
100 public void onFailure(Response response, Throwable failure)
101 {
102 HttpConversation conversation = client.getConversation(response.getConversationID(), false);
103
104 conversation.setAttribute(ATTRIBUTE, Boolean.TRUE);
105
106 conversation.updateResponseListeners(null);
107
108 HttpExchange exchange = conversation.getExchanges().peekLast();
109 assert exchange.getResponse() == response;
110 List<Response.ResponseListener> listeners = exchange.getResponseListeners();
111 HttpContentResponse contentResponse = new HttpContentResponse(response, getContent(), getEncoding());
112 notifier.forwardFailureComplete(listeners, exchange.getRequest(), exchange.getRequestFailure(), contentResponse, failure);
113 }
114
115 @Override
116 public void onComplete(Result result)
117 {
118 }
119 }
120 }