source: trunk/third/libghttp/http_req.c @ 15592

Revision 15592, 6.4 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15591, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * http_req.c -- Functions for making http requests
3 * Created: Christopher Blizzard <blizzard@appliedtheory.com>, 6-Aug-1998
4 *
5 * Copyright (C) 1998 Free Software Foundation
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <string.h>
23#include <stdlib.h>
24#include "http_req.h"
25#include "http_trans.h"
26#include "http_global.h"
27
28const char *
29http_req_type_char[] = {
30  "GET",
31  "OPTIONS",
32  "HEAD",
33  "POST",
34  "PUT",
35  "DELETE",
36  "TRACE",
37  "CONNECT",
38  "PROPFIND",
39  "PROPPATCH",
40  "MKCOL",
41  "COPY",
42  "MOVE",
43  "LOCK",
44  "UNLOCK",
45  NULL
46};
47
48http_req *
49http_req_new(void)
50{
51  http_req *l_return = NULL;
52 
53  l_return = (http_req *)malloc(sizeof(http_req));
54  memset(l_return, 0, sizeof(http_req));
55  /* default to 1.1 */
56  l_return->http_ver = 1.1;
57  l_return->headers = http_hdr_list_new();
58  return l_return;
59}
60
61void
62http_req_destroy(http_req *a_req)
63{
64  if (!a_req)
65    return;
66  if (a_req->headers)
67    http_hdr_list_destroy(a_req->headers);
68  free(a_req);
69}
70
71int
72http_req_prepare(http_req *a_req)
73{
74  int l_return = 0;
75  char l_buf[30];
76
77  if (!a_req)
78    return -1;
79  memset(l_buf, 0, 30);
80  /* set the host header */
81  http_hdr_set_value(a_req->headers,
82                     http_hdr_Host,
83                     a_req->host);
84  /* check to see if we have an entity body */
85  if ((a_req->type == http_req_type_post) ||
86      (a_req->type == http_req_type_put) ||
87      (a_req->type == http_req_type_trace))
88    {
89      sprintf(l_buf, "%d", a_req->body_len);
90      http_hdr_set_value(a_req->headers,
91                         http_hdr_Content_Length,
92                         l_buf);
93    }
94  /* if the user agent isn't set then set a default */
95  if (http_hdr_get_value(a_req->headers, http_hdr_User_Agent) == NULL)
96    http_hdr_set_value(a_req->headers, http_hdr_User_Agent,
97                       "libghttp/1.0");
98  return l_return;
99}
100
101int
102http_req_send(http_req *a_req, http_trans_conn *a_conn)
103{
104  char       *l_request = NULL;
105  int         l_request_len = 0;
106  int         i = 0;
107  int         l_len = 0;
108  int         l_headers_len = 0;
109  int         l_rv = 0;
110  char       *l_content = NULL;
111
112  /* see if we need to jump into the function somewhere */
113  if (a_conn->sync == HTTP_TRANS_ASYNC)
114    {
115      if (a_req->state == http_req_state_sending_request)
116        goto http_req_state_sending_request_jump;
117      if (a_req->state == http_req_state_sending_headers)
118        goto http_req_state_sending_headers_jump;
119      if (a_req->state == http_req_state_sending_body)
120        goto http_req_state_sending_body_jump;
121    }
122  /* enough for the request and the other little headers */
123  l_request = malloc(30 + strlen(a_req->resource) + (a_conn->proxy_host ?
124                                                     (strlen(a_req->host) + 20) : 0));
125  memset(l_request, 0, 30 + strlen(a_req->resource) + (a_conn->proxy_host ?
126                                                       (strlen(a_req->host) + 20) : 0));
127  /* copy it into the buffer */
128  if (a_conn->proxy_host)
129    {
130      l_request_len = sprintf(l_request,
131                              "%s %s HTTP/%01.1f\r\n",
132                              http_req_type_char[a_req->type],
133                              a_req->full_uri,
134                              a_req->http_ver);
135    }
136  else
137    {
138      l_request_len = sprintf(l_request,
139                              "%s %s HTTP/%01.1f\r\n",
140                              http_req_type_char[a_req->type],
141                              a_req->resource,
142                              a_req->http_ver);
143    }
144  /* set the request in the connection buffer */
145  http_trans_append_data_to_buf(a_conn, l_request, l_request_len);
146  /* free up the request - we don't need it anymore */
147  free(l_request);
148  l_request = NULL;
149  /* set the state */
150  a_req->state = http_req_state_sending_request;
151 http_req_state_sending_request_jump:
152  /* send the request */
153  do {
154    l_rv = http_trans_write_buf(a_conn);
155    if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE))
156      return HTTP_TRANS_NOT_DONE;
157    if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0))
158      return HTTP_TRANS_ERR;
159  } while (l_rv == HTTP_TRANS_NOT_DONE);
160  /* reset the buffer */
161  http_trans_buf_reset(a_conn);
162  /* set up all of the headers */
163  for (i = 0; i < HTTP_HDRS_MAX; i++)
164    {
165      l_len = 0;
166      if (a_req->headers->header[i])
167        {
168          l_len = strlen(a_req->headers->header[i]);
169          if (l_len > 0)
170            {
171              http_trans_append_data_to_buf(a_conn, a_req->headers->header[i], l_len);
172              l_headers_len += l_len;
173              http_trans_append_data_to_buf(a_conn, ": ", 2);
174              l_headers_len += 2;
175              /* note, it's ok to have no value for a request */
176              if ((l_len = strlen(a_req->headers->value[i])) > 0)
177                {
178                  http_trans_append_data_to_buf(a_conn, a_req->headers->value[i], l_len);
179                  l_headers_len += l_len;
180                }
181              http_trans_append_data_to_buf(a_conn, "\r\n", 2);
182              l_headers_len += 2;
183            }
184        }
185    }
186  http_trans_append_data_to_buf(a_conn, "\r\n", 2);
187  l_headers_len += 2;
188  /* set the state */
189  a_req->state = http_req_state_sending_headers;
190 http_req_state_sending_headers_jump:
191  /* blast that out to the network */
192  do {
193    l_rv = http_trans_write_buf(a_conn);
194    if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE))
195      return HTTP_TRANS_NOT_DONE;
196    if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0))
197      return HTTP_TRANS_ERR;
198  } while (l_rv == HTTP_TRANS_NOT_DONE);
199  /* reset the buffer */
200  http_trans_buf_reset(a_conn);
201  l_content = http_hdr_get_value(a_req->headers, http_hdr_Content_Length);
202  if (l_content)
203    {
204      /* append the information to the buffer */
205      http_trans_append_data_to_buf(a_conn, a_req->body, a_req->body_len);
206      a_req->state = http_req_state_sending_body;
207    http_req_state_sending_body_jump:
208      do {
209        l_rv = http_trans_write_buf(a_conn);
210        if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE))
211          return HTTP_TRANS_NOT_DONE;
212        if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0))
213          return HTTP_TRANS_ERR;
214      } while (l_rv == HTTP_TRANS_NOT_DONE);
215      /* reset the buffer */
216      http_trans_buf_reset(a_conn);
217    }
218  return HTTP_TRANS_DONE;
219}
Note: See TracBrowser for help on using the repository browser.