/*--------------------------------------------------
FUNCTION: httpc_send_header
DESC: Sends the current header information stored
in conn through conn->sock.
----------------------------------------------------*/
herror_t
httpc_send_header(httpc_conn_t * conn)
{
  hpair_t *walker;
  herror_t status;
  char buffer[1024];

  for (walker = conn->header; walker; walker = walker->next)
  {
    if (walker->key && walker->value)
    {
      sprintf(buffer, "%s: %s\r\n", walker->key, walker->value);
      if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK)
        return status;
    }
  }

  return hsocket_send(&(conn->sock), "\r\n");
}
Ejemplo n.º 2
0
herror_t
httpd_send_header(httpd_conn_t * res, int code, const char *text)
{
  struct tm stm;
  time_t nw;
  char buffer[255];
  char header[1024];
  hpair_t *cur;
  herror_t status;

  /* set status code */
  sprintf(header, "HTTP/1.1 %d %s\r\n", code, text);

  /* set date */
  nw = time(NULL);
  localtime_r(&nw, &stm);
  strftime(buffer, 255, "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", &stm);
  strcat(header, buffer);

  /* set content-type */
  /* 
   * if (res->content_type[0] == '\0') { strcat(header, "Content-Type:
   * text/html\r\n"); } else { sprintf(buffer, "Content-Type: %s\r\n",
   * res->content_type); strcat(header, buffer); }
   */

  /* set server name */
  strcat(header, "Server: nanoHTTP library\r\n");

  /* set _httpd_connection status */
  /* strcat (header, "Connection: close\r\n"); */

  /* add pairs */
  for (cur = res->header; cur; cur = cur->next)
  {
    sprintf(buffer, "%s: %s\r\n", cur->key, cur->value);
    strcat(header, buffer);
  }

  /* set end of header */
  strcat(header, "\r\n");

  /* send header */
  if ((status = hsocket_send(res->sock, header, strlen(header))) != H_OK)
    return status;

  res->out = http_output_stream_new(res->sock, res->header);
  return H_OK;
}
/*--------------------------------------------------
FUNCTION: httpc_talk_to_server
DESC: This function is the heart of the httpc
module. It will send the request and process the
response.

Here the parameters:

method:
the request method. This can be HTTP_REQUEST_POST and
HTTP_REQUEST_GET.

conn:
the connection object (created with httpc_new())

urlstr:
the complete url in string format.
http://<host>:<port>/<context>
where <port> is not mendatory.

start_cb:
a callback function, which will be called when
the response header is completely arrives.

cb:
a callback function, which will be called everytime
when data arrives.

content_size:
size of content to send.
(only if method is HTTP_REQUEST_POST)

content:
the content data to send.
(only if method is HTTP_REQUEST_POST)

userdata:
a user define data, which will be passed to the
start_cb and cb callbacks as a parameter. This
can also be NULL.


If success, this function will return 0.
>0 otherwise.
----------------------------------------------------*/
static herror_t
httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
                     const char *urlstr)
{

  hurl_t url;
  char buffer[4096];
  herror_t status;
  int ssl;

  if (conn == NULL)
  {
    return herror_new("httpc_talk_to_server",
                      GENERAL_INVALID_PARAM, "httpc_conn_t param is NULL");
  }
  /* Build request header */
  httpc_header_set_date(conn);

  if ((status = hurl_parse(&url, urlstr)) != H_OK)
  {
    log_error2("Can not parse URL '%s'", SAVE_STR(urlstr));
    return status;
  }
/* TODO (#1#): Check for HTTP protocol in URL */

  /* Set hostname */
  httpc_set_header(conn, HEADER_HOST, url.host);

  ssl = url.protocol == PROTOCOL_HTTPS ? 1 : 0;

  /* Open connection */
  if ((status = hsocket_open(&conn->sock, url.host, url.port, ssl)) != H_OK)
    return status;

  switch(method)
  {
    case HTTP_REQUEST_GET:

      sprintf(buffer, "GET %s HTTP/%s\r\n",
        (url.context[0] != '\0') ? url.context : ("/"),
        (conn->version == HTTP_1_0) ? "1.0" : "1.1");
      break;

    case HTTP_REQUEST_POST:

      sprintf(buffer, "POST %s HTTP/%s\r\n",
        (url.context[0] != '\0') ? url.context : ("/"),
        (conn->version == HTTP_1_0) ? "1.0" : "1.1");
      break;

    default:
      log_error1("Unknown method type!");
      return herror_new("httpc_talk_to_server",
        GENERAL_INVALID_PARAM,
        "hreq_method_t must be  HTTP_REQUEST_GET or HTTP_REQUEST_POST");
  }

  log_verbose1("Sending request...");
  if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK)
  {
    log_error2("Cannot send request (%s)", herror_message(status));
    hsocket_close(&(conn->sock));
    return status;
  }

  log_verbose1("Sending header...");
  if ((status = httpc_send_header(conn)) != H_OK)
  {
    log_error2("Cannot send header (%s)", herror_message(status));
    hsocket_close(&(conn->sock));
    return status;
  }

  return H_OK;
}