コード例 #1
0
ファイル: cache.c プロジェクト: fredollinger/dillo
/*
 *  Free the components of a CacheEntry_t struct.
 */
static void Cache_entry_free(CacheEntry_t *entry)
{
   a_Url_free((DilloUrl *)entry->Url);
   dFree(entry->TypeDet);
   dFree(entry->TypeHdr);
   dFree(entry->TypeMeta);
   dFree(entry->TypeNorm);
   dStr_free(entry->Header, TRUE);
   a_Url_free((DilloUrl *)entry->Location);
   Cache_auth_free(entry->Auth);
   dStr_free(entry->Data, 1);
   dStr_free(entry->UTF8Data, 1);
   if (entry->CharsetDecoder)
      a_Decode_free(entry->CharsetDecoder);
   if (entry->TransferDecoder)
      a_Decode_free(entry->TransferDecoder);
   if (entry->ContentDecoder)
      a_Decode_free(entry->ContentDecoder);
   dFree(entry);
}
コード例 #2
0
ファイル: cache.c プロジェクト: fredollinger/dillo
/*
 * Change Content-Type for cache entry found by url.
 * from = { "http" | "meta" }
 * Return new content type.
 */
const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype,
                                     const char *from)
{
   const char *curr;
   char *major, *minor, *charset;
   CacheEntry_t *entry = Cache_entry_search(url);

   dReturn_val_if_fail (entry != NULL, NULL);

   _MSG("a_Cache_set_content_type {%s} {%s}\n", ctype, URL_STR(url));

   curr = Cache_current_content_type(entry);
   if  (entry->TypeMeta || (*from == 'h' && entry->TypeHdr) ) {
      /* Type is already been set. Do nothing.
       * BTW, META overrides TypeHdr */
   } else {
      if (*from == 'h') {
         /* Content-Type from HTTP header */
         entry->TypeHdr = dStrdup(ctype);
      } else {
         /* Content-Type from META */
         entry->TypeMeta = dStrdup(ctype);
      }
      if (a_Misc_content_type_cmp(curr, ctype)) {
         /* ctype gives one different from current */
         a_Misc_parse_content_type(ctype, &major, &minor, &charset);
         if (*from == 'm' && charset &&
             ((!major || !*major) && (!minor || !*minor))) {
            /* META only gives charset; use detected MIME type too */
            entry->TypeNorm = dStrconcat(entry->TypeDet, ctype, NULL);
         } else if (*from == 'm' &&
                    !dStrnAsciiCasecmp(ctype, "text/xhtml", 10)) {
            /* WORKAROUND: doxygen uses "text/xhtml" in META */
            entry->TypeNorm = dStrdup(entry->TypeDet);
         }
         if (charset) {
            if (entry->CharsetDecoder)
               a_Decode_free(entry->CharsetDecoder);
            entry->CharsetDecoder = a_Decode_charset_init(charset);
            curr = Cache_current_content_type(entry);

            /* Invalidate UTF8Data */
            dStr_free(entry->UTF8Data, 1);
            entry->UTF8Data = NULL;
         }
         dFree(major); dFree(minor); dFree(charset);
      }
   }
   return curr;
}
コード例 #3
0
ファイル: cache.c プロジェクト: epitron/dillo
static void Cache_finish_msg(CacheEntry_t *entry)
{
   if (entry->Flags & CA_GotData) {
      /* already finished */
      return;
   }

   if ((entry->ExpectedSize || entry->TransferSize) &&
       entry->TypeHdr == NULL) {
      MSG_HTTP("Message with a body lacked Content-Type header.\n");
   }
   if ((entry->Flags & CA_GotLength) &&
       (entry->ExpectedSize != entry->TransferSize)) {
      MSG_HTTP("Content-Length does NOT match message body at\n"
               "%s\n", URL_STR_(entry->Url));
      MSG("Expected size: %d, Transfer size: %d\n",
          entry->ExpectedSize, entry->TransferSize);
   }
   entry->Flags |= CA_GotData;
   entry->Flags &= ~CA_Stopped;          /* it may catch up! */
   if (entry->TransferDecoder) {
      a_Decode_transfer_free(entry->TransferDecoder);
      entry->TransferDecoder = NULL;
   }
   if (entry->ContentDecoder) {
      a_Decode_free(entry->ContentDecoder);
      entry->ContentDecoder = NULL;
   }
   dStr_fit(entry->Data);                /* fit buffer size! */

   if ((entry = Cache_process_queue(entry))) {
      if (entry->Flags & CA_GotHeader) {
         Cache_unref_data(entry);
      }
   }
}
コード例 #4
0
ファイル: cache.c プロジェクト: fredollinger/dillo
/*
 * Receive new data, update the reception buffer (for next read), update the
 * cache, and service the client queue.
 *
 * This function gets called whenever the IO has new data.
 *  'Op' is the operation to perform
 *  'VPtr' is a (void) pointer to the IO control structure
 */
