Przeglądaj źródła

[http] Use a retry timer to trigger retried requests

Use a retry timer to allow for the possibility of deferring a retried
request.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 lat temu
rodzic
commit
0d657b8e94
1 zmienionych plików z 44 dodań i 15 usunięć
  1. 44
    15
      src/net/tcp/httpcore.c

+ 44
- 15
src/net/tcp/httpcore.c Wyświetl plik

@@ -42,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
42 42
 #include <ipxe/socket.h>
43 43
 #include <ipxe/tcpip.h>
44 44
 #include <ipxe/process.h>
45
+#include <ipxe/retry.h>
45 46
 #include <ipxe/linebuf.h>
46 47
 #include <ipxe/base64.h>
47 48
 #include <ipxe/base16.h>
@@ -103,6 +104,8 @@ enum http_flags {
103 104
 	HTTP_BASIC_AUTH = 0x0020,
104 105
 	/** Provide Digest authentication details */
105 106
 	HTTP_DIGEST_AUTH = 0x0040,
107
+	/** Socket must be reopened */
108
+	HTTP_REOPEN_SOCKET = 0x0080,
106 109
 };
107 110
 
108 111
 /** HTTP receive state */
@@ -179,6 +182,9 @@ struct http_request {
179 182
 	char *auth_nonce;
180 183
 	/** Authentication opaque string (if any) */
181 184
 	char *auth_opaque;
185
+
186
+	/** Request retry timer */
187
+	struct retry_timer timer;
182 188
 };
183 189
 
184 190
 /**
@@ -249,13 +255,43 @@ static int http_socket_open ( struct http_request *http ) {
249 255
 	return 0;
250 256
 }
251 257
 
258
+/**
259
+ * Retry HTTP request
260
+ *
261
+ * @v timer		Retry timer
262
+ * @v fail		Failure indicator
263
+ */
264
+static void http_retry ( struct retry_timer *timer, int fail __unused ) {
265
+	struct http_request *http =
266
+		container_of ( timer, struct http_request, timer );
267
+	int rc;
268
+
269
+	/* Reopen socket if required */
270
+	if ( http->flags & HTTP_REOPEN_SOCKET ) {
271
+		http->flags &= ~HTTP_REOPEN_SOCKET;
272
+		DBGC ( http, "HTTP %p reopening connection\n", http );
273
+		if ( ( rc = http_socket_open ( http ) ) != 0 ) {
274
+			http_close ( http, rc );
275
+			return;
276
+		}
277
+	}
278
+
279
+	/* Retry the request if applicable */
280
+	if ( http->flags & HTTP_TRY_AGAIN ) {
281
+		http->flags &= ~HTTP_TRY_AGAIN;
282
+		DBGC ( http, "HTTP %p retrying request\n", http );
283
+		http->flags |= HTTP_TX_PENDING;
284
+		http->rx_state = HTTP_RX_RESPONSE;
285
+		process_add ( &http->process );
286
+	}
287
+}
288
+
252 289
 /**
253 290
  * Mark HTTP request as completed successfully
254 291
  *
255 292
  * @v http		HTTP request
256 293
  */
257 294
 static void http_done ( struct http_request *http ) {
258
-	int rc;
259 295
 
260 296
 	/* If we are not at an appropriate stage of the protocol
261 297
 	 * (including being in the middle of a chunked transfer),
@@ -296,25 +332,17 @@ static void http_done ( struct http_request *http ) {
296 332
 	}
297 333
 
298 334
 	/* If the server is not intending to keep the connection
299
-	 * alive, then reopen the socket.
335
+	 * alive, then close the socket and mark it as requiring
336
+	 * reopening.
300 337
 	 */
301 338
 	if ( ! ( http->flags & HTTP_SERVER_KEEPALIVE ) ) {
302
-		DBGC ( http, "HTTP %p reopening connection\n", http );
303 339
 		intf_restart ( &http->socket, 0 );
304
-		if ( ( rc = http_socket_open ( http ) ) != 0 ) {
305
-			http_close ( http, rc );
306
-			return;
307
-		}
340
+		http->flags &= ~HTTP_SERVER_KEEPALIVE;
341
+		http->flags |= HTTP_REOPEN_SOCKET;
308 342
 	}
309
-	http->flags &= ~HTTP_SERVER_KEEPALIVE;
310 343
 
311
-	/* Retry the request if applicable */
312
-	if ( http->flags & HTTP_TRY_AGAIN ) {
313
-		http->flags &= ~HTTP_TRY_AGAIN;
314
-		http->flags |= HTTP_TX_PENDING;
315
-		http->rx_state = HTTP_RX_RESPONSE;
316
-		process_add ( &http->process );
317
-	}
344
+	/* Start request retry timer */
345
+	start_timer_nodelay ( &http->timer );
318 346
 }
319 347
 
320 348
 /**
@@ -1467,6 +1495,7 @@ int http_open_filter ( struct interface *xfer, struct uri *uri,
1467 1495
 	http->filter = filter;
1468 1496
 	intf_init ( &http->socket, &http_socket_desc, &http->refcnt );
1469 1497
 	process_init ( &http->process, &http_process_desc, &http->refcnt );
1498
+	timer_init ( &http->timer, http_retry, &http->refcnt );
1470 1499
 	http->flags = HTTP_TX_PENDING;
1471 1500
 
1472 1501
 	/* Open socket */

Ładowanie…
Anuluj
Zapisz