herror_t
httpc_mime_begin(httpc_conn_t * conn, const char *url,
                 const char *related_start,
                 const char *related_start_info, const char *related_type)
{
  herror_t status;
  char buffer[300];
  char temp[75];
  char boundary[75];

  /* 
     Set Content-type Set multipart/related parameter type=..; start=.. ;
     start-info= ..; boundary=...

   */
  sprintf(buffer, "multipart/related;");
  /* 
     using sprintf instead of snprintf because visual c does not support
     snprintf */
#ifdef WIN32
#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2)
#endif

  if (related_type)
  {
    snprintf(temp, 75, " type=\"%s\";", related_type);
    strcat(buffer, temp);
  }

  if (related_start)
  {
    snprintf(temp, 75, " start=\"%s\";", related_start);
    strcat(buffer, temp);
  }

  if (related_start_info)
  {
    snprintf(temp, 75, " start-info=\"%s\";", related_start_info);
    strcat(buffer, temp);
  }

  _httpc_mime_get_boundary(conn, boundary);
  snprintf(temp, 75, " boundary=\"%s\"", boundary);
  strcat(buffer, temp);

  httpc_set_header(conn, HEADER_CONTENT_TYPE, buffer);

  status = httpc_post_begin(conn, url);
  return status;
}
/*--------------------------------------------------
FUNCTION: httpc_header_set_date
DESC: Adds the current date to the header.
----------------------------------------------------*/
static void
httpc_header_set_date(httpc_conn_t * conn)
{
  char buffer[32];
  time_t ts;
  struct tm stm;

  ts = time(NULL);
  localtime_r(&ts, &stm);
  strftime(buffer, 32, "%a, %d %b %Y %H:%M:%S GMT", &stm);

  httpc_set_header(conn, HEADER_DATE, buffer);

  return;
}
static int
_httpc_set_basic_authorization_header(httpc_conn_t *conn, const char *key, const char *user, const char *password)
{
  /* XXX: use malloc/free */
  char in[64], out[64];

  if (!user)
    user = "";

  if (!password)
    password = "";

  memset(in, 0, 64);
  memset(out, 0, 64);

  sprintf(in, "%s:%s", user, password);

  base64_encode(in, out);

  sprintf(in, "Basic %s", out);

  return httpc_set_header(conn, key, in);
}
Esempio n. 4
0
int main(int argc, char **argv)
{
  httpc_conn_t *conn; /* Client connection object */
  hresponse_t *res; /* Response object **/

  herror_t status;
  FILE *f;
  size_t size;
  char url[50], file[50], id[50], content_type[50];
  
  char buffer[MAX_BUFFER_SIZE+1];

  /* Check usage */
  if (argc < 5)
  {
    fprintf(stderr, "usage %s <url> <file> <id> <content-type>\n", argv[0]);
    exit(1);
  }

  /* Set log level to see more information written by the library */
  // log_set_level(NANOHTTP_LOG_VERBOSE);

  /* Initialize httpc module */
  if ((status = httpc_init(argc, argv)) != H_OK)
  {
    fprintf(stderr, "Cannot init httpc (%s)\n", herror_message(status));
    herror_release(status);
    return 1;
  }

  /* Create the client connection object */
  conn = httpc_new();

  httpc_set_header(conn, HEADER_TRANSFER_ENCODING, TRANSFER_ENCODING_CHUNKED);

  /*
   Open connection for mime
   */
  if ((status = httpc_mime_begin(conn, argv[1], argv[3], "", argv[4])) != H_OK)
  {
    fprintf(stderr, "Can not start MIME: %s\n", herror_message(status));
    herror_release(status);
    exit(1);
  }

  if (!send_file(conn,  argv[2], argv[3], argv[4]))
  {
    fprintf(stderr, "send_file failed\n");
    exit(1);
  }

  while (1)
  {
    printf("Enter filename ['.' for finish]: ");
    gets(file);
    if (!strcmp(file, "."))
       break;

    printf("Enter part id:");
    gets(id);
    printf("Enter content-type:");
    gets(content_type);

    if (!send_file(conn, file, id, content_type))
       exit(1);
  }

  if ((status = httpc_mime_end(conn, &res)) != H_OK)
  {
    fprintf(stderr, "httpc_mime_end failed (%s)\n", herror_message(status));
    herror_release(status);
    exit(1);
  }

   /* Show response */
  show_response(res);

  /* clean up*/
  hresponse_free(res);
  httpc_free(conn);
  return 0;
}
/*--------------------------------------------------
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;
}