1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-message-server-io.c: server-side request/response
5 * Copyright (C) 2000-2003, Ximian, Inc.
15 #include "soup-message-private.h"
16 #include "soup-address.h"
17 #include "soup-auth.h"
18 #include "soup-headers.h"
19 #include "soup-misc.h"
20 #include "soup-private.h"
21 #include "soup-server-message.h"
22 #include "soup-server.h"
23 #include "soup-socket.h"
26 parse_request_headers (SoupMessage *msg, char *headers, guint headers_len,
27 SoupTransferEncoding *encoding, guint *content_len,
31 char *req_path = NULL, *url;
32 const char *length, *enc, *req_host;
35 if (!soup_headers_parse_request (headers, headers_len,
37 (char **) &msg->method,
39 &msg->priv->http_version))
40 return SOUP_STATUS_BAD_REQUEST;
42 /* Handle request body encoding */
43 length = soup_message_get_header (msg->request_headers,
45 enc = soup_message_get_header (msg->request_headers,
49 if (g_strcasecmp (enc, "chunked") == 0)
50 *encoding = SOUP_TRANSFER_CHUNKED;
52 g_warning ("Unknown encoding type in HTTP request.");
54 return SOUP_STATUS_NOT_IMPLEMENTED;
58 *encoding = SOUP_TRANSFER_CONTENT_LENGTH;
62 return SOUP_STATUS_BAD_REQUEST;
66 *encoding = SOUP_TRANSFER_CONTENT_LENGTH;
70 /* Generate correct context for request */
71 server = soup_server_message_get_server (SOUP_SERVER_MESSAGE (msg));
72 req_host = soup_message_get_header (msg->request_headers, "Host");
74 if (*req_path != '/') {
75 /* Check for absolute URI */
78 absolute = soup_uri_new (req_path);
80 url = g_strdup (req_path);
81 soup_uri_free (absolute);
84 return SOUP_STATUS_BAD_REQUEST;
86 } else if (req_host) {
87 url = g_strdup_printf ("%s://%s:%d%s",
88 soup_server_get_protocol (server) == SOUP_PROTOCOL_HTTPS ? "https" : "http",
89 req_host, soup_server_get_port (server),
91 } else if (msg->priv->http_version == SOUP_HTTP_1_0) {
92 /* No Host header, no AbsoluteUri */
93 SoupAddress *addr = soup_socket_get_local_address (sock);
94 const char *host = soup_address_get_physical (addr);
96 url = g_strdup_printf ("%s://%s:%d%s",
97 soup_server_get_protocol (server) == SOUP_PROTOCOL_HTTPS ? "https" : "http",
98 host, soup_server_get_port (server),
102 return SOUP_STATUS_BAD_REQUEST;
105 uri = soup_uri_new (url);
110 return SOUP_STATUS_BAD_REQUEST;
112 soup_message_set_uri (msg, uri);
115 return SOUP_STATUS_OK;
119 write_header (gpointer name, gpointer value, gpointer headers)
121 g_string_append_printf (headers, "%s: %s\r\n",
122 (char *)name, (char *)value);
126 get_response_headers (SoupMessage *msg, GString *headers,
127 SoupTransferEncoding *encoding,
130 SoupServerMessage *smsg = SOUP_SERVER_MESSAGE (msg);
132 g_string_append_printf (headers, "HTTP/1.1 %d %s\r\n",
133 msg->status_code, msg->reason_phrase);
135 soup_message_foreach_header (msg->response_headers,
136 write_header, headers);
138 *encoding = soup_server_message_get_encoding (smsg);
139 if (*encoding == SOUP_TRANSFER_CONTENT_LENGTH) {
140 g_string_append_printf (headers, "Content-Length: %d\r\n",
141 msg->response.length);
142 } else if (*encoding == SOUP_TRANSFER_CHUNKED)
143 g_string_append (headers, "Transfer-Encoding: chunked\r\n");
145 g_string_append (headers, "\r\n");
149 soup_message_read_request (SoupMessage *req, SoupSocket *sock)
151 soup_message_io_server (req, sock,
152 get_response_headers,
153 parse_request_headers,