Coverage Report

Created: 2026-09-01 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libevent/http.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3
 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. The name of the author may not be used to endorse or promote products
14
 *    derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27
28
#include "event2/event-config.h"
29
#include "evconfig-private.h"
30
31
0
#define member_size(type, member) sizeof(((type *)0)->member)
32
33
#ifdef EVENT__HAVE_SYS_PARAM_H
34
#include <sys/param.h>
35
#endif
36
#ifdef EVENT__HAVE_SYS_TYPES_H
37
#include <sys/types.h>
38
#endif
39
40
#ifdef HAVE_SYS_IOCCOM_H
41
#include <sys/ioccom.h>
42
#endif
43
#ifdef EVENT__HAVE_SYS_RESOURCE_H
44
#include <sys/resource.h>
45
#endif
46
#ifdef EVENT__HAVE_SYS_TIME_H
47
#include <sys/time.h>
48
#endif
49
#ifdef EVENT__HAVE_SYS_WAIT_H
50
#include <sys/wait.h>
51
#endif
52
53
#ifndef _WIN32
54
#include <sys/socket.h>
55
#include <sys/stat.h>
56
#else /* _WIN32 */
57
#include <winsock2.h>
58
#include <ws2tcpip.h>
59
#endif /* _WIN32 */
60
61
#ifdef EVENT__HAVE_SYS_UN_H
62
#include <sys/un.h>
63
#endif
64
#ifdef EVENT__HAVE_AFUNIX_H
65
#include <afunix.h>
66
#endif
67
68
#include <sys/queue.h>
69
70
#ifdef EVENT__HAVE_NETINET_IN_H
71
#include <netinet/in.h>
72
#endif
73
#ifdef EVENT__HAVE_ARPA_INET_H
74
#include <arpa/inet.h>
75
#endif
76
#ifdef EVENT__HAVE_NETDB_H
77
#include <netdb.h>
78
#endif
79
80
#ifdef _WIN32
81
#include <winsock2.h>
82
#endif
83
84
#include <ctype.h>
85
#include <errno.h>
86
#include <stdio.h>
87
#include <stdlib.h>
88
#include <string.h>
89
#ifndef _WIN32
90
#include <syslog.h>
91
#endif /* !_WIN32 */
92
#include <signal.h>
93
#ifdef EVENT__HAVE_UNISTD_H
94
#include <unistd.h>
95
#endif
96
#ifdef EVENT__HAVE_FCNTL_H
97
#include <fcntl.h>
98
#endif
99
100
#undef timeout_pending
101
#undef timeout_initialized
102
103
#include "strlcpy-internal.h"
104
#include "event2/http.h"
105
#include "event2/event.h"
106
#include "event2/buffer.h"
107
#include "event2/bufferevent.h"
108
#include "event2/http_struct.h"
109
#include "event2/http_compat.h"
110
#include "event2/util.h"
111
#include "event2/ws.h"
112
#include "event2/listener.h"
113
#include "log-internal.h"
114
#include "util-internal.h"
115
#include "http-internal.h"
116
#include "mm-internal.h"
117
#include "bufferevent-internal.h"
118
119
#ifndef EVENT__HAVE_GETNAMEINFO
120
#define NI_MAXSERV 32
121
#define NI_MAXHOST 1025
122
123
#ifndef NI_NUMERICHOST
124
#define NI_NUMERICHOST 1
125
#endif
126
127
#ifndef NI_NUMERICSERV
128
#define NI_NUMERICSERV 2
129
#endif
130
static int
131
fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
132
  size_t hostlen, char *serv, size_t servlen, int flags)
133
{
134
  struct sockaddr_in *sin = (struct sockaddr_in *)sa;
135
136
  if (serv != NULL) {
137
    char tmpserv[16];
138
    evutil_snprintf(tmpserv, sizeof(tmpserv),
139
        "%d", ntohs(sin->sin_port));
140
    if (strlcpy(serv, tmpserv, servlen) >= servlen)
141
      return (-1);
142
  }
143
144
  if (host != NULL) {
145
    if (flags & NI_NUMERICHOST) {
146
      if (strlcpy(host, inet_ntoa(sin->sin_addr),
147
          hostlen) >= hostlen)
148
        return (-1);
149
      else
150
        return (0);
151
    } else {
152
      struct hostent *hp;
153
      hp = gethostbyaddr((char *)&sin->sin_addr,
154
          sizeof(struct in_addr), AF_INET);
155
      if (hp == NULL)
156
        return (-2);
157
158
      if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
159
        return (-1);
160
      else
161
        return (0);
162
    }
163
  }
164
  return (0);
165
}
166
167
#endif
168
169
static int evhttp_validate_len_and_encoding_(struct evhttp_request *req);
170
171
#define REQ_VERSION_BEFORE(req, major_v, minor_v)     \
172
0
  ((req)->major < (major_v) ||         \
173
0
      ((req)->major == (major_v) && (req)->minor < (minor_v)))
174
175
#define REQ_VERSION_ATLEAST(req, major_v, minor_v)      \
176
0
  ((req)->major > (major_v) ||         \
177
0
      ((req)->major == (major_v) && (req)->minor >= (minor_v)))
178
179
#ifndef MIN
180
#define MIN(a,b) (((a)<(b))?(a):(b))
181
#endif
182
183
/** The request obj owns the evhttp connection and needs to free it */
184
0
#define EVHTTP_REQ_OWN_CONNECTION 0x0001
185
/** The request object is owned by the user; the user must free it */
186
0
#define EVHTTP_USER_OWNED   0x0004
187
/** The request will be used again upstack; freeing must be deferred */
188
9.87k
#define EVHTTP_REQ_DEFER_FREE   0x0008
189
/** The request should be freed upstack */
190
0
#define EVHTTP_REQ_NEEDS_FREE   0x0010
191
192
extern int debug;
193
194
static evutil_socket_t create_bind_socket_nonblock(struct evutil_addrinfo *, int reuse);
195
static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
196
static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
197
static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri, unsigned flags);
198
static enum message_read_status evhttp_parse_headers_impl_(
199
  struct evhttp_request *req,
200
  struct evbuffer *buffer,
201
  struct evkeyvalq *headers);
202
static int evhttp_associate_new_request_with_connection(
203
  struct evhttp_connection *evcon);
204
static void evhttp_connection_start_detectclose(
205
  struct evhttp_connection *evcon);
206
static void evhttp_connection_stop_detectclose(
207
  struct evhttp_connection *evcon);
208
static void evhttp_request_dispatch(struct evhttp_connection* evcon);
209
static void evhttp_read_firstline(struct evhttp_connection *evcon,
210
          struct evhttp_request *req);
211
static void evhttp_read_header(struct evhttp_connection *evcon,
212
    struct evhttp_request *req);
213
static int evhttp_add_header_internal(struct evkeyvalq *headers,
214
    const char *key, const char *value);
215
static const char *evhttp_response_phrase_internal(int code);
216
static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t, struct bufferevent *bev);
217
static void evhttp_write_buffer(struct evhttp_connection *,
218
    void (*)(struct evhttp_connection *, void *), void *);
219
static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
220
static int evhttp_method_may_have_body_(struct evhttp_connection *, enum evhttp_cmd_type);
221
222
/* callbacks for bufferevent */
223
static void evhttp_read_cb(struct bufferevent *, void *);
224
static void evhttp_write_cb(struct bufferevent *, void *);
225
static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
226
static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp, const char *hostname);
227
static const char *evhttp_method_(struct evhttp_connection *evcon,
228
  enum evhttp_cmd_type type, ev_uint16_t *flags);
229
230
#ifndef EVENT__HAVE_STRSEP
231
/* strsep replacement for platforms that lack it.  Only works if
232
 * del is one character long. */
233
static char *
234
strsep(char **s, const char *del)
235
{
236
  char *d, *tok;
237
  EVUTIL_ASSERT(strlen(del) == 1);
238
  if (!s || !*s)
239
    return NULL;
240
  tok = *s;
241
  d = strstr(tok, del);
242
  if (d) {
243
    *d = '\0';
244
    *s = d + 1;
245
  } else
246
    *s = NULL;
247
  return tok;
248
}
249
#endif
250
251
static size_t
252
html_replace(const char ch, const char **escaped)
253
147M
{
254
147M
  switch (ch) {
255
51.0k
  case '<':
256
51.0k
    *escaped = "&lt;";
257
51.0k
    return 4;
258
7.58k
  case '>':
259
7.58k
    *escaped = "&gt;";
260
7.58k
    return 4;
261
163k
  case '"':
262
163k
    *escaped = "&quot;";
263
163k
    return 6;
264
35.9M
  case '\'':
265
35.9M
    *escaped = "&#039;";
266
35.9M
    return 6;
267
1.64M
  case '&':
268
1.64M
    *escaped = "&amp;";
269
1.64M
    return 5;
270
109M
  default:
271
109M
    break;
272
147M
  }
273
274
109M
  return 1;
275
147M
}
276
277
/*
278
 * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
279
 * &#039; and &amp; correspondingly.
280
 *
281
 * The returned string needs to be freed by the caller.
282
 */
283
284
char *
285
evhttp_htmlescape(const char *html)
286
2.63k
{
287
2.63k
  size_t i;
288
2.63k
  size_t new_size = 0, old_size = 0;
289
2.63k
  char *escaped_html, *p;
290
291
2.63k
  if (html == NULL)
292
0
    return (NULL);
293
294
2.63k
  old_size = strlen(html);
295
73.6M
  for (i = 0; i < old_size; ++i) {
296
73.6M
    const char *replaced = NULL;
297
73.6M
    const size_t replace_size = html_replace(html[i], &replaced);
298
73.6M
    if (replace_size > EV_SIZE_MAX - new_size) {
299
0
      event_warn("%s: html_replace overflow", __func__);
300
0
      return (NULL);
301
0
    }
302
73.6M
    new_size += replace_size;
303
73.6M
  }
304
305
2.63k
  if (new_size == EV_SIZE_MAX)
306
0
    return (NULL);
307
2.63k
  p = escaped_html = mm_malloc(new_size + 1);
308
2.63k
  if (escaped_html == NULL) {
309
0
    event_warn("%s: malloc(%lu)", __func__,
310
0
               (unsigned long)(new_size + 1));
311
0
    return (NULL);
312
0
  }
313
73.6M
  for (i = 0; i < old_size; ++i) {
314
73.6M
    const char *replaced = &html[i];
315
73.6M
    const size_t len = html_replace(html[i], &replaced);
316
73.6M
    memcpy(p, replaced, len);
317
73.6M
    p += len;
318
73.6M
  }
319
320
2.63k
  *p = '\0';
321
322
2.63k
  return (escaped_html);
323
2.63k
}
324
325
/** Given an evhttp_cmd_type, returns a constant string containing the
326
 * equivalent HTTP command, or NULL if the evhttp_cmd_type is
327
 * unrecognized. */
328
static const char *
329
evhttp_method_(struct evhttp_connection *evcon,
330
              enum evhttp_cmd_type type, ev_uint16_t *flags)
331
0
{
332
0
  struct evhttp_ext_method ext_method;
333
0
  const char *method    = NULL;
334
0
  ev_uint16_t tmp_flags = EVHTTP_METHOD_HAS_BODY;
335
336
0
  switch (type) {
337
0
  case EVHTTP_REQ_GET:
338
0
    method = "GET";
339
0
    break;
340
0
  case EVHTTP_REQ_POST:
341
0
    method = "POST";
342
0
    break;
343
0
  case EVHTTP_REQ_HEAD:
344
0
    method = "HEAD";
345
0
    tmp_flags &= ~EVHTTP_METHOD_HAS_BODY;
346
0
    break;
347
0
  case EVHTTP_REQ_PUT:
348
0
    method = "PUT";
349
0
    break;
350
0
  case EVHTTP_REQ_DELETE:
351
0
    method = "DELETE";
352
0
    break;
353
0
  case EVHTTP_REQ_OPTIONS:
354
0
    method = "OPTIONS";
355
0
    break;
356
0
  case EVHTTP_REQ_TRACE:
357
0
    method = "TRACE";
358
0
    tmp_flags &= ~EVHTTP_METHOD_HAS_BODY;
359
0
    break;
360
0
  case EVHTTP_REQ_CONNECT:
361
0
    method = "CONNECT";
362
0
    break;
363
0
  case EVHTTP_REQ_PATCH:
364
0
    method = "PATCH";
365
0
    break;
366
0
  case EVHTTP_REQ_PROPFIND:
367
0
    method = "PROPFIND";
368
0
    break;
369
0
  case EVHTTP_REQ_PROPPATCH:
370
0
    method = "PROPPATCH";
371
0
    break;
372
0
  case EVHTTP_REQ_MKCOL:
373
0
    method = "MKCOL";
374
0
    break;
375
0
  case EVHTTP_REQ_LOCK:
376
0
    method = "LOCK";
377
0
    break;
378
0
  case EVHTTP_REQ_UNLOCK:
379
0
    method = "UNLOCK";
380
0
    break;
381
0
  case EVHTTP_REQ_COPY:
382
0
    method = "COPY";
383
0
    break;
384
0
  case EVHTTP_REQ_MOVE:
385
0
    method = "MOVE";
386
0
    break;
387
0
  default:
388
    /* setup the structure to allow for the cmp.
389
     *
390
     * if the cmp function is set, it has the ability to
391
     * modify method and flags. Other fields will be
392
     * ignored.
393
     *
394
     * NOTE: the flags returned are OR'd with the current
395
     *       flags.
396
     */
397
0
    tmp_flags = 0;
398
0
    ext_method.method = NULL;
399
0
    ext_method.type   = type;
400
0
    ext_method.flags  = tmp_flags;
401
402
0
    if (evcon->ext_method_cmp != NULL &&
403
0
      evcon->ext_method_cmp(&ext_method) == 0) {
404
405
0
      if (ext_method.type != type) {
406
0
        event_debug(("%s: callback modified type from %u to %u, not allowed",
407
0
                    __func__, type, ext_method.type));
408
0
        return NULL;
409
0
      }
410
411
0
      method     = ext_method.method;
412
0
      tmp_flags |= ext_method.flags;
413
0
    }
414
415
0
    break;
416
0
  }
417
418
0
  event_debug(("%s: type=%04x => '%s' flags=%04x",
419
0
               __func__, (int)type, method, tmp_flags));
420
421
0
  if (flags)
422
0
    *flags = tmp_flags;
423
0
  return (method);
424
0
}
425
426
/**
427
 * Determines if a response should have a body.
428
 * Follows the rules in RFC 2616 section 4.3.
429
 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
430
 *     a body.
431
 */
432
static int
433
evhttp_response_needs_body(struct evhttp_request *req)
434
1.01k
{
435
1.01k
  return (req->response_code != HTTP_NOCONTENT &&
436
1.01k
    req->response_code != HTTP_NOTMODIFIED &&
437
1.01k
    (req->response_code < 100 || req->response_code >= 200) &&
438
0
    req->type != EVHTTP_REQ_CONNECT &&
439
0
    req->type != EVHTTP_REQ_HEAD);
440
1.01k
}
441
442
/** Helper: called after we've added some data to an evcon's bufferevent's
443
 * output buffer.  Sets the evconn's writing-is-done callback, and puts
444
 * the bufferevent into writing mode.
445
 */
446
static void
447
evhttp_write_buffer(struct evhttp_connection *evcon,
448
    void (*cb)(struct evhttp_connection *, void *), void *arg)
449
1.01k
{
450
1.01k
  event_debug(("%s: preparing to write buffer\n", __func__));
451
452
  /* Set call back */
453
1.01k
  evcon->cb = cb;
454
1.01k
  evcon->cb_arg = arg;
455
456
  /* Disable the read callback: we don't actually care about data;
457
   * we only care about close detection. (We don't disable reading --
458
   * EV_READ, since we *do* want to learn about any close events.) */
459
1.01k
  bufferevent_setcb(evcon->bufev,
460
1.01k
      NULL, /*read*/
461
1.01k
      evhttp_write_cb,
462
1.01k
      evhttp_error_cb,
463
1.01k
      evcon);
464
465
1.01k
  bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
466
1.01k
}
467
468
static void
469
evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
470
0
{
471
0
  bufferevent_disable(evcon->bufev, EV_WRITE);
472
0
}
473
474
static void
475
evhttp_send_continue(struct evhttp_connection *evcon,
476
      struct evhttp_request *req)
477
0
{
478
0
  bufferevent_enable(evcon->bufev, EV_WRITE);
479
0
  evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
480
0
      "HTTP/%d.%d 100 Continue\r\n\r\n",
481
0
      req->major, req->minor);
482
0
  evcon->cb = evhttp_send_continue_done;
483
0
  evcon->cb_arg = NULL;
484
0
  bufferevent_setcb(evcon->bufev,
485
0
      evhttp_read_cb,
486
0
      evhttp_write_cb,
487
0
      evhttp_error_cb,
488
0
      evcon);
489
0
}
490
491
/** Helper: returns true iff evconn is in any connected state. */
492
static int
493
evhttp_connected(struct evhttp_connection *evcon)
494
1.01k
{
495
1.01k
  switch (evcon->state) {
496
1.01k
  case EVCON_DISCONNECTED:
497
1.01k
  case EVCON_CONNECTING:
498
1.01k
    return (0);
499
0
  case EVCON_IDLE:
500
0
  case EVCON_READING_FIRSTLINE:
501
0
  case EVCON_READING_HEADERS:
502
0
  case EVCON_READING_BODY:
503
0
  case EVCON_READING_TRAILER:
504
0
  case EVCON_WRITING:
505
0
  default:
506
0
    return (1);
507
1.01k
  }
508
1.01k
}
509
510
/* Create the headers needed for an outgoing HTTP request, adds them to
511
 * the request's header list, and writes the request line to the
512
 * connection's output buffer.
513
 */
514
static void
515
evhttp_make_header_request(struct evhttp_connection *evcon,
516
    struct evhttp_request *req)
517
0
{
518
0
  const char *method;
519
  /* NOTE: some version of GCC reports a warning that flags may be uninitialized, hence assignment */
520
0
  ev_uint16_t flags = 0;
521
522
  /* Generate request line */
523
0
  if (!(method = evhttp_method_(evcon, req->type, &flags))) {
524
0
    method = "NULL";
525
0
  }
526
527
0
  evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
528
0
      "%s %s HTTP/%d.%d\r\n",
529
0
      method, req->uri, req->major, req->minor);
530
531
  /* Add the content length on a request if missing
532
   * Always add it for POST and PUT requests as clients expect it */
533
0
  if ((flags & EVHTTP_METHOD_HAS_BODY) &&
534
0
      (evbuffer_get_length(req->output_buffer) > 0 ||
535
0
       req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
536
0
      evhttp_find_header(req->output_headers, "Content-Length") == NULL) {
537
0
    char size[22];
538
0
    evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
539
0
        EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
540
0
    evhttp_add_header(req->output_headers, "Content-Length", size);
541
0
  }
542
0
}
543
544
/** Return true if the list of headers in 'headers', interpreted with respect
545
 * to flags, means that we should send a "connection: close" when the request
546
 * is done. */
547
static int
548
evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
549
1.01k
{
550
1.01k
  const char *connection = evhttp_find_header(headers, "Connection");
551
1.01k
  return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
552
1.01k
}
553
554
static int
555
evhttp_is_request_connection_close(struct evhttp_request *req)
556
0
{
557
0
  if (req->type == EVHTTP_REQ_CONNECT)
558
0
    return 0;
559
560
0
  return
561
0
    evhttp_is_connection_close(req->flags, req->input_headers) ||
562
0
    evhttp_is_connection_close(req->flags, req->output_headers);
563
0
}
564
565
/* Return true iff 'headers' contains 'Connection: keep-alive' */
566
static int
567
evhttp_is_connection_keepalive(struct evkeyvalq* headers)
568
1.01k
{
569
1.01k
  const char *connection = evhttp_find_header(headers, "Connection");
570
1.01k
  return (connection != NULL
571
1.01k
      && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
572
1.01k
}
573
574
/* Add a correct "Date" header to headers, unless it already has one. */
575
static void
576
evhttp_maybe_add_date_header(struct evkeyvalq *headers)
577
0
{
578
0
  if (evhttp_find_header(headers, "Date") == NULL) {
579
0
    char date[50];
580
0
    if ((signed)sizeof(date) > evutil_date_rfc1123(date, sizeof(date), NULL)) {
581
0
      evhttp_add_header(headers, "Date", date);
582
0
    }
583
0
  }
584
0
}
585
586
/* Add a "Content-Length" header with value 'content_length' to headers,
587
 * unless it already has a content-length or transfer-encoding header. */
588
static void
589
evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
590
    size_t content_length)
591
0
{
592
0
  if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
593
0
      evhttp_find_header(headers, "Content-Length") == NULL) {
594
0
    char len[22];
595
0
    evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
596
0
        EV_SIZE_ARG(content_length));
597
0
    evhttp_add_header(headers, "Content-Length", len);
598
0
  }
599
0
}
600
601
/*
602
 * Create the headers needed for an HTTP reply in req->output_headers,
603
 * and write the first HTTP response for req line to evcon.
604
 */
605
static void
606
evhttp_make_header_response(struct evhttp_connection *evcon,
607
    struct evhttp_request *req)
608
1.01k
{
609
1.01k
  int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
610
1.01k
  int need_body = evhttp_response_needs_body(req);
611
612
1.01k
  evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
613
1.01k
      "HTTP/%d.%d %d %s\r\n",
614
1.01k
      req->major, req->minor, req->response_code,
615
1.01k
      req->response_code_line);
616
617
1.01k
  if (req->major == 1) {
618
0
    if (req->minor >= 1)
619
0
      evhttp_maybe_add_date_header(req->output_headers);
620
621
    /*
622
     * if the protocol is 1.0; and the connection was keep-alive
623
     * we need to add a keep-alive header, too.
624
     */
625
0
    if (req->minor == 0 && is_keepalive)
626
0
      evhttp_add_header(req->output_headers,
627
0
          "Connection", "keep-alive");
628
629
0
    if ((req->minor >= 1 || is_keepalive) && need_body) {
630
      /*
631
       * we need to add the content length if the
632
       * user did not give it, this is required for
633
       * persistent connections to work.
634
       */
635
0
      evhttp_maybe_add_content_length_header(
636
0
        req->output_headers,
637
0
        evbuffer_get_length(req->output_buffer));
638
0
    }
639
0
  }
640
641
  /* Potentially add headers for unidentified content. */
642
1.01k
  if (need_body) {
643
0
    if (evhttp_find_header(req->output_headers,
644
0
      "Content-Type") == NULL
645
0
        && evcon->http_server->default_content_type) {
646
0
      evhttp_add_header(req->output_headers,
647
0
          "Content-Type",
648
0
          evcon->http_server->default_content_type);
649
0
    }
650
0
  }
651
652
  /* if the request asked for a close, we send a close, too */
653
1.01k
  if (evhttp_is_connection_close(req->flags, req->input_headers)) {
654
0
    evhttp_remove_header(req->output_headers, "Connection");
655
0
    evhttp_add_header(req->output_headers, "Connection", "close");
656
0
  }
657
1.01k
}
658
659
enum expect { NO, CONTINUE, OTHER };
660
static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
661
1.01k
{
662
1.01k
  const char *expect;
663
1.01k
  struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
664
665
1.01k
  if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
666
1.01k
    return NO;
667
668
0
  expect = evhttp_find_header(h, "Expect");
669
0
  if (!expect)
670
0
    return NO;
671
672
0
  return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
673
0
}
674
675
676
/** Generate all headers appropriate for sending the http request in req (or
677
 * the response, if we're sending a response), and write them to evcon's
678
 * bufferevent. Also writes all data from req->output_buffer */
679
static void
680
evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
681
1.01k
{
682
1.01k
  struct evkeyval *header;
683
1.01k
  struct evbuffer *output = bufferevent_get_output(evcon->bufev);
684
685
  /*
686
   * Depending if this is a HTTP request or response, we might need to
687
   * add some new headers or remove existing headers.
688
   */
689
1.01k
  if (req->kind == EVHTTP_REQUEST) {
690
0
    evhttp_make_header_request(evcon, req);
691
1.01k
  } else {
692
1.01k
    evhttp_make_header_response(evcon, req);
693
1.01k
  }
694
695
3.05k
  TAILQ_FOREACH(header, req->output_headers, next) {
696
3.05k
    evbuffer_add_printf(output, "%s: %s\r\n",
697
3.05k
        header->key, header->value);
698
3.05k
  }
699
1.01k
  evbuffer_add(output, "\r\n", 2);
700
701
1.01k
  if (evhttp_have_expect(req, 0) != CONTINUE &&
702
1.01k
    evbuffer_get_length(req->output_buffer)) {
703
    /*
704
     * For a request, we add the POST data, for a reply, this
705
     * is the regular data.
706
     */
707
0
    evbuffer_add_buffer(output, req->output_buffer);
708
0
  }
709
1.01k
}
710
711
void
712
evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
713
    ev_ssize_t new_max_headers_size)
714
0
{
715
0
  if (new_max_headers_size<0)
716
0
    evcon->max_headers_size = EV_SIZE_MAX;
717
0
  else
718
0
    evcon->max_headers_size = new_max_headers_size;
719
0
}
720
void
721
evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
722
    ev_ssize_t new_max_body_size)
723
0
{
724
0
  if (new_max_body_size<0)
725
0
    evcon->max_body_size = EV_UINT64_MAX;
726
0
  else
727
0
    evcon->max_body_size = new_max_body_size;
728
0
}
729
730
static int
731
evhttp_connection_incoming_fail(struct evhttp_request *req,
732
    enum evhttp_request_error error)
