aboutsummaryrefslogtreecommitdiff
path: root/src/lib/internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/internal.h')
-rw-r--r--src/lib/internal.h604
1 files changed, 601 insertions, 3 deletions
diff --git a/src/lib/internal.h b/src/lib/internal.h
index 8de88598..c14d96eb 100644
--- a/src/lib/internal.h
+++ b/src/lib/internal.h
@@ -126,6 +126,599 @@ extern void *mhd_panic_cls;
126#endif /* ! MHD_STATICSTR_LEN_ */ 126#endif /* ! MHD_STATICSTR_LEN_ */
127 127
128 128
129
130/**
131 * Ability to use same connection for next request
132 */
133enum MHD_ConnKeepAlive
134{
135 /**
136 * Connection must be closed after sending response.
137 */
138 MHD_CONN_MUST_CLOSE = -1,
139
140 /**
141 * KeelAlive state is not yet determined
142 */
143 MHD_CONN_KEEPALIVE_UNKOWN = 0,
144
145 /**
146 * Connection can be used for serving next request
147 */
148 MHD_CONN_USE_KEEPALIVE = 1
149};
150
151
152/**
153 * Function to receive plaintext data.
154 *
155 * @param conn the connection struct
156 * @param write_to where to write received data
157 * @param max_bytes maximum number of bytes to receive
158 * @return number of bytes written to @a write_to
159 */
160typedef ssize_t
161(*ReceiveCallback) (struct MHD_Connection *conn,
162 void *write_to,
163 size_t max_bytes);
164
165
166/**
167 * Function to transmit plaintext data.
168 *
169 * @param conn the connection struct
170 * @param read_from where to read data to transmit
171 * @param max_bytes maximum number of bytes to transmit
172 * @return number of bytes transmitted
173 */
174typedef ssize_t
175(*TransmitCallback) (struct MHD_Connection *conn,
176 const void *read_from,
177 size_t max_bytes);
178
179
180/**
181 * States in a state machine for a request.
182 *
183 * The main transitions are any-state to #MHD_REQUEST_CLOSED, any
184 * state to state+1, #MHD_REQUEST_FOOTERS_SENT to
185 * #MHD_REQUEST_INIT. #MHD_REQUEST_CLOSED is the terminal state
186 * and #MHD_REQUEST_INIT the initial state.
187 *
188 * Note that transitions for *reading* happen only after the input has
189 * been processed; transitions for *writing* happen after the
190 * respective data has been put into the write buffer (the write does
191 * not have to be completed yet). A transition to
192 * #MHD_REQUEST_CLOSED or #MHD_REQUEST_INIT requires the write
193 * to be complete.
194 */
195enum MHD_REQUEST_STATE
196{
197 /**
198 * Request just started (no headers received).
199 * Waiting for the line with the request type, URL and version.
200 */
201 MHD_REQUEST_INIT = 0,
202
203 /**
204 * 1: We got the URL (and request type and version). Wait for a header line.
205 */
206 MHD_REQUEST_URL_RECEIVED = MHD_REQUEST_INIT + 1,
207
208 /**
209 * 2: We got part of a multi-line request header. Wait for the rest.
210 */
211 MHD_REQUEST_HEADER_PART_RECEIVED = MHD_REQUEST_URL_RECEIVED + 1,
212
213 /**
214 * 3: We got the request headers. Process them.
215 */
216 MHD_REQUEST_HEADERS_RECEIVED = MHD_REQUEST_HEADER_PART_RECEIVED + 1,
217
218 /**
219 * 4: We have processed the request headers. Send 100 continue.
220 */
221 MHD_REQUEST_HEADERS_PROCESSED = MHD_REQUEST_HEADERS_RECEIVED + 1,
222
223 /**
224 * 5: We have processed the headers and need to send 100 CONTINUE.
225 */
226 MHD_REQUEST_CONTINUE_SENDING = MHD_REQUEST_HEADERS_PROCESSED + 1,
227
228 /**
229 * 6: We have sent 100 CONTINUE (or do not need to). Read the message body.
230 */
231 MHD_REQUEST_CONTINUE_SENT = MHD_REQUEST_CONTINUE_SENDING + 1,
232
233 /**
234 * 7: We got the request body. Wait for a line of the footer.
235 */
236 MHD_REQUEST_BODY_RECEIVED = MHD_REQUEST_CONTINUE_SENT + 1,
237
238 /**
239 * 8: We got part of a line of the footer. Wait for the
240 * rest.
241 */
242 MHD_REQUEST_FOOTER_PART_RECEIVED = MHD_REQUEST_BODY_RECEIVED + 1,
243
244 /**
245 * 9: We received the entire footer. Wait for a response to be queued
246 * and prepare the response headers.
247 */
248 MHD_REQUEST_FOOTERS_RECEIVED = MHD_REQUEST_FOOTER_PART_RECEIVED + 1,
249
250 /**
251 * 10: We have prepared the response headers in the writ buffer.
252 * Send the response headers.
253 */
254 MHD_REQUEST_HEADERS_SENDING = MHD_REQUEST_FOOTERS_RECEIVED + 1,
255
256 /**
257 * 11: We have sent the response headers. Get ready to send the body.
258 */
259 MHD_REQUEST_HEADERS_SENT = MHD_REQUEST_HEADERS_SENDING + 1,
260
261 /**
262 * 12: We are ready to send a part of a non-chunked body. Send it.
263 */
264 MHD_REQUEST_NORMAL_BODY_READY = MHD_REQUEST_HEADERS_SENT + 1,
265
266 /**
267 * 13: We are waiting for the client to provide more
268 * data of a non-chunked body.
269 */
270 MHD_REQUEST_NORMAL_BODY_UNREADY = MHD_REQUEST_NORMAL_BODY_READY + 1,
271
272 /**
273 * 14: We are ready to send a chunk.
274 */
275 MHD_REQUEST_CHUNKED_BODY_READY = MHD_REQUEST_NORMAL_BODY_UNREADY + 1,
276
277 /**
278 * 15: We are waiting for the client to provide a chunk of the body.
279 */
280 MHD_REQUEST_CHUNKED_BODY_UNREADY = MHD_REQUEST_CHUNKED_BODY_READY + 1,
281
282 /**
283 * 16: We have sent the response body. Prepare the footers.
284 */
285 MHD_REQUEST_BODY_SENT = MHD_REQUEST_CHUNKED_BODY_UNREADY + 1,
286
287 /**
288 * 17: We have prepared the response footer. Send it.
289 */
290 MHD_REQUEST_FOOTERS_SENDING = MHD_REQUEST_BODY_SENT + 1,
291
292 /**
293 * 18: We have sent the response footer. Shutdown or restart.
294 */
295 MHD_REQUEST_FOOTERS_SENT = MHD_REQUEST_FOOTERS_SENDING + 1,
296
297 /**
298 * 19: This request is to be closed.
299 */
300 MHD_REQUEST_CLOSED = MHD_REQUEST_FOOTERS_SENT + 1,
301
302 /**
303 * 20: This request is finished (only to be freed)
304 */
305 MHD_REQUEST_IN_CLEANUP = MHD_REQUEST_CLOSED + 1,
306
307#ifdef UPGRADE_SUPPORT
308 /**
309 * Request was "upgraded" and socket is now under the
310 * control of the application.
311 */
312 MHD_REQUEST_UPGRADE
313#endif /* UPGRADE_SUPPORT */
314
315};
316
317
318/**
319 * Header or cookie in HTTP request or response.
320 */
321struct MHD_HTTP_Header
322{
323 /**
324 * Headers are kept in a linked list.
325 */
326 struct MHD_HTTP_Header *next;
327
328 /**
329 * The name of the header (key), without the colon.
330 */
331 char *header;
332
333 /**
334 * The value of the header.
335 */
336 char *value;
337
338 /**
339 * Type of the header (where in the HTTP protocol is this header
340 * from).
341 */
342 enum MHD_ValueKind kind;
343
344};
345
346
347/**
348 * State kept for each HTTP request.
349 */
350struct MHD_Request
351{
352
353 /**
354 * Reference to the MHD_Daemon struct.
355 */
356 struct MHD_Daemon *daemon;
357
358 /**
359 * Connection this request is associated with.
360 */
361 struct MHD_Connection *connection;
362
363 /**
364 * Linked list of parsed headers.
365 */
366 struct MHD_HTTP_Header *headers_received;
367
368 /**
369 * Tail of linked list of parsed headers.
370 */
371 struct MHD_HTTP_Header *headers_received_tail;
372
373 /**
374 * The memory pool is created whenever we first read from the TCP
375 * stream and destroyed at the end of each request (and re-created
376 * for the next request). In the meantime, this pointer is NULL.
377 * The pool is used for all request-related data except for the
378 * response (which maybe shared between requests) and the IP
379 * address (which persists across individual requests).
380 */
381 struct MemoryPool *pool;
382
383 /**
384 * We allow the main application to associate some pointer with the
385 * HTTP request, which is passed to each #MHD_AccessHandlerCallback
386 * and some other API calls. Here is where we store it. (MHD does
387 * not know or care what it is).
388 */
389 void *client_context;
390
391 /**
392 * Request method. Should be GET/POST/etc. Allocated in pool.
393 */
394 char *method;
395
396 /**
397 * Requested URL (everything after "GET" only). Allocated
398 * in pool.
399 */
400 const char *url;
401
402 /**
403 * HTTP version string (i.e. http/1.1). Allocated
404 * in pool.
405 */
406 char *version;
407
408 /**
409 * Close connection after sending response?
410 * Functions may change value from "Unknown" or "KeepAlive" to "Must close",
411 * but no functions reset value "Must Close" to any other value.
412 */
413 enum MHD_ConnKeepAlive keepalive;
414
415 /**
416 * Buffer for reading requests. Allocated in pool. Actually one
417 * byte larger than @e read_buffer_size (if non-NULL) to allow for
418 * 0-termination.
419 */
420 char *read_buffer;
421
422 /**
423 * Buffer for writing response (headers only). Allocated
424 * in pool.
425 */
426 char *write_buffer;
427
428 /**
429 * Last incomplete header line during parsing of headers.
430 * Allocated in pool. Only valid if state is
431 * either #MHD_REQUEST_HEADER_PART_RECEIVED or
432 * #MHD_REQUEST_FOOTER_PART_RECEIVED.
433 */
434 char *last;
435
436 /**
437 * Position after the colon on the last incomplete header
438 * line during parsing of headers.
439 * Allocated in pool. Only valid if state is
440 * either #MHD_REQUEST_HEADER_PART_RECEIVED or
441 * #MHD_REQUEST_FOOTER_PART_RECEIVED.
442 */
443 char *colon;
444
445
446 /**
447 * Function used for reading HTTP request stream.
448 */
449 ReceiveCallback recv_cls;
450
451 /**
452 * Function used for writing HTTP response stream.
453 */
454 TransmitCallback send_cls;
455
456#ifdef UPGRADE_SUPPORT
457 /**
458 * If this connection was upgraded, this points to
459 * the upgrade response details such that the
460 * #thread_main_connection_upgrade()-logic can perform the
461 * bi-directional forwarding.
462 */
463 struct MHD_UpgradeResponseHandle *urh;
464#endif /* UPGRADE_SUPPORT */
465
466 /**
467 * Foreign address (of length @e addr_len).
468 */
469 struct sockaddr_storage addr;
470
471 /**
472 * Thread handle for this connection (if we are using
473 * one thread per connection).
474 */
475 MHD_thread_handle_ID_ pid;
476
477 /**
478 * Size of @e read_buffer (in bytes). This value indicates
479 * how many bytes we're willing to read into the buffer;
480 * the real buffer is one byte longer to allow for
481 * adding zero-termination (when needed).
482 */
483 size_t read_buffer_size;
484
485 /**
486 * Position where we currently append data in
487 * @e read_buffer (last valid position).
488 */
489 size_t read_buffer_offset;
490
491 /**
492 * Size of @e write_buffer (in bytes).
493 */
494 size_t write_buffer_size;
495
496 /**
497 * Offset where we are with sending from @e write_buffer.
498 */
499 size_t write_buffer_send_offset;
500
501 /**
502 * Last valid location in write_buffer (where do we
503 * append and up to where is it safe to send?)
504 */
505 size_t write_buffer_append_offset;
506
507 /**
508 * Number of bytes we had in the HTTP header, set once we
509 * pass #MHD_REQUEST_HEADERS_RECEIVED.
510 */
511 size_t header_size;
512
513 /**
514 * How many more bytes of the body do we expect
515 * to read? #MHD_SIZE_UNKNOWN for unknown.
516 */
517 uint64_t remaining_upload_size;
518
519 /**
520 * If we are receiving with chunked encoding, where are we right
521 * now? Set to 0 if we are waiting to receive the chunk size;
522 * otherwise, this is the size of the current chunk. A value of
523 * zero is also used when we're at the end of the chunks.
524 */
525 uint64_t current_chunk_size;
526
527 /**
528 * If we are receiving with chunked encoding, where are we currently
529 * with respect to the current chunk (at what offset / position)?
530 */
531 uint64_t current_chunk_offset;
532
533 /**
534 * Current write position in the actual response
535 * (excluding headers, content only; should be 0
536 * while sending headers).
537 */
538 uint64_t response_write_position;
539
540#if defined(_MHD_HAVE_SENDFILE)
541 enum MHD_resp_sender_
542 {
543 MHD_resp_sender_std = 0,
544 MHD_resp_sender_sendfile
545 } resp_sender;
546#endif /* _MHD_HAVE_SENDFILE */
547
548 /**
549 * Position in the 100 CONTINUE message that
550 * we need to send when receiving http 1.1 requests.
551 */
552 size_t continue_message_write_offset;
553
554 /**
555 * State in the FSM for this request.
556 */
557 enum MHD_REQUEST_STATE state;
558
559 /**
560 * What is this request waiting for?
561 */
562 enum MHD_RequestEventLoopInfo event_loop_info;
563
564 /**
565 * HTTP response code. Only valid if response object
566 * is already set.
567 */
568 unsigned int responseCode;
569
570 /**
571 * Did we ever call the "default_handler" on this request? (this
572 * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED
573 * handler when the request closes down).
574 */
575 bool client_aware;
576
577 /**
578 * Are we currently inside the "idle" handler (to avoid recursively
579 * invoking it).
580 */
581 bool in_idle;
582
583 /**
584 * Are we currently inside the "idle" handler (to avoid recursively
585 * invoking it).
586 */
587 bool in_cleanup;
588
589 /**
590 * Are we receiving with chunked encoding? This will be set to
591 * #MHD_YES after we parse the headers and are processing the body
592 * with chunks. After we are done with the body and we are
593 * processing the footers; once the footers are also done, this will
594 * be set to #MHD_NO again (before the final call to the handler).
595 */
596 bool have_chunked_upload;
597
598 /**
599 * Is the request suspended?
600 */
601 bool suspended;
602
603 /**
604 * Is the request wanting to resume?
605 */
606 bool resuming;
607};
608
609
610/**
611 * State kept per HTTP connection.
612 */
613struct MHD_Connection
614{
615
616#ifdef EPOLL_SUPPORT
617 /**
618 * Next pointer for the EDLL listing connections that are epoll-ready.
619 */
620 struct MHD_Connection *nextE;
621
622 /**
623 * Previous pointer for the EDLL listing connections that are epoll-ready.
624 */
625 struct MHD_Connection *prevE;
626#endif
627
628 /**
629 * Next pointer for the DLL describing our IO state.
630 */
631 struct MHD_Connection *next;
632
633 /**
634 * Previous pointer for the DLL describing our IO state.
635 */
636 struct MHD_Connection *prev;
637
638 /**
639 * Next pointer for the XDLL organizing connections by timeout.
640 * This DLL can be either the
641 * 'manual_timeout_head/manual_timeout_tail' or the
642 * 'normal_timeout_head/normal_timeout_tail', depending on whether a
643 * custom timeout is set for the connection.
644 */
645 struct MHD_Connection *nextX;
646
647 /**
648 * Previous pointer for the XDLL organizing connections by timeout.
649 */
650 struct MHD_Connection *prevX;
651
652 /**
653 * Reference to the MHD_Daemon struct.
654 */
655 struct MHD_Daemon *daemon;
656
657 /**
658 * Information about the current request we are processing
659 * on this connection.
660 */
661 struct MHD_Request request;
662
663
664 /**
665 * Set to `true` if the thread has been joined.
666 */
667 bool thread_joined;
668
669 /**
670 * true if #socket_fd is non-blocking, false otherwise.
671 */
672 bool sk_nonblck;
673
674 /**
675 * Has this socket been closed for reading (i.e. other side closed
676 * the connection)? If so, we must completely close the connection
677 * once we are done sending our response (and stop trying to read
678 * from this socket).
679 */
680 bool read_closed;
681
682
683 /**
684 * Length of the foreign address.
685 */
686 socklen_t addr_len;
687
688 /**
689 * Last time this connection had any activity
690 * (reading or writing).
691 */
692 time_t last_activity;
693
694 /**
695 * After how many seconds of inactivity should
696 * this connection time out? Zero for no timeout.
697 */
698 time_t connection_timeout;
699
700 /**
701 * Socket for this connection. Set to #MHD_INVALID_SOCKET if
702 * this connection has died (daemon should clean
703 * up in that case).
704 */
705 MHD_socket socket_fd;
706
707
708#ifdef EPOLL_SUPPORT
709 /**
710 * What is the state of this socket in relation to epoll?
711 */
712 enum MHD_EpollState epoll_state;
713#endif
714
715
716};
717
718
719
720
721
129/** 722/**
130 * State kept for each MHD daemon. All connections are kept in two 723 * State kept for each MHD daemon. All connections are kept in two
131 * doubly-linked lists. The first one reflects the state of the 724 * doubly-linked lists. The first one reflects the state of the
@@ -324,8 +917,14 @@ struct MHD_Daemon
324 MHD_socket listen_socket; 917 MHD_socket listen_socket;
325 918
326 /** 919 /**
920 * Inter-thread communication channel.
921 */
922 struct MHD_itc_ itc;
923
924 /**
327 * Which threading model do we use? Postive 925 * Which threading model do we use? Postive
328 * numbers indicate the number of worker threads to be used. 926 * numbers indicate the number of worker threads to be used.
927 * Values larger than 1 imply a thread pool.
329 */ 928 */
330 enum MHD_ThreadingModel threading_model; 929 enum MHD_ThreadingModel threading_model;
331 930
@@ -337,7 +936,7 @@ struct MHD_Daemon
337 936
338 /** 937 /**
339 * Address family to use when listening. 938 * Address family to use when listening.
340 * Default is #MHD_AF_AUTO. 939 * Default is #MHD_AF_NONE (do not listen).
341 */ 940 */
342 enum MHD_AddressFamily listen_af; 941 enum MHD_AddressFamily listen_af;
343 942
@@ -357,8 +956,7 @@ struct MHD_Daemon
357 /** 956 /**
358 * On which port should we listen on? Only effective if we were not 957 * On which port should we listen on? Only effective if we were not
359 * given a listen socket or a full address via 958 * given a listen socket or a full address via
360 * #MHD_daemon_bind_sa(). 0 means not set, which means to default 959 * #MHD_daemon_bind_sa(). 0 means to bind to random free port.
361 * to 80 (http) or 443 (https) respectively.
362 */ 960 */
363 uint16_t listen_port; 961 uint16_t listen_port;
364 962