Apache2
http_protocol.h
Go to the documentation of this file.
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements. See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
26 #ifndef APACHE_HTTP_PROTOCOL_H
27 #define APACHE_HTTP_PROTOCOL_H
28 
29 #include "httpd.h"
30 #include "apr_portable.h"
31 #include "apr_mmap.h"
32 #include "apr_buckets.h"
33 #include "util_filter.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
45 
46 
50 
51 /*
52  * Prototypes for routines which either talk directly back to the user,
53  * or control the ones that eventually do.
54  */
55 
62 
69 
80  const char *method, const char *uri,
81  const char *protocol);
82 
93  request_rec *r, const char *line,
94  const char **pmethod, const char **puri, const char **pprotocol);
95 
102 
109 
115 
124 
131 
132 /* Finish up stuff after a request */
133 
140 
150 AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error);
151 
152 /* Set last modified header line from the lastmod date of the associated file.
153  * Also, set content length.
154  *
155  * May return an error status, typically HTTP_NOT_MODIFIED (that when the
156  * permit_cache argument is set to one).
157  */
158 
165 
172 
181 
194  const char *type);
195 
201 
203 typedef struct etag_rec etag_rec;
204 
208 struct etag_rec {
210  const char *vlist_validator;
216  const char *pathname;
221 };
222 
231 AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak);
232 
240 
246 
253 
259 
260 typedef enum {
266 
277 
289 
301 
313 
325 
335 
336 /* Other ways to send stuff at the client. All of these keep track
337  * of bytes_sent automatically. This indirection is intended to make
338  * it a little more painless to slide things like HTTP-NG packetization
339  * underneath the main body of the code later. In the meantime, it lets
340  * us centralize a bit of accounting (bytes_sent).
341  *
342  * These also return the number of bytes written by the call.
343  * They should only be called with a timeout registered, for obvious reaasons.
344  * (Ditto the send_header stuff).
345  */
346 
357  apr_size_t length, apr_size_t *nbytes);
358 
359 #if APR_HAS_MMAP
369  request_rec *r,
370  apr_size_t offset,
371  apr_size_t length);
372 #endif
373 
374 
383 AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname);
384 
391 
396 #define AP_METHOD_CHECK_ALLOWED(mask, methname) \
397  ((mask) & (AP_METHOD_BIT << ap_method_number_of((methname))))
398 
409 
410 
419 
428 AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method);
429 
438 AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method);
439 
448  const char *method);
449 
457 
465 AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct);
466 
472 
473 
474 /* Hmmm... could macrofy these for now, and maybe forever, though the
475  * definitions of the macros would get a whole lot hairier.
476  */
477 
485 
493 AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r);
494 
502 static APR_INLINE int ap_rputs(const char *str, request_rec *r)
503 {
504  apr_size_t len;
505 
506  len = strlen(str);
507 
508  for (;;) {
509  if (len <= INT_MAX) {
510  return ap_rwrite(str, (int)len, r);
511  }
512  else {
513  int rc;
514 
515  rc = ap_rwrite(str, INT_MAX, r);
516  if (rc < 0) {
517  return rc;
518  }
519  else {
520  str += INT_MAX;
521  len -= INT_MAX;
522  }
523  }
524  }
525 }
526 
535 
543 AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list vlist);
544 
552 AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt,...)
553  __attribute__((format(printf,2,3)));
554 
561 
569 
578 
589 
590 /* Reading a block of data from the client connection (e.g., POST arg) */
591 
604 
614 
624 AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz);
625 
642 
654 
661 
666 
671 
679 AP_DECLARE_HOOK(int, note_auth_failure, (request_rec *r, const char *auth_type))
680 
705 
706 #define AP_GET_BASIC_AUTH_PW_NOTE "AP_GET_BASIC_AUTH_PW_NOTE"
707 
722  const char **username,
723  const char **password);
724 
735 
736 #define AP_GETLINE_FOLD (1 << 0) /* Whether to merge continuation lines */
737 #define AP_GETLINE_CRLF (1 << 1) /* Whether line ends must be CRLF */
738 #define AP_GETLINE_NOSPC_EOL (1 << 2) /* Whether to consume up to and including
739  the end of line on APR_ENOSPC */
740 #define AP_GETLINE_NONBLOCK (1 << 3) /* Whether to read non-blocking */
741 
752 AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags);
753 
771  apr_size_t *read, ap_filter_t *f,
773  apr_pool_t *p);
774 
782  apr_size_t *read, request_rec *r,
783  int flags, apr_bucket_brigade *bb);
784 
791 AP_DECLARE(int) ap_method_number_of(const char *method);
792 
800 AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum);
801 
802 
803 /* Hooks */
804 /*
805  * pre_read_request --- run right before read_request_line(),
806  * and not run during any subrequests.
807  */
816 
817 /*
818  * post_read_request --- run right after read_request or internal_redirect,
819  * and not run during any subrequests.
820  */
829 
830 
837 
838 
844 AP_DECLARE_HOOK(const char *,http_scheme,(const request_rec *r))
845 
846 
852 
853 
854 #define AP_PROTOCOL_HTTP1 "http/1.1"
855 
891  server_rec *s,
892  const apr_array_header_t *offers,
893  apr_array_header_t *proposals))
894 
895 
920  const char *protocol))
921 
922 
933 AP_DECLARE_HOOK(const char *,protocol_get,(const conn_rec *c))
934 
935 
952  server_rec *s, int report_all,
953  const apr_array_header_t **pupgrades);
954 
971  server_rec *s,
972  const apr_array_header_t *choices);
973 
989  server_rec *s,
990  const char *protocol);
991 
1003 AP_DECLARE(const char *) ap_get_protocol(conn_rec *c);
1004 
1020  server_rec *s, const char *protocol);
1021 
1023 typedef struct ap_bucket_error ap_bucket_error;
1024 
1034 struct ap_bucket_error {
1038  int status;
1040  const char *data;
1041 };
1042 
1045 
1051 #define AP_BUCKET_IS_ERROR(e) (e->type == &ap_bucket_type_error)
1052 
1062  const char *buf, apr_pool_t *p);
1063 
1072 AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf,
1073  apr_pool_t *p,
1074  apr_bucket_alloc_t *list);
1075 
1077 typedef struct ap_bucket_request ap_bucket_request;
1078 
1084 struct ap_bucket_request {
1087  apr_pool_t *pool; /* pool that holds the contents, not for modification */
1088  const char *method; /* request method */
1089  const char *uri; /* request uri */
1090  const char *protocol; /* request protocol */
1091  apr_table_t *headers; /* request headers */
1092 };
1093 
1096 
1102 #define AP_BUCKET_IS_REQUEST(e) (e->type == &ap_bucket_type_request)
1103 
1116  apr_bucket *b,
1117  const char *method,
1118  const char *uri,
1119  const char *protocol,
1121  apr_pool_t *p);
1122 
1135  apr_bucket *b,
1136  const char *method,
1137  const char *uri,
1138  const char *protocol,
1140  apr_pool_t *p);
1141 
1154  const char *method,
1155  const char *uri,
1156  const char *protocol,
1158  apr_pool_t *p,
1159  apr_bucket_alloc_t *list);
1160 
1173  const char *method,
1174  const char *uri,
1175  const char *protocol,
1177  apr_pool_t *p,
1178  apr_bucket_alloc_t *list);
1179 
1189  apr_pool_t *p,
1190  apr_bucket_alloc_t *list);
1191 
1193 typedef struct ap_bucket_response ap_bucket_response;
1194 
1200 struct ap_bucket_response {
1203  apr_pool_t *pool; /* pool that holds the contents, not for modification */
1204  int status; /* The status code */
1205  const char *reason; /* The optional HTTP reason for the status. */
1206  apr_table_t *headers; /* The response headers */
1207  apr_table_t *notes; /* internal notes about the response */
1208 };
1209 
1212 
1218 #define AP_BUCKET_IS_RESPONSE(e) (e->type == &ap_bucket_type_response)
1219 
1231  const char *reason, apr_table_t *headers,
1232  apr_table_t *notes, apr_pool_t *p);
1233 
1245  int status, const char *reason,
1247  apr_table_t *notes,
1248  apr_pool_t *p,
1249  apr_bucket_alloc_t *list);
1250 
1260  apr_pool_t *p,
1261  apr_bucket_alloc_t *list);
1262 
1264 typedef struct ap_bucket_headers ap_bucket_headers;
1265 
1271 struct ap_bucket_headers {
1274  apr_pool_t *pool; /* pool that holds the contents, not for modification */
1275  apr_table_t *headers; /* The headers */
1276 
1277 };
1278 
1281 
1287 #define AP_BUCKET_IS_HEADERS(e) (e->type == &ap_bucket_type_headers)
1288 
1298 
1307  apr_pool_t *p,
1308  apr_bucket_alloc_t *list);
1309 
1319  apr_pool_t *p,
1320  apr_bucket_alloc_t *list);
1327 
1334 
1341 
1348 
1354 AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
1355 
1364  apr_pool_t *pool,
1365  const char *name, const char *value);
1373  request_rec *r,
1374  apr_table_t *headers);
1375 
1381 
1390  apr_bucket *eos,
1391  request_rec *r,
1392  apr_table_t *trailers);
1393 
1394 #ifdef __cplusplus
1395 }
1396 #endif
1397 
1398 #endif /* !APACHE_HTTP_PROTOCOL_H */
#define AP_FN_ATTR_SENTINEL
Definition: ap_config.h:231
#define AP_DECLARE_HOOK(ret, name, args)
Definition: ap_hooks.h:74
APR-UTIL Buckets/Bucket Brigades.
APR MMAP routines.
APR Portability Routines.
int int ap_rflush(request_rec *r)
int ap_method_number_of(const char *method)
int ap_parse_request_line(request_rec *r)
ap_condition_e
Definition: http_protocol.h:260
int protocol_switch(conn_rec *c, request_rec *r, server_rec *s, const char *protocol)
void ap_set_etag(request_rec *r)
void ap_method_registry_init(apr_pool_t *p)
request_rec * ap_create_request(conn_rec *c)
void ap_finalize_sub_req_protocol(request_rec *sub_r)
void ap_setup_make_content_type(apr_pool_t *pool)
AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_response
apr_status_t ap_rgetline(char **s, apr_size_t n, apr_size_t *read, request_rec *r, int flags, apr_bucket_brigade *bb)
const char * http_scheme(const request_rec *r)
void ap_set_accept_ranges(request_rec *r)
apr_status_t ap_get_protocol_upgrades(conn_rec *c, request_rec *r, server_rec *s, int report_all, const apr_array_header_t **pupgrades)
ap_method_list_t * ap_make_method_list(apr_pool_t *p, int nelts)
apr_bucket * ap_bucket_request_make(apr_bucket *b, const char *method, const char *uri, const char *protocol, apr_table_t *headers, apr_pool_t *p)
int ap_map_http_request_error(apr_status_t rv, int status)
int ap_meets_conditions(request_rec *r)
ap_condition_e ap_condition_if_modified_since(request_rec *r, apr_table_t *headers)
const char * ap_get_status_line(int status)
int ap_method_register(apr_pool_t *p, const char *methname)
apr_status_t ap_h1_append_headers(apr_bucket_brigade *b, request_rec *r, apr_table_t *headers)
void ap_method_list_remove(ap_method_list_t *l, const char *method)
apr_bucket * ap_bucket_request_clone(apr_bucket *source, apr_pool_t *p, apr_bucket_alloc_t *list)
const char * ap_get_protocol(conn_rec *c)
int ap_h1_tokenize_request_line(request_rec *r, const char *line, const char **pmethod, const char **puri, const char **pprotocol)
void ap_set_etag_fd(request_rec *r, apr_file_t *fd)
void ap_method_list_add(ap_method_list_t *l, const char *method)
const char * protocol_get(const conn_rec *c)
void ap_send_interim_response(request_rec *r, int send_headers)
void ap_parse_uri(request_rec *r, const char *uri)
apr_time_t ap_rationalize_mtime(request_rec *r, apr_time_t mtime)
void ap_note_digest_auth_failure(request_rec *r)
int note_auth_failure(request_rec *r, const char *auth_type)
void ap_send_error_response(request_rec *r, int recursive_error)
void ap_finalize_request_protocol(request_rec *r)
void ap_note_auth_failure(request_rec *r)
AP_DECLARE_DATA ap_filter_rec_t * ap_old_write_func
int ap_get_basic_auth_pw(request_rec *r, const char **pw)
apr_status_t ap_h1_append_header(apr_bucket_brigade *b, apr_pool_t *pool, const char *name, const char *value)
void ap_note_basic_auth_failure(request_rec *r)
apr_status_t ap_http_header_filter(ap_filter_t *f, apr_bucket_brigade *b)
int ap_set_keepalive(request_rec *r)
void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
ap_condition_e ap_condition_if_range(request_rec *r, apr_table_t *headers)
int ap_rprintf(request_rec *r, const char *fmt,...) __attribute__((format(printf
ap_condition_e ap_condition_if_unmodified_since(request_rec *r, apr_table_t *headers)
const char * ap_make_content_type(request_rec *r, const char *type)
char * ap_make_etag(request_rec *r, int force_weak)
int ap_should_client_block(request_rec *r)
apr_status_t ap_get_basic_auth_components(const request_rec *r, const char **username, const char **password)
int ap_index_of_response(int status)
int ap_post_read_request(request_rec *r)
int protocol_propose(conn_rec *c, request_rec *r, server_rec *s, const apr_array_header_t *offers, apr_array_header_t *proposals)
apr_bucket * ap_bucket_response_create(int status, const char *reason, apr_table_t *headers, apr_table_t *notes, apr_pool_t *p, apr_bucket_alloc_t *list)
void ap_set_content_length(request_rec *r, apr_off_t length)
apr_status_t ap_switch_protocol(conn_rec *c, request_rec *r, server_rec *s, const char *protocol)
int log_transaction(request_rec *r)
apr_bucket * ap_bucket_request_maken(apr_bucket *b, const char *method, const char *uri, const char *protocol, apr_table_t *headers, apr_pool_t *p)
int ap_method_in_list(ap_method_list_t *l, const char *method)
const char * ap_method_name_of(apr_pool_t *p, int methnum)
int ap_rputc(int c, request_rec *r)
void ap_set_last_modified(request_rec *r)
apr_bucket * ap_bucket_headers_make(apr_bucket *b, apr_table_t *headers, apr_pool_t *p)
const char * ap_get_status_line_ex(apr_pool_t *p, int status)
int ap_assign_request_line(request_rec *r, const char *method, const char *uri, const char *protocol)
void ap_clear_method_list(ap_method_list_t *l)
apr_bucket * ap_bucket_response_make(apr_bucket *b, int status, const char *reason, apr_table_t *headers, apr_table_t *notes, apr_pool_t *p)
void ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb)
void ap_set_content_type(request_rec *r, const char *ct)
apr_status_t ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *b)
int ap_check_request_header(request_rec *r)
int ap_getline(char *s, int n, request_rec *r, int flags)
apr_bucket * ap_bucket_error_make(apr_bucket *b, int error, const char *buf, apr_pool_t *p)
AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_request
apr_bucket * ap_bucket_request_createn(const char *method, const char *uri, const char *protocol, apr_table_t *headers, apr_pool_t *p, apr_bucket_alloc_t *list)
void ap_copy_method_list(ap_method_list_t *dest, ap_method_list_t *src)
ap_condition_e ap_condition_if_match(request_rec *r, apr_table_t *headers)
ap_condition_e ap_condition_if_none_match(request_rec *r, apr_table_t *headers)
const char * ap_select_protocol(conn_rec *c, request_rec *r, server_rec *s, const apr_array_header_t *choices)
void ap_set_std_response_headers(request_rec *r)
apr_status_t ap_content_length_filter(ap_filter_t *, apr_bucket_brigade *)
apr_size_t ap_send_mmap(apr_mmap_t *mm, request_rec *r, apr_size_t offset, apr_size_t length)
int ap_rvputs(request_rec *r,...) AP_FN_ATTR_SENTINEL
apr_status_t ap_fgetline(char **s, apr_size_t n, apr_size_t *read, ap_filter_t *f, int flags, apr_bucket_brigade *bb, apr_pool_t *p)
void pre_read_request(request_rec *r, conn_rec *c)
request_rec * ap_read_request(conn_rec *c)
apr_bucket * ap_bucket_headers_clone(apr_bucket *source, apr_pool_t *p, apr_bucket_alloc_t *list)
apr_bucket * ap_bucket_headers_create(apr_table_t *headers, apr_pool_t *p, apr_bucket_alloc_t *list)
int ap_rwrite(const void *buf, int nbyte, request_rec *r)
void ap_h1_add_end_chunk(apr_bucket_brigade *b, apr_bucket *eos, request_rec *r, apr_table_t *trailers)
apr_bucket * ap_bucket_error_create(int error, const char *buf, apr_pool_t *p, apr_bucket_alloc_t *list)
long ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz)
int ap_setup_client_block(request_rec *r, int read_policy)
apr_port_t default_port(const request_rec *r)
int post_read_request(request_rec *r)
int ap_is_allowed_protocol(conn_rec *c, request_rec *r, server_rec *s, const char *protocol)
int ap_discard_request_body(request_rec *r)
AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_headers
apr_status_t ap_h1_terminate_header(apr_bucket_brigade *b)
int ap_vrprintf(request_rec *r, const char *fmt, va_list vlist)
apr_bucket * ap_bucket_request_create(const char *method, const char *uri, const char *protocol, apr_table_t *headers, apr_pool_t *p, apr_bucket_alloc_t *list)
apr_status_t ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t offset, apr_size_t length, apr_size_t *nbytes)
AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_error
apr_status_t ap_old_write_filter(ap_filter_t *f, apr_bucket_brigade *b)
void ap_get_mime_headers(request_rec *r)
char * ap_make_etag_ex(request_rec *r, etag_rec *er)
apr_bucket * ap_bucket_response_clone(apr_bucket *source, apr_pool_t *p, apr_bucket_alloc_t *list)
@ AP_CONDITION_NONE
Definition: http_protocol.h:261
@ AP_CONDITION_STRONG
Definition: http_protocol.h:264
@ AP_CONDITION_WEAK
Definition: http_protocol.h:263
@ AP_CONDITION_NOMATCH
Definition: http_protocol.h:262
struct apr_bucket_alloc_t apr_bucket_alloc_t
Definition: apr_buckets.h:128
dav_resource int dav_locktoken dav_response int flags
Definition: mod_dav.h:1458
request_rec * r
Definition: mod_dav.h:518
dav_buffer const char * str
Definition: mod_dav.h:465
int status
Definition: mod_dav.h:141
apr_bucket_brigade * bb
Definition: mod_dav.h:555
const char * s
Definition: mod_dav.h:1327
dav_error * src
Definition: mod_dav.h:186
apr_bucket_brigade request_rec apr_pool_t * pool
Definition: mod_dav.h:557
const char const char * uri
Definition: mod_dav.h:631
const char * name
Definition: mod_dav.h:805
apr_table_t * headers
Definition: mod_proxy.h:1484
int apr_status_t
Definition: apr_errno.h:44
apr_uint16_t apr_port_t
Definition: apr_network_io.h:230
off_t apr_off_t
Definition: apr.h:396
#define __attribute__(__x)
Definition: apr.h:63
size_t apr_size_t
Definition: apr.h:394
#define APR_INLINE
Definition: apr.h:65
struct apr_pool_t apr_pool_t
Definition: apr_pools.h:60
struct apr_table_t apr_table_t
Definition: apr_tables.h:56
apr_int64_t apr_time_t
Definition: apr_time.h:45
void insert_error_filter(request_rec *r)
HTTP Daemon routines.
#define AP_DECLARE_DATA
Definition: macros.h:15
#define AP_DECLARE(x)
Definition: macros.h:1
#define AP_CORE_DECLARE(x)
Definition: macros.h:3
#define AP_DECLARE_NONSTD(x)
Definition: macros.h:2
A bucket referring to an HTTP error.
Definition: http_protocol.h:1033
const char * data
Definition: http_protocol.h:1039
apr_bucket_refcount refcount
Definition: http_protocol.h:1035
int status
Definition: http_protocol.h:1037
A bucket referring to an HTTP header set.
Definition: http_protocol.h:1270
apr_table_t * headers
Definition: http_protocol.h:1274
apr_pool_t * pool
Definition: http_protocol.h:1273
apr_bucket_refcount refcount
Definition: http_protocol.h:1272
A bucket referring to a HTTP request.
Definition: http_protocol.h:1083
apr_pool_t * pool
Definition: http_protocol.h:1086
const char * protocol
Definition: http_protocol.h:1089
const char * method
Definition: http_protocol.h:1087
apr_bucket_refcount refcount
Definition: http_protocol.h:1085
const char * uri
Definition: http_protocol.h:1088
apr_table_t * headers
Definition: http_protocol.h:1090
A bucket referring to a HTTP response.
Definition: http_protocol.h:1199
const char * reason
Definition: http_protocol.h:1204
apr_pool_t * pool
Definition: http_protocol.h:1202
apr_table_t * headers
Definition: http_protocol.h:1205
apr_bucket_refcount refcount
Definition: http_protocol.h:1201
apr_table_t * notes
Definition: http_protocol.h:1206
int status
Definition: http_protocol.h:1203
This structure is used for recording information about the registered filters. It associates a name w...
Definition: util_filter.h:226
The representation of a filter chain.
Definition: util_filter.h:278
Structure for handling HTTP methods.
Definition: httpd.h:658
Definition: apr_tables.h:62
Definition: apr_buckets.h:263
Definition: apr_buckets.h:539
Definition: apr_buckets.h:136
Definition: apr_buckets.h:229
Definition: apr_arch_file_io.h:107
Definition: apr_file_info.h:174
Definition: apr_mmap.h:62
Structure to store things which are per connection.
Definition: httpd.h:1193
A structure with the ingredients for a file based etag.
Definition: http_protocol.h:208
const char * pathname
Definition: http_protocol.h:216
apr_time_t request_time
Definition: http_protocol.h:212
int force_weak
Definition: http_protocol.h:220
apr_file_t * fd
Definition: http_protocol.h:218
const char * vlist_validator
Definition: http_protocol.h:210
apr_finfo_t * finfo
Definition: http_protocol.h:214
A structure that represents the current request.
Definition: httpd.h:856
A structure to store information for each virtual server.
Definition: httpd.h:1382
apr_pool_t * p
Apache filter library.