733
0
{
734
0
  switch (error) {
735
0
    case EVREQ_HTTP_DATA_TOO_LONG:
736
0
      req->response_code = HTTP_ENTITYTOOLARGE;
737
0
      break;
738
0
    default:
739
0
      req->response_code = HTTP_BADREQUEST;
740
0
  }
741
742
0
  switch (error) {
743
0
  case EVREQ_HTTP_TIMEOUT:
744
0
  case EVREQ_HTTP_EOF:
745
    /*
746
     * these are cases in which we probably should just
747
     * close the connection and not send a reply.  this
748
     * case may happen when a browser keeps a persistent
749
     * connection open and we timeout on the read.  when
750
     * the request is still being used for sending, we
751
     * need to disassociate it from the connection here.
752
     */
753
0
    if (!req->userdone) {
754
      /* remove it so that it will not be freed */
755
0
      TAILQ_REMOVE(&req->evcon->requests, req, next);
756
      /* indicate that this request no longer has a
757
       * connection object
758
       */
759
0
      req->evcon = NULL;
760
0
    }
761
0
    return (-1);
762
0
  case EVREQ_HTTP_INVALID_HEADER:
763
0
  case EVREQ_HTTP_BUFFER_ERROR:
764
0
  case EVREQ_HTTP_REQUEST_CANCEL:
765
0
  case EVREQ_HTTP_DATA_TOO_LONG:
766
0
  default:  /* xxx: probably should just error on default */
767
    /* the callback looks at the uri to determine errors */
768
0
    if (req->uri) {
769
0
      mm_free(req->uri);
770
0
      req->uri = NULL;
771
0
    }
772
0
    if (req->uri_elems) {
773
0
      evhttp_uri_free(req->uri_elems);
774
0
      req->uri_elems = NULL;
775
0
    }
776
777
    /*
778
     * the callback needs to send a reply, once the reply has
779
     * been send, the connection should get freed.
780
     */
781
0
    (*req->cb)(req, req->cb_arg);
782
0
  }
783
784
0
  return (0);
785
0
}
786
787
/* Free connection ownership of which can be acquired by user using
788
 * evhttp_request_own(). */
789
static inline void
790
evhttp_request_free_auto(struct evhttp_request *req)
791
0
{
792
0
  if (!(req->flags & EVHTTP_USER_OWNED))
793
0
    evhttp_request_free(req);
794
0
}
795
796
static void
797
evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
798
0
{
799
0
  TAILQ_REMOVE(&evcon->requests, req, next);
800
0
  evhttp_request_free_auto(req);
801
0
}
802
803
static void
804
evhttp_set_timeout_tv_(struct timeval *tv, const struct timeval *timeout, int def)
805
0
{
806
0
  if (timeout == NULL && def != -1) {
807
0
    tv->tv_sec = def;
808
0
    tv->tv_usec = 0;
809
0
    return;
810
0
  }
811
812
0
  if (timeout) {
813
0
    *tv = *timeout;
814
0
  } else {
815
0
    evutil_timerclear(tv);
816
0
  }
817
0
}
818
static void
819
evhttp_set_timeout_(struct timeval *tv, int timeout, int def)
820
0
{
821
0
  if (timeout == -1) {
822
0
    timeout = def;
823
0
  }
824
825
0
  if (timeout == -1) {
826
0
    evutil_timerclear(tv);
827
0
  } else {
828
0
    struct timeval timeout_tv;
829
0
    timeout_tv.tv_sec = timeout;
830
0
    timeout_tv.tv_usec = 0;
831
0
    *tv = timeout_tv;
832
0
  }
833
0
}
834
835
/* Called when evcon has experienced a (non-recoverable? -NM) error, as
836
 * given in error. If it's an outgoing connection, reset the connection,
837
 * retry any pending requests, and inform the user.  If it's incoming,
838
 * delegates to evhttp_connection_incoming_fail(). */
839
void
840
evhttp_connection_fail_(struct evhttp_connection *evcon,
841
    enum evhttp_request_error error)
842
0
{
843
0
  const int errsave = EVUTIL_SOCKET_ERROR();
844
0
  struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
845
0
  void (*cb)(struct evhttp_request *, void *);
846
0
  void *cb_arg;
847
0
  void (*error_cb)(enum evhttp_request_error, void *);
848
0
  void *error_cb_arg;
849
0
  EVUTIL_ASSERT(req != NULL);
850
851
0
  bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
852
853
0
  error_cb = req->error_cb;
854
0
  error_cb_arg = req->cb_arg;
855
856
0
  if (evcon->flags & EVHTTP_CON_INCOMING) {
857
    /*
858
     * for incoming requests, there are two different
859
     * failure cases.  it's either a network level error
860
     * or an http layer error. for problems on the network
861
     * layer like timeouts we just drop the connections.
862
     * For HTTP problems, we might have to send back a
863
     * reply before the connection can be freed.
864
     */
865
0
    if (evhttp_connection_incoming_fail(req, error) == -1)
866
0
      evhttp_connection_free(evcon);
867
0
    if (error_cb != NULL)
868
0
      error_cb(error, error_cb_arg);
869
0
    return;
870
0
  }
871
872
  /* when the request was canceled, the callback is not executed */
873
0
  if (error != EVREQ_HTTP_REQUEST_CANCEL) {
874
    /* save the callback for later; the cb might free our object */
875
0
    cb = req->cb;
876
0
    cb_arg = req->cb_arg;
877
0
  } else {
878
0
    cb = NULL;
879
0
    cb_arg = NULL;
880
0
  }
881
882
  /* do not fail all requests; the next request is going to get
883
   * send over a new connection.   when a user cancels a request,
884
   * all other pending requests should be processed as normal
885
   */
886
0
  evhttp_request_free_(evcon, req);
887
888
  /* reset the connection */
889
0
  evhttp_connection_reset_(evcon, 1);
890
891
  /* We are trying the next request that was queued on us */
892
0
  if (TAILQ_FIRST(&evcon->requests) != NULL)
893
0
    evhttp_connection_connect_(evcon);
894
0
  else
895
0
    if ((evcon->flags & EVHTTP_CON_OUTGOING) &&
896
0
        (evcon->flags & EVHTTP_CON_AUTOFREE)) {
897
0
      evhttp_connection_free(evcon);
898
0
    }
899
900
  /* The call to evhttp_connection_reset_ overwrote errno.
901
   * Let's restore the original errno, so that the user's
902
   * callback can have a better idea of what the error was.
903
   */
904
0
  EVUTIL_SET_SOCKET_ERROR(errsave);
905
906
  /* inform the user */
907
0
  if (error_cb != NULL)
908
0
    error_cb(error, error_cb_arg);
909
0
  if (cb != NULL)
910
0
    (*cb)(NULL, cb_arg);
911
0
}
912
913
/* Bufferevent callback: invoked when any data has been written from an
914
 * http connection's bufferevent */
915
static void
916
evhttp_write_cb(struct bufferevent *bufev, void *arg)
917
0
{
918
0
  struct evhttp_connection *evcon = arg;
919
920
  /* Activate our call back */
921
0
  if (evcon->cb != NULL)
922
0
    (*evcon->cb)(evcon, evcon->cb_arg);
923
0
}
924
925
/**
926
 * Advance the connection state.
927
 * - If this is an outgoing connection, we've just processed the response;
928
 *   idle or close the connection.
929
 * - If this is an incoming connection, we've just processed the request;
930
 *   respond.
931
 */
932
static void
933
evhttp_connection_done(struct evhttp_connection *evcon)
934
0
{
935
0
  struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
936
0
  int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
937
0
  int free_evcon = 0;
938
939
0
  if (con_outgoing) {
940
    /* idle or close the connection */
941
0
    int need_close = evhttp_is_request_connection_close(req);
942
0
    TAILQ_REMOVE(&evcon->requests, req, next);
943
0
    req->evcon = NULL;
944
945
0
    evcon->state = EVCON_IDLE;
946
947
    /* check if we got asked to close the connection */
948
0
    if (need_close)
949
0
      evhttp_connection_reset_(evcon, 1);
950
951
0
    if (TAILQ_FIRST(&evcon->requests) != NULL) {
952
      /*
953
       * We have more requests; reset the connection
954
       * and deal with the next request.
955
       */
956
0
      if (!evhttp_connected(evcon))
957
0
        evhttp_connection_connect_(evcon);
958
0
      else
959
0
        evhttp_request_dispatch(evcon);
960
0
    } else if (!need_close) {
961
      /*
962
       * The connection is going to be persistent, but we
963
       * need to detect if the other side closes it.
964
       */
965
0
      evhttp_connection_start_detectclose(evcon);
966
0
    } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
967
      /*
968
       * If we have no more requests that need completion
969
       * and we're not waiting for the connection to close
970
       */
971
0
       free_evcon = 1;
972
0
    }
973
0
  } else {
974
    /*
975
     * incoming connection - we need to leave the request on the
976
     * connection so that we can reply to it.
977
     */
978
0
    evcon->state = EVCON_WRITING;
979
0
  }
980
981
  /* notify the user of the request */
982
0
  (*req->cb)(req, req->cb_arg);
983
984
  /* if this was an outgoing request, we own and it's done. so free it. */
985
0
  if (con_outgoing) {
986
0
    evhttp_request_free_auto(req);
987
0
  }
988
989
  /* If this was the last request of an outgoing connection and we're
990
   * not waiting to receive a connection close event and we want to
991
   * automatically free the connection. We check to ensure our request
992
   * list is empty one last time just in case our callback added a
993
   * new request.
994
   */
995
0
  if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
996
0
    evhttp_connection_free(evcon);
997
0
  }
998
0
}
999
1000
/*
1001
 * Handles reading from a chunked request.
1002
 *   return ALL_DATA_READ:
1003
 *     all data has been read
1004
 *   return MORE_DATA_EXPECTED:
1005
 *     more data is expected
1006
 *   return DATA_CORRUPTED:
1007
 *     data is corrupted
1008
 *   return REQUEST_CANCELED:
1009
 *     request was canceled by the user calling evhttp_cancel_request
1010
 *   return DATA_TOO_LONG:
1011
 *     ran over the maximum limit
1012
 */
1013
1014
static enum message_read_status
1015
evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
1016
0
{
1017
0
  if (req == NULL || buf == NULL) {
1018
0
      return DATA_CORRUPTED;
1019
0
  }
1020
1021
0
  while (1) {
1022
0
    size_t buflen;
1023
1024
0
    if ((buflen = evbuffer_get_length(buf)) == 0) {
1025
0
      break;
1026
0
    }
1027
1028
    /* evbuffer_get_length returns size_t, but len variable is ssize_t,
1029
     * check for overflow conditions */
1030
0
    if (buflen > EV_SSIZE_MAX) {
1031
0
      return DATA_CORRUPTED;
1032
0
    }
1033
1034
0
    if (req->ntoread < 0) {
1035
      /* Read chunk size */
1036
0
      ev_int64_t ntoread;
1037
0
      char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF_STRICT);
1038
0
      char *endp;
1039
0
      int error;
1040
0
      size_t len_p;
1041
0
      if (p == NULL)
1042
0
        break;
1043
0
      len_p = strlen(p);
1044
      /* the last chunk is on a new line? */
1045
0
      if (len_p == 0) {
1046
0
        mm_free(p);
1047
0
        continue;
1048
0
      }
1049
      /* strtoll(,,16) lets through whitespace, 0x, +, and - prefixes, but HTTP doesn't. */
1050
0
      error = isspace(p[0]) ||
1051
0
        p[0] == '-' ||
1052
0
        p[0] == '+' ||
1053
0
        (len_p >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X'));
1054
0
      if (error) {
1055
0
        mm_free(p);
1056
0
        return (DATA_CORRUPTED);
1057
0
      }
1058
0
      ntoread = evutil_strtoll(p, &endp, 16);
1059
0
      error = (*p == '\0' ||
1060
0
          (*endp != '\0' && *endp != ' ') ||
1061
0
          ntoread < 0);
1062
0
      mm_free(p);
1063
0
      if (error) {
1064
        /* could not get chunk size */
1065
0
        return (DATA_CORRUPTED);
1066
0
      }
1067
1068
      /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
1069
0
      if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
1070
0
          return DATA_CORRUPTED;
1071
0
      }
1072
1073
0
      if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
1074
        /* failed body length test */
1075
0
        event_debug(("Request body is too long"));
1076
0
        return (DATA_TOO_LONG);
1077
0
      }
1078
1079
0
      req->body_size += (size_t)ntoread;
1080
0
      req->ntoread = ntoread;
1081
0
      if (req->ntoread == 0) {
1082
        /* Last chunk */
1083
0
        return (ALL_DATA_READ);
1084
0
      }
1085
0
      continue;
1086
0
    }
1087
1088
    /* req->ntoread is signed int64, len is ssize_t, based on arch,
1089
     * ssize_t could only be 32b, check for these conditions */
1090
0
    if (req->ntoread > EV_SSIZE_MAX) {
1091
0
      return DATA_CORRUPTED;
1092
0
    }
1093
1094
    /* don't have enough to complete a chunk; wait for more */
1095
0
    if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
1096
0
      return (MORE_DATA_EXPECTED);
1097
1098
    /* Completed chunk */
1099
0
    evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
1100
0
    req->ntoread = -1;
1101
0
    if (req->chunk_cb != NULL) {
1102
0
      req->flags |= EVHTTP_REQ_DEFER_FREE;
1103
0
      (*req->chunk_cb)(req, req->cb_arg);
1104
0
      evbuffer_drain(req->input_buffer,
1105
0
          evbuffer_get_length(req->input_buffer));
1106
0
      req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1107
0
      if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1108
0
        return (REQUEST_CANCELED);
1109
0
      }
1110
0
    }
1111
0
  }
1112
1113
0
  return (MORE_DATA_EXPECTED);
1114
0
}
1115
1116
static void
1117
evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1118
0
{
1119
0
  struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1120
0
  struct evkeyvalq tmp_headers;
1121
0
  TAILQ_INIT(&tmp_headers);
1122
1123
0
  switch (evhttp_parse_headers_impl_(req, buf, &tmp_headers)) {
1124
0
  case DATA_CORRUPTED:
1125
0
  case DATA_TOO_LONG:
1126
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1127
0
    break;
1128
0
  case ALL_DATA_READ:
1129
0
    bufferevent_disable(evcon->bufev, EV_READ);
1130
0
    evhttp_connection_done(evcon);
1131
0
    break;
1132
0
  case MORE_DATA_EXPECTED:
1133
0
  case REQUEST_CANCELED: /* ??? */
1134
0
  default:
1135
0
    break;
1136
0
  }
1137
1138
0
  evhttp_clear_headers(&tmp_headers);
1139
0
}
1140
1141
static void
1142
evhttp_lingering_close(struct evhttp_connection *evcon,
1143
  struct evhttp_request *req)
1144
0
{
1145
0
  struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1146
1147
0
  size_t n = evbuffer_get_length(buf);
1148
0
  if (n > (size_t) req->ntoread)
1149
0
    n = (size_t) req->ntoread;
1150
0
  req->ntoread -= n;
1151
0
  req->body_size += n;
1152
1153
0
  event_debug(("Request body is too long, left " EV_I64_FMT,
1154
0
    EV_I64_ARG(req->ntoread)));
1155
1156
0
  evbuffer_drain(buf, n);
1157
0
  if (!req->ntoread)
1158
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1159
0
}
1160
static void
1161
evhttp_lingering_fail(struct evhttp_connection *evcon,
1162
  struct evhttp_request *req)
1163
0
{
1164
0
  if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1165
0
    evhttp_lingering_close(evcon, req);
1166
0
  else
1167
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1168
0
}
1169
1170
static void
1171
evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1172
0
{
1173
0
  struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1174
1175
0
  if (req->chunked) {
1176
0
    switch (evhttp_handle_chunked_read(req, buf)) {
1177
0
    case ALL_DATA_READ:
1178
      /* finished last chunk */
1179
0
      evcon->state = EVCON_READING_TRAILER;
1180
0
      evhttp_read_trailer(evcon, req);
1181
0
      return;
1182
0
    case DATA_CORRUPTED:
1183
      /* corrupted data */
1184
0
      evhttp_connection_fail_(evcon,
1185
0
          EVREQ_HTTP_INVALID_HEADER);
1186
0
      return;
1187
0
    case DATA_TOO_LONG:
1188
0
      evhttp_connection_fail_(evcon,
1189
0
          EVREQ_HTTP_DATA_TOO_LONG);
1190
0
      return;
1191
0
    case REQUEST_CANCELED:
1192
      /* request canceled */
1193
0
      evhttp_request_free_auto(req);
1194
0
      return;
1195
0
    case MORE_DATA_EXPECTED:
1196
0
    default:
1197
0
      break;
1198
0
    }
1199
0
  } else if (req->ntoread < 0) {
1200
    /* Read until connection close. */
1201
0
    if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1202
0
      evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1203
0
      return;
1204
0
    }
1205
1206
0
    req->body_size += evbuffer_get_length(buf);
1207
0
    evbuffer_add_buffer(req->input_buffer, buf);
1208
0
  } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1209
    /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1210
    /* We've postponed moving the data until now, but we're
1211
     * about to use it. */
1212
0
    size_t n = evbuffer_get_length(buf);
1213
1214
0
    if (n > (size_t) req->ntoread)
1215
0
      n = (size_t) req->ntoread;
1216
0
    req->ntoread -= n;
1217
0
    req->body_size += n;
1218
0
    evbuffer_remove_buffer(buf, req->input_buffer, n);
1219
0
  }
1220
1221
0
  if (req->body_size > req->evcon->max_body_size ||
1222
0
      (!req->chunked && req->ntoread >= 0 &&
1223
0
    (size_t)req->ntoread > req->evcon->max_body_size)) {
1224
    /* XXX: The above cast comparison must be checked for overflow */
1225
    /* failed body length test */
1226
1227
0
    evhttp_lingering_fail(evcon, req);
1228
0
    return;
1229
0
  }
1230
1231
0
  if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1232
0
    req->flags |= EVHTTP_REQ_DEFER_FREE;
1233
0
    (*req->chunk_cb)(req, req->cb_arg);
1234
0
    req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1235
0
    evbuffer_drain(req->input_buffer,
1236
0
        evbuffer_get_length(req->input_buffer));
1237
0
    if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1238
0
      evhttp_request_free_auto(req);
1239
0
      return;
1240
0
    }
1241
0
  }
1242
1243
0
  if (!req->ntoread) {
1244
0
    bufferevent_disable(evcon->bufev, EV_READ);
1245
    /* Completed content length */
1246
0
    evhttp_connection_done(evcon);
1247
0
    return;
1248
0
  }
1249
0
}
1250
1251
#define get_deferred_queue(evcon)   \
1252
1.01k
  ((evcon)->base)
1253
1254
/*
1255
 * Gets called when more data becomes available
1256
 */
1257
1258
static void
1259
evhttp_read_cb(struct bufferevent *bufev, void *arg)
1260
0
{
1261
0
  struct evhttp_connection *evcon = arg;
1262
0
  struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1263
1264
  /* Cancel if it's pending. */
1265
0
  event_deferred_cb_cancel_(get_deferred_queue(evcon),
1266
0
      &evcon->read_more_deferred_cb);
1267
1268
0
  switch (evcon->state) {
1269
0
  case EVCON_READING_FIRSTLINE:
1270
0
    evhttp_read_firstline(evcon, req);
1271
    /* note the request may have been freed in
1272
     * evhttp_read_body */
1273
0
    break;
1274
0
  case EVCON_READING_HEADERS:
1275
0
    evhttp_read_header(evcon, req);
1276
    /* note the request may have been freed in
1277
     * evhttp_read_body */
1278
0
    break;
1279
0
  case EVCON_READING_BODY:
1280
0
    evhttp_read_body(evcon, req);
1281
    /* note the request may have been freed in
1282
     * evhttp_read_body */
1283
0
    break;
1284
0
  case EVCON_READING_TRAILER:
1285
0
    evhttp_read_trailer(evcon, req);
1286
0
    break;
1287
0
  case EVCON_IDLE:
1288
0
    {
1289
#ifdef USE_DEBUG
1290
      struct evbuffer *input;
1291
      size_t total_len;
1292
1293
      input = bufferevent_get_input(evcon->bufev);
1294
      total_len = evbuffer_get_length(input);
1295
      event_debug(("%s: read "EV_SIZE_FMT
1296
        " bytes in EVCON_IDLE state,"
1297
        " resetting connection",
1298
        __func__, EV_SIZE_ARG(total_len)));
1299
#endif
1300
1301
0
      evhttp_connection_reset_(evcon, 1);
1302
0
    }
1303
0
    break;
1304
0
  case EVCON_DISCONNECTED:
1305
0
  case EVCON_CONNECTING:
1306
0
  case EVCON_WRITING:
1307
0
  default:
1308
0
    event_errx(1, "%s: illegal connection state %d",
1309
0
         __func__, evcon->state);
1310
0
  }
1311
0
}
1312
1313
static void
1314
evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1315
0
{
1316
0
  struct evhttp_connection *evcon = data;
1317
0
  struct bufferevent *bev = evcon->bufev;
1318
0
  if (bev->readcb)
1319
0
    (bev->readcb)(evcon->bufev, evcon);
1320
0
}
1321
1322
static void
1323
evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1324
0
{
1325
  /* This is after writing the request to the server */
1326
0
  struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1327
0
  struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1328
0
  EVUTIL_ASSERT(req != NULL);
1329
1330
0
  EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1331
1332
  /* We need to wait until we've written all of our output data before we can
1333
   * continue */
1334
0
  if (evbuffer_get_length(output) > 0)
1335
0
    return;
1336
1337
  /* We are done writing our header and are now expecting the response */
1338
0
  req->kind = EVHTTP_RESPONSE;
1339
1340
0
  evhttp_start_read_(evcon);
1341
0
}
1342
1343
/*
1344
 * Clean up a connection object
1345
 */
1346
1347
void
1348
evhttp_connection_free(struct evhttp_connection *evcon)
1349
1.01k
{
1350
1.01k
  struct evhttp_request *req;
1351
1352
  /* notify interested parties that this connection is going down */
1353
1.01k
  if (evhttp_connected(evcon) && evcon->closecb != NULL)
1354
0
    (*evcon->closecb)(evcon, evcon->closecb_arg);
1355
1356
  /* remove all requests that might be queued on this
1357
   * connection.  for server connections, this should be empty.
1358
   * because it gets dequeued either in evhttp_connection_done or
1359
   * evhttp_connection_fail_.
1360
   */
1361
1.01k
  while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1362
0
    evhttp_request_free_(evcon, req);
1363
0
  }
1364
1365
1.01k
  if (evcon->http_server != NULL) {
1366
1.01k
    struct evhttp *http = evcon->http_server;
1367
1.01k
    TAILQ_REMOVE(&http->connections, evcon, next);
1368
1.01k
    http->connection_cnt--;
1369
1.01k
  }
1370
1371
1.01k
  if (event_initialized(&evcon->retry_ev)) {
1372
0
    event_del(&evcon->retry_ev);
1373
0
    event_debug_unassign(&evcon->retry_ev);
1374
0
  }
1375
1376
1.01k
  event_deferred_cb_cancel_(get_deferred_queue(evcon),
1377
1.01k
      &evcon->read_more_deferred_cb);
1378
1379
1.01k
  if (evcon->bufev != NULL) {
1380
0
    bufferevent_free(evcon->bufev);
1381
0
  }
1382
1383
1.01k
  if (evcon->bind_address != NULL)
1384
0
    mm_free(evcon->bind_address);
1385
1386
1.01k
  if (evcon->address != NULL)
1387
1.01k
    mm_free(evcon->address);
1388
1389
1.01k
#ifndef _WIN32
1390
1.01k
  if (evcon->unixsocket != NULL)
1391
0
    mm_free(evcon->unixsocket);
1392
1.01k
#endif
1393
1394
1.01k
  mm_free(evcon);
1395
1.01k
}
1396
1397
void
1398
0
evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1399
0
  evcon->flags |= EVHTTP_CON_AUTOFREE;
1400
0
}
1401
1402
void
1403
evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1404
    const char *address)
1405
0
{
1406
0
  EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1407
0
  if (evcon->bind_address)
1408
0
    mm_free(evcon->bind_address);
1409
0
  if ((evcon->bind_address = mm_strdup(address)) == NULL)
1410
0
    event_warn("%s: strdup", __func__);
1411
0
}
1412
1413
void
1414
evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1415
    ev_uint16_t port)
1416
0
{
1417
0
  EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1418
0
  evcon->bind_port = port;
1419
0
}
1420
1421
static void
1422
evhttp_request_dispatch(struct evhttp_connection* evcon)
1423
0
{
1424
0
  struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1425
1426
  /* this should not usually happy but it's possible */
1427
0
  if (req == NULL)
1428
0
    return;
1429
1430
0
  EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1431
1432
  /* delete possible close detection events */
1433
0
  evhttp_connection_stop_detectclose(evcon);
1434
1435
  /* we assume that the connection is connected already */
1436
0
  EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1437
1438
0
  evcon->state = EVCON_WRITING;
1439
1440
  /* Create the header from the store arguments */
1441
0
  evhttp_make_header(evcon, req);
1442
1443
0
  evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1444
0
}
1445
1446
/** Hard-reset our connection state
1447
 *
1448
 * This will:
1449
 * - reset fd
1450
 * - clears out buffers
1451
 * - call closecb
1452
 */
