Class: WebHookService

Inherits:
Object
  • Object
show all
Defined in:
app/services/web_hook_service.rb

Defined Under Namespace

Classes: InternalErrorResponse

Constant Summary collapse

REQUEST_BODY_SIZE_LIMIT =
25.megabytes
RESPONSE_BODY_SIZE_LIMIT =

Response body is for UI display only. It does not make much sense to save whatever the receivers throw back at us

8.kilobytes
RESPONSE_HEADERS_COUNT_LIMIT =

The headers are for debugging purpose. They are displayed on the UI only.

50
RESPONSE_HEADERS_SIZE_LIMIT =
1.kilobytes

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hook, data, hook_name, uniqueness_token = nil, force: false) ⇒ WebHookService

Returns a new instance of WebHookService.


43
44
45
46
47
48
49
50
51
52
53
# File 'app/services/web_hook_service.rb', line 43

def initialize(hook, data, hook_name, uniqueness_token = nil, force: false)
  @hook = hook
  @data = data.to_h
  @hook_name = hook_name.to_s
  @uniqueness_token = uniqueness_token
  @force = force
  @request_options = {
    timeout: Gitlab.config.gitlab.webhook_timeout,
    allow_local_requests: hook.allow_local_requests?
  }
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.


36
37
38
# File 'app/services/web_hook_service.rb', line 36

def data
  @data
end

#hookObject

Returns the value of attribute hook.


36
37
38
# File 'app/services/web_hook_service.rb', line 36

def hook
  @hook
end

#hook_nameObject

Returns the value of attribute hook_name.


36
37
38
# File 'app/services/web_hook_service.rb', line 36

def hook_name
  @hook_name
end

#request_optionsObject

Returns the value of attribute request_options.


36
37
38
# File 'app/services/web_hook_service.rb', line 36

def request_options
  @request_options
end

#uniqueness_tokenObject (readonly)

Returns the value of attribute uniqueness_token.


37
38
39
# File 'app/services/web_hook_service.rb', line 37

def uniqueness_token
  @uniqueness_token
end

Class Method Details

.hook_to_event(hook_name) ⇒ Object


39
40
41
# File 'app/services/web_hook_service.rb', line 39

def self.hook_to_event(hook_name)
  hook_name.to_s.singularize.titleize
end

Instance Method Details

#async_executeObject


104
105
106
107
108
109
110
111
112
113
114
115
# File 'app/services/web_hook_service.rb', line 104

def async_execute
  Gitlab::ApplicationContext.with_context(hook.application_context) do
    break log_rate_limited if rate_limit!
    break log_recursion_blocked if recursion_blocked?

    params = {
      recursion_detection_request_uuid: Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid
    }.compact

    WebHookWorker.perform_async(hook.id, data, hook_name, params)
  end
end

#disabled?Boolean

Returns:

  • (Boolean)

55
56
57
# File 'app/services/web_hook_service.rb', line 55

def disabled?
  !@force && !hook.executable?
end

#executeObject


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/services/web_hook_service.rb', line 59

def execute
  return { status: :error, message: 'Hook disabled' } if disabled?

  if recursion_blocked?
    log_recursion_blocked
    return { status: :error, message: 'Recursive webhook blocked' }
  end

  Gitlab::WebHooks::RecursionDetection.register!(hook)

  start_time = Gitlab::Metrics::System.monotonic_time

  response = if parsed_url.userinfo.blank?
               make_request(hook.url)
             else
               make_request_with_auth
             end

  log_execution(
    response: response,
    execution_duration: Gitlab::Metrics::System.monotonic_time - start_time
  )

  {
    status: :success,
    http_status: response.code,
    message: response.body
  }
rescue *Gitlab::HTTP::HTTP_ERRORS,
       Gitlab::Json::LimitedEncoder::LimitExceeded, URI::InvalidURIError => e
  execution_duration = Gitlab::Metrics::System.monotonic_time - start_time
  log_execution(
    response: InternalErrorResponse.new,
    execution_duration: execution_duration,
    error_message: e.to_s
  )

  Gitlab::AppLogger.error("WebHook Error after #{execution_duration.to_i.seconds}s => #{e}")

  {
    status: :error,
    message: e.to_s
  }
end