| Conditions | 18 |
| Total Lines | 86 |
| Code Lines | 50 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like org_fedora_oscap.data_fetch._curl_fetch() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | """ |
||
| 178 | def _curl_fetch(url, out_file, ca_certs_path=None): |
||
| 179 | """ |
||
| 180 | Function that fetches data and writes it out to the given file path. If a |
||
| 181 | path to the file with CA certificates is given and the url starts with |
||
| 182 | 'https', the server certificate is validated. |
||
| 183 | |||
| 184 | :param url: url of the data that has to start with 'http://' or "https://" |
||
| 185 | :type url: str |
||
| 186 | :param out_file: path to the output file |
||
| 187 | :type out_file: str |
||
| 188 | :param ca_certs_path: path to the file with CA certificates for server |
||
| 189 | certificate validation |
||
| 190 | :type ca_certs_path: str |
||
| 191 | :raise WrongRequestError: if a wrong combination of arguments is passed |
||
| 192 | (ca_certs_path file path given and url starting with |
||
| 193 | http://) or arguments don't have required format |
||
| 194 | :raise CertificateValidationError: if server certificate validation fails |
||
| 195 | :raise FetchError: if data fetching fails (usually due to I/O errors) |
||
| 196 | |||
| 197 | """ |
||
| 198 | |||
| 199 | if url.startswith("ftp"): |
||
| 200 | match = FTP_URL_RE.match(url) |
||
| 201 | if not match: |
||
| 202 | msg = "Wrong url not matching '%s'" % FTP_URL_RE_STR |
||
| 203 | raise WrongRequestError(msg) |
||
| 204 | else: |
||
| 205 | protocol, path = match.groups() |
||
| 206 | if '@' not in path: |
||
| 207 | # no user:pass given -> use anonymous login to the FTP server |
||
| 208 | url = protocol + "://anonymous:@" + path |
||
| 209 | elif url.startswith("file"): |
||
| 210 | match = FILE_URL_RE.match(url) |
||
| 211 | if not match: |
||
| 212 | msg = "Wrong url not matching '%s'" % FILE_URL_RE_STR |
||
| 213 | raise WrongRequestError(msg) |
||
| 214 | else: |
||
| 215 | match = HTTP_URL_RE.match(url) |
||
| 216 | if not match: |
||
| 217 | msg = "Wrong url not matching '%s'" % HTTP_URL_RE_STR |
||
| 218 | raise WrongRequestError(msg) |
||
| 219 | |||
| 220 | # the first group contains the protocol, the second one the rest |
||
| 221 | protocol = match.groups()[0] |
||
| 222 | |||
| 223 | if not out_file: |
||
| 224 | raise WrongRequestError("out_file cannot be an empty string") |
||
| 225 | |||
| 226 | if ca_certs_path and protocol != "https": |
||
| 227 | msg = "Cannot verify server certificate when using plain HTTP" |
||
| 228 | raise WrongRequestError(msg) |
||
| 229 | |||
| 230 | curl = pycurl.Curl() |
||
| 231 | curl.setopt(pycurl.URL, url) |
||
| 232 | |||
| 233 | if ca_certs_path and protocol == "https": |
||
| 234 | # the strictest verification |
||
| 235 | curl.setopt(pycurl.SSL_VERIFYHOST, 2) |
||
| 236 | curl.setopt(pycurl.SSL_VERIFYPEER, 1) |
||
| 237 | curl.setopt(pycurl.CAINFO, ca_certs_path) |
||
| 238 | |||
| 239 | # may be turned off by flags (specified on command line, take precedence) |
||
| 240 | if not conf.payload.verify_ssl: |
||
| 241 | log.warning("Disabling SSL verification due to the noverifyssl flag") |
||
| 242 | curl.setopt(pycurl.SSL_VERIFYHOST, 0) |
||
| 243 | curl.setopt(pycurl.SSL_VERIFYPEER, 0) |
||
| 244 | |||
| 245 | try: |
||
| 246 | with open(out_file, "wb") as fobj: |
||
| 247 | curl.setopt(pycurl.WRITEDATA, fobj) |
||
| 248 | curl.perform() |
||
| 249 | except pycurl.error as err: |
||
| 250 | # first arg is the error code |
||
| 251 | if err.args[0] == pycurl.E_SSL_CACERT: |
||
| 252 | msg = "Failed to connect to server and validate its "\ |
||
| 253 | "certificate: %s" % err |
||
| 254 | raise CertificateValidationError(msg) |
||
| 255 | else: |
||
| 256 | msg = "Failed to fetch data: %s" % err |
||
| 257 | raise FetchError(msg) |
||
| 258 | |||
| 259 | if protocol in ("http", "https"): |
||
| 260 | return_code = curl.getinfo(pycurl.HTTP_CODE) |
||
| 261 | if 400 <= return_code < 600: |
||
| 262 | msg = _(f"Failed to fetch data - the request returned HTTP error code {return_code}") |
||
| 263 | raise FetchError(msg) |
||
| 264 |