1453
static void
1454
evhttp_connection_reset_hard_(struct evhttp_connection *evcon)
1455
0
{
1456
0
  struct evbuffer *tmp;
1457
0
  int err;
1458
1459
  /* XXXX This is not actually an optimal fix.  Instead we ought to have
1460
     an API for "stop connecting", or use bufferevent_replacefd to turn off
1461
     connecting.  But for Libevent 2.0, this seems like a minimal change
1462
     least likely to disrupt the rest of the bufferevent and http code.
1463
1464
     Why is this here?  If the fd is set in the bufferevent, and the
1465
     bufferevent is connecting, then you can't actually stop the
1466
     bufferevent from trying to connect with bufferevent_disable().  The
1467
     connect will never trigger, since we close the fd, but the timeout
1468
     might.  That caused an assertion failure in evhttp_connection_fail_.
1469
  */
1470
0
  bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1471
1472
  /* inform interested parties about connection close */
1473
0
  if (evhttp_connected(evcon) && evcon->closecb != NULL)
1474
0
    (*evcon->closecb)(evcon, evcon->closecb_arg);
1475
1476
  /** FIXME: manipulating with fd is unwanted */
1477
0
  err = bufferevent_replacefd(evcon->bufev, -1);
1478
0
  EVUTIL_ASSERT(!err && "setfd");
1479
1480
  /* we need to clean up any buffered data */
1481
0
  tmp = bufferevent_get_output(evcon->bufev);
1482
0
  err = evbuffer_drain(tmp, -1);
1483
0
  EVUTIL_ASSERT(!err && "drain output");
1484
0
  tmp = bufferevent_get_input(evcon->bufev);
1485
0
  err = evbuffer_drain(tmp, -1);
1486
0
  EVUTIL_ASSERT(!err && "drain input");
1487
0
}
1488
1489
/** Reset our connection state
1490
 *
1491
 * This will:
1492
 * - disables reading/writing
1493
 * - puts us in DISCONNECTED state
1494
 *
1495
 * @param hard - hard reset will (@see evhttp_connection_reset_hard_())
1496
 */
1497
void
1498
evhttp_connection_reset_(struct evhttp_connection *evcon, int hard)
1499
0
{
1500
0
  bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1501
1502
0
  if (hard) {
1503
0
    evhttp_connection_reset_hard_(evcon);
1504
0
  }
1505
1506
0
  evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1507
0
  evcon->state = EVCON_DISCONNECTED;
1508
0
}
1509
1510
static void
1511
evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1512
0
{
1513
0
  evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1514
0
  bufferevent_enable(evcon->bufev, EV_READ);
1515
0
}
1516
1517
static void
1518
evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1519
0
{
1520
0
  evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1521
0
  bufferevent_disable(evcon->bufev, EV_READ);
1522
0
}
1523
1524
static void
1525
evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1526
0
{
1527
0
  struct evhttp_connection *evcon = arg;
1528
1529
0
  evcon->state = EVCON_DISCONNECTED;
1530
0
  evhttp_connection_connect_(evcon);
1531
0
}
1532
1533
static void
1534
evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1535
0
{
1536
0
  struct evcon_requestq requests;
1537
0
  EVUTIL_ASSERT(evcon->flags & EVHTTP_CON_OUTGOING);
1538
1539
0
  evhttp_connection_reset_(evcon, 1);
1540
1541
0
  if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1542
0
    struct timeval tv_retry = evcon->initial_retry_timeout;
1543
0
    int i;
1544
0
    evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1545
    /* XXXX handle failure from evhttp_add_event */
1546
0
    for (i=0; i < evcon->retry_cnt; ++i) {
1547
0
      tv_retry.tv_usec *= 2;
1548
0
      if (tv_retry.tv_usec > 1000000) {
1549
0
        tv_retry.tv_usec -= 1000000;
1550
0
        tv_retry.tv_sec += 1;
1551
0
      }
1552
0
      tv_retry.tv_sec *= 2;
1553
0
      if (tv_retry.tv_sec > 3600) {
1554
0
        tv_retry.tv_sec = 3600;
1555
0
        tv_retry.tv_usec = 0;
1556
0
      }
1557
0
    }
1558
0
    event_add(&evcon->retry_ev, &tv_retry);
1559
0
    evcon->retry_cnt++;
1560
0
    return;
1561
0
  }
1562
1563
  /*
1564
   * User callback can do evhttp_make_request() on the same
1565
   * evcon so new request will be added to evcon->requests.  To
1566
   * avoid freeing it prematurely we iterate over the copy of
1567
   * the queue.
1568
   */
1569
0
  TAILQ_INIT(&requests);
1570
0
  while (TAILQ_FIRST(&evcon->requests) != NULL) {
1571
0
    struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1572
0
    TAILQ_REMOVE(&evcon->requests, request, next);
1573
0
    TAILQ_INSERT_TAIL(&requests, request, next);
1574
0
  }
1575
1576
  /* for now, we just signal all requests by executing their callbacks */
1577
0
  while (TAILQ_FIRST(&requests) != NULL) {
1578
0
    struct evhttp_request *request = TAILQ_FIRST(&requests);
1579
0
    TAILQ_REMOVE(&requests, request, next);
1580
0
    request->evcon = NULL;
1581
1582
    /* we might want to set an error here */
1583
0
    request->cb(request, request->cb_arg);
1584
0
    evhttp_request_free_auto(request);
1585
0
  }
1586
1587
0
  if (TAILQ_FIRST(&evcon->requests) == NULL
1588
0
    && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1589
0
    evhttp_connection_free(evcon);
1590
0
  }
1591
1592
0
}
1593
1594
static void
1595
evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1596
    struct evhttp_request *req)
1597
0
{
1598
0
  struct evbuffer *buf;
1599
1600
  /** Second time, we can't read anything */
1601
0
  if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1602
0
    evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1603
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1604
0
    return;
1605
0
  }
1606
1607
0
  req->kind = EVHTTP_RESPONSE;
1608
1609
0
  buf = bufferevent_get_output(evcon->bufev);
1610
0
  evbuffer_unfreeze(buf, 1);
1611
0
  evbuffer_drain(buf, evbuffer_get_length(buf));
1612
0
  evbuffer_freeze(buf, 1);
1613
1614
0
  evhttp_start_read_(evcon);
1615
0
  evcon->flags |= EVHTTP_CON_READING_ERROR;
1616
0
}
1617
1618
static void
1619
evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1620
0
{
1621
0
  struct evhttp_connection *evcon = arg;
1622
0
  struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1623
1624
0
  switch (evcon->state) {
1625
0
  case EVCON_CONNECTING:
1626
0
    if (what & BEV_EVENT_TIMEOUT) {
1627
0
      event_debug(("%s: connection timeout for \"%s:%d\" on "
1628
0
        EV_SOCK_FMT,
1629
0
        __func__, evcon->address, evcon->port,
1630
0
        EV_SOCK_ARG(bufferevent_getfd(bufev))));
1631
0
      evhttp_connection_cb_cleanup(evcon);
1632
0
      return;
1633
0
    }
1634
0
    break;
1635
1636
0
  case EVCON_READING_BODY:
1637
0
    if (!req->chunked && req->ntoread < 0
1638
0
        && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1639
      /* EOF on read can be benign */
1640
0
      evhttp_connection_done(evcon);
1641
0
      return;
1642
0
    }
1643
0
    break;
1644
1645
0
  case EVCON_DISCONNECTED:
1646
0
  case EVCON_IDLE:
1647
0
  case EVCON_READING_FIRSTLINE:
1648
0
  case EVCON_READING_HEADERS:
1649
0
  case EVCON_READING_TRAILER:
1650
0
  case EVCON_WRITING:
1651
0
  default:
1652
0
    break;
1653
0
  }
1654
1655
  /* when we are in close detect mode, a read error means that
1656
   * the other side closed their connection.
1657
   */
1658
0
  if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1659
0
    evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1660
0
    EVUTIL_ASSERT(evcon->http_server == NULL);
1661
    /* For connections from the client, we just
1662
     * reset the connection so that it becomes
1663
     * disconnected.
1664
     */
1665
0
    EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1666
0
    evhttp_connection_reset_(evcon, 1);
1667
1668
    /*
1669
     * If we have no more requests that need completion
1670
     * and we want to auto-free the connection when all
1671
     * requests have been completed.
1672
     */
1673
0
    if (TAILQ_FIRST(&evcon->requests) == NULL
1674
0
      && (evcon->flags & EVHTTP_CON_OUTGOING)
1675
0
      && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1676
0
      evhttp_connection_free(evcon);
1677
0
    }
1678
0
    return;
1679
0
  }
1680
1681
0
  if (what & BEV_EVENT_TIMEOUT) {
1682
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1683
0
  } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1684
0
    if (what & BEV_EVENT_WRITING &&
1685
0
      evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1686
0
      evhttp_connection_read_on_write_error(evcon, req);
1687
0
      return;
1688
0
    }
1689
1690
0
    if (what & BEV_EVENT_READING &&
1691
0
      evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1692
0
      evbuffer_get_length(bufferevent_get_input(bufev))) {
1693
0
      event_deferred_cb_schedule_(get_deferred_queue(evcon),
1694
0
          &evcon->read_more_deferred_cb);
1695
0
      return;
1696
0
    }
1697
1698
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1699
0
  } else if (what == BEV_EVENT_CONNECTED) {
1700
0
  } else {
1701
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1702
0
  }
1703
0
}
1704
1705
/*
1706
 * Event callback for asynchronous connection attempt.
1707
 */
1708
static void
1709
evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1710
0
{
1711
0
  struct evhttp_connection *evcon = arg;
1712
1713
0
  if (!(what & BEV_EVENT_CONNECTED)) {
1714
    /* some operating systems return ECONNREFUSED immediately
1715
     * when connecting to a local address.  the cleanup is going
1716
     * to reschedule this function call.
1717
     */
1718
0
#ifndef _WIN32
1719
0
    if (errno == ECONNREFUSED)
1720
0
      goto cleanup;
1721
0
#endif
1722
0
    evhttp_error_cb(bufev, what, arg);
1723
0
    return;
1724
0
  }
1725
1726
  /* We are connected to the server now */
1727
0
  event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1728
0
      __func__, evcon->address, evcon->port,
1729
0
      EV_SOCK_ARG(bufferevent_getfd(bufev))));
1730
1731
  /* Reset the retry count as we were successful in connecting */
1732
0
  evcon->retry_cnt = 0;
1733
0
  evcon->state = EVCON_IDLE;
1734
1735
  /* reset the bufferevent cbs */
1736
0
  bufferevent_setcb(evcon->bufev,
1737
0
      evhttp_read_cb,
1738
0
      evhttp_write_cb,
1739
0
      evhttp_error_cb,
1740
0
      evcon);
1741
1742
0
  bufferevent_set_timeouts(evcon->bufev,
1743
0
      &evcon->timeout_read, &evcon->timeout_write);
1744
1745
  /* try to start requests that have queued up on this connection */
1746
0
  evhttp_request_dispatch(evcon);
1747
0
  return;
1748
1749
0
 cleanup:
1750
0
  evhttp_connection_cb_cleanup(evcon);
1751
0
}
1752
1753
/*
1754
 * Check if we got a valid response code.
1755
 */
1756
1757
static int
1758
evhttp_valid_response_code(int code)
1759
2.35k
{
1760
2.35k
  if (code == 0)
1761
4
    return (0);
1762
1763
2.34k
  return (1);
1764
2.35k
}
1765
1766
static int
1767
evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1768
5.95k
{
1769
5.95k
  char major, minor;
1770
5.95k
  char ch;
1771
5.95k
  int n = sscanf(version, "HTTP/%c.%c%c", &major, &minor, &ch);
1772
5.95k
  if (n != 2 || major > '1' || major < '0' || minor > '9' || minor < '0') {
1773
1.31k
    event_debug(("%s: bad version %s on message %p from %s",
1774
1.31k
      __func__, version, (void *)req, req->remote_host));
1775
1.31k
    return (-1);
1776
1.31k
  }
1777
4.64k
  req->major = major - '0';
1778
4.64k
  req->minor = minor - '0';
1779
4.64k
  return (0);
1780
5.95k
}
1781
1782
/* Parses the status line of a web server */
1783
1784
static int
1785
evhttp_parse_response_line(struct evhttp_request *req, char *line)
1786
3.11k
{
1787
3.11k
  char *protocol;
1788
3.11k
  char *number;
1789
3.11k
  const char *readable = "";
1790
1791
3.11k
  protocol = strsep(&line, " ");
1792
3.11k
  if (line == NULL)
1793
207
    return (-1);
1794
2.91k
  number = strsep(&line, " ");
1795
2.91k
  if (line != NULL)
1796
2.81k
    readable = line;
1797
1798
2.91k
  if (evhttp_parse_http_version(protocol, req) < 0)
1799
560
    return (-1);
1800
1801
2.35k
  req->response_code = atoi(number);
1802
2.35k
  if (!evhttp_valid_response_code(req->response_code)) {
1803
4
    event_debug(("%s: bad response code \"%s\"",
1804
4
      __func__, number));
1805
4
    return (-1);
1806
4
  }
1807
1808
2.34k
  if (req->response_code_line != NULL)
1809
0
    mm_free(req->response_code_line);
1810
2.34k
  if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1811
0
    event_warn("%s: strdup", __func__);
1812
0
    return (-1);
1813
0
  }
1814
1815
2.34k
  return (0);
1816
2.34k
}
1817
1818
/* Parse the first line of a HTTP request */
1819
1820
static int
1821
evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1822
3.40k
{
1823
3.40k
  char *eos = line + len;
1824
3.40k
  char *method;
1825
3.40k
  char *uri;
1826
3.40k
  char *version;
1827
3.40k
  size_t method_len;
1828
3.40k
  enum evhttp_cmd_type type = 0;
1829
1830
3.88k
  while (eos > line && *(eos-1) == ' ') {
1831
481
    *(eos-1) = '\0';
1832
481
    --eos;
1833
481
    --len;
1834
481
  }
1835
3.40k
  if (len < strlen("GET / HTTP/1.0"))
1836
254
    return -1;
1837
1838
  /* Parse the request line */
1839
3.15k
  method = strsep(&line, " ");
1840
3.15k
  if (!line)
1841
60
    return -1;
1842
3.09k
  uri = line;
1843
3.09k
  version = strrchr(uri, ' ');
1844
3.09k
  if (!version || uri == version)
1845
47
    return -1;
1846
3.04k
  *version = '\0';
1847
3.04k
  version++;
1848
1849
3.04k
  method_len = (uri - method) - 1;
1850
1851
  /* First line */
1852
3.04k
  switch (method_len) {
1853
248
      case 3:
1854
    /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1855
            
1856
    /* Since both GET and PUT share the same character 'T' at the end,
1857
     * if the string doesn't have 'T', we can immediately determine this
1858
     * is an invalid HTTP method */
1859
            
1860
248
    if (method[2] != 'T') {
1861
33
        break;
1862
33
    }
1863
            
1864
215
    switch (*method) {
1865
14
        case 'G':
1866
      /* This first byte is 'G', so make sure the next byte is
1867
       * 'E', if it isn't then this isn't a valid method */
1868
                    
1869
14
      if (method[1] == 'E') {
1870
3
          type = EVHTTP_REQ_GET;
1871
3
      }
1872
                    
1873
14
      break;
1874
198
        case 'P':
1875
      /* First byte is P, check second byte for 'U', if not,
1876
       * we know it's an invalid method */
1877
198
      if (method[1] == 'U') {
1878
184
          type = EVHTTP_REQ_PUT;
1879
184
      }
1880
198
      break;
1881
3
        default:
1882
3
      break;
1883
215
    }
1884
215
    break;
1885
835
      case 4:
1886
    /* The method length is 4 bytes, leaving only the methods POST, HEAD, LOCK, COPY and MOVE */
1887
835
    switch (*method) {
1888
253
        case 'P':
1889
253
      if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1890
231
          type = EVHTTP_REQ_POST;
1891
231
      }
1892
253
      break;
1893
35
        case 'H':
1894
35
      if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1895
1
          type = EVHTTP_REQ_HEAD;
1896
1
      }
1897
35
      break;
1898
183
        case 'L':
1899
183
      if (method[3] == 'K' && method[2] == 'C' && method[1] == 'O') {
1900
152
          type = EVHTTP_REQ_LOCK;
1901
152
      }
1902
183
      break;
1903
151
        case 'C':
1904
151
      if (method[3] == 'Y' && method[2] == 'P' && method[1] == 'O') {
1905
133
          type = EVHTTP_REQ_COPY;
1906
133
      }
1907
151
      break;
1908
205
        case 'M':
1909
205
      if (method[3] == 'E' && method[2] == 'V' && method[1] == 'O') {
1910
179
          type = EVHTTP_REQ_MOVE;
1911
179
      }
1912
205
      break;
1913
8
        default:
1914
8
      break;
1915
835
    }
1916
835
    break;
1917
835
      case 5:
1918
    /* Method length is 5 bytes, which can only encompass PATCH, TRACE and MKCOL */
1919
671
    switch (*method) {
1920
308
        case 'P':
1921
308
      if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1922
261
          type = EVHTTP_REQ_PATCH;
1923
261
      }
1924
308
      break;
1925
34
        case 'T':
1926
34
      if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1927
1
          type = EVHTTP_REQ_TRACE;
1928
1
      }
1929
                    
1930
34
      break;
1931
324
        case 'M':
1932
324
      if (method[4] == 'L' && method[3] == 'O' && method[2] == 'C' && method[1] == 'K') {
1933
280
          type = EVHTTP_REQ_MKCOL;
1934
280
      }
1935
324
      break;
1936
5
        default:
1937
5
      break;
1938
671
    }
1939
671
    break;
1940
671
      case 6:
1941
    /* Method length is 6, only valid methods 6 bytes in length is DELETE and UNLOCK */
1942
395
    switch (*method) {
1943
161
        case 'D':
1944
161
      if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' &&
1945
135
        method[2] == 'L' && method[1] == 'E') {
1946
113
          type = EVHTTP_REQ_DELETE;
1947
113
      }
1948
161
      break;
1949
226
        case 'U':
1950
226
      if (method[5] == 'K' && method[4] == 'C' && method[3] == 'O' &&
1951
201
        method[2] == 'L' && method[1] == 'N') {
1952
179
          type = EVHTTP_REQ_UNLOCK;
1953
179
      }
1954
226
      break;
1955
8
        default:
1956
8
      break;
1957
395
    }
1958
395
    break;
1959
395
      case 7:
1960
    /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1961
299
    switch (*method) {
1962
222
        case 'O':
1963
222
      if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1964
195
        method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1965
162
          type = EVHTTP_REQ_OPTIONS;
1966
162
      }
1967
                   
1968
222
            break;
1969
69
        case 'C':
1970
69
      if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1971
37
        method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1972
11
          type = EVHTTP_REQ_CONNECT;
1973
11
      }
1974
                    
1975
69
      break;
1976
8
        default:
1977
8
      break;
1978
299
    }
1979
299
    break;
1980
299
      case 8:
1981
    /* Method length is 8, only valid method 8 bytes in length is PROPFIND */
1982
1983
    /* If the first byte isn't 'P' then it's invalid */
1984
251
    if (*method != 'P') {
1985
42
        break;
1986
42
    }
1987
1988
209
    if (method[7] == 'D' && method[6] == 'N' && method[5] == 'I' &&
1989
175
      method[4] == 'F' && method[3] == 'P' && method[2] == 'O' &&
1990
142
      method[1] == 'R') {
1991
132
        type = EVHTTP_REQ_PROPFIND;
1992
132
    }
1993
1994
209
    break;
1995
205
      case 9:
1996
    /* Method length is 9, only valid method 9 bytes in length is PROPPATCH */
1997
1998
    /* If the first byte isn't 'P' then it's invalid */
1999
205
    if (*method != 'P') {
2000
8
        break;
2001
8
    }
2002
2003
197
    if (method[8] == 'H' && method[7] == 'C' && method[6] == 'T' &&
2004
172
      method[5] == 'A' && method[4] == 'P' && method[3] == 'P' &&
2005
147
      method[2] == 'O' && method[1] == 'R') {
2006
122
        type = EVHTTP_REQ_PROPPATCH;
2007
122
    }
2008
2009
197
    break;
2010
3.04k
  } /* switch */
2011
2012
3.04k
  if (!type) {
2013
    /* check extended methods, we only care about the
2014
     * type set by the cmp function if the cmp function
2015
     * returns a 0 value.
2016
     */
2017
899
    struct evhttp_ext_method ext_method;
2018
2019
899
    ext_method.method = method;
2020
899
    ext_method.type = 0;
2021
899
    ext_method.flags = 0;
2022
2023
899
    if (req->evcon->ext_method_cmp &&
2024
0
        req->evcon->ext_method_cmp(&ext_method) == 0) {
2025
      /* make sure the other fields in ext_method are
2026
       * not changed by the callback.
2027
       */
2028
0
      if (strcmp(ext_method.method, method) != 0) {
2029
0
        event_warn("%s: modifying the 'method' field of ext_method_cmp's "
2030
0
          "parameter is not allowed", __func__);
2031
0
        return -1;
2032
0
      }
2033
0
      if (ext_method.flags != 0) {
2034
0
        event_warn("%s: modifying the 'flags' field of ext_method_cmp's "
2035
0
          "parameter is not allowed", __func__);
2036
0
        return -1;
2037
0
      }
2038
0
      type = ext_method.type;
2039
0
    }
2040
899
  }
2041
2042
3.04k
  if (!type) {
2043
899
    event_debug(("%s: bad method %s on request %p from %s",
2044
899
                __func__, method, (void *)req, req->remote_host));
2045
    /* No error yet; we'll give a better error later when
2046
     * we see that req->type is unsupported. */
2047
899
  }
2048
2049
3.04k
  req->type = type;
2050
2051
3.04k
  if (evhttp_parse_http_version(version, req) < 0)
2052
751
    return -1;
2053
2054
2.29k
  if ((req->uri = mm_strdup(uri)) == NULL) {
2055
0
    event_debug(("%s: mm_strdup", __func__));
2056
0
    return -1;
2057
0
  }
2058
2059
2.29k
  if (type == EVHTTP_REQ_CONNECT) {
2060
9
    if ((req->uri_elems = evhttp_uri_parse_authority(req->uri, 0)) == NULL) {
2061
7
      return -1;
2062
7
    }
2063
2.28k
  } else {
2064
2.28k
    if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
2065
2.28k
          EVHTTP_URI_NONCONFORMANT)) == NULL) {
2066
42
      return -1;
2067
42
    }
2068
2.28k
  }
2069
2070
2.24k
  return 0;
2071
2.29k
}
2072
2073
const char *
2074
evhttp_find_header(const struct evkeyvalq *headers, const char *key)
2075
8.55k
{
2076
8.55k
  struct evkeyval *header;
2077
2078
19.5k
  TAILQ_FOREACH(header, headers, next) {
2079
19.5k
    if (evutil_ascii_strcasecmp(header->key, key) == 0)
2080
5.16k
      return (header->value);
2081
19.5k
  }
2082
2083
3.39k
  return (NULL);
2084
8.55k
}
2085
2086
/* Like evhttp_find_header, but set *duplicate to 1 if the header appears
2087
 * more than once, and to 0 otherwise.
2088
 */
2089
static const char *
2090
evhttp_find_unique_header(const struct evkeyvalq *headers, const char *key,
2091
    int *duplicate)
2092
0
{
2093
0
  const char *result = NULL;
2094
0
  struct evkeyval *header;
2095
2096
0
  *duplicate = 0;
2097
2098
0
  TAILQ_FOREACH(header, headers, next) {
2099
0
    if (evutil_ascii_strcasecmp(header->key, key) == 0) {
2100
0
      if (result == NULL) {
2101
0
        result = header->value;
2102
0
      } else {
2103
0
        *duplicate = 1;
2104
0
        break;
2105
0
      }
2106
0
    }
2107
0
  }
2108
2109
0
  return (result);
2110
0
}
2111
2112
void
2113
evhttp_clear_headers(struct evkeyvalq *headers)
2114
26.8k
{
2115
26.8k
  struct evkeyval *header;
2116
2117
26.8k
  for (header = TAILQ_FIRST(headers);
2118
44.6k
      header != NULL;
2119
26.8k
      header = TAILQ_FIRST(headers)) {
2120
17.8k
    TAILQ_REMOVE(headers, header, next);
2121
17.8k
    mm_free(header->key);
2122
17.8k
    mm_free(header->value);
2123
17.8k
    mm_free(header);
2124
17.8k
  }
2125
26.8k
}
2126
2127
/*
2128
 * Returns 0,  if the header was successfully removed.
2129
 * Returns -1, if the header could not be found.
2130
 */
2131
2132
int
2133
evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2134
9.82k
{
2135
9.82k
  struct evkeyval *header;
2136
2137
291k
  TAILQ_FOREACH(header, headers, next) {
2138
291k
    if (evutil_ascii_strcasecmp(header->key, key) == 0)
2139
7.77k
      break;
2140
291k
  }
2141
2142
9.82k
  if (header == NULL)
2143
2.04k
    return (-1);
2144
2145
  /* Free and remove the header that we found */
2146
7.77k
  TAILQ_REMOVE(headers, header, next);
2147
7.77k
  mm_free(header->key);
2148
7.77k
  mm_free(header->value);
2149
7.77k
  mm_free(header);
2150
2151
7.77k
  return (0);
2152
9.82k
}
2153
2154
static int
2155
evhttp_header_is_valid_value(const char *value)
2156
11.3k
{
2157
11.3k
  const char *p = value;
2158
2159
11.3k
  if (strpbrk(p, "\r\n") != NULL) {
2160
    /* Reject any header containing CR or LF. */
2161
158
    return (0);
2162
158
  }
2163
2164
11.1k
  return (1);
2165
11.3k
}
2166
2167
int
2168
evhttp_add_header(struct evkeyvalq *headers,
2169
    const char *key, const char *value)
