You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

httpcore.c 42KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648
  1. /*
  2. * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /**
  25. * @file
  26. *
  27. * Hyper Text Transfer Protocol (HTTP) core functionality
  28. *
  29. */
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include <strings.h>
  35. #include <byteswap.h>
  36. #include <errno.h>
  37. #include <ctype.h>
  38. #include <assert.h>
  39. #include <ipxe/uri.h>
  40. #include <ipxe/refcnt.h>
  41. #include <ipxe/iobuf.h>
  42. #include <ipxe/xfer.h>
  43. #include <ipxe/open.h>
  44. #include <ipxe/socket.h>
  45. #include <ipxe/tcpip.h>
  46. #include <ipxe/process.h>
  47. #include <ipxe/retry.h>
  48. #include <ipxe/timer.h>
  49. #include <ipxe/linebuf.h>
  50. #include <ipxe/base64.h>
  51. #include <ipxe/base16.h>
  52. #include <ipxe/md5.h>
  53. #include <ipxe/blockdev.h>
  54. #include <ipxe/acpi.h>
  55. #include <ipxe/version.h>
  56. #include <ipxe/params.h>
  57. #include <ipxe/profile.h>
  58. #include <ipxe/http.h>
  59. /* Disambiguate the various error causes */
  60. #define EACCES_401 __einfo_error ( EINFO_EACCES_401 )
  61. #define EINFO_EACCES_401 \
  62. __einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )
  63. #define EIO_OTHER __einfo_error ( EINFO_EIO_OTHER )
  64. #define EINFO_EIO_OTHER \
  65. __einfo_uniqify ( EINFO_EIO, 0x01, "Unrecognised HTTP response code" )
  66. #define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
  67. #define EINFO_EIO_CONTENT_LENGTH \
  68. __einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
  69. #define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
  70. #define EINFO_EINVAL_RESPONSE \
  71. __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
  72. #define EINVAL_HEADER __einfo_error ( EINFO_EINVAL_HEADER )
  73. #define EINFO_EINVAL_HEADER \
  74. __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid header" )
  75. #define EINVAL_CONTENT_LENGTH __einfo_error ( EINFO_EINVAL_CONTENT_LENGTH )
  76. #define EINFO_EINVAL_CONTENT_LENGTH \
  77. __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid content length" )
  78. #define EINVAL_CHUNK_LENGTH __einfo_error ( EINFO_EINVAL_CHUNK_LENGTH )
  79. #define EINFO_EINVAL_CHUNK_LENGTH \
  80. __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid chunk length" )
  81. #define ENOENT_404 __einfo_error ( EINFO_ENOENT_404 )
  82. #define EINFO_ENOENT_404 \
  83. __einfo_uniqify ( EINFO_ENOENT, 0x01, "HTTP 404 Not Found" )
  84. #define EPERM_403 __einfo_error ( EINFO_EPERM_403 )
  85. #define EINFO_EPERM_403 \
  86. __einfo_uniqify ( EINFO_EPERM, 0x01, "HTTP 403 Forbidden" )
  87. #define EPROTO_UNSOLICITED __einfo_error ( EINFO_EPROTO_UNSOLICITED )
  88. #define EINFO_EPROTO_UNSOLICITED \
  89. __einfo_uniqify ( EINFO_EPROTO, 0x01, "Unsolicited data" )
  90. /** Block size used for HTTP block device request */
  91. #define HTTP_BLKSIZE 512
  92. /** Retry delay used when we cannot understand the Retry-After header */
  93. #define HTTP_RETRY_SECONDS 5
  94. /** Receive profiler */
  95. static struct profiler http_rx_profiler __profiler = { .name = "http.rx" };
  96. /** Data transfer profiler */
  97. static struct profiler http_xfer_profiler __profiler = { .name = "http.xfer" };
  98. /** HTTP flags */
  99. enum http_flags {
  100. /** Request is waiting to be transmitted */
  101. HTTP_TX_PENDING = 0x0001,
  102. /** Fetch header only */
  103. HTTP_HEAD_ONLY = 0x0002,
  104. /** Client would like to keep connection alive */
  105. HTTP_CLIENT_KEEPALIVE = 0x0004,
  106. /** Server will keep connection alive */
  107. HTTP_SERVER_KEEPALIVE = 0x0008,
  108. /** Discard the current request and try again */
  109. HTTP_TRY_AGAIN = 0x0010,
  110. /** Provide Basic authentication details */
  111. HTTP_BASIC_AUTH = 0x0020,
  112. /** Provide Digest authentication details */
  113. HTTP_DIGEST_AUTH = 0x0040,
  114. /** Include qop parameter in Digest authentication reponse */
  115. HTTP_DIGEST_AUTH_QOP = 0x0080,
  116. /** Use MD5-sess algorithm for Digest authentication */
  117. HTTP_DIGEST_AUTH_MD5_SESS = 0x0100,
  118. /** Socket must be reopened */
  119. HTTP_REOPEN_SOCKET = 0x0200,
  120. };
  121. /** HTTP receive state */
  122. enum http_rx_state {
  123. HTTP_RX_RESPONSE = 0,
  124. HTTP_RX_HEADER,
  125. HTTP_RX_CHUNK_LEN,
  126. /* In HTTP_RX_DATA, it is acceptable for the server to close
  127. * the connection (unless we are in the middle of a chunked
  128. * transfer).
  129. */
  130. HTTP_RX_DATA,
  131. /* In the following states, it is acceptable for the server to
  132. * close the connection.
  133. */
  134. HTTP_RX_TRAILER,
  135. HTTP_RX_IDLE,
  136. HTTP_RX_DEAD,
  137. };
  138. /**
  139. * An HTTP request
  140. *
  141. */
  142. struct http_request {
  143. /** Reference count */
  144. struct refcnt refcnt;
  145. /** Data transfer interface */
  146. struct interface xfer;
  147. /** Partial transfer interface */
  148. struct interface partial;
  149. /** URI being fetched */
  150. struct uri *uri;
  151. /** Default port */
  152. unsigned int default_port;
  153. /** Filter (if any) */
  154. int ( * filter ) ( struct interface *xfer,
  155. const char *name,
  156. struct interface **next );
  157. /** Transport layer interface */
  158. struct interface socket;
  159. /** Flags */
  160. unsigned int flags;
  161. /** Starting offset of partial transfer (if applicable) */
  162. size_t partial_start;
  163. /** Length of partial transfer (if applicable) */
  164. size_t partial_len;
  165. /** TX process */
  166. struct process process;
  167. /** RX state */
  168. enum http_rx_state rx_state;
  169. /** Response code */
  170. unsigned int code;
  171. /** Received length */
  172. size_t rx_len;
  173. /** Length remaining (or 0 if unknown) */
  174. size_t remaining;
  175. /** HTTP is using Transfer-Encoding: chunked */
  176. int chunked;
  177. /** Current chunk length remaining (if applicable) */
  178. size_t chunk_remaining;
  179. /** Line buffer for received header lines */
  180. struct line_buffer linebuf;
  181. /** Receive data buffer (if applicable) */
  182. userptr_t rx_buffer;
  183. /** Authentication realm (if any) */
  184. char *auth_realm;
  185. /** Authentication nonce (if any) */
  186. char *auth_nonce;
  187. /** Authentication opaque string (if any) */
  188. char *auth_opaque;
  189. /** Request retry timer */
  190. struct retry_timer timer;
  191. /** Retry delay (in timer ticks) */
  192. unsigned long retry_delay;
  193. };
  194. /**
  195. * Free HTTP request
  196. *
  197. * @v refcnt Reference counter
  198. */
  199. static void http_free ( struct refcnt *refcnt ) {
  200. struct http_request *http =
  201. container_of ( refcnt, struct http_request, refcnt );
  202. uri_put ( http->uri );
  203. empty_line_buffer ( &http->linebuf );
  204. free ( http->auth_realm );
  205. free ( http->auth_nonce );
  206. free ( http->auth_opaque );
  207. free ( http );
  208. };
  209. /**
  210. * Close HTTP request
  211. *
  212. * @v http HTTP request
  213. * @v rc Return status code
  214. */
  215. static void http_close ( struct http_request *http, int rc ) {
  216. /* Prevent further processing of any current packet */
  217. http->rx_state = HTTP_RX_DEAD;
  218. /* Prevent reconnection */
  219. http->flags &= ~HTTP_CLIENT_KEEPALIVE;
  220. /* Remove process */
  221. process_del ( &http->process );
  222. /* Close all data transfer interfaces */
  223. intf_shutdown ( &http->socket, rc );
  224. intf_shutdown ( &http->partial, rc );
  225. intf_shutdown ( &http->xfer, rc );
  226. }
  227. /**
  228. * Open HTTP socket
  229. *
  230. * @v http HTTP request
  231. * @ret rc Return status code
  232. */
  233. static int http_socket_open ( struct http_request *http ) {
  234. struct uri *uri = http->uri;
  235. struct sockaddr_tcpip server;
  236. struct interface *socket;
  237. int rc;
  238. /* Open socket */
  239. memset ( &server, 0, sizeof ( server ) );
  240. server.st_port = htons ( uri_port ( uri, http->default_port ) );
  241. socket = &http->socket;
  242. if ( http->filter ) {
  243. if ( ( rc = http->filter ( socket, uri->host, &socket ) ) != 0 )
  244. return rc;
  245. }
  246. if ( ( rc = xfer_open_named_socket ( socket, SOCK_STREAM,
  247. ( struct sockaddr * ) &server,
  248. uri->host, NULL ) ) != 0 )
  249. return rc;
  250. return 0;
  251. }
  252. /**
  253. * Retry HTTP request
  254. *
  255. * @v timer Retry timer
  256. * @v fail Failure indicator
  257. */
  258. static void http_retry ( struct retry_timer *timer, int fail __unused ) {
  259. struct http_request *http =
  260. container_of ( timer, struct http_request, timer );
  261. int rc;
  262. /* Reopen socket if required */
  263. if ( http->flags & HTTP_REOPEN_SOCKET ) {
  264. http->flags &= ~HTTP_REOPEN_SOCKET;
  265. DBGC ( http, "HTTP %p reopening connection\n", http );
  266. if ( ( rc = http_socket_open ( http ) ) != 0 ) {
  267. http_close ( http, rc );
  268. return;
  269. }
  270. }
  271. /* Retry the request if applicable */
  272. if ( http->flags & HTTP_TRY_AGAIN ) {
  273. http->flags &= ~HTTP_TRY_AGAIN;
  274. DBGC ( http, "HTTP %p retrying request\n", http );
  275. http->flags |= HTTP_TX_PENDING;
  276. http->rx_state = HTTP_RX_RESPONSE;
  277. process_add ( &http->process );
  278. }
  279. }
  280. /**
  281. * Mark HTTP request as completed successfully
  282. *
  283. * @v http HTTP request
  284. */
  285. static void http_done ( struct http_request *http ) {
  286. /* If we are not at an appropriate stage of the protocol
  287. * (including being in the middle of a chunked transfer),
  288. * force an error.
  289. */
  290. if ( ( http->rx_state < HTTP_RX_DATA ) || ( http->chunked != 0 ) ) {
  291. DBGC ( http, "HTTP %p connection closed unexpectedly in state "
  292. "%d\n", http, http->rx_state );
  293. http_close ( http, -ECONNRESET );
  294. return;
  295. }
  296. /* If we had a Content-Length, and the received content length
  297. * isn't correct, force an error
  298. */
  299. if ( http->remaining != 0 ) {
  300. DBGC ( http, "HTTP %p incorrect length %zd, should be %zd\n",
  301. http, http->rx_len, ( http->rx_len + http->remaining ) );
  302. http_close ( http, -EIO_CONTENT_LENGTH );
  303. return;
  304. }
  305. /* Enter idle state */
  306. http->rx_state = HTTP_RX_IDLE;
  307. http->rx_len = 0;
  308. assert ( http->remaining == 0 );
  309. assert ( http->chunked == 0 );
  310. assert ( http->chunk_remaining == 0 );
  311. /* Close partial transfer interface */
  312. if ( ! ( http->flags & HTTP_TRY_AGAIN ) )
  313. intf_restart ( &http->partial, 0 );
  314. /* Close everything unless we want to keep the connection alive */
  315. if ( ! ( http->flags & ( HTTP_CLIENT_KEEPALIVE | HTTP_TRY_AGAIN ) ) ) {
  316. http_close ( http, 0 );
  317. return;
  318. }
  319. /* If the server is not intending to keep the connection
  320. * alive, then close the socket and mark it as requiring
  321. * reopening.
  322. */
  323. if ( ! ( http->flags & HTTP_SERVER_KEEPALIVE ) ) {
  324. intf_restart ( &http->socket, 0 );
  325. http->flags &= ~HTTP_SERVER_KEEPALIVE;
  326. http->flags |= HTTP_REOPEN_SOCKET;
  327. }
  328. /* Start request retry timer */
  329. start_timer_fixed ( &http->timer, http->retry_delay );
  330. http->retry_delay = 0;
  331. }
  332. /**
  333. * Convert HTTP response code to return status code
  334. *
  335. * @v response HTTP response code
  336. * @ret rc Return status code
  337. */
  338. static int http_response_to_rc ( unsigned int response ) {
  339. switch ( response ) {
  340. case 200:
  341. case 206:
  342. case 301:
  343. case 302:
  344. case 303:
  345. return 0;
  346. case 404:
  347. return -ENOENT_404;
  348. case 403:
  349. return -EPERM_403;
  350. case 401:
  351. return -EACCES_401;
  352. default:
  353. return -EIO_OTHER;
  354. }
  355. }
  356. /**
  357. * Handle HTTP response
  358. *
  359. * @v http HTTP request
  360. * @v response HTTP response
  361. * @ret rc Return status code
  362. */
  363. static int http_rx_response ( struct http_request *http, char *response ) {
  364. char *spc;
  365. DBGC ( http, "HTTP %p response \"%s\"\n", http, response );
  366. /* Check response starts with "HTTP/" */
  367. if ( strncmp ( response, "HTTP/", 5 ) != 0 )
  368. return -EINVAL_RESPONSE;
  369. /* Locate and store response code */
  370. spc = strchr ( response, ' ' );
  371. if ( ! spc )
  372. return -EINVAL_RESPONSE;
  373. http->code = strtoul ( spc, NULL, 10 );
  374. /* Move to receive headers */
  375. http->rx_state = ( ( http->flags & HTTP_HEAD_ONLY ) ?
  376. HTTP_RX_TRAILER : HTTP_RX_HEADER );
  377. return 0;
  378. }
  379. /**
  380. * Handle HTTP Location header
  381. *
  382. * @v http HTTP request
  383. * @v value HTTP header value
  384. * @ret rc Return status code
  385. */
  386. static int http_rx_location ( struct http_request *http, char *value ) {
  387. int rc;
  388. /* Redirect to new location */
  389. DBGC ( http, "HTTP %p redirecting to %s\n", http, value );
  390. if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI_STRING,
  391. value ) ) != 0 ) {
  392. DBGC ( http, "HTTP %p could not redirect: %s\n",
  393. http, strerror ( rc ) );
  394. return rc;
  395. }
  396. return 0;
  397. }
  398. /**
  399. * Handle HTTP Content-Length header
  400. *
  401. * @v http HTTP request
  402. * @v value HTTP header value
  403. * @ret rc Return status code
  404. */
  405. static int http_rx_content_length ( struct http_request *http, char *value ) {
  406. struct block_device_capacity capacity;
  407. size_t content_len;
  408. char *endp;
  409. /* Parse content length */
  410. content_len = strtoul ( value, &endp, 10 );
  411. if ( ! ( ( *endp == '\0' ) || isspace ( *endp ) ) ) {
  412. DBGC ( http, "HTTP %p invalid Content-Length \"%s\"\n",
  413. http, value );
  414. return -EINVAL_CONTENT_LENGTH;
  415. }
  416. /* If we already have an expected content length, and this
  417. * isn't it, then complain
  418. */
  419. if ( http->remaining && ( http->remaining != content_len ) ) {
  420. DBGC ( http, "HTTP %p incorrect Content-Length %zd (expected "
  421. "%zd)\n", http, content_len, http->remaining );
  422. return -EIO_CONTENT_LENGTH;
  423. }
  424. if ( ! ( http->flags & HTTP_HEAD_ONLY ) )
  425. http->remaining = content_len;
  426. /* Do nothing more if we are retrying the request */
  427. if ( http->flags & HTTP_TRY_AGAIN )
  428. return 0;
  429. /* Use seek() to notify recipient of filesize */
  430. xfer_seek ( &http->xfer, http->remaining );
  431. xfer_seek ( &http->xfer, 0 );
  432. /* Report block device capacity if applicable */
  433. if ( http->flags & HTTP_HEAD_ONLY ) {
  434. capacity.blocks = ( content_len / HTTP_BLKSIZE );
  435. capacity.blksize = HTTP_BLKSIZE;
  436. capacity.max_count = -1U;
  437. block_capacity ( &http->partial, &capacity );
  438. }
  439. return 0;
  440. }
  441. /**
  442. * Handle HTTP Transfer-Encoding header
  443. *
  444. * @v http HTTP request
  445. * @v value HTTP header value
  446. * @ret rc Return status code
  447. */
  448. static int http_rx_transfer_encoding ( struct http_request *http, char *value ){
  449. if ( strcasecmp ( value, "chunked" ) == 0 ) {
  450. /* Mark connection as using chunked transfer encoding */
  451. http->chunked = 1;
  452. }
  453. return 0;
  454. }
  455. /**
  456. * Handle HTTP Connection header
  457. *
  458. * @v http HTTP request
  459. * @v value HTTP header value
  460. * @ret rc Return status code
  461. */
  462. static int http_rx_connection ( struct http_request *http, char *value ) {
  463. if ( strcasecmp ( value, "keep-alive" ) == 0 ) {
  464. /* Mark connection as being kept alive by the server */
  465. http->flags |= HTTP_SERVER_KEEPALIVE;
  466. }
  467. return 0;
  468. }
  469. /**
  470. * Handle WWW-Authenticate Basic header
  471. *
  472. * @v http HTTP request
  473. * @v params Parameters
  474. * @ret rc Return status code
  475. */
  476. static int http_rx_basic_auth ( struct http_request *http, char *params ) {
  477. DBGC ( http, "HTTP %p Basic authentication required (%s)\n",
  478. http, params );
  479. /* If we received a 401 Unauthorized response, then retry
  480. * using Basic authentication
  481. */
  482. if ( ( http->code == 401 ) &&
  483. ( ! ( http->flags & HTTP_BASIC_AUTH ) ) &&
  484. ( http->uri->user != NULL ) ) {
  485. http->flags |= ( HTTP_TRY_AGAIN | HTTP_BASIC_AUTH );
  486. }
  487. return 0;
  488. }
  489. /**
  490. * Parse Digest authentication parameter
  491. *
  492. * @v params Parameters
  493. * @v name Parameter name (including trailing "=\"")
  494. * @ret value Parameter value, or NULL
  495. */
  496. static char * http_digest_param ( char *params, const char *name ) {
  497. char *key;
  498. char *value;
  499. char *terminator;
  500. /* Locate parameter */
  501. key = strstr ( params, name );
  502. if ( ! key )
  503. return NULL;
  504. /* Extract value */
  505. value = ( key + strlen ( name ) );
  506. terminator = strchr ( value, '"' );
  507. if ( ! terminator )
  508. return NULL;
  509. return strndup ( value, ( terminator - value ) );
  510. }
  511. /**
  512. * Handle WWW-Authenticate Digest header
  513. *
  514. * @v http HTTP request
  515. * @v params Parameters
  516. * @ret rc Return status code
  517. */
  518. static int http_rx_digest_auth ( struct http_request *http, char *params ) {
  519. DBGC ( http, "HTTP %p Digest authentication required (%s)\n",
  520. http, params );
  521. /* If we received a 401 Unauthorized response, then retry
  522. * using Digest authentication
  523. */
  524. if ( ( http->code == 401 ) &&
  525. ( ! ( http->flags & HTTP_DIGEST_AUTH ) ) &&
  526. ( http->uri->user != NULL ) ) {
  527. /* Extract realm */
  528. free ( http->auth_realm );
  529. http->auth_realm = http_digest_param ( params, "realm=\"" );
  530. if ( ! http->auth_realm ) {
  531. DBGC ( http, "HTTP %p Digest prompt missing realm\n",
  532. http );
  533. return -EINVAL_HEADER;
  534. }
  535. /* Extract nonce */
  536. free ( http->auth_nonce );
  537. http->auth_nonce = http_digest_param ( params, "nonce=\"" );
  538. if ( ! http->auth_nonce ) {
  539. DBGC ( http, "HTTP %p Digest prompt missing nonce\n",
  540. http );
  541. return -EINVAL_HEADER;
  542. }
  543. /* Extract opaque */
  544. free ( http->auth_opaque );
  545. http->auth_opaque = http_digest_param ( params, "opaque=\"" );
  546. if ( ! http->auth_opaque ) {
  547. /* Not an error; "opaque" is optional */
  548. }
  549. /* Check for presence of qop */
  550. if ( strstr ( params, "qop=\"" ) != NULL )
  551. http->flags |= HTTP_DIGEST_AUTH_QOP;
  552. /* Check for MD5-sess. For some bizarre reason,
  553. * RFC2617 requires this to be unquoted, which means
  554. * that http_digest_param() cannot be used.
  555. */
  556. if ( strstr ( params, "algorithm=MD5-sess" ) != NULL )
  557. http->flags |= HTTP_DIGEST_AUTH_MD5_SESS;
  558. /* Retry using digest authentication */
  559. http->flags |= ( HTTP_TRY_AGAIN | HTTP_DIGEST_AUTH );
  560. }
  561. return 0;
  562. }
  563. /** An HTTP WWW-Authenticate header handler */
  564. struct http_auth_header_handler {
  565. /** Scheme (e.g. "Basic") */
  566. const char *scheme;
  567. /** Handle received parameters
  568. *
  569. * @v http HTTP request
  570. * @v params Parameters
  571. * @ret rc Return status code
  572. */
  573. int ( * rx ) ( struct http_request *http, char *params );
  574. };
  575. /** List of HTTP WWW-Authenticate header handlers */
  576. static struct http_auth_header_handler http_auth_header_handlers[] = {
  577. {
  578. .scheme = "Basic",
  579. .rx = http_rx_basic_auth,
  580. },
  581. {
  582. .scheme = "Digest",
  583. .rx = http_rx_digest_auth,
  584. },
  585. { NULL, NULL },
  586. };
  587. /**
  588. * Handle HTTP WWW-Authenticate header
  589. *
  590. * @v http HTTP request
  591. * @v value HTTP header value
  592. * @ret rc Return status code
  593. */
  594. static int http_rx_www_authenticate ( struct http_request *http, char *value ) {
  595. struct http_auth_header_handler *handler;
  596. char *separator;
  597. char *scheme;
  598. char *params;
  599. int rc;
  600. /* Extract scheme */
  601. separator = strchr ( value, ' ' );
  602. if ( ! separator ) {
  603. DBGC ( http, "HTTP %p malformed WWW-Authenticate header\n",
  604. http );
  605. return -EINVAL_HEADER;
  606. }
  607. *separator = '\0';
  608. scheme = value;
  609. params = ( separator + 1 );
  610. /* Hand off to header handler, if one exists */
  611. for ( handler = http_auth_header_handlers; handler->scheme; handler++ ){
  612. if ( strcasecmp ( scheme, handler->scheme ) == 0 ) {
  613. if ( ( rc = handler->rx ( http, params ) ) != 0 )
  614. return rc;
  615. break;
  616. }
  617. }
  618. return 0;
  619. }
  620. /**
  621. * Handle HTTP Retry-After header
  622. *
  623. * @v http HTTP request
  624. * @v value HTTP header value
  625. * @ret rc Return status code
  626. */
  627. static int http_rx_retry_after ( struct http_request *http, char *value ) {
  628. unsigned long seconds;
  629. char *endp;
  630. DBGC ( http, "HTTP %p retry requested (%s)\n", http, value );
  631. /* If we received a 503 Service Unavailable response, then
  632. * retry after the specified number of seconds. If the value
  633. * is not a simple number of seconds (e.g. a full HTTP date),
  634. * then retry after a fixed delay, since we don't have code
  635. * able to parse full HTTP dates.
  636. */
  637. if ( http->code == 503 ) {
  638. seconds = strtoul ( value, &endp, 10 );
  639. if ( *endp != '\0' ) {
  640. seconds = HTTP_RETRY_SECONDS;
  641. DBGC ( http, "HTTP %p cannot understand \"%s\"; "
  642. "using %ld seconds\n", http, value, seconds );
  643. }
  644. http->flags |= HTTP_TRY_AGAIN;
  645. http->retry_delay = ( seconds * TICKS_PER_SEC );
  646. }
  647. return 0;
  648. }
  649. /** An HTTP header handler */
  650. struct http_header_handler {
  651. /** Name (e.g. "Content-Length") */
  652. const char *header;
  653. /** Handle received header
  654. *
  655. * @v http HTTP request
  656. * @v value HTTP header value
  657. * @ret rc Return status code
  658. *
  659. * If an error is returned, the download will be aborted.
  660. */
  661. int ( * rx ) ( struct http_request *http, char *value );
  662. };
  663. /** List of HTTP header handlers */
  664. static struct http_header_handler http_header_handlers[] = {
  665. {
  666. .header = "Location",
  667. .rx = http_rx_location,
  668. },
  669. {
  670. .header = "Content-Length",
  671. .rx = http_rx_content_length,
  672. },
  673. {
  674. .header = "Transfer-Encoding",
  675. .rx = http_rx_transfer_encoding,
  676. },
  677. {
  678. .header = "Connection",
  679. .rx = http_rx_connection,
  680. },
  681. {
  682. .header = "WWW-Authenticate",
  683. .rx = http_rx_www_authenticate,
  684. },
  685. {
  686. .header = "Retry-After",
  687. .rx = http_rx_retry_after,
  688. },
  689. { NULL, NULL }
  690. };
  691. /**
  692. * Handle HTTP header
  693. *
  694. * @v http HTTP request
  695. * @v header HTTP header
  696. * @ret rc Return status code
  697. */
  698. static int http_rx_header ( struct http_request *http, char *header ) {
  699. struct http_header_handler *handler;
  700. char *separator;
  701. char *value;
  702. int rc;
  703. /* An empty header line marks the end of this phase */
  704. if ( ! header[0] ) {
  705. empty_line_buffer ( &http->linebuf );
  706. /* Handle response code */
  707. if ( ! ( http->flags & HTTP_TRY_AGAIN ) ) {
  708. if ( ( rc = http_response_to_rc ( http->code ) ) != 0 )
  709. return rc;
  710. }
  711. /* Move to next state */
  712. if ( http->rx_state == HTTP_RX_HEADER ) {
  713. DBGC ( http, "HTTP %p start of data\n", http );
  714. http->rx_state = ( http->chunked ?
  715. HTTP_RX_CHUNK_LEN : HTTP_RX_DATA );
  716. if ( ( http->partial_len != 0 ) &&
  717. ( ! ( http->flags & HTTP_TRY_AGAIN ) ) ) {
  718. http->remaining = http->partial_len;
  719. }
  720. return 0;
  721. } else {
  722. DBGC ( http, "HTTP %p end of trailer\n", http );
  723. http_done ( http );
  724. return 0;
  725. }
  726. }
  727. DBGC ( http, "HTTP %p header \"%s\"\n", http, header );
  728. /* Split header at the ": " */
  729. separator = strstr ( header, ": " );
  730. if ( ! separator ) {
  731. DBGC ( http, "HTTP %p malformed header\n", http );
  732. return -EINVAL_HEADER;
  733. }
  734. *separator = '\0';
  735. value = ( separator + 2 );
  736. /* Hand off to header handler, if one exists */
  737. for ( handler = http_header_handlers ; handler->header ; handler++ ) {
  738. if ( strcasecmp ( header, handler->header ) == 0 ) {
  739. if ( ( rc = handler->rx ( http, value ) ) != 0 )
  740. return rc;
  741. break;
  742. }
  743. }
  744. return 0;
  745. }
  746. /**
  747. * Handle HTTP chunk length
  748. *
  749. * @v http HTTP request
  750. * @v length HTTP chunk length
  751. * @ret rc Return status code
  752. */
  753. static int http_rx_chunk_len ( struct http_request *http, char *length ) {
  754. char *endp;
  755. /* Skip blank lines between chunks */
  756. if ( length[0] == '\0' )
  757. return 0;
  758. /* Parse chunk length */
  759. http->chunk_remaining = strtoul ( length, &endp, 16 );
  760. if ( *endp != '\0' ) {
  761. DBGC ( http, "HTTP %p invalid chunk length \"%s\"\n",
  762. http, length );
  763. return -EINVAL_CHUNK_LENGTH;
  764. }
  765. /* Terminate chunked encoding if applicable */
  766. if ( http->chunk_remaining == 0 ) {
  767. DBGC ( http, "HTTP %p end of chunks\n", http );
  768. http->chunked = 0;
  769. http->rx_state = HTTP_RX_TRAILER;
  770. return 0;
  771. }
  772. /* Use seek() to notify recipient of new filesize */
  773. DBGC ( http, "HTTP %p start of chunk of length %zd\n",
  774. http, http->chunk_remaining );
  775. if ( ! ( http->flags & HTTP_TRY_AGAIN ) ) {
  776. xfer_seek ( &http->xfer,
  777. ( http->rx_len + http->chunk_remaining ) );
  778. xfer_seek ( &http->xfer, http->rx_len );
  779. }
  780. /* Start receiving data */
  781. http->rx_state = HTTP_RX_DATA;
  782. return 0;
  783. }
  784. /** An HTTP line-based data handler */
  785. struct http_line_handler {
  786. /** Handle line
  787. *
  788. * @v http HTTP request
  789. * @v line Line to handle
  790. * @ret rc Return status code
  791. */
  792. int ( * rx ) ( struct http_request *http, char *line );
  793. };
  794. /** List of HTTP line-based data handlers */
  795. static struct http_line_handler http_line_handlers[] = {
  796. [HTTP_RX_RESPONSE] = { .rx = http_rx_response },
  797. [HTTP_RX_HEADER] = { .rx = http_rx_header },
  798. [HTTP_RX_CHUNK_LEN] = { .rx = http_rx_chunk_len },
  799. [HTTP_RX_TRAILER] = { .rx = http_rx_header },
  800. };
  801. /**
  802. * Handle new data arriving via HTTP connection
  803. *
  804. * @v http HTTP request
  805. * @v iobuf I/O buffer
  806. * @v meta Data transfer metadata
  807. * @ret rc Return status code
  808. */
  809. static int http_socket_deliver ( struct http_request *http,
  810. struct io_buffer *iobuf,
  811. struct xfer_metadata *meta __unused ) {
  812. struct http_line_handler *lh;
  813. char *line;
  814. size_t data_len;
  815. ssize_t line_len;
  816. int rc = 0;
  817. profile_start ( &http_rx_profiler );
  818. while ( iobuf && iob_len ( iobuf ) ) {
  819. switch ( http->rx_state ) {
  820. case HTTP_RX_IDLE:
  821. /* Receiving any data in this state is an error */
  822. DBGC ( http, "HTTP %p received %zd bytes while %s\n",
  823. http, iob_len ( iobuf ),
  824. ( ( http->rx_state == HTTP_RX_IDLE ) ?
  825. "idle" : "dead" ) );
  826. rc = -EPROTO_UNSOLICITED;
  827. goto done;
  828. case HTTP_RX_DEAD:
  829. /* Do no further processing */
  830. goto done;
  831. case HTTP_RX_DATA:
  832. /* Pass received data to caller */
  833. data_len = iob_len ( iobuf );
  834. if ( http->chunk_remaining &&
  835. ( http->chunk_remaining < data_len ) ) {
  836. data_len = http->chunk_remaining;
  837. }
  838. if ( http->remaining &&
  839. ( http->remaining < data_len ) ) {
  840. data_len = http->remaining;
  841. }
  842. if ( http->flags & HTTP_TRY_AGAIN ) {
  843. /* Discard all received data */
  844. iob_pull ( iobuf, data_len );
  845. } else if ( http->rx_buffer != UNULL ) {
  846. /* Copy to partial transfer buffer */
  847. copy_to_user ( http->rx_buffer, http->rx_len,
  848. iobuf->data, data_len );
  849. iob_pull ( iobuf, data_len );
  850. } else if ( data_len < iob_len ( iobuf ) ) {
  851. /* Deliver partial buffer as raw data */
  852. profile_start ( &http_xfer_profiler );
  853. rc = xfer_deliver_raw ( &http->xfer,
  854. iobuf->data, data_len );
  855. iob_pull ( iobuf, data_len );
  856. if ( rc != 0 )
  857. goto done;
  858. profile_stop ( &http_xfer_profiler );
  859. } else {
  860. /* Deliver whole I/O buffer */
  861. profile_start ( &http_xfer_profiler );
  862. if ( ( rc = xfer_deliver_iob ( &http->xfer,
  863. iob_disown ( iobuf ) ) ) != 0 )
  864. goto done;
  865. profile_stop ( &http_xfer_profiler );
  866. }
  867. http->rx_len += data_len;
  868. if ( http->chunk_remaining ) {
  869. http->chunk_remaining -= data_len;
  870. if ( http->chunk_remaining == 0 )
  871. http->rx_state = HTTP_RX_CHUNK_LEN;
  872. }
  873. if ( http->remaining ) {
  874. http->remaining -= data_len;
  875. if ( ( http->remaining == 0 ) &&
  876. ( http->rx_state == HTTP_RX_DATA ) ) {
  877. http_done ( http );
  878. }
  879. }
  880. break;
  881. case HTTP_RX_RESPONSE:
  882. case HTTP_RX_HEADER:
  883. case HTTP_RX_CHUNK_LEN:
  884. case HTTP_RX_TRAILER:
  885. /* In the other phases, buffer and process a
  886. * line at a time
  887. */
  888. line_len = line_buffer ( &http->linebuf, iobuf->data,
  889. iob_len ( iobuf ) );
  890. if ( line_len < 0 ) {
  891. rc = line_len;
  892. DBGC ( http, "HTTP %p could not buffer line: "
  893. "%s\n", http, strerror ( rc ) );
  894. goto done;
  895. }
  896. iob_pull ( iobuf, line_len );
  897. line = buffered_line ( &http->linebuf );
  898. if ( line ) {
  899. lh = &http_line_handlers[http->rx_state];
  900. if ( ( rc = lh->rx ( http, line ) ) != 0 )
  901. goto done;
  902. }
  903. break;
  904. default:
  905. assert ( 0 );
  906. break;
  907. }
  908. }
  909. done:
  910. if ( rc )
  911. http_close ( http, rc );
  912. free_iob ( iobuf );
  913. profile_stop ( &http_rx_profiler );
  914. return rc;
  915. }
  916. /**
  917. * Check HTTP socket flow control window
  918. *
  919. * @v http HTTP request
  920. * @ret len Length of window
  921. */
  922. static size_t http_socket_window ( struct http_request *http __unused ) {
  923. /* Window is always open. This is to prevent TCP from
  924. * stalling if our parent window is not currently open.
  925. */
  926. return ( ~( ( size_t ) 0 ) );
  927. }
  928. /**
  929. * Close HTTP socket
  930. *
  931. * @v http HTTP request
  932. * @v rc Reason for close
  933. */
  934. static void http_socket_close ( struct http_request *http, int rc ) {
  935. /* If we have an error, terminate */
  936. if ( rc != 0 ) {
  937. http_close ( http, rc );
  938. return;
  939. }
  940. /* Mark HTTP request as complete */
  941. http_done ( http );
  942. }
  943. /**
  944. * Generate HTTP Basic authorisation string
  945. *
  946. * @v http HTTP request
  947. * @ret auth Authorisation string, or NULL on error
  948. *
  949. * The authorisation string is dynamically allocated, and must be
  950. * freed by the caller.
  951. */
  952. static char * http_basic_auth ( struct http_request *http ) {
  953. const char *user = http->uri->user;
  954. const char *password = ( http->uri->password ?
  955. http->uri->password : "" );
  956. size_t user_pw_len =
  957. ( strlen ( user ) + 1 /* ":" */ + strlen ( password ) );
  958. char user_pw[ user_pw_len + 1 /* NUL */ ];
  959. size_t user_pw_base64_len = base64_encoded_len ( user_pw_len );
  960. char user_pw_base64[ user_pw_base64_len + 1 /* NUL */ ];
  961. char *auth;
  962. int len;
  963. /* Sanity check */
  964. assert ( user != NULL );
  965. /* Make "user:password" string from decoded fields */
  966. snprintf ( user_pw, sizeof ( user_pw ), "%s:%s", user, password );
  967. /* Base64-encode the "user:password" string */
  968. base64_encode ( ( void * ) user_pw, user_pw_len, user_pw_base64 );
  969. /* Generate the authorisation string */
  970. len = asprintf ( &auth, "Authorization: Basic %s\r\n",
  971. user_pw_base64 );
  972. if ( len < 0 )
  973. return NULL;
  974. return auth;
  975. }
  976. /**
  977. * Initialise HTTP digest
  978. *
  979. * @v ctx Digest context
  980. * @v string Initial string
  981. */
  982. static void http_digest_init ( struct md5_context *ctx ) {
  983. digest_init ( &md5_algorithm, ctx );
  984. }
  985. /**
  986. * Update HTTP digest with new data
  987. *
  988. * @v ctx Digest context
  989. * @v string String to append
  990. */
  991. static void http_digest_update ( struct md5_context *ctx, const char *string ) {
  992. static const char colon = ':';
  993. if ( ctx->len )
  994. digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
  995. digest_update ( &md5_algorithm, ctx, string, strlen ( string ) );
  996. }
  997. /**
  998. * Finalise HTTP digest
  999. *
  1000. * @v ctx Digest context
  1001. * @v out Buffer for digest output
  1002. * @v len Buffer length
  1003. */
  1004. static void http_digest_final ( struct md5_context *ctx, char *out,
  1005. size_t len ) {
  1006. uint8_t digest[MD5_DIGEST_SIZE];
  1007. digest_final ( &md5_algorithm, ctx, digest );
  1008. base16_encode ( digest, sizeof ( digest ), out, len );
  1009. }
  1010. /**
  1011. * Generate HTTP Digest authorisation string
  1012. *
  1013. * @v http HTTP request
  1014. * @v method HTTP method (e.g. "GET")
  1015. * @v uri HTTP request URI (e.g. "/index.html")
  1016. * @ret auth Authorisation string, or NULL on error
  1017. *
  1018. * The authorisation string is dynamically allocated, and must be
  1019. * freed by the caller.
  1020. */
  1021. static char * http_digest_auth ( struct http_request *http,
  1022. const char *method, const char *uri ) {
  1023. const char *user = http->uri->user;
  1024. const char *password = ( http->uri->password ?
  1025. http->uri->password : "" );
  1026. const char *realm = http->auth_realm;
  1027. const char *nonce = http->auth_nonce;
  1028. const char *opaque = http->auth_opaque;
  1029. char cnonce[ 9 /* "xxxxxxxx" + NUL */ ];
  1030. struct md5_context ctx;
  1031. char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
  1032. char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
  1033. char response[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
  1034. int qop = ( http->flags & HTTP_DIGEST_AUTH_QOP );
  1035. int md5sess = ( qop && ( http->flags & HTTP_DIGEST_AUTH_MD5_SESS ) );
  1036. char *auth;
  1037. int len;
  1038. /* Sanity checks */
  1039. assert ( user != NULL );
  1040. assert ( realm != NULL );
  1041. assert ( nonce != NULL );
  1042. /* Generate a client nonce */
  1043. snprintf ( cnonce, sizeof ( cnonce ), "%08lx", random() );
  1044. /* Generate HA1 */
  1045. http_digest_init ( &ctx );
  1046. http_digest_update ( &ctx, user );
  1047. http_digest_update ( &ctx, realm );
  1048. http_digest_update ( &ctx, password );
  1049. http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
  1050. if ( md5sess ) {
  1051. http_digest_init ( &ctx );
  1052. http_digest_update ( &ctx, ha1 );
  1053. http_digest_update ( &ctx, nonce );
  1054. http_digest_update ( &ctx, cnonce );
  1055. http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
  1056. }
  1057. /* Generate HA2 */
  1058. http_digest_init ( &ctx );
  1059. http_digest_update ( &ctx, method );
  1060. http_digest_update ( &ctx, uri );
  1061. http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );
  1062. /* Generate response */
  1063. http_digest_init ( &ctx );
  1064. http_digest_update ( &ctx, ha1 );
  1065. http_digest_update ( &ctx, nonce );
  1066. if ( qop ) {
  1067. http_digest_update ( &ctx, "00000001" /* nc */ );
  1068. http_digest_update ( &ctx, cnonce );
  1069. http_digest_update ( &ctx, "auth" /* qop */ );
  1070. }
  1071. http_digest_update ( &ctx, ha2 );
  1072. http_digest_final ( &ctx, response, sizeof ( response ) );
  1073. /* Generate the authorisation string */
  1074. len = asprintf ( &auth, "Authorization: Digest username=\"%s\", "
  1075. "realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
  1076. "%s%s%s%s%s%s%s%sresponse=\"%s\"\r\n",
  1077. user, realm, nonce, uri,
  1078. ( qop ? "qop=\"auth\", algorithm=" : "" ),
  1079. ( qop ? ( md5sess ? "MD5-sess, " : "MD5, " ) : "" ),
  1080. ( qop ? "nc=00000001, cnonce=\"" : "" ),
  1081. ( qop ? cnonce : "" ),
  1082. ( qop ? "\", " : "" ),
  1083. ( opaque ? "opaque=\"" : "" ),
  1084. ( opaque ? opaque : "" ),
  1085. ( opaque ? "\", " : "" ), response );
  1086. if ( len < 0 )
  1087. return NULL;
  1088. return auth;
  1089. }
  1090. /**
  1091. * Generate HTTP POST parameter list
  1092. *
  1093. * @v http HTTP request
  1094. * @v buf Buffer to contain HTTP POST parameters
  1095. * @v len Length of buffer
  1096. * @ret len Length of parameter list (excluding terminating NUL)
  1097. */
  1098. static size_t http_post_params ( struct http_request *http,
  1099. char *buf, size_t len ) {
  1100. struct parameter *param;
  1101. ssize_t remaining = len;
  1102. size_t frag_len;
  1103. /* Add each parameter in the form "key=value", joined with "&" */
  1104. len = 0;
  1105. for_each_param ( param, http->uri->params ) {
  1106. /* Add the "&", if applicable */
  1107. if ( len ) {
  1108. if ( remaining > 0 )
  1109. *buf = '&';
  1110. buf++;
  1111. len++;
  1112. remaining--;
  1113. }
  1114. /* URI-encode the key */
  1115. frag_len = uri_encode ( param->key, 0, buf, remaining );
  1116. buf += frag_len;
  1117. len += frag_len;
  1118. remaining -= frag_len;
  1119. /* Add the "=" */
  1120. if ( remaining > 0 )
  1121. *buf = '=';
  1122. buf++;
  1123. len++;
  1124. remaining--;
  1125. /* URI-encode the value */
  1126. frag_len = uri_encode ( param->value, 0, buf, remaining );
  1127. buf += frag_len;
  1128. len += frag_len;
  1129. remaining -= frag_len;
  1130. }
  1131. /* Ensure string is NUL-terminated even if no parameters are present */
  1132. if ( remaining > 0 )
  1133. *buf = '\0';
  1134. return len;
  1135. }
  1136. /**
  1137. * Generate HTTP POST body
  1138. *
  1139. * @v http HTTP request
  1140. * @ret post I/O buffer containing POST body, or NULL on error
  1141. */
  1142. static struct io_buffer * http_post ( struct http_request *http ) {
  1143. struct io_buffer *post;
  1144. size_t len;
  1145. size_t check_len;
  1146. /* Calculate length of parameter list */
  1147. len = http_post_params ( http, NULL, 0 );
  1148. /* Allocate parameter list */
  1149. post = alloc_iob ( len + 1 /* NUL */ );
  1150. if ( ! post )
  1151. return NULL;
  1152. /* Fill parameter list */
  1153. check_len = http_post_params ( http, iob_put ( post, len ),
  1154. ( len + 1 /* NUL */ ) );
  1155. assert ( len == check_len );
  1156. DBGC ( http, "HTTP %p POST %s\n", http, ( ( char * ) post->data ) );
  1157. return post;
  1158. }
  1159. /**
  1160. * HTTP process
  1161. *
  1162. * @v http HTTP request
  1163. */
  1164. static void http_step ( struct http_request *http ) {
  1165. struct io_buffer *post;
  1166. struct uri host_uri;
  1167. struct uri path_uri;
  1168. char *host_uri_string;
  1169. char *path_uri_string;
  1170. char *method;
  1171. char *range;
  1172. char *auth;
  1173. char *content;
  1174. int len;
  1175. int rc;
  1176. /* Do nothing if we have already transmitted the request */
  1177. if ( ! ( http->flags & HTTP_TX_PENDING ) )
  1178. return;
  1179. /* Do nothing until socket is ready */
  1180. if ( ! xfer_window ( &http->socket ) )
  1181. return;
  1182. /* Force a HEAD request if we have nowhere to send any received data */
  1183. if ( ( xfer_window ( &http->xfer ) == 0 ) &&
  1184. ( http->rx_buffer == UNULL ) ) {
  1185. http->flags |= ( HTTP_HEAD_ONLY | HTTP_CLIENT_KEEPALIVE );
  1186. }
  1187. /* Determine method */
  1188. method = ( ( http->flags & HTTP_HEAD_ONLY ) ? "HEAD" :
  1189. ( http->uri->params ? "POST" : "GET" ) );
  1190. /* Construct host URI */
  1191. memset ( &host_uri, 0, sizeof ( host_uri ) );
  1192. host_uri.host = http->uri->host;
  1193. host_uri.port = http->uri->port;
  1194. host_uri_string = format_uri_alloc ( &host_uri );
  1195. if ( ! host_uri_string ) {
  1196. rc = -ENOMEM;
  1197. goto err_host_uri;
  1198. }
  1199. /* Construct path URI */
  1200. memset ( &path_uri, 0, sizeof ( path_uri ) );
  1201. path_uri.path = ( http->uri->path ? http->uri->path : "/" );
  1202. path_uri.query = http->uri->query;
  1203. path_uri_string = format_uri_alloc ( &path_uri );
  1204. if ( ! path_uri_string ) {
  1205. rc = -ENOMEM;
  1206. goto err_path_uri;
  1207. }
  1208. /* Calculate range request parameters if applicable */
  1209. if ( http->partial_len ) {
  1210. len = asprintf ( &range, "Range: bytes=%zd-%zd\r\n",
  1211. http->partial_start,
  1212. ( http->partial_start + http->partial_len
  1213. - 1 ) );
  1214. if ( len < 0 ) {
  1215. rc = len;
  1216. goto err_range;
  1217. }
  1218. } else {
  1219. range = NULL;
  1220. }
  1221. /* Construct authorisation, if applicable */
  1222. if ( http->flags & HTTP_BASIC_AUTH ) {
  1223. auth = http_basic_auth ( http );
  1224. if ( ! auth ) {
  1225. rc = -ENOMEM;
  1226. goto err_auth;
  1227. }
  1228. } else if ( http->flags & HTTP_DIGEST_AUTH ) {
  1229. auth = http_digest_auth ( http, method, path_uri_string );
  1230. if ( ! auth ) {
  1231. rc = -ENOMEM;
  1232. goto err_auth;
  1233. }
  1234. } else {
  1235. auth = NULL;
  1236. }
  1237. /* Construct POST content, if applicable */
  1238. if ( http->uri->params ) {
  1239. post = http_post ( http );
  1240. if ( ! post ) {
  1241. rc = -ENOMEM;
  1242. goto err_post;
  1243. }
  1244. len = asprintf ( &content, "Content-Type: "
  1245. "application/x-www-form-urlencoded\r\n"
  1246. "Content-Length: %zd\r\n", iob_len ( post ) );
  1247. if ( len < 0 ) {
  1248. rc = len;
  1249. goto err_content;
  1250. }
  1251. } else {
  1252. post = NULL;
  1253. content = NULL;
  1254. }
  1255. /* Mark request as transmitted */
  1256. http->flags &= ~HTTP_TX_PENDING;
  1257. /* Send request */
  1258. if ( ( rc = xfer_printf ( &http->socket,
  1259. "%s %s HTTP/1.1\r\n"
  1260. "User-Agent: iPXE/%s\r\n"
  1261. "Host: %s\r\n"
  1262. "%s%s%s%s"
  1263. "\r\n",
  1264. method, path_uri_string, product_version,
  1265. host_uri_string,
  1266. ( ( http->flags & HTTP_CLIENT_KEEPALIVE ) ?
  1267. "Connection: keep-alive\r\n" : "" ),
  1268. ( range ? range : "" ),
  1269. ( auth ? auth : "" ),
  1270. ( content ? content : "" ) ) ) != 0 ) {
  1271. goto err_xfer;
  1272. }
  1273. /* Send POST content, if applicable */
  1274. if ( post ) {
  1275. if ( ( rc = xfer_deliver_iob ( &http->socket,
  1276. iob_disown ( post ) ) ) != 0 )
  1277. goto err_xfer_post;
  1278. }
  1279. err_xfer_post:
  1280. err_xfer:
  1281. free ( content );
  1282. err_content:
  1283. free ( post );
  1284. err_post:
  1285. free ( auth );
  1286. err_auth:
  1287. free ( range );
  1288. err_range:
  1289. free ( path_uri_string );
  1290. err_path_uri:
  1291. free ( host_uri_string );
  1292. err_host_uri:
  1293. if ( rc != 0 )
  1294. http_close ( http, rc );
  1295. }
  1296. /**
  1297. * Check HTTP data transfer flow control window
  1298. *
  1299. * @v http HTTP request
  1300. * @ret len Length of window
  1301. */
  1302. static size_t http_xfer_window ( struct http_request *http ) {
  1303. /* New block commands may be issued only when we are idle */
  1304. return ( ( http->rx_state == HTTP_RX_IDLE ) ? 1 : 0 );
  1305. }
  1306. /**
  1307. * Initiate HTTP partial read
  1308. *
  1309. * @v http HTTP request
  1310. * @v partial Partial transfer interface
  1311. * @v offset Starting offset
  1312. * @v buffer Data buffer
  1313. * @v len Length
  1314. * @ret rc Return status code
  1315. */
  1316. static int http_partial_read ( struct http_request *http,
  1317. struct interface *partial,
  1318. size_t offset, userptr_t buffer, size_t len ) {
  1319. /* Sanity check */
  1320. if ( http_xfer_window ( http ) == 0 )
  1321. return -EBUSY;
  1322. /* Initialise partial transfer parameters */
  1323. http->rx_buffer = buffer;
  1324. http->partial_start = offset;
  1325. http->partial_len = len;
  1326. /* Schedule request */
  1327. http->rx_state = HTTP_RX_RESPONSE;
  1328. http->flags = ( HTTP_TX_PENDING | HTTP_CLIENT_KEEPALIVE );
  1329. if ( ! len )
  1330. http->flags |= HTTP_HEAD_ONLY;
  1331. process_add ( &http->process );
  1332. /* Attach to parent interface and return */
  1333. intf_plug_plug ( &http->partial, partial );
  1334. return 0;
  1335. }
  1336. /**
  1337. * Issue HTTP block device read
  1338. *
  1339. * @v http HTTP request
  1340. * @v block Block data interface
  1341. * @v lba Starting logical block address
  1342. * @v count Number of blocks to transfer
  1343. * @v buffer Data buffer
  1344. * @v len Length of data buffer
  1345. * @ret rc Return status code
  1346. */
  1347. static int http_block_read ( struct http_request *http,
  1348. struct interface *block,
  1349. uint64_t lba, unsigned int count,
  1350. userptr_t buffer, size_t len __unused ) {
  1351. return http_partial_read ( http, block, ( lba * HTTP_BLKSIZE ),
  1352. buffer, ( count * HTTP_BLKSIZE ) );
  1353. }
  1354. /**
  1355. * Read HTTP block device capacity
  1356. *
  1357. * @v http HTTP request
  1358. * @v block Block data interface
  1359. * @ret rc Return status code
  1360. */
  1361. static int http_block_read_capacity ( struct http_request *http,
  1362. struct interface *block ) {
  1363. return http_partial_read ( http, block, 0, 0, 0 );
  1364. }
  1365. /**
  1366. * Describe HTTP device in an ACPI table
  1367. *
  1368. * @v http HTTP request
  1369. * @v acpi ACPI table
  1370. * @v len Length of ACPI table
  1371. * @ret rc Return status code
  1372. */
  1373. static int http_acpi_describe ( struct http_request *http,
  1374. struct acpi_description_header *acpi,
  1375. size_t len ) {
  1376. DBGC ( http, "HTTP %p cannot yet describe device in an ACPI table\n",
  1377. http );
  1378. ( void ) acpi;
  1379. ( void ) len;
  1380. return 0;
  1381. }
  1382. /** HTTP socket interface operations */
  1383. static struct interface_operation http_socket_operations[] = {
  1384. INTF_OP ( xfer_window, struct http_request *, http_socket_window ),
  1385. INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ),
  1386. INTF_OP ( xfer_window_changed, struct http_request *, http_step ),
  1387. INTF_OP ( intf_close, struct http_request *, http_socket_close ),
  1388. };
  1389. /** HTTP socket interface descriptor */
  1390. static struct interface_descriptor http_socket_desc =
  1391. INTF_DESC_PASSTHRU ( struct http_request, socket,
  1392. http_socket_operations, xfer );
  1393. /** HTTP partial transfer interface operations */
  1394. static struct interface_operation http_partial_operations[] = {
  1395. INTF_OP ( intf_close, struct http_request *, http_close ),
  1396. };
  1397. /** HTTP partial transfer interface descriptor */
  1398. static struct interface_descriptor http_partial_desc =
  1399. INTF_DESC ( struct http_request, partial, http_partial_operations );
  1400. /** HTTP data transfer interface operations */
  1401. static struct interface_operation http_xfer_operations[] = {
  1402. INTF_OP ( xfer_window, struct http_request *, http_xfer_window ),
  1403. INTF_OP ( block_read, struct http_request *, http_block_read ),
  1404. INTF_OP ( block_read_capacity, struct http_request *,
  1405. http_block_read_capacity ),
  1406. INTF_OP ( intf_close, struct http_request *, http_close ),
  1407. INTF_OP ( acpi_describe, struct http_request *, http_acpi_describe ),
  1408. };
  1409. /** HTTP data transfer interface descriptor */
  1410. static struct interface_descriptor http_xfer_desc =
  1411. INTF_DESC_PASSTHRU ( struct http_request, xfer,
  1412. http_xfer_operations, socket );
  1413. /** HTTP process descriptor */
  1414. static struct process_descriptor http_process_desc =
  1415. PROC_DESC_ONCE ( struct http_request, process, http_step );
  1416. /**
  1417. * Initiate an HTTP connection, with optional filter
  1418. *
  1419. * @v xfer Data transfer interface
  1420. * @v uri Uniform Resource Identifier
  1421. * @v default_port Default port number
  1422. * @v filter Filter to apply to socket, or NULL
  1423. * @ret rc Return status code
  1424. */
  1425. int http_open_filter ( struct interface *xfer, struct uri *uri,
  1426. unsigned int default_port,
  1427. int ( * filter ) ( struct interface *xfer,
  1428. const char *name,
  1429. struct interface **next ) ) {
  1430. struct http_request *http;
  1431. int rc;
  1432. /* Sanity checks */
  1433. if ( ! uri->host )
  1434. return -EINVAL;
  1435. /* Allocate and populate HTTP structure */
  1436. http = zalloc ( sizeof ( *http ) );
  1437. if ( ! http )
  1438. return -ENOMEM;
  1439. ref_init ( &http->refcnt, http_free );
  1440. intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt );
  1441. intf_init ( &http->partial, &http_partial_desc, &http->refcnt );
  1442. http->uri = uri_get ( uri );
  1443. http->default_port = default_port;
  1444. http->filter = filter;
  1445. intf_init ( &http->socket, &http_socket_desc, &http->refcnt );
  1446. process_init ( &http->process, &http_process_desc, &http->refcnt );
  1447. timer_init ( &http->timer, http_retry, &http->refcnt );
  1448. http->flags = HTTP_TX_PENDING;
  1449. /* Open socket */
  1450. if ( ( rc = http_socket_open ( http ) ) != 0 )
  1451. goto err;
  1452. /* Attach to parent interface, mortalise self, and return */
  1453. intf_plug_plug ( &http->xfer, xfer );
  1454. ref_put ( &http->refcnt );
  1455. return 0;
  1456. err:
  1457. DBGC ( http, "HTTP %p could not create request: %s\n",
  1458. http, strerror ( rc ) );
  1459. http_close ( http, rc );
  1460. ref_put ( &http->refcnt );
  1461. return rc;
  1462. }