void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
                          const DilloUrl *Url)
{
   int offset, len;
   const char *str;
   Dstr *dstr1, *dstr2, *dstr3;
   CacheEntry_t *entry = Cache_entry_search(Url);

   /* Assert a valid entry (not aborted) */
   dReturn_if_fail (entry != NULL);

   _MSG("__a_Cache_process_dbuf__\n");

   if (Op == IORead) {
      /*
       * Cache_get_header() will set CA_GotHeader if it has a full header, and
       * Cache_parse_header() will unset it if the header ends being
       * merely an informational response from the server (i.e., 100 Continue)
       */
      for (offset = 0; !(entry->Flags & CA_GotHeader) &&
           (len = Cache_get_header(entry, buf + offset, buf_size - offset));
           Cache_parse_header(entry) ) {
         offset += len;
      }

      if (entry->Flags & CA_GotHeader) {
         str = buf + offset;
         len = buf_size - offset;
         entry->TransferSize += len;
         dstr1 = dstr2 = dstr3 = NULL;

         /* Decode arrived data (<= 3 stages) */
         if (entry->TransferDecoder) {
            dstr1 = a_Decode_process(entry->TransferDecoder, str, len);
            str = dstr1->str;
            len = dstr1->len;
         }
         if (entry->ContentDecoder) {
            dstr2 = a_Decode_process(entry->ContentDecoder, str, len);
            str = dstr2->str;
            len = dstr2->len;
         }
         dStr_append_l(entry->Data, str, len);
         if (entry->CharsetDecoder && entry->UTF8Data) {
            dstr3 = a_Decode_process(entry->CharsetDecoder, str, len);
            dStr_append_l(entry->UTF8Data, dstr3->str, dstr3->len);
         }
         dStr_free(dstr1, 1);
         dStr_free(dstr2, 1);
         dStr_free(dstr3, 1);

         if (entry->Data->len)
            entry->Flags &= ~CA_IsEmpty;

         entry = Cache_process_queue(entry);
      }
   } else if (Op == IOClose) {
      if ((entry->ExpectedSize || entry->TransferSize) &&
          entry->TypeHdr == NULL) {
         MSG_HTTP("Message with a body lacked Content-Type header.\n");
      }
      if ((entry->Flags & CA_GotLength) &&
          (entry->ExpectedSize != entry->TransferSize)) {
         MSG_HTTP("Content-Length does NOT match message body,\n"
                  " at: %s\n", URL_STR_(entry->Url));
         MSG("entry->ExpectedSize = %d, entry->TransferSize = %d\n",
             entry->ExpectedSize, entry->TransferSize);
      }
      if (!entry->TransferSize && !(entry->Flags & CA_Redirect) &&
          (entry->Flags & WEB_RootUrl)) {
         char *eol = strchr(entry->Header->str, '\n');
         if (eol) {
            char *status_line = dStrndup(entry->Header->str,
                                         eol - entry->Header->str);
            MSG_HTTP("Body was empty. Server sent status: %s\n", status_line);
            dFree(status_line);
         }
      }
      entry->Flags |= CA_GotData;
      entry->Flags &= ~CA_Stopped;          /* it may catch up! */
      if (entry->TransferDecoder) {
         a_Decode_free(entry->TransferDecoder);
         entry->TransferDecoder = NULL;
      }
      if (entry->ContentDecoder) {
         a_Decode_free(entry->ContentDecoder);
         entry->ContentDecoder = NULL;
      }
      dStr_fit(entry->Data);                /* fit buffer size! */

      if ((entry = Cache_process_queue(entry))) {
         if (entry->Flags & CA_GotHeader) {
            Cache_unref_data(entry);
         }
      }
   } else if (Op == IOAbort) {
      /* unused */
      MSG("a_Cache_process_dbuf Op = IOAbort; not implemented!\n");
   }
}