2170
11.8k
{
2171
11.8k
  event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2172
2173
  /* RFC 9110 defines field-names as case-sensitive non-empty strings made of the following characters */
2174
  // field-name     = 1*tchar
2175
  // tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" / 0-9 / A-Z / a-z
2176
  /* For simplicity, we'll reject field-names containing the documented most dangerous characters */
2177
  // "Field values containing CR, LF, or NUL characters are invalid and dangerous, due to the varying ways that implementations might parse and interpret those characters; a recipient of CR, LF, or NUL within a field value MUST either reject the message or replace each of those characters with SP before further processing or forwarding of that message."
2178
11.8k
  if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL || key[0] == '\0') {
2179
    /* drop illegal headers */
2180
586
    event_debug(("%s: dropping illegal header key\n", __func__));
2181
586
    return (-1);
2182
586
  }
2183
2184
11.3k
  if (!evhttp_header_is_valid_value(value)) {
2185
158
    event_debug(("%s: dropping illegal header value\n", __func__));
2186
158
    return (-1);
2187
158
  }
2188
2189
11.1k
  return (evhttp_add_header_internal(headers, key, value));
2190
11.3k
}
2191
2192
static int
2193
evhttp_add_header_internal(struct evkeyvalq *headers,
2194
    const char *key, const char *value)
2195
25.5k
{
2196
25.5k
  struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2197
25.5k
  if (header == NULL) {
2198
0
    event_warn("%s: calloc", __func__);
2199
0
    return (-1);
2200
0
  }
2201
25.5k
  if ((header->key = mm_strdup(key)) == NULL) {
2202
0
    mm_free(header);
2203
0
    event_warn("%s: strdup", __func__);
2204
0
    return (-1);
2205
0
  }
2206
25.5k
  if ((header->value = mm_strdup(value)) == NULL) {
2207
0
    mm_free(header->key);
2208
0
    mm_free(header);
2209
0
    event_warn("%s: strdup", __func__);
2210
0
    return (-1);
2211
0
  }
2212
2213
25.5k
  TAILQ_INSERT_TAIL(headers, header, next);
2214
2215
25.5k
  return (0);
2216
25.5k
}
2217
2218
/*
2219
 * Parses header lines from a request or a response into the specified
2220
 * request object given an event buffer.
2221
 *
2222
 * Returns
2223
 *   DATA_CORRUPTED      on error
2224
 *   MORE_DATA_EXPECTED  when we need to read more headers
2225
 *   ALL_DATA_READ       when all headers have been read.
2226
 */
2227
2228
enum message_read_status
2229
evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2230
8.85k
{
2231
8.85k
  char *line;
2232
8.85k
  enum message_read_status status = ALL_DATA_READ;
2233
2234
8.85k
  size_t len;
2235
  /* XXX try */
2236
8.85k
  line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2237
8.85k
  if (line == NULL) {
2238
2.12k
    if (req->evcon != NULL &&
2239
2.12k
        evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2240
395
      return (DATA_TOO_LONG);
2241
1.73k
    else
2242
1.73k
      return (MORE_DATA_EXPECTED);
2243
2.12k
  }
2244
2245
6.72k
  if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2246
205
    mm_free(line);
2247
205
    return (DATA_TOO_LONG);
2248
205
  }
2249
2250
6.52k
  req->headers_size = len;
2251
2252
6.52k
  switch (req->kind) {
2253
3.40k
  case EVHTTP_REQUEST:
2254
3.40k
    if (evhttp_parse_request_line(req, line, len) == -1)
2255
1.16k
      status = DATA_CORRUPTED;
2256
3.40k
    break;
2257
3.11k
  case EVHTTP_RESPONSE:
2258
3.11k
    if (evhttp_parse_response_line(req, line) == -1)
2259
771
      status = DATA_CORRUPTED;
2260
3.11k
    break;
2261
0
  default:
2262
0
    status = DATA_CORRUPTED;
2263
6.52k
  }
2264
2265
6.52k
  mm_free(line);
2266
6.52k
  return (status);
2267
6.52k
}
2268
2269
static int
2270
evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2271
4.46k
{
2272
4.46k
  struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2273
4.46k
  char *newval;
2274
4.46k
  size_t old_len, line_len;
2275
2276
4.46k
  if (header == NULL)
2277
78
    return (-1);
2278
2279
4.38k
  old_len = strlen(header->value);
2280
2281
  /* Strip space from start and end of line. */
2282
10.0k
  while (*line == ' ' || *line == '\t')
2283
5.69k
    ++line;
2284
4.38k
  evutil_rtrim_lws_(line);
2285
2286
4.38k
  line_len = strlen(line);
2287
2288
4.38k
  newval = mm_realloc(header->value, old_len + line_len + 2);
2289
4.38k
  if (newval == NULL)
2290
0
    return (-1);
2291
2292
4.38k
  newval[old_len] = ' ';
2293
4.38k
  memcpy(newval + old_len + 1, line, line_len + 1);
2294
4.38k
  header->value = newval;
2295
2296
4.38k
  return (0);
2297
4.38k
}
2298
2299
/* As `evhttp_parse_headers_`, but put any headers we find into `headers`. */
2300
static enum message_read_status
2301
evhttp_parse_headers_impl_(
2302
  struct evhttp_request *req,
2303
  struct evbuffer *buffer,
2304
  struct evkeyvalq *headers)
2305
4.59k
{
2306
4.59k
  enum message_read_status errcode = DATA_CORRUPTED;
2307
4.59k
  char *line;
2308
4.59k
  enum message_read_status status = MORE_DATA_EXPECTED;
2309
2310
4.59k
  size_t len;
2311
11.8k
  while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2312
11.8k
         != NULL) {
2313
9.25k
    char *skey, *svalue;
2314
2315
9.25k
    req->headers_size += len;
2316
2317
9.25k
    if (req->evcon != NULL &&
2318
9.25k
        req->headers_size > req->evcon->max_headers_size) {
2319
247
      errcode = DATA_TOO_LONG;
2320
247
      goto error;
2321
247
    }
2322
2323
9.01k
    if (*line == '\0') { /* Last header - Done */
2324
230
      status = ALL_DATA_READ;
2325
230
      mm_free(line);
2326
230
      break;
2327
230
    }
2328
2329
    /* Check if this is a continuation line */
2330
8.78k
    if (*line == ' ' || *line == '\t') {
2331
4.46k
      if (evhttp_append_to_last_header(headers, line) == -1)
2332
78
        goto error;
2333
4.38k
      mm_free(line);
2334
4.38k
      continue;
2335
4.46k
    }
2336
2337
    /* Processing of header lines */
2338
4.31k
    svalue = line;
2339
4.31k
    skey = strsep(&svalue, ":");
2340
4.31k
    if (svalue == NULL)
2341
1.25k
      goto error;
2342
2343
3.06k
    svalue += strspn(svalue, " ");
2344
3.06k
    evutil_rtrim_lws_(svalue);
2345
2346
3.06k
    if (evhttp_add_header(headers, skey, svalue) == -1)
2347
146
      goto error;
2348
2349
2.92k
    mm_free(line);
2350
2.92k
  }
2351
2352
2.86k
  if (status == MORE_DATA_EXPECTED) {
2353
2.63k
    if (req->evcon != NULL &&
2354
2.63k
    req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2355
446
      return (DATA_TOO_LONG);
2356
2.63k
  }
2357
2358
2.42k
  return (status);
2359
2360
1.72k
 error:
2361
1.72k
  mm_free(line);
2362
1.72k
  return (errcode);
2363
2.86k
}
2364
2365
/* Return true if 'ch' is a single linear WS character (per the HTTP spec).
2366
 * We reject CR and LF elsewhere. */
2367
#define IS_LWS(ch) \
2368
0
  (((ch) == ' ' ) || ((ch) == '\t'))
2369
2370
/* Returns true when the string beginning at `value` and ending at `eos`
2371
 * (non-inclusive) is a `transfer-coding`  "chunked".  Case insensitive.
2372
 */
2373
int
2374
evhttp_str_is_chunked_(const char *value, const char *eos)
2375
0
{
2376
  /* the end of the encoding. */
2377
0
  const char *end;
2378
2379
0
  if (eos == NULL) {
2380
0
    eos = value + strlen(value);
2381
0
  }
2382
2383
0
  while (value < eos && IS_LWS(*value)) {
2384
0
    ++value;
2385
0
  }
2386
0
  end = value;
2387
  /* A transfer-coding can end with OWS ; OWS to indicate a
2388
   * transfer-parameter.  (See RFC 9110)
2389
   */
2390
0
  while (end < eos && !IS_LWS(*end) && *end != ';') {
2391
0
    ++end;
2392
0
  }
2393
2394
0
  return (end - value) == strlen("chunked")
2395
0
      && evutil_ascii_strncasecmp(value, "chunked", strlen("chunked")) == 0;
2396
0
}
2397
2398
/* Check a single Transfer-Encoding header value.
2399
 *
2400
 * Returns an evhttp_transfer_encoding_header_status value depending
2401
 * on its contents.
2402
 */
2403
enum evhttp_transfer_encoding_header_status
2404
evhttp_check_transfer_encoding_(const char *value)
2405
0
{
2406
0
  const char *comma;
2407
2408
0
  while ((comma = strchr(value, ',')) != NULL) {
2409
0
    if (evhttp_str_is_chunked_(value, comma)) {
2410
      /* If we find that an encoding is chunked
2411
       * and it is followed by a comma, it is not the final
2412
       * encoding
2413
       */
2414
0
      return TE_INVALID;
2415
0
    }
2416
0
    value = comma + 1;
2417
0
  }
2418
2419
0
  if (evhttp_str_is_chunked_(value, NULL)) {
2420
0
    return TE_ENDS_IN_CHUNKED;
2421
0
  } else {
2422
0
    return TE_NO_CHUNKED;
2423
0
  }
2424
0
}
2425
2426
2427
/* Return 0 if the Transfer-Encoding and Content-Length heeaders appear to be consistent,
2428
 * and -1 otherwise.
2429
 *
2430
 * Sets "req->chunked" if appropriate.
2431
 *
2432
 * Used to prevent request smuggling.
2433
 */
2434
static int
2435
evhttp_validate_len_and_encoding_(struct evhttp_request *req)
2436
0
{
2437
0
  struct evkeyvalq *headers = req->input_headers;
2438
0
  struct evkeyval *h = NULL;
2439
0
  int is_chunked = 0;
2440
0
  int dup_cl = 0;
2441
2442
0
  if (evhttp_find_header(headers, "Transfer-Encoding") != NULL &&
2443
0
      evhttp_find_unique_header(headers, "Content-Length", &dup_cl) != NULL) {
2444
    /* Both TE and CL were present: Not allowed. */
2445
0
    return -1;
2446
0
  }
2447
0
  if (dup_cl) {
2448
    /* CL was present twice: Not allowed.
2449
     * (Technically we can permit this if the values are the same,
2450
     * but we don't.) */
2451
0
    return -1;
2452
0
  }
2453
2454
  /* Now walk through the Transfer-Encoding headers. */
2455
0
  TAILQ_FOREACH(h, headers, next) {
2456
0
    if (evutil_ascii_strcasecmp(h->key, "Transfer-Encoding") == 0) {
2457
0
      if (is_chunked) {
2458
        /* We already encountered a chunked
2459
           encoding; no further encodings are allowed */
2460
0
        return -1;
2461
0
      }
2462
2463
0
      switch (evhttp_check_transfer_encoding_(h->value))
2464
0
      {
2465
0
      case TE_INVALID:
2466
        /* We found "chunked" somewhere not at the end. */
2467
0
        return -1;
2468
0
      case TE_ENDS_IN_CHUNKED:
2469
        /* We found chunked at the end. */
2470
0
        is_chunked = 1;
2471
0
        break;
2472
0
      case TE_NO_CHUNKED:
2473
        /* "chunked" didn't appear; this is fine. */
2474
0
        break;
2475
0
      }
2476
0
    }
2477
0
  }
2478
2479
0
  req->chunked = is_chunked;
2480
2481
0
  return 0;
2482
0
}
2483
2484
2485
enum message_read_status
2486
evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer *buffer)
2487
4.59k
{
2488
4.59k
  return evhttp_parse_headers_impl_(req, buffer, req->input_headers);
2489
4.59k
}
2490
2491
static int
2492
evhttp_get_body_length(struct evhttp_request *req)
2493
0
{
2494
0
  struct evkeyvalq *headers = req->input_headers;
2495
0
  const char *content_length;
2496
0
  const char *connection;
2497
2498
0
  content_length = evhttp_find_header(headers, "Content-Length");
2499
0
  connection = evhttp_find_header(headers, "Connection");
2500
2501
0
  if (content_length == NULL && connection == NULL)
2502
0
    req->ntoread = -1;
2503
0
  else if (content_length == NULL &&
2504
0
      evutil_ascii_strcasecmp(connection, "Close") != 0) {
2505
0
    req->ntoread = 0;
2506
0
  } else if (content_length == NULL) {
2507
0
    req->ntoread = -1;
2508
0
  } else {
2509
0
    char *endp;
2510
0
    ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2511
0
    if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2512
0
      event_debug(("%s: illegal content length: %s",
2513
0
        __func__, content_length));
2514
0
      return (-1);
2515
0
    }
2516
0
    req->ntoread = ntoread;
2517
0
  }
2518
2519
0
  event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2520
0
    __func__, EV_I64_ARG(req->ntoread),
2521
0
    EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2522
2523
0
  return (0);
2524
0
}
2525
2526
static int
2527
evhttp_method_may_have_body_(struct evhttp_connection *evcon, enum evhttp_cmd_type type)
2528
0
{
2529
  /* NOTE: some version of GCC reports a warning that flags may be uninitialized, hence assignment */
2530
0
  ev_uint16_t flags = 0;
2531
0
  evhttp_method_(evcon, type, &flags);
2532
0
  return (flags & EVHTTP_METHOD_HAS_BODY) ? 1 : 0;
2533
0
}
2534
2535
static void
2536
evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2537
0
{
2538
  /* If this is a request without a body, then we are done */
2539
0
  if (req->kind == EVHTTP_REQUEST &&
2540
0
      !evhttp_method_may_have_body_(evcon, req->type)) {
2541
0
    evhttp_connection_done(evcon);
2542
0
    return;
2543
0
  }
2544
0
  evcon->state = EVCON_READING_BODY;
2545
2546
0
  if (req->chunked) {
2547
0
    req->ntoread = -1;
2548
0
  } else {
2549
0
    if (evhttp_get_body_length(req) == -1) {
2550
0
      evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2551
0
      return;
2552
0
    }
2553
0
    if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2554
      /* An incoming request with no content-length and no
2555
       * transfer-encoding has no body. */
2556
0
      evhttp_connection_done(evcon);
2557
0
      return;
2558
0
    }
2559
0
  }
2560
2561
  /* Should we send a 100 Continue status line? */
2562
0
  switch (evhttp_have_expect(req, 1)) {
2563
0
    case CONTINUE:
2564
        /* XXX It would be nice to do some sanity
2565
           checking here. Does the resource exist?
2566
           Should the resource accept post requests? If
2567
           no, we should respond with an error. For
2568
           now, just optimistically tell the client to
2569
           send their message body. */
2570
0
        if (req->ntoread > 0) {
2571
          /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */ 
2572
0
          if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2573
0
            (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2574
0
            evhttp_lingering_fail(evcon, req);
2575
0
            return;
2576
0
          }
2577
0
        }
2578
0
        if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2579
0
          evhttp_send_continue(evcon, req);
2580
0
      break;
2581
0
    case OTHER:
2582
0
      evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2583
0
      return;
2584
0
    case NO: break;
2585
0
  }
2586
2587
0
  evhttp_read_body(evcon, req);
2588
  /* note the request may have been freed in evhttp_read_body */
2589
0
}
2590
2591
static void
2592
evhttp_read_firstline(struct evhttp_connection *evcon,
2593
          struct evhttp_request *req)
2594
0
{
2595
0
  enum message_read_status res;
2596
2597
0
  res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2598
0
  if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2599
    /* Error while reading, terminate */
2600
0
    event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2601
0
      __func__, EV_SOCK_ARG(bufferevent_getfd(evcon->bufev))));
2602
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2603
0
    return;
2604
0
  } else if (res == MORE_DATA_EXPECTED) {
2605
    /* Need more header lines */
2606
0
    return;
2607
0
  }
2608
2609
0
  evcon->state = EVCON_READING_HEADERS;
2610
0
  evhttp_read_header(evcon, req);
2611
0
}
2612
2613
static void
2614
evhttp_read_header(struct evhttp_connection *evcon,
2615
       struct evhttp_request *req)
2616
0
{
2617
0
  enum message_read_status res;
2618
0
  evutil_socket_t fd = bufferevent_getfd(evcon->bufev);
2619
2620
0
  res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2621
0
  if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2622
    /* Error while reading, terminate */
2623
0
    event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2624
0
      __func__, EV_SOCK_ARG(fd)));
2625
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2626
0
    return;
2627
0
  } else if (res == MORE_DATA_EXPECTED) {
2628
    /* Need more header lines */
2629
0
    return;
2630
0
  }
2631
2632
0
  if (evhttp_validate_len_and_encoding_(req) < 0) {
2633
0
    event_debug(("%s: bad combination of headers on "EV_SOCK_FMT"\n",
2634
0
      __func__, EV_SOCK_ARG(fd)));
2635
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2636
0
    return;
2637
0
  }
2638
2639
  /* Callback can shut down connection with negative return value */
2640
0
  if (req->header_cb != NULL) {
2641
0
    if ((*req->header_cb)(req, req->cb_arg) < 0) {
2642
0
      evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2643
0
      return;
2644
0
    }
2645
0
  }
2646
2647
  /* Done reading headers, do the real work */
2648
0
  switch (req->kind) {
2649
0
  case EVHTTP_REQUEST:
2650
0
    event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2651
0
      __func__, EV_SOCK_ARG(fd)));
2652
0
    evhttp_get_body(evcon, req);
2653
    /* note the request may have been freed in evhttp_get_body */
2654
0
    break;
2655
2656
0
  case EVHTTP_RESPONSE:
2657
    /* Start over if we got a 100 Continue response. */
2658
0
    if (req->response_code == 100) {
2659
0
      struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2660
0
      evbuffer_add_buffer(output, req->output_buffer);
2661
0
      evhttp_start_write_(evcon);
2662
0
      return;
2663
0
    }
2664
0
    if (!evhttp_response_needs_body(req)) {
2665
0
      event_debug(("%s: skipping body for code %d\n",
2666
0
          __func__, req->response_code));
2667
0
      evhttp_connection_done(evcon);
2668
0
    } else {
2669
0
      event_debug(("%s: start of read body for %s on "
2670
0
        EV_SOCK_FMT"\n",
2671
0
        __func__, req->remote_host, EV_SOCK_ARG(fd)));
2672
0
      evhttp_get_body(evcon, req);
2673
      /* note the request may have been freed in
2674
       * evhttp_get_body */
2675
0
    }
2676
0
    break;
2677
2678
0
  default:
2679
0
    event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2680
0
        EV_SOCK_ARG(fd));
2681
0
    evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2682
0
    break;
2683
0
  }
2684
  /* request may have been freed above */
2685
0
}
2686
2687
/*
2688
 * Creates a TCP connection to the specified port and executes a callback
2689
 * when finished.  Failure or success is indicate by the passed connection
2690
 * object.
2691
 *
2692
 * Although this interface accepts a hostname, it is intended to take
2693
 * only numeric hostnames so that non-blocking DNS resolution can
2694
 * happen elsewhere.
2695
 */
2696
2697
struct evhttp_connection *
2698
evhttp_connection_new(const char *address, ev_uint16_t port)
2699
0
{
2700
0
  return (evhttp_connection_base_new(NULL, NULL, address, port));
2701
0
}
2702
2703
/* We were passed a bev with file descriptor set.
2704
 * Assume that this is an already-open connection that we
2705
 * can start sending requests on.
2706
 */
2707
static int
2708
evhttp_connection_set_existing_(struct evhttp_connection *evcon, struct bufferevent* bev)
2709
0
{
2710
0
  evcon->state = EVCON_IDLE;
2711
0
  evcon->flags |= EVHTTP_CON_OUTGOING;
2712
0
  return 0;
2713
0
}
2714
2715
static struct evhttp_connection *
2716
evhttp_connection_new_(struct event_base *base, struct bufferevent* bev)
2717
1.01k
{
2718
1.01k
  struct evhttp_connection *evcon;
2719
2720
1.01k
  if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2721
0
    event_warn("%s: calloc failed", __func__);
2722
0
    goto error;
2723
0
  }
2724
2725
1.01k
  evcon->max_headers_size = EV_SIZE_MAX;
2726
1.01k
  evcon->max_body_size = EV_SIZE_MAX;
2727
2728
1.01k
  evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2729
1.01k
  evcon->timeout_read.tv_sec    = HTTP_READ_TIMEOUT;
2730
1.01k
  evcon->timeout_write.tv_sec   = HTTP_WRITE_TIMEOUT;
2731
1.01k
  evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2732
2733
1.01k
  evcon->retry_cnt = evcon->retry_max = 0;
2734
2735
1.01k
  if (bev == NULL) {
2736
0
    if (!(bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE))) {
2737
0
      event_warn("%s: bufferevent_socket_new failed", __func__);
2738
0
      goto error;
2739
0
    }
2740
0
  }
2741
2742
1.01k
  bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2743
1.01k
  evcon->bufev = bev;
2744
2745
1.01k
  evcon->state = EVCON_DISCONNECTED;
2746
1.01k
  TAILQ_INIT(&evcon->requests);
2747
2748
1.01k
  if (base != NULL) {
2749
1.01k
    evcon->base = base;
2750
1.01k
    if (bufferevent_get_base(bev) != base)
2751
0
      bufferevent_base_set(base, evcon->bufev);
2752
1.01k
  }
2753
2754
1.01k
  event_deferred_cb_init_(
2755
1.01k
      &evcon->read_more_deferred_cb,
2756
1.01k
      bufferevent_get_priority(bev),
2757
1.01k
      evhttp_deferred_read_cb, evcon);
2758
2759
1.01k
  evcon->ai_family = AF_UNSPEC;
2760
2761
1.01k
  return (evcon);
2762
2763
0
 error:
2764
0
  if (evcon != NULL)
2765
0
    evhttp_connection_free(evcon);
2766
0
  return (NULL);
2767
1.01k
}
2768
2769
struct evhttp_connection *
2770
evhttp_connection_base_bufferevent_reuse_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev)
2771
0
{
2772
0
  struct evhttp_connection *evcon = NULL;
2773
0
  if (bev == NULL)
2774
0
    goto error;
2775
2776
0
  evcon = evhttp_connection_new_(base, bev);
2777
2778
0
  if (evcon == NULL)
2779
0
    goto error;
2780
2781
0
  if (evhttp_connection_set_existing_(evcon, bev))
2782
0
    goto error;
2783
2784
0
  evcon->dns_base = dnsbase;
2785
0
  evcon->address = NULL;
2786
0
  evcon->port = 0;
2787
0
#ifndef _WIN32
2788
0
  evcon->unixsocket = NULL;
2789
0
#endif
2790
2791
0
  return (evcon);
2792
0
 error:
2793
0
  if (evcon != NULL)
2794
0
    evhttp_connection_free(evcon);
2795
0
  return (NULL);
2796
0
}
2797
2798
#ifndef _WIN32
2799
struct evhttp_connection *
2800
evhttp_connection_base_bufferevent_unix_new(struct event_base *base, struct bufferevent* bev, const char *unixsocket)
2801
0
{
2802
0
  struct evhttp_connection *evcon;
2803
2804
0
  if (strlen(unixsocket) >= member_size(struct sockaddr_un, sun_path)) {
2805
0
    event_warn("%s: unix socket too long", __func__);
2806
0
    return NULL;
2807
0
  }
2808
2809
0
  evcon = evhttp_connection_new_(base, bev);
2810
0
  if (evcon == NULL)
2811
0
    goto error;
2812
2813
0
  if ((evcon->unixsocket = mm_strdup(unixsocket)) == NULL) {
2814
0
    event_warn("%s: strdup failed", __func__);
2815
0
    goto error;
2816
0
  }
2817
2818
0
  evcon->ai_family = AF_UNIX;
2819
2820
0
  return (evcon);
2821
0
 error:
2822
0
  if (evcon != NULL)
2823
0
    evhttp_connection_free(evcon);
2824
0
  return (NULL);
2825
0
}
2826
#endif
2827
2828
struct evhttp_connection *
2829
evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2830
    const char *address, unsigned short port)
2831
1.01k
{
2832
1.01k
  struct evhttp_connection *evcon;
2833
2834
1.01k
  event_debug(("Attempting connection to %s:%d\n", address, port));
2835
2836
1.01k
  evcon = evhttp_connection_new_(base, bev);
2837
1.01k
  if (evcon == NULL)
2838
0
    goto error;
2839
2840
1.01k
  if ((evcon->address = mm_strdup(address)) == NULL) {
2841
0
    event_warn("%s: strdup failed", __func__);
2842
0
    goto error;
2843
0
  }
2844
1.01k
  evcon->port = port;
2845
1.01k
  evcon->dns_base = dnsbase;
2846
2847
1.01k
  return (evcon);
2848
0
error:
2849
0
  if (evcon != NULL)
2850
0
    evhttp_connection_free(evcon);
2851
0
  return (NULL);
2852
1.01k
}
2853
2854
2855
struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2856
0
{
2857
0
  return evcon->bufev;
2858
0
}
2859
2860
struct evhttp *
2861
evhttp_connection_get_server(struct evhttp_connection *evcon)
2862
0
{
2863
0
  return evcon->http_server;
2864
0
}
2865
2866
struct evhttp_connection *
2867
evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2868
    const char *address, ev_uint16_t port)
