/* ** 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; }
/* Save Locally ** ------------ ** Saves a file to local disk. This can for example be used to dump ** data objects of unknown media types to local disk. The stream prompts ** for a file name for the temporary file. */ PUBLIC HTStream* HTSaveLocally (HTRequest * request, void * param, HTFormat input_format, HTFormat output_format, HTStream * output_stream) { FILE * fp = NULL; char * filename = NULL; HTUserProfile * up = HTRequest_userProfile(request); char * tmproot = HTUserProfile_tmp(up); if (HTLib_secure()) { HTRequest_addError(request, ERR_NON_FATAL, NO, HTERR_UNAUTHORIZED, NULL, 0, "HTSaveLocally"); return HTErrorStream(); } if (!tmproot) { HTTRACE(STREAM_TRACE, "Save File... turned off\n"); return HTErrorStream(); } /* Let's prompt the user for a file name for this file */ { HTAlertCallback *cbf = HTAlert_find(HT_A_PROMPT); HTParentAnchor *anchor = (HTParentAnchor *) HTRequest_anchor(request); /* ** If we found an alert handler for prompting the user then call it. ** If not then either we are in non-interactive mode or no handler ** has been registered. For now we then return a blackhole which may ** not be the best thing to do. */ if (cbf) { HTAlertPar * reply = HTAlert_newReply(); char * suffix = HTBind_getSuffix(anchor); char * deflt = get_filename(tmproot, HTAnchor_physical(anchor), suffix, YES); if ((*cbf)(request, HT_A_PROMPT, HT_MSG_FILENAME,deflt,NULL,reply)) filename = HTAlert_replyMessage(reply); HTAlert_deleteReply(reply); HT_FREE(suffix); HT_FREE(deflt); } if (filename) { if ((fp = fopen(filename, "wb")) == NULL) { HTRequest_addError(request, ERR_NON_FATAL, NO, HTERR_NO_FILE, filename, strlen(filename),"HTSaveLocally"); HT_FREE(filename); return HTErrorStream(); } } else if (cbf) { HTTRACE(STREAM_TRACE, "Save File... No file name - error stream\n"); return HTErrorStream(); } else { HTTRACE(STREAM_TRACE, "Save File... No file name - black hole\n"); return HTBlackHole(); } } /* Now we are ready for creating the file writer stream */ if (fp) { HTStream * me = HTFileSave_new(request, fp, NO); me->filename = filename; return me; } HT_FREE(filename); return HTErrorStream(); }