request.c 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567
  1. /*
  2. HTTP request handling tests
  3. Copyright (C) 2001-2024, Joe Orton <[email protected]>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "config.h"
  17. #include <sys/types.h>
  18. #include <time.h> /* for time() */
  19. #ifdef HAVE_STDLIB_H
  20. #include <stdlib.h>
  21. #endif
  22. #ifdef HAVE_UNISTD_H
  23. #include <unistd.h>
  24. #endif
  25. #include <fcntl.h>
  26. #include <errno.h>
  27. #include "ne_request.h"
  28. #include "ne_socket.h"
  29. #include "tests.h"
  30. #include "child.h"
  31. #include "utils.h"
  32. static char buffer[BUFSIZ];
  33. static ne_session *def_sess;
  34. static ne_request *def_req;
  35. /* Last (real) port used by fail_request_with_error(). */
  36. static unsigned int fail_request_last_port;
  37. static int prepare_request(server_fn fn, void *ud)
  38. {
  39. static char uri[100];
  40. unsigned int port;
  41. CALL(new_spawn_server(1, fn, ud, &port));
  42. def_sess = ne_session_create("http", "localhost", port);
  43. sprintf(uri, "/test%d", test_num);
  44. def_req = ne_request_create(def_sess, "GET", uri);
  45. return OK;
  46. }
  47. static int finish_request(void)
  48. {
  49. ne_request_destroy(def_req);
  50. return destroy_and_wait(def_sess);
  51. }
  52. #define RESP200 "HTTP/1.1 200 OK\r\n" "Server: neon-test-server\r\n"
  53. #define TE_CHUNKED "Transfer-Encoding: chunked\r\n"
  54. #define CHUNK(len, data) #len "\r\n" data "\r\n"
  55. #define ABCDE_CHUNKS CHUNK(1, "a") CHUNK(1, "b") \
  56. CHUNK(1, "c") CHUNK(1, "d") \
  57. CHUNK(1, "e") CHUNK(0, "")
  58. /* takes response body chunks and appends them to a buffer. */
  59. static int collector(void *ud, const char *data, size_t len)
  60. {
  61. ne_buffer *buf = ud;
  62. ne_buffer_append(buf, data, len);
  63. return 0;
  64. }
  65. typedef ne_request *(*construct_request)(ne_session *sess, void *userdata);
  66. /* construct a get request, callback for run_request. */
  67. static ne_request *construct_get(ne_session *sess, void *userdata)
  68. {
  69. ne_request *r = ne_request_create(sess, "GET", "/");
  70. ne_buffer *buf = userdata;
  71. if (buf) ne_add_response_body_reader(r, ne_accept_2xx, collector, buf);
  72. return r;
  73. }
  74. /* run a request created by callback 'cb' in session 'sess'. */
  75. static int run_request(ne_session *sess, int status,
  76. construct_request cb, void *userdata)
  77. {
  78. ne_request *req = cb(sess, userdata);
  79. ON(req == NULL);
  80. ONREQ(ne_request_dispatch(req));
  81. ONV(ne_get_status(req)->code != status,
  82. ("response status-code was %d not %d",
  83. ne_get_status(req)->code, status));
  84. ne_request_destroy(req);
  85. return OK;
  86. }
  87. /* Runs a server function 'fn', expecting to get a header 'name' with
  88. * value 'value' in the response. If 'value' is NULL, expects that
  89. * *no* header of that name is present. */
  90. static int expect_header_value(const char *name, const char *value,
  91. server_fn fn, void *userdata)
  92. {
  93. ne_session *sess;
  94. ne_request *req;
  95. const char *gotval;
  96. CALL(make_session(&sess, fn, userdata));
  97. NE_DEBUG(NE_DBG_HTTP, "[test] Testing for expected header [%s] / [%s]\n",
  98. name, value);
  99. req = ne_request_create(sess, "FOO", "/bar");
  100. ONREQ(ne_request_dispatch(req));
  101. ne_close_connection(sess);
  102. CALL(await_server());
  103. gotval = ne_get_response_header(req, name);
  104. ONV(value && !gotval, ("header '%s: %s' not sent", name, value));
  105. ONV(!value && gotval, ("header '%s: %s' not expected", name, gotval));
  106. ONV(value && gotval && strcmp(gotval, value),
  107. ("header '%s' mis-match: got '%s' not '%s'",
  108. name, gotval, value));
  109. ne_request_destroy(req);
  110. ne_session_destroy(sess);
  111. return OK;
  112. }
  113. /* runs a server function 'fn', expecting response body to be equal to
  114. * 'expect' */
  115. static int expect_response(const char *expect, server_fn fn, void *userdata)
  116. {
  117. ne_session *sess;
  118. ne_buffer *buf = ne_buffer_create();
  119. CALL(session_server(&sess, fn, userdata));
  120. CALL(run_request(sess, 200, construct_get, buf));
  121. CALL(destroy_and_wait(sess));
  122. ONN("response body match", strcmp(buf->data, expect));
  123. ne_buffer_destroy(buf);
  124. return OK;
  125. }
  126. #define EMPTY_RESP RESP200 "Content-Length: 0\r\n\r\n"
  127. /* Process a request with given method and response, expecting to get
  128. * a zero-length response body. A second request is sent down the
  129. * connection (to ensure that the response isn't silently eaten), so
  130. * 'resp' must be an HTTP/1.1 response with no 'Connection: close'
  131. * header. */
  132. static int expect_no_body(const char *method, const char *resp)
  133. {
  134. ne_session *sess;
  135. ne_request *req;
  136. ssize_t ret;
  137. char *r = ne_malloc(strlen(resp) + sizeof(EMPTY_RESP));
  138. strcpy(r, resp);
  139. strcat(r, EMPTY_RESP);
  140. CALL(session_server(&sess, single_serve_string, r));
  141. ne_free(r);
  142. req = ne_request_create(sess, method, "/first");
  143. ONN("failed to begin request", ne_begin_request(req));
  144. ret = ne_read_response_block(req, buffer, BUFSIZ);
  145. ONV(ret != 0, ("got response block of size %" NE_FMT_SSIZE_T, ret));
  146. ONN("failed to end request", ne_end_request(req));
  147. /* process following request; makes sure that nothing extra has
  148. * been eaten by the first request. */
  149. ONV(any_request(sess, "/second"),
  150. ("second request on connection failed: %s",ne_get_error(sess)));
  151. ne_request_destroy(req);
  152. return destroy_and_wait(sess);
  153. }
  154. static int reason_phrase(void)
  155. {
  156. ne_session *sess;
  157. CALL(make_session(&sess, single_serve_string, RESP200
  158. "Connection: close\r\n\r\n"));
  159. ONREQ(any_request(sess, "/foo"));
  160. ne_close_connection(sess);
  161. CALL(await_server());
  162. ONV(strcmp(ne_get_error(sess), "200 OK"),
  163. ("reason phrase mismatch: got `%s' not `200 OK'",
  164. ne_get_error(sess)));
  165. ne_session_destroy(sess);
  166. return OK;
  167. }
  168. #if 0
  169. /* This feature was added then remoevd, it potentially wasn't safe
  170. * since the location string wasn't cleaned or checked to be a valid
  171. * URI. */
  172. static int redirect_error(void)
  173. {
  174. ne_session *sess;
  175. CALL(make_session(&sess, single_serve_string,
  176. "HTTP/1.1 301 Moved Permanently\r\n"
  177. "Location: http://example.com/redirected\r\n"
  178. "Connection: close\r\n\r\n"));
  179. ONREQ(any_request(sess, "/foo"));
  180. ne_close_connection(sess);
  181. CALL(await_server());
  182. ONV(strcmp(ne_get_error(sess), "Redirected to http://example.com/redirected"),
  183. ("error mismatch: got `%s' not redirect location",
  184. ne_get_error(sess)));
  185. ne_session_destroy(sess);
  186. return OK;
  187. }
  188. #endif
  189. static int no_body_304(void)
  190. {
  191. return expect_no_body("GET", "HTTP/1.1 304 Not Mfodified\r\n"
  192. "Content-Length: 5\r\n\r\n");
  193. }
  194. static int no_body_204(void)
  195. {
  196. return expect_no_body("GET", "HTTP/1.1 204 Not Modified\r\n"
  197. "Content-Length: 5\r\n\r\n");
  198. }
  199. static int no_body_HEAD(void)
  200. {
  201. return expect_no_body("HEAD", "HTTP/1.1 200 OK\r\n"
  202. "Content-Length: 5\r\n\r\n");
  203. }
  204. static int chunk_oversize(void)
  205. {
  206. #define BIG (20000)
  207. char *body = ne_malloc(BIG + 1);
  208. static const char rnd[] = "abcdefghijklm";
  209. int n;
  210. ne_buffer *buf = ne_buffer_create();
  211. for (n = 0; n < BIG; n++) {
  212. body[n] = rnd[n % (sizeof(rnd) - 1)];
  213. }
  214. body[n] = '\0';
  215. #undef BIG
  216. ne_buffer_concat(buf, RESP200 TE_CHUNKED "\r\n"
  217. "4E20\r\n", body, "\r\n",
  218. "0\r\n\r\n", NULL);
  219. CALL(expect_response(body, single_serve_string, buf->data));
  220. ne_buffer_destroy(buf);
  221. ne_free(body);
  222. return OK;
  223. }
  224. /* obscure case which is possibly a valid request by 2616, but should
  225. * be handled correctly in any case. neon <0.22.0 tries to
  226. * eat the response body, which is probably incorrect. */
  227. static int no_body_chunks(void)
  228. {
  229. return expect_no_body("HEAD", "HTTP/1.1 204 Not Modified\r\n"
  230. TE_CHUNKED "\r\n");
  231. }
  232. static int serve_twice(ne_socket *sock, void *userdata)
  233. {
  234. const char *resp = userdata;
  235. CALL(discard_request(sock));
  236. SEND_STRING(sock, resp);
  237. CALL(discard_request(sock));
  238. SEND_STRING(sock, resp);
  239. return OK;
  240. }
  241. /* Test persistent connection handling: serve 'response' twice on a
  242. * single TCP connection, expecting to get a response body equal to
  243. * 'body' both times. */
  244. static int test_persist_p(const char *response, const char *body, int proxy)
  245. {
  246. ne_session *sess;
  247. ne_buffer *buf = ne_buffer_create();
  248. if (proxy) {
  249. CALL(proxied_session_server(&sess, "http", "localhost", 1234,
  250. serve_twice, (void *)response));
  251. ne_set_session_flag(sess, NE_SESSFLAG_CONNAUTH, 1);
  252. }
  253. else {
  254. CALL(session_server(&sess, serve_twice, (void *)response));
  255. }
  256. CALL(run_request(sess, 200, construct_get, buf));
  257. ONV(strcmp(buf->data, body),
  258. ("response #1 mismatch: [%s] not [%s]", buf->data, body));
  259. /* Run it again. */
  260. ne_buffer_clear(buf);
  261. CALL(run_request(sess, 200, construct_get, buf));
  262. CALL(destroy_and_wait(sess));
  263. ONV(strcmp(buf->data, body),
  264. ("response #2 mismatch: [%s] not [%s]", buf->data, body));
  265. ne_buffer_destroy(buf);
  266. return OK;
  267. }
  268. static int test_persist(const char *response, const char *body)
  269. {
  270. return test_persist_p(response, body, 0);
  271. }
  272. static int persist_http11(void)
  273. {
  274. return test_persist(RESP200 "Content-Length: 5\r\n\r\n" "abcde",
  275. "abcde");
  276. }
  277. static int persist_chunked(void)
  278. {
  279. return test_persist(RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS,
  280. "abcde");
  281. }
  282. static int persist_http10(void)
  283. {
  284. return test_persist("HTTP/1.0 200 OK\r\n"
  285. "Connection: keep-alive\r\n"
  286. "Content-Length: 5\r\n\r\n" "abcde",
  287. "abcde");
  288. }
  289. static int persist_proxy_http10(void)
  290. {
  291. return test_persist_p("HTTP/1.0 200 OK\r\n"
  292. "Proxy-Connection: keep-alive\r\n"
  293. "Content-Length: 5\r\n\r\n" "abcde",
  294. "abcde", 1);
  295. }
  296. /* Server function for fail_early_eof */
  297. static int serve_eof(ne_socket *sock, void *ud)
  298. {
  299. const char *resp = ud;
  300. /* dummy request/response. */
  301. CALL(discard_request(sock));
  302. CALL(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n"));
  303. /* real request/response. */
  304. CALL(discard_request(sock));
  305. CALL(SEND_STRING(sock, resp));
  306. return OK;
  307. }
  308. /* Utility function: 'resp' is a truncated response; such that an EOF
  309. * arrives early during response processing; but NOT as a valid
  310. * premature EOF due to a persistent connection timeout. It is an
  311. * error if the request is then retried, and the test fails. */
  312. static int fail_early_eof(const char *resp)
  313. {
  314. ne_session *sess;
  315. unsigned int port;
  316. CALL(new_spawn_server(3, serve_eof, (char *)resp, &port));
  317. sess = ne_session_create("http", "localhost", port);
  318. ONREQ(any_request(sess, "/foo"));
  319. ONN("request retried after early EOF",
  320. any_request(sess, "/foobar") == NE_OK);
  321. CALL(reap_server());
  322. ne_session_destroy(sess);
  323. return OK;
  324. }
  325. /* This failed with neon <0.22. */
  326. static int fail_eof_continued(void)
  327. {
  328. return fail_early_eof("HTTP/1.1 100 OK\r\n\r\n");
  329. }
  330. static int fail_eof_headers(void)
  331. {
  332. return fail_early_eof("HTTP/1.1 200 OK\r\nJimbob\r\n");
  333. }
  334. static int fail_eof_chunk(void)
  335. {
  336. return fail_early_eof(RESP200 TE_CHUNKED "\r\n" "1\r\n" "a");
  337. }
  338. static int fail_eof_badclen(void)
  339. {
  340. return fail_early_eof(RESP200 "Content-Length: 10\r\n\r\n" "abcde");
  341. }
  342. /* Persistent connection timeout where a FIN is sent to terminate the
  343. * connection, which is caught by a 0 return from the read() when the
  344. * second request reads the status-line. */
  345. static int ptimeout_eof(void)
  346. {
  347. ne_session *sess;
  348. unsigned int port;
  349. CALL(new_spawn_server(4, single_serve_string,
  350. RESP200 "Content-Length: 0\r\n" "\r\n",
  351. &port));
  352. sess = ne_session_create("http", "localhost", port);
  353. CALL(any_2xx_request(sess, "/first"));
  354. CALL(any_2xx_request(sess, "/second"));
  355. ONN("server died prematurely?", dead_server());
  356. reap_server();
  357. ne_session_destroy(sess);
  358. return OK;
  359. }
  360. /* Persistent connection timeout where a FIN is sent to terminate the
  361. * connection, but the request fails in the write() call which sends
  362. * the body. */
  363. static int ptimeout_eof2(void)
  364. {
  365. ne_session *sess;
  366. unsigned int port;
  367. CALL(new_spawn_server(4, single_serve_string,
  368. RESP200 "Content-Length: 0\r\n" "\r\n",
  369. &port));
  370. sess = ne_session_create("http", "localhost", port);
  371. CALL(any_2xx_request(sess, "/first"));
  372. minisleep();
  373. CALL(any_2xx_request_body(sess, "/second"));
  374. ONN("server died prematurely?", dead_server());
  375. reap_server();
  376. ne_session_destroy(sess);
  377. return OK;
  378. }
  379. /* TODO: add a ptimeout_reset too, if an RST can be reliably generated
  380. * mid-connection. */
  381. static int incr_server(ne_socket *sock, void *arg)
  382. {
  383. struct many_serve_args *msa = arg;
  384. CALL(many_serve_string(sock, msa));
  385. msa->count++;
  386. return OK;
  387. }
  388. /* Emulates a persistent connection timeout on the server. This tests
  389. * the timeout occurring after between 1 and 10 requests down the
  390. * connection. */
  391. static int persist_timeout(void)
  392. {
  393. ne_session *sess;
  394. ne_buffer *buf = ne_buffer_create();
  395. struct many_serve_args args;
  396. unsigned int port;
  397. int n;
  398. args.str = RESP200 "Content-Length: 5\r\n\r\n" "abcde";
  399. args.count = 1;
  400. CALL(new_spawn_server(9, incr_server, &args, &port));
  401. sess = ne_session_create("http", "localhost", port);
  402. for (args.count = 1; args.count < 10; args.count++) {
  403. for (n = 0; n < args.count; n++) {
  404. ONV(run_request(sess, 200, construct_get, buf),
  405. ("%d of %d, request failed: %s", n, args.count,
  406. ne_get_error(sess)));
  407. ONV(strcmp(buf->data, "abcde"),
  408. ("%d of %d, response body mismatch", n, args.count));
  409. /* Ready for next time. */
  410. ne_buffer_clear(buf);
  411. }
  412. }
  413. ne_buffer_destroy(buf);
  414. return destroy_and_wait(sess);
  415. }
  416. /* Test that an HTTP/1.0 server is not presumed to support persistent
  417. * connections by default. */
  418. static int no_persist_http10(void)
  419. {
  420. ne_session *sess;
  421. unsigned int port;
  422. CALL(new_spawn_server(4, single_serve_string,
  423. "HTTP/1.0 200 OK\r\n"
  424. "Content-Length: 5\r\n\r\n"
  425. "abcde"
  426. "Hello, world - what a nice day!\r\n",
  427. &port));
  428. sess = ne_session_create("http", "localhost", port);
  429. /* if the connection is treated as persistent, the status-line for
  430. * the second request will be "Hello, world...", which will
  431. * fail. */
  432. ONREQ(any_request(sess, "/foobar"));
  433. ONREQ(any_request(sess, "/foobar"));
  434. ONN("server died prematurely?", dead_server());
  435. CALL(reap_server());
  436. ne_session_destroy(sess);
  437. return OK;
  438. }
  439. #define NO_BODY "Content-Length: 0\r\n\r\n"
  440. static int response_bodies(void)
  441. {
  442. struct {
  443. const char *expect;
  444. server_fn fn;
  445. const char *response;
  446. } ts[] = {
  447. { "a", single_serve_string, RESP200 "Connection: close\r\n" "\r\n" "a" },
  448. { "a", single_serve_string, RESP200 "Content-Length: \t\t 1 \t\t\r\n"
  449. "\r\n" "a" "bbbbbbbbasdasd" },
  450. { "a", single_serve_string, RESP200 TE_CHUNKED "\r\n"
  451. "1\r\n" "a\r\n"
  452. "0\r\n" "\r\n"
  453. "g;lkjalskdjalksjd" },
  454. { "abcde", single_serve_string, "HTTP/1.1 200 OK\r\n\r\n" "abcde" }, /* no headers */
  455. { "abcde", single_serve_string, RESP200 "Stupid Header\r\n" "ReallyStupidHeader\r\n"
  456. "Content-Length: 5\r\n" "\r\n" "abcde" },
  457. { "abcde", single_serve_string, RESP200 "Content-Length: \r\n 5\r\n" "\r\n" "abcde" },
  458. { "abcde", single_serve_string, RESP200 "Content-Length: \r\n \r\n \r\n \r\n 5\r\n" "\r\n" "abcde" },
  459. /* chunk tests */
  460. { "abcde", single_serve_string, RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS },
  461. { "abcde", single_serve_string, RESP200 "Transfer-Encoding: CHUNKED\r\n" "\r\n" ABCDE_CHUNKS },
  462. /* http://bugzilla.gnome.org/show_bug.cgi?id=310636 says privoxy
  463. * uses the "identity" transfer-coding. */
  464. { "abcde", single_serve_string, RESP200 "Transfer-Encoding: identity\r\n" "Content-Length: 5\r\n"
  465. "\r\n" "abcde" },
  466. /* leading zero's */
  467. { "0123456789abcdef", single_serve_string, RESP200 TE_CHUNKED "\r\n"
  468. "000000010\r\n" "0123456789abcdef\r\n"
  469. "000000000\r\n" "\r\n" },
  470. /* chunk-extensions. */
  471. { "0123456789abcdef", single_serve_string, RESP200 TE_CHUNKED "\r\n"
  472. "000000010; foo=bar; norm=fish\r\n"
  473. "0123456789abcdef\r\n"
  474. "000000000\r\n" "\r\n" },
  475. { "0123456789abcdef", single_serve_string, RESP200 TE_CHUNKED "\r\n"
  476. "10 \t ; foo=bar\r\n"
  477. "0123456789abcdef\r\n"
  478. "000000000\r\n" "\r\n" },
  479. /* trailers. */
  480. { "abcde", single_serve_string, RESP200 TE_CHUNKED "\r\n"
  481. "00000005; foo=bar; norm=fish\r\n"
  482. "abcde\r\n"
  483. "000000000\r\n"
  484. "X-Hello: world\r\n"
  485. "X-Another: header\r\n"
  486. "\r\n" },
  487. /* T-E dominates over C-L. */
  488. { "abcde", single_serve_string, RESP200 TE_CHUNKED
  489. "Content-Length: 300\r\n"
  490. "\r\n" ABCDE_CHUNKS },
  491. { "abcde", single_serve_string, RESP200 "Content-Length: 300\r\n"
  492. TE_CHUNKED "\r\n" ABCDE_CHUNKS },
  493. { NULL, NULL, NULL }
  494. };
  495. unsigned n;
  496. for (n = 0; ts[n].expect != NULL; n++ ){
  497. CALL(expect_response(ts[n].expect, ts[n].fn, (void *)ts[n].response));
  498. }
  499. return OK;
  500. }
  501. static int response_headers(void)
  502. {
  503. struct {
  504. const char *name, *value;
  505. server_fn fn;
  506. const char *response;
  507. } ts[] = {
  508. { "ranDom-HEader", "", single_serve_string, RESP200 "RANDom-HeADEr:\r\n" NO_BODY },
  509. { "ranDom-HEader", "noddy", single_serve_string, RESP200 "RANDom-HeADEr: noddy\r\n" NO_BODY },
  510. { "ranDom-HEader", "fishy", single_serve_string, RESP200 "RANDom-HeADEr: fishy\r\n" NO_BODY },
  511. { "ranDom-HEader", "fishy", single_serve_string, RESP200 "RANDom-HeADEr: \t fishy\r\n" NO_BODY},
  512. { "ranDom-HEader", "fishy", single_serve_string, RESP200 "RANDom-HeADEr: fishy \r\n" NO_BODY },
  513. { "ranDom-HEader", "geezer", single_serve_string, RESP200 "RANDom-HeADEr: \t \tgeezer\r\n" NO_BODY },
  514. { "gONe", "fishing", single_serve_string,
  515. RESP200 TE_CHUNKED "\r\n0\r\n" "Hello: world\r\n" "GONE: fishing\r\n" "\r\n" },
  516. { "hello", "w o r l d", single_serve_string,
  517. RESP200 "Hello: \n\tw\r\n\to r l\r\n\td \r\n" NO_BODY },
  518. { "X-Header", "jim, jab, jar", single_serve_string,
  519. RESP200 "X-Header: jim\r\n" "x-header: jab\r\n" "x-Header: jar\r\n" NO_BODY },
  520. { "X-Header", "jim, jab, jar", single_serve_string,
  521. RESP200 "X-Header: jim \r\n" "x-header: jab \r\n" "x-Header: jar \r\n" NO_BODY },
  522. /* RFC 2616 14.10: headers listed in Connection must be stripped on
  523. * receiving an HTTP/1.0 message in case there was a pre-1.1 proxy
  524. * somewhere. */
  525. { "X-Widget", NULL, single_serve_string,
  526. "HTTP/1.0 200 OK\r\n" "Connection: x-widget\r\n" "x-widget: blah\r\n" NO_BODY },
  527. { "X-Widget", NULL, single_serve_string,
  528. "HTTP/1.0 200 OK\r\n" "Connection: connection, x-fish, x-widget\r\n" "x-widget: blah\r\n" NO_BODY },
  529. /* Test trailer header handling. */
  530. { "X-Trailer", "foo", single_serve_string,
  531. RESP200 TE_CHUNKED "X-Header: bar\r\n\r\n"
  532. CHUNK(6, "foobar") "0\r\nX-Trailer: foo\r\n\r\n" },
  533. { "X-Header", "foo", single_serve_string,
  534. RESP200 TE_CHUNKED "X-Header: foo\r\n\r\n"
  535. CHUNK(6, "foobar") "0\r\nX-Trailer: barish\r\n\r\n" },
  536. /* Test that merging between trailers and main response headers works. */
  537. { "X-Trailer", "fooish, barish", single_serve_string,
  538. RESP200 TE_CHUNKED "X-Trailer: fooish\r\n\r\n"
  539. CHUNK(6, "foobar") "0\r\nX-Trailer: barish\r\n\r\n" },
  540. /* Test that bare LFs are treated as a spaces. */
  541. { "X-Test", "just plain spaces", single_serve_string,
  542. RESP200 "X-Test: just\rplain\rspaces\r\n" NO_BODY },
  543. /* Invalid vs valid header names */
  544. { "Content\"Length", NULL, single_serve_string,
  545. RESP200 "Content\"Length: foobar\r\n" NO_BODY },
  546. { "Content!Length", "foobar", single_serve_string,
  547. RESP200 "Content!Length: foobar\r\n" NO_BODY },
  548. { NULL, NULL, NULL, NULL }
  549. };
  550. unsigned n;
  551. for (n = 0; ts[n].name != NULL; n++ ){
  552. CALL(expect_header_value(ts[n].name, ts[n].value, ts[n].fn, (void *)ts[n].response));
  553. }
  554. return OK;
  555. }
  556. static int post_send_retry(ne_request *req, void *userdata,
  557. const ne_status *status)
  558. {
  559. return status->code == 400 ? NE_RETRY : NE_OK;
  560. }
  561. /* Test that the stored response headers are forgotten if the request
  562. * is retried. */
  563. static int reset_headers(void)
  564. {
  565. ne_session *sess;
  566. ne_request *req;
  567. const char *value;
  568. CALL(make_session(&sess, single_serve_string,
  569. "HTTP/1.1 400 Hit me again\r\n"
  570. "Content-Length: 0\r\n"
  571. "X-Foo: bar\r\n" "\r\n"
  572. "HTTP/1.1 200 Thank you kindly\r\n"
  573. "Content-Length: 0\r\n"
  574. "X-Foo: hello fair world\r\n" "\r\n"));
  575. ne_hook_post_send(sess, post_send_retry, NULL);
  576. req = ne_request_create(sess, "GET", "/foo");
  577. ONREQ(ne_request_dispatch(req));
  578. value = ne_get_response_header(req, "X-Foo");
  579. ONCMP("hello fair world", value, "response header", "X-Foo");
  580. ne_request_destroy(req);
  581. return destroy_and_wait(sess);
  582. }
  583. static int iterate_none(void)
  584. {
  585. ne_session *sess;
  586. ne_request *req;
  587. CALL(make_session(&sess, single_serve_string,
  588. "HTTP/1.0 200 OK\r\n\r\n"));
  589. req = ne_request_create(sess, "GET", "/");
  590. ONREQ(ne_request_dispatch(req));
  591. ONN("iterator was not NULL for no headers",
  592. ne_response_header_iterate(req, NULL, NULL, NULL) != NULL);
  593. ne_request_destroy(req);
  594. return destroy_and_wait(sess);
  595. }
  596. #define MANY_HEADERS (90)
  597. static int iterate_many(void)
  598. {
  599. ne_request *req;
  600. ne_buffer *buf = ne_buffer_create();
  601. ne_session *sess;
  602. int n;
  603. struct header {
  604. char name[10], value[10];
  605. int seen;
  606. } hdrs[MANY_HEADERS];
  607. void *cursor = NULL;
  608. const char *name, *value;
  609. ne_buffer_czappend(buf, "HTTP/1.0 200 OK\r\n");
  610. for (n = 0; n < MANY_HEADERS; n++) {
  611. sprintf(hdrs[n].name, "x-%d", n);
  612. sprintf(hdrs[n].value, "Y-%d", n);
  613. hdrs[n].seen = 0;
  614. ne_buffer_concat(buf, hdrs[n].name, ": ", hdrs[n].value, "\r\n", NULL);
  615. }
  616. ne_buffer_czappend(buf, "\r\n");
  617. CALL(make_session(&sess, single_serve_string, buf->data));
  618. req = ne_request_create(sess, "GET", "/foo");
  619. ONREQ(ne_request_dispatch(req));
  620. while ((cursor = ne_response_header_iterate(req, cursor, &name, &value))) {
  621. ONV(strncmp(name, "x-", 2) || strncmp(value, "Y-", 2)
  622. || strcmp(name + 2, value + 2)
  623. || (n = atoi(name + 2)) >= MANY_HEADERS
  624. || n < 0,
  625. ("bad name/value pair: %s = %s", name, value));
  626. NE_DEBUG(NE_DBG_HTTP, "iterate: got pair (%d): %s = %s\n",
  627. n, name, value);
  628. ONV(hdrs[n].seen == 1, ("duplicate pair %d", n));
  629. hdrs[n].seen = 1;
  630. }
  631. for (n = 0; n < MANY_HEADERS; n++) {
  632. ONV(hdrs[n].seen == 0, ("unseen pair %d", n));
  633. }
  634. ne_buffer_destroy(buf);
  635. ne_request_destroy(req);
  636. return destroy_and_wait(sess);
  637. }
  638. struct s1xx_args {
  639. int count;
  640. int hdrs;
  641. };
  642. static int serve_1xx(ne_socket *sock, void *ud)
  643. {
  644. struct s1xx_args *args = ud;
  645. CALL(discard_request(sock));
  646. do {
  647. if (args->hdrs) {
  648. SEND_STRING(sock, "HTTP/1.1 100 Continue\r\n"
  649. "Random: header\r\n"
  650. "Another: header\r\n\r\n");
  651. } else {
  652. SEND_STRING(sock, "HTTP/1.1 100 Continue\r\n\r\n");
  653. }
  654. } while (--args->count > 0);
  655. SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n");
  656. return OK;
  657. }
  658. #define sess def_sess
  659. static int skip_interim_1xx(void)
  660. {
  661. struct s1xx_args args = {0, 0};
  662. ON(prepare_request(serve_1xx, &args));
  663. ONREQ(ne_request_dispatch(def_req));
  664. return finish_request();
  665. }
  666. static int skip_many_1xx(void)
  667. {
  668. struct s1xx_args args = {5, 0};
  669. ON(prepare_request(serve_1xx, &args));
  670. ONREQ(ne_request_dispatch(def_req));
  671. return finish_request();
  672. }
  673. static int skip_1xx_hdrs(void)
  674. {
  675. struct s1xx_args args = {5, 5};
  676. ON(prepare_request(serve_1xx, &args));
  677. ONREQ(ne_request_dispatch(def_req));
  678. return finish_request();
  679. }
  680. #undef sess
  681. /* server for expect_100_once: serves a 100-continue request, and
  682. * fails if the request body is sent twice. */
  683. static int serve_100_once(ne_socket *sock, void *ud)
  684. {
  685. struct s1xx_args args = {2, 0};
  686. char ch;
  687. CALL(serve_1xx(sock, &args));
  688. CALL(discard_body(sock));
  689. ONN("body was served twice", ne_sock_read(sock, &ch, 1) == 1);
  690. return OK;
  691. }
  692. /* regression test; fails with neon <0.22, where the request body was
  693. * served *every* time a 1xx response was received, rather than just
  694. * once. */
  695. static int expect_100_once(void)
  696. {
  697. ne_session *sess;
  698. ne_request *req;
  699. char body[BUFSIZ];
  700. CALL(make_session(&sess, serve_100_once, NULL));
  701. req = ne_request_create(sess, "GET", "/foo");
  702. ne_set_request_flag(req, NE_REQFLAG_EXPECT100, 1);
  703. ONN("expect100 flag ignored",
  704. ne_get_request_flag(req, NE_REQFLAG_EXPECT100) != 1);
  705. memset(body, 'A', sizeof(body));
  706. ne_set_request_body_buffer(req, body, sizeof(body));
  707. ONREQ(ne_request_dispatch(req));
  708. ne_request_destroy(req);
  709. return destroy_and_wait(sess);
  710. }
  711. /* regression test for enabling 100-continue without sending a body. */
  712. static int expect_100_nobody(void)
  713. {
  714. ne_session *sess;
  715. ne_request *req;
  716. CALL(make_session(&sess, serve_100_once, NULL));
  717. req = ne_request_create(sess, "GET", "/foo");
  718. ne_set_request_flag(req, NE_REQFLAG_EXPECT100, 1);
  719. ONREQ(ne_request_dispatch(req));
  720. ne_request_destroy(req);
  721. return destroy_and_wait(sess);
  722. }
  723. struct body {
  724. char *body;
  725. size_t size;
  726. };
  727. static int want_body(ne_socket *sock, void *userdata)
  728. {
  729. struct body *b = userdata;
  730. char *buf = ne_malloc(b->size);
  731. clength = 0;
  732. CALL(discard_request(sock));
  733. ONN("request has c-l header", clength == 0);
  734. ONN("request length", clength != b->size);
  735. NE_DEBUG(NE_DBG_HTTP,
  736. "reading body of %" NE_FMT_SIZE_T " bytes...\n", b->size);
  737. ON(ne_sock_fullread(sock, buf, b->size));
  738. ON(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n"));
  739. ON(memcmp(buf, b->body, b->size));
  740. ne_free(buf);
  741. return OK;
  742. }
  743. static ssize_t provide_body(void *userdata, char *buf, size_t buflen)
  744. {
  745. static const char *pnt;
  746. static size_t left;
  747. struct body *b = userdata;
  748. if (buflen == 0) {
  749. pnt = b->body;
  750. left = b->size;
  751. } else {
  752. if (left < buflen) buflen = left;
  753. memcpy(buf, pnt, buflen);
  754. left -= buflen;
  755. }
  756. return buflen;
  757. }
  758. static int send_bodies(void)
  759. {
  760. unsigned int n, m;
  761. struct body bodies[] = {
  762. { "abcde", 5 },
  763. { "\0\0\0\0\0\0", 6 },
  764. { NULL, 50000 },
  765. { NULL }
  766. };
  767. #define BIG 2
  768. /* make the body with some cruft. */
  769. bodies[BIG].body = ne_malloc(bodies[BIG].size);
  770. for (n = 0; n < bodies[BIG].size; n++) {
  771. bodies[BIG].body[n] = (char)n%80;
  772. }
  773. for (m = 0; m < 2; m++) {
  774. for (n = 0; bodies[n].body != NULL; n++) {
  775. ne_session *sess;
  776. ne_request *req;
  777. CALL(session_server(&sess, want_body, &(bodies[n])));
  778. req = ne_request_create(sess, "PUT", "/");
  779. ON(req == NULL);
  780. if (m == 0) {
  781. ne_set_request_body_buffer(req, bodies[n].body, bodies[n].size);
  782. } else {
  783. ne_set_request_body_provider(req, bodies[n].size,
  784. provide_body, &bodies[n]);
  785. }
  786. ONREQ(ne_request_dispatch(req));
  787. ne_request_destroy(req);
  788. CALL(destroy_and_wait(sess));
  789. }
  790. }
  791. ne_free(bodies[BIG].body);
  792. return OK;
  793. }
  794. /* Utility function: run a request using the given server fn, and the
  795. * request should fail. If 'error' is non-NULL, it must be a substring
  796. * of the error string. */
  797. static int fail_request_with_error(int with_body, server_fn fn, void *ud,
  798. int forever, const char *error)
  799. {
  800. ne_session *sess;
  801. ne_request *req;
  802. unsigned int port;
  803. int ret;
  804. CALL(new_spawn_server(forever ? 100 : 1, fn, ud, &port));
  805. sess = ne_session_create("http", "localhost", port);
  806. /* Set default timeout, required by e.g. fail_excess_1xx. */
  807. ne_set_read_timeout(sess, 2);
  808. req = ne_request_create(sess, "GET", "/");
  809. if (with_body) {
  810. static const char *body = "random stuff";
  811. ne_set_request_body_buffer(req, body, strlen(body));
  812. }
  813. /* request should fail. */
  814. ret = ne_request_dispatch(req);
  815. ONN("request succeeded", ret == NE_OK);
  816. if (!forever) {
  817. /* reap the server, don't care what it's doing. */
  818. reap_server();
  819. }
  820. NE_DEBUG(NE_DBG_HTTP, "Response gave error `%s'\n", ne_get_error(sess));
  821. ONV(error && strstr(ne_get_error(sess), error) == NULL,
  822. ("failed with error `%s', no `%s'", ne_get_error(sess), error));
  823. if (!forever)
  824. ONV(any_request(sess, "/fail/to/connect") != NE_CONNECT,
  825. ("subsequent request re-used connection?"));
  826. ne_request_destroy(req);
  827. ne_session_destroy(sess);
  828. fail_request_last_port = port;
  829. return OK;
  830. }
  831. /* Run a random GET request which is given 'body' as the response; the
  832. * request must fail, and 'error' must be found in the error
  833. * string. */
  834. static int invalid_response_gives_error(const char *resp, const char *error)
  835. {
  836. return fail_request_with_error(0, single_serve_string, (void *)resp, 0, error);
  837. }
  838. /* Utility function: run a request using the given server fn, and the
  839. * request must fail. */
  840. static int fail_request(int with_body, server_fn fn, void *ud, int forever)
  841. {
  842. return fail_request_with_error(with_body, fn, ud, forever, NULL);
  843. }
  844. static int unbounded_headers(void)
  845. {
  846. struct infinite i = { RESP200, "x-foo: bar\r\n" };
  847. return fail_request(0, serve_infinite, &i, 0);
  848. }
  849. static int blank_response(void)
  850. {
  851. return fail_request(0, single_serve_string, "\r\n", 0);
  852. }
  853. static int serve_non_http(ne_socket *sock, void *ud)
  854. {
  855. SEND_STRING(sock, "Hello Mum.\n");
  856. ne_sock_readline(sock, buffer, BUFSIZ);
  857. return OK;
  858. }
  859. /* Test behaviour when not speaking to an HTTP server. Regression test
  860. * for infinite loop. */
  861. static int not_http(void)
  862. {
  863. return fail_request(0, serve_non_http, NULL, 0);
  864. }
  865. static int unbounded_folding(void)
  866. {
  867. struct infinite i = { "HTTP/1.0 200 OK\r\nFoo: bar\r\n",
  868. " hello there.\r\n" };
  869. return fail_request(0, serve_infinite, &i, 0);
  870. }
  871. static int serve_close(ne_socket *sock, void *ud)
  872. {
  873. /* do nothing; the socket will be closed. */
  874. return 0;
  875. }
  876. /* Returns non-zero if port is alive. */
  877. static int is_alive(int port)
  878. {
  879. ne_sock_addr *addr;
  880. ne_socket *sock = ne_sock_create();
  881. const ne_inet_addr *ia;
  882. int connected = 0;
  883. addr = ne_addr_resolve("localhost", 0);
  884. for (ia = ne_addr_first(addr); ia && !connected; ia = ne_addr_next(addr))
  885. connected = ne_sock_connect(sock, ia, port) == 0;
  886. ne_addr_destroy(addr);
  887. if (sock == NULL)
  888. return 0;
  889. else {
  890. ne_sock_close(sock);
  891. return 1;
  892. }
  893. }
  894. /* This is a regression test for neon 0.17.0 and earlier, which goes
  895. * into an infinite loop if a request with a body is sent to a server
  896. * which simply closes the connection. */
  897. static int closed_connection(void)
  898. {
  899. int ret;
  900. /* This spawns a server process which will run the 'serve_close'
  901. * response function 200 times, then die. This guarantees that the
  902. * request eventually fails... */
  903. CALL(fail_request(1, serve_close, NULL, 1));
  904. /* if server died -> infinite loop was detected. */
  905. ret = !is_alive(fail_request_last_port);
  906. reap_server();
  907. ONN("server aborted, infinite loop?", ret);
  908. return OK;
  909. }
  910. static int serve_close2(ne_socket *sock, void *userdata)
  911. {
  912. int *count = userdata;
  913. *count += 1;
  914. if (*count == 1)
  915. return 0;
  916. NE_DEBUG(NE_DBG_HTTP, "Re-entered! Buggy client.\n");
  917. CALL(discard_request(sock));
  918. CALL(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n"));
  919. return 0;
  920. }
  921. /* As closed_connection(); but check that the client doesn't retry
  922. * after receiving the EOF on the first request down a new
  923. * connection. */
  924. static int close_not_retried(void)
  925. {
  926. int count = 0;
  927. ne_session *sess;
  928. unsigned int port;
  929. CALL(new_spawn_server(3, serve_close2, &count, &port));
  930. sess = ne_session_create("http", "localhost", port);
  931. ONN("request was retried after EOF", any_request(sess, "/foo") == NE_OK);
  932. reap_server();
  933. ne_session_destroy(sess);
  934. return OK;
  935. }
  936. static enum {
  937. prog_error, /* error */
  938. prog_transfer, /* doing a transfer */
  939. prog_done /* finished. */
  940. } prog_state = prog_transfer;
  941. static ne_off_t prog_last = -1, prog_total;
  942. #define FOFF "%" NE_FMT_NE_OFF_T
  943. /* callback for send_progress. */
  944. static void s_progress(void *userdata, ne_off_t prog, ne_off_t total)
  945. {
  946. NE_DEBUG(NE_DBG_HTTP,
  947. "progress callback: " FOFF "/" FOFF ".\n",
  948. prog, total);
  949. switch (prog_state) {
  950. case prog_error:
  951. case prog_done:
  952. return;
  953. case prog_transfer:
  954. if (total != prog_total) {
  955. t_context("total unexpected: " FOFF " not " FOFF "", total, prog_total);
  956. prog_state = prog_error;
  957. }
  958. else if (prog > total) {
  959. t_context("first progress was invalid (" FOFF "/" FOFF ")", prog, total);
  960. prog_state = prog_error;
  961. }
  962. else if (prog_last != -1 && prog_last > prog) {
  963. t_context("progress went backwards: " FOFF " to " FOFF, prog_last, prog);
  964. prog_state = prog_error;
  965. }
  966. else if (prog_last == prog) {
  967. t_context("no progress made! " FOFF " to " FOFF, prog_last, prog);
  968. prog_state = prog_error;
  969. }
  970. else if (prog == total) {
  971. prog_state = prog_done;
  972. }
  973. break;
  974. }
  975. prog_last = prog;
  976. }
  977. #undef FOFF
  978. static ssize_t provide_progress(void *userdata, char *buf, size_t bufsiz)
  979. {
  980. int *count = userdata;
  981. if (*count >= 0 && buf != NULL) {
  982. buf[0] = 'a';
  983. *count -= 1;
  984. return 1;
  985. } else {
  986. return 0;
  987. }
  988. }
  989. static int send_progress(void)
  990. {
  991. static int count = 200;
  992. ON(prepare_request(single_serve_string,
  993. RESP200 "Connection: close\r\n\r\n"));
  994. prog_total = 200;
  995. ne_set_progress(def_sess, s_progress, NULL);
  996. ne_set_request_body_provider(def_req, count,
  997. provide_progress, &count);
  998. #define sess def_sess
  999. ONREQ(ne_request_dispatch(def_req));
  1000. #undef sess
  1001. ON(finish_request());
  1002. CALL(prog_state == prog_error);
  1003. return OK;
  1004. }
  1005. static int read_timeout(void)
  1006. {
  1007. ne_session *sess;
  1008. ne_request *req;
  1009. time_t start, finish;
  1010. int ret;
  1011. CALL(make_session(&sess, sleepy_server, NULL));
  1012. /* timeout after one second. */
  1013. ne_set_read_timeout(sess, 1);
  1014. req = ne_request_create(sess, "GET", "/timeout");
  1015. time(&start);
  1016. ret = ne_request_dispatch(req);
  1017. time(&finish);
  1018. reap_server();
  1019. ONN("request succeeded, should have timed out", ret == NE_OK);
  1020. ONV(ret != NE_TIMEOUT,
  1021. ("request failed non-timeout error: %s", ne_get_error(sess)));
  1022. ONN("timeout ignored, or very slow machine", finish - start > 3);
  1023. ne_request_destroy(req);
  1024. ne_session_destroy(sess);
  1025. return OK;
  1026. }
  1027. /* expect failure code 'code', for request to given hostname and port,
  1028. * without running a server. */
  1029. static int fail_noserver(const char *hostname, unsigned int port, int code)
  1030. {
  1031. ne_session *sess = ne_session_create("http", hostname, port);
  1032. int ret = any_request(sess, "/foo");
  1033. ne_session_destroy(sess);
  1034. ONV(ret == NE_OK,
  1035. ("request to server at %s:%u succeeded?!", hostname, port));
  1036. ONV(ret != code, ("request failed with %d not %d", ret, code));
  1037. return OK;
  1038. }
  1039. static int fail_lookup(void)
  1040. {
  1041. return fail_noserver("no.such.domain", 4242, NE_LOOKUP);
  1042. }
  1043. /* neon 0.23.0 to 0.23.3: if a nameserver lookup failed, subsequent
  1044. * requests on the session would crash. */
  1045. static int fail_double_lookup(void)
  1046. {
  1047. ne_session *sess = ne_session_create("http", "nonesuch.invalid", 80);
  1048. ONN("request did not give lookup failure",
  1049. any_request(sess, "/foo") != NE_LOOKUP);
  1050. ONN("second request did not give lookup failure",
  1051. any_request(sess, "/bar") != NE_LOOKUP);
  1052. ne_session_destroy(sess);
  1053. return OK;
  1054. }
  1055. static int fail_connect(void)
  1056. {
  1057. return fail_noserver("localhost", 32767, NE_CONNECT);
  1058. }
  1059. /* Test that the origin server hostname is NOT resolved for a proxied
  1060. * request. */
  1061. static int proxy_no_resolve(void)
  1062. {
  1063. ne_session *sess;
  1064. int ret;
  1065. CALL(proxied_session_server(&sess, "http", "no.such.server.invalid", 80,
  1066. single_serve_string,
  1067. RESP200 "Content-Length: 0\r\n\r\n"));
  1068. ret = any_request(sess, "/foo");
  1069. ONN("origin server name resolved when proxy used", ret == NE_LOOKUP);
  1070. return destroy_and_wait(sess);
  1071. }
  1072. /* If the chunk size is entirely invalid, the request should be
  1073. * aborted. Fails with neon <0.22; invalid chunk sizes would be
  1074. * silently treated as 'zero'. */
  1075. static int fail_chunksize(void)
  1076. {
  1077. return fail_request(0, single_serve_string,
  1078. RESP200 TE_CHUNKED "\r\n" "ZZZZZ\r\n\r\n", 0);
  1079. }
  1080. /* in neon <0.22, if an error occcurred whilst reading the response
  1081. * body, the connection would not be closed (though this test will
  1082. * succeed in neon <0.22 since it the previous test fails). */
  1083. static int abort_respbody(void)
  1084. {
  1085. ne_session *sess;
  1086. CALL(make_session(&sess, single_serve_string,
  1087. RESP200 TE_CHUNKED "\r\n"
  1088. "zzz\r\n"
  1089. RESP200 "Content-Length: 0\r\n\r\n"));
  1090. /* connection must be aborted on the first request, since it
  1091. * contains an invalid chunk size. */
  1092. ONN("invalid chunk size was accepted?",
  1093. any_request(sess, "/foo") != NE_ERROR);
  1094. ne_close_connection(sess);
  1095. CALL(await_server());
  1096. /* second request should fail since server has gone away. */
  1097. ONN("connection was not aborted", any_request(sess, "/foo") == NE_OK);
  1098. ne_session_destroy(sess);
  1099. return OK;
  1100. }
  1101. static int serve_then_abort(ne_socket *sock, void *ud)
  1102. {
  1103. int *flag = ud;
  1104. if (*flag == 1) {
  1105. CALL(single_serve_string(sock,
  1106. RESP200 "Content-Length: 0\r\n\r\n"
  1107. RESP200 TE_CHUNKED "\r\n"
  1108. "zzzzz\r\n"));
  1109. *flag = 0;
  1110. }
  1111. exit(0);
  1112. }
  1113. /* Test that after an aborted request on a persistent connection, a
  1114. * failure of the *subsequent* request is not treated as a persistent
  1115. * connection timeout and retried. */
  1116. static int retry_after_abort(void)
  1117. {
  1118. ne_session *sess;
  1119. int flag = 1;
  1120. /* Serve two responses down a single persistent connection, the
  1121. * second of which is invalid and will cause the request to be
  1122. * aborted. */
  1123. CALL(make_session(&sess, serve_then_abort, &flag));
  1124. ONREQ(any_request(sess, "/first"));
  1125. ONN("second request should fail", any_request(sess, "/second") == NE_OK);
  1126. ne_close_connection(sess);
  1127. CALL(await_server());
  1128. /* A third attempt to connect to the server should fail to
  1129. * connect, though this is racy since someone else might come
  1130. * along and steal the port... oh well. */
  1131. ONN("third request was retried",
  1132. any_request(sess, "/third") != NE_CONNECT);
  1133. ne_session_destroy(sess);
  1134. return OK;
  1135. }
  1136. /* Fail to parse the response status line: check the error message is
  1137. * sane. Failed during 0.23-dev briefly, and possibly with 0.22.0
  1138. * too. */
  1139. static int fail_statusline(void)
  1140. {
  1141. ne_session *sess;
  1142. int ret;
  1143. CALL(make_session(&sess, single_serve_string, "Fish.\r\n"));
  1144. ret = any_request(sess, "/fail");
  1145. ONV(ret != NE_ERROR, ("request failed with %d not NE_ERROR", ret));
  1146. ne_close_connection(sess);
  1147. ONV(strstr(ne_get_error(sess),
  1148. "Could not parse response status line") == NULL,
  1149. ("session error was `%s'", ne_get_error(sess)));
  1150. ne_session_destroy(sess);
  1151. return OK;
  1152. }
  1153. #define LEN (9000)
  1154. static int fail_long_header(void)
  1155. {
  1156. char resp[LEN + 500] = "HTTP/1.1 200 OK\r\n"
  1157. "Server: fish\r\n";
  1158. size_t len = strlen(resp);
  1159. /* add a long header */
  1160. memset(resp + len, 'a', LEN);
  1161. resp[len + LEN] = '\0';
  1162. strcat(resp, "\r\n\r\n");
  1163. return invalid_response_gives_error(resp, "Line too long");
  1164. }
  1165. #define VALID_ABCDE "abcde\r\n" CHUNK(0, "")
  1166. static int fail_on_invalid(void)
  1167. {
  1168. static const struct {
  1169. const char *resp, *error;
  1170. } ts[] = {
  1171. /* non-chunked TE. */
  1172. { RESP200 "transfer-encoding: punked\r\n" "\r\n" ABCDE_CHUNKS ,
  1173. "Unknown transfer-coding" },
  1174. /* chunk without trailing CRLF */
  1175. { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcdeFISH",
  1176. "delimiter was invalid" },
  1177. /* chunk with CR then EOF */
  1178. { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcde\n",
  1179. "not read chunk delimiter" },
  1180. /* chunk with CR then notLF */
  1181. { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcde\rZZZ",
  1182. "delimiter was invalid" },
  1183. /* chunk with CR then notLF */
  1184. { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcde\r\r\n",
  1185. "delimiter was invalid" },
  1186. /* chunk with non-hex character */
  1187. { RESP200 TE_CHUNKED "\r\n" "5Z\r\n" "abcde",
  1188. "Could not parse chunk size" },
  1189. /* chunk size overflow */
  1190. { RESP200 TE_CHUNKED "\r\n" "800000000\r\n" "abcde\r\n",
  1191. "Could not parse chunk size" },
  1192. { RESP200 TE_CHUNKED "\r\n" "-8000\r\n" "abcde\r\n",
  1193. "Could not parse chunk size" },
  1194. { RESP200 TE_CHUNKED "\r\n" "0x5\r\n" VALID_ABCDE,
  1195. "Could not parse chunk size" },
  1196. { RESP200 TE_CHUNKED "\r\n" "+5\r\n" VALID_ABCDE,
  1197. "Could not parse chunk size" },
  1198. { RESP200 TE_CHUNKED "\r\n" "5 5\r\n" VALID_ABCDE,
  1199. "Could not parse chunk size" },
  1200. /* LF rather than CRLF in chunk-size is invalid. */
  1201. { RESP200 TE_CHUNKED "\r\n" "5\n" VALID_ABCDE,
  1202. "Invalid chunk-size line" },
  1203. { RESP200 TE_CHUNKED "\r\n" ";5\r\n" VALID_ABCDE,
  1204. "Could not parse chunk size" },
  1205. /* EOF at chunk size */
  1206. { RESP200 TE_CHUNKED "\r\n", "Could not read chunk size" },
  1207. /* negative C-L */
  1208. { RESP200 "Content-Length: -1\r\n" "\r\n" "abcde",
  1209. "Invalid Content-Length" },
  1210. /* invalid C-Ls */
  1211. { RESP200 "Content-Length: 5, 3\r\n" "\r\n" "abcde",
  1212. "Invalid Content-Length" },
  1213. { RESP200 "Content-Length: 5z\r\n" "\r\n" "abcde",
  1214. "Invalid Content-Length" },
  1215. { RESP200 "Content-Length: z5\r\n" "\r\n" "abcde",
  1216. "Invalid Content-Length" },
  1217. /* stupidly-large C-L */
  1218. { RESP200 "Content-Length: 99999999999999999999999999\r\n"
  1219. "\r\n" "abcde",
  1220. "Invalid Content-Length" },
  1221. /* incompatible HTTP-version */
  1222. { "HTTP/2.0 200 OK\r\n"
  1223. "Content-Length: 0\r\n\r\n",
  1224. "Incompatible HTTP version" },
  1225. { "HTTP/0.9 200 OK\r\n"
  1226. "Content-Length: 0\r\n\r\n",
  1227. "Incompatible HTTP version" },
  1228. { NULL, NULL }
  1229. };
  1230. unsigned n;
  1231. for (n = 0; ts[n].resp; n++) {
  1232. NE_DEBUG(NE_DBG_HTTP, "-- fail_on_invalid - test %u\n", n);
  1233. CALL(invalid_response_gives_error(ts[n].resp, ts[n].error));
  1234. }
  1235. return OK;
  1236. }
  1237. static int versions(void)
  1238. {
  1239. ne_session *sess;
  1240. CALL(make_session(&sess, single_serve_string,
  1241. "HTTP/1.1 200 OK\r\n"
  1242. "Content-Length: 0\r\n\r\n"
  1243. "HTTP/1.0 200 OK\r\n"
  1244. "Content-Length: 0\r\n\r\n"));
  1245. ONREQ(any_request(sess, "/http11"));
  1246. ONN("did not detect HTTP/1.1 compliance",
  1247. ne_version_pre_http11(sess) != 0);
  1248. ONREQ(any_request(sess, "/http10"));
  1249. ONN("did not detect lack of HTTP/1.1 compliance",
  1250. ne_version_pre_http11(sess) == 0);
  1251. return destroy_and_wait(sess);
  1252. }
  1253. struct cr_args {
  1254. const char *method, *uri;
  1255. int result;
  1256. };
  1257. static void hk_createreq(ne_request *req, void *userdata,
  1258. const char *method, const char *requri)
  1259. {
  1260. struct cr_args *args = userdata;
  1261. args->result = 1; /* presume failure */
  1262. if (strcmp(args->method, method))
  1263. t_context("Hook got method %s not %s", method, args->method);
  1264. else if (strcmp(args->uri, requri))
  1265. t_context("Hook got Req-URI %s not %s", requri, args->uri);
  1266. else
  1267. args->result = 0;
  1268. }
  1269. static int hook_create_req(void)
  1270. {
  1271. ne_session *sess;
  1272. struct cr_args args;
  1273. ne_uri uri;
  1274. char *u;
  1275. CALL(make_session(&sess, single_serve_string, EMPTY_RESP EMPTY_RESP));
  1276. ne_hook_create_request(sess, hk_createreq, &args);
  1277. args.method = "GET";
  1278. args.uri = "/foo";
  1279. args.result = -1;
  1280. ONREQ(any_request(sess, "/foo"));
  1281. ONN("first hook never called", args.result == -1);
  1282. if (args.result) return FAIL;
  1283. memset(&uri, 0, sizeof uri);
  1284. ne_fill_server_uri(sess, &uri);
  1285. uri.path = "/bar";
  1286. args.uri = u = ne_uri_unparse(&uri);
  1287. args.result = -1;
  1288. ne_free(uri.host);
  1289. ne_free(uri.scheme);
  1290. /* force use of absoluteURI in request-uri */
  1291. ne_session_proxy(sess, "localhost", 7777);
  1292. ONREQ(any_request(sess, "/bar"));
  1293. ONN("second hook never called", args.result == -1);
  1294. if (args.result) return FAIL;
  1295. ne_free(u);
  1296. return destroy_and_wait(sess);
  1297. }
  1298. static int serve_check_method(ne_socket *sock, void *ud)
  1299. {
  1300. char *method = ud;
  1301. char buf[20];
  1302. size_t methlen = strlen(method);
  1303. if (ne_sock_read(sock, buf, methlen) != (ssize_t)methlen)
  1304. return -1;
  1305. ONN("method corrupted", memcmp(buf, method, methlen));
  1306. return single_serve_string(sock, "HTTP/1.1 204 OK\r\n\r\n");
  1307. }
  1308. /* Test that the method string passed to ne_request_create is
  1309. * strdup'ed. */
  1310. static int dup_method(void)
  1311. {
  1312. char method[] = "FOO";
  1313. ne_session *sess;
  1314. ne_request *req;
  1315. CALL(make_session(&sess, serve_check_method, method));
  1316. req = ne_request_create(sess, method, "/bar");
  1317. strcpy(method, "ZZZ");
  1318. ONREQ(ne_request_dispatch(req));
  1319. ne_request_destroy(req);
  1320. return destroy_and_wait(sess);
  1321. }
  1322. static int abortive_reader(void *userdata, const char *buf, size_t len)
  1323. {
  1324. ne_session *sess = userdata;
  1325. if (len == 5 && strncmp(buf, "abcde", 5) == 0) {
  1326. ne_set_error(sess, "Reader callback failed");
  1327. } else {
  1328. ne_set_error(sess, "Reader callback called with length %" NE_FMT_SIZE_T,
  1329. len);
  1330. }
  1331. return NE_ERROR;
  1332. }
  1333. static int abort_reader(void)
  1334. {
  1335. ne_session *sess;
  1336. ne_request *req;
  1337. int ret;
  1338. CALL(make_session(&sess, single_serve_string,
  1339. RESP200 "Content-Length: 5\r\n\r\n"
  1340. "abcde"
  1341. "HTTP/1.1 200 OK\r\n"
  1342. "Content-Length: 0\r\n\r\n"));
  1343. req = ne_request_create(sess, "GET", "/foo");
  1344. ne_add_response_body_reader(req, ne_accept_2xx, abortive_reader, sess);
  1345. ret = ne_request_dispatch(req);
  1346. ONV(ret != NE_ERROR, ("request did not fail with NE_ERROR: %d", ret));
  1347. ONV(strcmp(ne_get_error(sess), "Reader callback failed") != 0,
  1348. ("unexpected session error string: %s", ne_get_error(sess)));
  1349. ne_request_destroy(req);
  1350. /* test that the connection was closed. */
  1351. ONN("connection not closed after aborted response",
  1352. any_2xx_request(sess, "/failmeplease") == OK);
  1353. return destroy_and_wait(sess);
  1354. }
  1355. /* attempt and fail to send request from offset 500 of /dev/null. */
  1356. static int send_bad_offset(void)
  1357. {
  1358. ne_session *sess;
  1359. ne_request *req;
  1360. int ret, fds[2];
  1361. CALL(make_session(&sess, single_serve_string,
  1362. RESP200 "Content-Length: 0\r\n" "\r\n"));
  1363. /* create a pipe, on which seek is guaranteed to fail. */
  1364. ONN("could not create pipe", pipe(fds) != 0);
  1365. req = ne_request_create(sess, "PUT", "/null");
  1366. ne_set_request_body_fd(req, fds[0], 500, 5);
  1367. ret = ne_request_dispatch(req);
  1368. close(fds[0]);
  1369. close(fds[1]);
  1370. ONN("request dispatched with bad offset!", ret == NE_OK);
  1371. ONV(ret != NE_ERROR,
  1372. ("request failed with unexpected error code %d: %s",
  1373. ret, ne_get_error(sess)));
  1374. ONV(strstr(ne_get_error(sess), "Could not seek") == NULL,
  1375. ("bad error message from seek failure: %s", ne_get_error(sess)));
  1376. reap_server();
  1377. ne_request_destroy(req);
  1378. ne_session_destroy(sess);
  1379. return OK;
  1380. }
  1381. static void thook_create_req(ne_request *req, void *userdata,
  1382. const char *method, const char *requri)
  1383. {
  1384. ne_buffer *buf = userdata;
  1385. ne_buffer_concat(buf, "(create,", method, ",", requri, ")\n", NULL);
  1386. }
  1387. static void hook_pre_send(ne_request *req, void *userdata,
  1388. ne_buffer *header)
  1389. {
  1390. ne_buffer *buf = userdata;
  1391. ne_buffer_czappend(buf, "(pre-send)\n");
  1392. }
  1393. /* Returns a static string giving a comma-separated representation of
  1394. * the status structure passed in. */
  1395. static char *status_to_string(const ne_status *status)
  1396. {
  1397. static char sbuf[128];
  1398. ne_snprintf(sbuf, sizeof sbuf, "HTTP/%d.%d,%d,%s",
  1399. status->major_version, status->minor_version,
  1400. status->code, status->reason_phrase);
  1401. return sbuf;
  1402. }
  1403. static void hook_post_headers(ne_request *req, void *userdata,
  1404. const ne_status *status)
  1405. {
  1406. ne_buffer *buf = userdata;
  1407. ne_buffer_concat(buf, "(post-headers,", status_to_string(status), ")\n",
  1408. NULL);
  1409. }
  1410. static int hook_post_send(ne_request *req, void *userdata,
  1411. const ne_status *status)
  1412. {
  1413. ne_buffer *buf = userdata;
  1414. ne_buffer_concat(buf, "(post-send,", status_to_string(status), ")\n",
  1415. NULL);
  1416. return NE_OK;
  1417. }
  1418. static void hook_destroy_req(ne_request *req, void *userdata)
  1419. {
  1420. ne_buffer *buf = userdata;
  1421. ne_buffer_czappend(buf, "(destroy-req)\n");
  1422. }
  1423. static void hook_destroy_sess(void *userdata)
  1424. {
  1425. ne_buffer *buf = userdata;
  1426. ne_buffer_czappend(buf, "(destroy-sess)\n");
  1427. }
  1428. static void hook_close_conn(void *userdata)
  1429. {
  1430. ne_buffer *buf = userdata;
  1431. ne_buffer_czappend(buf, "(close-conn)\n");
  1432. }
  1433. static int hooks(void)
  1434. {
  1435. ne_buffer *buf = ne_buffer_create();
  1436. ne_session *sess;
  1437. struct many_serve_args args;
  1438. args.str = RESP200 "Content-Length: 0\r\n" "\r\n";
  1439. args.count = 3;
  1440. CALL(make_session(&sess, many_serve_string, &args));
  1441. ne_hook_create_request(sess, thook_create_req, buf);
  1442. ne_hook_pre_send(sess, hook_pre_send, buf);
  1443. ne_hook_post_headers(sess, hook_post_headers, buf);
  1444. ne_hook_post_send(sess, hook_post_send, buf);
  1445. ne_hook_destroy_request(sess, hook_destroy_req, buf);
  1446. ne_hook_destroy_session(sess, hook_destroy_sess, buf);
  1447. ne_hook_close_conn(sess, hook_close_conn, buf);
  1448. CALL(any_2xx_request(sess, "/first"));
  1449. ONCMP("(create,GET,/first)\n"
  1450. "(pre-send)\n"
  1451. "(post-headers,HTTP/1.1,200,OK)\n"
  1452. "(post-send,HTTP/1.1,200,OK)\n"
  1453. "(destroy-req)\n", buf->data, "hook ordering", "first result");
  1454. ne_buffer_clear(buf);
  1455. /* Unhook for mismatched fn/ud pointers: */
  1456. ne_unhook_create_request(sess, hk_createreq, buf);
  1457. ne_unhook_create_request(sess, thook_create_req, sess);
  1458. /* Unhook real functions. */
  1459. ne_unhook_pre_send(sess, hook_pre_send, buf);
  1460. ne_unhook_destroy_request(sess, hook_destroy_req, buf);
  1461. ne_unhook_post_headers(sess, hook_post_headers, buf);
  1462. CALL(any_2xx_request(sess, "/second"));
  1463. ONCMP("(create,GET,/second)\n"
  1464. "(post-send,HTTP/1.1,200,OK)\n",
  1465. buf->data, "hook ordering", "second result");
  1466. ne_buffer_clear(buf);
  1467. /* Double hook create, double hook then double unhook post. */
  1468. ne_hook_create_request(sess, thook_create_req, buf);
  1469. ne_hook_post_send(sess, hook_post_send, buf);
  1470. ne_unhook_post_send(sess, hook_post_send, buf);
  1471. ne_unhook_post_send(sess, hook_post_send, buf);
  1472. CALL(any_2xx_request(sess, "/third"));
  1473. ONCMP("(create,GET,/third)\n"
  1474. "(create,GET,/third)\n",
  1475. buf->data, "hook ordering", "third result");
  1476. ne_buffer_clear(buf);
  1477. ne_session_destroy(sess);
  1478. CALL(await_server());
  1479. ONCMP("(destroy-sess)\n"
  1480. "(close-conn)\n", buf->data, "hook ordering", "first destroyed session");
  1481. ne_buffer_clear(buf);
  1482. sess = ne_session_create("http", "www.example.com", 80);
  1483. ne_hook_destroy_session(sess, hook_destroy_sess, buf);
  1484. ne_unhook_destroy_session(sess, hook_destroy_sess, buf);
  1485. ne_session_destroy(sess);
  1486. ONCMP("", buf->data, "hook ordering", "second destroyed session");
  1487. ne_buffer_destroy(buf);
  1488. return OK;
  1489. }
  1490. static void hook_self_destroy_req(ne_request *req, void *userdata)
  1491. {
  1492. ne_unhook_destroy_request(ne_get_session(req),
  1493. hook_self_destroy_req, userdata);
  1494. }
  1495. /* Test that it's safe to call ne_unhook_destroy_request from a
  1496. * destroy_request hook. */
  1497. static int hook_self_destroy(void)
  1498. {
  1499. ne_session *sess = ne_session_create("http", "localhost", 1234);
  1500. ne_hook_destroy_request(sess, hook_self_destroy_req, NULL);
  1501. ne_request_destroy(ne_request_create(sess, "GET", "/"));
  1502. ne_session_destroy(sess);
  1503. return OK;
  1504. }
  1505. static int icy_protocol(void)
  1506. {
  1507. ne_session *sess;
  1508. CALL(make_session(&sess, single_serve_string,
  1509. "ICY 200 OK\r\n"
  1510. "Content-Length: 0\r\n\r\n"));
  1511. ne_set_session_flag(sess, NE_SESSFLAG_ICYPROTO, 1);
  1512. ONREQ(any_request(sess, "/foo"));
  1513. return destroy_and_wait(sess);
  1514. }
  1515. static void status_cb(void *userdata, ne_session_status status,
  1516. const ne_session_status_info *info)
  1517. {
  1518. ne_buffer *buf = userdata;
  1519. char scratch[512];
  1520. switch (status) {
  1521. case ne_status_lookup:
  1522. ne_buffer_concat(buf, "lookup(", info->lu.hostname, ")-", NULL);
  1523. break;
  1524. case ne_status_connecting:
  1525. ne_iaddr_print(info->ci.address, scratch, sizeof scratch);
  1526. ne_buffer_concat(buf, "connecting(", info->lu.hostname,
  1527. ",", scratch, ")-", NULL);
  1528. break;
  1529. case ne_status_disconnected:
  1530. ne_buffer_czappend(buf, "dis");
  1531. /* fallthrough */
  1532. case ne_status_connected:
  1533. ne_buffer_concat(buf, "connected(", info->cd.hostname,
  1534. ")-", NULL);
  1535. break;
  1536. case ne_status_sending:
  1537. case ne_status_recving:
  1538. ne_snprintf(scratch, sizeof scratch,
  1539. "%" NE_FMT_NE_OFF_T ",%" NE_FMT_NE_OFF_T,
  1540. info->sr.progress, info->sr.total);
  1541. ne_buffer_concat(buf,
  1542. status == ne_status_sending ? "send" : "recv",
  1543. "(", scratch, ")-", NULL);
  1544. break;
  1545. default:
  1546. ne_buffer_czappend(buf, "bork!");
  1547. break;
  1548. }
  1549. }
  1550. static int status(void)
  1551. {
  1552. ne_session *sess;
  1553. ne_buffer *buf = ne_buffer_create();
  1554. const char *host, *addr = get_lh_addr();
  1555. char expect[1024];
  1556. CALL(make_session(&sess, single_serve_string, RESP200
  1557. "Content-Length: 5\r\n\r\n" "abcde"));
  1558. host = get_session_host();
  1559. ne_snprintf(expect, sizeof expect,
  1560. "connecting(%s,%s)-"
  1561. "connected(%s)-"
  1562. "send(0,5000)-"
  1563. "send(5000,5000)-"
  1564. "recv(0,5)-"
  1565. "recv(5,5)-"
  1566. "disconnected(%s)-",
  1567. host, addr, host, host);
  1568. ne_set_notifier(sess, status_cb, buf);
  1569. CALL(any_2xx_request_body(sess, "/status"));
  1570. CALL(destroy_and_wait(sess));
  1571. ONV(strcmp(expect, buf->data),
  1572. ("status event sequence mismatch: got [%s] not [%s]",
  1573. buf->data, expect));
  1574. ne_buffer_destroy(buf);
  1575. return OK;
  1576. }
  1577. static int status_chunked(void)
  1578. {
  1579. ne_session *sess;
  1580. ne_buffer *buf = ne_buffer_create();
  1581. const char *host, *addr = get_lh_addr();
  1582. char expect[1024];
  1583. CALL(make_session(&sess, single_serve_string,
  1584. RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS));
  1585. host = get_session_host();
  1586. /* This sequence is not exactly guaranteed by the API, but it's
  1587. * what the current implementation should do. */
  1588. ne_snprintf(expect, sizeof expect,
  1589. "connecting(%s,%s)-"
  1590. "connected(%s)-"
  1591. "send(0,5000)-"
  1592. "send(5000,5000)-"
  1593. "recv(0,-1)-"
  1594. "recv(1,-1)-"
  1595. "recv(2,-1)-"
  1596. "recv(3,-1)-"
  1597. "recv(4,-1)-"
  1598. "recv(5,-1)-"
  1599. "disconnected(%s)-",
  1600. host, addr, host, host);
  1601. ne_set_notifier(sess, status_cb, buf);
  1602. CALL(any_2xx_request_body(sess, "/status"));
  1603. CALL(destroy_and_wait(sess));
  1604. ONV(strcmp(expect, buf->data),
  1605. ("status event sequence mismatch: got [%s] not [%s]",
  1606. buf->data, expect));
  1607. ne_buffer_destroy(buf);
  1608. return OK;
  1609. }
  1610. static int local_addr(void)
  1611. {
  1612. ne_session *sess;
  1613. ne_inet_addr *ia = get_lh_inet_addr();
  1614. CALL(make_session(&sess, single_serve_string, RESP200
  1615. "Connection: close\r\n\r\n"));
  1616. ne_set_localaddr(sess, ia);
  1617. ONREQ(any_request(sess, "/foo"));
  1618. ne_session_destroy(sess);
  1619. ne_iaddr_free(ia);
  1620. return reap_server();
  1621. }
  1622. /* Regression in 0.27.0, ne_set_progress(sess, NULL, NULL) should
  1623. * register the progress callback. */
  1624. static int dereg_progress(void)
  1625. {
  1626. ne_session *sess;
  1627. CALL(make_session(&sess, single_serve_string,
  1628. RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS));
  1629. ne_set_progress(sess, NULL, NULL);
  1630. ONREQ(any_request(sess, "/foo"));
  1631. return destroy_and_wait(sess);
  1632. }
  1633. static int addrlist(void)
  1634. {
  1635. ne_session *sess;
  1636. ne_inet_addr *ia = get_lh_inet_addr();
  1637. const ne_inet_addr *ial[1];
  1638. unsigned int port;
  1639. CALL(new_spawn_server(1, single_serve_string, EMPTY_RESP, &port));
  1640. sess = ne_session_create("http", "www.example.com", port);
  1641. ial[0] = ia;
  1642. ne_set_addrlist(sess, ial, 1);
  1643. CALL(any_2xx_request(sess, "/blah"));
  1644. ne_iaddr_free(ia);
  1645. return destroy_and_wait(sess);
  1646. }
  1647. static int socks_session(ne_session **sess, struct socks_server *srv,
  1648. const char *hostname, unsigned int port,
  1649. server_fn server, void *userdata)
  1650. {
  1651. unsigned int realport;
  1652. srv->server = server;
  1653. srv->userdata = userdata;
  1654. CALL(new_spawn_server(1, socks_server, srv, &realport));
  1655. *sess = ne_session_create("http", hostname, port);
  1656. ne_session_socks_proxy(*sess, srv->version, "localhost", realport,
  1657. srv->username, srv->password);
  1658. return OK;
  1659. }
  1660. static int socks_proxy(void)
  1661. {
  1662. ne_session *sess;
  1663. struct socks_server srv = {0};
  1664. srv.version = NE_SOCK_SOCKSV5;
  1665. srv.failure = fail_none;
  1666. srv.expect_port = 4242;
  1667. srv.expect_addr = NULL;
  1668. srv.expect_fqdn = "socks.example.com";
  1669. srv.username = "bloggs";
  1670. srv.password = "guessme";
  1671. CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port,
  1672. single_serve_string, EMPTY_RESP));
  1673. CALL(any_2xx_request(sess, "/blee"));
  1674. return destroy_and_wait(sess);
  1675. }
  1676. static int socks_v4_proxy(void)
  1677. {
  1678. ne_session *sess;
  1679. struct socks_server srv = {0};
  1680. srv.version = NE_SOCK_SOCKSV4;
  1681. srv.failure = fail_none;
  1682. srv.expect_port = 4242;
  1683. srv.expect_addr = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4);
  1684. srv.expect_fqdn = "localhost";
  1685. srv.username = "bloggs";
  1686. srv.password = "guessme";
  1687. CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port,
  1688. single_serve_string, EMPTY_RESP));
  1689. CALL(any_2xx_request(sess, "/blee"));
  1690. ne_iaddr_free(srv.expect_addr);
  1691. return destroy_and_wait(sess);
  1692. }
  1693. /* Server function which serves the request body back as the response
  1694. * body. */
  1695. static int serve_mirror(ne_socket *sock, void *userdata)
  1696. {
  1697. char response[1024];
  1698. CALL(discard_request(sock));
  1699. ONV(clength == 0 || clength > sizeof buffer,
  1700. ("C-L out of bounds: %lu", clength));
  1701. ONV(ne_sock_fullread(sock, buffer, clength),
  1702. ("read failed: %s", ne_sock_error(sock)));
  1703. ne_snprintf(response, sizeof response,
  1704. "HTTP/1.0 200 OK\r\n"
  1705. "Content-Length: %lu\r\n"
  1706. "\r\n", clength);
  1707. ONN("send response header failed",
  1708. server_send(sock, response, strlen(response)));
  1709. ONN("send response body failed",
  1710. server_send(sock, buffer, clength));
  1711. ONV(ne_sock_read(sock, buffer, 1) != NE_SOCK_CLOSED,
  1712. ("client sent data after request: %c", buffer[0]));
  1713. return OK;
  1714. }
  1715. /* Test for ne_set_request_body_fd() bug in <= 0.29.3. */
  1716. static int send_length(void)
  1717. {
  1718. ne_session *sess;
  1719. ne_request *req;
  1720. int fd;
  1721. ne_buffer *buf = ne_buffer_create();
  1722. fd = open("foobar.txt", O_RDONLY);
  1723. ONV(fd < 0, ("open random.txt failed: %s", strerror(errno)));
  1724. CALL(make_session(&sess, serve_mirror, NULL));
  1725. req = ne_request_create(sess, "GET", "/foo");
  1726. ne_set_request_body_fd(req, fd, 0, 3);
  1727. ne_add_response_body_reader(req, ne_accept_2xx, collector, buf);
  1728. ONREQ(ne_request_dispatch(req));
  1729. ONCMP("foo", buf->data, "response body", "match");
  1730. ne_request_destroy(req);
  1731. ne_buffer_destroy(buf);
  1732. close(fd);
  1733. return destroy_and_wait(sess);
  1734. }
  1735. /* Test for error code for a SOCKS proxy failure, bug in <= 0.29.3. */
  1736. static int socks_fail(void)
  1737. {
  1738. ne_session *sess;
  1739. struct socks_server srv = {0};
  1740. int ret;
  1741. srv.version = NE_SOCK_SOCKSV5;
  1742. srv.failure = fail_init_vers;
  1743. srv.expect_port = 4242;
  1744. srv.expect_addr = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4);
  1745. srv.expect_fqdn = "localhost";
  1746. srv.username = "bloggs";
  1747. srv.password = "guessme";
  1748. CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port,
  1749. single_serve_string, EMPTY_RESP));
  1750. ret = any_request(sess, "/blee");
  1751. ONV(ret != NE_ERROR,
  1752. ("request failed with %d not NE_ERROR", ret));
  1753. ONV(strstr(ne_get_error(sess),
  1754. "Could not establish connection from SOCKS proxy") == NULL
  1755. || strstr(ne_get_error(sess),
  1756. "Invalid version in proxy response") == NULL,
  1757. ("unexpected error string: %s", ne_get_error(sess)));
  1758. ne_iaddr_free(srv.expect_addr);
  1759. return destroy_and_wait(sess);
  1760. }
  1761. static int safe_flags(void)
  1762. {
  1763. ne_session *sess = ne_session_create("http", "localhost", 80);
  1764. ne_request *req = ne_request_create(sess, "GET", "/");
  1765. ne_set_request_flag(req, NE_REQFLAG_LAST, 0xAAAAAAAA);
  1766. ONN("flags array bound check failed", ne_get_session(req) != sess);
  1767. ne_request_destroy(req);
  1768. ne_session_destroy(sess);
  1769. return OK;
  1770. }
  1771. /* Hit the timeout (2 seconds) for reading interim responses. */
  1772. static int fail_excess_1xx(void)
  1773. {
  1774. struct s1xx_args args = {20000000, 0};
  1775. return fail_request_with_error(0, serve_1xx, &args, 0,
  1776. "Timed out reading interim responses");
  1777. }
  1778. static int serve_check_reqline(ne_socket *sock, void *userdata)
  1779. {
  1780. const char *expect = userdata;
  1781. ONN("failed to read request-line",
  1782. ne_sock_readline(sock, buffer, BUFSIZ) <= 0);
  1783. NE_DEBUG(NE_DBG_HTTP, "child: got request-line %s\n", buffer);
  1784. if (strcmp(expect, buffer) != 0)
  1785. return single_serve_string(sock, "HTTP/1.1 400 Bad Request-Line\r\n" EMPTY_RESP);
  1786. else
  1787. return single_serve_string(sock, RESP200 "Connection: close\r\n\r\n");
  1788. }
  1789. /* Test that various request target forms are allowed. */
  1790. static int target_forms(void)
  1791. {
  1792. static const struct {
  1793. const char *uri, *reqline;
  1794. } ts[] = {
  1795. { "/foo", "GET /foo HTTP/1.1\r\n" },
  1796. { "/foo?bar", "GET /foo?bar HTTP/1.1\r\n" },
  1797. { "ftp://www.example.com/foo", "GET ftp://www.example.com/foo HTTP/1.1\r\n" },
  1798. { "*", "GET * HTTP/1.1\r\n" },
  1799. { NULL, NULL }
  1800. };
  1801. unsigned n;
  1802. for (n = 0; ts[n].uri; n++) {
  1803. ne_session *sess;
  1804. CALL(make_session(&sess, serve_check_reqline, (void *)ts[n].reqline));
  1805. ONREQ(any_2xx_request(sess, ts[n].uri));
  1806. CALL(destroy_and_wait(sess));
  1807. }
  1808. return OK;
  1809. }
  1810. /* Interim response callback. */
  1811. static void test_interim(void *userdata, ne_request *req, const ne_status *st)
  1812. {
  1813. ne_buffer *buf = userdata;
  1814. const char *val;
  1815. ne_buffer_snprintf(buf, 15, "[code=%d]", st->code);
  1816. val = ne_get_response_header(req, "X-Interim");
  1817. ne_buffer_concat(buf, "[hdr=", val ? val : "null", "]", NULL);
  1818. }
  1819. /* Test for interim response headers. */
  1820. static int interims(void)
  1821. {
  1822. ne_session *sess;
  1823. ne_request *req;
  1824. ne_buffer *buf = ne_buffer_create();
  1825. CALL(make_session(&sess, single_serve_string,
  1826. "HTTP/1.1 103 Early Stuff\r\n"
  1827. "X-Interim: foobar\r\n" "\r\n"
  1828. "HTTP/1.1 102 Stuff Is Happening\r\n"
  1829. "X-Interim: bar, foo\r\n" "\r\n"
  1830. "HTTP/1.1 200 Thank you kindly\r\n"
  1831. "Content-Length: 0\r\n"
  1832. "X-Not-Interim: finally\r\n" "\r\n"));
  1833. req = ne_request_create(sess, "GET", "/");
  1834. ne_add_interim_handler(req, test_interim, buf);
  1835. ONREQ(ne_request_dispatch(req));
  1836. ONN("interim header leaked to final response",
  1837. ne_get_response_header(req, "X-Interim") != NULL);
  1838. ne_request_destroy(req);
  1839. CALL(destroy_and_wait(sess));
  1840. ONCMPN("[code=103][hdr=foobar][code=102][hdr=bar, foo]", buf->data,
  1841. "interim responses", "trace");
  1842. ne_buffer_destroy(buf);
  1843. return OK;
  1844. }
  1845. static int retry_408(void)
  1846. {
  1847. ne_session *sess;
  1848. /* Serve two responses down a single persistent connection, the
  1849. * second of which is invalid and will cause the request to be
  1850. * aborted. */
  1851. CALL(multi_session_server(&sess, "http", "localhost",
  1852. 2, single_serve_string,
  1853. EMPTY_RESP
  1854. "HTTP/1.1 408 Request Timeout\r\n"
  1855. "Server: neon-test-server\r\n"
  1856. "Content-Length: 0\r\n\r\n"));
  1857. CALL(any_2xx_request(sess, "/first408"));
  1858. CALL(any_2xx_request(sess, "/second408"));
  1859. return destroy_and_wait(sess);
  1860. }
  1861. /* Ensure that only a 408 on a persisted connection is
  1862. * retried. Otherwise it should just be handled as a final
  1863. * response. */
  1864. static int dont_retry_408(void)
  1865. {
  1866. ne_session *sess;
  1867. CALL(make_session(&sess, single_serve_string,
  1868. "HTTP/1.1 408 Request Timeout\r\n"
  1869. "Server: neon-test-server\r\n"
  1870. "Content-Length: 0\r\n\r\n"));
  1871. /* Run any request, ensure it gets a 408 response. */
  1872. CALL(run_request(sess, 408, construct_get, NULL));
  1873. return destroy_and_wait(sess);
  1874. }
  1875. static const char *ipv6_check_result = "500 Something Went Wrong";
  1876. #define V6_EXAMPLE_HOST "[2001:db8::cafe]"
  1877. static void ipv6_host_checker(char *value)
  1878. {
  1879. NE_DEBUG(NE_DBG_HTTP, "child: header value [%s]\n", value);
  1880. if (strcmp(value, V6_EXAMPLE_HOST) == 0)
  1881. ipv6_check_result = "200 Good Header";
  1882. else
  1883. ipv6_check_result = "400 Bad Header";
  1884. }
  1885. /* Server which acts as a proxy accepting a CONNECT request. */
  1886. static int serve_v6_check(ne_socket *sock, void *ud)
  1887. {
  1888. char resp[512];
  1889. got_header = ipv6_host_checker;
  1890. want_header = "Host";
  1891. CALL(discard_request(sock));
  1892. ne_snprintf(resp, sizeof resp, "HTTP/1.1 %s\r\n"
  1893. "Content-Length: 0\r\n"
  1894. "Server: serve_v6_check\r\n\r\n",
  1895. ipv6_check_result);
  1896. SEND_STRING(sock, resp);
  1897. return 0;
  1898. }
  1899. static int ipv6_literal(void)
  1900. {
  1901. ne_session *sess;
  1902. CALL(fakeproxied_session_server(&sess, "http", V6_EXAMPLE_HOST,
  1903. 80, serve_v6_check, NULL));
  1904. CALL(any_2xx_request(sess, "/ipv6ish"));
  1905. return destroy_and_wait(sess);
  1906. }
  1907. static int targets(void)
  1908. {
  1909. struct {
  1910. const char *scheme;
  1911. const char *host;
  1912. int port;
  1913. const char *method;
  1914. const char *target;
  1915. const char *expected;
  1916. } ts[] = {
  1917. { "http", "example.com", 80, "GET", "/fish", "http://example.com/fish" },
  1918. { "http", "example.com", 8080, "GET", "/fish", "http://example.com:8080/fish" },
  1919. { "https", "example.com", 443, "GET", "/", "https://example.com/" },
  1920. { "http", "proxy.example.com", 80, "GET", "ftp://example.com/fishfood", "ftp://example.com/fishfood" },
  1921. { "https", "example.com", 443, "OPTIONS", "*", "https://example.com" },
  1922. { NULL }
  1923. };
  1924. unsigned n;
  1925. for (n = 0; ts[n].scheme != NULL; n++ ) {
  1926. const ne_uri *uri, *uri2;
  1927. ne_session *sess;
  1928. ne_request *req;
  1929. char *actual;
  1930. sess = ne_session_create(ts[n].scheme, ts[n].host, ts[n].port);
  1931. req = ne_request_create(sess, ts[n].method, ts[n].target);
  1932. uri = ne_get_request_target(req);
  1933. uri2 = ne_get_request_target(req);
  1934. actual = uri ? ne_uri_unparse(uri) : NULL;
  1935. ONCMP(ts[n].expected, actual, "request target", "URI");
  1936. ONN("caching failed, different rv on second call", uri != uri2);
  1937. if (actual) ne_free(actual);
  1938. ne_request_destroy(req);
  1939. ne_session_destroy(sess);
  1940. }
  1941. return OK;
  1942. }
  1943. /* TODO: test that ne_set_notifier(, NULL, NULL) DTRT too. */
  1944. ne_test tests[] = {
  1945. T(lookup_localhost),
  1946. T(response_bodies),
  1947. T(no_body_204),
  1948. T(no_body_304),
  1949. T(no_body_HEAD),
  1950. T(reason_phrase),
  1951. T(chunk_oversize),
  1952. T(no_body_chunks),
  1953. T(persist_http11),
  1954. T(persist_chunked),
  1955. T(persist_http10),
  1956. T(persist_proxy_http10),
  1957. T(persist_timeout),
  1958. T(no_persist_http10),
  1959. T(ptimeout_eof),
  1960. T(ptimeout_eof2),
  1961. T(closed_connection),
  1962. T(close_not_retried),
  1963. T(send_progress),
  1964. T(response_headers),
  1965. T(reset_headers),
  1966. T(iterate_none),
  1967. T(iterate_many),
  1968. T(skip_interim_1xx),
  1969. T(skip_many_1xx),
  1970. T(skip_1xx_hdrs),
  1971. T(send_bodies),
  1972. T(expect_100_once),
  1973. T(expect_100_nobody),
  1974. T(unbounded_headers),
  1975. T(unbounded_folding),
  1976. T(blank_response),
  1977. T(not_http),
  1978. T(fail_eof_continued),
  1979. T(fail_eof_headers),
  1980. T(fail_eof_chunk),
  1981. T(fail_eof_badclen),
  1982. T(fail_long_header),
  1983. T(fail_on_invalid),
  1984. T(read_timeout),
  1985. T(fail_connect),
  1986. T(proxy_no_resolve),
  1987. T(fail_chunksize),
  1988. T(abort_respbody),
  1989. T(retry_after_abort),
  1990. T(fail_statusline),
  1991. T(dup_method),
  1992. T(versions),
  1993. T(hook_create_req),
  1994. T(abort_reader),
  1995. T(send_bad_offset),
  1996. T(hooks),
  1997. T(hook_self_destroy),
  1998. T(icy_protocol),
  1999. T(status),
  2000. T(status_chunked),
  2001. T(local_addr),
  2002. T(dereg_progress),
  2003. T(addrlist),
  2004. T(socks_proxy),
  2005. T(socks_v4_proxy),
  2006. T(send_length),
  2007. T(socks_fail),
  2008. T(fail_lookup),
  2009. T(fail_double_lookup),
  2010. T(safe_flags),
  2011. T(fail_excess_1xx),
  2012. T(target_forms),
  2013. T(interims),
  2014. T(retry_408),
  2015. T(dont_retry_408),
  2016. T(ipv6_literal),
  2017. #if 0
  2018. T(redirect_error),
  2019. #endif
  2020. T(targets),
  2021. T(NULL)
  2022. };