// This module handles HTTP transactions.
//
-// Copyright (c) 1996-2022 by the citadel.org team
+// Copyright (c) 1996-2023 by the citadel.org team
//
// This program is open source software. Use, duplication, or
// disclosure are subject to the GNU General Public License v3.
+// uncomment one or more of these to see raw http transactions
+//#define DEBUG_HTTP
+//#define REQUEST_BODY_TO_STDERR
+//#define RESPONSE_BODY_TO_STDERR
+
#include "webcit.h"
// Write data to the HTTP client. Encrypt if necessary.
syslog(LOG_DEBUG, "Client disconnected");
}
else {
-//#ifdef DEBUG_HTTP
+#ifdef DEBUG_HTTP
syslog(LOG_DEBUG, "< %s %s", h.method, h.url);
-//#endif
+#endif
// If there is a request body, read it now.
char *ccl = header_val(&h, "Content-Length");
}
if (h.request_body_length > 0) {
syslog(LOG_DEBUG, "Reading request body (%ld bytes)", h.request_body_length);
- h.request_body = malloc(h.request_body_length);
+
+ // Sometimes we need the request body by itself, sometimes we need it with headers.
+ // So we save it with synthetic headers, and also provide a pointer into the place where the body begins.
+
+ char *cct = header_val(&h, "Content-Type");
+ if (cct) {
+ h.request_body_with_synth_headers = malloc(h.request_body_length + 1024);
+ memset(h.request_body_with_synth_headers, h.request_body_length + 1024, 0);
+ sprintf(h.request_body_with_synth_headers, "Content-Type: %s\r\n\r\n", cct);
+ h.request_body = h.request_body_with_synth_headers + strlen(h.request_body_with_synth_headers);
+ }
+ else { // a request body absent a Content-Type: header is invalid, but handle it anyway.
+ h.request_body_with_synth_headers = malloc(h.request_body_length);
+ memset(h.request_body_with_synth_headers, h.request_body_length, 0);
+ h.request_body = h.request_body_with_synth_headers;
+ }
+
client_read(ch, h.request_body, h.request_body_length);
// Write the entire request body to stderr -- not what you want during normal operation.
- #ifdef BODY_TO_STDERR
- write(2, HKEY("---\n"));
+ #ifdef REQUEST_BODY_TO_STDERR
+ write(2, HKEY("--- REQUEST BODY BEGIN ---\n"));
write(2, h.request_body, h.request_body_length);
- write(2, HKEY("---\n"));
+ write(2, HKEY("--- REQUEST BODY END ---\n"));
#endif
}
perform_request(&h);
// Write the entire response body to stderr -- not what you want during normal operation.
- #ifdef BODY_TO_STDERR
- write(2, HKEY("---\n"));
+ #ifdef RESPONSE_BODY_TO_STDERR
+ write(2, HKEY("--- RESPONSE BODY BEGIN ---\n"));
write(2, h.response_body, h.response_body_length);
- write(2, HKEY("---\n"));
+ write(2, HKEY("--- RESPONSE BODY END ---\n"));
#endif
// Output the results back to the client.
if (h.url) {
free(h.url);
}
- if (h.request_body) {
- free(h.request_body);
+ if (h.request_body_with_synth_headers) {
+ free(h.request_body_with_synth_headers);
}
if (h.response_string) {
free(h.response_string);