Forum Discussion

SiKing's avatar
SiKing
Community Expert
6 years ago

add request header to all calls

I am trying to find a better solution for adding a header to all calls. This questions was already asked here and earlier here. The proposed solution for both of these was to add a RequestFilter.filterRequest event:

def headers = request.requestHeaders
headers.put( "X-test", "test" )
request.requestHeaders = headers

This solution has two problems:

  1. This just keeps adding the same header for each call; meaning if you make the call say three times, you have three of these headers. I tried adding a RequestFilter.afterRequest event with request.requestHeaders.clear(), but that did not work.
  2. I have multiple services in my project, and I need to add this header for all requests of only one of my services.

Any advice would be appreciated.

  • RequestFilter.filterRequest event:

    // add header only for "interesting" service
    if(request.operation.interface.name != "interesting/service")
    	return
    
    def headers = request.requestHeaders
    headers.put("X-Test", "random string")
    request.requestHeaders = headers
    

    RequestFilter.afterRequest event:

    // look for header only for "interesting" service
    if(request.operation.interface.name != "interesting/service")
    	return
    
    def headers = request.requestHeaders
    if(headers.containsKey("X-Test"))
    {
    	// request.requestHeaders.clear() does not work here! 
    	headers.remove("X-Test")
    	request.requestHeaders = headers
    }
    

    I am using this to add an "Authorization" header to all my requests. Only the service of interest gets the Auth header, and afterwards it gets cleared out so nothing goes into SCM.

    Word of caution: SoapUI (and ReadyAPI) have a long standing bug: If you have many testcases running in parallel, the events could lose track of things and fire all over the place.

  • SiKing's avatar
    SiKing
    Community Expert

    RequestFilter.filterRequest event:

    // add header only for "interesting" service
    if(request.operation.interface.name != "interesting/service")
    	return
    
    def headers = request.requestHeaders
    headers.put("X-Test", "random string")
    request.requestHeaders = headers
    

    RequestFilter.afterRequest event:

    // look for header only for "interesting" service
    if(request.operation.interface.name != "interesting/service")
    	return
    
    def headers = request.requestHeaders
    if(headers.containsKey("X-Test"))
    {
    	// request.requestHeaders.clear() does not work here! 
    	headers.remove("X-Test")
    	request.requestHeaders = headers
    }
    

    I am using this to add an "Authorization" header to all my requests. Only the service of interest gets the Auth header, and afterwards it gets cleared out so nothing goes into SCM.

    Word of caution: SoapUI (and ReadyAPI) have a long standing bug: If you have many testcases running in parallel, the events could lose track of things and fire all over the place.

  • SiKing's avatar
    SiKing
    Community Expert

    I have a solution, but it is ugly.

    if(!request.operation.name.startsWith("/constant/path"))
    	return
    
    def headers = request.requestHeaders
    if(headers.containsKey("X-Test"))
    	headers.remove("X-Test")
    headers.put( "X-Test", "random string" )
    request.requestHeaders = headers
    

    I have not been able to find a reliable way to clear out this header. This means that every time the "random string" changes, I end up with git changes.

    • nmrao's avatar
      nmrao
      Champion Level 3
      1. adding header multiple times is solved with what I have provided.
      2. event listener can be possible to apply for restricted service by applying condition as needed
      instead of
      request.operation.name.startsWith("/constant/path")
      How about below?

      def serviceName = 'service1'
      if (serviceName == request.operation.interface.name) {
      //Earlier provided code
      }
  • nmrao's avatar
    nmrao
    Champion Level 3

    By the way, SubmitListener.beforeSubmit() can also be used. Result would be same, all out going request will have this header.

      • SiKing's avatar
        SiKing
        Community Expert

        Not quite.

        I still have no way of applying this to only one of my services. The SoapUI API is completely undocumented, so there is a lot of trial and error. :(

  • nmrao's avatar
    nmrao
    Champion Level 3

    SiKing 

     

    Please try this.(could not try the code for myself)

     

    //Add multiple key value pairs to be set as headers
    def headersToSet = ['X-test': 'test']
    
    //Not required to modify beyond this
    def headers = request.requestHeaders
    
    def showHeaderCount = {msg -> log.info "Header count ${msg} is: headers.size()" }
    
    def setHeader = { key, value ->
    	showHeaderCount('before')
    	if (key in headers.getKeys()) {
    		headers.remove(key)
    		showHeaderCount('after')
    	}
    	headers.put(key, value)
    }
    headersToSet.each { k, v -> setHeader(k, v) }
    request.requestHeaders = headers