Пример #1
0
/* this huge function handles extended services */
int ztest_esrequest (void *handle, bend_esrequest_rr *rr)
{
    /* user-defined handle - created in bend_init */
    int *counter = (int*) handle;  

    yaz_log(LOG_LOG, "ESRequest no %d", *counter);

    (*counter)++;

    if (rr->esr->packageName)
    	yaz_log(LOG_LOG, "packagename: %s", rr->esr->packageName);
    yaz_log(LOG_LOG, "Waitaction: %d", *rr->esr->waitAction);


    yaz_log(LOG_LOG, "function: %d", *rr->esr->function);

    if (!rr->esr->taskSpecificParameters)
    {
        yaz_log (LOG_WARN, "No task specific parameters");
    }
    else if (rr->esr->taskSpecificParameters->which == Z_External_itemOrder)
    {
    	Z_ItemOrder *it = rr->esr->taskSpecificParameters->u.itemOrder;
	yaz_log (LOG_LOG, "Received ItemOrder");
        if (it->which == Z_IOItemOrder_esRequest)
	{
	    Z_IORequest *ir = it->u.esRequest;
	    Z_IOOriginPartToKeep *k = ir->toKeep;
	    Z_IOOriginPartNotToKeep *n = ir->notToKeep;
	    
	    if (k && k->contact)
	    {
	        if (k->contact->name)
		    yaz_log(LOG_LOG, "contact name %s", k->contact->name);
		if (k->contact->phone)
		    yaz_log(LOG_LOG, "contact phone %s", k->contact->phone);
		if (k->contact->email)
		    yaz_log(LOG_LOG, "contact email %s", k->contact->email);
	    }
	    if (k->addlBilling)
	    {
	        yaz_log(LOG_LOG, "Billing info (not shown)");
	    }
	    
	    if (n->resultSetItem)
	    {
	        yaz_log(LOG_LOG, "resultsetItem");
		yaz_log(LOG_LOG, "setId: %s", n->resultSetItem->resultSetId);
		yaz_log(LOG_LOG, "item: %d", *n->resultSetItem->item);
	    }
	    if (n->itemRequest)
	    {
		Z_External *r = (Z_External*) n->itemRequest;
		ILL_ItemRequest *item_req = 0;
		ILL_APDU *ill_apdu = 0;
		if (r->direct_reference)
		{
		    oident *ent = oid_getentbyoid(r->direct_reference);
		    if (ent)
			yaz_log(LOG_LOG, "OID %s", ent->desc);
                    if (ent && ent->value == VAL_TEXT_XML)
                    {
			yaz_log (LOG_LOG, "ILL XML request");
                        if (r->which == Z_External_octet)
                            yaz_log (LOG_LOG, "%.*s", r->u.octet_aligned->len,
                                     r->u.octet_aligned->buf); 
                    }
		    if (ent && ent->value == VAL_ISO_ILL_1)
		    {
			yaz_log (LOG_LOG, "Decode ItemRequest begin");
			if (r->which == ODR_EXTERNAL_single)
			{
			    odr_setbuf(rr->decode,
				       (char *) r->u.single_ASN1_type->buf,
				       r->u.single_ASN1_type->len, 0);
			    
			    if (!ill_ItemRequest (rr->decode, &item_req, 0, 0))
			    {
				yaz_log (LOG_LOG,
                                    "Couldn't decode ItemRequest %s near %d",
                                       odr_errmsg(odr_geterror(rr->decode)),
                                       odr_offset(rr->decode));
                            }
			    else
			        yaz_log(LOG_LOG, "Decode ItemRequest OK");
			    if (rr->print)
			    {
				ill_ItemRequest (rr->print, &item_req, 0,
                                    "ItemRequest");
				odr_reset (rr->print);
 			    }
			}
			if (!item_req && r->which == ODR_EXTERNAL_single)
			{
			    yaz_log (LOG_LOG, "Decode ILL APDU begin");
			    odr_setbuf(rr->decode,
				       (char*) r->u.single_ASN1_type->buf,
				       r->u.single_ASN1_type->len, 0);
			    
			    if (!ill_APDU (rr->decode, &ill_apdu, 0, 0))
			    {
				yaz_log (LOG_LOG,
                                    "Couldn't decode ILL APDU %s near %d",
                                       odr_errmsg(odr_geterror(rr->decode)),
                                       odr_offset(rr->decode));
                                yaz_log(LOG_LOG, "PDU dump:");
                                odr_dumpBER(yaz_log_file(),
                                     (char *) r->u.single_ASN1_type->buf,
                                     r->u.single_ASN1_type->len);
                            }
			    else
			        yaz_log(LOG_LOG, "Decode ILL APDU OK");
			    if (rr->print)
                            {
				ill_APDU (rr->print, &ill_apdu, 0,
                                    "ILL APDU");
				odr_reset (rr->print);
			    }
			}
		    }
		}
		if (item_req)
		{
		    yaz_log (LOG_LOG, "ILL protocol version = %d",
			     *item_req->protocol_version_num);
		}
	    }
            if (k)
            {

		Z_External *ext = (Z_External *)
                    odr_malloc (rr->stream, sizeof(*ext));
		Z_IUOriginPartToKeep *keep = (Z_IUOriginPartToKeep *)
                    odr_malloc (rr->stream, sizeof(*keep));
		Z_IOTargetPart *targetPart = (Z_IOTargetPart *)
		    odr_malloc (rr->stream, sizeof(*targetPart));

		rr->taskPackage = (Z_TaskPackage *)
                    odr_malloc (rr->stream, sizeof(*rr->taskPackage));
		rr->taskPackage->packageType =
		    odr_oiddup (rr->stream, rr->esr->packageType);
		rr->taskPackage->packageName = 0;
		rr->taskPackage->userId = 0;
		rr->taskPackage->retentionTime = 0;
		rr->taskPackage->permissions = 0;
		rr->taskPackage->description = 0;
		rr->taskPackage->targetReference = (Odr_oct *)
		    odr_malloc (rr->stream, sizeof(Odr_oct));
		rr->taskPackage->targetReference->buf =
		    (unsigned char *) odr_strdup (rr->stream, "911");
		rr->taskPackage->targetReference->len =
		    rr->taskPackage->targetReference->size =
		    strlen((char *) (rr->taskPackage->targetReference->buf));
		rr->taskPackage->creationDateTime = 0;
		rr->taskPackage->taskStatus = odr_intdup(rr->stream, 0);
		rr->taskPackage->packageDiagnostics = 0;
		rr->taskPackage->taskSpecificParameters = ext;

		ext->direct_reference =
		    odr_oiddup (rr->stream, rr->esr->packageType);
		ext->indirect_reference = 0;
		ext->descriptor = 0;
		ext->which = Z_External_itemOrder;
		ext->u.itemOrder = (Z_ItemOrder *)
		    odr_malloc (rr->stream, sizeof(*ext->u.update));
		ext->u.itemOrder->which = Z_IOItemOrder_taskPackage;
		ext->u.itemOrder->u.taskPackage =  (Z_IOTaskPackage *)
		    odr_malloc (rr->stream, sizeof(Z_IOTaskPackage));
		ext->u.itemOrder->u.taskPackage->originPart = k;
		ext->u.itemOrder->u.taskPackage->targetPart = targetPart;

                targetPart->itemRequest = 0;
                targetPart->statusOrErrorReport = 0;
                targetPart->auxiliaryStatus = 0;
            }
	}
    }
    else if (rr->esr->taskSpecificParameters->which == Z_External_update)
    {
    	Z_IUUpdate *up = rr->esr->taskSpecificParameters->u.update;
	yaz_log (LOG_LOG, "Received DB Update");
	if (up->which == Z_IUUpdate_esRequest)
	{
	    Z_IUUpdateEsRequest *esRequest = up->u.esRequest;
	    Z_IUOriginPartToKeep *toKeep = esRequest->toKeep;
	    Z_IUSuppliedRecords *notToKeep = esRequest->notToKeep;
	    
	    yaz_log (LOG_LOG, "action");
	    if (toKeep->action)
	    {
		switch (*toKeep->action)
		{
		case Z_IUOriginPartToKeep_recordInsert:
		    yaz_log (LOG_LOG, " recordInsert");
		    break;
		case Z_IUOriginPartToKeep_recordReplace:
		    yaz_log (LOG_LOG, " recordReplace");
		    break;
		case Z_IUOriginPartToKeep_recordDelete:
		    yaz_log (LOG_LOG, " recordDelete");
		    break;
		case Z_IUOriginPartToKeep_elementUpdate:
		    yaz_log (LOG_LOG, " elementUpdate");
		    break;
		case Z_IUOriginPartToKeep_specialUpdate:
		    yaz_log (LOG_LOG, " specialUpdate");
		    break;
		default:
		    yaz_log (LOG_LOG, " unknown (%d)", *toKeep->action);
		}
	    }
	    if (toKeep->databaseName)
	    {
		yaz_log (LOG_LOG, "database: %s", toKeep->databaseName);
		if (!strcmp(toKeep->databaseName, "fault"))
		{
		    rr->errcode = 109;
		    rr->errstring = toKeep->databaseName;
		}
		if (!strcmp(toKeep->databaseName, "accept"))
		    rr->errcode = -1;
	    }
	    if (toKeep)
	    {
		Z_External *ext = (Z_External *)
                    odr_malloc (rr->stream, sizeof(*ext));
		Z_IUOriginPartToKeep *keep = (Z_IUOriginPartToKeep *)
                    odr_malloc (rr->stream, sizeof(*keep));
		Z_IUTargetPart *targetPart = (Z_IUTargetPart *)
		    odr_malloc (rr->stream, sizeof(*targetPart));

		rr->taskPackage = (Z_TaskPackage *)
                    odr_malloc (rr->stream, sizeof(*rr->taskPackage));
		rr->taskPackage->packageType =
		    odr_oiddup (rr->stream, rr->esr->packageType);
		rr->taskPackage->packageName = 0;
		rr->taskPackage->userId = 0;
		rr->taskPackage->retentionTime = 0;
		rr->taskPackage->permissions = 0;
		rr->taskPackage->description = 0;
		rr->taskPackage->targetReference = (Odr_oct *)
		    odr_malloc (rr->stream, sizeof(Odr_oct));
		rr->taskPackage->targetReference->buf =
		    (unsigned char *) odr_strdup (rr->stream, "123");
		rr->taskPackage->targetReference->len =
		    rr->taskPackage->targetReference->size =
		    strlen((char *) (rr->taskPackage->targetReference->buf));
		rr->taskPackage->creationDateTime = 0;
		rr->taskPackage->taskStatus = odr_intdup(rr->stream, 0);
		rr->taskPackage->packageDiagnostics = 0;
		rr->taskPackage->taskSpecificParameters = ext;

		ext->direct_reference =
		    odr_oiddup (rr->stream, rr->esr->packageType);
		ext->indirect_reference = 0;
		ext->descriptor = 0;
		ext->which = Z_External_update;
		ext->u.update = (Z_IUUpdate *)
		    odr_malloc (rr->stream, sizeof(*ext->u.update));
		ext->u.update->which = Z_IUUpdate_taskPackage;
		ext->u.update->u.taskPackage =  (Z_IUUpdateTaskPackage *)
		    odr_malloc (rr->stream, sizeof(Z_IUUpdateTaskPackage));
		ext->u.update->u.taskPackage->originPart = keep;
		ext->u.update->u.taskPackage->targetPart = targetPart;

		keep->action = (int *) odr_malloc (rr->stream, sizeof(int));
		*keep->action = *toKeep->action;
		keep->databaseName =
		    odr_strdup (rr->stream, toKeep->databaseName);
		keep->schema = 0;
		keep->elementSetName = 0;
		keep->actionQualifier = 0;

		targetPart->updateStatus = odr_intdup (rr->stream, 1);
		targetPart->num_globalDiagnostics = 0;
		targetPart->globalDiagnostics = (Z_DiagRec **) odr_nullval();
		targetPart->num_taskPackageRecords = 1;
		targetPart->taskPackageRecords = 
                    (Z_IUTaskPackageRecordStructure **)
                    odr_malloc (rr->stream,
                                sizeof(Z_IUTaskPackageRecordStructure *));
		targetPart->taskPackageRecords[0] =
                    (Z_IUTaskPackageRecordStructure *)
                    odr_malloc (rr->stream,
                                sizeof(Z_IUTaskPackageRecordStructure));
                
		targetPart->taskPackageRecords[0]->which =
                    Z_IUTaskPackageRecordStructure_record;
		targetPart->taskPackageRecords[0]->u.record = 
                    z_ext_record (rr->stream, VAL_SUTRS, "test", 4);
		targetPart->taskPackageRecords[0]->correlationInfo = 0; 
		targetPart->taskPackageRecords[0]->recordStatus =
                    odr_intdup (rr->stream,
                                Z_IUTaskPackageRecordStructure_success);  
		targetPart->taskPackageRecords[0]->num_supplementalDiagnostics
                    = 0;

		targetPart->taskPackageRecords[0]->supplementalDiagnostics = 0;
            }
	    if (notToKeep)
	    {
		int i;
		for (i = 0; i < notToKeep->num; i++)
		{
		    Z_External *rec = notToKeep->elements[i]->record;

		    if (rec->direct_reference)
		    {
			struct oident *oident;
			oident = oid_getentbyoid(rec->direct_reference);
			if (oident)
			    yaz_log (LOG_LOG, "record %d type %s", i,
				     oident->desc);
		    }
		    switch (rec->which)
		    {
		    case Z_External_sutrs:
			if (rec->u.octet_aligned->len > 170)
			    yaz_log (LOG_LOG, "%d bytes:\n%.168s ...",
				     rec->u.sutrs->len,
				     rec->u.sutrs->buf);
			else
			    yaz_log (LOG_LOG, "%d bytes:\n%s",
				     rec->u.sutrs->len,
				     rec->u.sutrs->buf);
                        break;
		    case Z_External_octet        :
			if (rec->u.octet_aligned->len > 170)
			    yaz_log (LOG_LOG, "%d bytes:\n%.168s ...",
				     rec->u.octet_aligned->len,
				     rec->u.octet_aligned->buf);
			else
			    yaz_log (LOG_LOG, "%d bytes\n%s",
				     rec->u.octet_aligned->len,
				     rec->u.octet_aligned->buf);
		    }
		}
	    }
	}
    }
    else if (rr->esr->taskSpecificParameters->which == Z_External_update0)
    {
	yaz_log(LOG_LOG, "Received DB Update (version 0)");
    }
    else
    {
        yaz_log (LOG_WARN, "Unknown Extended Service(%d)",
		 rr->esr->taskSpecificParameters->which);
	
    }
    return 0;
}
Пример #2
0
Z_HTTP_Response *yaz_url_exec(yaz_url_t p, const char *uri,
                              const char *method,
                              Z_HTTP_Header *user_headers,
                              const char *buf, size_t len)
{
    Z_HTTP_Response *res = 0;
    int number_of_redirects = 0;

    yaz_cookies_reset(p->cookies);
    wrbuf_rewind(p->w_error);
    while (1)
    {
        void *add;
        COMSTACK conn = 0;
        int code;
        const char *location = 0;
        char *http_user = 0;
        char *http_pass = 0;
        char *uri_lean = 0;
        Z_GDU *gdu;

        extract_user_pass(p->odr_out->mem, uri, &uri_lean,
                          &http_user, &http_pass);

        gdu = z_get_HTTP_Request_uri(p->odr_out, uri_lean, 0, p->proxy ? 1 : 0);
        gdu->u.HTTP_Request->method = odr_strdup(p->odr_out, method);

        yaz_cookies_request(p->cookies, p->odr_out, gdu->u.HTTP_Request);
        for ( ; user_headers; user_headers = user_headers->next)
        {
            /* prefer new Host over user-supplied Host */
            if (!strcmp(user_headers->name, "Host"))
                ;
            /* prefer user-supplied User-Agent over YAZ' own */
            else if (!strcmp(user_headers->name, "User-Agent"))
                z_HTTP_header_set(p->odr_out, &gdu->u.HTTP_Request->headers,
                                  user_headers->name, user_headers->value);
            else
                z_HTTP_header_add(p->odr_out, &gdu->u.HTTP_Request->headers,
                                  user_headers->name, user_headers->value);
        }
        if (http_user && http_pass)
            z_HTTP_header_add_basic_auth(p->odr_out,
                                         &gdu->u.HTTP_Request->headers,
                                         http_user, http_pass);

        res = 0;
        if (buf && len)
        {
            gdu->u.HTTP_Request->content_buf = (char *) buf;
            gdu->u.HTTP_Request->content_len = len;
        }
        if (!z_GDU(p->odr_out, &gdu, 0, 0))
        {
            wrbuf_printf(p->w_error, "Can not encode HTTP request for URL %s",
                         uri);
            log_warn(p);
            return 0;
        }
        conn = cs_create_host_proxy(uri_lean, 1, &add, p->proxy);
        if (!conn)
        {
            wrbuf_printf(p->w_error, "Can not resolve URL %s", uri);
            log_warn(p);
        }
        else if (cs_connect(conn, add) < 0)
        {
            wrbuf_printf(p->w_error, "Can not connect to URL %s", uri);
            log_warn(p);
        }
        else
        {
            int len;
            char *buf = odr_getbuf(p->odr_out, &len, 0);

            if (p->verbose)
                fwrite(buf, 1, len, stdout);

            if (cs_put(conn, buf, len) < 0)
            {
                wrbuf_printf(p->w_error, "cs_put fail for URL %s", uri);
                log_warn(p);
            }
            else
            {
                char *netbuffer = 0;
                int netlen = 0;
                int cs_res = cs_get(conn, &netbuffer, &netlen);
                if (cs_res <= 0)
                {
                    wrbuf_printf(p->w_error, "cs_get failed for URL %s", uri);
                    log_warn(p);
                }
                else
                {
                    Z_GDU *gdu;
                    if (p->verbose)
                        fwrite(netbuffer, 1, cs_res, stdout);
                    odr_setbuf(p->odr_in, netbuffer, cs_res, 0);
                    if (!z_GDU(p->odr_in, &gdu, 0, 0)
                            || gdu->which != Z_GDU_HTTP_Response)
                    {
                        wrbuf_printf(p->w_error, "HTTP decoding fail for "
                                     "URL %s", uri);
                        log_warn(p);
                    }
                    else
                    {
                        res = gdu->u.HTTP_Response;
                    }
                }
                xfree(netbuffer);
            }
        }
        if (conn)
            cs_close(conn);
        if (!res)
            break;
        code = res->code;
        location = z_HTTP_header_lookup(res->headers, "Location");
        if (++number_of_redirects <= p->max_redirects &&
                location && (code == 301 || code == 302 || code == 307))
        {
            int host_change = 0;
            const char *nlocation = yaz_check_location(p->odr_in, uri,
                                    location, &host_change);

            odr_reset(p->odr_out);
            uri = odr_strdup(p->odr_out, nlocation);
        }
        else
            break;
        yaz_cookies_response(p->cookies, res);
        odr_reset(p->odr_in);
    }
    return res;
}