/* * Returns a message to the client ; the connection is shut down for read, * and the request is cleared so that no server connection can be initiated. * The buffer is marked for read shutdown on the other side to protect the * message, and the buffer write is enabled. The message is contained in a * "chunk". If it is null, then an empty message is used. The reply buffer does * not need to be empty before this, and its contents will not be overwritten. * The primary goal of this function is to return error messages to a client. */ void stream_int_retnclose(struct stream_interface *si, const struct chunk *msg) { buffer_auto_read(si->ib); buffer_abort(si->ib); buffer_auto_close(si->ib); buffer_erase(si->ib); if (likely(msg && msg->len)) buffer_write(si->ob, msg->str, msg->len); si->ob->wex = tick_add_ifset(now_ms, si->ob->wto); buffer_auto_read(si->ob); buffer_auto_close(si->ob); buffer_shutr_now(si->ob); }
/* This analyser tries to fetch a line from the request buffer which looks like : * * "PROXY" <SP> PROTO <SP> SRC3 <SP> DST3 <SP> SRC4 <SP> <DST4> "\r\n" * * There must be exactly one space between each field. Fields are : * - PROTO : layer 4 protocol, which must be "TCP4" or "TCP6". * - SRC3 : layer 3 (eg: IP) source address in standard text form * - DST3 : layer 3 (eg: IP) destination address in standard text form * - SRC4 : layer 4 (eg: TCP port) source address in standard text form * - DST4 : layer 4 (eg: TCP port) destination address in standard text form * * This line MUST be at the beginning of the buffer and MUST NOT wrap. * * Once the data is fetched, the values are set in the session's field and data * are removed from the buffer. The function returns zero if it needs to wait * for more data (max: timeout_client), or 1 if it has finished and removed itself. */ int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_bit) { char *line = req->data; char *end = req->data + req->l; int len; DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n", now_ms, __FUNCTION__, s, req, req->rex, req->wex, req->flags, req->l, req->analysers); if (req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT)) goto fail; len = MIN(req->l, 6); if (!len) goto missing; /* Decode a possible proxy request, fail early if it does not match */ if (strncmp(line, "PROXY ", len) != 0) goto fail; line += 6; if (req->l < 18) /* shortest possible line */ goto missing; if (!memcmp(line, "TCP4 ", 5) != 0) { u32 src3, dst3, sport, dport; line += 5; src3 = inetaddr_host_lim_ret(line, end, &line); if (line == end) goto missing; if (*line++ != ' ') goto fail; dst3 = inetaddr_host_lim_ret(line, end, &line); if (line == end) goto missing; if (*line++ != ' ') goto fail; sport = read_uint((const char **)&line, end); if (line == end) goto missing; if (*line++ != ' ') goto fail; dport = read_uint((const char **)&line, end); if (line > end - 2) goto missing; if (*line++ != '\r') goto fail; if (*line++ != '\n') goto fail; /* update the session's addresses and mark them set */ ((struct sockaddr_in *)&s->si[0].addr.from)->sin_family = AF_INET; ((struct sockaddr_in *)&s->si[0].addr.from)->sin_addr.s_addr = htonl(src3); ((struct sockaddr_in *)&s->si[0].addr.from)->sin_port = htons(sport); ((struct sockaddr_in *)&s->si[0].addr.to)->sin_family = AF_INET; ((struct sockaddr_in *)&s->si[0].addr.to)->sin_addr.s_addr = htonl(dst3); ((struct sockaddr_in *)&s->si[0].addr.to)->sin_port = htons(dport); s->flags |= SN_FRT_ADDR_SET; } else if (!memcmp(line, "TCP6 ", 5) != 0) { u32 sport, dport; char *src_s; char *dst_s, *sport_s, *dport_s; struct in6_addr src3, dst3; line+=5; src_s = line; dst_s = sport_s = dport_s = NULL; while (1) { if (line > end - 2) { goto missing; } else if (*line == '\r') { *line = 0; line++; if (*line++ != '\n') goto fail; break; } if (*line == ' ') { *line = 0; if (!dst_s) dst_s = line+1; else if (!sport_s) sport_s = line+1; else if (!dport_s) dport_s = line+1; } line++; } if (!dst_s || !sport_s || !dport_s) goto fail; sport = read_uint((const char **)&sport_s,dport_s-1); if ( *sport_s != 0 ) goto fail; dport = read_uint((const char **)&dport_s,line-2); if ( *dport_s != 0 ) goto fail; if (inet_pton(AF_INET6, src_s, (void *)&src3) != 1) goto fail; if (inet_pton(AF_INET6, dst_s, (void *)&dst3) != 1) goto fail; /* update the session's addresses and mark them set */ ((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_family = AF_INET6; memcpy(&((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_addr, &src3, sizeof(struct in6_addr)); ((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_port = htons(sport); ((struct sockaddr_in6 *)&s->si[0].addr.to)->sin6_family = AF_INET6; memcpy(&((struct sockaddr_in6 *)&s->si[0].addr.to)->sin6_addr, &dst3, sizeof(struct in6_addr)); ((struct sockaddr_in6 *)&s->si[0].addr.to)->sin6_port = htons(dport); s->flags |= SN_FRT_ADDR_SET; } else { goto fail; } /* remove the PROXY line from the request */ len = line - req->data; buffer_replace2(req, req->data, line, NULL, 0); req->total -= len; /* don't count the header line */ req->analysers &= ~an_bit; return 1; missing: if (!(req->flags & (BF_SHUTR|BF_FULL))) { buffer_dont_connect(s->req); return 0; } /* missing data and buffer is either full or shutdown => fail */ fail: buffer_abort(req); buffer_abort(s->rep); req->analysers = 0; s->fe->fe_counters.failed_req++; if (s->listener->counters) s->listener->counters->failed_req++; if (!(s->flags & SN_ERR_MASK)) s->flags |= SN_ERR_PRXCOND; if (!(s->flags & SN_FINST_MASK)) s->flags |= SN_FINST_R; return 0; }
int bbdocument_add(char subname[],char documenturi[],char documenttype[],char document[],const int dokument_size,unsigned int lastmodified,char *acl_allow, char *acl_denied,const char title[], char doctype[], char *attributes, container *attrkeys) { struct ReposetoryHeaderFormat ReposetoryHeader; int htmlbuffersize = 0;//((dokument_size *2) +512); //+512 da vi skal ha med div meta data, som html kode char *htmlbuffer = NULL;// = malloc(htmlbuffersize); char *imagebuffer; char *documenttype_real; size_t imageSize; unsigned int DocIDForExistTest; unsigned int lastmodifiedForExistTest; struct hashtable *metahash = NULL; buffer *documentbuffer; memset(&ReposetoryHeader,0,sizeof(ReposetoryHeader)); printf("bbdocument_add: \"%s\"\n",documenturi); printf("bbdocument_add: Attributes = \"%s\" (", attributes); if (attrkeys!=NULL) printf("+)\n"); else printf(" )\n"); //tester at det ikke finnes først. Hvis det finnes hånterer vi det. Eventuelt også lagre den nye versjonen hvis det er forandret. if (uriindex_get(documenturi,&DocIDForExistTest,&lastmodifiedForExistTest,subname)) { if (lastmodifiedForExistTest == lastmodified) { printf("bbdocument_add: Uri \"%s\" all redy exist with DocID \"%u\" and time \"%u\"\n",documenturi,DocIDForExistTest,lastmodifiedForExistTest); return 1; } //hvis url er kjent, men oppdater rebruker vi den. ReposetoryHeader.DocID = DocIDForExistTest; } else { //hvis vi ikke har DocID har vi et system som trenger å få opprettet det. For eks bb eller bdisk. ReposetoryHeader.DocID = rGeneraeADocID(subname); #ifdef DEBUG printf("Dident have a known DocID for document. Did generet on. DOcID is now %u\n",ReposetoryHeader.DocID); #endif } // hvis vi har en "text applicatino" enkoding, som ikke er en vanlig tekst fil, men tekst som kommer fra // en apllikasjon behandler vi det som text. //if (strcmp(documenttype,"tapp") == 0) { // documenttype_real = strdup("text"); //} //else if (documenttype[0] == '\0') { if ((documenttype_real = sfindductype(documenturi)) == NULL) { printf("Will use .none as documenttype because I can't decide format. File name isent dos type (8.3): %s\n", documenturi); documenttype_real = strdup("none"); } } else { documenttype_real = malloc(strlen(documenttype)+1); strcpy(documenttype_real,documenttype); } //hvis vi ikke her med noen egen doctype så bruker vi den vi har fått via documenttype if (doctype[0] == '\0') { //vi trenger ikke å ha \0 på slutten her strncpy(ReposetoryHeader.doctype,documenttype_real,sizeof(ReposetoryHeader.doctype)); } else { //vi trenger ikke å ha \0 på slutten her strncpy(ReposetoryHeader.doctype,doctype,sizeof(ReposetoryHeader.doctype)); } documentbuffer = buffer_init(0); if (!bbdocument_convert(documenttype_real,document,dokument_size,documentbuffer,title,subname,documenturi, lastmodified,acl_allow, acl_denied, &metahash)) { printf("can't run bbdocument_convert\n"); //lager en tom html buffer //Setter titelen som subjekt. Hva hvis vi ikke har title? htmlbuffersize = strlen(html_text_tempelate) + strlen(title) + 1; htmlbuffer = malloc(htmlbuffersize); snprintf(htmlbuffer, htmlbuffersize, html_text_tempelate,title,""); htmlbuffersize = strlen(htmlbuffer); printf("useing title \"%s\" as title\n",title); printf("htmlbuffersize %i\n",htmlbuffersize); free(buffer_abort(documentbuffer)); } else { htmlbuffersize = buffer_length(documentbuffer); htmlbuffer = buffer_exit(documentbuffer); } buffer *attrbuffer = buffer_init(-1); bprintf(attrbuffer, "%s,", attributes); if (metahash) { struct hashtable_itr *itr; if (hashtable_count(metahash) > 0) { itr = hashtable_iterator(metahash); do { char *key, *value; key = hashtable_iterator_key(itr); value = hashtable_iterator_value(itr); printf("%s: Key: %s Value: %s\n", documenttype_real, key, value); if (strcmp(key, "lastmodified") == 0) { lastmodified = atol(value); continue; } bprintf(attrbuffer, "%s=%s,", key, value); } while (hashtable_iterator_advance(itr)); free(itr); } hashtable_destroy(metahash, 1); } char *all_attributes = buffer_exit(attrbuffer); //prøver å lag et bilde //if ( (imagebuffer = generate_thumbnail( document, dokument_size, &imageSize )) == NULL ) { if (!bbdocument_makethumb(documenttype_real,document,dokument_size,&imagebuffer,&imageSize)) { printf("can't generate image\n"); ReposetoryHeader.imageSize = 0; imagebuffer = NULL; } else { debug("generated image\n"); ReposetoryHeader.imageSize = imageSize; } ReposetoryHeader.clientVersion = 2.14; //runarb: 8 juli 2008: tar bort bruken av ReposetoryHeader's url //runarb: 11 juli 2008: kan ikke gjøre dette, da vi kopierer den inn i DocumentIndex fra ReposetoryHeader strncpy(ReposetoryHeader.url,documenturi,sizeof(ReposetoryHeader.url)); ReposetoryHeader.response = 200; strcpy(ReposetoryHeader.content_type,"htm"); ReposetoryHeader.acl_allowSize = strlen(acl_allow); #ifdef IIACL ReposetoryHeader.acl_deniedSize = strlen(acl_denied); #endif ReposetoryHeader.time = lastmodified; ReposetoryHeader.storageTime = 0; //setes automatisk av rApendPostcompress #ifdef DEBUG printf("ACL was allow \"%s\", %i bytes, denied \"%s\", %i bytes\nsubname %s\n",acl_allow,ReposetoryHeader.acl_allowSize,acl_allow,ReposetoryHeader.acl_allowSize,subname); #endif ReposetoryHeader.urllen = strlen(documenturi); ReposetoryHeader.attributeslen = strlen(all_attributes); rApendPostcompress(&ReposetoryHeader, htmlbuffer, imagebuffer, subname, acl_allow, acl_denied, NULL, documenturi, all_attributes, attrkeys, htmlbuffersize); #ifdef DEBUG printf("legger til DocID \"%u\", time \"%u\"\n",ReposetoryHeader.DocID,lastmodified); printf("htmlSize %u, imageSize %ho\n",ReposetoryHeader.htmlSize2,ReposetoryHeader.imageSize); printf("html: -%s-\n",htmlbuffer); #endif uriindex_add(documenturi,ReposetoryHeader.DocID,lastmodified,subname); free(all_attributes); free(htmlbuffer); free(documenttype_real); if (imagebuffer != NULL) { free(imagebuffer); } return 1; }