/* ** 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; }
/** \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; }
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; }