summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-response.c
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp/nanohttp-response.c')
-rwxr-xr-xnanohttp/nanohttp-response.c213
1 files changed, 213 insertions, 0 deletions
diff --git a/nanohttp/nanohttp-response.c b/nanohttp/nanohttp-response.c
new file mode 100755
index 0000000..8f55856
--- /dev/null
+++ b/nanohttp/nanohttp-response.c
@@ -0,0 +1,213 @@
+/******************************************************************
+* $Id: nanohttp-response.c,v 1.1 2004/10/15 13:30:42 snowdrop Exp $
+*
+* CSOAP Project: A http client/server library in C
+* Copyright (C) 2003-2004 Ferhat Ayaz
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Email: ferhatayaz@yahoo.com
+******************************************************************/
+
+#include <nanohttp/nanohttp-common.h>
+#include <nanohttp/nanohttp-response.h>
+
+
+#ifdef MEM_DEBUG
+#include <utils/alloc.h>
+#endif
+
+static
+hresponse_t*
+hresponse_new()
+{
+ hresponse_t *res;
+
+ /* create response object */
+ res = (hresponse_t *) malloc(sizeof(hresponse_t));
+ res->version = HTTP_1_1;
+ res->errcode = -1;
+ res->desc[0] = '\0';
+ res->header = NULL;
+ res->in = NULL;
+ res->content_type = NULL;
+ res->attachments = NULL;
+ return res;
+}
+
+static
+hresponse_t*
+_hresponse_parse_header(const char *buffer)
+{
+ hresponse_t *res;
+ char *s1, *s2, *str;
+
+ /* create response object */
+ res = hresponse_new();
+
+ /* *** parse spec *** */
+ /* [HTTP/1.1 | 1.2] [CODE] [DESC] */
+
+ /* stage 1: HTTP spec */
+ str = (char *) strtok_r((char *) buffer, " ", &s2);
+ s1 = s2;
+ if (str == NULL) {
+ log_error1("Parse error reading HTTP spec");
+ return NULL;
+ }
+
+ if (!strcmp(str, "HTTP/1.0"))
+ res->version = HTTP_1_0;
+ else
+ res->version = HTTP_1_1;
+
+ /* stage 2: http code */
+ str = (char *) strtok_r(s1, " ", &s2);
+ s1 = s2;
+ if (str == NULL) {
+ log_error1("Parse error reading HTTP code");
+ return NULL;
+ }
+ res->errcode = atoi(str);
+
+ /* stage 3: description text */
+ str = (char *) strtok_r(s1, "\r\n", &s2);
+ s1 = s2;
+ if (str == NULL) {
+ log_error1("Parse error reading HTTP description");
+ return NULL;
+ }
+/* res->desc = (char *) malloc(strlen(str) + 1);*/
+ strncpy(res->desc, str, RESPONSE_MAX_DESC_SIZE);
+ res->desc[strlen(str)] = '\0';
+
+ /* *** parse header *** */
+ /* [key]: [value] */
+ for (;;) {
+ str = strtok_r(s1, "\n", &s2);
+ s1 = s2;
+
+ /* check if header ends without body */
+ if (str == NULL) {
+ return res;
+ }
+ /* check also for end of header */
+ if (!strcmp(str, "\r")) {
+ break;
+ }
+ str[strlen(str) - 1] = '\0';
+ res->header = hpairnode_parse(str, ":", res->header);
+ }
+
+ /* Check Content-type */
+ str = hpairnode_get(res->header, HEADER_CONTENT_TYPE);
+ if (str != NULL)
+ res->content_type = content_type_new(str);
+
+ /* return response object */
+ return res;
+}
+
+hresponse_t *
+hresponse_new_from_socket(hsocket_t sock)
+{
+ int i=0, status;
+ hresponse_t *res;
+ attachments_t *mimeMessage;
+ char buffer[MAX_HEADER_SIZE+1];
+
+read_header: /* for errorcode: 100 (continue) */
+ /* Read header */
+ while (i<MAX_HEADER_SIZE)
+ {
+ status = hsocket_read(sock, &(buffer[i]), 1, 1);
+ if (status == -1)
+ {
+ log_error1("Socket read error");
+ return NULL;
+ }
+
+ buffer[i+1] = '\0'; /* for strmp */
+
+ if (i > 3)
+ {
+ if (!strcmp(&(buffer[i-1]), "\n\n") ||
+ !strcmp(&(buffer[i-2]), "\n\r\n"))
+ break;
+ }
+ i++;
+ }
+
+ /* Create response */
+ res = _hresponse_parse_header(buffer);
+ if (res == NULL)
+ {
+ log_error1("Header parse error");
+ return NULL;
+ }
+
+ /* Chec for Errorcode: 100 (continue) */
+ if (res->errcode == 100) {
+ hresponse_free(res);
+ i=0;
+ goto read_header;
+ }
+
+ /* Create input stream */
+ res->in = http_input_stream_new(sock, res->header);
+
+
+ /* Check for MIME message */
+ if ((res->content_type &&
+ !strcmp(res->content_type->type, "multipart/related")))
+ {
+ status = mime_get_attachments(res->content_type, res->in, &mimeMessage);
+ if (status != H_OK)
+ {
+ /* TODO (#1#): Handle error */
+ hresponse_free(res);
+ return NULL;
+ }
+ else
+ {
+ res->attachments = mimeMessage;
+ res->in = http_input_stream_new_from_file(mimeMessage->root_part->filename);
+ }
+ }
+
+ return res;
+}
+
+
+
+void
+hresponse_free(hresponse_t * res)
+{
+ if (res == NULL)
+ return;
+
+ if (res->header)
+ hpairnode_free_deep(res->header);
+
+ if (res->in)
+ http_input_stream_free(res->in);
+
+ if (res->content_type)
+ content_type_free(res->content_type);
+
+ free(res);
+}
+