@@ -35,6 +35,7 @@ public function __construct(ZendClient $client = null, ResponseFactory $response
35
35
*/
36
36
public function sendRequest (RequestInterface $ request )
37
37
{
38
+ $ request = $ this ->sanitizeRequest ($ request );
38
39
$ headers = new Headers ();
39
40
40
41
foreach ($ request ->getHeaders () as $ key => $ value ) {
@@ -44,10 +45,25 @@ public function sendRequest(RequestInterface $request)
44
45
$ zendRequest = new Request ();
45
46
$ zendRequest ->setMethod ($ request ->getMethod ());
46
47
$ zendRequest ->setUri ((string ) $ request ->getUri ());
47
- $ zendRequest ->setVersion ($ request ->getProtocolVersion ());
48
48
$ zendRequest ->setHeaders ($ headers );
49
49
$ zendRequest ->setContent ($ request ->getBody ()->getContents ());
50
50
51
+ $ options = [
52
+ 'httpversion ' => $ request ->getProtocolVersion (),
53
+ ];
54
+
55
+ if (extension_loaded ('curl ' )) {
56
+ $ options ['curloptions ' ] = [
57
+ CURLOPT_HTTP_VERSION => $ this ->getProtocolVersion ($ request ->getProtocolVersion ()),
58
+ ];
59
+ }
60
+
61
+ $ this ->client ->setOptions ($ options );
62
+
63
+ if ($ this ->client ->getAdapter () instanceof ZendClient \Adapter \Curl && $ request ->getMethod ()) {
64
+ $ request = $ request ->withHeader ('Content-Length ' , '0 ' );
65
+ }
66
+
51
67
try {
52
68
$ zendResponse = $ this ->client ->send ($ zendRequest );
53
69
} catch (RuntimeException $ exception ) {
@@ -62,4 +78,77 @@ public function sendRequest(RequestInterface $request)
62
78
$ zendResponse ->getVersion ()
63
79
);
64
80
}
81
+
82
+ private function sanitizeRequest (RequestInterface $ request )
83
+ {
84
+ $ request = $ this ->sanitizeWithTrace ($ request );
85
+ $ request = $ this ->sanitizeWithCurl ($ request );
86
+
87
+ return $ request ;
88
+ }
89
+
90
+ /**
91
+ * Zend request remove the body if it's a trace but does not rewrite the content length header,
92
+ * This can lead to error from the server has it can expect a specific content length, but don't have
93
+ * a body, so we set content-length to 0 to avoid bad reading from the server.
94
+ *
95
+ * @param RequestInterface $request
96
+ *
97
+ * @return RequestInterface|static
98
+ */
99
+ private function sanitizeWithTrace (RequestInterface $ request )
100
+ {
101
+ if ($ request ->getMethod () === 'TRACE ' ) {
102
+ $ request = $ request ->withHeader ('Content-Length ' , '0 ' );
103
+ }
104
+
105
+ return $ request ;
106
+ }
107
+
108
+ /**
109
+ * Get specific curl options for Zend Curl Adapter
110
+ *
111
+ * @param RequestInterface $request
112
+ *
113
+ * @return RequestInterface|static
114
+ */
115
+ private function sanitizeWithCurl (RequestInterface $ request )
116
+ {
117
+ if ($ this ->client ->getAdapter () instanceof ZendClient \Adapter \Curl && !in_array ($ request ->getMethod (), [
118
+ 'POST ' ,
119
+ 'PUT ' ,
120
+ 'PATCH '
121
+ ], true )) {
122
+
123
+ $ request = $ request ->withHeader ('Content-Length ' , '0 ' );
124
+ }
125
+
126
+ return $ request ;
127
+ }
128
+
129
+ /**
130
+ * Return cURL constant for specified HTTP version
131
+ *
132
+ * @param string $requestVersion
133
+ *
134
+ * @throws \UnexpectedValueException if unsupported version requested
135
+ *
136
+ * @return int
137
+ */
138
+ private function getProtocolVersion ($ requestVersion )
139
+ {
140
+ switch ($ requestVersion ) {
141
+ case '1.0 ' :
142
+ return CURL_HTTP_VERSION_1_0 ;
143
+ case '1.1 ' :
144
+ return CURL_HTTP_VERSION_1_1 ;
145
+ case '2.0 ' :
146
+ if (defined ('CURL_HTTP_VERSION_2_0 ' )) {
147
+ return CURL_HTTP_VERSION_2_0 ;
148
+ }
149
+ throw new \UnexpectedValueException ('libcurl 7.33 needed for HTTP 2.0 support ' );
150
+ }
151
+
152
+ return CURL_HTTP_VERSION_NONE ;
153
+ }
65
154
}
0 commit comments