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 43KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649
  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 ( user_pw, user_pw_len, user_pw_base64,
  969. sizeof ( user_pw_base64 ) );
  970. /* Generate the authorisation string */
  971. len = asprintf ( &auth, "Authorization: Basic %s\r\n",
  972. user_pw_base64 );
  973. if ( len < 0 )
  974. return NULL;
  975. return auth;
  976. }
  977. /**
  978. * Initialise HTTP digest
  979. *
  980. * @v ctx Digest context
  981. * @v string Initial string
  982. */
  983. static void http_digest_init ( struct md5_context *ctx ) {
  984. digest_init ( &md5_algorithm, ctx );
  985. }
  986. /**
  987. * Update HTTP digest with new data
  988. *
  989. * @v ctx Digest context
  990. * @v string String to append
  991. */
  992. static void http_digest_update ( struct md5_context *ctx, const char *string ) {
  993. static const char colon = ':';
  994. if ( ctx->len )
  995. digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
  996. digest_update ( &md5_algorithm, ctx, string, strlen ( string ) );
  997. }
  998. /**
  999. * Finalise HTTP digest
  1000. *
  1001. * @v ctx Digest context
  1002. * @v out Buffer for digest output
  1003. * @v len Buffer length
  1004. */
  1005. static void http_digest_final ( struct md5_context *ctx, char *out,
  1006. size_t len ) {
  1007. uint8_t digest[MD5_DIGEST_SIZE];
  1008. digest_final ( &md5_algorithm, ctx, digest );
  1009. base16_encode ( digest, sizeof ( digest ), out, len );
  1010. }
  1011. /**
  1012. * Generate HTTP Digest authorisation string
  1013. *
  1014. * @v http HTTP request
  1015. * @v method HTTP method (e.g. "GET")
  1016. * @v uri HTTP request URI (e.g. "/index.html")
  1017. * @ret auth Authorisation string, or NULL on error
  1018. *
  1019. * The authorisation string is dynamically allocated, and must be
  1020. * freed by the caller.
  1021. */
  1022. static char * http_digest_auth ( struct http_request *http,
  1023. const char *method, const char *uri ) {
  1024. const char *user = http->uri->user;
  1025. const char *password = ( http->uri->password ?
  1026. http->uri->password : "" );
  1027. const char *realm = http->auth_realm;
  1028. const char *nonce = http->auth_nonce;
  1029. const char *opaque = http->auth_opaque;
  1030. char cnonce[ 9 /* "xxxxxxxx" + NUL */ ];
  1031. struct md5_context ctx;
  1032. char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
  1033. char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
  1034. char response[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
  1035. int qop = ( http->flags & HTTP_DIGEST_AUTH_QOP );
  1036. int md5sess = ( qop && ( http->flags & HTTP_DIGEST_AUTH_MD5_SESS ) );
  1037. char *auth;
  1038. int len;
  1039. /* Sanity checks */
  1040. assert ( user != NULL );
  1041. assert ( realm != NULL );
  1042. assert ( nonce != NULL );
  1043. /* Generate a client nonce */
  1044. snprintf ( cnonce, sizeof ( cnonce ), "%08lx", random() );
  1045. /* Generate HA1 */
  1046. http_digest_init ( &ctx );
  1047. http_digest_update ( &ctx, user );
  1048. http_digest_update ( &ctx, realm );
  1049. http_digest_update ( &ctx, password );
  1050. http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
  1051. if ( md5sess ) {
  1052. http_digest_init ( &ctx );
  1053. http_digest_update ( &ctx, ha1 );
  1054. http_digest_update ( &ctx, nonce );
  1055. http_digest_update ( &ctx, cnonce );
  1056. http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
  1057. }
  1058. /* Generate HA2 */
  1059. http_digest_init ( &ctx );
  1060. http_digest_update ( &ctx, method );
  1061. http_digest_update ( &ctx, uri );
  1062. http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );
  1063. /* Generate response */
  1064. http_digest_init ( &ctx );
  1065. http_digest_update ( &ctx, ha1 );
  1066. http_digest_update ( &ctx, nonce );
  1067. if ( qop ) {
  1068. http_digest_update ( &ctx, "00000001" /* nc */ );
  1069. http_digest_update ( &ctx, cnonce );
  1070. http_digest_update ( &ctx, "auth" /* qop */ );
  1071. }
  1072. http_digest_update ( &ctx, ha2 );
  1073. http_digest_final ( &ctx, response, sizeof ( response ) );
  1074. /* Generate the authorisation string */
  1075. len = asprintf ( &auth, "Authorization: Digest username=\"%s\", "
  1076. "realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
  1077. "%s%s%s%s%s%s%s%sresponse=\"%s\"\r\n",
  1078. user, realm, nonce, uri,
  1079. ( qop ? "qop=\"auth\", algorithm=" : "" ),
  1080. ( qop ? ( md5sess ? "MD5-sess, " : "MD5, " ) : "" ),
  1081. ( qop ? "nc=00000001, cnonce=\"" : "" ),
  1082. ( qop ? cnonce : "" ),
  1083. ( qop ? "\", " : "" ),
  1084. ( opaque ? "opaque=\"" : "" ),
  1085. ( opaque ? opaque : "" ),
  1086. ( opaque ? "\", " : "" ), response );
  1087. if ( len < 0 )
  1088. return NULL;
  1089. return auth;
  1090. }
  1091. /**
  1092. * Generate HTTP POST parameter list
  1093. *
  1094. * @v http HTTP request
  1095. * @v buf Buffer to contain HTTP POST parameters
  1096. * @v len Length of buffer
  1097. * @ret len Length of parameter list (excluding terminating NUL)
  1098. */
  1099. static size_t http_post_params ( struct http_request *http,
  1100. char *buf, size_t len ) {
  1101. struct parameter *param;
  1102. ssize_t remaining = len;
  1103. size_t frag_len;
  1104. /* Add each parameter in the form "key=value", joined with "&" */
  1105. len = 0;
  1106. for_each_param ( param, http->uri->params ) {
  1107. /* Add the "&", if applicable */
  1108. if ( len ) {
  1109. if ( remaining > 0 )
  1110. *buf = '&';
  1111. buf++;
  1112. len++;
  1113. remaining--;
  1114. }
  1115. /* URI-encode the key */
  1116. frag_len = uri_encode ( param->key, 0, buf, remaining );
  1117. buf += frag_len;
  1118. len += frag_len;
  1119. remaining -= frag_len;
  1120. /* Add the "=" */
  1121. if ( remaining > 0 )
  1122. *buf = '=';
  1123. buf++;
  1124. len++;
  1125. remaining--;
  1126. /* URI-encode the value */
  1127. frag_len = uri_encode ( param->value, 0, buf, remaining );
  1128. buf += frag_len;
  1129. len += frag_len;
  1130. remaining -= frag_len;
  1131. }
  1132. /* Ensure string is NUL-terminated even if no parameters are present */
  1133. if ( remaining > 0 )
  1134. *buf = '\0';
  1135. return len;
  1136. }
  1137. /**
  1138. * Generate HTTP POST body
  1139. *
  1140. * @v http HTTP request
  1141. * @ret post I/O buffer containing POST body, or NULL on error
  1142. */
  1143. static struct io_buffer * http_post ( struct http_request *http ) {
  1144. struct io_buffer *post;
  1145. size_t len;
  1146. size_t check_len;
  1147. /* Calculate length of parameter list */
  1148. len = http_post_params ( http, NULL, 0 );
  1149. /* Allocate parameter list */
  1150. post = alloc_iob ( len + 1 /* NUL */ );
  1151. if ( ! post )
  1152. return NULL;
  1153. /* Fill parameter list */
  1154. check_len = http_post_params ( http, iob_put ( post, len ),
  1155. ( len + 1 /* NUL */ ) );
  1156. assert ( len == check_len );
  1157. DBGC ( http, "HTTP %p POST %s\n", http, ( ( char * ) post->data ) );
  1158. return post;
  1159. }
  1160. /**
  1161. * HTTP process
  1162. *
  1163. * @v http HTTP request
  1164. */
  1165. static void http_step ( struct http_request *http ) {
  1166. struct io_buffer *post;
  1167. struct uri host_uri;
  1168. struct uri path_uri;
  1169. char *host_uri_string;
  1170. char *path_uri_string;
  1171. char *method;
  1172. char *range;
  1173. char *auth;
  1174. char *content;
  1175. int len;
  1176. int rc;
  1177. /* Do nothing if we have already transmitted the request */
  1178. if ( ! ( http->flags & HTTP_TX_PENDING ) )
  1179. return;
  1180. /* Do nothing until socket is ready */
  1181. if ( ! xfer_window ( &http->socket ) )
  1182. return;
  1183. /* Force a HEAD request if we have nowhere to send any received data */
  1184. if ( ( xfer_window ( &http->xfer ) == 0 ) &&
  1185. ( http->rx_buffer == UNULL ) ) {
  1186. http->flags |= ( HTTP_HEAD_ONLY | HTTP_CLIENT_KEEPALIVE );
  1187. }
  1188. /* Determine method */
  1189. method = ( ( http->flags & HTTP_HEAD_ONLY ) ? "HEAD" :
  1190. ( http->uri->params ? "POST" : "GET" ) );
  1191. /* Construct host URI */
  1192. memset ( &host_uri, 0, sizeof ( host_uri ) );
  1193. host_uri.host = http->uri->host;
  1194. host_uri.port = http->uri->port;
  1195. host_uri_string = format_uri_alloc ( &host_uri );
  1196. if ( ! host_uri_string ) {
  1197. rc = -ENOMEM;
  1198. goto err_host_uri;
  1199. }
  1200. /* Construct path URI */
  1201. memset ( &path_uri, 0, sizeof ( path_uri ) );
  1202. path_uri.path = ( http->uri->path ? http->uri->path : "/" );
  1203. path_uri.query = http->uri->query;
  1204. path_uri_string = format_uri_alloc ( &path_uri );
  1205. if ( ! path_uri_string ) {
  1206. rc = -ENOMEM;
  1207. goto err_path_uri;
  1208. }
  1209. /* Calculate range request parameters if applicable */
  1210. if ( http->partial_len ) {
  1211. len = asprintf ( &range, "Range: bytes=%zd-%zd\r\n",
  1212. http->partial_start,
  1213. ( http->partial_start + http->partial_len
  1214. - 1 ) );
  1215. if ( len < 0 ) {
  1216. rc = len;
  1217. goto err_range;
  1218. }
  1219. } else {
  1220. range = NULL;
  1221. }
  1222. /* Construct authorisation, if applicable */
  1223. if ( http->flags & HTTP_BASIC_AUTH ) {
  1224. auth = http_basic_auth ( http );
  1225. if ( ! auth ) {
  1226. rc = -ENOMEM;
  1227. goto err_auth;
  1228. }
  1229. } else if ( http->flags & HTTP_DIGEST_AUTH ) {
  1230. auth = http_digest_auth ( http, method, path_uri_string );
  1231. if ( ! auth ) {
  1232. rc = -ENOMEM;
  1233. goto err_auth;
  1234. }
  1235. } else {
  1236. auth = NULL;
  1237. }
  1238. /* Construct POST content, if applicable */
  1239. if ( http->uri->params ) {
  1240. post = http_post ( http );
  1241. if ( ! post ) {
  1242. rc = -ENOMEM;
  1243. goto err_post;
  1244. }
  1245. len = asprintf ( &content, "Content-Type: "
  1246. "application/x-www-form-urlencoded\r\n"
  1247. "Content-Length: %zd\r\n", iob_len ( post ) );
  1248. if ( len < 0 ) {
  1249. rc = len;
  1250. goto err_content;
  1251. }
  1252. } else {
  1253. post = NULL;
  1254. content = NULL;
  1255. }
  1256. /* Mark request as transmitted */
  1257. http->flags &= ~HTTP_TX_PENDING;
  1258. /* Send request */
  1259. if ( ( rc = xfer_printf ( &http->socket,
  1260. "%s %s HTTP/1.1\r\n"
  1261. "User-Agent: iPXE/%s\r\n"
  1262. "Host: %s\r\n"
  1263. "%s%s%s%s"
  1264. "\r\n",
  1265. method, path_uri_string, product_version,
  1266. host_uri_string,
  1267. ( ( http->flags & HTTP_CLIENT_KEEPALIVE ) ?
  1268. "Connection: keep-alive\r\n" : "" ),
  1269. ( range ? range : "" ),
  1270. ( auth ? auth : "" ),
  1271. ( content ? content : "" ) ) ) != 0 ) {
  1272. goto err_xfer;
  1273. }
  1274. /* Send POST content, if applicable */
  1275. if ( post ) {
  1276. if ( ( rc = xfer_deliver_iob ( &http->socket,
  1277. iob_disown ( post ) ) ) != 0 )
  1278. goto err_xfer_post;
  1279. }
  1280. err_xfer_post:
  1281. err_xfer:
  1282. free ( content );
  1283. err_content:
  1284. free ( post );
  1285. err_post:
  1286. free ( auth );
  1287. err_auth:
  1288. free ( range );
  1289. err_range:
  1290. free ( path_uri_string );
  1291. err_path_uri:
  1292. free ( host_uri_string );
  1293. err_host_uri:
  1294. if ( rc != 0 )
  1295. http_close ( http, rc );
  1296. }
  1297. /**
  1298. * Check HTTP data transfer flow control window
  1299. *
  1300. * @v http HTTP request
  1301. * @ret len Length of window
  1302. */
  1303. static size_t http_xfer_window ( struct http_request *http ) {
  1304. /* New block commands may be issued only when we are idle */
  1305. return ( ( http->rx_state == HTTP_RX_IDLE ) ? 1 : 0 );
  1306. }
  1307. /**
  1308. * Initiate HTTP partial read
  1309. *
  1310. * @v http HTTP request
  1311. * @v partial Partial transfer interface
  1312. * @v offset Starting offset
  1313. * @v buffer Data buffer
  1314. * @v len Length
  1315. * @ret rc Return status code
  1316. */
  1317. static int http_partial_read ( struct http_request *http,
  1318. struct interface *partial,
  1319. size_t offset, userptr_t buffer, size_t len ) {
  1320. /* Sanity check */
  1321. if ( http_xfer_window ( http ) == 0 )
  1322. return -EBUSY;
  1323. /* Initialise partial transfer parameters */
  1324. http->rx_buffer = buffer;
  1325. http->partial_start = offset;
  1326. http->partial_len = len;
  1327. /* Schedule request */
  1328. http->rx_state = HTTP_RX_RESPONSE;
  1329. http->flags = ( HTTP_TX_PENDING | HTTP_CLIENT_KEEPALIVE );
  1330. if ( ! len )
  1331. http->flags |= HTTP_HEAD_ONLY;
  1332. process_add ( &http->process );
  1333. /* Attach to parent interface and return */
  1334. intf_plug_plug ( &http->partial, partial );
  1335. return 0;
  1336. }
  1337. /**
  1338. * Issue HTTP block device read
  1339. *
  1340. * @v http HTTP request
  1341. * @v block Block data interface
  1342. * @v lba Starting logical block address
  1343. * @v count Number of blocks to transfer
  1344. * @v buffer Data buffer
  1345. * @v len Length of data buffer
  1346. * @ret rc Return status code
  1347. */
  1348. static int http_block_read ( struct http_request *http,
  1349. struct interface *block,
  1350. uint64_t lba, unsigned int count,
  1351. userptr_t buffer, size_t len __unused ) {
  1352. return http_partial_read ( http, block, ( lba * HTTP_BLKSIZE ),
  1353. buffer, ( count * HTTP_BLKSIZE ) );
  1354. }
  1355. /**
  1356. * Read HTTP block device capacity
  1357. *
  1358. * @v http HTTP request
  1359. * @v block Block data interface
  1360. * @ret rc Return status code
  1361. */
  1362. static int http_block_read_capacity ( struct http_request *http,
  1363. struct interface *block ) {
  1364. return http_partial_read ( http, block, 0, 0, 0 );
  1365. }
  1366. /**
  1367. * Describe HTTP device in an ACPI table
  1368. *
  1369. * @v http HTTP request
  1370. * @v acpi ACPI table
  1371. * @v len Length of ACPI table
  1372. * @ret rc Return status code
  1373. */
  1374. static int http_acpi_describe ( struct http_request *http,
  1375. struct acpi_description_header *acpi,
  1376. size_t len ) {
  1377. DBGC ( http, "HTTP %p cannot yet describe device in an ACPI table\n",
  1378. http );
  1379. ( void ) acpi;
  1380. ( void ) len;
  1381. return 0;
  1382. }
  1383. /** HTTP socket interface operations */
  1384. static struct interface_operation http_socket_operations[] = {
  1385. INTF_OP ( xfer_window, struct http_request *, http_socket_window ),
  1386. INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ),
  1387. INTF_OP ( xfer_window_changed, struct http_request *, http_step ),
  1388. INTF_OP ( intf_close, struct http_request *, http_socket_close ),
  1389. };
  1390. /** HTTP socket interface descriptor */
  1391. static struct interface_descriptor http_socket_desc =
  1392. INTF_DESC_PASSTHRU ( struct http_request, socket,
  1393. http_socket_operations, xfer );
  1394. /** HTTP partial transfer interface operations */
  1395. static struct interface_operation http_partial_operations[] = {
  1396. INTF_OP ( intf_close, struct http_request *, http_close ),
  1397. };
  1398. /** HTTP partial transfer interface descriptor */
  1399. static struct interface_descriptor http_partial_desc =
  1400. INTF_DESC ( struct http_request, partial, http_partial_operations );
  1401. /** HTTP data transfer interface operations */
  1402. static struct interface_operation http_xfer_operations[] = {
  1403. INTF_OP ( xfer_window, struct http_request *, http_xfer_window ),
  1404. INTF_OP ( block_read, struct http_request *, http_block_read ),
  1405. INTF_OP ( block_read_capacity, struct http_request *,
  1406. http_block_read_capacity ),
  1407. INTF_OP ( intf_close, struct http_request *, http_close ),
  1408. INTF_OP ( acpi_describe, struct http_request *, http_acpi_describe ),
  1409. };
  1410. /** HTTP data transfer interface descriptor */
  1411. static struct interface_descriptor http_xfer_desc =
  1412. INTF_DESC_PASSTHRU ( struct http_request, xfer,
  1413. http_xfer_operations, socket );
  1414. /** HTTP process descriptor */
  1415. static struct process_descriptor http_process_desc =
  1416. PROC_DESC_ONCE ( struct http_request, process, http_step );
  1417. /**
  1418. * Initiate an HTTP connection, with optional filter
  1419. *
  1420. * @v xfer Data transfer interface
  1421. * @v uri Uniform Resource Identifier
  1422. * @v default_port Default port number
  1423. * @v filter Filter to apply to socket, or NULL
  1424. * @ret rc Return status code
  1425. */
  1426. int http_open_filter ( struct interface *xfer, struct uri *uri,
  1427. unsigned int default_port,
  1428. int ( * filter ) ( struct interface *xfer,
  1429. const char *name,
  1430. struct interface **next ) ) {
  1431. struct http_request *http;
  1432. int rc;
  1433. /* Sanity checks */
  1434. if ( ! uri->host )
  1435. return -EINVAL;
  1436. /* Allocate and populate HTTP structure */
  1437. http = zalloc ( sizeof ( *http ) );
  1438. if ( ! http )
  1439. return -ENOMEM;
  1440. ref_init ( &http->refcnt, http_free );
  1441. intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt );
  1442. intf_init ( &http->partial, &http_partial_desc, &http->refcnt );
  1443. http->uri = uri_get ( uri );
  1444. http->default_port = default_port;
  1445. http->filter = filter;
  1446. intf_init ( &http->socket, &http_socket_desc, &http->refcnt );
  1447. process_init ( &http->process, &http_process_desc, &http->refcnt );
  1448. timer_init ( &http->timer, http_retry, &http->refcnt );
  1449. http->flags = HTTP_TX_PENDING;
  1450. /* Open socket */
  1451. if ( ( rc = http_socket_open ( http ) ) != 0 )
  1452. goto err;
  1453. /* Attach to parent interface, mortalise self, and return */
  1454. intf_plug_plug ( &http->xfer, xfer );
  1455. ref_put ( &http->refcnt );
  1456. return 0;
  1457. err:
  1458. DBGC ( http, "HTTP %p could not create request: %s\n",
  1459. http, strerror ( rc ) );
  1460. http_close ( http, rc );
  1461. ref_put ( &http->refcnt );
  1462. return rc;
  1463. }