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.



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

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, hook = nil) ⇒ Object



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

def self.hook_to_event(hook_name, hook = nil)
  return hook.class.name.titleize if hook.is_a?(SystemHook)

  hook_name.to_s.singularize.titleize
end

Instance Method Details

#async_executeObject



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

def async_execute
  Gitlab::ApplicationContext.with_context(hook.application_context) do
    break log_silent_mode_enabled if Gitlab::SilentMode.enabled?
    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)


57
58
59
# File 'app/services/web_hook_service.rb', line 57

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

#executeObject



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
103
104
# File 'app/services/web_hook_service.rb', line 61

def execute
  if Gitlab::SilentMode.enabled?
    log_silent_mode_enabled
    return ServiceResponse.error(message: 'Silent mode enabled')
  end

  return ServiceResponse.error(message: 'Hook disabled') if disabled?

  if recursion_blocked?
    log_recursion_blocked
    return ServiceResponse.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(parsed_url.to_s)
             else
               make_request_with_auth
             end

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

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

  log_execution(
    response: InternalErrorResponse.new,
    execution_duration: execution_duration,
    error_message: error_message
  )

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

  ServiceResponse.error(message: error_message)
end