2869
0
{
2870
0
  return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2871
0
}
2872
2873
void evhttp_connection_set_family(struct evhttp_connection *evcon,
2874
  int family)
2875
0
{
2876
0
  evcon->ai_family = family;
2877
0
}
2878
2879
int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2880
  int flags)
2881
0
{
2882
0
  int avail_flags = 0;
2883
0
  avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2884
0
  avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2885
2886
0
  if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2887
0
    return 1;
2888
0
  evcon->flags &= ~avail_flags;
2889
2890
0
  evcon->flags |= flags;
2891
2892
0
  return 0;
2893
0
}
2894
2895
void
2896
evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon,
2897
  evhttp_ext_method_cb cmp)
2898
0
{
2899
0
  evcon->ext_method_cmp = cmp;
2900
0
}
2901
2902
void
2903
evhttp_connection_set_base(struct evhttp_connection *evcon,
2904
    struct event_base *base)
2905
0
{
2906
0
  EVUTIL_ASSERT(evcon->base == NULL);
2907
0
  EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2908
0
  evcon->base = base;
2909
0
  bufferevent_base_set(base, evcon->bufev);
2910
0
}
2911
2912
void
2913
evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2914
    int timeout)
2915
0
{
2916
0
  if (timeout != -1) {
2917
0
    evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2918
0
  } else {
2919
0
    evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2920
0
  }
2921
0
  evhttp_set_timeout_(&evcon->timeout_read,  timeout, HTTP_READ_TIMEOUT);
2922
0
  evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2923
0
  bufferevent_set_timeouts(evcon->bufev,
2924
0
      &evcon->timeout_read, &evcon->timeout_write);
2925
0
}
2926
void
2927
evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2928
    const struct timeval* tv)
2929
0
{
2930
0
  if (tv) {
2931
0
    evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2932
0
  } else {
2933
0
    evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2934
0
  }
2935
0
  evhttp_set_timeout_tv_(&evcon->timeout_read,  tv, HTTP_READ_TIMEOUT);
2936
0
  evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2937
0
  bufferevent_set_timeouts(evcon->bufev,
2938
0
      &evcon->timeout_read, &evcon->timeout_write);
2939
0
}
2940
void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2941
    const struct timeval *tv)
2942
0
{
2943
0
  evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2944
0
  evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2945
0
  if (evcon->state == EVCON_CONNECTING)
2946
0
    bufferevent_set_timeouts(evcon->bufev,
2947
0
        &evcon->timeout_connect, &evcon->timeout_connect);
2948
0
}
2949
void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2950
    const struct timeval *tv)
2951
0
{
2952
0
  evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2953
0
  evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2954
0
  if (evcon->state != EVCON_CONNECTING)
2955
0
    bufferevent_set_timeouts(evcon->bufev,
2956
0
        &evcon->timeout_read, &evcon->timeout_write);
2957
0
}
2958
void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2959
    const struct timeval *tv)
2960
0
{
2961
0
  evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2962
0
  evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2963
0
  if (evcon->state != EVCON_CONNECTING)
2964
0
    bufferevent_set_timeouts(evcon->bufev,
2965
0
        &evcon->timeout_read, &evcon->timeout_write);
2966
0
}
2967
2968
void
2969
evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2970
    const struct timeval *tv)
2971
0
{
2972
0
  if (tv) {
2973
0
    evcon->initial_retry_timeout = *tv;
2974
0
  } else {
2975
0
    evutil_timerclear(&evcon->initial_retry_timeout);
2976
0
    evcon->initial_retry_timeout.tv_sec = 2;
2977
0
  }
2978
0
}
2979
2980
void
2981
evhttp_connection_set_retries(struct evhttp_connection *evcon,
2982
    int retry_max)
2983
0
{
2984
0
  evcon->retry_max = retry_max;
2985
0
}
2986
2987
void
2988
evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2989
    void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2990
0
{
2991
0
  evcon->closecb = cb;
2992
0
  evcon->closecb_arg = cbarg;
2993
0
}
2994
2995
void
2996
evhttp_connection_get_peer(struct evhttp_connection *evcon,
2997
    const char **address, ev_uint16_t *port)
2998
0
{
2999
0
  *address = evcon->address;
3000
0
  *port = evcon->port;
3001
0
}
3002
3003
const struct sockaddr*
3004
evhttp_connection_get_addr(struct evhttp_connection *evcon)
3005
0
{
3006
0
  return bufferevent_socket_get_conn_address_(evcon->bufev);
3007
0
}
3008
3009
int
3010
evhttp_connection_connect_(struct evhttp_connection *evcon)
3011
0
{
3012
0
  int old_state = evcon->state;
3013
0
  const char *address = evcon->address;
3014
0
  const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
3015
0
  int ret;
3016
3017
0
  if (evcon->state == EVCON_CONNECTING)
3018
0
    return (0);
3019
3020
  /* Do not do hard reset, since this will reset the fd, but someone may
3021
   * change some options for it (i.e. setsockopt(), #875)
3022
   *
3023
   * However don't think that this options will be preserved for all
3024
   * connection lifetime, they will be reseted in the following cases:
3025
   * - evhttp_connection_set_local_address()
3026
   * - evhttp_connection_set_local_port()
3027
   * - evhttp_connection_set_retries()
3028
   * */
3029
0
  evhttp_connection_reset_(evcon, 0);
3030
3031
0
  EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
3032
0
  evcon->flags |= EVHTTP_CON_OUTGOING;
3033
3034
0
  if (evcon->bind_address || evcon->bind_port) {
3035
0
    int fd = bind_socket(evcon->bind_address, evcon->bind_port,
3036
0
      0 /*reuse*/);
3037
0
    if (fd == -1) {
3038
0
      event_debug(("%s: failed to bind to \"%s\"",
3039
0
        __func__, evcon->bind_address));
3040
0
      return (-1);
3041
0
    }
3042
3043
0
    if (bufferevent_replacefd(evcon->bufev, fd))
3044
0
      return (-1);
3045
0
  }
3046
3047
  /* Set up a callback for successful connection setup */
3048
0
  bufferevent_setcb(evcon->bufev,
3049
0
      NULL /* evhttp_read_cb */,
3050
0
      NULL /* evhttp_write_cb */,
3051
0
      evhttp_connection_cb,
3052
0
      evcon);
3053
0
  bufferevent_set_timeouts(evcon->bufev,
3054
0
      &evcon->timeout_connect, &evcon->timeout_connect);
3055
  /* make sure that we get a write callback */
3056
0
  if (bufferevent_enable(evcon->bufev, EV_WRITE))
3057
0
    return (-1);
3058
3059
0
  evcon->state = EVCON_CONNECTING;
3060
3061
0
  if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
3062
0
    sa &&
3063
0
    (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
3064
0
    int socklen = sizeof(struct sockaddr_in);
3065
0
    if (sa->sa_family == AF_INET6) {
3066
0
      socklen = sizeof(struct sockaddr_in6);
3067
0
    }
3068
0
    ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
3069
0
  }
3070
0
#ifndef _WIN32
3071
0
  else if (evcon->unixsocket) {
3072
0
    struct sockaddr_un sockaddr;
3073
0
    sockaddr.sun_family = AF_UNIX;
3074
0
    strcpy(sockaddr.sun_path, evcon->unixsocket);
3075
0
    ret = bufferevent_socket_connect(evcon->bufev, (const struct sockaddr*)&sockaddr, sizeof(sockaddr));
3076
0
  }
3077
0
#endif
3078
0
  else {
3079
0
    ret = bufferevent_socket_connect_hostname(evcon->bufev,
3080
0
        evcon->dns_base, evcon->ai_family, address, evcon->port);
3081
0
  }
3082
3083
0
  if (ret < 0) {
3084
0
    evcon->state = old_state;
3085
0
    event_sock_warn(bufferevent_getfd(evcon->bufev), "%s: connection to \"%s\" failed",
3086
0
        __func__, evcon->address);
3087
    /* some operating systems return ECONNREFUSED immediately
3088
     * when connecting to a local address.  the cleanup is going
3089
     * to reschedule this function call.
3090
     */
3091
0
    evhttp_connection_cb_cleanup(evcon);
3092
0
    return (0);
3093
0
  }
3094
3095
0
  return (0);
3096
0
}
3097
3098
/*
3099
 * Starts an HTTP request on the provided evhttp_connection object.
3100
 * If the connection object is not connected to the web server already,
3101
 * this will start the connection.
3102
 */
3103
3104
int
3105
evhttp_make_request(struct evhttp_connection *evcon,
3106
    struct evhttp_request *req,
3107
    enum evhttp_cmd_type type, const char *uri)
3108
0
{
3109
  /* We are making a request */
3110
0
  req->kind = EVHTTP_REQUEST;
3111
0
  req->type = type;
3112
0
  if (req->uri != NULL)
3113
0
    mm_free(req->uri);
3114
0
  if ((req->uri = mm_strdup(uri)) == NULL) {
3115
0
    event_warn("%s: strdup", __func__);
3116
0
    evhttp_request_free_auto(req);
3117
0
    return (-1);
3118
0
  }
3119
3120
  /* Set the protocol version if it is not supplied */
3121
0
  if (!req->major && !req->minor) {
3122
0
    req->major = 1;
3123
0
    req->minor = 1;
3124
0
  }
3125
3126
0
  EVUTIL_ASSERT(req->evcon == NULL);
3127
0
  req->evcon = evcon;
3128
0
  EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
3129
3130
0
  TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3131
3132
  /* We do not want to conflict with retry_ev */
3133
0
  if (evcon->retry_cnt)
3134
0
    return (0);
3135
3136
  /* If the connection object is not connected; make it so */
3137
0
  if (!evhttp_connected(evcon)) {
3138
0
    int res = evhttp_connection_connect_(evcon);
3139
    /* evhttp_connection_fail_(), which is called through
3140
     * evhttp_connection_connect_(), assumes that req lies in
3141
     * evcon->requests.  Thus, enqueue the request in advance and
3142
     * remove it in the error case. */
3143
0
    if (res != 0)
3144
0
      TAILQ_REMOVE(&evcon->requests, req, next);
3145
3146
0
    return (res);
3147
0
  }
3148
3149
  /*
3150
   * If it's connected already and we are the first in the queue,
3151
   * then we can dispatch this request immediately.  Otherwise, it
3152
   * will be dispatched once the pending requests are completed.
3153
   */
3154
0
  if (TAILQ_FIRST(&evcon->requests) == req)
3155
0
    evhttp_request_dispatch(evcon);
3156
3157
0
  return (0);
3158
0
}
3159
3160
void
3161
evhttp_cancel_request(struct evhttp_request *req)
3162
0
{
3163
0
  struct evhttp_connection *evcon = req->evcon;
3164
0
  if (evcon != NULL) {
3165
    /* We need to remove it from the connection */
3166
0
    if (TAILQ_FIRST(&evcon->requests) == req) {
3167
      /* it's currently being worked on, so reset
3168
       * the connection.
3169
       */
3170
0
      evhttp_connection_fail_(evcon,
3171
0
          EVREQ_HTTP_REQUEST_CANCEL);
3172
3173
      /* connection fail freed the request */
3174
0
      return;
3175
0
    } else {
3176
      /* otherwise, we can just remove it from the
3177
       * queue
3178
       */
3179
0
      TAILQ_REMOVE(&evcon->requests, req, next);
3180
0
    }
3181
0
  }
3182
3183
0
  evhttp_request_free_auto(req);
3184
0
}
3185
3186
/*
3187
 * Reads data from file descriptor into request structure
3188
 * Request structure needs to be set up correctly.
3189
 */
3190
3191
void
3192
evhttp_start_read_(struct evhttp_connection *evcon)
3193
0
{
3194
0
  bufferevent_disable(evcon->bufev, EV_WRITE);
3195
0
  bufferevent_enable(evcon->bufev, EV_READ);
3196
3197
0
  evcon->state = EVCON_READING_FIRSTLINE;
3198
  /* Reset the bufferevent callbacks */
3199
0
  bufferevent_setcb(evcon->bufev,
3200
0
      evhttp_read_cb,
3201
0
      evhttp_write_cb,
3202
0
      evhttp_error_cb,
3203
0
      evcon);
3204
3205
  /* If there's still data pending, process it next time through the
3206
   * loop.  Don't do it now; that could get recursive. */
3207
0
  if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
3208
0
    event_deferred_cb_schedule_(get_deferred_queue(evcon),
3209
0
        &evcon->read_more_deferred_cb);
3210
0
  }
3211
0
}
3212
3213
void
3214
evhttp_start_write_(struct evhttp_connection *evcon)
3215
0
{
3216
0
  bufferevent_disable(evcon->bufev, EV_WRITE);
3217
0
  bufferevent_enable(evcon->bufev, EV_READ);
3218
3219
0
  evcon->state = EVCON_WRITING;
3220
0
  evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
3221
0
}
3222
3223
static void
3224
evhttp_send_done(struct evhttp_connection *evcon, void *arg)
3225
0
{
3226
0
  int need_close;
3227
0
  struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
3228
0
  TAILQ_REMOVE(&evcon->requests, req, next);
3229
3230
0
  if (req->on_complete_cb != NULL) {
3231
0
    req->on_complete_cb(req, req->on_complete_cb_arg);
3232
0
  }
3233
3234
0
  need_close =
3235
0
      (REQ_VERSION_BEFORE(req, 1, 1) &&
3236
0
      !evhttp_is_connection_keepalive(req->input_headers)) ||
3237
0
      evhttp_is_request_connection_close(req);
3238
3239
0
  EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
3240
0
  evhttp_request_free(req);
3241
3242
0
  if (need_close) {
3243
0
    evhttp_connection_free(evcon);
3244
0
    return;
3245
0
  }
3246
3247
  /* we have a persistent connection; try to accept another request. */
3248
0
  if (evhttp_associate_new_request_with_connection(evcon) == -1) {
3249
0
    evhttp_connection_free(evcon);
3250
0
  }
3251
0
}
3252
3253
/*
3254
 * Returns an error page.
3255
 */
3256
void
3257
evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
3258
0
{
3259
0
#define ERR_FORMAT "<html><head>" \
3260
0
  "<title>%d %s</title>" \
3261
0
  "</head><body>" \
3262
0
  "<h1>%d %s</h1>%s" \
3263
0
  "</body></html>"
3264
3265
0
  struct evbuffer *buf = evbuffer_new();
3266
0
  struct evhttp *http = req->evcon->http_server;
3267
3268
0
  if (buf == NULL) {
3269
    /* if we cannot allocate memory; we just drop the connection */
3270
0
    evhttp_connection_free(req->evcon);
3271
0
    return;
3272
0
  }
3273
3274
0
  evhttp_response_code_(req, error, reason);
3275
3276
  /* Output error using callback for connection's evhttp, if available */
3277
0
  if ((http->errorcb == NULL) ||
3278
0
      ((*http->errorcb)(req, buf, error, reason, http->errorcbarg) < 0))
3279
0
  {
3280
0
    const char *heading = evhttp_response_phrase_internal(error);
3281
3282
0
    evbuffer_drain(buf, evbuffer_get_length(buf));
3283
0
    evbuffer_add_printf(buf, ERR_FORMAT,
3284
0
       error, heading, error, heading,
3285
0
       (reason ? reason : ""));
3286
0
  }
3287
3288
0
  evhttp_send_page_(req, buf);
3289
3290
0
  evbuffer_free(buf);
3291
0
#undef ERR_FORMAT
3292
0
}
3293
static void
3294
evhttp_send_notfound(struct evhttp_request *req, const char *url)
3295
0
{
3296
0
#define REASON_FORMAT "<p>The requested URL %s was not found on this server.</p>"
3297
0
  char   *escaped_url = NULL;
3298
0
  char   *reason = NULL;
3299
0
  size_t reason_len;
3300
3301
0
  url = (url != NULL ? url : req->uri);
3302
0
  if (url != NULL)
3303
0
    escaped_url = evhttp_htmlescape(url);
3304
3305
0
  if (escaped_url != NULL) {
3306
0
    reason_len = strlen(REASON_FORMAT)+strlen(escaped_url)+1;
3307
0
    reason = mm_malloc(reason_len);
3308
0
  }
3309
3310
0
  if ((escaped_url != NULL) && (reason != NULL))
3311
0
    evutil_snprintf(reason, reason_len, REASON_FORMAT, escaped_url);
3312
3313
0
  evhttp_send_error(req, HTTP_NOTFOUND, reason);
3314
3315
0
  if (reason != NULL)
3316
0
    mm_free(reason);
3317
0
  if (escaped_url != NULL)
3318
0
    mm_free(escaped_url);
3319
0
#undef REASON_FORMAT
3320
0
}
3321
3322
3323
/* Requires that headers and response code are already set up */
3324
3325
static inline void
3326
evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
3327
0
{
3328
0
  struct evhttp_connection *evcon = req->evcon;
3329
3330
0
  if (evcon == NULL) {
3331
0
    evhttp_request_free(req);
3332
0
    return;
3333
0
  }
3334
3335
0
  EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
3336
3337
  /* we expect no more calls form the user on this request */
3338
0
  req->userdone = 1;
3339
3340
  /* xxx: not sure if we really should expose the data buffer this way */
3341
0
  if (databuf != NULL)
3342
0
    evbuffer_add_buffer(req->output_buffer, databuf);
3343
3344
  /* Adds headers to the response */
3345
0
  evhttp_make_header(evcon, req);
3346
3347
0
  evhttp_write_buffer(evcon, evhttp_send_done, NULL);
3348
0
}
3349
3350
void
3351
evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
3352
    struct evbuffer *databuf)
3353
0
{
3354
0
  evhttp_response_code_(req, code, reason);
3355
3356
0
  evhttp_send(req, databuf);
3357
0
}
3358
3359
void
3360
evhttp_send_reply_start(struct evhttp_request *req, int code,
3361
    const char *reason)
3362
0
{
3363
0
  evhttp_response_code_(req, code, reason);
3364
3365
0
  if (req->evcon == NULL)
3366
0
    return;
3367
3368
0
  if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
3369
0
      REQ_VERSION_ATLEAST(req, 1, 1) &&
3370
0
      evhttp_response_needs_body(req)) {
3371
    /*
3372
     * prefer HTTP/1.1 chunked encoding to closing the connection;
3373
     * note RFC 2616 section 4.4 forbids it with Content-Length:
3374
     * and it's not necessary then anyway.
3375
     */
3376
0
    evhttp_add_header(req->output_headers, "Transfer-Encoding",
3377
0
        "chunked");
3378
0
    req->chunked = 1;
3379
0
  } else {
3380
0
    req->chunked = 0;
3381
0
  }
3382
0
  evhttp_make_header(req->evcon, req);
3383
0
  evhttp_write_buffer(req->evcon, NULL, NULL);
3384
0
}
3385
3386
void
3387
evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3388
    void (*cb)(struct evhttp_connection *, void *), void *arg)
3389
0
{
3390
0
  struct evhttp_connection *evcon = req->evcon;
3391
0
  struct evbuffer *output;
3392
3393
0
  if (evcon == NULL)
3394
0
    return;
3395
3396
0
  output = bufferevent_get_output(evcon->bufev);
3397
3398
0
  if (evbuffer_get_length(databuf) == 0)
3399
0
    return;
3400
0
  if (!evhttp_response_needs_body(req))
3401
0
    return;
3402
0
  if (req->chunked) {
3403
0
    evbuffer_add_printf(output, "%x\r\n",
3404
0
            (unsigned)evbuffer_get_length(databuf));
3405
0
  }
3406
0
  evbuffer_add_buffer(output, databuf);
3407
0
  if (req->chunked) {
3408
0
    evbuffer_add(output, "\r\n", 2);
3409
0
  }
3410
0
  evhttp_write_buffer(evcon, cb, arg);
3411
0
}
3412
3413
struct bufferevent *
3414
evhttp_start_ws_(struct evhttp_request *req)
3415
1.01k
{
3416
1.01k
  struct evhttp_connection *evcon = req->evcon;
3417
1.01k
  struct bufferevent *bufev;
3418
3419
1.01k
  evhttp_response_code_(req, HTTP_SWITCH_PROTOCOLS, "Switching Protocols");
3420
3421
1.01k
  if (req->evcon == NULL)
3422
0
    return NULL;
3423
3424
1.01k
  evhttp_make_header(req->evcon, req);
3425
1.01k
  evhttp_write_buffer(req->evcon, NULL, NULL);
3426
3427
1.01k
  TAILQ_REMOVE(&evcon->requests, req, next);
3428
3429
1.01k
  bufev = evcon->bufev;
3430
1.01k
  evcon->bufev = NULL;
3431
1.01k
  evcon->closecb = NULL;
3432
3433
1.01k
  evhttp_request_free(req);
3434
1.01k
  evhttp_connection_free(evcon);
3435
1.01k
  return bufev;
3436
1.01k
}
3437
3438
void
3439
evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3440
0
{
3441
0
  evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3442
0
}
3443
void
3444
evhttp_send_reply_end(struct evhttp_request *req)
3445
0
{
3446
0
  struct evhttp_connection *evcon = req->evcon;
3447
0
  struct evbuffer *output;
3448
3449
0
  if (evcon == NULL) {
3450
0
    evhttp_request_free(req);
3451
0
    return;
3452
0
  }
3453
3454
0
  output = bufferevent_get_output(evcon->bufev);
3455
3456
  /* we expect no more calls form the user on this request */
3457
0
  req->userdone = 1;
3458
3459
0
  if (req->chunked) {
3460
0
    evbuffer_add(output, "0\r\n\r\n", 5);
3461
0
    evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3462
0
    req->chunked = 0;
3463
0
  } else if (evbuffer_get_length(output) == 0) {
3464
    /* let the connection know that we are done with the request */
3465
0
    evhttp_send_done(evcon, NULL);
3466
0
  } else {
3467
    /* make the callback execute after all data has been written */
3468
0
    evcon->cb = evhttp_send_done;
3469
0
    evcon->cb_arg = NULL;
3470
0
  }
3471
0
}
3472
3473
static const char *informational_phrases[] = {
3474
  /* 100 */ "Continue",
3475
  /* 101 */ "Switching Protocols"
3476
};
3477
3478
static const char *success_phrases[] = {
3479
  /* 200 */ "OK",
3480
  /* 201 */ "Created",
3481
  /* 202 */ "Accepted",
3482
  /* 203 */ "Non-Authoritative Information",
3483
  /* 204 */ "No Content",
3484
  /* 205 */ "Reset Content",
3485
  /* 206 */ "Partial Content"
3486
};
3487
3488
static const char *redirection_phrases[] = {
3489
  /* 300 */ "Multiple Choices",
3490
  /* 301 */ "Moved Permanently",
3491
  /* 302 */ "Found",
3492
  /* 303 */ "See Other",
3493
  /* 304 */ "Not Modified",
3494
  /* 305 */ "Use Proxy",
3495
  /* 307 */ "Temporary Redirect"
3496
};
3497
3498
static const char *client_error_phrases[] = {
3499
  /* 400 */ "Bad Request",
3500
  /* 401 */ "Unauthorized",
3501
  /* 402 */ "Payment Required",
3502
  /* 403 */ "Forbidden",
3503
  /* 404 */ "Not Found",
3504
  /* 405 */ "Method Not Allowed",
3505
  /* 406 */ "Not Acceptable",
3506
  /* 407 */ "Proxy Authentication Required",
3507
  /* 408 */ "Request Time-out",
3508
  /* 409 */ "Conflict",
3509
  /* 410 */ "Gone",
3510
  /* 411 */ "Length Required",
3511
  /* 412 */ "Precondition Failed",
3512
  /* 413 */ "Request Entity Too Large",
3513
  /* 414 */ "Request-URI Too Large",
3514
  /* 415 */ "Unsupported Media Type",
3515
  /* 416 */ "Requested range not satisfiable",
3516
  /* 417 */ "Expectation Failed"
3517
};
3518
3519
static const char *server_error_phrases[] = {
3520
  /* 500 */ "Internal Server Error",
3521
  /* 501 */ "Not Implemented",
3522
  /* 502 */ "Bad Gateway",
3523
  /* 503 */ "Service Unavailable",
3524
  /* 504 */ "Gateway Time-out",
3525
  /* 505 */ "HTTP Version not supported"
3526
};
3527
3528
struct response_class {
3529
  const char *name;
3530
  size_t num_responses;
3531
  const char **responses;
3532
};
3533
3534
#ifndef MEMBERSOF
3535
0
#define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3536
#endif
3537
3538
static const struct response_class response_classes[] = {
3539
  /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3540
  /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3541
  /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3542
  /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3543
  /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3544
};
3545
3546
static const char *
3547
evhttp_response_phrase_internal(int code)
3548
0
{
3549
0
  int klass = code / 100 - 1;
3550
0
  int subcode = code % 100;
3551
3552
  /* Unknown class - can't do any better here */
3553
0
  if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3554
0
    return "Unknown Status Class";
3555
3556
  /* Unknown sub-code, return class name at least */
3557
0
  if (subcode >= (int) response_classes[klass].num_responses)
3558
0
    return response_classes[klass].name;
3559
3560
0
  return response_classes[klass].responses[subcode];
3561
0
}
3562
3563
void
3564
evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3565
1.01k
{
3566
1.01k
  req->kind = EVHTTP_RESPONSE;
3567
1.01k
  req->response_code = code;
3568
1.01k
  if (req->response_code_line != NULL)
3569
0
    mm_free(req->response_code_line);
3570
1.01k
  if (reason == NULL)
3571
0
    reason = evhttp_response_phrase_internal(code);
3572
1.01k
  req->response_code_line = mm_strdup(reason);
3573
1.01k
  if (req->response_code_line == NULL) {
3574
0
    event_warn("%s: strdup", __func__);
3575
    /* XXX what else can we do? */
3576
0
  }
3577
1.01k
}
3578
3579
void
3580
evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3581
0
{
3582
0
  if (!req->major || !req->minor) {
3583
0
    req->major = 1;
3584
0
    req->minor = 1;
3585
0
  }
3586
3587
0
  if (req->kind != EVHTTP_RESPONSE)
3588
0
    evhttp_response_code_(req, 200, "OK");
3589
3590
0
  evhttp_clear_headers(req->output_headers);
3591
0
  evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3592
0
  evhttp_add_header(req->output_headers, "Connection", "close");
3593
3594
0
  evhttp_send(req, databuf);
3595
0
}
3596
3597
static const char uri_chars[256] = {
3598
  /* 0 */
3599
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3600
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3601
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 1, 1, 0,
3602
  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 0, 0, 0, 0, 0, 0,
3603
  /* 64 */
3604
  0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
3605
  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 1,
3606
  0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
3607
  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 1, 0,
3608
  /* 128 */
3609
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3610
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3611
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3612
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3613
  /* 192 */
3614
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3615
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3616
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3617
  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3618
};
3619
3620
#define CHAR_IS_UNRESERVED(c)     \
3621
205M
  (uri_chars[(unsigned char)(c)])
