Ejemplo n.º 1
0
/*
**	This is our handle to the server reply stream when data is coming
**	back from our "client" request. It is responsible for setting up the
**	remaining streams in order to produce a complete HTTP output.
**	If we have a HTTP 1.x response then forward untouched.
*/
PRIVATE int MakeReplyPipe (HTStream * me, HTRequest * client)
{
    char * response_line = NULL;

    /* Generate the Response line */
    {
        HTAlertCallback *cbf = HTAlert_find(HT_A_MESSAGE);
        if (cbf) {
            HTAlertPar * reply = HTAlert_newReply();
            if ((*cbf)(client, HT_A_MESSAGE, HT_MSG_NULL, NULL,
                       HTRequest_error(client), reply))
                response_line = HTAlert_replyMessage(reply);
            HTAlert_deleteReply(reply);
        }

        if (response_line) {
            PUTS(response_line);
            HT_FREE(response_line);
        } else {
            PUTS(HTTP_VERSION);
            PUTS(" 500 Internal");
            PUTC(CR);
            PUTC(LF);
        }
    }

    /*
    ** We now have to create the rest of the response stream. We see whether
    ** there is a data object or not by looking at the Content Type of the
    ** client anchor.
    */
    {
        HTParentAnchor * anchor = HTRequest_anchor(client);
        HTFormat format = HTAnchor_format(anchor);
        me->target = (format == WWW_UNKNOWN) ?
                     HTTPResponse_new(client, me->target, YES, HTTP_11) :
                     HTMIMERequest_new(client,
                                       HTTPResponse_new(client,me->target, NO, HTTP_11), YES);
    }
    return HT_OK;
}
Ejemplo n.º 2
0
/** \brief Upload data to a specified URL.
*
* \param url Path to where data shall be uploaded
* \param auth (Optional) authentication information in the form of "user:password"
* \param data Data that shall be uploaded
* \param data_size size of the data
* \return Web server response
*/
PUBLIC HTTPResponse* sendHTTPData(const char *url, const char* auth, const void *data, uint32_t data_size) {
  CURL *curl_handle = NULL;
  CURLcode res;
  long rc, tries = 2, len;
  WebData* response_data = NULL;
  HTTPResponse* resp = NULL;
  char sessionKey[MAXLEN];

  struct curl_slist * headers = NULL;

  if( !url || !data ) {
    return NULL;
  }

  response_data = WebData_new(url);

  do {
    --tries;
    WebData_clear(response_data);

    if( curl_handle == NULL) {
      if(gbGlobalInitDone == FALSE) {
        curl_global_init(CURL_GLOBAL_ALL);
        gbGlobalInitDone = TRUE;
      }
      if( ( curl_handle = am_curl_init(auth, TRUE) ) ) {
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, response_data);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, response_data);
        //Transmission-specific options for HTTP POST
        if(strstr(response_data->url, "transmission") != NULL) {
          curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, parse_Transmission_response );
          headers = curl_slist_append(headers, "Content-Type: application/json");

          if( gSessionID ) {
            if((len = snprintf(sessionKey, MAXLEN, "X-Transmission-Session-Id: %s", gSessionID)) > 0) {
              sessionKey[len] = '\0';
            }

            headers = curl_slist_append(headers, sessionKey);
          }
          curl_easy_setopt( curl_handle, CURLOPT_HTTPHEADER, headers );
        }
        curl_easy_setopt(curl_handle, CURLOPT_URL, response_data->url);
      } else {
        dbg_printf(P_ERROR, "am_curl_init() failed");
        break;
      }
    }

    curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, data_size);

    if( ( res = curl_easy_perform(curl_handle) ) ) {
      dbg_printf(P_ERROR, "Upload to '%s' failed: %s", url, curl_easy_strerror(res));
      break;
    } else {
      curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &rc);
      dbg_printf(P_INFO2, "response code: %ld", rc);
      if(rc == 409) {
        if(gSessionID) {
          dbg_printf(P_DBG, "Error code 409, session ID: %s", gSessionID);
        } else {
          dbg_printf(P_ERROR, "Error code 409, no session ID");
        }

        closeCURLSession( curl_handle );
        curl_slist_free_all( headers );
        headers = NULL;
        curl_handle = NULL;
      } else {
        resp = HTTPResponse_new();
        curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &resp->responseCode);

        //copy data if present
        if(response_data->response->data) {
          resp->size = response_data->response->buffer_pos;
          resp->data = am_strndup(response_data->response->data, resp->size);
        }
        //copy filename if present
        if(response_data->content_filename) {
          resp->content_filename = am_strdup(response_data->content_filename);
        }
        break;
      }
    }
  } while(tries > 0);

  /* cleanup */
  closeCURLSession(curl_handle);

  if(headers) {
    curl_slist_free_all(headers);
  }

  WebData_free(response_data);

  return resp;
}
Ejemplo n.º 3
0
PUBLIC HTTPResponse* getHTTPData(const char *url, const char *cookies, CURL ** curl_session) {
  CURLcode      res;
  CURL         *curl_handle = NULL;
  CURL         *session = *curl_session;
  char         *escaped_url = NULL;
  WebData      *data = NULL;
  HTTPResponse *resp = NULL;
  long          responseCode = -1;

  if(!url) {
    return NULL;
  }

  data = WebData_new(url);

  if(!data) {
    return NULL;
  }

  dbg_printf(P_INFO2, "[getHTTPData] url=%s, curl_session=%p", url, (void*)session);
  if(session == NULL) {
    if(gbGlobalInitDone == FALSE) {
      curl_global_init(CURL_GLOBAL_ALL);
      gbGlobalInitDone = TRUE;
    }
    session = am_curl_init(NULL, FALSE);
    *curl_session = session;
  }

  curl_handle = session;

  if(curl_handle) {
    escaped_url = url_encode_whitespace(url);
    assert(escaped_url);
    curl_easy_setopt(curl_handle, CURLOPT_URL, escaped_url);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, data);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, data);

    if(cookies && *cookies) {
      /* if there's an explicit cookie string, use it */
      curl_easy_setopt(curl_handle, CURLOPT_COOKIE, cookies);
    } else {
      /* otherwise, enable cookie-handling since there might be cookies defined within the URL */
      curl_easy_setopt(curl_handle, CURLOPT_COOKIEFILE, "");
    }

    res = curl_easy_perform(curl_handle);
    /* curl_easy_cleanup(curl_handle); */
    curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &responseCode);
    dbg_printf(P_INFO2, "[getHTTPData] response code: %d", responseCode);
    if(res != 0) {
        dbg_printf(P_ERROR, "[getHTTPData] '%s': %s (retval: %d)", url, curl_easy_strerror(res), res);
    } else {
      /* Only the very first connection attempt (where curl_session == NULL) should store the session,
      ** and only the last one should close the session.
      */
      resp = HTTPResponse_new();
      resp->responseCode = responseCode;
      //copy data if present
      if(data->response->data) {
        resp->size = data->response->buffer_pos;
        resp->data = am_strndup(data->response->data, resp->size);
      }
      //copy filename if present
      if(data->content_filename) {
        resp->content_filename = am_strdup(data->content_filename);
      }
    }
    am_free(escaped_url);
  } else {
    dbg_printf(P_ERROR, "curl_handle is uninitialized!");
    resp = NULL;
  }
  WebData_free(data);
  return resp;
}