Coverage Report

Created: 2025-07-11 06:22

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