3622
3623
/*
3624
 * Helper functions to encode/decode a string for inclusion in a URI.
3625
 * The returned string must be freed by the caller.
3626
 */
3627
char *
3628
evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3629
2.63k
{
3630
2.63k
  struct evbuffer *buf = evbuffer_new();
3631
2.63k
  const char *p, *end;
3632
2.63k
  char *result = NULL;
3633
3634
2.63k
  if (!buf) {
3635
0
    goto out;
3636
0
  }
3637
3638
2.63k
  if (len >= 0) {
3639
0
    if (uri + len < uri) {
3640
0
      goto out;
3641
0
    }
3642
3643
0
    end = uri + len;
3644
2.63k
  } else {
3645
2.63k
    size_t slen = strlen(uri);
3646
3647
2.63k
    if (slen >= EV_SSIZE_MAX) {
3648
      /* we don't want to mix signed and unsigned */
3649
0
      goto out;
3650
0
    }
3651
3652
2.63k
    end = uri + slen;
3653
2.63k
  }
3654
3655
73.6M
  for (p = uri; p < end; p++) {
3656
73.6M
    if (CHAR_IS_UNRESERVED(*p)) {
3657
49.3M
      evbuffer_add(buf, p, 1);
3658
49.3M
    } else if (*p == ' ' && space_as_plus) {
3659
0
      evbuffer_add(buf, "+", 1);
3660
24.2M
    } else {
3661
24.2M
      evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3662
24.2M
    }
3663
73.6M
  }
3664
3665
2.63k
  evbuffer_add(buf, "", 1); /* NUL-terminator. */
3666
2.63k
  result = mm_malloc(evbuffer_get_length(buf));
3667
3668
2.63k
  if (result)
3669
2.63k
    evbuffer_remove(buf, result, evbuffer_get_length(buf));
3670
3671
2.63k
out:
3672
2.63k
  if (buf)
3673
2.63k
    evbuffer_free(buf);
3674
2.63k
  return result;
3675
2.63k
}
3676
3677
char *
3678
evhttp_encode_uri(const char *str)
3679
2.63k
{
3680
2.63k
  return evhttp_uriencode(str, -1, 0);
3681
2.63k
}
3682
3683
/*
3684
 * @param decode_plus_ctl: if 1, we decode plus into space.  If 0, we don't.
3685
 *     If -1, when true we transform plus to space only after we've seen
3686
 *     a ?.  -1 is deprecated.
3687
 * @return the number of bytes written to 'ret'.
3688
 */
3689
int
3690
evhttp_decode_uri_internal(
3691
  const char *uri, size_t length, char *ret, int decode_plus_ctl)
3692
17.0k
{
3693
17.0k
  char c;
3694
17.0k
  int j;
3695
17.0k
  int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3696
17.0k
  unsigned i;
3697
3698
83.2M
  for (i = j = 0; i < length; i++) {
3699
83.2M
    c = uri[i];
3700
83.2M
    if (c == '?') {
3701
168k
      if (decode_plus_ctl < 0)
3702
110k
        decode_plus = 1;
3703
83.0M
    } else if (c == '+' && decode_plus) {
3704
5.66k
      c = ' ';
3705
83.0M
    } else if ((i + 2) < length && c == '%' &&
3706
127k
      EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3707
86.5k
      char tmp[3];
3708
86.5k
      tmp[0] = uri[i+1];
3709
86.5k
      tmp[1] = uri[i+2];
3710
86.5k
      tmp[2] = '\0';
3711
86.5k
      c = (char)strtol(tmp, NULL, 16);
3712
86.5k
      i += 2;
3713
86.5k
    }
3714
83.2M
    ret[j++] = c;
3715
83.2M
  }
3716
17.0k
  ret[j] = '\0';
3717
3718
17.0k
  return (j);
3719
17.0k
}
3720
3721
/* deprecated */
3722
char *
3723
evhttp_decode_uri(const char *uri)
3724
2.63k
{
3725
2.63k
  char *ret;
3726
3727
2.63k
  if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3728
0
    event_warn("%s: malloc(%lu)", __func__,
3729
0
        (unsigned long)(strlen(uri) + 1));
3730
0
    return (NULL);
3731
0
  }
3732
3733
2.63k
  evhttp_decode_uri_internal(uri, strlen(uri),
3734
2.63k
      ret, -1 /*always_decode_plus*/);
3735
3736
2.63k
  return (ret);
3737
2.63k
}
3738
3739
char *
3740
evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3741
0
{
3742
0
  char *ret;
3743
0
  int n;
3744
3745
0
  if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3746
0
    event_warn("%s: malloc(%lu)", __func__,
3747
0
        (unsigned long)(strlen(uri) + 1));
3748
0
    return (NULL);
3749
0
  }
3750
3751
0
  n = evhttp_decode_uri_internal(uri, strlen(uri),
3752
0
      ret, !!decode_plus/*always_decode_plus*/);
3753
3754
0
  if (size_out) {
3755
0
    EVUTIL_ASSERT(n >= 0);
3756
0
    *size_out = (size_t)n;
3757
0
  }
3758
3759
0
  return (ret);
3760
0
}
3761
3762
/*
3763
 * Helper function to parse out arguments in a query.
3764
 * The arguments are separated by key and value.
3765
 */
3766
3767
static int
3768
evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3769
    int is_whole_uri, unsigned flags)
3770
5.00k
{
3771
5.00k
  char *line=NULL;
3772
5.00k
  char *p;
3773
5.00k
  const char *query_part;
3774
5.00k
  int result = -1;
3775
5.00k
  struct evhttp_uri *uri=NULL;
3776
3777
5.00k
  TAILQ_INIT(headers);
3778
3779
5.00k
  if (is_whole_uri) {
3780
2.50k
    uri = evhttp_uri_parse(str);
3781
2.50k
    if (!uri)
3782
1.80k
      goto error;
3783
697
    query_part = evhttp_uri_get_query(uri);
3784
2.50k
  } else {
3785
2.50k
    query_part = str;
3786
2.50k
  }
3787
3788
  /* No arguments - we are done */
3789
3.19k
  if (!query_part || !strlen(query_part)) {
3790
556
    result = 0;
3791
556
    goto done;
3792
556
  }
3793
3794
2.64k
  if ((line = mm_strdup(query_part)) == NULL) {
3795
0
    event_warn("%s: strdup", __func__);
3796
0
    goto error;
3797
0
  }
3798
3799
2.64k
  p = line;
3800
808k
  while (p != NULL && *p != '\0') {
3801
806k
    char *key, *value, *decoded_value;
3802
806k
    int err;
3803
3804
806k
    value = strsep(&p, "&");
3805
806k
    key = strsep(&value, "=");
3806
806k
    if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3807
804k
      if (value == NULL)
3808
801k
        value = (char *)"";
3809
804k
      if (*key == '\0')
3810
791k
        continue;
3811
804k
    } else {
3812
2.20k
      if (value == NULL || *key == '\0')
3813
961
        goto error;
3814
2.20k
    }
3815
3816
14.4k
    if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3817
0
      event_warn("%s: mm_malloc", __func__);
3818
0
      goto error;
3819
0
    }
3820
14.4k
    evhttp_decode_uri_internal(value, strlen(value),
3821
14.4k
        decoded_value, 1 /*always_decode_plus*/);
3822
14.4k
    event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3823
14.4k
    if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3824
9.82k
      evhttp_remove_header(headers, key);
3825
14.4k
    err = evhttp_add_header_internal(headers, key, decoded_value);
3826
14.4k
    mm_free(decoded_value);
3827
14.4k
    if (err)
3828
0
      goto error;
3829
14.4k
  }
3830
3831
1.68k
  result = 0;
3832
1.68k
  goto done;
3833
2.76k
error:
3834
2.76k
  evhttp_clear_headers(headers);
3835
5.00k
done:
3836
5.00k
  if (line)
3837
2.64k
    mm_free(line);
3838
5.00k
  if (uri)
3839
697
    evhttp_uri_free(uri);
3840
5.00k
  return result;
3841
2.76k
}
3842
3843
int
3844
evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3845
2.50k
{
3846
2.50k
  return evhttp_parse_query_impl(uri, headers, 1, 0);
3847
2.50k
}
3848
int
3849
evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3850
0
{
3851
0
  return evhttp_parse_query_impl(uri, headers, 0, 0);
3852
0
}
3853
int
3854
evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3855
2.50k
{
3856
2.50k
  return evhttp_parse_query_impl(uri, headers, 0, flags);
3857
2.50k
}
3858
3859
static struct evhttp_cb *
3860
evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3861
0
{
3862
0
  struct evhttp_cb *cb;
3863
0
  size_t offset = 0;
3864
0
  char *translated;
3865
0
  const char *path;
3866
3867
  /* Test for different URLs */
3868
0
  path = evhttp_uri_get_path(req->uri_elems);
3869
0
  offset = strlen(path);
3870
0
  if ((translated = mm_malloc(offset + 1)) == NULL)
3871
0
    return (NULL);
3872
0
  evhttp_decode_uri_internal(path, offset, translated,
3873
0
      0 /* decode_plus */);
3874
3875
0
  TAILQ_FOREACH(cb, callbacks, next) {
3876
0
    if (!strcmp(cb->what, translated)) {
3877
0
      mm_free(translated);
3878
0
      return (cb);
3879
0
    }
3880
0
  }
3881
3882
0
  mm_free(translated);
3883
0
  return (NULL);
3884
0
}
3885
3886
3887
static int
3888
prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3889
0
{
3890
0
  char c;
3891
3892
0
  while (1) {
3893
0
    switch (c = *pattern++) {
3894
0
    case '\0':
3895
0
      return *name == '\0';
3896
3897
0
    case '*':
3898
0
      while (*name != '\0') {
3899
0
        if (prefix_suffix_match(pattern, name,
3900
0
          ignorecase))
3901
0
          return (1);
3902
0
        ++name;
3903
0
      }
3904
0
      return (0);
3905
0
    default:
3906
0
      if (c != *name) {
3907
0
        if (!ignorecase ||
3908
0
            EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3909
0
          return (0);
3910
0
      }
3911
0
      ++name;
3912
0
    }
3913
0
  }
3914
  /* NOTREACHED */
3915
0
}
3916
3917
/*
3918
   Search the vhost hierarchy beginning with http for a server alias
3919
   matching hostname.  If a match is found, and outhttp is non-null,
3920
   outhttp is set to the matching http object and 1 is returned.
3921
*/
3922
3923
static int
3924
evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3925
      const char *hostname)
3926
0
{
3927
0
  struct evhttp_server_alias *alias;
3928
0
  struct evhttp *vhost;
3929
3930
0
  TAILQ_FOREACH(alias, &http->aliases, next) {
3931
    /* XXX Do we need to handle IP addresses? */
3932
0
    if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3933
0
      if (outhttp)
3934
0
        *outhttp = http;
3935
0
      return 1;
3936
0
    }
3937
0
  }
3938
3939
  /* XXX It might be good to avoid recursion here, but I don't
3940
     see a way to do that w/o a list. */
3941
0
  TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3942
0
    if (evhttp_find_alias(vhost, outhttp, hostname))
3943
0
      return 1;
3944
0
  }
3945
3946
0
  return 0;
3947
0
}
3948
3949
/*
3950
   Attempts to find the best http object to handle a request for a hostname.
3951
   All aliases for the root http object and vhosts are searched for an exact
3952
   match. Then, the vhost hierarchy is traversed again for a matching
3953
   pattern.
3954
3955
   If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3956
   is set with the best matching http object. If there are no matches, the
3957
   root http object is stored in outhttp and 0 is returned.
3958
*/
3959
3960
static int
3961
evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3962
      const char *hostname)
3963
0
{
3964
0
  struct evhttp *vhost;
3965
0
  struct evhttp *oldhttp;
3966
0
  int match_found = 0;
3967
3968
0
  if (evhttp_find_alias(http, outhttp, hostname))
3969
0
    return 1;
3970
3971
0
  do {
3972
0
    oldhttp = http;
3973
0
    TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3974
0
      if (prefix_suffix_match(vhost->vhost_pattern,
3975
0
        hostname, 1 /* ignorecase */)) {
3976
0
        http = vhost;
3977
0
        match_found = 1;
3978
0
        break;
3979
0
      }
3980
0
    }
3981
0
  } while (oldhttp != http);
3982
3983
0
  if (outhttp)
3984
0
    *outhttp = http;
3985
3986
0
  return match_found;
3987
0
}
3988
3989
static void
3990
evhttp_handle_request(struct evhttp_request *req, void *arg)
3991
0
{
3992
0
  struct evhttp *http = arg;
3993
0
  struct evhttp_cb *cb = NULL;
3994
0
  const char *hostname;
3995
3996
  /* we have a new request on which the user needs to take action */
3997
0
  req->userdone = 0;
3998
3999
0
  bufferevent_disable(req->evcon->bufev, EV_READ);
4000
4001
0
  if (req->uri == NULL) {
4002
0
    evhttp_send_error(req, req->response_code, NULL);
4003
0
    return;
4004
0
  }
4005
4006
0
  if ((http->allowed_methods & req->type) == 0) {
4007
0
    event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
4008
0
      (unsigned)req->type, (unsigned)http->allowed_methods));
4009
0
    evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
4010
0
    return;
4011
0
  }
4012
4013
  /* handle potential virtual hosts */
4014
0
  hostname = evhttp_request_get_host(req);
4015
0
  if (hostname != NULL) {
4016
0
    evhttp_find_vhost(http, &http, hostname);
4017
0
  }
4018
4019
0
  if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
4020
0
    (*cb->cb)(req, cb->cbarg);
4021
0
    return;
4022
0
  }
4023
4024
  /* Generic call back */
4025
0
  if (http->gencb) {
4026
0
    (*http->gencb)(req, http->gencbarg);
4027
0
    return;
4028
0
  } else
4029
0
    evhttp_send_notfound(req, NULL);
4030
0
}
4031
4032
/* Listener callback when a connection arrives at a server. */
4033
static void
4034
accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
4035
0
{
4036
0
  struct evhttp_bound_socket *bound = arg;
4037
4038
0
  struct evhttp *http = bound->http;
4039
4040
0
  struct bufferevent *bev = NULL;
4041
0
  if (bound->bevcb)
4042
0
    bev = bound->bevcb(http->base, bound->bevcbarg);
4043
4044
0
  evhttp_get_request(http, nfd, peer_sa, peer_socklen, bev);
4045
0
}
4046
4047
int
4048
evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
4049
0
{
4050
0
  struct evhttp_bound_socket *bound =
4051
0
    evhttp_bind_socket_with_handle(http, address, port);
4052
0
  if (bound == NULL)
4053
0
    return (-1);
4054
0
  return (0);
4055
0
}
4056
4057
struct evhttp_bound_socket *
4058
evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
4059
0
{
4060
0
  evutil_socket_t fd;
4061
0
  struct evhttp_bound_socket *bound;
4062
0
  int serrno;
4063
4064
0
  if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
4065
0
    return (NULL);
4066
4067
0
  if (listen(fd, 128) == -1) {
4068
0
    serrno = EVUTIL_SOCKET_ERROR();
4069
0
    event_sock_warn(fd, "%s: listen", __func__);
4070
0
    evutil_closesocket(fd);
4071
0
    EVUTIL_SET_SOCKET_ERROR(serrno);
4072
0
    return (NULL);
4073
0
  }
4074
4075
0
  bound = evhttp_accept_socket_with_handle(http, fd);
4076
4077
0
  if (bound != NULL) {
4078
0
    event_debug(("Bound to port %d - Awaiting connections ... ",
4079
0
      port));
4080
0
    return (bound);
4081
0
  }
4082
4083
0
  return (NULL);
4084
0
}
4085
4086
int
4087
evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
4088
0
{
4089
0
  struct evhttp_bound_socket *bound =
4090
0
    evhttp_accept_socket_with_handle(http, fd);
4091
0
  if (bound == NULL)
4092
0
    return (-1);
4093
0
  return (0);
4094
0
}
4095
4096
void
4097
evhttp_foreach_bound_socket(struct evhttp *http,
4098
                            evhttp_bound_socket_foreach_fn *function,
4099
                            void *argument)
4100
0
{
4101
0
  struct evhttp_bound_socket *bound;
4102
4103
0
  TAILQ_FOREACH(bound, &http->sockets, next)
4104
0
    function(bound, argument);
4105
0
}
4106
4107
struct evhttp_bound_socket *
4108
evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
4109
0
{
4110
0
  struct evhttp_bound_socket *bound;
4111
0
  struct evconnlistener *listener;
4112
0
  const int flags =
4113
0
      LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
4114
4115
0
  listener = evconnlistener_new(http->base, NULL, NULL,
4116
0
      flags,
4117
0
      0, /* Backlog is '0' because we already said 'listen' */
4118
0
      fd);
4119
0
  if (!listener)
4120
0
    return (NULL);
4121
4122
0
  bound = evhttp_bind_listener(http, listener);
4123
0
  if (!bound) {
4124
0
    evconnlistener_free(listener);
4125
0
    return (NULL);
4126
0
  }
4127
0
  return (bound);
4128
0
}
4129
4130
struct evhttp_bound_socket *
4131
evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
4132
0
{
4133
0
  struct evhttp_bound_socket *bound;
4134
4135
0
  bound = mm_malloc(sizeof(struct evhttp_bound_socket));
4136
0
  if (bound == NULL)
4137
0
    return (NULL);
4138
4139
0
  bound->listener = listener;
4140
0
  bound->bevcb = NULL;
4141
0
  bound->http = http;
4142
0
  TAILQ_INSERT_TAIL(&http->sockets, bound, next);
4143
4144
0
  evconnlistener_set_cb(listener, accept_socket_cb, bound);
4145
0
  return bound;
4146
0
}
4147
4148
evutil_socket_t
4149
evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
4150
0
{
4151
0
  return evconnlistener_get_fd(bound->listener);
4152
0
}
4153
4154
struct evconnlistener *
4155
evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
4156
0
{
4157
0
  return bound->listener;
4158
0
}
4159
4160
void
4161
evhttp_bound_set_bevcb(struct evhttp_bound_socket *bound,
4162
    struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4163
0
{
4164
0
  bound->bevcb = cb;
4165
0
  bound->bevcbarg = cbarg;
4166
0
}
4167
4168
void
4169
evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
4170
0
{
4171
0
  TAILQ_REMOVE(&http->sockets, bound, next);
4172
0
  evconnlistener_free(bound->listener);
4173
0
  mm_free(bound);
4174
0
}
4175
4176
static struct evhttp*
4177
evhttp_new_object(void)
4178
4.27k
{
4179
4.27k
  struct evhttp *http = NULL;
4180
4181
4.27k
  if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
4182
0
    event_warn("%s: calloc", __func__);
4183
0
    return (NULL);
4184
0
  }
4185
4186
4.27k
  evutil_timerclear(&http->timeout_read);
4187
4.27k
  evutil_timerclear(&http->timeout_write);
4188
4189
4.27k
  evhttp_set_max_headers_size(http, EV_SIZE_MAX);
4190
4.27k
  evhttp_set_max_body_size(http, EV_SIZE_MAX);
4191
4.27k
  evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
4192
4.27k
  evhttp_set_allowed_methods(http,
4193
4.27k
      EVHTTP_REQ_GET |
4194
4.27k
      EVHTTP_REQ_POST |
4195
4.27k
      EVHTTP_REQ_HEAD |
4196
4.27k
      EVHTTP_REQ_PUT |
4197
4.27k
      EVHTTP_REQ_DELETE);
4198
4199
4.27k
  TAILQ_INIT(&http->sockets);
4200
4.27k
  TAILQ_INIT(&http->callbacks);
4201
4.27k
  TAILQ_INIT(&http->connections);
4202
4.27k
  TAILQ_INIT(&http->ws_sessions);
4203
4.27k
  TAILQ_INIT(&http->virtualhosts);
4204
4.27k
  TAILQ_INIT(&http->aliases);
4205
4206
4.27k
  return (http);
4207
4.27k
}
4208
4209
struct evhttp *
4210
evhttp_new(struct event_base *base)
4211
4.27k
{
4212
4.27k
  struct evhttp *http = NULL;
4213
4214
4.27k
  http = evhttp_new_object();
4215
4.27k
  if (http == NULL)
4216
0
    return (NULL);
4217
4.27k
  http->base = base;
4218
4219
4.27k
  return (http);
4220
4.27k
}
4221
4222
/*
4223
 * Start a web server on the specified address and port.
4224
 */
4225
4226
struct evhttp *
4227
evhttp_start(const char *address, ev_uint16_t port)
4228
0
{
4229
0
  struct evhttp *http = NULL;
4230
4231
0
  http = evhttp_new_object();
4232
0
  if (http == NULL)
4233
0
    return (NULL);
4234
0
  if (evhttp_bind_socket(http, address, port) == -1) {
4235
0
    mm_free(http);
4236
0
    return (NULL);
4237
0
  }
4238
4239
0
  return (http);
4240
0
}
4241
4242
void
4243
evhttp_free(struct evhttp* http)
4244
4.27k
{
4245
4.27k
  struct evhttp_cb *http_cb;
4246
4.27k
  struct evhttp_connection *evcon;
4247
4.27k
  struct evws_connection *evws;
4248
4.27k
  struct evhttp_bound_socket *bound;
4249
4.27k
  struct evhttp* vhost;
4250
4.27k
  struct evhttp_server_alias *alias;
4251
4252
  /* Remove the accepting part */
4253
4.27k
  while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
4254
0
    TAILQ_REMOVE(&http->sockets, bound, next);
4255
4256
0
    evconnlistener_free(bound->listener);
4257
4258
0
    mm_free(bound);
4259
0
  }
4260
4261
4.27k
  while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
4262
    /* evhttp_connection_free removes the connection */
4263
0
    evhttp_connection_free(evcon);
4264
0
  }
4265
4266
4.27k
  while ((evws = TAILQ_FIRST(&http->ws_sessions)) != NULL) {
4267
0
    evws_connection_free(evws);
4268
0
  }
4269
4270
4.27k
  while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
4271
0
    TAILQ_REMOVE(&http->callbacks, http_cb, next);
4272
0
    mm_free(http_cb->what);
4273
0
    mm_free(http_cb);
4274
0
  }
4275
4276
4.27k
  while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
4277
0
    TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
4278
4279
0
    evhttp_free(vhost);
4280
0
  }
4281
4282
4.27k
  if (http->vhost_pattern != NULL)
4283
0
    mm_free(http->vhost_pattern);
4284
4285
4.27k
  while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
4286
0
    TAILQ_REMOVE(&http->aliases, alias, next);
4287
0
    mm_free(alias->alias);
4288
0
    mm_free(alias);
4289
0
  }
4290
4291
4.27k
  mm_free(http);
4292
4.27k
}
4293
4294
int
4295
evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
4296
    struct evhttp* vhost)
4297
0
{
4298
  /* a vhost can only be a vhost once and should not have bound sockets */
4299
0
  if (vhost->vhost_pattern != NULL ||
4300
0
      TAILQ_FIRST(&vhost->sockets) != NULL)
4301
0
    return (-1);
4302
4303
0
  vhost->vhost_pattern = mm_strdup(pattern);
4304
0
  if (vhost->vhost_pattern == NULL)
4305
0
    return (-1);
4306
4307
0
  TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
4308
4309
0
  return (0);
4310
0
}
4311
4312
int
4313
evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
4314
0
{
4315
0
  if (vhost->vhost_pattern == NULL)
4316
0
    return (-1);
4317
4318
0
  TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
4319
4320
0
  mm_free(vhost->vhost_pattern);
4321
0
  vhost->vhost_pattern = NULL;
4322
4323
0
  return (0);
4324
0
}
4325
4326
int
4327
evhttp_add_server_alias(struct evhttp *http, const char *alias)
4328
0
{
4329
0
  struct evhttp_server_alias *evalias;
4330
4331
0
  evalias = mm_calloc(1, sizeof(*evalias));
4332
0
  if (!evalias)
4333
0
    return -1;
4334
4335
0
  evalias->alias = mm_strdup(alias);
4336
0
  if (!evalias->alias) {
4337
0
    mm_free(evalias);
4338
0
    return -1;
4339
0
  }
4340
4341
0
  TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
4342
4343
0
  return 0;
4344
0
}
4345
4346
int
4347
evhttp_remove_server_alias(struct evhttp *http, const char *alias)
4348
0
{
4349
0
  struct evhttp_server_alias *evalias;
4350
4351
0
  TAILQ_FOREACH(evalias, &http->aliases, next) {
4352
0
    if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
4353
0
      TAILQ_REMOVE(&http->aliases, evalias, next);
4354
0
      mm_free(evalias->alias);
4355
0
      mm_free(evalias);
4356
0
      return 0;
4357
0
    }
4358
0
  }
4359
4360
0
  return -1;
4361
0
}
4362
4363
void
4364
evhttp_set_timeout(struct evhttp* http, int timeout)
4365
0
{
4366
0
  evhttp_set_timeout_(&http->timeout_read,  timeout, -1);
4367
0
  evhttp_set_timeout_(&http->timeout_write, timeout, -1);
4368
0
}
4369
void
4370
evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
4371
0
{
4372
0
  evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4373
0
  evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4374
0
}
4375
void
4376
evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
4377
0
{
4378
0
  evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4379
0
}
4380
void
4381
evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
4382
0
{
4383
0
  evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4384
0
}
4385
4386
int evhttp_set_flags(struct evhttp *http, int flags)
4387
0
{
4388
0
  int avail_flags = 0;
4389
0
  avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4390
4391
0
  if (flags & ~avail_flags)
4392
0
    return 1;
4393
0
  http->flags &= ~avail_flags;
4394
4395
0
  http->flags |= flags;
4396
4397
0
  return 0;
4398
0
}
4399
4400
void
4401
evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4402
4.27k
{
4403
4.27k
  if (max_headers_size < 0)
4404
4.27k
    http->default_max_headers_size = EV_SIZE_MAX;
4405
0
  else
4406
0
    http->default_max_headers_size = max_headers_size;
4407
4.27k
}
4408
4409
void
4410
evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4411
4.27k
{
4412
4.27k
  if (max_body_size < 0)
4413
4.27k
    http->default_max_body_size = EV_UINT64_MAX;
4414
0
  else
4415
0
    http->default_max_body_size = max_body_size;
4416
4.27k
}
4417
4418
void
4419
evhttp_set_max_connections(struct evhttp* http, int max_connections)
4420
0
{
4421
0
  if (max_connections < 0)
4422
0
    http->connection_max = 0;
4423
0
  else
4424
0
    http->connection_max = max_connections;
4425
0
}
4426
4427
int
4428
evhttp_get_connection_count(struct evhttp* http)
4429
0
{
4430
0
  return http->connection_cnt;
4431
0
}
4432
4433
void
4434
evhttp_set_default_content_type(struct evhttp *http,
4435
4.27k
  const char *content_type) {
4436
4.27k
  http->default_content_type = content_type;
4437
4.27k
}
4438
4439
void
4440
evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods)
4441
4.27k
{
4442
4.27k
  http->allowed_methods = methods;
4443
4.27k
}
4444
4445
void
4446
evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp)
4447
0
{
4448
0
  http->ext_method_cmp = cmp;
4449
0
}
4450
4451
int
4452
evhttp_set_cb(struct evhttp *http, const char *uri,
4453
    void (*cb)(struct evhttp_request *, void *), void *cbarg)
4454
0
{
4455
0
  struct evhttp_cb *http_cb;
4456
4457
0
  TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4458
0
    if (strcmp(http_cb->what, uri) == 0)
4459
0
      return (-1);
4460
0
  }
4461
4462
0
  if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4463
0
    event_warn("%s: calloc", __func__);
4464
0
    return (-2);
4465
0
  }
4466
4467
0
  http_cb->what = mm_strdup(uri);
4468
0
  if (http_cb->what == NULL) {
4469
0
    event_warn("%s: strdup", __func__);
4470
0
    mm_free(http_cb);
4471
0
    return (-3);
4472
0
  }
4473
0
  http_cb->cb = cb;
4474
0
  http_cb->cbarg = cbarg;
4475
4476
0
  TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4477
4478
0
  return (0);
4479
0
}
4480
4481
int
4482
evhttp_del_cb(struct evhttp *http, const char *uri)
4483
0
{
4484
0
  struct evhttp_cb *http_cb;
4485
4486
0
  TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4487
0
    if (strcmp(http_cb->what, uri) == 0)
4488
0
      break;
4489
0
  }
4490
0
  if (http_cb == NULL)
4491
0
    return (-1);
4492
4493
0
  TAILQ_REMOVE(&http->callbacks, http_cb, next);
4494
0
  mm_free(http_cb->what);
4495
0
  mm_free(http_cb);
4496
4497
0
  return (0);
4498
0
}
4499
4500
void
4501
evhttp_set_gencb(struct evhttp *http,
4502
    void (*cb)(struct evhttp_request *, void *), void *cbarg)
4503
0
{
4504
0
  http->gencb = cb;
4505
0
  http->gencbarg = cbarg;
4506
0
}
4507
4508
void
4509
evhttp_set_bevcb(struct evhttp *http,
4510
    struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4511
0
{
4512
0
  http->bevcb = cb;
4513
0
  http->bevcbarg = cbarg;
4514
0
}
4515
4516
void
4517
evhttp_set_newreqcb(struct evhttp *http,
4518
    int (*cb)(struct evhttp_request *, void *), void *cbarg)
4519
0
{
4520
0
  http->newreqcb = cb;
4521
0
  http->newreqcbarg = cbarg;
4522
0
}
4523
void
4524
evhttp_set_errorcb(struct evhttp *http,
4525
    int (*cb)(struct evhttp_request *, struct evbuffer *, int, const char *, void *),
4526
    void *cbarg)
4527
0
{
4528
0
  http->errorcb = cb;
4529
0
  http->errorcbarg = cbarg;
4530
0
}
4531
4532
/*
4533
 * Request related functions
4534
 */
4535
4536
struct evhttp_request *
4537
evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4538
9.87k
{
4539
9.87k
  struct evhttp_request *req = NULL;
4540
4541
  /* Allocate request structure */
4542
9.87k
  if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4543
0
    event_warn("%s: calloc", __func__);
4544
0
    goto error;
4545
0
  }
4546
4547
9.87k
  req->headers_size = 0;
4548
9.87k
  req->body_size = 0;
4549
4550
9.87k
  req->kind = EVHTTP_RESPONSE;
4551
9.87k
  req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4552
9.87k
  if (req->input_headers == NULL) {
4553
0
    event_warn("%s: calloc", __func__);
4554
0
    goto error;
4555
0
  }
4556
9.87k
  TAILQ_INIT(req->input_headers);
4557
4558
9.87k
  req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4559
9.87k
  if (req->output_headers == NULL) {
4560
0
    event_warn("%s: calloc", __func__);
4561
0
    goto error;
4562
0
  }
4563
9.87k
  TAILQ_INIT(req->output_headers);
4564
4565
9.87k
  if ((req->input_buffer = evbuffer_new()) == NULL) {
4566
0
    event_warn("%s: evbuffer_new", __func__);
4567
0
    goto error;
4568
0
  }
4569
4570
9.87k
  if ((req->output_buffer = evbuffer_new()) == NULL) {
4571
0
    event_warn("%s: evbuffer_new", __func__);
4572
0
    goto error;
4573
0
  }
4574
4575
9.87k
  req->cb = cb;
4576
9.87k
  req->cb_arg = arg;
4577
4578
9.87k
  return (req);
4579
4580
0
 error:
4581
0
  if (req != NULL)
4582
0
    evhttp_request_free(req);
4583
0
  return (NULL);
4584
9.87k
}
4585
4586
void
4587
evhttp_request_free(struct evhttp_request *req)
4588
9.87k
{
4589
9.87k
  if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4590
0
    req->flags |= EVHTTP_REQ_NEEDS_FREE;
4591
0
    return;
4592
0
  }
4593
4594
9.87k
  if (req->remote_host != NULL)
4595
0
    mm_free(req->remote_host);
4596
9.87k
  if (req->uri != NULL)
4597
2.29k
    mm_free(req->uri);
4598
9.87k
  if (req->uri_elems != NULL)
4599
2.24k
    evhttp_uri_free(req->uri_elems);
4600
9.87k
  if (req->response_code_line != NULL)
4601
3.36k
    mm_free(req->response_code_line);
4602
9.87k
  if (req->host_cache != NULL)
4603
3
    mm_free(req->host_cache);
4604
4605
9.87k
  evhttp_clear_headers(req->input_headers);
4606
9.87k
  mm_free(req->input_headers);
4607
4608
9.87k
  evhttp_clear_headers(req->output_headers);
4609
9.87k
  mm_free(req->output_headers);
4610
4611
9.87k
  if (req->input_buffer != NULL)
4612
9.87k
    evbuffer_free(req->input_buffer);
4613
4614
9.87k
  if (req->output_buffer != NULL)
4615
9.87k
    evbuffer_free(req->output_buffer);
4616
4617
9.87k
  mm_free(req);
4618
9.87k
}
4619
4620
void
4621
evhttp_request_own(struct evhttp_request *req)
4622
0
{
4623
0
  req->flags |= EVHTTP_USER_OWNED;
4624
0
}
4625
4626
int
4627
evhttp_request_is_owned(struct evhttp_request *req)
4628
0
{
4629
0
  return (req->flags & EVHTTP_USER_OWNED) != 0;
4630
0
}
4631
4632
struct evhttp_connection *
4633
evhttp_request_get_connection(struct evhttp_request *req)
4634
1.01k
{
4635
1.01k
  return req->evcon;
4636
1.01k
}
4637
4638
struct event_base *
4639
evhttp_connection_get_base(struct evhttp_connection *conn)
4640
0
{
4641
0
  return conn->base;
4642
0
}
4643
4644
void
4645
evhttp_request_set_chunked_cb(struct evhttp_request *req,
4646
    void (*cb)(struct evhttp_request *, void *))
4647
0
{
4648
0
  req->chunk_cb = cb;
4649
0
}
4650
4651
void
4652
evhttp_request_set_header_cb(struct evhttp_request *req,
4653
    int (*cb)(struct evhttp_request *, void *))
4654
0
{
4655
0
  req->header_cb = cb;
4656
0
}
4657
4658
void
4659
evhttp_request_set_error_cb(struct evhttp_request *req,
4660
    void (*cb)(enum evhttp_request_error, void *))
4661
0
{
4662
0
  req->error_cb = cb;
4663
0
}
4664
4665
void
4666
evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4667
    void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4668
0
{
4669
0
  req->on_complete_cb = cb;
4670
0
  req->on_complete_cb_arg = cb_arg;
4671
0
}
4672
4673
/*
4674
 * Allows for inspection of the request URI
4675
 */
4676
4677
const char *
4678
45
evhttp_request_get_uri(const struct evhttp_request *req) {
4679
45
  if (req->uri == NULL)
4680
0
    event_debug(("%s: request %p has no uri\n", __func__, (void *)req));
4681
45
  return (req->uri);
4682
45
}
4683
4684
const struct evhttp_uri *
4685
45
evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4686
45
  if (req->uri_elems == NULL)
4687
0
    event_debug(("%s: request %p has no uri elems\n",
4688
45
          __func__, (void *)req));
4689
45
  return (req->uri_elems);
4690
45
}
4691
4692
const char *
4693
evhttp_request_get_host(struct evhttp_request *req)
4694
133
{
4695
133
  const char *host = NULL;
4696
4697
133
  if (req->host_cache)
4698
0
    return req->host_cache;
4699
4700
133
  if (req->uri_elems)
4701
133
    host = evhttp_uri_get_host(req->uri_elems);
4702
133
  if (!host && req->input_headers) {
4703
127
    const char *p;
4704
127
    size_t len;
4705
4706
127
    host = evhttp_find_header(req->input_headers, "Host");
4707
    /* The Host: header may include a port. Remove it here
4708
       to be consistent with uri_elems case above. */
4709
127
    if (host) {
4710
34
      p = host + strlen(host) - 1;
4711
296
      while (p > host && EVUTIL_ISDIGIT_(*p))
4712
262
        --p;
4713
34
      if (p > host && *p == ':') {
4714
3
        len = p - host;
4715
3
        req->host_cache = mm_malloc(len + 1);
4716
3
        if (!req->host_cache) {
4717
0
          event_warn("%s: malloc", __func__);
4718
0
          return NULL;
4719
0
        }
4720
3
        memcpy(req->host_cache, host, len);
4721
3
        req->host_cache[len] = '\0';
4722
3
        host = req->host_cache;
4723
3
      }
4724
34
    }
4725
127
  }
4726
4727
133
  return host;
4728
133
}
4729
4730
enum evhttp_cmd_type
4731
133
evhttp_request_get_command(const struct evhttp_request *req) {
4732
133
  return (req->type);
4733
133
}
4734
4735
int
4736
evhttp_request_get_response_code(const struct evhttp_request *req)
4737
97
{
4738
97
  return req->response_code;
4739
97
}
4740
4741
const char *
4742
evhttp_request_get_response_code_line(const struct evhttp_request *req)
4743
97
{
4744
97
  return req->response_code_line;
4745
97
}
4746
4747
/** Returns the input headers */
4748
struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4749
2.17k
{
4750
2.17k
  return (req->input_headers);
4751
2.17k
}
4752
4753
/** Returns the output headers */
4754
struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4755
1.01k
{
4756
1.01k
  return (req->output_headers);
4757
1.01k
}
4758
4759
/** Returns the input buffer */
4760
struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4761
26
{
4762
26
  return (req->input_buffer);
4763
26
}
4764
4765
/** Returns the output buffer */
4766
struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4767
0
{
4768
0
  return (req->output_buffer);
4769
0
}
4770
4771
4772
/*
4773
 * Takes a file descriptor to read a request from.
4774
 * The callback is executed once the whole request has been read.
4775
 */
4776
4777
static struct evhttp_connection*
4778
evhttp_get_request_connection(
4779
  struct evhttp* http,
4780
  evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen,
4781
  struct bufferevent* bev)
4782
0
{
4783
0
  struct evhttp_connection *evcon;
4784
4785
0
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4786
0
  if (sa->sa_family == AF_UNIX) {
4787
0
    struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4788
0
    sa_un->sun_path[0] = '\0';
4789
0
  }
4790
0
#endif
4791
4792
0
#ifndef _WIN32
4793
0
  if (sa->sa_family == AF_UNIX) {
4794
0
    struct sockaddr_un *sockaddr = (struct sockaddr_un *)sa;
4795
4796
0
    event_debug(("%s: new request from unix socket on "
4797
0
      EV_SOCK_FMT"\n", __func__, EV_SOCK_ARG(fd)));
4798
4799
    /* we need a connection object to put the http request on */
4800
0
    if (!bev && http->bevcb != NULL) {
4801
0
      bev = (*http->bevcb)(http->base, http->bevcbarg);
4802
0
    }
4803
4804
0
    evcon = evhttp_connection_base_bufferevent_unix_new(http->base,
4805
0
      bev, sockaddr->sun_path);
4806
0
  }
4807
0
  else
4808
0
#endif
4809
0
  {
4810
0
    char *hostname = NULL, *portname = NULL;
4811
4812
0
    name_from_addr(sa, salen, &hostname, &portname);
4813
0
    if (hostname == NULL || portname == NULL) {
4814
0
      if (hostname) mm_free(hostname);
4815
0
      if (portname) mm_free(portname);
4816
0
      return (NULL);
4817
0
    }
4818
4819
0
    event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4820
0
      __func__, hostname, portname, EV_SOCK_ARG(fd)));
4821
4822
    /* we need a connection object to put the http request on */
4823
0
    if (!bev && http->bevcb != NULL) {
4824
0
      bev = (*http->bevcb)(http->base, http->bevcbarg);
4825
0
    }
4826
0
    evcon = evhttp_connection_base_bufferevent_new(
4827
0
      http->base, NULL, bev, hostname, atoi(portname));
4828
0
    mm_free(hostname);
4829
0
    mm_free(portname);
4830
0
  }
4831
0
  if (evcon == NULL)
4832
0
    return (NULL);
4833
4834
0
  evcon->max_headers_size = http->default_max_headers_size;
4835
0
  evcon->max_body_size = http->default_max_body_size;
4836
0
  if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4837
0
    evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4838
4839
0
  evcon->flags |= EVHTTP_CON_INCOMING;
4840
0
  evcon->state = EVCON_READING_FIRSTLINE;
4841
4842
0
  if (bufferevent_replacefd(evcon->bufev, fd))
4843
0
    goto err;
4844
0
  if (bufferevent_enable(evcon->bufev, EV_READ))
4845
0
    goto err;
4846
0
  if (bufferevent_disable(evcon->bufev, EV_WRITE))
4847
0
    goto err;
4848
0
  if (bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen)) {
4849
0
    goto err;
4850
0
  }
4851
4852
0
  return (evcon);
4853
4854
0
err:
4855
0
  evhttp_connection_free(evcon);
4856
0
  return (NULL);
4857
0
}
4858
4859
static int
4860
evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4861
0
{
4862
0
  struct evhttp *http = evcon->http_server;
4863
0
  struct evhttp_request *req;
4864
0
  if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4865
0
    return (-1);
4866
4867
0
  if (evcon->address != NULL) {
4868
0
    if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4869
0
      event_warn("%s: strdup", __func__);
4870
0
      evhttp_request_free(req);
4871
0
      return (-1);
4872
0
    }
4873
0
  }
4874
0
  req->remote_port = evcon->port;
4875
4876
0
  req->evcon = evcon; /* the request ends up owning the connection */
4877
0
  req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4878
4879
  /* We did not present the request to the user yet, so treat it
4880
   * as if the user was done with the request.  This allows us
4881
   * to free the request on a persistent connection if the
4882
   * client drops it without sending a request.
4883
   */
4884
0
  req->userdone = 1;
4885
0
  req->kind = EVHTTP_REQUEST;
4886
4887
0
  if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4888
0
    evhttp_request_free(req);
4889
0
    return (-1);
4890
0
  }
4891
4892
0
  TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4893
4894
0
  evhttp_start_read_(evcon);
4895
4896
0
  return (0);
4897
0
}
4898
4899
static void
4900
evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4901
    struct sockaddr *sa, ev_socklen_t salen,
4902
    struct bufferevent *bev)
4903
0
{
4904
0
  struct evhttp_connection *evcon;
4905
4906
0
  evcon = evhttp_get_request_connection(http, fd, sa, salen, bev);
4907
0
  if (evcon == NULL) {
4908
0
    event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4909
0
        __func__, EV_SOCK_ARG(fd));
4910
0
    evutil_closesocket(fd);
4911
0
    return;
4912
0
  }
4913
4914
  /* the timeout can be used by the server to close idle connections */
4915
0
  if (evutil_timerisset(&http->timeout_read))
4916
0
    evhttp_connection_set_read_timeout_tv(evcon,  &http->timeout_read);
4917
0
  if (evutil_timerisset(&http->timeout_write))
4918
0
    evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4919
4920
  /*
4921
   * if we want to accept more than one request on a connection,
4922
   * we need to know which http server it belongs to.
4923
   */
4924
0
  evcon->http_server = http;
4925
0
  evcon->ext_method_cmp = http->ext_method_cmp;
4926
0
  TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4927
0
  http->connection_cnt++;
4928
4929
  /* send "service unavailable" if we've reached the connection limit */
4930
0
  if (http->connection_max && http->connection_max < http->connection_cnt) {
4931
0
    struct evhttp_request *req;
4932
4933
0
    if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL) {
4934
0
      evhttp_connection_free(evcon);
4935
0
      return;
4936
0
    }
4937
4938
0
    req->evcon = evcon; /* the request owns the connection */
4939
0
    req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4940
0
    req->kind = EVHTTP_REQUEST;
4941
    /* note, req->remote_host not needed since we don't read */
4942
4943
0
    TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4944
4945
    /* send error to client */
4946
0
    evcon->state = EVCON_WRITING;
4947
0
    bufferevent_enable(evcon->bufev, EV_READ); /* enable close events */
4948
0
    evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
4949
4950
0
  } else if (evhttp_associate_new_request_with_connection(evcon) == -1)
4951
0
    evhttp_connection_free(evcon);
4952
0
}
4953
4954
4955
/*
4956
 * Network helper functions that we do not want to export to the rest of
4957
 * the world.
4958
 */
4959
4960
static void
4961
name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4962
    char **phost, char **pport)
4963
0
{
4964
0
  char ntop[NI_MAXHOST];
4965
0
  char strport[NI_MAXSERV];
4966
0
  int ni_result;
4967
4968
0
#ifdef EVENT__HAVE_GETNAMEINFO
4969
0
  ni_result = getnameinfo(sa, salen,
4970
0
    ntop, sizeof(ntop), strport, sizeof(strport),
4971
0
    NI_NUMERICHOST|NI_NUMERICSERV);
4972
4973
0
  if (ni_result != 0) {
4974
0
#ifdef EAI_SYSTEM
4975
    /* Windows doesn't have an EAI_SYSTEM. */
4976
0
    if (ni_result == EAI_SYSTEM)
4977
0
      event_err(1, "getnameinfo failed");
4978
0
    else
4979
0
#endif
4980
0
      event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4981
0
    return;
4982
0
  }
4983
#else
4984
  ni_result = fake_getnameinfo(sa, salen,
4985
    ntop, sizeof(ntop), strport, sizeof(strport),
4986
    NI_NUMERICHOST|NI_NUMERICSERV);
4987
  if (ni_result != 0)
4988
      return;
4989
#endif
4990
4991
0
  *phost = mm_strdup(ntop);
4992
0
  *pport = mm_strdup(strport);
4993
0
}
4994
4995
/* Create a non-blocking socket and bind it */
4996
static evutil_socket_t
4997
create_bind_socket_nonblock(struct evutil_addrinfo *ai, int reuse)
4998
0
{
4999
0
  evutil_socket_t fd;
5000
5001
0
  int r;
5002
0
  int serrno;
5003
5004
  /* Create listen socket */
5005
0
  fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
5006
0
      SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
5007
0
  if (fd == -1) {
5008
0
      event_sock_warn(-1, "socket");
5009
0
      return (-1);
5010
0
  }
5011
5012
  /* TODO(panjf2000): make this TCP keep-alive value configurable */
5013
0
  if (evutil_set_tcp_keepalive(fd, 1, 300) < 0)
5014
0
    goto out;
5015
0
  if (reuse) {
5016
0
    if (evutil_make_listen_socket_reuseable(fd) < 0)
5017
0
      goto out;
5018
0
  }
5019
5020
0
  if (ai != NULL) {
5021
0
    r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
5022
0
    if (r == -1)
5023
0
      goto out;
5024
0
  }
5025
5026
0
  return (fd);
5027
5028
0
 out:
5029
0
  serrno = EVUTIL_SOCKET_ERROR();
5030
0
  evutil_closesocket(fd);
5031
0
  EVUTIL_SET_SOCKET_ERROR(serrno);
5032
0
  return (-1);
5033
0
}
5034
5035
static struct evutil_addrinfo *
5036
make_addrinfo(const char *address, ev_uint16_t port)
5037
0
{
5038
0
  struct evutil_addrinfo *ai = NULL;
5039
5040
0
  struct evutil_addrinfo hints;
5041
0
  char strport[NI_MAXSERV];
5042
0
  int ai_result;
5043
5044
0
  memset(&hints, 0, sizeof(hints));
5045
0
  hints.ai_family = AF_UNSPEC;
5046
0
  hints.ai_socktype = SOCK_STREAM;
5047
  /* turn NULL hostname into INADDR_ANY, and skip looking up any address
5048
   * types we don't have an interface to connect to. */
5049
0
  hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
5050
0
  evutil_snprintf(strport, sizeof(strport), "%d", port);
5051
0
  if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
5052
0
      != 0) {
5053
0
    if (ai_result == EVUTIL_EAI_SYSTEM)
5054
0
      event_warn("getaddrinfo");
5055
0
    else
5056
0
      event_warnx("getaddrinfo: %s",
5057
0
          evutil_gai_strerror(ai_result));
5058
0
    return (NULL);
5059
0
  }
5060
5061
0
  return (ai);
5062
0
}
5063
5064
static evutil_socket_t
5065
bind_socket(const char *address, ev_uint16_t port, int reuse)
5066
0
{
5067
0
  evutil_socket_t fd;
5068
0
  struct evutil_addrinfo *aitop = NULL;
5069
5070
  /* just create an unbound socket */
5071
0
  if (address == NULL && port == 0)
5072
0
    return create_bind_socket_nonblock(NULL, 0);
5073
5074
0
  aitop = make_addrinfo(address, port);
5075
5076
0
  if (aitop == NULL)
5077
0
    return (-1);
5078
5079
0
  fd = create_bind_socket_nonblock(aitop, reuse);
5080
5081
0
  evutil_freeaddrinfo(aitop);
5082
5083
0
  return (fd);
5084
0
}
5085
5086
struct evhttp_uri {
5087
  unsigned flags;
5088
  char *scheme; /* scheme; e.g http, ftp etc */
5089
  char *userinfo; /* userinfo (typically username:pass), or NULL */
5090
  char *host; /* hostname, IP address, or NULL */
5091
  int port; /* port, or zero */
5092
#ifndef _WIN32
5093
  char *unixsocket; /* unix domain socket or NULL */
5094
#endif
5095
  char *path; /* path, or "". */
5096
  char *query; /* query, or NULL */
5097
  char *fragment; /* fragment or NULL */
5098
};
5099
5100
struct evhttp_uri *
5101
evhttp_uri_new(void)
5102
0
{
5103
0
  struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5104
0
  if (uri)
5105
0
    uri->port = -1;
5106
0
  return uri;
5107
0
}
5108
5109
void
5110
evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
5111
0
{
5112
0
  uri->flags = flags;
5113
0
}
5114
5115
/* Return true if the string starting at s and ending immediately before eos
5116
 * is a valid URI scheme according to RFC3986
5117
 */
5118
static int
5119
scheme_ok(const char *s, const char *eos)
5120
1.95k
{
5121
  /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
5122
1.95k
  EVUTIL_ASSERT(eos >= s);
5123
1.95k
  if (s == eos)
5124
102
    return 0;
5125
1.85k
  if (!EVUTIL_ISALPHA_(*s))
5126
892
    return 0;
5127
2.98M
  while (++s < eos) {
5128
2.98M
    if (! EVUTIL_ISALNUM_(*s) &&
5129
9.80k
        *s != '+' && *s != '-' && *s != '.')
5130
342
      return 0;
5131
2.98M
  }
5132
621
  return 1;
5133
963
}
5134
5135
2.99M
#define SUBDELIMS "!$&'()*+,;="
5136
5137
/* Return true iff [s..eos) is a valid userinfo */
5138
static int
5139
userinfo_ok(const char *s, const char *eos)
5140
606
{
5141
46.3M
  while (s < eos) {
5142
46.3M
    if (CHAR_IS_UNRESERVED(*s) ||
5143
2.46M
        strchr(SUBDELIMS, *s) ||
5144
74.3k
        *s == ':')
5145
46.2M
      ++s;
5146
71.5k
    else if (*s == '%' && s+2 < eos &&
5147
71.4k
        EVUTIL_ISXDIGIT_(s[1]) &&
5148
71.4k
        EVUTIL_ISXDIGIT_(s[2]))
5149
71.4k
      s += 3;
5150
80
    else
5151
80
      return 0;
5152
46.3M
  }
5153
526
  return 1;
5154
606
}
5155
5156
static int
5157
regname_ok(const char *s, const char *eos)
5158
1.01k
{
5159
13.5M
  while (s && s<eos) {
5160
13.5M
    if (CHAR_IS_UNRESERVED(*s) ||
5161
84.9k
        strchr(SUBDELIMS, *s))
5162
13.5M
      ++s;
5163
23.5k
    else if (*s == '%' &&
5164
23.3k
        EVUTIL_ISXDIGIT_(s[1]) &&
5165
23.3k
        EVUTIL_ISXDIGIT_(s[2]))
5166
23.3k
      s += 3;
5167
239
    else
5168
239
      return 0;
5169
13.5M
  }
5170
777
  return 1;
5171
1.01k
}
5172
5173
static int
5174
parse_port(const char *s, const char *eos)
5175
116
{
5176
116
  int portnum = 0;
5177
674
  while (s < eos) {
5178
570
    if (! EVUTIL_ISDIGIT_(*s))
5179
0
      return -1;
5180
570
    portnum = (portnum * 10) + (*s - '0');
5181
570
    if (portnum < 0)
5182
0
      return -1;
5183
570
    if (portnum > 65535)
5184
12
      return -1;
5185
558
    ++s;
5186
558
  }
5187
104
  return portnum;
5188
116
}
5189
5190
/* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
5191
static int
5192
bracket_addr_ok(const char *s, const char *eos)
5193
748
{
5194
748
  if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
5195
6
    return 0;
5196
742
  if (s[1] == 'v') {
5197
    /* IPvFuture, or junk.
5198
       "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
5199
     */
5200
117
    s += 2; /* skip [v */
5201
117
    --eos;
5202
117
    if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
5203
6
      return 0;
5204
495
    while (s < eos && *s != '.') {
5205
408
      if (EVUTIL_ISXDIGIT_(*s))
5206
384
        ++s;
5207
24
      else
5208
24
        return 0;
5209
408
    }
5210
87
    if (*s != '.')
5211
17
      return 0;
5212
70
    ++s;
5213
1.56k
    while (s < eos) {
5214
1.51k
      if (CHAR_IS_UNRESERVED(*s) ||
5215
358
          strchr(SUBDELIMS, *s) ||
5216
60
          *s == ':')
5217
1.49k
        ++s;
5218
20
      else
5219
20
        return 0;
5220
1.51k
    }
5221
50
    return 2;
5222
625
  } else {
5223
    /* IPv6, or junk */
5224
625
    char buf[64];
5225
625
    ev_ssize_t n_chars = eos-s-2;
5226
625
    struct in6_addr in6;
5227
625
    if (n_chars >= 64) /* way too long */
5228
42
      return 0;
5229
583
    memcpy(buf, s+1, n_chars);
5230
583
    buf[n_chars]='\0';
5231
583
    return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
5232
625
  }
5233
742
}
5234
5235
static int
5236
parse_authority(struct evhttp_uri *uri, char *s, char *eos, unsigned *flags)
5237
1.87k
{
5238
1.87k
  size_t len;
5239
1.87k
  char *cp, *port;
5240
5241
1.87k
  EVUTIL_ASSERT(eos);
5242
1.87k
  if (eos == s) {
5243
18
    uri->host = mm_strdup("");
5244
18
    if (uri->host == NULL) {
5245
0
      event_warn("%s: strdup", __func__);
5246
0
      return -1;
5247
0
    }
5248
18
    return 0;
5249
18
  }
5250
5251
  /* Optionally, we start with "userinfo@" */
5252
5253
1.85k
  cp = strchr(s, '@');
5254
1.85k
  if (cp && cp < eos) {
5255
606
    if (! userinfo_ok(s,cp))
5256
80
      return -1;
5257
526
    *cp++ = '\0';
5258
526
    uri->userinfo = mm_strdup(s);
5259
526
    if (uri->userinfo == NULL) {
5260
0
      event_warn("%s: strdup", __func__);
5261
0
      return -1;
5262
0
    }
5263
1.25k
  } else {
5264
1.25k
    cp = s;
5265
1.25k
  }
5266
5267
1.77k
#ifndef _WIN32
5268
1.77k
  if (*flags & EVHTTP_URI_UNIX_SOCKET && !strncmp(cp, "unix:", 5)) {
5269
0
    char *e = strchr(cp + 5, ':');
5270
0
    if (e) {
5271
0
      *e = '\0';
5272
0
      uri->unixsocket = mm_strdup(cp + 5);
5273
0
      return 0;
5274
0
    } else {
5275
0
      return -1;
5276
0
    }
5277
0
  }
5278
1.77k
#endif
5279
5280
  /* Optionally, we end with ":port" */
5281
2.82k
  for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
5282
1.05k
    ;
5283
1.77k
  if (port >= cp && *port == ':') {
5284
153
    if (port+1 == eos) /* Leave port unspecified; the RFC allows a
5285
            * nil port */
5286
37
      uri->port = -1;
5287
116
    else if ((uri->port = parse_port(port+1, eos))<0)
5288
12
      return -1;
5289
141
    eos = port;
5290
141
  }
5291
  /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
5292
   * an IP-Literal, or a reg-name */
5293
1.76k
  EVUTIL_ASSERT(eos >= cp);
5294
1.76k
  len = eos-cp;
5295
1.76k
  if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
5296
    /* IPv6address, IP-Literal, or junk. */
5297
748
    if (! bracket_addr_ok(cp, eos))
5298
669
      return -1;
5299
79
    if (*flags & EVHTTP_URI_HOST_STRIP_BRACKETS)
5300
0
      len = eos-cp-2;
5301
1.01k
  } else {
5302
    /* Make sure the host part is ok. */
5303
1.01k
    if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
5304
239
      return -1;
5305
1.01k
  }
5306
5307
856
  uri->host = mm_malloc(len+1);
5308
856
  if (uri->host == NULL) {
5309
0
    event_warn("%s: malloc", __func__);
5310
0
    return -1;
5311
0
  }
5312
856
  if (*cp == '[' && *flags & EVHTTP_URI_HOST_STRIP_BRACKETS) {
5313
0
    memcpy(uri->host, cp+1, len);
5314
0
    *flags |= _EVHTTP_URI_HOST_HAS_BRACKETS;
5315
856
  } else {
5316
856
    memcpy(uri->host, cp, len);
5317
856
  }
5318
856
  uri->host[len] = '\0';
5319
856
  return 0;
5320
5321
856
}
5322
5323
static char *
5324
end_of_authority(char *cp)
5325
1.87k
{
5326
78.2M
  while (*cp) {
5327
78.2M
    if (*cp == '?' || *cp == '#' || *cp == '/')
5328
324
      return cp;
5329
78.2M
    ++cp;
5330
78.2M
  }
5331
1.55k
  return cp;
5332
1.87k
}
5333
5334
enum uri_part {
5335
  PART_PATH,
5336
  PART_QUERY,
5337
  PART_FRAGMENT
5338
};
5339
5340
/* Return the character after the longest prefix of 'cp' that matches...
5341
 *   *pchar / "/" if allow_qchars is false, or
5342
 *   *(pchar / "/" / "?") if allow_qchars is true.
5343
 */
5344
static char *
5345
end_of_path(char *cp, enum uri_part part, unsigned flags)
5346
7.19k
{
5347
7.19k
  if (flags & EVHTTP_URI_NONCONFORMANT) {
5348
    /* If NONCONFORMANT:
5349
     *   Path is everything up to a # or ? or nul.
5350
     *   Query is everything up a # or nul
5351
     *   Fragment is everything up to a nul.
5352
     */
5353
2.28k
    switch (part) {
5354
2.24k
    case PART_PATH:
5355
15.2k
      while (*cp && *cp != '#' && *cp != '?')
5356
12.9k
        ++cp;
5357
2.24k
      break;
5358
28
    case PART_QUERY:
5359
1.00k
      while (*cp && *cp != '#')
5360
973
        ++cp;
5361
28
      break;
5362
6
    case PART_FRAGMENT:
5363
6
      cp += strlen(cp);
5364
6
      break;
5365
2.28k
    };
5366
2.28k
    return cp;
5367
2.28k
  }
5368
5369
6.14M
  while (*cp) {
5370
6.14M
    if (CHAR_IS_UNRESERVED(*cp) ||
5371
440k
        strchr(SUBDELIMS, *cp) ||
5372
43.9k
        *cp == ':' || *cp == '@' || *cp == '/')
5373
6.11M
      ++cp;
5374
32.9k
    else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
5375
7.84k
        EVUTIL_ISXDIGIT_(cp[2]))
5376
7.80k
      cp += 3;
5377
25.1k
    else if (*cp == '?' && part != PART_PATH)
5378
21.7k
      ++cp;
5379
3.43k
    else
5380
3.43k
      return cp;
5381
6.14M
  }
5382
1.48k
  return cp;
5383
4.91k
}
5384
5385
static int
5386
path_matches_noscheme(const char *cp)
5387
3.29k
{
5388
2.33M
  while (*cp) {
5389
2.33M
    if (*cp == ':')
5390
28
      return 0;
5391
2.33M
    else if (*cp == '/')
5392
2.08k
      return 1;
5393
2.33M
    ++cp;
5394
2.33M
  }
5395
1.17k
  return 1;
5396
3.29k
}
5397
5398
struct evhttp_uri *
5399
evhttp_uri_parse(const char *source_uri)
5400
5.14k
{
5401
5.14k
  return evhttp_uri_parse_with_flags(source_uri, 0);
5402
5.14k
}
5403
5404
struct evhttp_uri *
5405
evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
5406
7.42k
{
5407
7.42k
  char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
5408
7.42k
  char *path = NULL, *fragment = NULL;
5409
7.42k
  int got_authority = 0;
5410
5411
7.42k
  struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5412
7.42k
  if (uri == NULL) {
5413
0
    event_warn("%s: calloc", __func__);
5414
0
    goto err;
5415
0
  }
5416
7.42k
  uri->port = -1;
5417
7.42k
  uri->flags = flags;
5418
5419
7.42k
  readbuf = mm_strdup(source_uri);
5420
7.42k
  if (readbuf == NULL) {
5421
0
    event_warn("%s: strdup", __func__);
5422
0
    goto err;
5423
0
  }
5424
5425
7.42k
  readp = readbuf;
5426
7.42k
  token = NULL;
5427
5428
  /* We try to follow RFC3986 here as much as we can, and match
5429
     the productions
5430
5431
        URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
5432
5433
        relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
5434
   */
5435
5436
  /* 1. scheme: */
5437
7.42k
  token = strchr(readp, ':');
5438
7.42k
  if (token && scheme_ok(readp,token)) {
5439
621
    *token = '\0';
5440
621
    uri->scheme = mm_strdup(readp);
5441
621
    if (uri->scheme == NULL) {
5442
0
      event_warn("%s: strdup", __func__);
5443
0
      goto err;
5444
0
    }
5445
621
    readp = token+1; /* eat : */
5446
621
  }
5447
5448
  /* 2. Optionally, "//" then an 'authority' part. */
5449
7.42k
  if (readp[0]=='/' && readp[1] == '/') {
5450
1.86k
    char *authority;
5451
1.86k
    readp += 2;
5452
1.86k
    authority = readp;
5453
1.86k
    path = end_of_authority(readp);
5454
1.86k
    if (parse_authority(uri, authority, path, &uri->flags) < 0)
5455
993
      goto err;
5456
872
    readp = path;
5457
872
    got_authority = 1;
5458
872
  }
5459
5460
  /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
5461
   */
5462
6.43k
  path = readp;
5463
6.43k
  readp = end_of_path(path, PART_PATH, flags);
5464
5465
  /* Query */
5466
6.43k
  if (*readp == '?') {
5467
492
    *readp = '\0';
5468
492
    ++readp;
5469
492
    query = readp;
5470
492
    readp = end_of_path(readp, PART_QUERY, flags);
5471
492
  }
5472
  /* fragment */
5473
6.43k
  if (*readp == '#') {
5474
272
    *readp = '\0';
5475
272
    ++readp;
5476
272
    fragment = readp;
5477
272
    readp = end_of_path(readp, PART_FRAGMENT, flags);
5478
272
  }
5479
6.43k
  if (*readp != '\0') {
5480
2.70k
    goto err;
5481
2.70k
  }
5482
5483
  /* These next two cases may be unreachable; I'm leaving them
5484
   * in to be defensive. */
5485
  /* If you didn't get an authority, the path can't begin with "//" */
5486
3.72k
  if (!got_authority && path[0]=='/' && path[1]=='/')
5487
0
    goto err;
5488
  /* If you did get an authority, the path must begin with "/" or be
5489
   * empty. */
5490
3.72k
  if (got_authority && path[0] != '/' && path[0] != '\0')
5491
0
    goto err;
5492
  /* (End of maybe-unreachable cases) */
5493
5494
  /* If there was no scheme, the first part of the path (if any) must
5495
   * have no colon in it. */
5496
3.72k
  if (! uri->scheme && !path_matches_noscheme(path))
5497
28
    goto err;
5498
5499
3.70k
  EVUTIL_ASSERT(path);
5500
3.70k
  uri->path = mm_strdup(path);
5501
3.70k
  if (uri->path == NULL) {
5502
0
    event_warn("%s: strdup", __func__);
5503
0
    goto err;
5504
0
  }
5505
5506
3.70k
  if (query) {
5507
322
    uri->query = mm_strdup(query);
5508
322
    if (uri->query == NULL) {
5509
0
      event_warn("%s: strdup", __func__);
5510
0
      goto err;
5511
0
    }
5512
322
  }
5513
3.70k
  if (fragment) {
5514
163
    uri->fragment = mm_strdup(fragment);
5515
163
    if (uri->fragment == NULL) {
5516
0
      event_warn("%s: strdup", __func__);
5517
0
      goto err;
5518
0
    }
5519
163
  }
5520
5521
3.70k
  mm_free(readbuf);
5522
5523
3.70k
  return uri;
5524
3.72k
err:
5525
3.72k
  if (uri)
5526
3.72k
    evhttp_uri_free(uri);
5527
3.72k
  if (readbuf)
5528
3.72k
    mm_free(readbuf);
5529
3.72k
  return NULL;
5530
3.70k
}
5531
5532
static struct evhttp_uri *
5533
evhttp_uri_parse_authority(char *source_uri, unsigned flags)
5534
9
{
5535
9
  struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5536
9
  char *end;
5537
5538
9
  if (uri == NULL) {
5539
0
    event_warn("%s: calloc", __func__);
5540
0
    goto err;
5541
0
  }
5542
9
  uri->port = -1;
5543
9
  uri->flags = flags;
5544
5545
9
  end = end_of_authority(source_uri);
5546
9
  if (parse_authority(uri, source_uri, end, &uri->flags) < 0)
5547
7
    goto err;
5548
5549
2
  uri->path = mm_strdup("");
5550
2
  if (uri->path == NULL) {
5551
0
    event_warn("%s: strdup", __func__);
5552
0
    goto err;
5553
0
  }
5554
5555
2
  return uri;
5556
7
err:
5557
7
  if (uri)
5558
7
    evhttp_uri_free(uri);
5559
7
  return NULL;
5560
2
}
5561
5562
void
5563
evhttp_uri_free(struct evhttp_uri *uri)
5564
7.43k
{
5565
7.43k
#define URI_FREE_STR_(f)    \
5566
52.0k
  if (uri->f) {     \
5567
6.20k
    mm_free(uri->f);   \
5568
6.20k
  }
5569
5570
7.43k
  URI_FREE_STR_(scheme);
5571
7.43k
  URI_FREE_STR_(userinfo);
5572
7.43k
  URI_FREE_STR_(host);
5573
7.43k
#ifndef _WIN32
5574
7.43k
  URI_FREE_STR_(unixsocket);
5575
7.43k
#endif
5576
7.43k
  URI_FREE_STR_(path);
5577
7.43k
  URI_FREE_STR_(query);
5578
7.43k
  URI_FREE_STR_(fragment);
5579
5580
7.43k
  mm_free(uri);
5581
7.43k
#undef URI_FREE_STR_
5582
7.43k
}
5583
5584
char *
5585
evhttp_uri_join(const struct evhttp_uri *uri, char *buf, size_t limit)
5586
762
{
5587
762
  struct evbuffer *tmp = 0;
5588
762
  size_t joined_size = 0;
5589
762
  char *output = NULL;
5590
5591
1.64k
#define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5592
5593
762
  if (!uri || !buf || !limit)
5594
0
    return NULL;
5595
5596
762
  tmp = evbuffer_new();
5597
762
  if (!tmp)
5598
0
    return NULL;
5599
5600
762
  if (uri->scheme) {
5601
221
    URI_ADD_(scheme);
5602
221
    evbuffer_add(tmp, ":", 1);
5603
221
  }
5604
762
#ifndef _WIN32
5605
762
  if (uri->unixsocket) {
5606
0
    evbuffer_add(tmp, "//", 2);
5607
0
    if (uri->userinfo)
5608
0
      evbuffer_add_printf(tmp, "%s@", uri->userinfo);
5609
0
    evbuffer_add_printf(tmp, "unix:%s:", uri->unixsocket);
5610
0
  }
5611
762
  else
5612
762
#endif
5613
762
  if (uri->host) {
5614
436
    evbuffer_add(tmp, "//", 2);
5615
436
    if (uri->userinfo)
5616
273
      evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5617
436
    if (uri->flags & _EVHTTP_URI_HOST_HAS_BRACKETS) {
5618
0
      evbuffer_add(tmp, "[", 1);
5619
0
      URI_ADD_(host);
5620
0
      evbuffer_add(tmp, "]", 1);
5621
436
    } else {
5622
436
      URI_ADD_(host);
5623
436
    }
5624
436
    if (uri->port >= 0)
5625
66
      evbuffer_add_printf(tmp,":%d", uri->port);
5626
5627
436
    if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5628
0
      goto err;
5629
436
  }
5630
5631
762
  if (uri->path)
5632
762
    URI_ADD_(path);
5633
5634
762
  if (uri->query) {
5635
143
    evbuffer_add(tmp, "?", 1);
5636
143
    URI_ADD_(query);
5637
143
  }
5638
5639
762
  if (uri->fragment) {
5640
79
    evbuffer_add(tmp, "#", 1);
5641
79
    URI_ADD_(fragment);
5642
79
  }
5643
5644
762
  evbuffer_add(tmp, "\0", 1); /* NUL */
5645
5646
762
  joined_size = evbuffer_get_length(tmp);
5647
5648
762
  if (joined_size > limit) {
5649
    /* It doesn't fit. */
5650
328
    evbuffer_free(tmp);
5651
328
    return NULL;
5652
328
  }
5653
434
  evbuffer_remove(tmp, buf, joined_size);
5654
5655
434
  output = buf;
5656
434
err:
5657
434
  evbuffer_free(tmp);
5658
5659
434
  return output;
5660
434
#undef URI_ADD_
5661
434
}
5662
5663
const char *
5664
evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5665
45
{
5666
45
  return uri->scheme;
5667
45
}
5668
const char *
5669
evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5670
45
{
5671
45
  return uri->userinfo;
5672
45
}
5673
const char *
5674
evhttp_uri_get_host(const struct evhttp_uri *uri)
5675
178
{
5676
178
  return uri->host;
5677
178
}
5678
#ifndef _WIN32
5679
const char *
5680
evhttp_uri_get_unixsocket(const struct evhttp_uri *uri)
5681
0
{
5682
0
  return uri->unixsocket;
5683
0
}
5684
#endif
5685
int
5686
evhttp_uri_get_port(const struct evhttp_uri *uri)
5687
45
{
5688
45
  return uri->port;
5689
45
}
5690
const char *
5691
evhttp_uri_get_path(const struct evhttp_uri *uri)
5692
45
{
5693
45
  return uri->path;
5694
45
}
5695
const char *
5696
evhttp_uri_get_query(const struct evhttp_uri *uri)
5697
742
{
5698
742
  return uri->query;
5699
742
}
5700
const char *
5701
evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5702
45
{
5703
45
  return uri->fragment;
5704
45
}
5705
5706
0
#define URI_SET_STR_(f) do {         \
5707
0
  if (uri->f)           \
5708
0
    mm_free(uri->f);       \
5709
0
  if (f) {           \
5710
0
    if ((uri->f = mm_strdup(f)) == NULL) {   \
5711
0
      event_warn("%s: strdup()", __func__);  \
5712
0
      return -1;        \
5713
0
    }           \
5714
0
  } else {           \
5715
0
    uri->f = NULL;          \
5716
0
  }              \
5717
0
  } while(0)
5718
5719
int
5720
evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5721
0
{
5722
0
  if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5723
0
    return -1;
5724
5725
0
  URI_SET_STR_(scheme);
5726
0
  return 0;
5727
0
}
5728
int
5729
evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5730
0
{
5731
0
  if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5732
0
    return -1;
5733
0
  URI_SET_STR_(userinfo);
5734
0
  return 0;
5735
0
}
5736
int
5737
evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5738
0
{
5739
0
  size_t len = 0;
5740
5741
0
  if (host) {
5742
0
    len = strlen(host);
5743
5744
0
    if (host[0] == '[') {
5745
0
      if (! bracket_addr_ok(host, host+len))
5746
0
        return -1;
5747
0
    } else {
5748
0
      if (! regname_ok(host, host+len))
5749
0
        return -1;
5750
0
    }
5751
0
  }
5752
5753
0
  if (host && host[0] == '[' && uri->flags & EVHTTP_URI_HOST_STRIP_BRACKETS) {
5754
0
    char *new_host;
5755
5756
0
    len -= 2;
5757
0
    new_host = mm_realloc(uri->host, len+1);
5758
0
    if (!new_host) {
5759
0
      free(uri->host);
5760
0
      uri->host = NULL;
5761
0
    } else {
5762
0
      memcpy(new_host, host+1, len);
5763
0
      new_host[len] = '\0';
5764
0
      uri->host = new_host;
5765
0
    }
5766
0
    uri->flags |= _EVHTTP_URI_HOST_HAS_BRACKETS;
5767
0
  } else {
5768
0
    URI_SET_STR_(host);
5769
0
    uri->flags &= ~_EVHTTP_URI_HOST_HAS_BRACKETS;
5770
0
  }
5771
5772
0
  return 0;
5773
0
}
5774
#ifndef _WIN32
5775
int
5776
evhttp_uri_set_unixsocket(struct evhttp_uri *uri, const char *unixsocket)
5777
0
{
5778
0
  URI_SET_STR_(unixsocket);
5779
0
  return 0;
5780
0
}
5781
#endif
5782
int
5783
evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5784
0
{
5785
0
  if (port < -1)
5786
0
    return -1;
5787
0
  uri->port = port;
5788
0
  return 0;
5789
0
}
5790
#define end_of_cpath(cp,p,f) \
5791
0
  ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5792
5793
int
5794
evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5795
0
{
5796
0
  if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5797
0
    return -1;
5798
5799
0
  URI_SET_STR_(path);
5800
0
  return 0;
5801
0
}
5802
int
5803
evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5804
0
{
5805
0
  if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5806
0
    return -1;
5807
0
  URI_SET_STR_(query);
5808
0
  return 0;
5809
0
}
5810
int
5811
evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5812
0
{
5813
0
  if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5814
0
    return -1;
5815
0
  URI_SET_STR_(fragment);
5816
0
  return 0;
5817
0
}